diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a7159e0152..9d98201210 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,9 +11,9 @@ jobs: node-version: [14.x] steps: - - uses: actions/checkout@v2.3.2 + - uses: actions/checkout@v3.3.0 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2.1.1 + uses: actions/setup-node@v2.1.2 with: node-version: ${{ matrix.node-version }} - run: yarn install @@ -28,9 +28,9 @@ jobs: node-version: [14.x] steps: - - uses: actions/checkout@v2.3.2 + - uses: actions/checkout@v3.3.0 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2.1.1 + uses: actions/setup-node@v2.1.2 with: node-version: ${{ matrix.node-version }} - run: yarn install @@ -45,9 +45,9 @@ jobs: node-version: [10.x, 12.x, 14.x] steps: - - uses: actions/checkout@v2.3.2 + - uses: actions/checkout@v3.3.0 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2.1.1 + uses: actions/setup-node@v2.1.2 with: node-version: ${{ matrix.node-version }} - run: yarn install diff --git a/.gitignore b/.gitignore index 66db8b8a79..ab793ce1ec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ .history .DS_Store node_modules -dist/ coverage/ # local env files diff --git a/package.json b/package.json index 06f1913c33..11e44eadd3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "name": "tiptap-packages", "private": true, + "version": "1.0.0", "workspaces": [ "packages/*" ], diff --git a/packages/tiptap-commands/dist/commands.common.js b/packages/tiptap-commands/dist/commands.common.js new file mode 100644 index 0000000000..0570586106 --- /dev/null +++ b/packages/tiptap-commands/dist/commands.common.js @@ -0,0 +1,667 @@ + + /*! + * tiptap-commands v1.12.5 + * (c) 2020 Scrumpy UG (limited liability) + * @license MIT + */ + +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +var prosemirrorCommands = require('prosemirror-commands'); +var prosemirrorSchemaList = require('prosemirror-schema-list'); +var prosemirrorInputrules = require('prosemirror-inputrules'); +var prosemirrorState = require('prosemirror-state'); +var prosemirrorModel = require('prosemirror-model'); +var tiptapUtils = require('tiptap-utils'); +var prosemirrorUtils = require('prosemirror-utils'); + +function insertText () { + var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; + return function (state, dispatch) { + var $from = state.selection.$from; + var pos = $from.pos.pos; + dispatch(state.tr.insertText(text, pos)); + return true; + }; +} + +function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); +} + +function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } +} + +function _iterableToArray(iter) { + if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); +} + +function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); +} + +function getMarksBetween(start, end, state) { + var marks = []; + state.doc.nodesBetween(start, end, function (node, pos) { + marks = [].concat(_toConsumableArray(marks), _toConsumableArray(node.marks.map(function (mark) { + return { + start: pos, + end: pos + node.nodeSize, + mark: mark + }; + }))); + }); + return marks; +} + +function markInputRule (regexp, markType, getAttrs) { + return new prosemirrorInputrules.InputRule(regexp, function (state, match, start, end) { + var attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs; + var tr = state.tr; + var m = match.length - 1; + var markEnd = end; + var markStart = start; + + if (match[m]) { + var matchStart = start + match[0].indexOf(match[m - 1]); + var matchEnd = matchStart + match[m - 1].length - 1; + var textStart = matchStart + match[m - 1].lastIndexOf(match[m]); + var textEnd = textStart + match[m].length; + var excludedMarks = getMarksBetween(start, end, state).filter(function (item) { + var excluded = item.mark.type.excluded; + return excluded.find(function (type) { + return type.name === markType.name; + }); + }).filter(function (item) { + return item.end > matchStart; + }); + + if (excludedMarks.length) { + return false; + } + + if (textEnd < matchEnd) { + tr.delete(textEnd, matchEnd); + } + + if (textStart > matchStart) { + tr.delete(matchStart, textStart); + } + + markStart = matchStart; + markEnd = markStart + match[m].length; + } + + tr.addMark(markStart, markEnd, markType.create(attrs)); + tr.removeStoredMark(markType); + return tr; + }); +} + +function nodeInputRule (regexp, type, getAttrs) { + return new prosemirrorInputrules.InputRule(regexp, function (state, match, start, end) { + var attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs; + var tr = state.tr; + + if (match[0]) { + tr.replaceWith(start - 1, end, type.create(attrs)); + } + + return tr; + }); +} + +function pasteRule (regexp, type, getAttrs) { + var handler = function handler(fragment) { + var nodes = []; + fragment.forEach(function (child) { + if (child.isText) { + var text = child.text; + var pos = 0; + var match; + + do { + match = regexp.exec(text); + + if (match) { + var start = match.index; + var end = start + match[0].length; + var attrs = getAttrs instanceof Function ? getAttrs(match[0]) : getAttrs; + + if (start > 0) { + nodes.push(child.cut(pos, start)); + } + + nodes.push(child.cut(start, end).mark(type.create(attrs).addToSet(child.marks))); + pos = end; + } + } while (match); + + if (pos < text.length) { + nodes.push(child.cut(pos)); + } + } else { + nodes.push(child.copy(handler(child.content))); + } + }); + return prosemirrorModel.Fragment.fromArray(nodes); + }; + + return new prosemirrorState.Plugin({ + props: { + transformPasted: function transformPasted(slice) { + return new prosemirrorModel.Slice(handler(slice.content), slice.openStart, slice.openEnd); + } + } + }); +} + +function markPasteRule (regexp, type, getAttrs) { + var handler = function handler(fragment) { + var nodes = []; + fragment.forEach(function (child) { + if (child.isText) { + var text = child.text, + marks = child.marks; + var pos = 0; + var match; + var isLink = !!marks.filter(function (x) { + return x.type.name === 'link'; + })[0]; // eslint-disable-next-line + + while (!isLink && (match = regexp.exec(text)) !== null) { + if (match[1]) { + var start = match.index; + var end = start + match[0].length; + var textStart = start + match[0].indexOf(match[1]); + var textEnd = textStart + match[1].length; + var attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs; // adding text before markdown to nodes + + if (start > 0) { + nodes.push(child.cut(pos, start)); + } // adding the markdown part to nodes + + + nodes.push(child.cut(textStart, textEnd).mark(type.create(attrs).addToSet(child.marks))); + pos = end; + } + } // adding rest of text to nodes + + + if (pos < text.length) { + nodes.push(child.cut(pos)); + } + } else { + nodes.push(child.copy(handler(child.content))); + } + }); + return prosemirrorModel.Fragment.fromArray(nodes); + }; + + return new prosemirrorState.Plugin({ + props: { + transformPasted: function transformPasted(slice) { + return new prosemirrorModel.Slice(handler(slice.content), slice.openStart, slice.openEnd); + } + } + }); +} + +function removeMark (type) { + return function (state, dispatch) { + var tr = state.tr, + selection = state.selection; + var from = selection.from, + to = selection.to; + var $from = selection.$from, + empty = selection.empty; + + if (empty) { + var range = tiptapUtils.getMarkRange($from, type); + from = range.from; + to = range.to; + } + + tr.removeMark(from, to, type); + return dispatch(tr); + }; +} + +function replaceText () { + var range = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + var type = arguments.length > 1 ? arguments[1] : undefined; + var attrs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + return function (state, dispatch) { + var _state$selection = state.selection, + $from = _state$selection.$from, + $to = _state$selection.$to; + var index = $from.index(); + var from = range ? range.from : $from.pos; + var to = range ? range.to : $to.pos; + + if (!$from.parent.canReplaceWith(index, index, type)) { + return false; + } + + if (dispatch) { + dispatch(state.tr.replaceWith(from, to, type.create(attrs))); + } + + return true; + }; +} + +function setInlineBlockType (type) { + var attrs = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + return function (state, dispatch) { + var $from = state.selection.$from; + var index = $from.index(); + + if (!$from.parent.canReplaceWith(index, index, type)) { + return false; + } + + if (dispatch) { + dispatch(state.tr.replaceSelectionWith(type.create(attrs))); + } + + return true; + }; +} + +// see https://github.com/ProseMirror/prosemirror-transform/blob/master/src/structure.js +// Since this piece of code was "borrowed" from prosemirror, ESLint rules are ignored. + +/* eslint-disable max-len, no-plusplus, no-undef, eqeqeq */ + +function canSplit(doc, pos) { + var depth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1; + var typesAfter = arguments.length > 3 ? arguments[3] : undefined; + var $pos = doc.resolve(pos); + var base = $pos.depth - depth; + var innerType = typesAfter && typesAfter[typesAfter.length - 1] || $pos.parent; + if (base < 0 || $pos.parent.type.spec.isolating || !$pos.parent.canReplace($pos.index(), $pos.parent.childCount) || !innerType.type.validContent($pos.parent.content.cutByIndex($pos.index(), $pos.parent.childCount))) return false; + + for (var d = $pos.depth - 1, i = depth - 2; d > base; d--, i--) { + var node = $pos.node(d); + + var _index = $pos.index(d); + + if (node.type.spec.isolating) return false; + var rest = node.content.cutByIndex(_index, node.childCount); + var after = typesAfter && typesAfter[i] || node; + if (after != node) rest = rest.replaceChild(0, after.type.create(after.attrs)); + /* Change starts from here */ + // if (!node.canReplace(index + 1, node.childCount) || !after.type.validContent(rest)) + // return false + + if (!node.canReplace(_index + 1, node.childCount)) return false; + /* Change ends here */ + } + + var index = $pos.indexAfter(base); + var baseType = typesAfter && typesAfter[0]; + return $pos.node(base).canReplaceWith(index, index, baseType ? baseType.type : $pos.node(base + 1).type); +} // this is a copy of splitListItem +// see https://github.com/ProseMirror/prosemirror-schema-list/blob/master/src/schema-list.js + + +function splitToDefaultListItem(itemType) { + return function (state, dispatch) { + var _state$selection = state.selection, + $from = _state$selection.$from, + $to = _state$selection.$to, + node = _state$selection.node; + if (node && node.isBlock || $from.depth < 2 || !$from.sameParent($to)) return false; + var grandParent = $from.node(-1); + if (grandParent.type != itemType) return false; + + if ($from.parent.content.size == 0) { + // In an empty block. If this is a nested list, the wrapping + // list item should be split. Otherwise, bail out and let next + // command handle lifting. + if ($from.depth == 2 || $from.node(-3).type != itemType || $from.index(-2) != $from.node(-2).childCount - 1) return false; + + if (dispatch) { + var wrap = prosemirrorModel.Fragment.empty; + var keepItem = $from.index(-1) > 0; // Build a fragment containing empty versions of the structure + // from the outer list item to the parent node of the cursor + + for (var d = $from.depth - (keepItem ? 1 : 2); d >= $from.depth - 3; d--) { + wrap = prosemirrorModel.Fragment.from($from.node(d).copy(wrap)); + } // Add a second list item with an empty default start node + + + wrap = wrap.append(prosemirrorModel.Fragment.from(itemType.createAndFill())); + + var _tr = state.tr.replace($from.before(keepItem ? null : -1), $from.after(-3), new prosemirrorModel.Slice(wrap, keepItem ? 3 : 2, 2)); + + _tr.setSelection(state.selection.constructor.near(_tr.doc.resolve($from.pos + (keepItem ? 3 : 2)))); + + dispatch(_tr.scrollIntoView()); + } + + return true; + } + + var nextType = $to.pos == $from.end() ? grandParent.contentMatchAt($from.indexAfter(-1)).defaultType : null; + var tr = state.tr.delete($from.pos, $to.pos); + /* Change starts from here */ + // let types = nextType && [null, {type: nextType}] + + var types = nextType && [{ + type: itemType + }, { + type: nextType + }]; + if (!types) types = [{ + type: itemType + }, null]; + /* Change ends here */ + + if (!canSplit(tr.doc, $from.pos, 2, types)) return false; + if (dispatch) dispatch(tr.split($from.pos, 2, types).scrollIntoView()); + return true; + }; +} +/* eslint-enable max-len, no-plusplus, no-undef, eqeqeq */ + +function toggleBlockType (type, toggletype) { + var attrs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + return function (state, dispatch, view) { + var isActive = tiptapUtils.nodeIsActive(state, type, attrs); + + if (isActive) { + return prosemirrorCommands.setBlockType(toggletype)(state, dispatch, view); + } + + return prosemirrorCommands.setBlockType(type, attrs)(state, dispatch, view); + }; +} + +function isList(node, schema) { + return node.type === schema.nodes.bullet_list || node.type === schema.nodes.ordered_list || node.type === schema.nodes.todo_list; +} + +function toggleList(listType, itemType) { + return function (state, dispatch, view) { + var schema = state.schema, + selection = state.selection; + var $from = selection.$from, + $to = selection.$to; + var range = $from.blockRange($to); + + if (!range) { + return false; + } + + var parentList = prosemirrorUtils.findParentNode(function (node) { + return isList(node, schema); + })(selection); + + if (range.depth >= 1 && parentList && range.depth - parentList.depth <= 1) { + if (parentList.node.type === listType) { + return prosemirrorSchemaList.liftListItem(itemType)(state, dispatch, view); + } + + if (isList(parentList.node, schema) && listType.validContent(parentList.node.content)) { + var tr = state.tr; + tr.setNodeMarkup(parentList.pos, listType); + + if (dispatch) { + dispatch(tr); + } + + return false; + } + } + + return prosemirrorSchemaList.wrapInList(listType)(state, dispatch, view); + }; +} + +function toggleWrap (type) { + return function (state, dispatch, view) { + var isActive = tiptapUtils.nodeIsActive(state, type); + + if (isActive) { + return prosemirrorCommands.lift(state, dispatch); + } + + return prosemirrorCommands.wrapIn(type)(state, dispatch, view); + }; +} + +function updateMark (type, attrs) { + return function (state, dispatch) { + var tr = state.tr, + selection = state.selection, + doc = state.doc; + var from = selection.from, + to = selection.to; + var $from = selection.$from, + empty = selection.empty; + + if (empty) { + var range = tiptapUtils.getMarkRange($from, type); + from = range.from; + to = range.to; + } + + var hasMark = doc.rangeHasMark(from, to, type); + + if (hasMark) { + tr.removeMark(from, to, type); + } + + tr.addMark(from, to, type.create(attrs)); + return dispatch(tr); + }; +} + +Object.defineProperty(exports, 'autoJoin', { + enumerable: true, + get: function () { + return prosemirrorCommands.autoJoin; + } +}); +Object.defineProperty(exports, 'baseKeymap', { + enumerable: true, + get: function () { + return prosemirrorCommands.baseKeymap; + } +}); +Object.defineProperty(exports, 'chainCommands', { + enumerable: true, + get: function () { + return prosemirrorCommands.chainCommands; + } +}); +Object.defineProperty(exports, 'createParagraphNear', { + enumerable: true, + get: function () { + return prosemirrorCommands.createParagraphNear; + } +}); +Object.defineProperty(exports, 'deleteSelection', { + enumerable: true, + get: function () { + return prosemirrorCommands.deleteSelection; + } +}); +Object.defineProperty(exports, 'exitCode', { + enumerable: true, + get: function () { + return prosemirrorCommands.exitCode; + } +}); +Object.defineProperty(exports, 'joinBackward', { + enumerable: true, + get: function () { + return prosemirrorCommands.joinBackward; + } +}); +Object.defineProperty(exports, 'joinDown', { + enumerable: true, + get: function () { + return prosemirrorCommands.joinDown; + } +}); +Object.defineProperty(exports, 'joinForward', { + enumerable: true, + get: function () { + return prosemirrorCommands.joinForward; + } +}); +Object.defineProperty(exports, 'joinUp', { + enumerable: true, + get: function () { + return prosemirrorCommands.joinUp; + } +}); +Object.defineProperty(exports, 'lift', { + enumerable: true, + get: function () { + return prosemirrorCommands.lift; + } +}); +Object.defineProperty(exports, 'liftEmptyBlock', { + enumerable: true, + get: function () { + return prosemirrorCommands.liftEmptyBlock; + } +}); +Object.defineProperty(exports, 'macBaseKeymap', { + enumerable: true, + get: function () { + return prosemirrorCommands.macBaseKeymap; + } +}); +Object.defineProperty(exports, 'newlineInCode', { + enumerable: true, + get: function () { + return prosemirrorCommands.newlineInCode; + } +}); +Object.defineProperty(exports, 'pcBaseKeymap', { + enumerable: true, + get: function () { + return prosemirrorCommands.pcBaseKeymap; + } +}); +Object.defineProperty(exports, 'selectAll', { + enumerable: true, + get: function () { + return prosemirrorCommands.selectAll; + } +}); +Object.defineProperty(exports, 'selectNodeBackward', { + enumerable: true, + get: function () { + return prosemirrorCommands.selectNodeBackward; + } +}); +Object.defineProperty(exports, 'selectNodeForward', { + enumerable: true, + get: function () { + return prosemirrorCommands.selectNodeForward; + } +}); +Object.defineProperty(exports, 'selectParentNode', { + enumerable: true, + get: function () { + return prosemirrorCommands.selectParentNode; + } +}); +Object.defineProperty(exports, 'setBlockType', { + enumerable: true, + get: function () { + return prosemirrorCommands.setBlockType; + } +}); +Object.defineProperty(exports, 'splitBlock', { + enumerable: true, + get: function () { + return prosemirrorCommands.splitBlock; + } +}); +Object.defineProperty(exports, 'splitBlockKeepMarks', { + enumerable: true, + get: function () { + return prosemirrorCommands.splitBlockKeepMarks; + } +}); +Object.defineProperty(exports, 'toggleMark', { + enumerable: true, + get: function () { + return prosemirrorCommands.toggleMark; + } +}); +Object.defineProperty(exports, 'wrapIn', { + enumerable: true, + get: function () { + return prosemirrorCommands.wrapIn; + } +}); +Object.defineProperty(exports, 'addListNodes', { + enumerable: true, + get: function () { + return prosemirrorSchemaList.addListNodes; + } +}); +Object.defineProperty(exports, 'liftListItem', { + enumerable: true, + get: function () { + return prosemirrorSchemaList.liftListItem; + } +}); +Object.defineProperty(exports, 'sinkListItem', { + enumerable: true, + get: function () { + return prosemirrorSchemaList.sinkListItem; + } +}); +Object.defineProperty(exports, 'splitListItem', { + enumerable: true, + get: function () { + return prosemirrorSchemaList.splitListItem; + } +}); +Object.defineProperty(exports, 'wrapInList', { + enumerable: true, + get: function () { + return prosemirrorSchemaList.wrapInList; + } +}); +Object.defineProperty(exports, 'textblockTypeInputRule', { + enumerable: true, + get: function () { + return prosemirrorInputrules.textblockTypeInputRule; + } +}); +Object.defineProperty(exports, 'wrappingInputRule', { + enumerable: true, + get: function () { + return prosemirrorInputrules.wrappingInputRule; + } +}); +exports.insertText = insertText; +exports.markInputRule = markInputRule; +exports.markPasteRule = markPasteRule; +exports.nodeInputRule = nodeInputRule; +exports.pasteRule = pasteRule; +exports.removeMark = removeMark; +exports.replaceText = replaceText; +exports.setInlineBlockType = setInlineBlockType; +exports.splitToDefaultListItem = splitToDefaultListItem; +exports.toggleBlockType = toggleBlockType; +exports.toggleList = toggleList; +exports.toggleWrap = toggleWrap; +exports.updateMark = updateMark; diff --git a/packages/tiptap-commands/dist/commands.esm.js b/packages/tiptap-commands/dist/commands.esm.js new file mode 100644 index 0000000000..2871fd24a8 --- /dev/null +++ b/packages/tiptap-commands/dist/commands.esm.js @@ -0,0 +1,468 @@ + + /*! + * tiptap-commands v1.12.5 + * (c) 2020 Scrumpy UG (limited liability) + * @license MIT + */ + +import { setBlockType, lift, wrapIn } from 'prosemirror-commands'; +export { autoJoin, baseKeymap, chainCommands, createParagraphNear, deleteSelection, exitCode, joinBackward, joinDown, joinForward, joinUp, lift, liftEmptyBlock, macBaseKeymap, newlineInCode, pcBaseKeymap, selectAll, selectNodeBackward, selectNodeForward, selectParentNode, setBlockType, splitBlock, splitBlockKeepMarks, toggleMark, wrapIn } from 'prosemirror-commands'; +import { liftListItem, wrapInList } from 'prosemirror-schema-list'; +export { addListNodes, liftListItem, sinkListItem, splitListItem, wrapInList } from 'prosemirror-schema-list'; +import { InputRule } from 'prosemirror-inputrules'; +export { textblockTypeInputRule, wrappingInputRule } from 'prosemirror-inputrules'; +import { Plugin } from 'prosemirror-state'; +import { Slice, Fragment } from 'prosemirror-model'; +import { getMarkRange, nodeIsActive } from 'tiptap-utils'; +import { findParentNode } from 'prosemirror-utils'; + +function insertText () { + var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; + return function (state, dispatch) { + var $from = state.selection.$from; + var pos = $from.pos.pos; + dispatch(state.tr.insertText(text, pos)); + return true; + }; +} + +function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); +} + +function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } +} + +function _iterableToArray(iter) { + if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); +} + +function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); +} + +function getMarksBetween(start, end, state) { + var marks = []; + state.doc.nodesBetween(start, end, function (node, pos) { + marks = [].concat(_toConsumableArray(marks), _toConsumableArray(node.marks.map(function (mark) { + return { + start: pos, + end: pos + node.nodeSize, + mark: mark + }; + }))); + }); + return marks; +} + +function markInputRule (regexp, markType, getAttrs) { + return new InputRule(regexp, function (state, match, start, end) { + var attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs; + var tr = state.tr; + var m = match.length - 1; + var markEnd = end; + var markStart = start; + + if (match[m]) { + var matchStart = start + match[0].indexOf(match[m - 1]); + var matchEnd = matchStart + match[m - 1].length - 1; + var textStart = matchStart + match[m - 1].lastIndexOf(match[m]); + var textEnd = textStart + match[m].length; + var excludedMarks = getMarksBetween(start, end, state).filter(function (item) { + var excluded = item.mark.type.excluded; + return excluded.find(function (type) { + return type.name === markType.name; + }); + }).filter(function (item) { + return item.end > matchStart; + }); + + if (excludedMarks.length) { + return false; + } + + if (textEnd < matchEnd) { + tr.delete(textEnd, matchEnd); + } + + if (textStart > matchStart) { + tr.delete(matchStart, textStart); + } + + markStart = matchStart; + markEnd = markStart + match[m].length; + } + + tr.addMark(markStart, markEnd, markType.create(attrs)); + tr.removeStoredMark(markType); + return tr; + }); +} + +function nodeInputRule (regexp, type, getAttrs) { + return new InputRule(regexp, function (state, match, start, end) { + var attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs; + var tr = state.tr; + + if (match[0]) { + tr.replaceWith(start - 1, end, type.create(attrs)); + } + + return tr; + }); +} + +function pasteRule (regexp, type, getAttrs) { + var handler = function handler(fragment) { + var nodes = []; + fragment.forEach(function (child) { + if (child.isText) { + var text = child.text; + var pos = 0; + var match; + + do { + match = regexp.exec(text); + + if (match) { + var start = match.index; + var end = start + match[0].length; + var attrs = getAttrs instanceof Function ? getAttrs(match[0]) : getAttrs; + + if (start > 0) { + nodes.push(child.cut(pos, start)); + } + + nodes.push(child.cut(start, end).mark(type.create(attrs).addToSet(child.marks))); + pos = end; + } + } while (match); + + if (pos < text.length) { + nodes.push(child.cut(pos)); + } + } else { + nodes.push(child.copy(handler(child.content))); + } + }); + return Fragment.fromArray(nodes); + }; + + return new Plugin({ + props: { + transformPasted: function transformPasted(slice) { + return new Slice(handler(slice.content), slice.openStart, slice.openEnd); + } + } + }); +} + +function markPasteRule (regexp, type, getAttrs) { + var handler = function handler(fragment) { + var nodes = []; + fragment.forEach(function (child) { + if (child.isText) { + var text = child.text, + marks = child.marks; + var pos = 0; + var match; + var isLink = !!marks.filter(function (x) { + return x.type.name === 'link'; + })[0]; // eslint-disable-next-line + + while (!isLink && (match = regexp.exec(text)) !== null) { + if (match[1]) { + var start = match.index; + var end = start + match[0].length; + var textStart = start + match[0].indexOf(match[1]); + var textEnd = textStart + match[1].length; + var attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs; // adding text before markdown to nodes + + if (start > 0) { + nodes.push(child.cut(pos, start)); + } // adding the markdown part to nodes + + + nodes.push(child.cut(textStart, textEnd).mark(type.create(attrs).addToSet(child.marks))); + pos = end; + } + } // adding rest of text to nodes + + + if (pos < text.length) { + nodes.push(child.cut(pos)); + } + } else { + nodes.push(child.copy(handler(child.content))); + } + }); + return Fragment.fromArray(nodes); + }; + + return new Plugin({ + props: { + transformPasted: function transformPasted(slice) { + return new Slice(handler(slice.content), slice.openStart, slice.openEnd); + } + } + }); +} + +function removeMark (type) { + return function (state, dispatch) { + var tr = state.tr, + selection = state.selection; + var from = selection.from, + to = selection.to; + var $from = selection.$from, + empty = selection.empty; + + if (empty) { + var range = getMarkRange($from, type); + from = range.from; + to = range.to; + } + + tr.removeMark(from, to, type); + return dispatch(tr); + }; +} + +function replaceText () { + var range = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + var type = arguments.length > 1 ? arguments[1] : undefined; + var attrs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + return function (state, dispatch) { + var _state$selection = state.selection, + $from = _state$selection.$from, + $to = _state$selection.$to; + var index = $from.index(); + var from = range ? range.from : $from.pos; + var to = range ? range.to : $to.pos; + + if (!$from.parent.canReplaceWith(index, index, type)) { + return false; + } + + if (dispatch) { + dispatch(state.tr.replaceWith(from, to, type.create(attrs))); + } + + return true; + }; +} + +function setInlineBlockType (type) { + var attrs = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + return function (state, dispatch) { + var $from = state.selection.$from; + var index = $from.index(); + + if (!$from.parent.canReplaceWith(index, index, type)) { + return false; + } + + if (dispatch) { + dispatch(state.tr.replaceSelectionWith(type.create(attrs))); + } + + return true; + }; +} + +// see https://github.com/ProseMirror/prosemirror-transform/blob/master/src/structure.js +// Since this piece of code was "borrowed" from prosemirror, ESLint rules are ignored. + +/* eslint-disable max-len, no-plusplus, no-undef, eqeqeq */ + +function canSplit(doc, pos) { + var depth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1; + var typesAfter = arguments.length > 3 ? arguments[3] : undefined; + var $pos = doc.resolve(pos); + var base = $pos.depth - depth; + var innerType = typesAfter && typesAfter[typesAfter.length - 1] || $pos.parent; + if (base < 0 || $pos.parent.type.spec.isolating || !$pos.parent.canReplace($pos.index(), $pos.parent.childCount) || !innerType.type.validContent($pos.parent.content.cutByIndex($pos.index(), $pos.parent.childCount))) return false; + + for (var d = $pos.depth - 1, i = depth - 2; d > base; d--, i--) { + var node = $pos.node(d); + + var _index = $pos.index(d); + + if (node.type.spec.isolating) return false; + var rest = node.content.cutByIndex(_index, node.childCount); + var after = typesAfter && typesAfter[i] || node; + if (after != node) rest = rest.replaceChild(0, after.type.create(after.attrs)); + /* Change starts from here */ + // if (!node.canReplace(index + 1, node.childCount) || !after.type.validContent(rest)) + // return false + + if (!node.canReplace(_index + 1, node.childCount)) return false; + /* Change ends here */ + } + + var index = $pos.indexAfter(base); + var baseType = typesAfter && typesAfter[0]; + return $pos.node(base).canReplaceWith(index, index, baseType ? baseType.type : $pos.node(base + 1).type); +} // this is a copy of splitListItem +// see https://github.com/ProseMirror/prosemirror-schema-list/blob/master/src/schema-list.js + + +function splitToDefaultListItem(itemType) { + return function (state, dispatch) { + var _state$selection = state.selection, + $from = _state$selection.$from, + $to = _state$selection.$to, + node = _state$selection.node; + if (node && node.isBlock || $from.depth < 2 || !$from.sameParent($to)) return false; + var grandParent = $from.node(-1); + if (grandParent.type != itemType) return false; + + if ($from.parent.content.size == 0) { + // In an empty block. If this is a nested list, the wrapping + // list item should be split. Otherwise, bail out and let next + // command handle lifting. + if ($from.depth == 2 || $from.node(-3).type != itemType || $from.index(-2) != $from.node(-2).childCount - 1) return false; + + if (dispatch) { + var wrap = Fragment.empty; + var keepItem = $from.index(-1) > 0; // Build a fragment containing empty versions of the structure + // from the outer list item to the parent node of the cursor + + for (var d = $from.depth - (keepItem ? 1 : 2); d >= $from.depth - 3; d--) { + wrap = Fragment.from($from.node(d).copy(wrap)); + } // Add a second list item with an empty default start node + + + wrap = wrap.append(Fragment.from(itemType.createAndFill())); + + var _tr = state.tr.replace($from.before(keepItem ? null : -1), $from.after(-3), new Slice(wrap, keepItem ? 3 : 2, 2)); + + _tr.setSelection(state.selection.constructor.near(_tr.doc.resolve($from.pos + (keepItem ? 3 : 2)))); + + dispatch(_tr.scrollIntoView()); + } + + return true; + } + + var nextType = $to.pos == $from.end() ? grandParent.contentMatchAt($from.indexAfter(-1)).defaultType : null; + var tr = state.tr.delete($from.pos, $to.pos); + /* Change starts from here */ + // let types = nextType && [null, {type: nextType}] + + var types = nextType && [{ + type: itemType + }, { + type: nextType + }]; + if (!types) types = [{ + type: itemType + }, null]; + /* Change ends here */ + + if (!canSplit(tr.doc, $from.pos, 2, types)) return false; + if (dispatch) dispatch(tr.split($from.pos, 2, types).scrollIntoView()); + return true; + }; +} +/* eslint-enable max-len, no-plusplus, no-undef, eqeqeq */ + +function toggleBlockType (type, toggletype) { + var attrs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + return function (state, dispatch, view) { + var isActive = nodeIsActive(state, type, attrs); + + if (isActive) { + return setBlockType(toggletype)(state, dispatch, view); + } + + return setBlockType(type, attrs)(state, dispatch, view); + }; +} + +function isList(node, schema) { + return node.type === schema.nodes.bullet_list || node.type === schema.nodes.ordered_list || node.type === schema.nodes.todo_list; +} + +function toggleList(listType, itemType) { + return function (state, dispatch, view) { + var schema = state.schema, + selection = state.selection; + var $from = selection.$from, + $to = selection.$to; + var range = $from.blockRange($to); + + if (!range) { + return false; + } + + var parentList = findParentNode(function (node) { + return isList(node, schema); + })(selection); + + if (range.depth >= 1 && parentList && range.depth - parentList.depth <= 1) { + if (parentList.node.type === listType) { + return liftListItem(itemType)(state, dispatch, view); + } + + if (isList(parentList.node, schema) && listType.validContent(parentList.node.content)) { + var tr = state.tr; + tr.setNodeMarkup(parentList.pos, listType); + + if (dispatch) { + dispatch(tr); + } + + return false; + } + } + + return wrapInList(listType)(state, dispatch, view); + }; +} + +function toggleWrap (type) { + return function (state, dispatch, view) { + var isActive = nodeIsActive(state, type); + + if (isActive) { + return lift(state, dispatch); + } + + return wrapIn(type)(state, dispatch, view); + }; +} + +function updateMark (type, attrs) { + return function (state, dispatch) { + var tr = state.tr, + selection = state.selection, + doc = state.doc; + var from = selection.from, + to = selection.to; + var $from = selection.$from, + empty = selection.empty; + + if (empty) { + var range = getMarkRange($from, type); + from = range.from; + to = range.to; + } + + var hasMark = doc.rangeHasMark(from, to, type); + + if (hasMark) { + tr.removeMark(from, to, type); + } + + tr.addMark(from, to, type.create(attrs)); + return dispatch(tr); + }; +} + +export { insertText, markInputRule, markPasteRule, nodeInputRule, pasteRule, removeMark, replaceText, setInlineBlockType, splitToDefaultListItem, toggleBlockType, toggleList, toggleWrap, updateMark }; diff --git a/packages/tiptap-commands/dist/commands.js b/packages/tiptap-commands/dist/commands.js new file mode 100644 index 0000000000..50f4763199 --- /dev/null +++ b/packages/tiptap-commands/dist/commands.js @@ -0,0 +1,665 @@ + + /*! + * tiptap-commands v1.12.5 + * (c) 2020 Scrumpy UG (limited liability) + * @license MIT + */ + +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('prosemirror-commands'), require('prosemirror-schema-list'), require('prosemirror-inputrules'), require('prosemirror-state'), require('prosemirror-model'), require('tiptap-utils'), require('prosemirror-utils')) : + typeof define === 'function' && define.amd ? define(['exports', 'prosemirror-commands', 'prosemirror-schema-list', 'prosemirror-inputrules', 'prosemirror-state', 'prosemirror-model', 'tiptap-utils', 'prosemirror-utils'], factory) : + (global = global || self, factory(global.tiptapCommands = {}, global.prosemirrorCommands, global.prosemirrorSchemaList, global.prosemirrorInputrules, global.prosemirrorState, global.prosemirrorModel, global.tiptapUtils, global.prosemirrorUtils)); +}(this, (function (exports, prosemirrorCommands, prosemirrorSchemaList, prosemirrorInputrules, prosemirrorState, prosemirrorModel, tiptapUtils, prosemirrorUtils) { 'use strict'; + + function insertText () { + var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; + return function (state, dispatch) { + var $from = state.selection.$from; + var pos = $from.pos.pos; + dispatch(state.tr.insertText(text, pos)); + return true; + }; + } + + function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); + } + + function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } + } + + function _iterableToArray(iter) { + if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); + } + + function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); + } + + function getMarksBetween(start, end, state) { + var marks = []; + state.doc.nodesBetween(start, end, function (node, pos) { + marks = [].concat(_toConsumableArray(marks), _toConsumableArray(node.marks.map(function (mark) { + return { + start: pos, + end: pos + node.nodeSize, + mark: mark + }; + }))); + }); + return marks; + } + + function markInputRule (regexp, markType, getAttrs) { + return new prosemirrorInputrules.InputRule(regexp, function (state, match, start, end) { + var attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs; + var tr = state.tr; + var m = match.length - 1; + var markEnd = end; + var markStart = start; + + if (match[m]) { + var matchStart = start + match[0].indexOf(match[m - 1]); + var matchEnd = matchStart + match[m - 1].length - 1; + var textStart = matchStart + match[m - 1].lastIndexOf(match[m]); + var textEnd = textStart + match[m].length; + var excludedMarks = getMarksBetween(start, end, state).filter(function (item) { + var excluded = item.mark.type.excluded; + return excluded.find(function (type) { + return type.name === markType.name; + }); + }).filter(function (item) { + return item.end > matchStart; + }); + + if (excludedMarks.length) { + return false; + } + + if (textEnd < matchEnd) { + tr.delete(textEnd, matchEnd); + } + + if (textStart > matchStart) { + tr.delete(matchStart, textStart); + } + + markStart = matchStart; + markEnd = markStart + match[m].length; + } + + tr.addMark(markStart, markEnd, markType.create(attrs)); + tr.removeStoredMark(markType); + return tr; + }); + } + + function nodeInputRule (regexp, type, getAttrs) { + return new prosemirrorInputrules.InputRule(regexp, function (state, match, start, end) { + var attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs; + var tr = state.tr; + + if (match[0]) { + tr.replaceWith(start - 1, end, type.create(attrs)); + } + + return tr; + }); + } + + function pasteRule (regexp, type, getAttrs) { + var handler = function handler(fragment) { + var nodes = []; + fragment.forEach(function (child) { + if (child.isText) { + var text = child.text; + var pos = 0; + var match; + + do { + match = regexp.exec(text); + + if (match) { + var start = match.index; + var end = start + match[0].length; + var attrs = getAttrs instanceof Function ? getAttrs(match[0]) : getAttrs; + + if (start > 0) { + nodes.push(child.cut(pos, start)); + } + + nodes.push(child.cut(start, end).mark(type.create(attrs).addToSet(child.marks))); + pos = end; + } + } while (match); + + if (pos < text.length) { + nodes.push(child.cut(pos)); + } + } else { + nodes.push(child.copy(handler(child.content))); + } + }); + return prosemirrorModel.Fragment.fromArray(nodes); + }; + + return new prosemirrorState.Plugin({ + props: { + transformPasted: function transformPasted(slice) { + return new prosemirrorModel.Slice(handler(slice.content), slice.openStart, slice.openEnd); + } + } + }); + } + + function markPasteRule (regexp, type, getAttrs) { + var handler = function handler(fragment) { + var nodes = []; + fragment.forEach(function (child) { + if (child.isText) { + var text = child.text, + marks = child.marks; + var pos = 0; + var match; + var isLink = !!marks.filter(function (x) { + return x.type.name === 'link'; + })[0]; // eslint-disable-next-line + + while (!isLink && (match = regexp.exec(text)) !== null) { + if (match[1]) { + var start = match.index; + var end = start + match[0].length; + var textStart = start + match[0].indexOf(match[1]); + var textEnd = textStart + match[1].length; + var attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs; // adding text before markdown to nodes + + if (start > 0) { + nodes.push(child.cut(pos, start)); + } // adding the markdown part to nodes + + + nodes.push(child.cut(textStart, textEnd).mark(type.create(attrs).addToSet(child.marks))); + pos = end; + } + } // adding rest of text to nodes + + + if (pos < text.length) { + nodes.push(child.cut(pos)); + } + } else { + nodes.push(child.copy(handler(child.content))); + } + }); + return prosemirrorModel.Fragment.fromArray(nodes); + }; + + return new prosemirrorState.Plugin({ + props: { + transformPasted: function transformPasted(slice) { + return new prosemirrorModel.Slice(handler(slice.content), slice.openStart, slice.openEnd); + } + } + }); + } + + function removeMark (type) { + return function (state, dispatch) { + var tr = state.tr, + selection = state.selection; + var from = selection.from, + to = selection.to; + var $from = selection.$from, + empty = selection.empty; + + if (empty) { + var range = tiptapUtils.getMarkRange($from, type); + from = range.from; + to = range.to; + } + + tr.removeMark(from, to, type); + return dispatch(tr); + }; + } + + function replaceText () { + var range = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + var type = arguments.length > 1 ? arguments[1] : undefined; + var attrs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + return function (state, dispatch) { + var _state$selection = state.selection, + $from = _state$selection.$from, + $to = _state$selection.$to; + var index = $from.index(); + var from = range ? range.from : $from.pos; + var to = range ? range.to : $to.pos; + + if (!$from.parent.canReplaceWith(index, index, type)) { + return false; + } + + if (dispatch) { + dispatch(state.tr.replaceWith(from, to, type.create(attrs))); + } + + return true; + }; + } + + function setInlineBlockType (type) { + var attrs = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + return function (state, dispatch) { + var $from = state.selection.$from; + var index = $from.index(); + + if (!$from.parent.canReplaceWith(index, index, type)) { + return false; + } + + if (dispatch) { + dispatch(state.tr.replaceSelectionWith(type.create(attrs))); + } + + return true; + }; + } + + // see https://github.com/ProseMirror/prosemirror-transform/blob/master/src/structure.js + // Since this piece of code was "borrowed" from prosemirror, ESLint rules are ignored. + + /* eslint-disable max-len, no-plusplus, no-undef, eqeqeq */ + + function canSplit(doc, pos) { + var depth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1; + var typesAfter = arguments.length > 3 ? arguments[3] : undefined; + var $pos = doc.resolve(pos); + var base = $pos.depth - depth; + var innerType = typesAfter && typesAfter[typesAfter.length - 1] || $pos.parent; + if (base < 0 || $pos.parent.type.spec.isolating || !$pos.parent.canReplace($pos.index(), $pos.parent.childCount) || !innerType.type.validContent($pos.parent.content.cutByIndex($pos.index(), $pos.parent.childCount))) return false; + + for (var d = $pos.depth - 1, i = depth - 2; d > base; d--, i--) { + var node = $pos.node(d); + + var _index = $pos.index(d); + + if (node.type.spec.isolating) return false; + var rest = node.content.cutByIndex(_index, node.childCount); + var after = typesAfter && typesAfter[i] || node; + if (after != node) rest = rest.replaceChild(0, after.type.create(after.attrs)); + /* Change starts from here */ + // if (!node.canReplace(index + 1, node.childCount) || !after.type.validContent(rest)) + // return false + + if (!node.canReplace(_index + 1, node.childCount)) return false; + /* Change ends here */ + } + + var index = $pos.indexAfter(base); + var baseType = typesAfter && typesAfter[0]; + return $pos.node(base).canReplaceWith(index, index, baseType ? baseType.type : $pos.node(base + 1).type); + } // this is a copy of splitListItem + // see https://github.com/ProseMirror/prosemirror-schema-list/blob/master/src/schema-list.js + + + function splitToDefaultListItem(itemType) { + return function (state, dispatch) { + var _state$selection = state.selection, + $from = _state$selection.$from, + $to = _state$selection.$to, + node = _state$selection.node; + if (node && node.isBlock || $from.depth < 2 || !$from.sameParent($to)) return false; + var grandParent = $from.node(-1); + if (grandParent.type != itemType) return false; + + if ($from.parent.content.size == 0) { + // In an empty block. If this is a nested list, the wrapping + // list item should be split. Otherwise, bail out and let next + // command handle lifting. + if ($from.depth == 2 || $from.node(-3).type != itemType || $from.index(-2) != $from.node(-2).childCount - 1) return false; + + if (dispatch) { + var wrap = prosemirrorModel.Fragment.empty; + var keepItem = $from.index(-1) > 0; // Build a fragment containing empty versions of the structure + // from the outer list item to the parent node of the cursor + + for (var d = $from.depth - (keepItem ? 1 : 2); d >= $from.depth - 3; d--) { + wrap = prosemirrorModel.Fragment.from($from.node(d).copy(wrap)); + } // Add a second list item with an empty default start node + + + wrap = wrap.append(prosemirrorModel.Fragment.from(itemType.createAndFill())); + + var _tr = state.tr.replace($from.before(keepItem ? null : -1), $from.after(-3), new prosemirrorModel.Slice(wrap, keepItem ? 3 : 2, 2)); + + _tr.setSelection(state.selection.constructor.near(_tr.doc.resolve($from.pos + (keepItem ? 3 : 2)))); + + dispatch(_tr.scrollIntoView()); + } + + return true; + } + + var nextType = $to.pos == $from.end() ? grandParent.contentMatchAt($from.indexAfter(-1)).defaultType : null; + var tr = state.tr.delete($from.pos, $to.pos); + /* Change starts from here */ + // let types = nextType && [null, {type: nextType}] + + var types = nextType && [{ + type: itemType + }, { + type: nextType + }]; + if (!types) types = [{ + type: itemType + }, null]; + /* Change ends here */ + + if (!canSplit(tr.doc, $from.pos, 2, types)) return false; + if (dispatch) dispatch(tr.split($from.pos, 2, types).scrollIntoView()); + return true; + }; + } + /* eslint-enable max-len, no-plusplus, no-undef, eqeqeq */ + + function toggleBlockType (type, toggletype) { + var attrs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + return function (state, dispatch, view) { + var isActive = tiptapUtils.nodeIsActive(state, type, attrs); + + if (isActive) { + return prosemirrorCommands.setBlockType(toggletype)(state, dispatch, view); + } + + return prosemirrorCommands.setBlockType(type, attrs)(state, dispatch, view); + }; + } + + function isList(node, schema) { + return node.type === schema.nodes.bullet_list || node.type === schema.nodes.ordered_list || node.type === schema.nodes.todo_list; + } + + function toggleList(listType, itemType) { + return function (state, dispatch, view) { + var schema = state.schema, + selection = state.selection; + var $from = selection.$from, + $to = selection.$to; + var range = $from.blockRange($to); + + if (!range) { + return false; + } + + var parentList = prosemirrorUtils.findParentNode(function (node) { + return isList(node, schema); + })(selection); + + if (range.depth >= 1 && parentList && range.depth - parentList.depth <= 1) { + if (parentList.node.type === listType) { + return prosemirrorSchemaList.liftListItem(itemType)(state, dispatch, view); + } + + if (isList(parentList.node, schema) && listType.validContent(parentList.node.content)) { + var tr = state.tr; + tr.setNodeMarkup(parentList.pos, listType); + + if (dispatch) { + dispatch(tr); + } + + return false; + } + } + + return prosemirrorSchemaList.wrapInList(listType)(state, dispatch, view); + }; + } + + function toggleWrap (type) { + return function (state, dispatch, view) { + var isActive = tiptapUtils.nodeIsActive(state, type); + + if (isActive) { + return prosemirrorCommands.lift(state, dispatch); + } + + return prosemirrorCommands.wrapIn(type)(state, dispatch, view); + }; + } + + function updateMark (type, attrs) { + return function (state, dispatch) { + var tr = state.tr, + selection = state.selection, + doc = state.doc; + var from = selection.from, + to = selection.to; + var $from = selection.$from, + empty = selection.empty; + + if (empty) { + var range = tiptapUtils.getMarkRange($from, type); + from = range.from; + to = range.to; + } + + var hasMark = doc.rangeHasMark(from, to, type); + + if (hasMark) { + tr.removeMark(from, to, type); + } + + tr.addMark(from, to, type.create(attrs)); + return dispatch(tr); + }; + } + + Object.defineProperty(exports, 'autoJoin', { + enumerable: true, + get: function () { + return prosemirrorCommands.autoJoin; + } + }); + Object.defineProperty(exports, 'baseKeymap', { + enumerable: true, + get: function () { + return prosemirrorCommands.baseKeymap; + } + }); + Object.defineProperty(exports, 'chainCommands', { + enumerable: true, + get: function () { + return prosemirrorCommands.chainCommands; + } + }); + Object.defineProperty(exports, 'createParagraphNear', { + enumerable: true, + get: function () { + return prosemirrorCommands.createParagraphNear; + } + }); + Object.defineProperty(exports, 'deleteSelection', { + enumerable: true, + get: function () { + return prosemirrorCommands.deleteSelection; + } + }); + Object.defineProperty(exports, 'exitCode', { + enumerable: true, + get: function () { + return prosemirrorCommands.exitCode; + } + }); + Object.defineProperty(exports, 'joinBackward', { + enumerable: true, + get: function () { + return prosemirrorCommands.joinBackward; + } + }); + Object.defineProperty(exports, 'joinDown', { + enumerable: true, + get: function () { + return prosemirrorCommands.joinDown; + } + }); + Object.defineProperty(exports, 'joinForward', { + enumerable: true, + get: function () { + return prosemirrorCommands.joinForward; + } + }); + Object.defineProperty(exports, 'joinUp', { + enumerable: true, + get: function () { + return prosemirrorCommands.joinUp; + } + }); + Object.defineProperty(exports, 'lift', { + enumerable: true, + get: function () { + return prosemirrorCommands.lift; + } + }); + Object.defineProperty(exports, 'liftEmptyBlock', { + enumerable: true, + get: function () { + return prosemirrorCommands.liftEmptyBlock; + } + }); + Object.defineProperty(exports, 'macBaseKeymap', { + enumerable: true, + get: function () { + return prosemirrorCommands.macBaseKeymap; + } + }); + Object.defineProperty(exports, 'newlineInCode', { + enumerable: true, + get: function () { + return prosemirrorCommands.newlineInCode; + } + }); + Object.defineProperty(exports, 'pcBaseKeymap', { + enumerable: true, + get: function () { + return prosemirrorCommands.pcBaseKeymap; + } + }); + Object.defineProperty(exports, 'selectAll', { + enumerable: true, + get: function () { + return prosemirrorCommands.selectAll; + } + }); + Object.defineProperty(exports, 'selectNodeBackward', { + enumerable: true, + get: function () { + return prosemirrorCommands.selectNodeBackward; + } + }); + Object.defineProperty(exports, 'selectNodeForward', { + enumerable: true, + get: function () { + return prosemirrorCommands.selectNodeForward; + } + }); + Object.defineProperty(exports, 'selectParentNode', { + enumerable: true, + get: function () { + return prosemirrorCommands.selectParentNode; + } + }); + Object.defineProperty(exports, 'setBlockType', { + enumerable: true, + get: function () { + return prosemirrorCommands.setBlockType; + } + }); + Object.defineProperty(exports, 'splitBlock', { + enumerable: true, + get: function () { + return prosemirrorCommands.splitBlock; + } + }); + Object.defineProperty(exports, 'splitBlockKeepMarks', { + enumerable: true, + get: function () { + return prosemirrorCommands.splitBlockKeepMarks; + } + }); + Object.defineProperty(exports, 'toggleMark', { + enumerable: true, + get: function () { + return prosemirrorCommands.toggleMark; + } + }); + Object.defineProperty(exports, 'wrapIn', { + enumerable: true, + get: function () { + return prosemirrorCommands.wrapIn; + } + }); + Object.defineProperty(exports, 'addListNodes', { + enumerable: true, + get: function () { + return prosemirrorSchemaList.addListNodes; + } + }); + Object.defineProperty(exports, 'liftListItem', { + enumerable: true, + get: function () { + return prosemirrorSchemaList.liftListItem; + } + }); + Object.defineProperty(exports, 'sinkListItem', { + enumerable: true, + get: function () { + return prosemirrorSchemaList.sinkListItem; + } + }); + Object.defineProperty(exports, 'splitListItem', { + enumerable: true, + get: function () { + return prosemirrorSchemaList.splitListItem; + } + }); + Object.defineProperty(exports, 'wrapInList', { + enumerable: true, + get: function () { + return prosemirrorSchemaList.wrapInList; + } + }); + Object.defineProperty(exports, 'textblockTypeInputRule', { + enumerable: true, + get: function () { + return prosemirrorInputrules.textblockTypeInputRule; + } + }); + Object.defineProperty(exports, 'wrappingInputRule', { + enumerable: true, + get: function () { + return prosemirrorInputrules.wrappingInputRule; + } + }); + exports.insertText = insertText; + exports.markInputRule = markInputRule; + exports.markPasteRule = markPasteRule; + exports.nodeInputRule = nodeInputRule; + exports.pasteRule = pasteRule; + exports.removeMark = removeMark; + exports.replaceText = replaceText; + exports.setInlineBlockType = setInlineBlockType; + exports.splitToDefaultListItem = splitToDefaultListItem; + exports.toggleBlockType = toggleBlockType; + exports.toggleList = toggleList; + exports.toggleWrap = toggleWrap; + exports.updateMark = updateMark; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}))); diff --git a/packages/tiptap-commands/dist/commands.min.js b/packages/tiptap-commands/dist/commands.min.js new file mode 100644 index 0000000000..c76176b590 --- /dev/null +++ b/packages/tiptap-commands/dist/commands.min.js @@ -0,0 +1,14 @@ + + /*! + * tiptap-commands v1.12.5 + * (c) 2020 Scrumpy UG (limited liability) + * @license MIT + */ + + +/*! + * tiptap-commands v1.12.5 + * (c) 2020 Scrumpy UG (limited liability) + * @license MIT + */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("prosemirror-commands"),require("prosemirror-schema-list"),require("prosemirror-inputrules"),require("prosemirror-state"),require("prosemirror-model"),require("tiptap-utils"),require("prosemirror-utils")):"function"==typeof define&&define.amd?define(["exports","prosemirror-commands","prosemirror-schema-list","prosemirror-inputrules","prosemirror-state","prosemirror-model","tiptap-utils","prosemirror-utils"],t):t((e=e||self).tiptapCommands={},e.prosemirrorCommands,e.prosemirrorSchemaList,e.prosemirrorInputrules,e.prosemirrorState,e.prosemirrorModel,e.tiptapUtils,e.prosemirrorUtils)}(this,(function(e,t,r,n,o,i,u,a){"use strict";function c(e){return function(e){if(Array.isArray(e)){for(var t=0,r=new Array(e.length);t0&&void 0!==arguments[0]?arguments[0]:"";return function(t,r){var n=t.selection.$from.pos.pos;return r(t.tr.insertText(e,n)),!0}},e.markInputRule=function(e,t,r){return new n.InputRule(e,(function(e,n,o,i){var u=r instanceof Function?r(n):r,a=e.tr,l=n.length-1,p=i,f=o;if(n[l]){var s=o+n[0].indexOf(n[l-1]),d=s+n[l-1].length-1,m=s+n[l-1].lastIndexOf(n[l]),y=m+n[l].length;if(function(e,t,r){var n=[];return r.doc.nodesBetween(e,t,(function(e,t){n=[].concat(c(n),c(e.marks.map((function(r){return{start:t,end:t+e.nodeSize,mark:r}}))))})),n}(o,i,e).filter((function(e){return e.mark.type.excluded.find((function(e){return e.name===t.name}))})).filter((function(e){return e.end>s})).length)return!1;ys&&a.delete(s,m),p=(f=s)+n[l].length}return a.addMark(f,p,t.create(u)),a.removeStoredMark(t),a}))},e.markPasteRule=function(e,t,r){return new o.Plugin({props:{transformPasted:function(n){return new i.Slice(function n(o){var u=[];return o.forEach((function(o){if(o.isText){for(var i,a=o.text,c=0,l=!!o.marks.filter((function(e){return"link"===e.type.name}))[0];!l&&null!==(i=e.exec(a));)if(i[1]){var p=i.index,f=p+i[0].length,s=p+i[0].indexOf(i[1]),d=s+i[1].length,m=r instanceof Function?r(i):r;p>0&&u.push(o.cut(c,p)),u.push(o.cut(s,d).mark(t.create(m).addToSet(o.marks))),c=f}c0&&u.push(o.cut(c,l)),u.push(o.cut(l,p).mark(t.create(f).addToSet(o.marks))),c=p}}while(i);c0&&void 0!==arguments[0]?arguments[0]:null,t=arguments.length>1?arguments[1]:void 0,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return function(n,o){var i=n.selection,u=i.$from,a=i.$to,c=u.index(),l=e?e.from:u.pos,p=e?e.to:a.pos;return!!u.parent.canReplaceWith(c,c,t)&&(o&&o(n.tr.replaceWith(l,p,t.create(r))),!0)}},e.setInlineBlockType=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return function(r,n){var o=r.selection.$from,i=o.index();return!!o.parent.canReplaceWith(i,i,e)&&(n&&n(r.tr.replaceSelectionWith(e.create(t))),!0)}},e.splitToDefaultListItem=function(e){return function(t,r){var n=t.selection,o=n.$from,u=n.$to,a=n.node;if(a&&a.isBlock||o.depth<2||!o.sameParent(u))return!1;var c=o.node(-1);if(c.type!=e)return!1;if(0==o.parent.content.size){if(2==o.depth||o.node(-3).type!=e||o.index(-2)!=o.node(-2).childCount-1)return!1;if(r){for(var l=i.Fragment.empty,p=o.index(-1)>0,f=o.depth-(p?1:2);f>=o.depth-3;f--)l=i.Fragment.from(o.node(f).copy(l));l=l.append(i.Fragment.from(e.createAndFill()));var s=t.tr.replace(o.before(p?null:-1),o.after(-3),new i.Slice(l,p?3:2,2));s.setSelection(t.selection.constructor.near(s.doc.resolve(o.pos+(p?3:2)))),r(s.scrollIntoView())}return!0}var d=u.pos==o.end()?c.contentMatchAt(o.indexAfter(-1)).defaultType:null,m=t.tr.delete(o.pos,u.pos),y=d&&[{type:e},{type:d}];return y||(y=[{type:e},null]),!!function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1,n=arguments.length>3?arguments[3]:void 0,o=e.resolve(t),i=o.depth-r,u=n&&n[n.length-1]||o.parent;if(i<0||o.parent.type.spec.isolating||!o.parent.canReplace(o.index(),o.parent.childCount)||!u.type.validContent(o.parent.content.cutByIndex(o.index(),o.parent.childCount)))return!1;for(var a=o.depth-1,c=r-2;a>i;a--,c--){var l=o.node(a),p=o.index(a);if(l.type.spec.isolating)return!1;var f=l.content.cutByIndex(p,l.childCount),s=n&&n[c]||l;if(s!=l&&(f=f.replaceChild(0,s.type.create(s.attrs))),!l.canReplace(p+1,l.childCount))return!1}var d=o.indexAfter(i),m=n&&n[0];return o.node(i).canReplaceWith(d,d,m?m.type:o.node(i+1).type)}(m.doc,o.pos,2,y)&&(r&&r(m.split(o.pos,2,y).scrollIntoView()),!0)}},e.toggleBlockType=function(e,r){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return function(o,i,a){return u.nodeIsActive(o,e,n)?t.setBlockType(r)(o,i,a):t.setBlockType(e,n)(o,i,a)}},e.toggleList=function(e,t){return function(n,o,i){var u=n.schema,c=n.selection,p=c.$from,f=c.$to,s=p.blockRange(f);if(!s)return!1;var d=a.findParentNode((function(e){return l(e,u)}))(c);if(s.depth>=1&&d&&s.depth-d.depth<=1){if(d.node.type===e)return r.liftListItem(t)(n,o,i);if(l(d.node,u)&&e.validContent(d.node.content)){var m=n.tr;return m.setNodeMarkup(d.pos,e),o&&o(m),!1}}return r.wrapInList(e)(n,o,i)}},e.toggleWrap=function(e){return function(r,n,o){return u.nodeIsActive(r,e)?t.lift(r,n):t.wrapIn(e)(r,n,o)}},e.updateMark=function(e,t){return function(r,n){var o=r.tr,i=r.selection,a=r.doc,c=i.from,l=i.to,p=i.$from;if(i.empty){var f=u.getMarkRange(p,e);c=f.from,l=f.to}return a.rangeHasMark(c,l,e)&&o.removeMark(c,l,e),o.addMark(c,l,e.create(t)),n(o)}},Object.defineProperty(e,"__esModule",{value:!0})})); \ No newline at end of file diff --git a/packages/tiptap-extensions/dist/extensions.common.js b/packages/tiptap-extensions/dist/extensions.common.js new file mode 100644 index 0000000000..16d9619b58 --- /dev/null +++ b/packages/tiptap-extensions/dist/extensions.common.js @@ -0,0 +1,2859 @@ + + /*! + * tiptap-extensions v1.28.6 + * (c) 2020 Scrumpy UG (limited liability) + * @license MIT + */ + +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } + +var tiptap = require('tiptap'); +var tiptapCommands = require('tiptap-commands'); +var low = _interopDefault(require('lowlight/lib/core')); +var prosemirrorView = require('prosemirror-view'); +var prosemirrorUtils = require('prosemirror-utils'); +var prosemirrorState = require('prosemirror-state'); +var prosemirrorTables = require('prosemirror-tables'); +var tiptapUtils = require('tiptap-utils'); +var prosemirrorTransform = require('prosemirror-transform'); +var prosemirrorCollab = require('prosemirror-collab'); +var prosemirrorHistory = require('prosemirror-history'); + +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 _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 _slicedToArray(arr, i) { + return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); +} + +function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); +} + +function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } +} + +function _arrayWithHoles(arr) { + if (Array.isArray(arr)) return arr; +} + +function _iterableToArray(iter) { + if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); +} + +function _iterableToArrayLimit(arr, i) { + if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { + 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 _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); +} + +function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance"); +} + +var Blockquote = +/*#__PURE__*/ +function (_Node) { + _inherits(Blockquote, _Node); + + function Blockquote() { + _classCallCheck(this, Blockquote); + + return _possibleConstructorReturn(this, _getPrototypeOf(Blockquote).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); + + function BulletList() { + _classCallCheck(this, BulletList); + + return _possibleConstructorReturn(this, _getPrototypeOf(BulletList).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); + + function CodeBlock() { + _classCallCheck(this, CodeBlock); + + return _possibleConstructorReturn(this, _getPrototypeOf(CodeBlock).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({}, 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, state) { + // TODO: find way to cache decorations + // see: https://discuss.prosemirror.net/t/how-to-update-multiple-inline-decorations-on-node-change/1493 + var nodeName = state.selection.$head.parent.type.name; + var previousNodeName = oldState.selection.$head.parent.type.name; + + if (transaction.docChanged && [nodeName, previousNodeName].includes(name)) { + 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); + + function CodeBlockHighlight() { + var _this; + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, CodeBlockHighlight); + + _this = _possibleConstructorReturn(this, _getPrototypeOf(CodeBlockHighlight).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); + + function HardBreak() { + _classCallCheck(this, HardBreak); + + return _possibleConstructorReturn(this, _getPrototypeOf(HardBreak).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); + + function Heading() { + _classCallCheck(this, Heading); + + return _possibleConstructorReturn(this, _getPrototypeOf(Heading).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({}, 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); + + function HorizontalRule() { + _classCallCheck(this, HorizontalRule); + + return _possibleConstructorReturn(this, _getPrototypeOf(HorizontalRule).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); + + function Image() { + _classCallCheck(this, Image); + + return _possibleConstructorReturn(this, _getPrototypeOf(Image).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); + + function ListItem() { + _classCallCheck(this, ListItem); + + return _possibleConstructorReturn(this, _getPrototypeOf(ListItem).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|\\0").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 update(view, prevState) { + var prev = _this.key.getState(prevState); + + var next = _this.key.getState(view.state); // See how the state changed + + + var moved = prev.active && next.active && prev.range.from !== next.range.from; + var started = !prev.active && next.active; + var stopped = prev.active && !next.active; + var changed = !started && !stopped && prev.query !== next.query; + var handleStart = started || moved; + var handleChange = changed && !moved; + var handleExit = stopped || moved; // Cancel when suggestion isn't active + + if (!handleStart && !handleChange && !handleExit) { + return; + } + + var state = handleExit ? prev : next; + var 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 + + var virtualNode = decorationNode ? { + getBoundingClientRect: function getBoundingClientRect() { + return decorationNode.getBoundingClientRect(); + }, + clientWidth: decorationNode.clientWidth, + clientHeight: decorationNode.clientHeight + } : null; + var props = { + view: view, + range: state.range, + query: state.query, + text: state.text, + decorationNode: decorationNode, + virtualNode: virtualNode, + items: onFilter(Array.isArray(items) ? items : items(), state.query), + command: 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); + } + } + }; // Trigger the hooks when necessary + + if (handleExit) { + onExit(props); + } + + if (handleChange) { + onChange(props); + } + + if (handleStart) { + onEnter(props); + } + } + }; + }, + 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 = Object.assign({}, 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); + + function Mention() { + _classCallCheck(this, Mention); + + return _possibleConstructorReturn(this, _getPrototypeOf(Mention).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); + + function OrderedList() { + _classCallCheck(this, OrderedList); + + return _possibleConstructorReturn(this, _getPrototypeOf(OrderedList).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); + + function Table() { + _classCallCheck(this, Table); + + return _possibleConstructorReturn(this, _getPrototypeOf(Table).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); + + function TableHeader() { + _classCallCheck(this, TableHeader); + + return _possibleConstructorReturn(this, _getPrototypeOf(TableHeader).apply(this, arguments)); + } + + _createClass(TableHeader, [{ + key: "name", + get: function get() { + return 'table_header'; + } + }, { + key: "schema", + get: function get() { + return TableNodes.table_header; + } + }]); + + return TableHeader; +}(tiptap.Node); + +var TableCell = +/*#__PURE__*/ +function (_Node) { + _inherits(TableCell, _Node); + + function TableCell() { + _classCallCheck(this, TableCell); + + return _possibleConstructorReturn(this, _getPrototypeOf(TableCell).apply(this, arguments)); + } + + _createClass(TableCell, [{ + key: "name", + get: function get() { + return 'table_cell'; + } + }, { + key: "schema", + get: function get() { + return TableNodes.table_cell; + } + }]); + + return TableCell; +}(tiptap.Node); + +var TableRow = +/*#__PURE__*/ +function (_Node) { + _inherits(TableRow, _Node); + + function TableRow() { + _classCallCheck(this, TableRow); + + return _possibleConstructorReturn(this, _getPrototypeOf(TableRow).apply(this, arguments)); + } + + _createClass(TableRow, [{ + key: "name", + get: function get() { + return 'table_row'; + } + }, { + key: "schema", + get: function get() { + return TableNodes.table_row; + } + }]); + + return TableRow; +}(tiptap.Node); + +var TodoItem = +/*#__PURE__*/ +function (_Node) { + _inherits(TodoItem, _Node); + + function TodoItem() { + _classCallCheck(this, TodoItem); + + return _possibleConstructorReturn(this, _getPrototypeOf(TodoItem).apply(this, arguments)); + } + + _createClass(TodoItem, [{ + key: "keys", + value: function keys(_ref) { + var type = _ref.type; + return { + Enter: tiptapCommands.splitToDefaultListItem(type), + Tab: this.options.nested ? tiptapCommands.sinkListItem(type) : function () {}, + 'Shift-Tab': tiptapCommands.liftListItem(type) + }; + } + }, { + key: "name", + get: function get() { + return 'todo_item'; + } + }, { + key: "defaultOptions", + get: function get() { + return { + nested: false + }; + } + }, { + key: "view", + get: function get() { + return { + props: ['node', 'updateAttrs', 'view'], + methods: { + onChange: function onChange() { + this.updateAttrs({ + done: !this.node.attrs.done + }); + } + }, + template: "\n
  • \n \n
    \n
  • \n " + }; + } + }, { + key: "schema", + get: function get() { + var _this = this; + + return { + attrs: { + done: { + default: false + } + }, + draggable: true, + content: this.options.nested ? '(paragraph|todo_list)+' : 'paragraph+', + toDOM: function toDOM(node) { + var done = node.attrs.done; + return ['li', { + 'data-type': _this.name, + 'data-done': done.toString() + }, ['span', { + class: 'todo-checkbox', + contenteditable: 'false' + }], ['div', { + class: 'todo-content' + }, 0]]; + }, + parseDOM: [{ + priority: 51, + tag: "[data-type=\"".concat(this.name, "\"]"), + getAttrs: function getAttrs(dom) { + return { + done: dom.getAttribute('data-done') === 'true' + }; + } + }] + }; + } + }]); + + return TodoItem; +}(tiptap.Node); + +var TodoList = +/*#__PURE__*/ +function (_Node) { + _inherits(TodoList, _Node); + + function TodoList() { + _classCallCheck(this, TodoList); + + return _possibleConstructorReturn(this, _getPrototypeOf(TodoList).apply(this, arguments)); + } + + _createClass(TodoList, [{ + key: "commands", + value: function commands(_ref) { + var type = _ref.type, + schema = _ref.schema; + return function () { + return tiptapCommands.toggleList(type, schema.nodes.todo_item); + }; + } + }, { + key: "inputRules", + value: function inputRules(_ref2) { + var type = _ref2.type; + return [tiptapCommands.wrappingInputRule(/^\s*(\[ \])\s$/, type)]; + } + }, { + key: "name", + get: function get() { + return 'todo_list'; + } + }, { + key: "schema", + get: function get() { + var _this = this; + + return { + group: 'block', + content: 'todo_item+', + toDOM: function toDOM() { + return ['ul', { + 'data-type': _this.name + }, 0]; + }, + parseDOM: [{ + priority: 51, + tag: "[data-type=\"".concat(this.name, "\"]") + }] + }; + } + }]); + + return TodoList; +}(tiptap.Node); + +var Bold = +/*#__PURE__*/ +function (_Mark) { + _inherits(Bold, _Mark); + + function Bold() { + _classCallCheck(this, Bold); + + return _possibleConstructorReturn(this, _getPrototypeOf(Bold).apply(this, arguments)); + } + + _createClass(Bold, [{ + key: "keys", + value: function keys(_ref) { + var type = _ref.type; + return { + 'Mod-b': tiptapCommands.toggleMark(type) + }; + } + }, { + key: "commands", + value: function commands(_ref2) { + var type = _ref2.type; + return function () { + return tiptapCommands.toggleMark(type); + }; + } + }, { + key: "inputRules", + value: function inputRules(_ref3) { + var type = _ref3.type; + return [tiptapCommands.markInputRule(/(?:\*\*|__)([^*_]+)(?:\*\*|__)$/, type)]; + } + }, { + key: "pasteRules", + value: function pasteRules(_ref4) { + var type = _ref4.type; + return [tiptapCommands.markPasteRule(/(?:\*\*|__)([^*_]+)(?:\*\*|__)/g, type)]; + } + }, { + key: "name", + get: function get() { + return 'bold'; + } + }, { + key: "schema", + get: function get() { + return { + parseDOM: [{ + tag: 'strong' + }, { + tag: 'b', + getAttrs: function getAttrs(node) { + return node.style.fontWeight !== 'normal' && null; + } + }, { + style: 'font-weight', + getAttrs: function getAttrs(value) { + return /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null; + } + }], + toDOM: function toDOM() { + return ['strong', 0]; + } + }; + } + }]); + + return Bold; +}(tiptap.Mark); + +var Code = +/*#__PURE__*/ +function (_Mark) { + _inherits(Code, _Mark); + + function Code() { + _classCallCheck(this, Code); + + return _possibleConstructorReturn(this, _getPrototypeOf(Code).apply(this, arguments)); + } + + _createClass(Code, [{ + key: "keys", + value: function keys(_ref) { + var type = _ref.type; + return { + 'Mod-`': tiptapCommands.toggleMark(type) + }; + } + }, { + key: "commands", + value: function commands(_ref2) { + var type = _ref2.type; + return function () { + return tiptapCommands.toggleMark(type); + }; + } + }, { + key: "inputRules", + value: function inputRules(_ref3) { + var type = _ref3.type; + return [tiptapCommands.markInputRule(/(?:`)([^`]+)(?:`)$/, type)]; + } + }, { + key: "pasteRules", + value: function pasteRules(_ref4) { + var type = _ref4.type; + return [tiptapCommands.markPasteRule(/(?:`)([^`]+)(?:`)/g, type)]; + } + }, { + key: "name", + get: function get() { + return 'code'; + } + }, { + key: "schema", + get: function get() { + return { + excludes: '_', + parseDOM: [{ + tag: 'code' + }], + toDOM: function toDOM() { + return ['code', 0]; + } + }; + } + }]); + + return Code; +}(tiptap.Mark); + +var Italic = +/*#__PURE__*/ +function (_Mark) { + _inherits(Italic, _Mark); + + function Italic() { + _classCallCheck(this, Italic); + + return _possibleConstructorReturn(this, _getPrototypeOf(Italic).apply(this, arguments)); + } + + _createClass(Italic, [{ + key: "keys", + value: function keys(_ref) { + var type = _ref.type; + return { + 'Mod-i': tiptapCommands.toggleMark(type) + }; + } + }, { + key: "commands", + value: function commands(_ref2) { + var type = _ref2.type; + return function () { + return tiptapCommands.toggleMark(type); + }; + } + }, { + key: "inputRules", + value: function inputRules(_ref3) { + var type = _ref3.type; + return [tiptapCommands.markInputRule(/(?:^|[^_])(_([^_]+)_)$/, type), tiptapCommands.markInputRule(/(?:^|[^*])(\*([^*]+)\*)$/, type)]; + } + }, { + key: "pasteRules", + value: function pasteRules(_ref4) { + var type = _ref4.type; + return [tiptapCommands.markPasteRule(/_([^_]+)_/g, type), tiptapCommands.markPasteRule(/\*([^*]+)\*/g, type)]; + } + }, { + key: "name", + get: function get() { + return 'italic'; + } + }, { + key: "schema", + get: function get() { + return { + parseDOM: [{ + tag: 'i' + }, { + tag: 'em' + }, { + style: 'font-style=italic' + }], + toDOM: function toDOM() { + return ['em', 0]; + } + }; + } + }]); + + return Italic; +}(tiptap.Mark); + +var Link = +/*#__PURE__*/ +function (_Mark) { + _inherits(Link, _Mark); + + function Link() { + _classCallCheck(this, Link); + + return _possibleConstructorReturn(this, _getPrototypeOf(Link).apply(this, arguments)); + } + + _createClass(Link, [{ + key: "commands", + value: function commands(_ref) { + var type = _ref.type; + return function (attrs) { + if (attrs.href) { + return tiptapCommands.updateMark(type, attrs); + } + + return tiptapCommands.removeMark(type); + }; + } + }, { + key: "pasteRules", + value: function pasteRules(_ref2) { + var type = _ref2.type; + return [tiptapCommands.pasteRule(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-zA-Z]{2,}\b([-a-zA-Z0-9@:%_+.~#?&//=]*)/g, type, function (url) { + return { + href: url + }; + })]; + } + }, { + key: "name", + get: function get() { + return 'link'; + } + }, { + key: "defaultOptions", + get: function get() { + return { + openOnClick: true + }; + } + }, { + key: "schema", + get: function get() { + return { + attrs: { + href: { + default: null + } + }, + inclusive: false, + parseDOM: [{ + tag: 'a[href]', + getAttrs: function getAttrs(dom) { + return { + href: dom.getAttribute('href') + }; + } + }], + toDOM: function toDOM(node) { + return ['a', _objectSpread2({}, node.attrs, { + rel: 'noopener noreferrer nofollow' + }), 0]; + } + }; + } + }, { + key: "plugins", + get: function get() { + if (!this.options.openOnClick) { + return []; + } + + return [new tiptap.Plugin({ + props: { + handleClick: function handleClick(view, pos, event) { + var schema = view.state.schema; + var attrs = tiptapUtils.getMarkAttrs(view.state, schema.marks.link); + + if (attrs.href && event.target instanceof HTMLAnchorElement) { + event.stopPropagation(); + window.open(attrs.href); + } + } + } + })]; + } + }]); + + return Link; +}(tiptap.Mark); + +var Strike = +/*#__PURE__*/ +function (_Mark) { + _inherits(Strike, _Mark); + + function Strike() { + _classCallCheck(this, Strike); + + return _possibleConstructorReturn(this, _getPrototypeOf(Strike).apply(this, arguments)); + } + + _createClass(Strike, [{ + key: "keys", + value: function keys(_ref) { + var type = _ref.type; + return { + 'Mod-d': tiptapCommands.toggleMark(type) + }; + } + }, { + key: "commands", + value: function commands(_ref2) { + var type = _ref2.type; + return function () { + return tiptapCommands.toggleMark(type); + }; + } + }, { + key: "inputRules", + value: function inputRules(_ref3) { + var type = _ref3.type; + return [tiptapCommands.markInputRule(/~([^~]+)~$/, type)]; + } + }, { + key: "pasteRules", + value: function pasteRules(_ref4) { + var type = _ref4.type; + return [tiptapCommands.markPasteRule(/~([^~]+)~/g, type)]; + } + }, { + key: "name", + get: function get() { + return 'strike'; + } + }, { + key: "schema", + get: function get() { + return { + parseDOM: [{ + tag: 's' + }, { + tag: 'del' + }, { + tag: 'strike' + }, { + style: 'text-decoration', + getAttrs: function getAttrs(value) { + return value === 'line-through'; + } + }], + toDOM: function toDOM() { + return ['s', 0]; + } + }; + } + }]); + + return Strike; +}(tiptap.Mark); + +var Underline = +/*#__PURE__*/ +function (_Mark) { + _inherits(Underline, _Mark); + + function Underline() { + _classCallCheck(this, Underline); + + return _possibleConstructorReturn(this, _getPrototypeOf(Underline).apply(this, arguments)); + } + + _createClass(Underline, [{ + key: "keys", + value: function keys(_ref) { + var type = _ref.type; + return { + 'Mod-u': tiptapCommands.toggleMark(type) + }; + } + }, { + key: "commands", + value: function commands(_ref2) { + var type = _ref2.type; + return function () { + return tiptapCommands.toggleMark(type); + }; + } + }, { + key: "name", + get: function get() { + return 'underline'; + } + }, { + key: "schema", + get: function get() { + return { + parseDOM: [{ + tag: 'u' + }, { + style: 'text-decoration', + getAttrs: function getAttrs(value) { + return value === 'underline'; + } + }], + toDOM: function toDOM() { + return ['u', 0]; + } + }; + } + }]); + + return Underline; +}(tiptap.Mark); + +var Collaboration = +/*#__PURE__*/ +function (_Extension) { + _inherits(Collaboration, _Extension); + + function Collaboration() { + _classCallCheck(this, Collaboration); + + return _possibleConstructorReturn(this, _getPrototypeOf(Collaboration).apply(this, arguments)); + } + + _createClass(Collaboration, [{ + key: "init", + value: function init() { + var _this = this; + + this.getSendableSteps = this.debounce(function (state) { + var sendable = prosemirrorCollab.sendableSteps(state); + + if (sendable) { + _this.options.onSendable({ + editor: _this.editor, + sendable: { + version: sendable.version, + steps: sendable.steps.map(function (step) { + return step.toJSON(); + }), + clientID: sendable.clientID + } + }); + } + }, this.options.debounce); + this.editor.on('transaction', function (_ref) { + var state = _ref.state; + + _this.getSendableSteps(state); + }); + } + }, { + key: "debounce", + value: function debounce(fn, delay) { + var timeout; + return function () { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + if (timeout) { + clearTimeout(timeout); + } + + timeout = setTimeout(function () { + fn.apply(void 0, args); + timeout = null; + }, delay); + }; + } + }, { + key: "name", + get: function get() { + return 'collaboration'; + } + }, { + key: "defaultOptions", + get: function get() { + var _this2 = this; + + return { + version: 0, + clientID: Math.floor(Math.random() * 0xFFFFFFFF), + debounce: 250, + onSendable: function onSendable() {}, + update: function update(_ref2) { + var steps = _ref2.steps, + version = _ref2.version; + var _this2$editor = _this2.editor, + state = _this2$editor.state, + view = _this2$editor.view, + schema = _this2$editor.schema; + + if (prosemirrorCollab.getVersion(state) > version) { + return; + } + + view.dispatch(prosemirrorCollab.receiveTransaction(state, steps.map(function (item) { + return prosemirrorTransform.Step.fromJSON(schema, item.step); + }), steps.map(function (item) { + return item.clientID; + }))); + } + }; + } + }, { + key: "plugins", + get: function get() { + return [prosemirrorCollab.collab({ + version: this.options.version, + clientID: this.options.clientID + })]; + } + }]); + + return Collaboration; +}(tiptap.Extension); + +var Focus = +/*#__PURE__*/ +function (_Extension) { + _inherits(Focus, _Extension); + + function Focus() { + _classCallCheck(this, Focus); + + return _possibleConstructorReturn(this, _getPrototypeOf(Focus).apply(this, arguments)); + } + + _createClass(Focus, [{ + key: "name", + get: function get() { + return 'focus'; + } + }, { + key: "defaultOptions", + get: function get() { + return { + className: 'has-focus', + nested: false + }; + } + }, { + key: "plugins", + get: function get() { + var _this = this; + + return [new tiptap.Plugin({ + props: { + decorations: function decorations(_ref) { + var doc = _ref.doc, + plugins = _ref.plugins, + selection = _ref.selection; + var editablePlugin = plugins.find(function (plugin) { + return plugin.key.startsWith('editable$'); + }); + var editable = editablePlugin.props.editable(); + var active = editable && _this.options.className; + var focused = _this.editor.focused; + var anchor = selection.anchor; + var decorations = []; + + if (!active || !focused) { + return false; + } + + doc.descendants(function (node, pos) { + var hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize; + + if (hasAnchor && !node.isText) { + var decoration = prosemirrorView.Decoration.node(pos, pos + node.nodeSize, { + class: _this.options.className + }); + decorations.push(decoration); + } + + return _this.options.nested; + }); + return prosemirrorView.DecorationSet.create(doc, decorations); + } + } + })]; + } + }]); + + return Focus; +}(tiptap.Extension); + +var History = +/*#__PURE__*/ +function (_Extension) { + _inherits(History, _Extension); + + function History() { + _classCallCheck(this, History); + + return _possibleConstructorReturn(this, _getPrototypeOf(History).apply(this, arguments)); + } + + _createClass(History, [{ + key: "keys", + value: function keys() { + var keymap = { + 'Mod-z': prosemirrorHistory.undo, + 'Mod-y': prosemirrorHistory.redo, + 'Shift-Mod-z': prosemirrorHistory.redo + }; + return keymap; + } + }, { + key: "commands", + value: function commands() { + return { + undo: function undo() { + return prosemirrorHistory.undo; + }, + redo: function redo() { + return prosemirrorHistory.redo; + }, + undoDepth: function undoDepth() { + return prosemirrorHistory.undoDepth; + }, + redoDepth: function redoDepth() { + return prosemirrorHistory.redoDepth; + } + }; + } + }, { + key: "name", + get: function get() { + return 'history'; + } + }, { + key: "defaultOptions", + get: function get() { + return { + depth: '', + newGroupDelay: '' + }; + } + }, { + key: "plugins", + get: function get() { + return [prosemirrorHistory.history({ + depth: this.options.depth, + newGroupDelay: this.options.newGroupDelay + })]; + } + }]); + + return History; +}(tiptap.Extension); + +var Placeholder = +/*#__PURE__*/ +function (_Extension) { + _inherits(Placeholder, _Extension); + + function Placeholder() { + _classCallCheck(this, Placeholder); + + return _possibleConstructorReturn(this, _getPrototypeOf(Placeholder).apply(this, arguments)); + } + + _createClass(Placeholder, [{ + key: "name", + get: function get() { + return 'placeholder'; + } + }, { + key: "defaultOptions", + get: function get() { + return { + emptyEditorClass: 'is-editor-empty', + emptyNodeClass: 'is-empty', + emptyNodeText: 'Write something …', + showOnlyWhenEditable: true, + showOnlyCurrent: true + }; + } + }, { + key: "update", + get: function get() { + return function (view) { + view.updateState(view.state); + }; + } + }, { + key: "plugins", + get: function get() { + var _this = this; + + return [new tiptap.Plugin({ + props: { + decorations: function decorations(_ref) { + var doc = _ref.doc, + plugins = _ref.plugins, + selection = _ref.selection; + var editablePlugin = plugins.find(function (plugin) { + return plugin.key.startsWith('editable$'); + }); + var editable = editablePlugin.props.editable(); + var active = editable || !_this.options.showOnlyWhenEditable; + var anchor = selection.anchor; + var decorations = []; + var isEditorEmpty = doc.textContent.length === 0; + + if (!active) { + return false; + } + + doc.descendants(function (node, pos) { + var hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize; + var isNodeEmpty = node.content.size === 0; + + if ((hasAnchor || !_this.options.showOnlyCurrent) && isNodeEmpty) { + var classes = [_this.options.emptyNodeClass]; + + if (isEditorEmpty) { + classes.push(_this.options.emptyEditorClass); + } + + var decoration = prosemirrorView.Decoration.node(pos, pos + node.nodeSize, { + class: classes.join(' '), + 'data-empty-text': typeof _this.options.emptyNodeText === 'function' ? _this.options.emptyNodeText(node) : _this.options.emptyNodeText + }); + decorations.push(decoration); + } + + return false; + }); + return prosemirrorView.DecorationSet.create(doc, decorations); + } + } + })]; + } + }]); + + return Placeholder; +}(tiptap.Extension); + +var Search = +/*#__PURE__*/ +function (_Extension) { + _inherits(Search, _Extension); + + function Search() { + var _this; + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, Search); + + _this = _possibleConstructorReturn(this, _getPrototypeOf(Search).call(this, options)); + _this.results = []; + _this.searchTerm = null; + _this._updating = false; + return _this; + } + + _createClass(Search, [{ + key: "commands", + value: function commands() { + var _this2 = this; + + return { + find: function find(attrs) { + return _this2.find(attrs); + }, + replace: function replace(attrs) { + return _this2.replace(attrs); + }, + replaceAll: function replaceAll(attrs) { + return _this2.replaceAll(attrs); + }, + clearSearch: function clearSearch() { + return _this2.clear(); + } + }; + } + }, { + key: "_search", + value: function _search(doc) { + var _this3 = this; + + this.results = []; + var mergedTextNodes = []; + var index = 0; + + if (!this.searchTerm) { + return; + } + + doc.descendants(function (node, pos) { + if (node.isText) { + if (mergedTextNodes[index]) { + mergedTextNodes[index] = { + text: mergedTextNodes[index].text + node.text, + pos: mergedTextNodes[index].pos + }; + } else { + mergedTextNodes[index] = { + text: node.text, + pos: pos + }; + } + } else { + index += 1; + } + }); + mergedTextNodes.forEach(function (_ref) { + var text = _ref.text, + pos = _ref.pos; + var search = _this3.findRegExp; + var m; // eslint-disable-next-line no-cond-assign + + while (m = search.exec(text)) { + if (m[0] === '') { + break; + } + + _this3.results.push({ + from: pos + m.index, + to: pos + m.index + m[0].length + }); + } + }); + } + }, { + key: "replace", + value: function replace(_replace) { + var _this4 = this; + + return function (state, dispatch) { + var firstResult = _this4.results[0]; + + if (!firstResult) { + return; + } + + var _this4$results$ = _this4.results[0], + from = _this4$results$.from, + to = _this4$results$.to; + dispatch(state.tr.insertText(_replace, from, to)); + + _this4.editor.commands.find(_this4.searchTerm); + }; + } + }, { + key: "rebaseNextResult", + value: function rebaseNextResult(replace, index) { + var lastOffset = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + var nextIndex = index + 1; + + if (!this.results[nextIndex]) { + return null; + } + + var _this$results$index = this.results[index], + currentFrom = _this$results$index.from, + currentTo = _this$results$index.to; + var offset = currentTo - currentFrom - replace.length + lastOffset; + var _this$results$nextInd = this.results[nextIndex], + from = _this$results$nextInd.from, + to = _this$results$nextInd.to; + this.results[nextIndex] = { + to: to - offset, + from: from - offset + }; + return offset; + } + }, { + key: "replaceAll", + value: function replaceAll(replace) { + var _this5 = this; + + return function (_ref2, dispatch) { + var tr = _ref2.tr; + var offset; + + if (!_this5.results.length) { + return; + } + + _this5.results.forEach(function (_ref3, index) { + var from = _ref3.from, + to = _ref3.to; + tr.insertText(replace, from, to); + offset = _this5.rebaseNextResult(replace, index, offset); + }); + + dispatch(tr); + + _this5.editor.commands.find(_this5.searchTerm); + }; + } + }, { + key: "find", + value: function find(searchTerm) { + var _this6 = this; + + return function (state, dispatch) { + _this6.searchTerm = _this6.options.disableRegex ? searchTerm.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&') : searchTerm; + + _this6.updateView(state, dispatch); + }; + } + }, { + key: "clear", + value: function clear() { + var _this7 = this; + + return function (state, dispatch) { + _this7.searchTerm = null; + + _this7.updateView(state, dispatch); + }; + } + }, { + key: "updateView", + value: function updateView(_ref4, dispatch) { + var tr = _ref4.tr; + this._updating = true; + dispatch(tr); + this._updating = false; + } + }, { + key: "createDeco", + value: function createDeco(doc) { + this._search(doc); + + return this.decorations ? prosemirrorView.DecorationSet.create(doc, this.decorations) : []; + } + }, { + key: "name", + get: function get() { + return 'search'; + } + }, { + key: "defaultOptions", + get: function get() { + return { + autoSelectNext: true, + findClass: 'find', + searching: false, + caseSensitive: false, + disableRegex: true, + alwaysSearch: false + }; + } + }, { + key: "findRegExp", + get: function get() { + return RegExp(this.searchTerm, !this.options.caseSensitive ? 'gui' : 'gu'); + } + }, { + key: "decorations", + get: function get() { + var _this8 = this; + + return this.results.map(function (deco) { + return prosemirrorView.Decoration.inline(deco.from, deco.to, { + class: _this8.options.findClass + }); + }); + } + }, { + key: "plugins", + get: function get() { + var _this9 = this; + + return [new tiptap.Plugin({ + state: { + init: function init() { + return prosemirrorView.DecorationSet.empty; + }, + apply: function apply(tr, old) { + if (_this9._updating || _this9.options.searching || tr.docChanged && _this9.options.alwaysSearch) { + return _this9.createDeco(tr.doc); + } + + if (tr.docChanged) { + return old.map(tr.mapping, tr.doc); + } + + return old; + } + }, + props: { + decorations: function decorations(state) { + return this.getState(state); + } + } + })]; + } + }]); + + return Search; +}(tiptap.Extension); + +var TrailingNode = +/*#__PURE__*/ +function (_Extension) { + _inherits(TrailingNode, _Extension); + + function TrailingNode() { + _classCallCheck(this, TrailingNode); + + return _possibleConstructorReturn(this, _getPrototypeOf(TrailingNode).apply(this, arguments)); + } + + _createClass(TrailingNode, [{ + key: "name", + get: function get() { + return 'trailing_node'; + } + }, { + key: "defaultOptions", + get: function get() { + return { + node: 'paragraph', + notAfter: ['paragraph'] + }; + } + }, { + key: "plugins", + get: function get() { + var _this = this; + + var plugin = new tiptap.PluginKey(this.name); + var disabledNodes = Object.entries(this.editor.schema.nodes).map(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2), + value = _ref2[1]; + + return value; + }).filter(function (node) { + return _this.options.notAfter.includes(node.name); + }); + return [new tiptap.Plugin({ + key: plugin, + view: function view() { + return { + update: function update(view) { + var state = view.state; + var insertNodeAtEnd = plugin.getState(state); + + if (!insertNodeAtEnd) { + return; + } + + var doc = state.doc, + schema = state.schema, + tr = state.tr; + var type = schema.nodes[_this.options.node]; + var transaction = tr.insert(doc.content.size, type.create()); + view.dispatch(transaction); + } + }; + }, + state: { + init: function init(_, state) { + var lastNode = state.tr.doc.lastChild; + return !tiptapUtils.nodeEqualsType({ + node: lastNode, + types: disabledNodes + }); + }, + apply: function apply(tr, value) { + if (!tr.docChanged) { + return value; + } + + var lastNode = tr.doc.lastChild; + return !tiptapUtils.nodeEqualsType({ + node: lastNode, + types: disabledNodes + }); + } + } + })]; + } + }]); + + return TrailingNode; +}(tiptap.Extension); + +exports.Blockquote = Blockquote; +exports.Bold = Bold; +exports.BulletList = BulletList; +exports.Code = Code; +exports.CodeBlock = CodeBlock; +exports.CodeBlockHighlight = CodeBlockHighlight; +exports.Collaboration = Collaboration; +exports.Focus = Focus; +exports.HardBreak = HardBreak; +exports.Heading = Heading; +exports.Highlight = HighlightPlugin; +exports.History = History; +exports.HorizontalRule = HorizontalRule; +exports.Image = Image; +exports.Italic = Italic; +exports.Link = Link; +exports.ListItem = ListItem; +exports.Mention = Mention; +exports.OrderedList = OrderedList; +exports.Placeholder = Placeholder; +exports.Search = Search; +exports.Strike = Strike; +exports.Suggestions = SuggestionsPlugin; +exports.Table = Table; +exports.TableCell = TableCell; +exports.TableHeader = TableHeader; +exports.TableRow = TableRow; +exports.TodoItem = TodoItem; +exports.TodoList = TodoList; +exports.TrailingNode = TrailingNode; +exports.Underline = Underline; diff --git a/packages/tiptap-extensions/dist/extensions.esm.js b/packages/tiptap-extensions/dist/extensions.esm.js new file mode 100644 index 0000000000..dddce17eb4 --- /dev/null +++ b/packages/tiptap-extensions/dist/extensions.esm.js @@ -0,0 +1,2823 @@ + + /*! + * tiptap-extensions v1.28.6 + * (c) 2020 Scrumpy UG (limited liability) + * @license MIT + */ + +import { Node, Plugin, PluginKey, Mark, Extension } from 'tiptap'; +import { toggleWrap, wrappingInputRule, toggleList, toggleBlockType, setBlockType, textblockTypeInputRule, chainCommands, exitCode, nodeInputRule, splitListItem, sinkListItem, liftListItem, insertText, replaceText, splitToDefaultListItem, toggleMark, markInputRule, markPasteRule, updateMark, removeMark, pasteRule } from 'tiptap-commands'; +import low from 'lowlight/lib/core'; +import { DecorationSet, Decoration } from 'prosemirror-view'; +import { findBlockNodes, createTable } from 'prosemirror-utils'; +import { Plugin as Plugin$1, PluginKey as PluginKey$1, TextSelection } from 'prosemirror-state'; +import { tableNodes, addColumnBefore, addColumnAfter, deleteColumn, addRowBefore, addRowAfter, deleteRow, deleteTable, mergeCells, splitCell, toggleHeaderColumn, toggleHeaderRow, toggleHeaderCell, setCellAttr, fixTables, goToNextCell, columnResizing, tableEditing } from 'prosemirror-tables'; +import { getMarkAttrs, nodeEqualsType } from 'tiptap-utils'; +import { Step } from 'prosemirror-transform'; +import { sendableSteps, getVersion, receiveTransaction, collab } from 'prosemirror-collab'; +import { undo, redo, undoDepth, redoDepth, history } from 'prosemirror-history'; + +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 _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 _slicedToArray(arr, i) { + return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); +} + +function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); +} + +function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } +} + +function _arrayWithHoles(arr) { + if (Array.isArray(arr)) return arr; +} + +function _iterableToArray(iter) { + if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); +} + +function _iterableToArrayLimit(arr, i) { + if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { + 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 _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); +} + +function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance"); +} + +var Blockquote = +/*#__PURE__*/ +function (_Node) { + _inherits(Blockquote, _Node); + + function Blockquote() { + _classCallCheck(this, Blockquote); + + return _possibleConstructorReturn(this, _getPrototypeOf(Blockquote).apply(this, arguments)); + } + + _createClass(Blockquote, [{ + key: "commands", + value: function commands(_ref) { + var type = _ref.type, + schema = _ref.schema; + return function () { + return toggleWrap(type, schema.nodes.paragraph); + }; + } + }, { + key: "keys", + value: function keys(_ref2) { + var type = _ref2.type; + return { + 'Ctrl->': toggleWrap(type) + }; + } + }, { + key: "inputRules", + value: function inputRules(_ref3) { + var type = _ref3.type; + return [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; +}(Node); + +var BulletList = +/*#__PURE__*/ +function (_Node) { + _inherits(BulletList, _Node); + + function BulletList() { + _classCallCheck(this, BulletList); + + return _possibleConstructorReturn(this, _getPrototypeOf(BulletList).apply(this, arguments)); + } + + _createClass(BulletList, [{ + key: "commands", + value: function commands(_ref) { + var type = _ref.type, + schema = _ref.schema; + return function () { + return toggleList(type, schema.nodes.list_item); + }; + } + }, { + key: "keys", + value: function keys(_ref2) { + var type = _ref2.type, + schema = _ref2.schema; + return { + 'Shift-Ctrl-8': toggleList(type, schema.nodes.list_item) + }; + } + }, { + key: "inputRules", + value: function inputRules(_ref3) { + var type = _ref3.type; + return [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; +}(Node); + +var CodeBlock = +/*#__PURE__*/ +function (_Node) { + _inherits(CodeBlock, _Node); + + function CodeBlock() { + _classCallCheck(this, CodeBlock); + + return _possibleConstructorReturn(this, _getPrototypeOf(CodeBlock).apply(this, arguments)); + } + + _createClass(CodeBlock, [{ + key: "commands", + value: function commands(_ref) { + var type = _ref.type, + schema = _ref.schema; + return function () { + return toggleBlockType(type, schema.nodes.paragraph); + }; + } + }, { + key: "keys", + value: function keys(_ref2) { + var type = _ref2.type; + return { + 'Shift-Ctrl-\\': setBlockType(type) + }; + } + }, { + key: "inputRules", + value: function inputRules(_ref3) { + var type = _ref3.type; + return [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; +}(Node); + +function getDecorations(_ref) { + var doc = _ref.doc, + name = _ref.name; + var decorations = []; + var blocks = 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({}, node, { + from: from, + to: to + }); + }).forEach(function (node) { + var decoration = Decoration.inline(node.from, node.to, { + class: node.classes.join(' ') + }); + decorations.push(decoration); + }); + }); + return DecorationSet.create(doc, decorations); +} + +function HighlightPlugin(_ref2) { + var name = _ref2.name; + return new Plugin({ + name: new PluginKey('highlight'), + state: { + init: function init(_, _ref3) { + var doc = _ref3.doc; + return getDecorations({ + doc: doc, + name: name + }); + }, + apply: function apply(transaction, decorationSet, oldState, state) { + // TODO: find way to cache decorations + // see: https://discuss.prosemirror.net/t/how-to-update-multiple-inline-decorations-on-node-change/1493 + var nodeName = state.selection.$head.parent.type.name; + var previousNodeName = oldState.selection.$head.parent.type.name; + + if (transaction.docChanged && [nodeName, previousNodeName].includes(name)) { + 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); + + function CodeBlockHighlight() { + var _this; + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, CodeBlockHighlight); + + _this = _possibleConstructorReturn(this, _getPrototypeOf(CodeBlockHighlight).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 toggleBlockType(type, schema.nodes.paragraph); + }; + } + }, { + key: "keys", + value: function keys(_ref4) { + var type = _ref4.type; + return { + 'Shift-Ctrl-\\': setBlockType(type) + }; + } + }, { + key: "inputRules", + value: function inputRules(_ref5) { + var type = _ref5.type; + return [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; +}(Node); + +var HardBreak = +/*#__PURE__*/ +function (_Node) { + _inherits(HardBreak, _Node); + + function HardBreak() { + _classCallCheck(this, HardBreak); + + return _possibleConstructorReturn(this, _getPrototypeOf(HardBreak).apply(this, arguments)); + } + + _createClass(HardBreak, [{ + key: "keys", + value: function keys(_ref) { + var type = _ref.type; + var command = chainCommands(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; +}(Node); + +var Heading = +/*#__PURE__*/ +function (_Node) { + _inherits(Heading, _Node); + + function Heading() { + _classCallCheck(this, Heading); + + return _possibleConstructorReturn(this, _getPrototypeOf(Heading).apply(this, arguments)); + } + + _createClass(Heading, [{ + key: "commands", + value: function commands(_ref) { + var type = _ref.type, + schema = _ref.schema; + return function (attrs) { + return 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({}, items, {}, _defineProperty({}, "Shift-Ctrl-".concat(level), setBlockType(type, { + level: level + }))); + }, {}); + } + }, { + key: "inputRules", + value: function inputRules(_ref3) { + var type = _ref3.type; + return this.options.levels.map(function (level) { + return 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; +}(Node); + +var HorizontalRule = +/*#__PURE__*/ +function (_Node) { + _inherits(HorizontalRule, _Node); + + function HorizontalRule() { + _classCallCheck(this, HorizontalRule); + + return _possibleConstructorReturn(this, _getPrototypeOf(HorizontalRule).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 [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; +}(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); + + function Image() { + _classCallCheck(this, Image); + + return _possibleConstructorReturn(this, _getPrototypeOf(Image).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 [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 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; +}(Node); + +var ListItem = +/*#__PURE__*/ +function (_Node) { + _inherits(ListItem, _Node); + + function ListItem() { + _classCallCheck(this, ListItem); + + return _possibleConstructorReturn(this, _getPrototypeOf(ListItem).apply(this, arguments)); + } + + _createClass(ListItem, [{ + key: "keys", + value: function keys(_ref) { + var type = _ref.type; + return { + Enter: splitListItem(type), + Tab: sinkListItem(type), + 'Shift-Tab': 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; +}(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|\\0").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 Plugin$1({ + key: new PluginKey$1('suggestions'), + view: function view() { + var _this = this; + + return { + update: function update(view, prevState) { + var prev = _this.key.getState(prevState); + + var next = _this.key.getState(view.state); // See how the state changed + + + var moved = prev.active && next.active && prev.range.from !== next.range.from; + var started = !prev.active && next.active; + var stopped = prev.active && !next.active; + var changed = !started && !stopped && prev.query !== next.query; + var handleStart = started || moved; + var handleChange = changed && !moved; + var handleExit = stopped || moved; // Cancel when suggestion isn't active + + if (!handleStart && !handleChange && !handleExit) { + return; + } + + var state = handleExit ? prev : next; + var 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 + + var virtualNode = decorationNode ? { + getBoundingClientRect: function getBoundingClientRect() { + return decorationNode.getBoundingClientRect(); + }, + clientWidth: decorationNode.clientWidth, + clientHeight: decorationNode.clientHeight + } : null; + var props = { + view: view, + range: state.range, + query: state.query, + text: state.text, + decorationNode: decorationNode, + virtualNode: virtualNode, + items: onFilter(Array.isArray(items) ? items : items(), state.query), + command: 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) { + insertText(appendText)(view.state, view.dispatch, view); + } + } + }; // Trigger the hooks when necessary + + if (handleExit) { + onExit(props); + } + + if (handleChange) { + onChange(props); + } + + if (handleStart) { + onEnter(props); + } + } + }; + }, + 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 = Object.assign({}, 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 DecorationSet.create(editorState.doc, [Decoration.inline(range.from, range.to, { + nodeName: 'span', + class: suggestionClass, + 'data-decoration-id': decorationId + })]); + } + } + }); +} + +var Mention = +/*#__PURE__*/ +function (_Node) { + _inherits(Mention, _Node); + + function Mention() { + _classCallCheck(this, Mention); + + return _possibleConstructorReturn(this, _getPrototypeOf(Mention).apply(this, arguments)); + } + + _createClass(Mention, [{ + key: "commands", + value: function commands(_ref) { + var _this = this; + + var schema = _ref.schema; + return function (attrs) { + return 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 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; +}(Node); + +var OrderedList = +/*#__PURE__*/ +function (_Node) { + _inherits(OrderedList, _Node); + + function OrderedList() { + _classCallCheck(this, OrderedList); + + return _possibleConstructorReturn(this, _getPrototypeOf(OrderedList).apply(this, arguments)); + } + + _createClass(OrderedList, [{ + key: "commands", + value: function commands(_ref) { + var type = _ref.type, + schema = _ref.schema; + return function () { + return toggleList(type, schema.nodes.list_item); + }; + } + }, { + key: "keys", + value: function keys(_ref2) { + var type = _ref2.type, + schema = _ref2.schema; + return { + 'Shift-Ctrl-9': toggleList(type, schema.nodes.list_item) + }; + } + }, { + key: "inputRules", + value: function inputRules(_ref3) { + var type = _ref3.type; + return [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; +}(Node); + +var TableNodes = 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); + + function Table() { + _classCallCheck(this, Table); + + return _possibleConstructorReturn(this, _getPrototypeOf(Table).apply(this, arguments)); + } + + _createClass(Table, [{ + key: "commands", + value: function commands(_ref) { + var schema = _ref.schema; + return { + createTable: function createTable$1(_ref2) { + var rowsCount = _ref2.rowsCount, + colsCount = _ref2.colsCount, + withHeaderRow = _ref2.withHeaderRow; + return function (state, dispatch) { + var offset = state.tr.selection.anchor + 1; + + var nodes = createTable(schema, rowsCount, colsCount, withHeaderRow); + + var tr = state.tr.replaceSelectionWith(nodes).scrollIntoView(); + var resolvedPos = tr.doc.resolve(offset); + tr.setSelection(TextSelection.near(resolvedPos)); + dispatch(tr); + }; + }, + addColumnBefore: function addColumnBefore$1() { + return addColumnBefore; + }, + addColumnAfter: function addColumnAfter$1() { + return addColumnAfter; + }, + deleteColumn: function deleteColumn$1() { + return deleteColumn; + }, + addRowBefore: function addRowBefore$1() { + return addRowBefore; + }, + addRowAfter: function addRowAfter$1() { + return addRowAfter; + }, + deleteRow: function deleteRow$1() { + return deleteRow; + }, + deleteTable: function deleteTable$1() { + return deleteTable; + }, + toggleCellMerge: function toggleCellMerge() { + return function (state, dispatch) { + if (mergeCells(state, dispatch)) { + return; + } + + splitCell(state, dispatch); + }; + }, + mergeCells: function mergeCells$1() { + return mergeCells; + }, + splitCell: function splitCell$1() { + return splitCell; + }, + toggleHeaderColumn: function toggleHeaderColumn$1() { + return toggleHeaderColumn; + }, + toggleHeaderRow: function toggleHeaderRow$1() { + return toggleHeaderRow; + }, + toggleHeaderCell: function toggleHeaderCell$1() { + return toggleHeaderCell; + }, + setCellAttr: function setCellAttr$1() { + return setCellAttr; + }, + fixTables: function fixTables$1() { + return fixTables; + } + }; + } + }, { + key: "keys", + value: function keys() { + return { + Tab: goToNextCell(1), + 'Shift-Tab': 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 ? [columnResizing()] : []), [tableEditing()]); + } + }]); + + return Table; +}(Node); + +var TableHeader = +/*#__PURE__*/ +function (_Node) { + _inherits(TableHeader, _Node); + + function TableHeader() { + _classCallCheck(this, TableHeader); + + return _possibleConstructorReturn(this, _getPrototypeOf(TableHeader).apply(this, arguments)); + } + + _createClass(TableHeader, [{ + key: "name", + get: function get() { + return 'table_header'; + } + }, { + key: "schema", + get: function get() { + return TableNodes.table_header; + } + }]); + + return TableHeader; +}(Node); + +var TableCell = +/*#__PURE__*/ +function (_Node) { + _inherits(TableCell, _Node); + + function TableCell() { + _classCallCheck(this, TableCell); + + return _possibleConstructorReturn(this, _getPrototypeOf(TableCell).apply(this, arguments)); + } + + _createClass(TableCell, [{ + key: "name", + get: function get() { + return 'table_cell'; + } + }, { + key: "schema", + get: function get() { + return TableNodes.table_cell; + } + }]); + + return TableCell; +}(Node); + +var TableRow = +/*#__PURE__*/ +function (_Node) { + _inherits(TableRow, _Node); + + function TableRow() { + _classCallCheck(this, TableRow); + + return _possibleConstructorReturn(this, _getPrototypeOf(TableRow).apply(this, arguments)); + } + + _createClass(TableRow, [{ + key: "name", + get: function get() { + return 'table_row'; + } + }, { + key: "schema", + get: function get() { + return TableNodes.table_row; + } + }]); + + return TableRow; +}(Node); + +var TodoItem = +/*#__PURE__*/ +function (_Node) { + _inherits(TodoItem, _Node); + + function TodoItem() { + _classCallCheck(this, TodoItem); + + return _possibleConstructorReturn(this, _getPrototypeOf(TodoItem).apply(this, arguments)); + } + + _createClass(TodoItem, [{ + key: "keys", + value: function keys(_ref) { + var type = _ref.type; + return { + Enter: splitToDefaultListItem(type), + Tab: this.options.nested ? sinkListItem(type) : function () {}, + 'Shift-Tab': liftListItem(type) + }; + } + }, { + key: "name", + get: function get() { + return 'todo_item'; + } + }, { + key: "defaultOptions", + get: function get() { + return { + nested: false + }; + } + }, { + key: "view", + get: function get() { + return { + props: ['node', 'updateAttrs', 'view'], + methods: { + onChange: function onChange() { + this.updateAttrs({ + done: !this.node.attrs.done + }); + } + }, + template: "\n
  • \n \n
    \n
  • \n " + }; + } + }, { + key: "schema", + get: function get() { + var _this = this; + + return { + attrs: { + done: { + default: false + } + }, + draggable: true, + content: this.options.nested ? '(paragraph|todo_list)+' : 'paragraph+', + toDOM: function toDOM(node) { + var done = node.attrs.done; + return ['li', { + 'data-type': _this.name, + 'data-done': done.toString() + }, ['span', { + class: 'todo-checkbox', + contenteditable: 'false' + }], ['div', { + class: 'todo-content' + }, 0]]; + }, + parseDOM: [{ + priority: 51, + tag: "[data-type=\"".concat(this.name, "\"]"), + getAttrs: function getAttrs(dom) { + return { + done: dom.getAttribute('data-done') === 'true' + }; + } + }] + }; + } + }]); + + return TodoItem; +}(Node); + +var TodoList = +/*#__PURE__*/ +function (_Node) { + _inherits(TodoList, _Node); + + function TodoList() { + _classCallCheck(this, TodoList); + + return _possibleConstructorReturn(this, _getPrototypeOf(TodoList).apply(this, arguments)); + } + + _createClass(TodoList, [{ + key: "commands", + value: function commands(_ref) { + var type = _ref.type, + schema = _ref.schema; + return function () { + return toggleList(type, schema.nodes.todo_item); + }; + } + }, { + key: "inputRules", + value: function inputRules(_ref2) { + var type = _ref2.type; + return [wrappingInputRule(/^\s*(\[ \])\s$/, type)]; + } + }, { + key: "name", + get: function get() { + return 'todo_list'; + } + }, { + key: "schema", + get: function get() { + var _this = this; + + return { + group: 'block', + content: 'todo_item+', + toDOM: function toDOM() { + return ['ul', { + 'data-type': _this.name + }, 0]; + }, + parseDOM: [{ + priority: 51, + tag: "[data-type=\"".concat(this.name, "\"]") + }] + }; + } + }]); + + return TodoList; +}(Node); + +var Bold = +/*#__PURE__*/ +function (_Mark) { + _inherits(Bold, _Mark); + + function Bold() { + _classCallCheck(this, Bold); + + return _possibleConstructorReturn(this, _getPrototypeOf(Bold).apply(this, arguments)); + } + + _createClass(Bold, [{ + key: "keys", + value: function keys(_ref) { + var type = _ref.type; + return { + 'Mod-b': toggleMark(type) + }; + } + }, { + key: "commands", + value: function commands(_ref2) { + var type = _ref2.type; + return function () { + return toggleMark(type); + }; + } + }, { + key: "inputRules", + value: function inputRules(_ref3) { + var type = _ref3.type; + return [markInputRule(/(?:\*\*|__)([^*_]+)(?:\*\*|__)$/, type)]; + } + }, { + key: "pasteRules", + value: function pasteRules(_ref4) { + var type = _ref4.type; + return [markPasteRule(/(?:\*\*|__)([^*_]+)(?:\*\*|__)/g, type)]; + } + }, { + key: "name", + get: function get() { + return 'bold'; + } + }, { + key: "schema", + get: function get() { + return { + parseDOM: [{ + tag: 'strong' + }, { + tag: 'b', + getAttrs: function getAttrs(node) { + return node.style.fontWeight !== 'normal' && null; + } + }, { + style: 'font-weight', + getAttrs: function getAttrs(value) { + return /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null; + } + }], + toDOM: function toDOM() { + return ['strong', 0]; + } + }; + } + }]); + + return Bold; +}(Mark); + +var Code = +/*#__PURE__*/ +function (_Mark) { + _inherits(Code, _Mark); + + function Code() { + _classCallCheck(this, Code); + + return _possibleConstructorReturn(this, _getPrototypeOf(Code).apply(this, arguments)); + } + + _createClass(Code, [{ + key: "keys", + value: function keys(_ref) { + var type = _ref.type; + return { + 'Mod-`': toggleMark(type) + }; + } + }, { + key: "commands", + value: function commands(_ref2) { + var type = _ref2.type; + return function () { + return toggleMark(type); + }; + } + }, { + key: "inputRules", + value: function inputRules(_ref3) { + var type = _ref3.type; + return [markInputRule(/(?:`)([^`]+)(?:`)$/, type)]; + } + }, { + key: "pasteRules", + value: function pasteRules(_ref4) { + var type = _ref4.type; + return [markPasteRule(/(?:`)([^`]+)(?:`)/g, type)]; + } + }, { + key: "name", + get: function get() { + return 'code'; + } + }, { + key: "schema", + get: function get() { + return { + excludes: '_', + parseDOM: [{ + tag: 'code' + }], + toDOM: function toDOM() { + return ['code', 0]; + } + }; + } + }]); + + return Code; +}(Mark); + +var Italic = +/*#__PURE__*/ +function (_Mark) { + _inherits(Italic, _Mark); + + function Italic() { + _classCallCheck(this, Italic); + + return _possibleConstructorReturn(this, _getPrototypeOf(Italic).apply(this, arguments)); + } + + _createClass(Italic, [{ + key: "keys", + value: function keys(_ref) { + var type = _ref.type; + return { + 'Mod-i': toggleMark(type) + }; + } + }, { + key: "commands", + value: function commands(_ref2) { + var type = _ref2.type; + return function () { + return toggleMark(type); + }; + } + }, { + key: "inputRules", + value: function inputRules(_ref3) { + var type = _ref3.type; + return [markInputRule(/(?:^|[^_])(_([^_]+)_)$/, type), markInputRule(/(?:^|[^*])(\*([^*]+)\*)$/, type)]; + } + }, { + key: "pasteRules", + value: function pasteRules(_ref4) { + var type = _ref4.type; + return [markPasteRule(/_([^_]+)_/g, type), markPasteRule(/\*([^*]+)\*/g, type)]; + } + }, { + key: "name", + get: function get() { + return 'italic'; + } + }, { + key: "schema", + get: function get() { + return { + parseDOM: [{ + tag: 'i' + }, { + tag: 'em' + }, { + style: 'font-style=italic' + }], + toDOM: function toDOM() { + return ['em', 0]; + } + }; + } + }]); + + return Italic; +}(Mark); + +var Link = +/*#__PURE__*/ +function (_Mark) { + _inherits(Link, _Mark); + + function Link() { + _classCallCheck(this, Link); + + return _possibleConstructorReturn(this, _getPrototypeOf(Link).apply(this, arguments)); + } + + _createClass(Link, [{ + key: "commands", + value: function commands(_ref) { + var type = _ref.type; + return function (attrs) { + if (attrs.href) { + return updateMark(type, attrs); + } + + return removeMark(type); + }; + } + }, { + key: "pasteRules", + value: function pasteRules(_ref2) { + var type = _ref2.type; + return [pasteRule(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-zA-Z]{2,}\b([-a-zA-Z0-9@:%_+.~#?&//=]*)/g, type, function (url) { + return { + href: url + }; + })]; + } + }, { + key: "name", + get: function get() { + return 'link'; + } + }, { + key: "defaultOptions", + get: function get() { + return { + openOnClick: true + }; + } + }, { + key: "schema", + get: function get() { + return { + attrs: { + href: { + default: null + } + }, + inclusive: false, + parseDOM: [{ + tag: 'a[href]', + getAttrs: function getAttrs(dom) { + return { + href: dom.getAttribute('href') + }; + } + }], + toDOM: function toDOM(node) { + return ['a', _objectSpread2({}, node.attrs, { + rel: 'noopener noreferrer nofollow' + }), 0]; + } + }; + } + }, { + key: "plugins", + get: function get() { + if (!this.options.openOnClick) { + return []; + } + + return [new Plugin({ + props: { + handleClick: function handleClick(view, pos, event) { + var schema = view.state.schema; + var attrs = getMarkAttrs(view.state, schema.marks.link); + + if (attrs.href && event.target instanceof HTMLAnchorElement) { + event.stopPropagation(); + window.open(attrs.href); + } + } + } + })]; + } + }]); + + return Link; +}(Mark); + +var Strike = +/*#__PURE__*/ +function (_Mark) { + _inherits(Strike, _Mark); + + function Strike() { + _classCallCheck(this, Strike); + + return _possibleConstructorReturn(this, _getPrototypeOf(Strike).apply(this, arguments)); + } + + _createClass(Strike, [{ + key: "keys", + value: function keys(_ref) { + var type = _ref.type; + return { + 'Mod-d': toggleMark(type) + }; + } + }, { + key: "commands", + value: function commands(_ref2) { + var type = _ref2.type; + return function () { + return toggleMark(type); + }; + } + }, { + key: "inputRules", + value: function inputRules(_ref3) { + var type = _ref3.type; + return [markInputRule(/~([^~]+)~$/, type)]; + } + }, { + key: "pasteRules", + value: function pasteRules(_ref4) { + var type = _ref4.type; + return [markPasteRule(/~([^~]+)~/g, type)]; + } + }, { + key: "name", + get: function get() { + return 'strike'; + } + }, { + key: "schema", + get: function get() { + return { + parseDOM: [{ + tag: 's' + }, { + tag: 'del' + }, { + tag: 'strike' + }, { + style: 'text-decoration', + getAttrs: function getAttrs(value) { + return value === 'line-through'; + } + }], + toDOM: function toDOM() { + return ['s', 0]; + } + }; + } + }]); + + return Strike; +}(Mark); + +var Underline = +/*#__PURE__*/ +function (_Mark) { + _inherits(Underline, _Mark); + + function Underline() { + _classCallCheck(this, Underline); + + return _possibleConstructorReturn(this, _getPrototypeOf(Underline).apply(this, arguments)); + } + + _createClass(Underline, [{ + key: "keys", + value: function keys(_ref) { + var type = _ref.type; + return { + 'Mod-u': toggleMark(type) + }; + } + }, { + key: "commands", + value: function commands(_ref2) { + var type = _ref2.type; + return function () { + return toggleMark(type); + }; + } + }, { + key: "name", + get: function get() { + return 'underline'; + } + }, { + key: "schema", + get: function get() { + return { + parseDOM: [{ + tag: 'u' + }, { + style: 'text-decoration', + getAttrs: function getAttrs(value) { + return value === 'underline'; + } + }], + toDOM: function toDOM() { + return ['u', 0]; + } + }; + } + }]); + + return Underline; +}(Mark); + +var Collaboration = +/*#__PURE__*/ +function (_Extension) { + _inherits(Collaboration, _Extension); + + function Collaboration() { + _classCallCheck(this, Collaboration); + + return _possibleConstructorReturn(this, _getPrototypeOf(Collaboration).apply(this, arguments)); + } + + _createClass(Collaboration, [{ + key: "init", + value: function init() { + var _this = this; + + this.getSendableSteps = this.debounce(function (state) { + var sendable = sendableSteps(state); + + if (sendable) { + _this.options.onSendable({ + editor: _this.editor, + sendable: { + version: sendable.version, + steps: sendable.steps.map(function (step) { + return step.toJSON(); + }), + clientID: sendable.clientID + } + }); + } + }, this.options.debounce); + this.editor.on('transaction', function (_ref) { + var state = _ref.state; + + _this.getSendableSteps(state); + }); + } + }, { + key: "debounce", + value: function debounce(fn, delay) { + var timeout; + return function () { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + if (timeout) { + clearTimeout(timeout); + } + + timeout = setTimeout(function () { + fn.apply(void 0, args); + timeout = null; + }, delay); + }; + } + }, { + key: "name", + get: function get() { + return 'collaboration'; + } + }, { + key: "defaultOptions", + get: function get() { + var _this2 = this; + + return { + version: 0, + clientID: Math.floor(Math.random() * 0xFFFFFFFF), + debounce: 250, + onSendable: function onSendable() {}, + update: function update(_ref2) { + var steps = _ref2.steps, + version = _ref2.version; + var _this2$editor = _this2.editor, + state = _this2$editor.state, + view = _this2$editor.view, + schema = _this2$editor.schema; + + if (getVersion(state) > version) { + return; + } + + view.dispatch(receiveTransaction(state, steps.map(function (item) { + return Step.fromJSON(schema, item.step); + }), steps.map(function (item) { + return item.clientID; + }))); + } + }; + } + }, { + key: "plugins", + get: function get() { + return [collab({ + version: this.options.version, + clientID: this.options.clientID + })]; + } + }]); + + return Collaboration; +}(Extension); + +var Focus = +/*#__PURE__*/ +function (_Extension) { + _inherits(Focus, _Extension); + + function Focus() { + _classCallCheck(this, Focus); + + return _possibleConstructorReturn(this, _getPrototypeOf(Focus).apply(this, arguments)); + } + + _createClass(Focus, [{ + key: "name", + get: function get() { + return 'focus'; + } + }, { + key: "defaultOptions", + get: function get() { + return { + className: 'has-focus', + nested: false + }; + } + }, { + key: "plugins", + get: function get() { + var _this = this; + + return [new Plugin({ + props: { + decorations: function decorations(_ref) { + var doc = _ref.doc, + plugins = _ref.plugins, + selection = _ref.selection; + var editablePlugin = plugins.find(function (plugin) { + return plugin.key.startsWith('editable$'); + }); + var editable = editablePlugin.props.editable(); + var active = editable && _this.options.className; + var focused = _this.editor.focused; + var anchor = selection.anchor; + var decorations = []; + + if (!active || !focused) { + return false; + } + + doc.descendants(function (node, pos) { + var hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize; + + if (hasAnchor && !node.isText) { + var decoration = Decoration.node(pos, pos + node.nodeSize, { + class: _this.options.className + }); + decorations.push(decoration); + } + + return _this.options.nested; + }); + return DecorationSet.create(doc, decorations); + } + } + })]; + } + }]); + + return Focus; +}(Extension); + +var History = +/*#__PURE__*/ +function (_Extension) { + _inherits(History, _Extension); + + function History() { + _classCallCheck(this, History); + + return _possibleConstructorReturn(this, _getPrototypeOf(History).apply(this, arguments)); + } + + _createClass(History, [{ + key: "keys", + value: function keys() { + var keymap = { + 'Mod-z': undo, + 'Mod-y': redo, + 'Shift-Mod-z': redo + }; + return keymap; + } + }, { + key: "commands", + value: function commands() { + return { + undo: function undo$1() { + return undo; + }, + redo: function redo$1() { + return redo; + }, + undoDepth: function undoDepth$1() { + return undoDepth; + }, + redoDepth: function redoDepth$1() { + return redoDepth; + } + }; + } + }, { + key: "name", + get: function get() { + return 'history'; + } + }, { + key: "defaultOptions", + get: function get() { + return { + depth: '', + newGroupDelay: '' + }; + } + }, { + key: "plugins", + get: function get() { + return [history({ + depth: this.options.depth, + newGroupDelay: this.options.newGroupDelay + })]; + } + }]); + + return History; +}(Extension); + +var Placeholder = +/*#__PURE__*/ +function (_Extension) { + _inherits(Placeholder, _Extension); + + function Placeholder() { + _classCallCheck(this, Placeholder); + + return _possibleConstructorReturn(this, _getPrototypeOf(Placeholder).apply(this, arguments)); + } + + _createClass(Placeholder, [{ + key: "name", + get: function get() { + return 'placeholder'; + } + }, { + key: "defaultOptions", + get: function get() { + return { + emptyEditorClass: 'is-editor-empty', + emptyNodeClass: 'is-empty', + emptyNodeText: 'Write something …', + showOnlyWhenEditable: true, + showOnlyCurrent: true + }; + } + }, { + key: "update", + get: function get() { + return function (view) { + view.updateState(view.state); + }; + } + }, { + key: "plugins", + get: function get() { + var _this = this; + + return [new Plugin({ + props: { + decorations: function decorations(_ref) { + var doc = _ref.doc, + plugins = _ref.plugins, + selection = _ref.selection; + var editablePlugin = plugins.find(function (plugin) { + return plugin.key.startsWith('editable$'); + }); + var editable = editablePlugin.props.editable(); + var active = editable || !_this.options.showOnlyWhenEditable; + var anchor = selection.anchor; + var decorations = []; + var isEditorEmpty = doc.textContent.length === 0; + + if (!active) { + return false; + } + + doc.descendants(function (node, pos) { + var hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize; + var isNodeEmpty = node.content.size === 0; + + if ((hasAnchor || !_this.options.showOnlyCurrent) && isNodeEmpty) { + var classes = [_this.options.emptyNodeClass]; + + if (isEditorEmpty) { + classes.push(_this.options.emptyEditorClass); + } + + var decoration = Decoration.node(pos, pos + node.nodeSize, { + class: classes.join(' '), + 'data-empty-text': typeof _this.options.emptyNodeText === 'function' ? _this.options.emptyNodeText(node) : _this.options.emptyNodeText + }); + decorations.push(decoration); + } + + return false; + }); + return DecorationSet.create(doc, decorations); + } + } + })]; + } + }]); + + return Placeholder; +}(Extension); + +var Search = +/*#__PURE__*/ +function (_Extension) { + _inherits(Search, _Extension); + + function Search() { + var _this; + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, Search); + + _this = _possibleConstructorReturn(this, _getPrototypeOf(Search).call(this, options)); + _this.results = []; + _this.searchTerm = null; + _this._updating = false; + return _this; + } + + _createClass(Search, [{ + key: "commands", + value: function commands() { + var _this2 = this; + + return { + find: function find(attrs) { + return _this2.find(attrs); + }, + replace: function replace(attrs) { + return _this2.replace(attrs); + }, + replaceAll: function replaceAll(attrs) { + return _this2.replaceAll(attrs); + }, + clearSearch: function clearSearch() { + return _this2.clear(); + } + }; + } + }, { + key: "_search", + value: function _search(doc) { + var _this3 = this; + + this.results = []; + var mergedTextNodes = []; + var index = 0; + + if (!this.searchTerm) { + return; + } + + doc.descendants(function (node, pos) { + if (node.isText) { + if (mergedTextNodes[index]) { + mergedTextNodes[index] = { + text: mergedTextNodes[index].text + node.text, + pos: mergedTextNodes[index].pos + }; + } else { + mergedTextNodes[index] = { + text: node.text, + pos: pos + }; + } + } else { + index += 1; + } + }); + mergedTextNodes.forEach(function (_ref) { + var text = _ref.text, + pos = _ref.pos; + var search = _this3.findRegExp; + var m; // eslint-disable-next-line no-cond-assign + + while (m = search.exec(text)) { + if (m[0] === '') { + break; + } + + _this3.results.push({ + from: pos + m.index, + to: pos + m.index + m[0].length + }); + } + }); + } + }, { + key: "replace", + value: function replace(_replace) { + var _this4 = this; + + return function (state, dispatch) { + var firstResult = _this4.results[0]; + + if (!firstResult) { + return; + } + + var _this4$results$ = _this4.results[0], + from = _this4$results$.from, + to = _this4$results$.to; + dispatch(state.tr.insertText(_replace, from, to)); + + _this4.editor.commands.find(_this4.searchTerm); + }; + } + }, { + key: "rebaseNextResult", + value: function rebaseNextResult(replace, index) { + var lastOffset = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + var nextIndex = index + 1; + + if (!this.results[nextIndex]) { + return null; + } + + var _this$results$index = this.results[index], + currentFrom = _this$results$index.from, + currentTo = _this$results$index.to; + var offset = currentTo - currentFrom - replace.length + lastOffset; + var _this$results$nextInd = this.results[nextIndex], + from = _this$results$nextInd.from, + to = _this$results$nextInd.to; + this.results[nextIndex] = { + to: to - offset, + from: from - offset + }; + return offset; + } + }, { + key: "replaceAll", + value: function replaceAll(replace) { + var _this5 = this; + + return function (_ref2, dispatch) { + var tr = _ref2.tr; + var offset; + + if (!_this5.results.length) { + return; + } + + _this5.results.forEach(function (_ref3, index) { + var from = _ref3.from, + to = _ref3.to; + tr.insertText(replace, from, to); + offset = _this5.rebaseNextResult(replace, index, offset); + }); + + dispatch(tr); + + _this5.editor.commands.find(_this5.searchTerm); + }; + } + }, { + key: "find", + value: function find(searchTerm) { + var _this6 = this; + + return function (state, dispatch) { + _this6.searchTerm = _this6.options.disableRegex ? searchTerm.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&') : searchTerm; + + _this6.updateView(state, dispatch); + }; + } + }, { + key: "clear", + value: function clear() { + var _this7 = this; + + return function (state, dispatch) { + _this7.searchTerm = null; + + _this7.updateView(state, dispatch); + }; + } + }, { + key: "updateView", + value: function updateView(_ref4, dispatch) { + var tr = _ref4.tr; + this._updating = true; + dispatch(tr); + this._updating = false; + } + }, { + key: "createDeco", + value: function createDeco(doc) { + this._search(doc); + + return this.decorations ? DecorationSet.create(doc, this.decorations) : []; + } + }, { + key: "name", + get: function get() { + return 'search'; + } + }, { + key: "defaultOptions", + get: function get() { + return { + autoSelectNext: true, + findClass: 'find', + searching: false, + caseSensitive: false, + disableRegex: true, + alwaysSearch: false + }; + } + }, { + key: "findRegExp", + get: function get() { + return RegExp(this.searchTerm, !this.options.caseSensitive ? 'gui' : 'gu'); + } + }, { + key: "decorations", + get: function get() { + var _this8 = this; + + return this.results.map(function (deco) { + return Decoration.inline(deco.from, deco.to, { + class: _this8.options.findClass + }); + }); + } + }, { + key: "plugins", + get: function get() { + var _this9 = this; + + return [new Plugin({ + state: { + init: function init() { + return DecorationSet.empty; + }, + apply: function apply(tr, old) { + if (_this9._updating || _this9.options.searching || tr.docChanged && _this9.options.alwaysSearch) { + return _this9.createDeco(tr.doc); + } + + if (tr.docChanged) { + return old.map(tr.mapping, tr.doc); + } + + return old; + } + }, + props: { + decorations: function decorations(state) { + return this.getState(state); + } + } + })]; + } + }]); + + return Search; +}(Extension); + +var TrailingNode = +/*#__PURE__*/ +function (_Extension) { + _inherits(TrailingNode, _Extension); + + function TrailingNode() { + _classCallCheck(this, TrailingNode); + + return _possibleConstructorReturn(this, _getPrototypeOf(TrailingNode).apply(this, arguments)); + } + + _createClass(TrailingNode, [{ + key: "name", + get: function get() { + return 'trailing_node'; + } + }, { + key: "defaultOptions", + get: function get() { + return { + node: 'paragraph', + notAfter: ['paragraph'] + }; + } + }, { + key: "plugins", + get: function get() { + var _this = this; + + var plugin = new PluginKey(this.name); + var disabledNodes = Object.entries(this.editor.schema.nodes).map(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2), + value = _ref2[1]; + + return value; + }).filter(function (node) { + return _this.options.notAfter.includes(node.name); + }); + return [new Plugin({ + key: plugin, + view: function view() { + return { + update: function update(view) { + var state = view.state; + var insertNodeAtEnd = plugin.getState(state); + + if (!insertNodeAtEnd) { + return; + } + + var doc = state.doc, + schema = state.schema, + tr = state.tr; + var type = schema.nodes[_this.options.node]; + var transaction = tr.insert(doc.content.size, type.create()); + view.dispatch(transaction); + } + }; + }, + state: { + init: function init(_, state) { + var lastNode = state.tr.doc.lastChild; + return !nodeEqualsType({ + node: lastNode, + types: disabledNodes + }); + }, + apply: function apply(tr, value) { + if (!tr.docChanged) { + return value; + } + + var lastNode = tr.doc.lastChild; + return !nodeEqualsType({ + node: lastNode, + types: disabledNodes + }); + } + } + })]; + } + }]); + + return TrailingNode; +}(Extension); + +export { Blockquote, Bold, BulletList, Code, CodeBlock, CodeBlockHighlight, Collaboration, Focus, HardBreak, Heading, HighlightPlugin as Highlight, History, HorizontalRule, Image, Italic, Link, ListItem, Mention, OrderedList, Placeholder, Search, Strike, SuggestionsPlugin as Suggestions, Table, TableCell, TableHeader, TableRow, TodoItem, TodoList, TrailingNode, Underline }; diff --git a/packages/tiptap-extensions/dist/extensions.js b/packages/tiptap-extensions/dist/extensions.js new file mode 100644 index 0000000000..5e85d12ef9 --- /dev/null +++ b/packages/tiptap-extensions/dist/extensions.js @@ -0,0 +1,2853 @@ + + /*! + * tiptap-extensions v1.28.6 + * (c) 2020 Scrumpy UG (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('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', '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, global.prosemirrorTables, global.tiptapUtils, global.prosemirrorTransform, global.prosemirrorCollab, global.prosemirrorHistory)); +}(this, (function (exports, tiptap, tiptapCommands, low, prosemirrorView, prosemirrorUtils, prosemirrorState, prosemirrorTables, tiptapUtils, prosemirrorTransform, prosemirrorCollab, prosemirrorHistory) { 'use strict'; + + low = low && low.hasOwnProperty('default') ? low['default'] : low; + + 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 _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 _slicedToArray(arr, i) { + return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); + } + + function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); + } + + function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } + } + + function _arrayWithHoles(arr) { + if (Array.isArray(arr)) return arr; + } + + function _iterableToArray(iter) { + if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); + } + + function _iterableToArrayLimit(arr, i) { + if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { + 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 _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); + } + + function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance"); + } + + var Blockquote = + /*#__PURE__*/ + function (_Node) { + _inherits(Blockquote, _Node); + + function Blockquote() { + _classCallCheck(this, Blockquote); + + return _possibleConstructorReturn(this, _getPrototypeOf(Blockquote).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); + + function BulletList() { + _classCallCheck(this, BulletList); + + return _possibleConstructorReturn(this, _getPrototypeOf(BulletList).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); + + function CodeBlock() { + _classCallCheck(this, CodeBlock); + + return _possibleConstructorReturn(this, _getPrototypeOf(CodeBlock).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({}, 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, state) { + // TODO: find way to cache decorations + // see: https://discuss.prosemirror.net/t/how-to-update-multiple-inline-decorations-on-node-change/1493 + var nodeName = state.selection.$head.parent.type.name; + var previousNodeName = oldState.selection.$head.parent.type.name; + + if (transaction.docChanged && [nodeName, previousNodeName].includes(name)) { + 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); + + function CodeBlockHighlight() { + var _this; + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, CodeBlockHighlight); + + _this = _possibleConstructorReturn(this, _getPrototypeOf(CodeBlockHighlight).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); + + function HardBreak() { + _classCallCheck(this, HardBreak); + + return _possibleConstructorReturn(this, _getPrototypeOf(HardBreak).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); + + function Heading() { + _classCallCheck(this, Heading); + + return _possibleConstructorReturn(this, _getPrototypeOf(Heading).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({}, 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); + + function HorizontalRule() { + _classCallCheck(this, HorizontalRule); + + return _possibleConstructorReturn(this, _getPrototypeOf(HorizontalRule).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); + + function Image() { + _classCallCheck(this, Image); + + return _possibleConstructorReturn(this, _getPrototypeOf(Image).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); + + function ListItem() { + _classCallCheck(this, ListItem); + + return _possibleConstructorReturn(this, _getPrototypeOf(ListItem).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|\\0").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 update(view, prevState) { + var prev = _this.key.getState(prevState); + + var next = _this.key.getState(view.state); // See how the state changed + + + var moved = prev.active && next.active && prev.range.from !== next.range.from; + var started = !prev.active && next.active; + var stopped = prev.active && !next.active; + var changed = !started && !stopped && prev.query !== next.query; + var handleStart = started || moved; + var handleChange = changed && !moved; + var handleExit = stopped || moved; // Cancel when suggestion isn't active + + if (!handleStart && !handleChange && !handleExit) { + return; + } + + var state = handleExit ? prev : next; + var 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 + + var virtualNode = decorationNode ? { + getBoundingClientRect: function getBoundingClientRect() { + return decorationNode.getBoundingClientRect(); + }, + clientWidth: decorationNode.clientWidth, + clientHeight: decorationNode.clientHeight + } : null; + var props = { + view: view, + range: state.range, + query: state.query, + text: state.text, + decorationNode: decorationNode, + virtualNode: virtualNode, + items: onFilter(Array.isArray(items) ? items : items(), state.query), + command: 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); + } + } + }; // Trigger the hooks when necessary + + if (handleExit) { + onExit(props); + } + + if (handleChange) { + onChange(props); + } + + if (handleStart) { + onEnter(props); + } + } + }; + }, + 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 = Object.assign({}, 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); + + function Mention() { + _classCallCheck(this, Mention); + + return _possibleConstructorReturn(this, _getPrototypeOf(Mention).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); + + function OrderedList() { + _classCallCheck(this, OrderedList); + + return _possibleConstructorReturn(this, _getPrototypeOf(OrderedList).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); + + function Table() { + _classCallCheck(this, Table); + + return _possibleConstructorReturn(this, _getPrototypeOf(Table).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); + + function TableHeader() { + _classCallCheck(this, TableHeader); + + return _possibleConstructorReturn(this, _getPrototypeOf(TableHeader).apply(this, arguments)); + } + + _createClass(TableHeader, [{ + key: "name", + get: function get() { + return 'table_header'; + } + }, { + key: "schema", + get: function get() { + return TableNodes.table_header; + } + }]); + + return TableHeader; + }(tiptap.Node); + + var TableCell = + /*#__PURE__*/ + function (_Node) { + _inherits(TableCell, _Node); + + function TableCell() { + _classCallCheck(this, TableCell); + + return _possibleConstructorReturn(this, _getPrototypeOf(TableCell).apply(this, arguments)); + } + + _createClass(TableCell, [{ + key: "name", + get: function get() { + return 'table_cell'; + } + }, { + key: "schema", + get: function get() { + return TableNodes.table_cell; + } + }]); + + return TableCell; + }(tiptap.Node); + + var TableRow = + /*#__PURE__*/ + function (_Node) { + _inherits(TableRow, _Node); + + function TableRow() { + _classCallCheck(this, TableRow); + + return _possibleConstructorReturn(this, _getPrototypeOf(TableRow).apply(this, arguments)); + } + + _createClass(TableRow, [{ + key: "name", + get: function get() { + return 'table_row'; + } + }, { + key: "schema", + get: function get() { + return TableNodes.table_row; + } + }]); + + return TableRow; + }(tiptap.Node); + + var TodoItem = + /*#__PURE__*/ + function (_Node) { + _inherits(TodoItem, _Node); + + function TodoItem() { + _classCallCheck(this, TodoItem); + + return _possibleConstructorReturn(this, _getPrototypeOf(TodoItem).apply(this, arguments)); + } + + _createClass(TodoItem, [{ + key: "keys", + value: function keys(_ref) { + var type = _ref.type; + return { + Enter: tiptapCommands.splitToDefaultListItem(type), + Tab: this.options.nested ? tiptapCommands.sinkListItem(type) : function () {}, + 'Shift-Tab': tiptapCommands.liftListItem(type) + }; + } + }, { + key: "name", + get: function get() { + return 'todo_item'; + } + }, { + key: "defaultOptions", + get: function get() { + return { + nested: false + }; + } + }, { + key: "view", + get: function get() { + return { + props: ['node', 'updateAttrs', 'view'], + methods: { + onChange: function onChange() { + this.updateAttrs({ + done: !this.node.attrs.done + }); + } + }, + template: "\n
  • \n \n
    \n
  • \n " + }; + } + }, { + key: "schema", + get: function get() { + var _this = this; + + return { + attrs: { + done: { + default: false + } + }, + draggable: true, + content: this.options.nested ? '(paragraph|todo_list)+' : 'paragraph+', + toDOM: function toDOM(node) { + var done = node.attrs.done; + return ['li', { + 'data-type': _this.name, + 'data-done': done.toString() + }, ['span', { + class: 'todo-checkbox', + contenteditable: 'false' + }], ['div', { + class: 'todo-content' + }, 0]]; + }, + parseDOM: [{ + priority: 51, + tag: "[data-type=\"".concat(this.name, "\"]"), + getAttrs: function getAttrs(dom) { + return { + done: dom.getAttribute('data-done') === 'true' + }; + } + }] + }; + } + }]); + + return TodoItem; + }(tiptap.Node); + + var TodoList = + /*#__PURE__*/ + function (_Node) { + _inherits(TodoList, _Node); + + function TodoList() { + _classCallCheck(this, TodoList); + + return _possibleConstructorReturn(this, _getPrototypeOf(TodoList).apply(this, arguments)); + } + + _createClass(TodoList, [{ + key: "commands", + value: function commands(_ref) { + var type = _ref.type, + schema = _ref.schema; + return function () { + return tiptapCommands.toggleList(type, schema.nodes.todo_item); + }; + } + }, { + key: "inputRules", + value: function inputRules(_ref2) { + var type = _ref2.type; + return [tiptapCommands.wrappingInputRule(/^\s*(\[ \])\s$/, type)]; + } + }, { + key: "name", + get: function get() { + return 'todo_list'; + } + }, { + key: "schema", + get: function get() { + var _this = this; + + return { + group: 'block', + content: 'todo_item+', + toDOM: function toDOM() { + return ['ul', { + 'data-type': _this.name + }, 0]; + }, + parseDOM: [{ + priority: 51, + tag: "[data-type=\"".concat(this.name, "\"]") + }] + }; + } + }]); + + return TodoList; + }(tiptap.Node); + + var Bold = + /*#__PURE__*/ + function (_Mark) { + _inherits(Bold, _Mark); + + function Bold() { + _classCallCheck(this, Bold); + + return _possibleConstructorReturn(this, _getPrototypeOf(Bold).apply(this, arguments)); + } + + _createClass(Bold, [{ + key: "keys", + value: function keys(_ref) { + var type = _ref.type; + return { + 'Mod-b': tiptapCommands.toggleMark(type) + }; + } + }, { + key: "commands", + value: function commands(_ref2) { + var type = _ref2.type; + return function () { + return tiptapCommands.toggleMark(type); + }; + } + }, { + key: "inputRules", + value: function inputRules(_ref3) { + var type = _ref3.type; + return [tiptapCommands.markInputRule(/(?:\*\*|__)([^*_]+)(?:\*\*|__)$/, type)]; + } + }, { + key: "pasteRules", + value: function pasteRules(_ref4) { + var type = _ref4.type; + return [tiptapCommands.markPasteRule(/(?:\*\*|__)([^*_]+)(?:\*\*|__)/g, type)]; + } + }, { + key: "name", + get: function get() { + return 'bold'; + } + }, { + key: "schema", + get: function get() { + return { + parseDOM: [{ + tag: 'strong' + }, { + tag: 'b', + getAttrs: function getAttrs(node) { + return node.style.fontWeight !== 'normal' && null; + } + }, { + style: 'font-weight', + getAttrs: function getAttrs(value) { + return /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null; + } + }], + toDOM: function toDOM() { + return ['strong', 0]; + } + }; + } + }]); + + return Bold; + }(tiptap.Mark); + + var Code = + /*#__PURE__*/ + function (_Mark) { + _inherits(Code, _Mark); + + function Code() { + _classCallCheck(this, Code); + + return _possibleConstructorReturn(this, _getPrototypeOf(Code).apply(this, arguments)); + } + + _createClass(Code, [{ + key: "keys", + value: function keys(_ref) { + var type = _ref.type; + return { + 'Mod-`': tiptapCommands.toggleMark(type) + }; + } + }, { + key: "commands", + value: function commands(_ref2) { + var type = _ref2.type; + return function () { + return tiptapCommands.toggleMark(type); + }; + } + }, { + key: "inputRules", + value: function inputRules(_ref3) { + var type = _ref3.type; + return [tiptapCommands.markInputRule(/(?:`)([^`]+)(?:`)$/, type)]; + } + }, { + key: "pasteRules", + value: function pasteRules(_ref4) { + var type = _ref4.type; + return [tiptapCommands.markPasteRule(/(?:`)([^`]+)(?:`)/g, type)]; + } + }, { + key: "name", + get: function get() { + return 'code'; + } + }, { + key: "schema", + get: function get() { + return { + excludes: '_', + parseDOM: [{ + tag: 'code' + }], + toDOM: function toDOM() { + return ['code', 0]; + } + }; + } + }]); + + return Code; + }(tiptap.Mark); + + var Italic = + /*#__PURE__*/ + function (_Mark) { + _inherits(Italic, _Mark); + + function Italic() { + _classCallCheck(this, Italic); + + return _possibleConstructorReturn(this, _getPrototypeOf(Italic).apply(this, arguments)); + } + + _createClass(Italic, [{ + key: "keys", + value: function keys(_ref) { + var type = _ref.type; + return { + 'Mod-i': tiptapCommands.toggleMark(type) + }; + } + }, { + key: "commands", + value: function commands(_ref2) { + var type = _ref2.type; + return function () { + return tiptapCommands.toggleMark(type); + }; + } + }, { + key: "inputRules", + value: function inputRules(_ref3) { + var type = _ref3.type; + return [tiptapCommands.markInputRule(/(?:^|[^_])(_([^_]+)_)$/, type), tiptapCommands.markInputRule(/(?:^|[^*])(\*([^*]+)\*)$/, type)]; + } + }, { + key: "pasteRules", + value: function pasteRules(_ref4) { + var type = _ref4.type; + return [tiptapCommands.markPasteRule(/_([^_]+)_/g, type), tiptapCommands.markPasteRule(/\*([^*]+)\*/g, type)]; + } + }, { + key: "name", + get: function get() { + return 'italic'; + } + }, { + key: "schema", + get: function get() { + return { + parseDOM: [{ + tag: 'i' + }, { + tag: 'em' + }, { + style: 'font-style=italic' + }], + toDOM: function toDOM() { + return ['em', 0]; + } + }; + } + }]); + + return Italic; + }(tiptap.Mark); + + var Link = + /*#__PURE__*/ + function (_Mark) { + _inherits(Link, _Mark); + + function Link() { + _classCallCheck(this, Link); + + return _possibleConstructorReturn(this, _getPrototypeOf(Link).apply(this, arguments)); + } + + _createClass(Link, [{ + key: "commands", + value: function commands(_ref) { + var type = _ref.type; + return function (attrs) { + if (attrs.href) { + return tiptapCommands.updateMark(type, attrs); + } + + return tiptapCommands.removeMark(type); + }; + } + }, { + key: "pasteRules", + value: function pasteRules(_ref2) { + var type = _ref2.type; + return [tiptapCommands.pasteRule(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-zA-Z]{2,}\b([-a-zA-Z0-9@:%_+.~#?&//=]*)/g, type, function (url) { + return { + href: url + }; + })]; + } + }, { + key: "name", + get: function get() { + return 'link'; + } + }, { + key: "defaultOptions", + get: function get() { + return { + openOnClick: true + }; + } + }, { + key: "schema", + get: function get() { + return { + attrs: { + href: { + default: null + } + }, + inclusive: false, + parseDOM: [{ + tag: 'a[href]', + getAttrs: function getAttrs(dom) { + return { + href: dom.getAttribute('href') + }; + } + }], + toDOM: function toDOM(node) { + return ['a', _objectSpread2({}, node.attrs, { + rel: 'noopener noreferrer nofollow' + }), 0]; + } + }; + } + }, { + key: "plugins", + get: function get() { + if (!this.options.openOnClick) { + return []; + } + + return [new tiptap.Plugin({ + props: { + handleClick: function handleClick(view, pos, event) { + var schema = view.state.schema; + var attrs = tiptapUtils.getMarkAttrs(view.state, schema.marks.link); + + if (attrs.href && event.target instanceof HTMLAnchorElement) { + event.stopPropagation(); + window.open(attrs.href); + } + } + } + })]; + } + }]); + + return Link; + }(tiptap.Mark); + + var Strike = + /*#__PURE__*/ + function (_Mark) { + _inherits(Strike, _Mark); + + function Strike() { + _classCallCheck(this, Strike); + + return _possibleConstructorReturn(this, _getPrototypeOf(Strike).apply(this, arguments)); + } + + _createClass(Strike, [{ + key: "keys", + value: function keys(_ref) { + var type = _ref.type; + return { + 'Mod-d': tiptapCommands.toggleMark(type) + }; + } + }, { + key: "commands", + value: function commands(_ref2) { + var type = _ref2.type; + return function () { + return tiptapCommands.toggleMark(type); + }; + } + }, { + key: "inputRules", + value: function inputRules(_ref3) { + var type = _ref3.type; + return [tiptapCommands.markInputRule(/~([^~]+)~$/, type)]; + } + }, { + key: "pasteRules", + value: function pasteRules(_ref4) { + var type = _ref4.type; + return [tiptapCommands.markPasteRule(/~([^~]+)~/g, type)]; + } + }, { + key: "name", + get: function get() { + return 'strike'; + } + }, { + key: "schema", + get: function get() { + return { + parseDOM: [{ + tag: 's' + }, { + tag: 'del' + }, { + tag: 'strike' + }, { + style: 'text-decoration', + getAttrs: function getAttrs(value) { + return value === 'line-through'; + } + }], + toDOM: function toDOM() { + return ['s', 0]; + } + }; + } + }]); + + return Strike; + }(tiptap.Mark); + + var Underline = + /*#__PURE__*/ + function (_Mark) { + _inherits(Underline, _Mark); + + function Underline() { + _classCallCheck(this, Underline); + + return _possibleConstructorReturn(this, _getPrototypeOf(Underline).apply(this, arguments)); + } + + _createClass(Underline, [{ + key: "keys", + value: function keys(_ref) { + var type = _ref.type; + return { + 'Mod-u': tiptapCommands.toggleMark(type) + }; + } + }, { + key: "commands", + value: function commands(_ref2) { + var type = _ref2.type; + return function () { + return tiptapCommands.toggleMark(type); + }; + } + }, { + key: "name", + get: function get() { + return 'underline'; + } + }, { + key: "schema", + get: function get() { + return { + parseDOM: [{ + tag: 'u' + }, { + style: 'text-decoration', + getAttrs: function getAttrs(value) { + return value === 'underline'; + } + }], + toDOM: function toDOM() { + return ['u', 0]; + } + }; + } + }]); + + return Underline; + }(tiptap.Mark); + + var Collaboration = + /*#__PURE__*/ + function (_Extension) { + _inherits(Collaboration, _Extension); + + function Collaboration() { + _classCallCheck(this, Collaboration); + + return _possibleConstructorReturn(this, _getPrototypeOf(Collaboration).apply(this, arguments)); + } + + _createClass(Collaboration, [{ + key: "init", + value: function init() { + var _this = this; + + this.getSendableSteps = this.debounce(function (state) { + var sendable = prosemirrorCollab.sendableSteps(state); + + if (sendable) { + _this.options.onSendable({ + editor: _this.editor, + sendable: { + version: sendable.version, + steps: sendable.steps.map(function (step) { + return step.toJSON(); + }), + clientID: sendable.clientID + } + }); + } + }, this.options.debounce); + this.editor.on('transaction', function (_ref) { + var state = _ref.state; + + _this.getSendableSteps(state); + }); + } + }, { + key: "debounce", + value: function debounce(fn, delay) { + var timeout; + return function () { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + if (timeout) { + clearTimeout(timeout); + } + + timeout = setTimeout(function () { + fn.apply(void 0, args); + timeout = null; + }, delay); + }; + } + }, { + key: "name", + get: function get() { + return 'collaboration'; + } + }, { + key: "defaultOptions", + get: function get() { + var _this2 = this; + + return { + version: 0, + clientID: Math.floor(Math.random() * 0xFFFFFFFF), + debounce: 250, + onSendable: function onSendable() {}, + update: function update(_ref2) { + var steps = _ref2.steps, + version = _ref2.version; + var _this2$editor = _this2.editor, + state = _this2$editor.state, + view = _this2$editor.view, + schema = _this2$editor.schema; + + if (prosemirrorCollab.getVersion(state) > version) { + return; + } + + view.dispatch(prosemirrorCollab.receiveTransaction(state, steps.map(function (item) { + return prosemirrorTransform.Step.fromJSON(schema, item.step); + }), steps.map(function (item) { + return item.clientID; + }))); + } + }; + } + }, { + key: "plugins", + get: function get() { + return [prosemirrorCollab.collab({ + version: this.options.version, + clientID: this.options.clientID + })]; + } + }]); + + return Collaboration; + }(tiptap.Extension); + + var Focus = + /*#__PURE__*/ + function (_Extension) { + _inherits(Focus, _Extension); + + function Focus() { + _classCallCheck(this, Focus); + + return _possibleConstructorReturn(this, _getPrototypeOf(Focus).apply(this, arguments)); + } + + _createClass(Focus, [{ + key: "name", + get: function get() { + return 'focus'; + } + }, { + key: "defaultOptions", + get: function get() { + return { + className: 'has-focus', + nested: false + }; + } + }, { + key: "plugins", + get: function get() { + var _this = this; + + return [new tiptap.Plugin({ + props: { + decorations: function decorations(_ref) { + var doc = _ref.doc, + plugins = _ref.plugins, + selection = _ref.selection; + var editablePlugin = plugins.find(function (plugin) { + return plugin.key.startsWith('editable$'); + }); + var editable = editablePlugin.props.editable(); + var active = editable && _this.options.className; + var focused = _this.editor.focused; + var anchor = selection.anchor; + var decorations = []; + + if (!active || !focused) { + return false; + } + + doc.descendants(function (node, pos) { + var hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize; + + if (hasAnchor && !node.isText) { + var decoration = prosemirrorView.Decoration.node(pos, pos + node.nodeSize, { + class: _this.options.className + }); + decorations.push(decoration); + } + + return _this.options.nested; + }); + return prosemirrorView.DecorationSet.create(doc, decorations); + } + } + })]; + } + }]); + + return Focus; + }(tiptap.Extension); + + var History = + /*#__PURE__*/ + function (_Extension) { + _inherits(History, _Extension); + + function History() { + _classCallCheck(this, History); + + return _possibleConstructorReturn(this, _getPrototypeOf(History).apply(this, arguments)); + } + + _createClass(History, [{ + key: "keys", + value: function keys() { + var keymap = { + 'Mod-z': prosemirrorHistory.undo, + 'Mod-y': prosemirrorHistory.redo, + 'Shift-Mod-z': prosemirrorHistory.redo + }; + return keymap; + } + }, { + key: "commands", + value: function commands() { + return { + undo: function undo() { + return prosemirrorHistory.undo; + }, + redo: function redo() { + return prosemirrorHistory.redo; + }, + undoDepth: function undoDepth() { + return prosemirrorHistory.undoDepth; + }, + redoDepth: function redoDepth() { + return prosemirrorHistory.redoDepth; + } + }; + } + }, { + key: "name", + get: function get() { + return 'history'; + } + }, { + key: "defaultOptions", + get: function get() { + return { + depth: '', + newGroupDelay: '' + }; + } + }, { + key: "plugins", + get: function get() { + return [prosemirrorHistory.history({ + depth: this.options.depth, + newGroupDelay: this.options.newGroupDelay + })]; + } + }]); + + return History; + }(tiptap.Extension); + + var Placeholder = + /*#__PURE__*/ + function (_Extension) { + _inherits(Placeholder, _Extension); + + function Placeholder() { + _classCallCheck(this, Placeholder); + + return _possibleConstructorReturn(this, _getPrototypeOf(Placeholder).apply(this, arguments)); + } + + _createClass(Placeholder, [{ + key: "name", + get: function get() { + return 'placeholder'; + } + }, { + key: "defaultOptions", + get: function get() { + return { + emptyEditorClass: 'is-editor-empty', + emptyNodeClass: 'is-empty', + emptyNodeText: 'Write something …', + showOnlyWhenEditable: true, + showOnlyCurrent: true + }; + } + }, { + key: "update", + get: function get() { + return function (view) { + view.updateState(view.state); + }; + } + }, { + key: "plugins", + get: function get() { + var _this = this; + + return [new tiptap.Plugin({ + props: { + decorations: function decorations(_ref) { + var doc = _ref.doc, + plugins = _ref.plugins, + selection = _ref.selection; + var editablePlugin = plugins.find(function (plugin) { + return plugin.key.startsWith('editable$'); + }); + var editable = editablePlugin.props.editable(); + var active = editable || !_this.options.showOnlyWhenEditable; + var anchor = selection.anchor; + var decorations = []; + var isEditorEmpty = doc.textContent.length === 0; + + if (!active) { + return false; + } + + doc.descendants(function (node, pos) { + var hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize; + var isNodeEmpty = node.content.size === 0; + + if ((hasAnchor || !_this.options.showOnlyCurrent) && isNodeEmpty) { + var classes = [_this.options.emptyNodeClass]; + + if (isEditorEmpty) { + classes.push(_this.options.emptyEditorClass); + } + + var decoration = prosemirrorView.Decoration.node(pos, pos + node.nodeSize, { + class: classes.join(' '), + 'data-empty-text': typeof _this.options.emptyNodeText === 'function' ? _this.options.emptyNodeText(node) : _this.options.emptyNodeText + }); + decorations.push(decoration); + } + + return false; + }); + return prosemirrorView.DecorationSet.create(doc, decorations); + } + } + })]; + } + }]); + + return Placeholder; + }(tiptap.Extension); + + var Search = + /*#__PURE__*/ + function (_Extension) { + _inherits(Search, _Extension); + + function Search() { + var _this; + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, Search); + + _this = _possibleConstructorReturn(this, _getPrototypeOf(Search).call(this, options)); + _this.results = []; + _this.searchTerm = null; + _this._updating = false; + return _this; + } + + _createClass(Search, [{ + key: "commands", + value: function commands() { + var _this2 = this; + + return { + find: function find(attrs) { + return _this2.find(attrs); + }, + replace: function replace(attrs) { + return _this2.replace(attrs); + }, + replaceAll: function replaceAll(attrs) { + return _this2.replaceAll(attrs); + }, + clearSearch: function clearSearch() { + return _this2.clear(); + } + }; + } + }, { + key: "_search", + value: function _search(doc) { + var _this3 = this; + + this.results = []; + var mergedTextNodes = []; + var index = 0; + + if (!this.searchTerm) { + return; + } + + doc.descendants(function (node, pos) { + if (node.isText) { + if (mergedTextNodes[index]) { + mergedTextNodes[index] = { + text: mergedTextNodes[index].text + node.text, + pos: mergedTextNodes[index].pos + }; + } else { + mergedTextNodes[index] = { + text: node.text, + pos: pos + }; + } + } else { + index += 1; + } + }); + mergedTextNodes.forEach(function (_ref) { + var text = _ref.text, + pos = _ref.pos; + var search = _this3.findRegExp; + var m; // eslint-disable-next-line no-cond-assign + + while (m = search.exec(text)) { + if (m[0] === '') { + break; + } + + _this3.results.push({ + from: pos + m.index, + to: pos + m.index + m[0].length + }); + } + }); + } + }, { + key: "replace", + value: function replace(_replace) { + var _this4 = this; + + return function (state, dispatch) { + var firstResult = _this4.results[0]; + + if (!firstResult) { + return; + } + + var _this4$results$ = _this4.results[0], + from = _this4$results$.from, + to = _this4$results$.to; + dispatch(state.tr.insertText(_replace, from, to)); + + _this4.editor.commands.find(_this4.searchTerm); + }; + } + }, { + key: "rebaseNextResult", + value: function rebaseNextResult(replace, index) { + var lastOffset = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + var nextIndex = index + 1; + + if (!this.results[nextIndex]) { + return null; + } + + var _this$results$index = this.results[index], + currentFrom = _this$results$index.from, + currentTo = _this$results$index.to; + var offset = currentTo - currentFrom - replace.length + lastOffset; + var _this$results$nextInd = this.results[nextIndex], + from = _this$results$nextInd.from, + to = _this$results$nextInd.to; + this.results[nextIndex] = { + to: to - offset, + from: from - offset + }; + return offset; + } + }, { + key: "replaceAll", + value: function replaceAll(replace) { + var _this5 = this; + + return function (_ref2, dispatch) { + var tr = _ref2.tr; + var offset; + + if (!_this5.results.length) { + return; + } + + _this5.results.forEach(function (_ref3, index) { + var from = _ref3.from, + to = _ref3.to; + tr.insertText(replace, from, to); + offset = _this5.rebaseNextResult(replace, index, offset); + }); + + dispatch(tr); + + _this5.editor.commands.find(_this5.searchTerm); + }; + } + }, { + key: "find", + value: function find(searchTerm) { + var _this6 = this; + + return function (state, dispatch) { + _this6.searchTerm = _this6.options.disableRegex ? searchTerm.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&') : searchTerm; + + _this6.updateView(state, dispatch); + }; + } + }, { + key: "clear", + value: function clear() { + var _this7 = this; + + return function (state, dispatch) { + _this7.searchTerm = null; + + _this7.updateView(state, dispatch); + }; + } + }, { + key: "updateView", + value: function updateView(_ref4, dispatch) { + var tr = _ref4.tr; + this._updating = true; + dispatch(tr); + this._updating = false; + } + }, { + key: "createDeco", + value: function createDeco(doc) { + this._search(doc); + + return this.decorations ? prosemirrorView.DecorationSet.create(doc, this.decorations) : []; + } + }, { + key: "name", + get: function get() { + return 'search'; + } + }, { + key: "defaultOptions", + get: function get() { + return { + autoSelectNext: true, + findClass: 'find', + searching: false, + caseSensitive: false, + disableRegex: true, + alwaysSearch: false + }; + } + }, { + key: "findRegExp", + get: function get() { + return RegExp(this.searchTerm, !this.options.caseSensitive ? 'gui' : 'gu'); + } + }, { + key: "decorations", + get: function get() { + var _this8 = this; + + return this.results.map(function (deco) { + return prosemirrorView.Decoration.inline(deco.from, deco.to, { + class: _this8.options.findClass + }); + }); + } + }, { + key: "plugins", + get: function get() { + var _this9 = this; + + return [new tiptap.Plugin({ + state: { + init: function init() { + return prosemirrorView.DecorationSet.empty; + }, + apply: function apply(tr, old) { + if (_this9._updating || _this9.options.searching || tr.docChanged && _this9.options.alwaysSearch) { + return _this9.createDeco(tr.doc); + } + + if (tr.docChanged) { + return old.map(tr.mapping, tr.doc); + } + + return old; + } + }, + props: { + decorations: function decorations(state) { + return this.getState(state); + } + } + })]; + } + }]); + + return Search; + }(tiptap.Extension); + + var TrailingNode = + /*#__PURE__*/ + function (_Extension) { + _inherits(TrailingNode, _Extension); + + function TrailingNode() { + _classCallCheck(this, TrailingNode); + + return _possibleConstructorReturn(this, _getPrototypeOf(TrailingNode).apply(this, arguments)); + } + + _createClass(TrailingNode, [{ + key: "name", + get: function get() { + return 'trailing_node'; + } + }, { + key: "defaultOptions", + get: function get() { + return { + node: 'paragraph', + notAfter: ['paragraph'] + }; + } + }, { + key: "plugins", + get: function get() { + var _this = this; + + var plugin = new tiptap.PluginKey(this.name); + var disabledNodes = Object.entries(this.editor.schema.nodes).map(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2), + value = _ref2[1]; + + return value; + }).filter(function (node) { + return _this.options.notAfter.includes(node.name); + }); + return [new tiptap.Plugin({ + key: plugin, + view: function view() { + return { + update: function update(view) { + var state = view.state; + var insertNodeAtEnd = plugin.getState(state); + + if (!insertNodeAtEnd) { + return; + } + + var doc = state.doc, + schema = state.schema, + tr = state.tr; + var type = schema.nodes[_this.options.node]; + var transaction = tr.insert(doc.content.size, type.create()); + view.dispatch(transaction); + } + }; + }, + state: { + init: function init(_, state) { + var lastNode = state.tr.doc.lastChild; + return !tiptapUtils.nodeEqualsType({ + node: lastNode, + types: disabledNodes + }); + }, + apply: function apply(tr, value) { + if (!tr.docChanged) { + return value; + } + + var lastNode = tr.doc.lastChild; + return !tiptapUtils.nodeEqualsType({ + node: lastNode, + types: disabledNodes + }); + } + } + })]; + } + }]); + + return TrailingNode; + }(tiptap.Extension); + + exports.Blockquote = Blockquote; + exports.Bold = Bold; + exports.BulletList = BulletList; + exports.Code = Code; + exports.CodeBlock = CodeBlock; + exports.CodeBlockHighlight = CodeBlockHighlight; + exports.Collaboration = Collaboration; + exports.Focus = Focus; + exports.HardBreak = HardBreak; + exports.Heading = Heading; + exports.Highlight = HighlightPlugin; + exports.History = History; + exports.HorizontalRule = HorizontalRule; + exports.Image = Image; + exports.Italic = Italic; + exports.Link = Link; + exports.ListItem = ListItem; + exports.Mention = Mention; + exports.OrderedList = OrderedList; + exports.Placeholder = Placeholder; + exports.Search = Search; + exports.Strike = Strike; + exports.Suggestions = SuggestionsPlugin; + exports.Table = Table; + exports.TableCell = TableCell; + exports.TableHeader = TableHeader; + exports.TableRow = TableRow; + exports.TodoItem = TodoItem; + exports.TodoList = TodoList; + exports.TrailingNode = TrailingNode; + exports.Underline = Underline; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}))); diff --git a/packages/tiptap-extensions/dist/extensions.min.js b/packages/tiptap-extensions/dist/extensions.min.js new file mode 100644 index 0000000000..17210ad3c2 --- /dev/null +++ b/packages/tiptap-extensions/dist/extensions.min.js @@ -0,0 +1,14 @@ + + /*! + * tiptap-extensions v1.28.6 + * (c) 2020 Scrumpy UG (limited liability) + * @license MIT + */ + + +/*! + * tiptap-extensions v1.28.6 + * (c) 2020 Scrumpy UG (limited liability) + * @license MIT + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("tiptap"),require("tiptap-commands"),require("lowlight/lib/core"),require("prosemirror-view"),require("prosemirror-utils"),require("prosemirror-state"),require("prosemirror-tables"),require("tiptap-utils"),require("prosemirror-transform"),require("prosemirror-collab"),require("prosemirror-history")):"function"==typeof define&&define.amd?define(["exports","tiptap","tiptap-commands","lowlight/lib/core","prosemirror-view","prosemirror-utils","prosemirror-state","prosemirror-tables","tiptap-utils","prosemirror-transform","prosemirror-collab","prosemirror-history"],e):e((t=t||self).tiptapExtensions={},t.tiptap,t.tiptapCommands,t.low,t.prosemirrorView,t.prosemirrorUtils,t.prosemirrorState,t.prosemirrorTables,t.tiptapUtils,t.prosemirrorTransform,t.prosemirrorCollab,t.prosemirrorHistory)}(this,(function(t,e,n,r,o,i,u,a,s,c,l,f){"use strict";function p(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function d(t,e){for(var n=0;n":n.toggleWrap(e)}}},{key:"inputRules",value:function(t){var e=t.type;return[n.wrappingInputRule(/^\s*>\s$/,e)]}},{key:"name",get:function(){return"blockquote"}},{key:"schema",get:function(){return{content:"block*",group:"block",defining:!0,draggable:!1,parseDOM:[{tag:"blockquote"}],toDOM:function(){return["blockquote",0]}}}}]),e}(e.Node),C=function(t){function e(){return p(this,e),w(this,k(e).apply(this,arguments))}return v(e,t),g(e,[{key:"commands",value:function(t){var e=t.type,r=t.schema;return function(){return n.toggleList(e,r.nodes.list_item)}}},{key:"keys",value:function(t){var e=t.type,r=t.schema;return{"Shift-Ctrl-8":n.toggleList(e,r.nodes.list_item)}}},{key:"inputRules",value:function(t){var e=t.type;return[n.wrappingInputRule(/^\s*([-+*])\s$/,e)]}},{key:"name",get:function(){return"bullet_list"}},{key:"schema",get:function(){return{content:"list_item+",group:"block",parseDOM:[{tag:"ul"}],toDOM:function(){return["ul",0]}}}}]),e}(e.Node),M=function(t){function e(){return p(this,e),w(this,k(e).apply(this,arguments))}return v(e,t),g(e,[{key:"commands",value:function(t){var e=t.type,r=t.schema;return function(){return n.toggleBlockType(e,r.nodes.paragraph)}}},{key:"keys",value:function(t){var e=t.type;return{"Shift-Ctrl-\\":n.setBlockType(e)}}},{key:"inputRules",value:function(t){var e=t.type;return[n.textblockTypeInputRule(/^```$/,e)]}},{key:"name",get:function(){return"code_block"}},{key:"schema",get:function(){return{content:"text*",marks:"",group:"block",code:!0,defining:!0,draggable:!1,parseDOM:[{tag:"pre",preserveWhitespace:"full"}],toDOM:function(){return["pre",["code",0]]}}}}]),e}(e.Node);function S(t){var e=t.doc,n=t.name,u=[],a=i.findBlockNodes(e).filter((function(t){return t.node.type.name===n}));return a.forEach((function(t){var e=t.pos+1;(function t(e){return e.reduce((function(e,n){return e.concat(Array.isArray(n)?t(n):n)}),[])})(function t(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];return e.map((function(e){var r=[].concat(x(n),x(e.properties?e.properties.className:[]));return e.children?t(e.children,r):{text:e.value,classes:r}}))}(r.highlightAuto(t.node.textContent).value)).map((function(t){var n=e,r=n+t.text.length;return e=r,m({},t,{from:n,to:r})})).forEach((function(t){var e=o.Decoration.inline(t.from,t.to,{class:t.classes.join(" ")});u.push(e)}))})),o.DecorationSet.create(e,u)}function T(t){var n=t.name;return new e.Plugin({name:new e.PluginKey("highlight"),state:{init:function(t,e){return S({doc:e.doc,name:n})},apply:function(t,e,r,o){var i=o.selection.$head.parent.type.name,u=r.selection.$head.parent.type.name;return t.docChanged&&[i,u].includes(n)?S({doc:t.doc,name:n}):e.map(t.mapping,t.doc)}},props:{decorations:function(t){return this.getState(t)}}})}var R=function(t){function e(){var t,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};p(this,e),t=w(this,k(e).call(this,n));try{Object.entries(t.options.languages).forEach((function(t){var e=O(t,2),n=e[0],o=e[1];r.registerLanguage(n,o)}))}catch(t){throw new Error("Invalid syntax highlight definitions: define at least one highlight.js language mapping")}return t}return v(e,t),g(e,[{key:"commands",value:function(t){var e=t.type,r=t.schema;return function(){return n.toggleBlockType(e,r.nodes.paragraph)}}},{key:"keys",value:function(t){var e=t.type;return{"Shift-Ctrl-\\":n.setBlockType(e)}}},{key:"inputRules",value:function(t){var e=t.type;return[n.textblockTypeInputRule(/^```$/,e)]}},{key:"name",get:function(){return"code_block"}},{key:"defaultOptions",get:function(){return{languages:{}}}},{key:"schema",get:function(){return{content:"text*",marks:"",group:"block",code:!0,defining:!0,draggable:!1,parseDOM:[{tag:"pre",preserveWhitespace:"full"}],toDOM:function(){return["pre",["code",0]]}}}},{key:"plugins",get:function(){return[T({name:this.name})]}}]),e}(e.Node),_=function(t){function e(){return p(this,e),w(this,k(e).apply(this,arguments))}return v(e,t),g(e,[{key:"keys",value:function(t){var e=t.type,r=n.chainCommands(n.exitCode,(function(t,n){return n(t.tr.replaceSelectionWith(e.create()).scrollIntoView()),!0}));return{"Mod-Enter":r,"Shift-Enter":r}}},{key:"name",get:function(){return"hard_break"}},{key:"schema",get:function(){return{inline:!0,group:"inline",selectable:!1,parseDOM:[{tag:"br"}],toDOM:function(){return["br"]}}}}]),e}(e.Node),A=function(t){function e(){return p(this,e),w(this,k(e).apply(this,arguments))}return v(e,t),g(e,[{key:"commands",value:function(t){var e=t.type,r=t.schema;return function(t){return n.toggleBlockType(e,r.nodes.paragraph,t)}}},{key:"keys",value:function(t){var e=t.type;return this.options.levels.reduce((function(t,r){return m({},t,{},h({},"Shift-Ctrl-".concat(r),n.setBlockType(e,{level:r})))}),{})}},{key:"inputRules",value:function(t){var e=t.type;return this.options.levels.map((function(t){return n.textblockTypeInputRule(new RegExp("^(#{1,".concat(t,"})\\s$")),e,(function(){return{level:t}}))}))}},{key:"name",get:function(){return"heading"}},{key:"defaultOptions",get:function(){return{levels:[1,2,3,4,5,6]}}},{key:"schema",get:function(){return{attrs:{level:{default:1}},content:"inline*",group:"block",defining:!0,draggable:!1,parseDOM:this.options.levels.map((function(t){return{tag:"h".concat(t),attrs:{level:t}}})),toDOM:function(t){return["h".concat(t.attrs.level),0]}}}}]),e}(e.Node),E=function(t){function e(){return p(this,e),w(this,k(e).apply(this,arguments))}return v(e,t),g(e,[{key:"commands",value:function(t){var e=t.type;return function(){return function(t,n){return n(t.tr.replaceSelectionWith(e.create()))}}}},{key:"inputRules",value:function(t){var e=t.type;return[n.nodeInputRule(/^(?:---|___\s|\*\*\*\s)$/,e)]}},{key:"name",get:function(){return"horizontal_rule"}},{key:"schema",get:function(){return{group:"block",parseDOM:[{tag:"hr"}],toDOM:function(){return["hr"]}}}}]),e}(e.Node),I=/!\[(.+|:?)]\((\S+)(?:(?:\s+)["'](\S+)["'])?\)/,N=function(t){function r(){return p(this,r),w(this,k(r).apply(this,arguments))}return v(r,t),g(r,[{key:"commands",value:function(t){var e=t.type;return function(t){return function(n,r){var o=n.selection,i=o.$cursor?o.$cursor.pos:o.$to.pos,u=e.create(t);r(n.tr.insert(i,u))}}}},{key:"inputRules",value:function(t){var e=t.type;return[n.nodeInputRule(I,e,(function(t){var e=O(t,4),n=e[1];return{src:e[2],alt:n,title:e[3]}}))]}},{key:"name",get:function(){return"image"}},{key:"schema",get:function(){return{inline:!0,attrs:{src:{},alt:{default:null},title:{default:null}},group:"inline",draggable:!0,parseDOM:[{tag:"img[src]",getAttrs:function(t){return{src:t.getAttribute("src"),title:t.getAttribute("title"),alt:t.getAttribute("alt")}}}],toDOM:function(t){return["img",t.attrs]}}}},{key:"plugins",get:function(){return[new e.Plugin({props:{handleDOMEvents:{drop:function(t,e){if(e.dataTransfer&&e.dataTransfer.files&&e.dataTransfer.files.length){var n=Array.from(e.dataTransfer.files).filter((function(t){return/image/i.test(t.type)}));if(0!==n.length){e.preventDefault();var r=t.state.schema,o=t.posAtCoords({left:e.clientX,top:e.clientY});n.forEach((function(e){var n=new FileReader;n.onload=function(e){var n=r.nodes.image.create({src:e.target.result}),i=t.state.tr.insert(o.pos,n);t.dispatch(i)},n.readAsDataURL(e)}))}}}}}})]}}]),r}(e.Node),j=function(t){function e(){return p(this,e),w(this,k(e).apply(this,arguments))}return v(e,t),g(e,[{key:"keys",value:function(t){var e=t.type;return{Enter:n.splitListItem(e),Tab:n.sinkListItem(e),"Shift-Tab":n.liftListItem(e)}}},{key:"name",get:function(){return"list_item"}},{key:"schema",get:function(){return{content:"paragraph block*",defining:!0,draggable:!1,parseDOM:[{tag:"li"}],toDOM:function(){return["li",0]}}}}]),e}(e.Node);function P(t){var e=t.matcher,r=void 0===e?{char:"@",allowSpaces:!1,startOfLine:!1}:e,i=t.appendText,a=void 0===i?null:i,s=t.suggestionClass,c=void 0===s?"suggestion":s,l=t.command,f=void 0===l?function(){return!1}:l,p=t.items,d=void 0===p?[]:p,g=t.onEnter,h=void 0===g?function(){return!1}:g,y=t.onChange,m=void 0===y?function(){return!1}:y,v=t.onExit,k=void 0===v?function(){return!1}:v,b=t.onKeyDown,w=void 0===b?function(){return!1}:b,O=t.onFilter,x=void 0===O?function(t,e){return e?t.filter((function(t){return JSON.stringify(t).toLowerCase().includes(e.toLowerCase())})):t}:O;return new u.Plugin({key:new u.PluginKey("suggestions"),view:function(){var t=this;return{update:function(e,r){var o=t.key.getState(r),i=t.key.getState(e.state),u=o.active&&i.active&&o.range.from!==i.range.from,s=!o.active&&i.active,c=o.active&&!i.active,l=s||u,p=!s&&!c&&o.query!==i.query&&!u,g=c||u;if(l||p||g){var y=g?o:i,v=document.querySelector('[data-decoration-id="'.concat(y.decorationId,'"]')),b=v?{getBoundingClientRect:function(){return v.getBoundingClientRect()},clientWidth:v.clientWidth,clientHeight:v.clientHeight}:null,w={view:e,range:y.range,query:y.query,text:y.text,decorationNode:v,virtualNode:b,items:x(Array.isArray(d)?d:d(),y.query),command:function(t){var r=t.range,o=t.attrs;f({range:r,attrs:o,schema:e.state.schema})(e.state,e.dispatch,e),a&&n.insertText(a)(e.state,e.dispatch,e)}};g&&k(w),p&&m(w),l&&h(w)}}}},state:{init:function(){return{active:!1,range:{},query:null,text:null}},apply:function(t,e){var n,o,i,u,a,s,c,l=t.selection,f=Object.assign({},e);if(l.from===l.to){(l.frome.range.to)&&(f.active=!1);var p=l.$from,d=(o=(n=r).char,i=void 0===o?"@":o,u=n.allowSpaces,a=void 0!==u&&u,s=n.startOfLine,c=void 0!==s&&s,function(t){if(t.depth<=0)return!1;for(var e,n="\\".concat(i),r=new RegExp("\\s".concat(n,"$")),o=c?"^":"",u=a?new RegExp("".concat(o).concat(n,".*?(?=\\s").concat(n,"|$)"),"gm"):new RegExp("".concat(o,"(?:^)?").concat(n,"[^\\s|\\0").concat(n,"]*"),"gm"),s=t.before(),l=t.end(),f=t.doc.textBetween(s,l,"\0","\0"),p=u.exec(f);null!==p;){var d=p.input.slice(Math.max(0,p.index-1),p.index);if(/^[\s\0]?$/.test(d)){var g=p.index+t.start(),h=g+p[0].length;a&&r.test(f.slice(h-1,h+1))&&(p[0]+=" ",h+=1),g=t.pos&&(e={range:{from:g,to:h},query:p[0].slice(i.length),text:p[0]})}p=u.exec(f)}return e})(p),g=(Math.random()+1).toString(36).substr(2,5);d?(f.active=!0,f.decorationId=e.decorationId?e.decorationId:g,f.range=d.range,f.query=d.query,f.text=d.text):f.active=!1}else f.active=!1;return f.active||(f.decorationId=null,f.range={},f.query=null,f.text=null),f}},props:{handleKeyDown:function(t,e){var n=this.getState(t.state),r=n.active,o=n.range;return!!r&&w({view:t,event:e,range:o})},decorations:function(t){var e=this.getState(t),n=e.active,r=e.range,i=e.decorationId;return n?o.DecorationSet.create(t.doc,[o.Decoration.inline(r.from,r.to,{nodeName:"span",class:c,"data-decoration-id":i})]):null}}})}var q=function(t){function e(){return p(this,e),w(this,k(e).apply(this,arguments))}return v(e,t),g(e,[{key:"commands",value:function(t){var e=this,r=t.schema;return function(t){return n.replaceText(null,r.nodes[e.name],t)}}},{key:"name",get:function(){return"mention"}},{key:"defaultOptions",get:function(){return{matcher:{char:"@",allowSpaces:!1,startOfLine:!1},mentionClass:"mention",suggestionClass:"mention-suggestion"}}},{key:"schema",get:function(){var t=this;return{attrs:{id:{},label:{}},group:"inline",inline:!0,selectable:!1,atom:!0,toDOM:function(e){return["span",{class:t.options.mentionClass,"data-mention-id":e.attrs.id},"".concat(t.options.matcher.char).concat(e.attrs.label)]},parseDOM:[{tag:"span[data-mention-id]",getAttrs:function(e){return{id:e.getAttribute("data-mention-id"),label:e.innerText.split(t.options.matcher.char).join("")}}}]}}},{key:"plugins",get:function(){var t=this;return[P({command:function(e){var r=e.range,o=e.attrs,i=e.schema;return n.replaceText(r,i.nodes[t.name],o)},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})]}}]),e}(e.Node),$=function(t){function e(){return p(this,e),w(this,k(e).apply(this,arguments))}return v(e,t),g(e,[{key:"commands",value:function(t){var e=t.type,r=t.schema;return function(){return n.toggleList(e,r.nodes.list_item)}}},{key:"keys",value:function(t){var e=t.type,r=t.schema;return{"Shift-Ctrl-9":n.toggleList(e,r.nodes.list_item)}}},{key:"inputRules",value:function(t){var e=t.type;return[n.wrappingInputRule(/^(\d+)\.\s$/,e,(function(t){return{order:+t[1]}}),(function(t,e){return e.childCount+e.attrs.order===+t[1]}))]}},{key:"name",get:function(){return"ordered_list"}},{key:"schema",get:function(){return{attrs:{order:{default:1}},content:"list_item+",group:"block",parseDOM:[{tag:"ol",getAttrs:function(t){return{order:t.hasAttribute("start")?+t.getAttribute("start"):1}}}],toDOM:function(t){return 1===t.attrs.order?["ol",0]:["ol",{start:t.attrs.order},0]}}}}]),e}(e.Node),L=a.tableNodes({tableGroup:"block",cellContent:"block+",cellAttributes:{background:{default:null,getFromDOM:function(t){return t.style.backgroundColor||null},setDOMAttr:function(t,e){if(t){var n={style:"".concat(e.style||"","background-color: ").concat(t,";")};Object.assign(e,n)}}}}}),B=function(t){function e(){return p(this,e),w(this,k(e).apply(this,arguments))}return v(e,t),g(e,[{key:"commands",value:function(t){var e=t.schema;return{createTable:function(t){var n=t.rowsCount,r=t.colsCount,o=t.withHeaderRow;return function(t,a){var s=t.tr.selection.anchor+1,c=i.createTable(e,n,r,o),l=t.tr.replaceSelectionWith(c).scrollIntoView(),f=l.doc.resolve(s);l.setSelection(u.TextSelection.near(f)),a(l)}},addColumnBefore:function(){return a.addColumnBefore},addColumnAfter:function(){return a.addColumnAfter},deleteColumn:function(){return a.deleteColumn},addRowBefore:function(){return a.addRowBefore},addRowAfter:function(){return a.addRowAfter},deleteRow:function(){return a.deleteRow},deleteTable:function(){return a.deleteTable},toggleCellMerge:function(){return function(t,e){a.mergeCells(t,e)||a.splitCell(t,e)}},mergeCells:function(){return a.mergeCells},splitCell:function(){return a.splitCell},toggleHeaderColumn:function(){return a.toggleHeaderColumn},toggleHeaderRow:function(){return a.toggleHeaderRow},toggleHeaderCell:function(){return a.toggleHeaderCell},setCellAttr:function(){return a.setCellAttr},fixTables:function(){return a.fixTables}}}},{key:"keys",value:function(){return{Tab:a.goToNextCell(1),"Shift-Tab":a.goToNextCell(-1)}}},{key:"name",get:function(){return"table"}},{key:"defaultOptions",get:function(){return{resizable:!1}}},{key:"schema",get:function(){return L.table}},{key:"plugins",get:function(){return[].concat(x(this.options.resizable?[a.columnResizing()]:[]),[a.tableEditing()])}}]),e}(e.Node),H=function(t){function e(){return p(this,e),w(this,k(e).apply(this,arguments))}return v(e,t),g(e,[{key:"name",get:function(){return"table_header"}},{key:"schema",get:function(){return L.table_header}}]),e}(e.Node),z=function(t){function e(){return p(this,e),w(this,k(e).apply(this,arguments))}return v(e,t),g(e,[{key:"name",get:function(){return"table_cell"}},{key:"schema",get:function(){return L.table_cell}}]),e}(e.Node),W=function(t){function e(){return p(this,e),w(this,k(e).apply(this,arguments))}return v(e,t),g(e,[{key:"name",get:function(){return"table_row"}},{key:"schema",get:function(){return L.table_row}}]),e}(e.Node),K=function(t){function e(){return p(this,e),w(this,k(e).apply(this,arguments))}return v(e,t),g(e,[{key:"keys",value:function(t){var e=t.type;return{Enter:n.splitToDefaultListItem(e),Tab:this.options.nested?n.sinkListItem(e):function(){},"Shift-Tab":n.liftListItem(e)}}},{key:"name",get:function(){return"todo_item"}},{key:"defaultOptions",get:function(){return{nested:!1}}},{key:"view",get:function(){return{props:["node","updateAttrs","view"],methods:{onChange:function(){this.updateAttrs({done:!this.node.attrs.done})}},template:'\n
  • \n \n
    \n
  • \n '}}},{key:"schema",get:function(){var t=this;return{attrs:{done:{default:!1}},draggable:!0,content:this.options.nested?"(paragraph|todo_list)+":"paragraph+",toDOM:function(e){var n=e.attrs.done;return["li",{"data-type":t.name,"data-done":n.toString()},["span",{class:"todo-checkbox",contenteditable:"false"}],["div",{class:"todo-content"},0]]},parseDOM:[{priority:51,tag:'[data-type="'.concat(this.name,'"]'),getAttrs:function(t){return{done:"true"===t.getAttribute("data-done")}}}]}}}]),e}(e.Node),V=function(t){function e(){return p(this,e),w(this,k(e).apply(this,arguments))}return v(e,t),g(e,[{key:"commands",value:function(t){var e=t.type,r=t.schema;return function(){return n.toggleList(e,r.nodes.todo_item)}}},{key:"inputRules",value:function(t){var e=t.type;return[n.wrappingInputRule(/^\s*(\[ \])\s$/,e)]}},{key:"name",get:function(){return"todo_list"}},{key:"schema",get:function(){var t=this;return{group:"block",content:"todo_item+",toDOM:function(){return["ul",{"data-type":t.name},0]},parseDOM:[{priority:51,tag:'[data-type="'.concat(this.name,'"]')}]}}}]),e}(e.Node),F=function(t){function e(){return p(this,e),w(this,k(e).apply(this,arguments))}return v(e,t),g(e,[{key:"keys",value:function(t){var e=t.type;return{"Mod-b":n.toggleMark(e)}}},{key:"commands",value:function(t){var e=t.type;return function(){return n.toggleMark(e)}}},{key:"inputRules",value:function(t){var e=t.type;return[n.markInputRule(/(?:\*\*|__)([^*_]+)(?:\*\*|__)$/,e)]}},{key:"pasteRules",value:function(t){var e=t.type;return[n.markPasteRule(/(?:\*\*|__)([^*_]+)(?:\*\*|__)/g,e)]}},{key:"name",get:function(){return"bold"}},{key:"schema",get:function(){return{parseDOM:[{tag:"strong"},{tag:"b",getAttrs:function(t){return"normal"!==t.style.fontWeight&&null}},{style:"font-weight",getAttrs:function(t){return/^(bold(er)?|[5-9]\d{2,})$/.test(t)&&null}}],toDOM:function(){return["strong",0]}}}}]),e}(e.Mark),G=function(t){function e(){return p(this,e),w(this,k(e).apply(this,arguments))}return v(e,t),g(e,[{key:"keys",value:function(t){var e=t.type;return{"Mod-`":n.toggleMark(e)}}},{key:"commands",value:function(t){var e=t.type;return function(){return n.toggleMark(e)}}},{key:"inputRules",value:function(t){var e=t.type;return[n.markInputRule(/(?:`)([^`]+)(?:`)$/,e)]}},{key:"pasteRules",value:function(t){var e=t.type;return[n.markPasteRule(/(?:`)([^`]+)(?:`)/g,e)]}},{key:"name",get:function(){return"code"}},{key:"schema",get:function(){return{excludes:"_",parseDOM:[{tag:"code"}],toDOM:function(){return["code",0]}}}}]),e}(e.Mark),U=function(t){function e(){return p(this,e),w(this,k(e).apply(this,arguments))}return v(e,t),g(e,[{key:"keys",value:function(t){var e=t.type;return{"Mod-i":n.toggleMark(e)}}},{key:"commands",value:function(t){var e=t.type;return function(){return n.toggleMark(e)}}},{key:"inputRules",value:function(t){var e=t.type;return[n.markInputRule(/(?:^|[^_])(_([^_]+)_)$/,e),n.markInputRule(/(?:^|[^*])(\*([^*]+)\*)$/,e)]}},{key:"pasteRules",value:function(t){var e=t.type;return[n.markPasteRule(/_([^_]+)_/g,e),n.markPasteRule(/\*([^*]+)\*/g,e)]}},{key:"name",get:function(){return"italic"}},{key:"schema",get:function(){return{parseDOM:[{tag:"i"},{tag:"em"},{style:"font-style=italic"}],toDOM:function(){return["em",0]}}}}]),e}(e.Mark),J=function(t){function r(){return p(this,r),w(this,k(r).apply(this,arguments))}return v(r,t),g(r,[{key:"commands",value:function(t){var e=t.type;return function(t){return t.href?n.updateMark(e,t):n.removeMark(e)}}},{key:"pasteRules",value:function(t){var e=t.type;return[n.pasteRule(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-zA-Z]{2,}\b([-a-zA-Z0-9@:%_+.~#?&//=]*)/g,e,(function(t){return{href:t}}))]}},{key:"name",get:function(){return"link"}},{key:"defaultOptions",get:function(){return{openOnClick:!0}}},{key:"schema",get:function(){return{attrs:{href:{default:null}},inclusive:!1,parseDOM:[{tag:"a[href]",getAttrs:function(t){return{href:t.getAttribute("href")}}}],toDOM:function(t){return["a",m({},t.attrs,{rel:"noopener noreferrer nofollow"}),0]}}}},{key:"plugins",get:function(){return this.options.openOnClick?[new e.Plugin({props:{handleClick:function(t,e,n){var r=t.state.schema,o=s.getMarkAttrs(t.state,r.marks.link);o.href&&n.target instanceof HTMLAnchorElement&&(n.stopPropagation(),window.open(o.href))}}})]:[]}}]),r}(e.Mark),Z=function(t){function e(){return p(this,e),w(this,k(e).apply(this,arguments))}return v(e,t),g(e,[{key:"keys",value:function(t){var e=t.type;return{"Mod-d":n.toggleMark(e)}}},{key:"commands",value:function(t){var e=t.type;return function(){return n.toggleMark(e)}}},{key:"inputRules",value:function(t){var e=t.type;return[n.markInputRule(/~([^~]+)~$/,e)]}},{key:"pasteRules",value:function(t){var e=t.type;return[n.markPasteRule(/~([^~]+)~/g,e)]}},{key:"name",get:function(){return"strike"}},{key:"schema",get:function(){return{parseDOM:[{tag:"s"},{tag:"del"},{tag:"strike"},{style:"text-decoration",getAttrs:function(t){return"line-through"===t}}],toDOM:function(){return["s",0]}}}}]),e}(e.Mark),X=function(t){function e(){return p(this,e),w(this,k(e).apply(this,arguments))}return v(e,t),g(e,[{key:"keys",value:function(t){var e=t.type;return{"Mod-u":n.toggleMark(e)}}},{key:"commands",value:function(t){var e=t.type;return function(){return n.toggleMark(e)}}},{key:"name",get:function(){return"underline"}},{key:"schema",get:function(){return{parseDOM:[{tag:"u"},{style:"text-decoration",getAttrs:function(t){return"underline"===t}}],toDOM:function(){return["u",0]}}}}]),e}(e.Mark),Y=function(t){function e(){return p(this,e),w(this,k(e).apply(this,arguments))}return v(e,t),g(e,[{key:"init",value:function(){var t=this;this.getSendableSteps=this.debounce((function(e){var n=l.sendableSteps(e);n&&t.options.onSendable({editor:t.editor,sendable:{version:n.version,steps:n.steps.map((function(t){return t.toJSON()})),clientID:n.clientID}})}),this.options.debounce),this.editor.on("transaction",(function(e){var n=e.state;t.getSendableSteps(n)}))}},{key:"debounce",value:function(t,e){var n;return function(){for(var r=arguments.length,o=new Array(r),i=0;ir||u.dispatch(l.receiveTransaction(i,n.map((function(t){return c.Step.fromJSON(a,t.step)})),n.map((function(t){return t.clientID}))))}}}},{key:"plugins",get:function(){return[l.collab({version:this.options.version,clientID:this.options.clientID})]}}]),e}(e.Extension),Q=function(t){function n(){return p(this,n),w(this,k(n).apply(this,arguments))}return v(n,t),g(n,[{key:"name",get:function(){return"focus"}},{key:"defaultOptions",get:function(){return{className:"has-focus",nested:!1}}},{key:"plugins",get:function(){var t=this;return[new e.Plugin({props:{decorations:function(e){var n=e.doc,r=e.plugins,i=e.selection,u=r.find((function(t){return t.key.startsWith("editable$")})).props.editable()&&t.options.className,a=t.editor.focused,s=i.anchor,c=[];return!(!u||!a)&&(n.descendants((function(e,n){if(s>=n&&s<=n+e.nodeSize&&!e.isText){var r=o.Decoration.node(n,n+e.nodeSize,{class:t.options.className});c.push(r)}return t.options.nested})),o.DecorationSet.create(n,c))}}})]}}]),n}(e.Extension),tt=function(t){function e(){return p(this,e),w(this,k(e).apply(this,arguments))}return v(e,t),g(e,[{key:"keys",value:function(){return{"Mod-z":f.undo,"Mod-y":f.redo,"Shift-Mod-z":f.redo}}},{key:"commands",value:function(){return{undo:function(){return f.undo},redo:function(){return f.redo},undoDepth:function(){return f.undoDepth},redoDepth:function(){return f.redoDepth}}}},{key:"name",get:function(){return"history"}},{key:"defaultOptions",get:function(){return{depth:"",newGroupDelay:""}}},{key:"plugins",get:function(){return[f.history({depth:this.options.depth,newGroupDelay:this.options.newGroupDelay})]}}]),e}(e.Extension),et=function(t){function n(){return p(this,n),w(this,k(n).apply(this,arguments))}return v(n,t),g(n,[{key:"name",get:function(){return"placeholder"}},{key:"defaultOptions",get:function(){return{emptyEditorClass:"is-editor-empty",emptyNodeClass:"is-empty",emptyNodeText:"Write something \u2026",showOnlyWhenEditable:!0,showOnlyCurrent:!0}}},{key:"update",get:function(){return function(t){t.updateState(t.state)}}},{key:"plugins",get:function(){var t=this;return[new e.Plugin({props:{decorations:function(e){var n=e.doc,r=e.plugins,i=e.selection,u=r.find((function(t){return t.key.startsWith("editable$")})).props.editable()||!t.options.showOnlyWhenEditable,a=i.anchor,s=[],c=0===n.textContent.length;return!!u&&(n.descendants((function(e,n){var r=a>=n&&a<=n+e.nodeSize,i=0===e.content.size;if((r||!t.options.showOnlyCurrent)&&i){var u=[t.options.emptyNodeClass];c&&u.push(t.options.emptyEditorClass);var l=o.Decoration.node(n,n+e.nodeSize,{class:u.join(" "),"data-empty-text":"function"==typeof t.options.emptyNodeText?t.options.emptyNodeText(e):t.options.emptyNodeText});s.push(l)}return!1})),o.DecorationSet.create(n,s))}}})]}}]),n}(e.Extension),nt=function(t){function n(){var t,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return p(this,n),(t=w(this,k(n).call(this,e))).results=[],t.searchTerm=null,t._updating=!1,t}return v(n,t),g(n,[{key:"commands",value:function(){var t=this;return{find:function(e){return t.find(e)},replace:function(e){return t.replace(e)},replaceAll:function(e){return t.replaceAll(e)},clearSearch:function(){return t.clear()}}}},{key:"_search",value:function(t){var e=this;this.results=[];var n=[],r=0;this.searchTerm&&(t.descendants((function(t,e){t.isText?n[r]?n[r]={text:n[r].text+t.text,pos:n[r].pos}:n[r]={text:t.text,pos:e}:r+=1})),n.forEach((function(t){for(var n,r=t.text,o=t.pos,i=e.findRegExp;(n=i.exec(r))&&""!==n[0];)e.results.push({from:o+n.index,to:o+n.index+n[0].length})})))}},{key:"replace",value:function(t){var e=this;return function(n,r){if(e.results[0]){var o=e.results[0],i=o.from,u=o.to;r(n.tr.insertText(t,i,u)),e.editor.commands.find(e.searchTerm)}}}},{key:"rebaseNextResult",value:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,r=e+1;if(!this.results[r])return null;var o=this.results[e],i=o.from,u=o.to,a=u-i-t.length+n,s=this.results[r],c=s.from,l=s.to;return this.results[r]={to:l-a,from:c-a},a}},{key:"replaceAll",value:function(t){var e=this;return function(n,r){var o,i=n.tr;e.results.length&&(e.results.forEach((function(n,r){var u=n.from,a=n.to;i.insertText(t,u,a),o=e.rebaseNextResult(t,r,o)})),r(i),e.editor.commands.find(e.searchTerm))}}},{key:"find",value:function(t){var e=this;return function(n,r){e.searchTerm=e.options.disableRegex?t.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"):t,e.updateView(n,r)}}},{key:"clear",value:function(){var t=this;return function(e,n){t.searchTerm=null,t.updateView(e,n)}}},{key:"updateView",value:function(t,e){var n=t.tr;this._updating=!0,e(n),this._updating=!1}},{key:"createDeco",value:function(t){return this._search(t),this.decorations?o.DecorationSet.create(t,this.decorations):[]}},{key:"name",get:function(){return"search"}},{key:"defaultOptions",get:function(){return{autoSelectNext:!0,findClass:"find",searching:!1,caseSensitive:!1,disableRegex:!0,alwaysSearch:!1}}},{key:"findRegExp",get:function(){return RegExp(this.searchTerm,this.options.caseSensitive?"gu":"gui")}},{key:"decorations",get:function(){var t=this;return this.results.map((function(e){return o.Decoration.inline(e.from,e.to,{class:t.options.findClass})}))}},{key:"plugins",get:function(){var t=this;return[new e.Plugin({state:{init:function(){return o.DecorationSet.empty},apply:function(e,n){return t._updating||t.options.searching||e.docChanged&&t.options.alwaysSearch?t.createDeco(e.doc):e.docChanged?n.map(e.mapping,e.doc):n}},props:{decorations:function(t){return this.getState(t)}}})]}}]),n}(e.Extension),rt=function(t){function n(){return p(this,n),w(this,k(n).apply(this,arguments))}return v(n,t),g(n,[{key:"name",get:function(){return"trailing_node"}},{key:"defaultOptions",get:function(){return{node:"paragraph",notAfter:["paragraph"]}}},{key:"plugins",get:function(){var t=this,n=new e.PluginKey(this.name),r=Object.entries(this.editor.schema.nodes).map((function(t){return O(t,2)[1]})).filter((function(e){return t.options.notAfter.includes(e.name)}));return[new e.Plugin({key:n,view:function(){return{update:function(e){var r=e.state;if(n.getState(r)){var o=r.doc,i=r.schema,u=r.tr,a=i.nodes[t.options.node],s=u.insert(o.content.size,a.create());e.dispatch(s)}}}},state:{init:function(t,e){var n=e.tr.doc.lastChild;return!s.nodeEqualsType({node:n,types:r})},apply:function(t,e){if(!t.docChanged)return e;var n=t.doc.lastChild;return!s.nodeEqualsType({node:n,types:r})}}})]}}]),n}(e.Extension);t.Blockquote=D,t.Bold=F,t.BulletList=C,t.Code=G,t.CodeBlock=M,t.CodeBlockHighlight=R,t.Collaboration=Y,t.Focus=Q,t.HardBreak=_,t.Heading=A,t.Highlight=T,t.History=tt,t.HorizontalRule=E,t.Image=N,t.Italic=U,t.Link=J,t.ListItem=j,t.Mention=q,t.OrderedList=$,t.Placeholder=et,t.Search=nt,t.Strike=Z,t.Suggestions=P,t.Table=B,t.TableCell=z,t.TableHeader=H,t.TableRow=W,t.TodoItem=K,t.TodoList=V,t.TrailingNode=rt,t.Underline=X,Object.defineProperty(t,"__esModule",{value:!0})})); \ No newline at end of file diff --git a/packages/tiptap-extensions/node_modules/prosemirror-transform/.tern-project b/packages/tiptap-extensions/node_modules/prosemirror-transform/.tern-project new file mode 100644 index 0000000000..dde39765e5 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-transform/.tern-project @@ -0,0 +1,8 @@ +{ + "libs": ["browser"], + "plugins": { + "node": {}, + "complete_strings": {}, + "es_modules": {} + } +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-transform/CHANGELOG.md b/packages/tiptap-extensions/node_modules/prosemirror-transform/CHANGELOG.md new file mode 100644 index 0000000000..11d23e5253 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-transform/CHANGELOG.md @@ -0,0 +1,278 @@ +## 1.2.3 (2019-12-03) + +### Bug fixes + +Fix a crash in `deleteRange` that occurred when deleting a region that spans to the ends of two nodes at different depths. + +## 1.2.2 (2019-11-20) + +### Bug fixes + +Rename ES module files to use a .js extension, since Webpack gets confused by .mjs + +## 1.2.1 (2019-11-19) + +### Bug fixes + +The file referred to in the package's `module` field now is compiled down to ES5. + +## 1.2.0 (2019-11-08) + +### New features + +Add a `module` field to package json file. + +## 1.1.6 (2019-11-01) + +### Bug fixes + +Fixes an issue where deleting a range from the start of block A to the end of block B would leave you with an empty block of type B. + +## 1.1.5 (2019-10-02) + +### Bug fixes + +Fix crash in building replace steps for open-ended slices with complicated node content expressions. + +## 1.1.4 (2019-08-26) + +### Bug fixes + +[`Mapping.invert`](https://prosemirror.net/docs/ref/#transform.Mapping.invert) is now part of the documented API (it was intented to be public from the start, but a typo prevented it from showing up in the docs). + +Fix an issue where a replace could needlessly drop content when the first node of the slice didn't fit the target context. + +`replaceRange` now more aggressively expands the replaced region if `replace` fails to place the slice. + +## 1.1.3 (2018-07-03) + +### Bug fixes + +Replacing from a code block into a paragraph that has marks, or similar scenarios that would join content with the wrong marks into a node, no longer crashes. + +## 1.1.2 (2018-06-29) + +### Bug fixes + +Fix issue where [`replaceRange`](https://prosemirror.net/docs/ref/#transform.Transform.replaceRange) might create invalid nodes. + +## 1.1.1 (2018-06-26) + +### Bug fixes + +Fix issues in the new [`dropPoint`](https://prosemirror.net/docs/ref/#transform.dropPoint) function. + +## 1.1.0 (2018-06-20) + +### New features + +[`Transform.getMirror`](https://prosemirror.net/docs/ref/#transform.Transform.getMirror), usable in obscure circumstances for inspecting the mirroring structure or a transform, is now a public method. + +New utility function [`dropPoint`](https://prosemirror.net/docs/ref/#transform.dropPoint), which tries to find a valid position for dropping a slice near a given document position. + +## 1.0.10 (2018-04-15) + +### Bug fixes + +[`Transform.setBlockType`](https://prosemirror.net/docs/ref/#transform.Transform.setBlockType) no longer drops marks on the nodes it updates. + +## 1.0.9 (2018-04-05) + +### Bug fixes + +Fix a bug that made [`replaceStep`](https://prosemirror.net/docs/ref/#transform.replaceStep) unable to generate wrapper nodes in some circumstances. + +## 1.0.8 (2018-04-04) + +### Bug fixes + +Fixes an issue where [`replaceStep`](https://prosemirror.net/docs/ref/#transform.replaceStep) could generate slices that internally violated the schema. + +## 1.0.7 (2018-03-21) + +### Bug fixes + +[`Transform.deleteRange`](https://prosemirror.net/docs/ref/#transform.Transform.deleteRange) will cover unmatched opening at the start of the deleted range. + +## 1.0.6 (2018-03-15) + +### Bug fixes + +Throw errors, rather than constructing invalid objects, when deserializing from invalid JSON data. + +## 1.0.5 (2018-03-14) + +### Bug fixes + +[`replaceStep`](https://prosemirror.net/docs/ref/#transform.replaceStep) will now return null rather than an empty step when it fails to place the slice. + +Avoid duplicating defining parent nodes in [`replaceRange`](https://prosemirror.net/docs/ref/#tranform.Transform.replaceRange). + +## 1.0.4 (2018-02-23) + +### Bug fixes + +Fix overeager closing of destination nodes when fitting a slice during replacing. + +## 1.0.3 (2018-02-23) + +### Bug fixes + +Fix a problem where slice-placing didn't handle content matches correctly and might generate invalid steps or fail to generate steps though a valid one exists. + +Allows adjacent nodes from an inserted slice to be placed in different parent nodes, allowing `Transform.replace` to create fits that weren't previously found. + +## 1.0.2 (2018-01-24) + +### Bug fixes + +Fixes a crash in [`replace`](https://prosemirror.net/docs/ref/#transform.Transform.replace). + +## 1.0.1 (2017-11-10) + +### Bug fixes + +The errors raised by [`Transform.step`](https://prosemirror.net/docs/ref/#transform.Transform.step) now properly inherit from Error. + +## 1.0.0 (2017-10-13) + +### Bug fixes + +When [`setBlockType`](https://prosemirror.net/docs/ref/#transform.Transform.setBlockType) comes across a textblock that can't be changed due to schema constraints, it skips it instead of failing. + +[`canSplit`](https://prosemirror.net/docs/ref/#transform.canSplit) now returns false when the requested split goes through isolating nodes. + +## 0.24.0 (2017-09-25) + +### Breaking changes + +The `setNodeType` method on transforms is now more descriptively called [`setNodeMarkup`](https://prosemirror.net/docs/ref/version/0.24.0.html#transform.Transform.setNodeMarkup). The old name will continue to work with a warning until the next release. + +## 0.23.0 (2017-09-13) + +### Breaking changes + +[`Step.toJSON`](https://prosemirror.net/docs/ref/version/0.23.0.html#transform.Step.toJSON) no longer has a default implementation. + +Steps no longer have an `offset` method. Map them through a map created with [`StepMap.offset`](https://prosemirror.net/docs/ref/version/0.23.0.html#transform.StepMap^offset) instead. + +The `clearMarkup` method on [`Transform`](https://prosemirror.net/docs/ref/version/0.23.0.html#transform.Transform) is no longer supported (you probably needed [`clearIncompatible`](https://prosemirror.net/docs/ref/version/0.23.0.html#transform.Transform.clearIncompatible) anyway). + +### Bug fixes + +Pasting a list item at the start of a non-empty textblock now wraps the textblock in a list. + +Marks on open nodes at the left of a slice are no longer dropped by [`Transform.replace`](https://prosemirror.net/docs/ref/version/0.23.0.html#transform.Transform.replace). + +### New features + +`StepMap` now has a static method [`offset`](https://prosemirror.net/docs/ref/version/0.23.0.html#transform.StepMap^offset), which can be used to create a map that offsets all positions by a given distance. + +Transform objects now have a [`clearIncompatible`](https://prosemirror.net/docs/ref/version/0.23.0.html#transform.Transform.clearIncompatible) method that can help make sure a node's content matches another node type. + +## 0.22.2 (2017-07-06) + +### Bug fixes + +Fix another bug in the way `canSplit` interpreted its `typesAfter` argument. + +## 0.22.1 (2017-07-03) + +### Bug fixes + +Fix crash in [`canSplit`](https://prosemirror.net/docs/ref/version/0.22.0.html#transform.canSplit) when an array containing null fields is passed as fourth argument. + +## 0.22.0 (2017-06-29) + +### Bug fixes + +[`canSplit`](https://prosemirror.net/docs/ref/version/0.22.0.html#transform.canSplit) now returns false when given custom after-split node types that don't match the content at that point. + +Fixes [`canLift`](https://prosemirror.net/docs/ref/version/0.22.0.html#transform.canLift) incorrectly returning null when lifting into an isolating node. + +## 0.21.1 (2017-05-16) + +### Bug fixes + +[`addMark`](https://prosemirror.net/docs/ref/version/0.21.0.html#transform.Transform.addMark) no longer assumes marks always [exclude](https://prosemirror.net/docs/ref/version/0.21.0.html#model.MarkSpec.excludes) only themselves. + +`replaceRange`](https://prosemirror.net/docs/ref/version/0.21.0.html#transform.Transform.replaceRange) and [`deleteRange`](https://prosemirror.net/docs/ref/version/0.21.0.html#transform.Transform.deleteRange) will no longer expand the range across isolating node boundaries. + +## 0.20.0 (2017-04-03) + +### Bug fixes + +Fixes issue where replacing would sometimes unexpectedly split nodes. + +## 0.18.0 (2017-02-24) + +### New features + +[`Transform.setNodeType`](https://prosemirror.net/docs/ref/version/0.18.0.html#transform.Transform.setNodeType) now takes an optional argument to set the new node's attributes. + +Steps now provide an [`offset`](https://prosemirror.net/docs/ref/version/0.18.0.html#transform.Step.offset) method, which makes it possible to create a copy the step with its position offset by a given amount. + +[`docChanged`](https://prosemirror.net/docs/ref/version/0.18.0.html#transform.Transform.docChanged) is now a property on the `Transform` class, rather than its `Transaction` subclass. + +`Mapping` instances now have [`invert`](https://prosemirror.net/docs/ref/version/0.18.0.html#transform.Mapping.invert) and [`appendMappingInverted`](https://prosemirror.net/docs/ref/version/0.18.0.html#transform.Mapping.appendMappingInverted) methods to make mapping through them in reverse easier. + +## 0.15.0 (2016-12-10) + +### Bug fixes + +Fix bug where pasted/inserted content would sometimes get incorrectly closed at the right side. + +## 0.13.0 (2016-11-11) + +### Bug fixes + +Fix issue where [`Transform.replace`](https://prosemirror.net/docs/ref/version/0.13.0.html#transform.Transform.replace) would, in specific circumstances, unneccessarily drop content. + +### New features + +The new [`Transform`](https://prosemirror.net/docs/ref/version/0.13.0.html#transform.Transform) method [`replaceRange`](https://prosemirror.net/docs/ref/version/0.13.0.html#transform.Transform.replaceRange), [`replaceRangeWith`](https://prosemirror.net/docs/ref/version/0.13.0.html#transform.Transform.replaceRangeWith), and [`deleteRange`](https://prosemirror.net/docs/ref/version/0.13.0.html#transform.Transform.deleteRange) provide a way to replace and delete content in a 'do what I mean' way, automatically expanding the replaced region over empty parent nodes and including the parent nodes in the inserted content when appropriate. + +## 0.12.1 (2016-11-01) + +### Bug fixes + +Fix bug in `Transform.setBlockType` when used in a transform that already has steps. + +## 0.12.0 (2016-10-21) + +### Breaking changes + +Mapped positions now count as deleted when the token to the +side specified by the `assoc` parameter is deleted, rather than when +both tokens around them are deleted. (This is usually what you already +wanted anyway.) + +## 0.11.0 (2016-09-21) + +### Breaking changes + +Moved into a separate module. + +The `Remapping` class was renamed to `Mapping` and works differently +(simpler, grows in only one direction, and has provision for mapping +through only a part of it). + +[`Transform`](https://prosemirror.net/docs/ref/version/0.11.0.html#transform.Transform) objects now build up a `Mapping` +instead of an array of maps. + +`PosMap` was renamed to [`StepMap`](https://prosemirror.net/docs/ref/version/0.11.0.html#transform.StepMap) to make it +clearer that this applies only to a single step (as opposed to +[`Mapping`](https://prosemirror.net/docs/ref/version/0.11.0.html#transform.Mapping). + +The arguments to [`canSplit`](https://prosemirror.net/docs/ref/version/0.11.0.html#transform.canSplit) and +[`split`](https://prosemirror.net/docs/ref/version/0.11.0.html#transform.Transform.split) were changed to make it +possible to specify multiple split-off node types for splits with a +depth greater than 1. + +Rename `joinable` to [`canJoin`](https://prosemirror.net/docs/ref/version/0.11.0.html#transform.canJoin). + +### New features + +Steps can now be [merged](https://prosemirror.net/docs/ref/version/0.11.0.html#transform.Step.merge) in some +circumstances, which can be useful when storing a lot of them. + diff --git a/packages/tiptap-extensions/node_modules/prosemirror-transform/CONTRIBUTING.md b/packages/tiptap-extensions/node_modules/prosemirror-transform/CONTRIBUTING.md new file mode 100644 index 0000000000..f2a345d830 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-transform/CONTRIBUTING.md @@ -0,0 +1,104 @@ +# How to contribute + +- [Getting help](#getting-help) +- [Submitting bug reports](#submitting-bug-reports) +- [Contributing code](#contributing-code) + +## Getting help + +Community discussion, questions, and informal bug reporting is done on the +[discuss.ProseMirror forum](http://discuss.prosemirror.net). + +## Submitting bug reports + +Report bugs on the +[GitHub issue tracker](http://github.com/prosemirror/prosemirror/issues). +Before reporting a bug, please read these pointers. + +- The issue tracker is for *bugs*, not requests for help. Questions + should be asked on the [forum](http://discuss.prosemirror.net). + +- Include information about the version of the code that exhibits the + problem. For browser-related issues, include the browser and browser + version on which the problem occurred. + +- Mention very precisely what went wrong. "X is broken" is not a good + bug report. What did you expect to happen? What happened instead? + Describe the exact steps a maintainer has to take to make the + problem occur. A screencast can be useful, but is no substitute for + a textual description. + +- A great way to make it easy to reproduce your problem, if it can not + be trivially reproduced on the website demos, is to submit a script + that triggers the issue. + +## Contributing code + +If you want to make a change that involves a significant overhaul of +the code or introduces a user-visible new feature, create an +[RFC](https://github.com/ProseMirror/rfcs/) first with your proposal. + +- Make sure you have a [GitHub Account](https://github.com/signup/free) + +- Fork the relevant repository + ([how to fork a repo](https://help.github.com/articles/fork-a-repo)) + +- Create a local checkout of the code. You can use the + [main repository](https://github.com/prosemirror/prosemirror) to + easily check out all core modules. + +- Make your changes, and commit them + +- Follow the code style of the rest of the project (see below). Run + `npm run lint` (in the main repository checkout) to make sure that + the linter is happy. + +- If your changes are easy to test or likely to regress, add tests in + the relevant `test/` directory. Either put them in an existing + `test-*.js` file, if they fit there, or add a new file. + +- Make sure all tests pass. Run `npm run test` to verify tests pass + (you will need Node.js v6+). + +- Submit a pull request ([how to create a pull request](https://help.github.com/articles/fork-a-repo)). + Don't put more than one feature/fix in a single pull request. + +By contributing code to ProseMirror you + + - Agree to license the contributed code under the project's [MIT + license](https://github.com/ProseMirror/prosemirror/blob/master/LICENSE). + + - Confirm that you have the right to contribute and license the code + in question. (Either you hold all rights on the code, or the rights + holder has explicitly granted the right to use it like this, + through a compatible open source license or through a direct + agreement with you.) + +### Coding standards + +- ES6 syntax, targeting an ES5 runtime (i.e. don't use library + elements added by ES6, don't use ES7/ES.next syntax). + +- 2 spaces per indentation level, no tabs. + +- No semicolons except when necessary. + +- Follow the surrounding code when it comes to spacing, brace + placement, etc. + +- Brace-less single-statement bodies are encouraged (whenever they + don't impact readability). + +- [getdocs](https://github.com/marijnh/getdocs)-style doc comments + above items that are part of the public API. + +- When documenting non-public items, you can put the type after a + single colon, so that getdocs doesn't pick it up and add it to the + API reference. + +- The linter (`npm run lint`) complains about unused variables and + functions. Prefix their names with an underscore to muffle it. + +- ProseMirror does *not* follow JSHint or JSLint prescribed style. + Patches that try to 'fix' code to pass one of these linters will not + be accepted. diff --git a/packages/tiptap-extensions/node_modules/prosemirror-transform/LICENSE b/packages/tiptap-extensions/node_modules/prosemirror-transform/LICENSE new file mode 100644 index 0000000000..ef9326c512 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-transform/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2015-2017 by Marijn Haverbeke and others + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/tiptap-extensions/node_modules/prosemirror-transform/README.md b/packages/tiptap-extensions/node_modules/prosemirror-transform/README.md new file mode 100644 index 0000000000..918b87e8de --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-transform/README.md @@ -0,0 +1,29 @@ +# prosemirror-transform + +[ [**WEBSITE**](https://prosemirror.net) | [**ISSUES**](https://github.com/prosemirror/prosemirror/issues) | [**FORUM**](https://discuss.prosemirror.net) | [**GITTER**](https://gitter.im/ProseMirror/prosemirror) | [**CHANGELOG**](https://github.com/ProseMirror/prosemirror-transform/blob/master/CHANGELOG.md) ] + +This is a [core module](https://prosemirror.net/docs/ref/#transform) of [ProseMirror](https://prosemirror.net). +ProseMirror is a well-behaved rich semantic content editor based on +contentEditable, with support for collaborative editing and custom +document schemas. + +This [module](https://prosemirror.net/docs/ref/#transform) implements +document [transforms](https://prosemirror.net/docs/guide/#transform), +which are used by the editor to treat changes as first-class values, +which can be saved, shared, and reasoned about. + +The [project page](https://prosemirror.net) has more information, a +number of [examples](https://prosemirror.net/examples/) and the +[documentation](https://prosemirror.net/docs/). + +This code is released under an +[MIT license](https://github.com/prosemirror/prosemirror/tree/master/LICENSE). +There's a [forum](http://discuss.prosemirror.net) for general +discussion and support requests, and the +[Github bug tracker](https://github.com/prosemirror/prosemirror/issues) +is the place to report issues. + +We aim to be an inclusive, welcoming community. To make that explicit, +we have a [code of +conduct](http://contributor-covenant.org/version/1/1/0/) that applies +to communication around the project. diff --git a/packages/tiptap-extensions/node_modules/prosemirror-transform/dist/index.es.js b/packages/tiptap-extensions/node_modules/prosemirror-transform/dist/index.es.js new file mode 100644 index 0000000000..340f2ce0ca --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-transform/dist/index.es.js @@ -0,0 +1,1689 @@ +import { ReplaceError, Slice, Fragment, MarkType } from 'prosemirror-model'; + +// Mappable:: interface +// There are several things that positions can be mapped through. +// Such objects conform to this interface. +// +// map:: (pos: number, assoc: ?number) → number +// Map a position through this object. When given, `assoc` (should +// be -1 or 1, defaults to 1) determines with which side the +// position is associated, which determines in which direction to +// move when a chunk of content is inserted at the mapped position. +// +// mapResult:: (pos: number, assoc: ?number) → MapResult +// Map a position, and return an object containing additional +// information about the mapping. The result's `deleted` field tells +// you whether the position was deleted (completely enclosed in a +// replaced range) during the mapping. When content on only one side +// is deleted, the position itself is only considered deleted when +// `assoc` points in the direction of the deleted content. + +// Recovery values encode a range index and an offset. They are +// represented as numbers, because tons of them will be created when +// mapping, for example, a large number of decorations. The number's +// lower 16 bits provide the index, the remaining bits the offset. +// +// Note: We intentionally don't use bit shift operators to en- and +// decode these, since those clip to 32 bits, which we might in rare +// cases want to overflow. A 64-bit float can represent 48-bit +// integers precisely. + +var lower16 = 0xffff; +var factor16 = Math.pow(2, 16); + +function makeRecover(index, offset) { return index + offset * factor16 } +function recoverIndex(value) { return value & lower16 } +function recoverOffset(value) { return (value - (value & lower16)) / factor16 } + +// ::- An object representing a mapped position with extra +// information. +var MapResult = function MapResult(pos, deleted, recover) { + if ( deleted === void 0 ) deleted = false; + if ( recover === void 0 ) recover = null; + + // :: number The mapped version of the position. + this.pos = pos; + // :: bool Tells you whether the position was deleted, that is, + // whether the step removed its surroundings from the document. + this.deleted = deleted; + this.recover = recover; +}; + +// :: class extends Mappable +// A map describing the deletions and insertions made by a step, which +// can be used to find the correspondence between positions in the +// pre-step version of a document and the same position in the +// post-step version. +var StepMap = function StepMap(ranges, inverted) { + if ( inverted === void 0 ) inverted = false; + + this.ranges = ranges; + this.inverted = inverted; +}; + +StepMap.prototype.recover = function recover (value) { + var diff = 0, index = recoverIndex(value); + if (!this.inverted) { for (var i = 0; i < index; i++) + { diff += this.ranges[i * 3 + 2] - this.ranges[i * 3 + 1]; } } + return this.ranges[index * 3] + diff + recoverOffset(value) +}; + +// : (number, ?number) → MapResult +StepMap.prototype.mapResult = function mapResult (pos, assoc) { + if ( assoc === void 0 ) assoc = 1; + return this._map(pos, assoc, false) }; + +// : (number, ?number) → number +StepMap.prototype.map = function map (pos, assoc) { + if ( assoc === void 0 ) assoc = 1; + return this._map(pos, assoc, true) }; + +StepMap.prototype._map = function _map (pos, assoc, simple) { + var diff = 0, oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; + for (var i = 0; i < this.ranges.length; i += 3) { + var start = this.ranges[i] - (this.inverted ? diff : 0); + if (start > pos) { break } + var oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex], end = start + oldSize; + if (pos <= end) { + var side = !oldSize ? assoc : pos == start ? -1 : pos == end ? 1 : assoc; + var result = start + diff + (side < 0 ? 0 : newSize); + if (simple) { return result } + var recover = makeRecover(i / 3, pos - start); + return new MapResult(result, assoc < 0 ? pos != start : pos != end, recover) + } + diff += newSize - oldSize; + } + return simple ? pos + diff : new MapResult(pos + diff) +}; + +StepMap.prototype.touches = function touches (pos, recover) { + var diff = 0, index = recoverIndex(recover); + var oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; + for (var i = 0; i < this.ranges.length; i += 3) { + var start = this.ranges[i] - (this.inverted ? diff : 0); + if (start > pos) { break } + var oldSize = this.ranges[i + oldIndex], end = start + oldSize; + if (pos <= end && i == index * 3) { return true } + diff += this.ranges[i + newIndex] - oldSize; + } + return false +}; + +// :: ((oldStart: number, oldEnd: number, newStart: number, newEnd: number)) +// Calls the given function on each of the changed ranges included in +// this map. +StepMap.prototype.forEach = function forEach (f) { + var oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; + for (var i = 0, diff = 0; i < this.ranges.length; i += 3) { + var start = this.ranges[i], oldStart = start - (this.inverted ? diff : 0), newStart = start + (this.inverted ? 0 : diff); + var oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex]; + f(oldStart, oldStart + oldSize, newStart, newStart + newSize); + diff += newSize - oldSize; + } +}; + +// :: () → StepMap +// Create an inverted version of this map. The result can be used to +// map positions in the post-step document to the pre-step document. +StepMap.prototype.invert = function invert () { + return new StepMap(this.ranges, !this.inverted) +}; + +StepMap.prototype.toString = function toString () { + return (this.inverted ? "-" : "") + JSON.stringify(this.ranges) +}; + +// :: (n: number) → StepMap +// Create a map that moves all positions by offset `n` (which may be +// negative). This can be useful when applying steps meant for a +// sub-document to a larger document, or vice-versa. +StepMap.offset = function offset (n) { + return n == 0 ? StepMap.empty : new StepMap(n < 0 ? [0, -n, 0] : [0, 0, n]) +}; + +StepMap.empty = new StepMap([]); + +// :: class extends Mappable +// A mapping represents a pipeline of zero or more [step +// maps](#transform.StepMap). It has special provisions for losslessly +// handling mapping positions through a series of steps in which some +// steps are inverted versions of earlier steps. (This comes up when +// ‘[rebasing](/docs/guide/#transform.rebasing)’ steps for +// collaboration or history management.) +var Mapping = function Mapping(maps, mirror, from, to) { + // :: [StepMap] + // The step maps in this mapping. + this.maps = maps || []; + // :: number + // The starting position in the `maps` array, used when `map` or + // `mapResult` is called. + this.from = from || 0; + // :: number + // The end position in the `maps` array. + this.to = to == null ? this.maps.length : to; + this.mirror = mirror; +}; + +// :: (?number, ?number) → Mapping +// Create a mapping that maps only through a part of this one. +Mapping.prototype.slice = function slice (from, to) { + if ( from === void 0 ) from = 0; + if ( to === void 0 ) to = this.maps.length; + + return new Mapping(this.maps, this.mirror, from, to) +}; + +Mapping.prototype.copy = function copy () { + return new Mapping(this.maps.slice(), this.mirror && this.mirror.slice(), this.from, this.to) +}; + +// :: (StepMap, ?number) +// Add a step map to the end of this mapping. If `mirrors` is +// given, it should be the index of the step map that is the mirror +// image of this one. +Mapping.prototype.appendMap = function appendMap (map, mirrors) { + this.to = this.maps.push(map); + if (mirrors != null) { this.setMirror(this.maps.length - 1, mirrors); } +}; + +// :: (Mapping) +// Add all the step maps in a given mapping to this one (preserving +// mirroring information). +Mapping.prototype.appendMapping = function appendMapping (mapping) { + for (var i = 0, startSize = this.maps.length; i < mapping.maps.length; i++) { + var mirr = mapping.getMirror(i); + this.appendMap(mapping.maps[i], mirr != null && mirr < i ? startSize + mirr : null); + } +}; + +// :: (number) → ?number +// Finds the offset of the step map that mirrors the map at the +// given offset, in this mapping (as per the second argument to +// `appendMap`). +Mapping.prototype.getMirror = function getMirror (n) { + if (this.mirror) { for (var i = 0; i < this.mirror.length; i++) + { if (this.mirror[i] == n) { return this.mirror[i + (i % 2 ? -1 : 1)] } } } +}; + +Mapping.prototype.setMirror = function setMirror (n, m) { + if (!this.mirror) { this.mirror = []; } + this.mirror.push(n, m); +}; + +// :: (Mapping) +// Append the inverse of the given mapping to this one. +Mapping.prototype.appendMappingInverted = function appendMappingInverted (mapping) { + for (var i = mapping.maps.length - 1, totalSize = this.maps.length + mapping.maps.length; i >= 0; i--) { + var mirr = mapping.getMirror(i); + this.appendMap(mapping.maps[i].invert(), mirr != null && mirr > i ? totalSize - mirr - 1 : null); + } +}; + +// :: () → Mapping +// Create an inverted version of this mapping. +Mapping.prototype.invert = function invert () { + var inverse = new Mapping; + inverse.appendMappingInverted(this); + return inverse +}; + +// : (number, ?number) → number +// Map a position through this mapping. +Mapping.prototype.map = function map (pos, assoc) { + if ( assoc === void 0 ) assoc = 1; + + if (this.mirror) { return this._map(pos, assoc, true) } + for (var i = this.from; i < this.to; i++) + { pos = this.maps[i].map(pos, assoc); } + return pos +}; + +// : (number, ?number) → MapResult +// Map a position through this mapping, returning a mapping +// result. +Mapping.prototype.mapResult = function mapResult (pos, assoc) { + if ( assoc === void 0 ) assoc = 1; + return this._map(pos, assoc, false) }; + +Mapping.prototype._map = function _map (pos, assoc, simple) { + var deleted = false, recoverables = null; + + for (var i = this.from; i < this.to; i++) { + var map = this.maps[i], rec = recoverables && recoverables[i]; + if (rec != null && map.touches(pos, rec)) { + pos = map.recover(rec); + continue + } + + var result = map.mapResult(pos, assoc); + if (result.recover != null) { + var corr = this.getMirror(i); + if (corr != null && corr > i && corr < this.to) { + if (result.deleted) { + i = corr; + pos = this.maps[corr].recover(result.recover); + continue + } else { +(recoverables || (recoverables = Object.create(null)))[corr] = result.recover; + } + } + } + + if (result.deleted) { deleted = true; } + pos = result.pos; + } + + return simple ? pos : new MapResult(pos, deleted) +}; + +function TransformError(message) { + var err = Error.call(this, message); + err.__proto__ = TransformError.prototype; + return err +} + +TransformError.prototype = Object.create(Error.prototype); +TransformError.prototype.constructor = TransformError; +TransformError.prototype.name = "TransformError"; + +// ::- Abstraction to build up and track an array of +// [steps](#transform.Step) representing a document transformation. +// +// Most transforming methods return the `Transform` object itself, so +// that they can be chained. +var Transform = function Transform(doc) { + // :: Node + // The current document (the result of applying the steps in the + // transform). + this.doc = doc; + // :: [Step] + // The steps in this transform. + this.steps = []; + // :: [Node] + // The documents before each of the steps. + this.docs = []; + // :: Mapping + // A mapping with the maps for each of the steps in this transform. + this.mapping = new Mapping; +}; + +var prototypeAccessors = { before: { configurable: true },docChanged: { configurable: true } }; + +// :: Node The starting document. +prototypeAccessors.before.get = function () { return this.docs.length ? this.docs[0] : this.doc }; + +// :: (step: Step) → this +// Apply a new step in this transform, saving the result. Throws an +// error when the step fails. +Transform.prototype.step = function step (object) { + var result = this.maybeStep(object); + if (result.failed) { throw new TransformError(result.failed) } + return this +}; + +// :: (Step) → StepResult +// Try to apply a step in this transformation, ignoring it if it +// fails. Returns the step result. +Transform.prototype.maybeStep = function maybeStep (step) { + var result = step.apply(this.doc); + if (!result.failed) { this.addStep(step, result.doc); } + return result +}; + +// :: bool +// True when the document has been changed (when there are any +// steps). +prototypeAccessors.docChanged.get = function () { + return this.steps.length > 0 +}; + +Transform.prototype.addStep = function addStep (step, doc) { + this.docs.push(this.doc); + this.steps.push(step); + this.mapping.appendMap(step.getMap()); + this.doc = doc; +}; + +Object.defineProperties( Transform.prototype, prototypeAccessors ); + +function mustOverride() { throw new Error("Override me") } + +var stepsByID = Object.create(null); + +// ::- A step object represents an atomic change. It generally applies +// only to the document it was created for, since the positions +// stored in it will only make sense for that document. +// +// New steps are defined by creating classes that extend `Step`, +// overriding the `apply`, `invert`, `map`, `getMap` and `fromJSON` +// methods, and registering your class with a unique +// JSON-serialization identifier using +// [`Step.jsonID`](#transform.Step^jsonID). +var Step = function Step () {}; + +Step.prototype.apply = function apply (_doc) { return mustOverride() }; + +// :: () → StepMap +// Get the step map that represents the changes made by this step, +// and which can be used to transform between positions in the old +// and the new document. +Step.prototype.getMap = function getMap () { return StepMap.empty }; + +// :: (doc: Node) → Step +// Create an inverted version of this step. Needs the document as it +// was before the step as argument. +Step.prototype.invert = function invert (_doc) { return mustOverride() }; + +// :: (mapping: Mappable) → ?Step +// Map this step through a mappable thing, returning either a +// version of that step with its positions adjusted, or `null` if +// the step was entirely deleted by the mapping. +Step.prototype.map = function map (_mapping) { return mustOverride() }; + +// :: (other: Step) → ?Step +// Try to merge this step with another one, to be applied directly +// after it. Returns the merged step when possible, null if the +// steps can't be merged. +Step.prototype.merge = function merge (_other) { return null }; + +// :: () → Object +// Create a JSON-serializeable representation of this step. When +// defining this for a custom subclass, make sure the result object +// includes the step type's [JSON id](#transform.Step^jsonID) under +// the `stepType` property. +Step.prototype.toJSON = function toJSON () { return mustOverride() }; + +// :: (Schema, Object) → Step +// Deserialize a step from its JSON representation. Will call +// through to the step class' own implementation of this method. +Step.fromJSON = function fromJSON (schema, json) { + if (!json || !json.stepType) { throw new RangeError("Invalid input for Step.fromJSON") } + var type = stepsByID[json.stepType]; + if (!type) { throw new RangeError(("No step type " + (json.stepType) + " defined")) } + return type.fromJSON(schema, json) +}; + +// :: (string, constructor) +// To be able to serialize steps to JSON, each step needs a string +// ID to attach to its JSON representation. Use this method to +// register an ID for your step classes. Try to pick something +// that's unlikely to clash with steps from other modules. +Step.jsonID = function jsonID (id, stepClass) { + if (id in stepsByID) { throw new RangeError("Duplicate use of step JSON ID " + id) } + stepsByID[id] = stepClass; + stepClass.prototype.jsonID = id; + return stepClass +}; + +// ::- The result of [applying](#transform.Step.apply) a step. Contains either a +// new document or a failure value. +var StepResult = function StepResult(doc, failed) { + // :: ?Node The transformed document. + this.doc = doc; + // :: ?string Text providing information about a failed step. + this.failed = failed; +}; + +// :: (Node) → StepResult +// Create a successful step result. +StepResult.ok = function ok (doc) { return new StepResult(doc, null) }; + +// :: (string) → StepResult +// Create a failed step result. +StepResult.fail = function fail (message) { return new StepResult(null, message) }; + +// :: (Node, number, number, Slice) → StepResult +// Call [`Node.replace`](#model.Node.replace) with the given +// arguments. Create a successful result if it succeeds, and a +// failed one if it throws a `ReplaceError`. +StepResult.fromReplace = function fromReplace (doc, from, to, slice) { + try { + return StepResult.ok(doc.replace(from, to, slice)) + } catch (e) { + if (e instanceof ReplaceError) { return StepResult.fail(e.message) } + throw e + } +}; + +// ::- Replace a part of the document with a slice of new content. +var ReplaceStep = /*@__PURE__*/(function (Step) { + function ReplaceStep(from, to, slice, structure) { + Step.call(this); + this.from = from; + this.to = to; + this.slice = slice; + this.structure = !!structure; + } + + if ( Step ) ReplaceStep.__proto__ = Step; + ReplaceStep.prototype = Object.create( Step && Step.prototype ); + ReplaceStep.prototype.constructor = ReplaceStep; + + ReplaceStep.prototype.apply = function apply (doc) { + if (this.structure && contentBetween(doc, this.from, this.to)) + { return StepResult.fail("Structure replace would overwrite content") } + return StepResult.fromReplace(doc, this.from, this.to, this.slice) + }; + + ReplaceStep.prototype.getMap = function getMap () { + return new StepMap([this.from, this.to - this.from, this.slice.size]) + }; + + ReplaceStep.prototype.invert = function invert (doc) { + return new ReplaceStep(this.from, this.from + this.slice.size, doc.slice(this.from, this.to)) + }; + + ReplaceStep.prototype.map = function map (mapping) { + var from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); + if (from.deleted && to.deleted) { return null } + return new ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice) + }; + + ReplaceStep.prototype.merge = function merge (other) { + if (!(other instanceof ReplaceStep) || other.structure != this.structure) { return null } + + if (this.from + this.slice.size == other.from && !this.slice.openEnd && !other.slice.openStart) { + var slice = this.slice.size + other.slice.size == 0 ? Slice.empty + : new Slice(this.slice.content.append(other.slice.content), this.slice.openStart, other.slice.openEnd); + return new ReplaceStep(this.from, this.to + (other.to - other.from), slice, this.structure) + } else if (other.to == this.from && !this.slice.openStart && !other.slice.openEnd) { + var slice$1 = this.slice.size + other.slice.size == 0 ? Slice.empty + : new Slice(other.slice.content.append(this.slice.content), other.slice.openStart, this.slice.openEnd); + return new ReplaceStep(other.from, this.to, slice$1, this.structure) + } else { + return null + } + }; + + ReplaceStep.prototype.toJSON = function toJSON () { + var json = {stepType: "replace", from: this.from, to: this.to}; + if (this.slice.size) { json.slice = this.slice.toJSON(); } + if (this.structure) { json.structure = true; } + return json + }; + + ReplaceStep.fromJSON = function fromJSON (schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + { throw new RangeError("Invalid input for ReplaceStep.fromJSON") } + return new ReplaceStep(json.from, json.to, Slice.fromJSON(schema, json.slice), !!json.structure) + }; + + return ReplaceStep; +}(Step)); + +Step.jsonID("replace", ReplaceStep); + +// ::- Replace a part of the document with a slice of content, but +// preserve a range of the replaced content by moving it into the +// slice. +var ReplaceAroundStep = /*@__PURE__*/(function (Step) { + function ReplaceAroundStep(from, to, gapFrom, gapTo, slice, insert, structure) { + Step.call(this); + this.from = from; + this.to = to; + this.gapFrom = gapFrom; + this.gapTo = gapTo; + this.slice = slice; + this.insert = insert; + this.structure = !!structure; + } + + if ( Step ) ReplaceAroundStep.__proto__ = Step; + ReplaceAroundStep.prototype = Object.create( Step && Step.prototype ); + ReplaceAroundStep.prototype.constructor = ReplaceAroundStep; + + ReplaceAroundStep.prototype.apply = function apply (doc) { + if (this.structure && (contentBetween(doc, this.from, this.gapFrom) || + contentBetween(doc, this.gapTo, this.to))) + { return StepResult.fail("Structure gap-replace would overwrite content") } + + var gap = doc.slice(this.gapFrom, this.gapTo); + if (gap.openStart || gap.openEnd) + { return StepResult.fail("Gap is not a flat range") } + var inserted = this.slice.insertAt(this.insert, gap.content); + if (!inserted) { return StepResult.fail("Content does not fit in gap") } + return StepResult.fromReplace(doc, this.from, this.to, inserted) + }; + + ReplaceAroundStep.prototype.getMap = function getMap () { + return new StepMap([this.from, this.gapFrom - this.from, this.insert, + this.gapTo, this.to - this.gapTo, this.slice.size - this.insert]) + }; + + ReplaceAroundStep.prototype.invert = function invert (doc) { + var gap = this.gapTo - this.gapFrom; + return new ReplaceAroundStep(this.from, this.from + this.slice.size + gap, + this.from + this.insert, this.from + this.insert + gap, + doc.slice(this.from, this.to).removeBetween(this.gapFrom - this.from, this.gapTo - this.from), + this.gapFrom - this.from, this.structure) + }; + + ReplaceAroundStep.prototype.map = function map (mapping) { + var from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); + var gapFrom = mapping.map(this.gapFrom, -1), gapTo = mapping.map(this.gapTo, 1); + if ((from.deleted && to.deleted) || gapFrom < from.pos || gapTo > to.pos) { return null } + return new ReplaceAroundStep(from.pos, to.pos, gapFrom, gapTo, this.slice, this.insert, this.structure) + }; + + ReplaceAroundStep.prototype.toJSON = function toJSON () { + var json = {stepType: "replaceAround", from: this.from, to: this.to, + gapFrom: this.gapFrom, gapTo: this.gapTo, insert: this.insert}; + if (this.slice.size) { json.slice = this.slice.toJSON(); } + if (this.structure) { json.structure = true; } + return json + }; + + ReplaceAroundStep.fromJSON = function fromJSON (schema, json) { + if (typeof json.from != "number" || typeof json.to != "number" || + typeof json.gapFrom != "number" || typeof json.gapTo != "number" || typeof json.insert != "number") + { throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON") } + return new ReplaceAroundStep(json.from, json.to, json.gapFrom, json.gapTo, + Slice.fromJSON(schema, json.slice), json.insert, !!json.structure) + }; + + return ReplaceAroundStep; +}(Step)); + +Step.jsonID("replaceAround", ReplaceAroundStep); + +function contentBetween(doc, from, to) { + var $from = doc.resolve(from), dist = to - from, depth = $from.depth; + while (dist > 0 && depth > 0 && $from.indexAfter(depth) == $from.node(depth).childCount) { + depth--; + dist--; + } + if (dist > 0) { + var next = $from.node(depth).maybeChild($from.indexAfter(depth)); + while (dist > 0) { + if (!next || next.isLeaf) { return true } + next = next.firstChild; + dist--; + } + } + return false +} + +function canCut(node, start, end) { + return (start == 0 || node.canReplace(start, node.childCount)) && + (end == node.childCount || node.canReplace(0, end)) +} + +// :: (NodeRange) → ?number +// Try to find a target depth to which the content in the given range +// can be lifted. Will not go across +// [isolating](#model.NodeSpec.isolating) parent nodes. +function liftTarget(range) { + var parent = range.parent; + var content = parent.content.cutByIndex(range.startIndex, range.endIndex); + for (var depth = range.depth;; --depth) { + var node = range.$from.node(depth); + var index = range.$from.index(depth), endIndex = range.$to.indexAfter(depth); + if (depth < range.depth && node.canReplace(index, endIndex, content)) + { return depth } + if (depth == 0 || node.type.spec.isolating || !canCut(node, index, endIndex)) { break } + } +} + +// :: (NodeRange, number) → this +// Split the content in the given range off from its parent, if there +// is sibling content before or after it, and move it up the tree to +// the depth specified by `target`. You'll probably want to use +// [`liftTarget`](#transform.liftTarget) to compute `target`, to make +// sure the lift is valid. +Transform.prototype.lift = function(range, target) { + var $from = range.$from; + var $to = range.$to; + var depth = range.depth; + + var gapStart = $from.before(depth + 1), gapEnd = $to.after(depth + 1); + var start = gapStart, end = gapEnd; + + var before = Fragment.empty, openStart = 0; + for (var d = depth, splitting = false; d > target; d--) + { if (splitting || $from.index(d) > 0) { + splitting = true; + before = Fragment.from($from.node(d).copy(before)); + openStart++; + } else { + start--; + } } + var after = Fragment.empty, openEnd = 0; + for (var d$1 = depth, splitting$1 = false; d$1 > target; d$1--) + { if (splitting$1 || $to.after(d$1 + 1) < $to.end(d$1)) { + splitting$1 = true; + after = Fragment.from($to.node(d$1).copy(after)); + openEnd++; + } else { + end++; + } } + + return this.step(new ReplaceAroundStep(start, end, gapStart, gapEnd, + new Slice(before.append(after), openStart, openEnd), + before.size - openStart, true)) +}; + +// :: (NodeRange, NodeType, ?Object, ?NodeRange) → ?[{type: NodeType, attrs: ?Object}] +// Try to find a valid way to wrap the content in the given range in a +// node of the given type. May introduce extra nodes around and inside +// the wrapper node, if necessary. Returns null if no valid wrapping +// could be found. When `innerRange` is given, that range's content is +// used as the content to fit into the wrapping, instead of the +// content of `range`. +function findWrapping(range, nodeType, attrs, innerRange) { + if ( innerRange === void 0 ) innerRange = range; + + var around = findWrappingOutside(range, nodeType); + var inner = around && findWrappingInside(innerRange, nodeType); + if (!inner) { return null } + return around.map(withAttrs).concat({type: nodeType, attrs: attrs}).concat(inner.map(withAttrs)) +} + +function withAttrs(type) { return {type: type, attrs: null} } + +function findWrappingOutside(range, type) { + var parent = range.parent; + var startIndex = range.startIndex; + var endIndex = range.endIndex; + var around = parent.contentMatchAt(startIndex).findWrapping(type); + if (!around) { return null } + var outer = around.length ? around[0] : type; + return parent.canReplaceWith(startIndex, endIndex, outer) ? around : null +} + +function findWrappingInside(range, type) { + var parent = range.parent; + var startIndex = range.startIndex; + var endIndex = range.endIndex; + var inner = parent.child(startIndex); + var inside = type.contentMatch.findWrapping(inner.type); + if (!inside) { return null } + var lastType = inside.length ? inside[inside.length - 1] : type; + var innerMatch = lastType.contentMatch; + for (var i = startIndex; innerMatch && i < endIndex; i++) + { innerMatch = innerMatch.matchType(parent.child(i).type); } + if (!innerMatch || !innerMatch.validEnd) { return null } + return inside +} + +// :: (NodeRange, [{type: NodeType, attrs: ?Object}]) → this +// Wrap the given [range](#model.NodeRange) in the given set of wrappers. +// The wrappers are assumed to be valid in this position, and should +// probably be computed with [`findWrapping`](#transform.findWrapping). +Transform.prototype.wrap = function(range, wrappers) { + var content = Fragment.empty; + for (var i = wrappers.length - 1; i >= 0; i--) + { content = Fragment.from(wrappers[i].type.create(wrappers[i].attrs, content)); } + + var start = range.start, end = range.end; + return this.step(new ReplaceAroundStep(start, end, start, end, new Slice(content, 0, 0), wrappers.length, true)) +}; + +// :: (number, ?number, NodeType, ?Object) → this +// Set the type of all textblocks (partly) between `from` and `to` to +// the given node type with the given attributes. +Transform.prototype.setBlockType = function(from, to, type, attrs) { + var this$1 = this; + if ( to === void 0 ) to = from; + + if (!type.isTextblock) { throw new RangeError("Type given to setBlockType should be a textblock") } + var mapFrom = this.steps.length; + this.doc.nodesBetween(from, to, function (node, pos) { + if (node.isTextblock && !node.hasMarkup(type, attrs) && canChangeType(this$1.doc, this$1.mapping.slice(mapFrom).map(pos), type)) { + // Ensure all markup that isn't allowed in the new node type is cleared + this$1.clearIncompatible(this$1.mapping.slice(mapFrom).map(pos, 1), type); + var mapping = this$1.mapping.slice(mapFrom); + var startM = mapping.map(pos, 1), endM = mapping.map(pos + node.nodeSize, 1); + this$1.step(new ReplaceAroundStep(startM, endM, startM + 1, endM - 1, + new Slice(Fragment.from(type.create(attrs, null, node.marks)), 0, 0), 1, true)); + return false + } + }); + return this +}; + +function canChangeType(doc, pos, type) { + var $pos = doc.resolve(pos), index = $pos.index(); + return $pos.parent.canReplaceWith(index, index + 1, type) +} + +// :: (number, ?NodeType, ?Object, ?[Mark]) → this +// Change the type, attributes, and/or marks of the node at `pos`. +// When `type` isn't given, the existing node type is preserved, +Transform.prototype.setNodeMarkup = function(pos, type, attrs, marks) { + var node = this.doc.nodeAt(pos); + if (!node) { throw new RangeError("No node at given position") } + if (!type) { type = node.type; } + var newNode = type.create(attrs, null, marks || node.marks); + if (node.isLeaf) + { return this.replaceWith(pos, pos + node.nodeSize, newNode) } + + if (!type.validContent(node.content)) + { throw new RangeError("Invalid content for node type " + type.name) } + + return this.step(new ReplaceAroundStep(pos, pos + node.nodeSize, pos + 1, pos + node.nodeSize - 1, + new Slice(Fragment.from(newNode), 0, 0), 1, true)) +}; + +// :: (Node, number, number, ?[?{type: NodeType, attrs: ?Object}]) → bool +// Check whether splitting at the given position is allowed. +function canSplit(doc, pos, depth, typesAfter) { + if ( depth === void 0 ) depth = 1; + + var $pos = doc.resolve(pos), base = $pos.depth - depth; + var innerType = (typesAfter && typesAfter[typesAfter.length - 1]) || $pos.parent; + if (base < 0 || $pos.parent.type.spec.isolating || + !$pos.parent.canReplace($pos.index(), $pos.parent.childCount) || + !innerType.type.validContent($pos.parent.content.cutByIndex($pos.index(), $pos.parent.childCount))) + { return false } + for (var d = $pos.depth - 1, i = depth - 2; d > base; d--, i--) { + var node = $pos.node(d), index$1 = $pos.index(d); + if (node.type.spec.isolating) { return false } + var rest = node.content.cutByIndex(index$1, node.childCount); + var after = (typesAfter && typesAfter[i]) || node; + if (after != node) { rest = rest.replaceChild(0, after.type.create(after.attrs)); } + if (!node.canReplace(index$1 + 1, node.childCount) || !after.type.validContent(rest)) + { return false } + } + var index = $pos.indexAfter(base); + var baseType = typesAfter && typesAfter[0]; + return $pos.node(base).canReplaceWith(index, index, baseType ? baseType.type : $pos.node(base + 1).type) +} + +// :: (number, ?number, ?[?{type: NodeType, attrs: ?Object}]) → this +// Split the node at the given position, and optionally, if `depth` is +// greater than one, any number of nodes above that. By default, the +// parts split off will inherit the node type of the original node. +// This can be changed by passing an array of types and attributes to +// use after the split. +Transform.prototype.split = function(pos, depth, typesAfter) { + if ( depth === void 0 ) depth = 1; + + var $pos = this.doc.resolve(pos), before = Fragment.empty, after = Fragment.empty; + for (var d = $pos.depth, e = $pos.depth - depth, i = depth - 1; d > e; d--, i--) { + before = Fragment.from($pos.node(d).copy(before)); + var typeAfter = typesAfter && typesAfter[i]; + after = Fragment.from(typeAfter ? typeAfter.type.create(typeAfter.attrs, after) : $pos.node(d).copy(after)); + } + return this.step(new ReplaceStep(pos, pos, new Slice(before.append(after), depth, depth), true)) +}; + +// :: (Node, number) → bool +// Test whether the blocks before and after a given position can be +// joined. +function canJoin(doc, pos) { + var $pos = doc.resolve(pos), index = $pos.index(); + return joinable($pos.nodeBefore, $pos.nodeAfter) && + $pos.parent.canReplace(index, index + 1) +} + +function joinable(a, b) { + return a && b && !a.isLeaf && a.canAppend(b) +} + +// :: (Node, number, ?number) → ?number +// Find an ancestor of the given position that can be joined to the +// block before (or after if `dir` is positive). Returns the joinable +// point, if any. +function joinPoint(doc, pos, dir) { + if ( dir === void 0 ) dir = -1; + + var $pos = doc.resolve(pos); + for (var d = $pos.depth;; d--) { + var before = (void 0), after = (void 0); + if (d == $pos.depth) { + before = $pos.nodeBefore; + after = $pos.nodeAfter; + } else if (dir > 0) { + before = $pos.node(d + 1); + after = $pos.node(d).maybeChild($pos.index(d) + 1); + } else { + before = $pos.node(d).maybeChild($pos.index(d) - 1); + after = $pos.node(d + 1); + } + if (before && !before.isTextblock && joinable(before, after)) { return pos } + if (d == 0) { break } + pos = dir < 0 ? $pos.before(d) : $pos.after(d); + } +} + +// :: (number, ?number) → this +// Join the blocks around the given position. If depth is 2, their +// last and first siblings are also joined, and so on. +Transform.prototype.join = function(pos, depth) { + if ( depth === void 0 ) depth = 1; + + var step = new ReplaceStep(pos - depth, pos + depth, Slice.empty, true); + return this.step(step) +}; + +// :: (Node, number, NodeType) → ?number +// Try to find a point where a node of the given type can be inserted +// near `pos`, by searching up the node hierarchy when `pos` itself +// isn't a valid place but is at the start or end of a node. Return +// null if no position was found. +function insertPoint(doc, pos, nodeType) { + var $pos = doc.resolve(pos); + if ($pos.parent.canReplaceWith($pos.index(), $pos.index(), nodeType)) { return pos } + + if ($pos.parentOffset == 0) + { for (var d = $pos.depth - 1; d >= 0; d--) { + var index = $pos.index(d); + if ($pos.node(d).canReplaceWith(index, index, nodeType)) { return $pos.before(d + 1) } + if (index > 0) { return null } + } } + if ($pos.parentOffset == $pos.parent.content.size) + { for (var d$1 = $pos.depth - 1; d$1 >= 0; d$1--) { + var index$1 = $pos.indexAfter(d$1); + if ($pos.node(d$1).canReplaceWith(index$1, index$1, nodeType)) { return $pos.after(d$1 + 1) } + if (index$1 < $pos.node(d$1).childCount) { return null } + } } +} + +// :: (Node, number, Slice) → ?number +// Finds a position at or around the given position where the given +// slice can be inserted. Will look at parent nodes' nearest boundary +// and try there, even if the original position wasn't directly at the +// start or end of that node. Returns null when no position was found. +function dropPoint(doc, pos, slice) { + var $pos = doc.resolve(pos); + if (!slice.content.size) { return pos } + var content = slice.content; + for (var i = 0; i < slice.openStart; i++) { content = content.firstChild.content; } + for (var pass = 1; pass <= (slice.openStart == 0 && slice.size ? 2 : 1); pass++) { + for (var d = $pos.depth; d >= 0; d--) { + var bias = d == $pos.depth ? 0 : $pos.pos <= ($pos.start(d + 1) + $pos.end(d + 1)) / 2 ? -1 : 1; + var insertPos = $pos.index(d) + (bias > 0 ? 1 : 0); + if (pass == 1 + ? $pos.node(d).canReplace(insertPos, insertPos, content) + : $pos.node(d).contentMatchAt(insertPos).findWrapping(content.firstChild.type)) + { return bias == 0 ? $pos.pos : bias < 0 ? $pos.before(d + 1) : $pos.after(d + 1) } + } + } + return null +} + +function mapFragment(fragment, f, parent) { + var mapped = []; + for (var i = 0; i < fragment.childCount; i++) { + var child = fragment.child(i); + if (child.content.size) { child = child.copy(mapFragment(child.content, f, child)); } + if (child.isInline) { child = f(child, parent, i); } + mapped.push(child); + } + return Fragment.fromArray(mapped) +} + +// ::- Add a mark to all inline content between two positions. +var AddMarkStep = /*@__PURE__*/(function (Step) { + function AddMarkStep(from, to, mark) { + Step.call(this); + this.from = from; + this.to = to; + this.mark = mark; + } + + if ( Step ) AddMarkStep.__proto__ = Step; + AddMarkStep.prototype = Object.create( Step && Step.prototype ); + AddMarkStep.prototype.constructor = AddMarkStep; + + AddMarkStep.prototype.apply = function apply (doc) { + var this$1 = this; + + var oldSlice = doc.slice(this.from, this.to), $from = doc.resolve(this.from); + var parent = $from.node($from.sharedDepth(this.to)); + var slice = new Slice(mapFragment(oldSlice.content, function (node, parent) { + if (!parent.type.allowsMarkType(this$1.mark.type)) { return node } + return node.mark(this$1.mark.addToSet(node.marks)) + }, parent), oldSlice.openStart, oldSlice.openEnd); + return StepResult.fromReplace(doc, this.from, this.to, slice) + }; + + AddMarkStep.prototype.invert = function invert () { + return new RemoveMarkStep(this.from, this.to, this.mark) + }; + + AddMarkStep.prototype.map = function map (mapping) { + var from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); + if (from.deleted && to.deleted || from.pos >= to.pos) { return null } + return new AddMarkStep(from.pos, to.pos, this.mark) + }; + + AddMarkStep.prototype.merge = function merge (other) { + if (other instanceof AddMarkStep && + other.mark.eq(this.mark) && + this.from <= other.to && this.to >= other.from) + { return new AddMarkStep(Math.min(this.from, other.from), + Math.max(this.to, other.to), this.mark) } + }; + + AddMarkStep.prototype.toJSON = function toJSON () { + return {stepType: "addMark", mark: this.mark.toJSON(), + from: this.from, to: this.to} + }; + + AddMarkStep.fromJSON = function fromJSON (schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + { throw new RangeError("Invalid input for AddMarkStep.fromJSON") } + return new AddMarkStep(json.from, json.to, schema.markFromJSON(json.mark)) + }; + + return AddMarkStep; +}(Step)); + +Step.jsonID("addMark", AddMarkStep); + +// ::- Remove a mark from all inline content between two positions. +var RemoveMarkStep = /*@__PURE__*/(function (Step) { + function RemoveMarkStep(from, to, mark) { + Step.call(this); + this.from = from; + this.to = to; + this.mark = mark; + } + + if ( Step ) RemoveMarkStep.__proto__ = Step; + RemoveMarkStep.prototype = Object.create( Step && Step.prototype ); + RemoveMarkStep.prototype.constructor = RemoveMarkStep; + + RemoveMarkStep.prototype.apply = function apply (doc) { + var this$1 = this; + + var oldSlice = doc.slice(this.from, this.to); + var slice = new Slice(mapFragment(oldSlice.content, function (node) { + return node.mark(this$1.mark.removeFromSet(node.marks)) + }), oldSlice.openStart, oldSlice.openEnd); + return StepResult.fromReplace(doc, this.from, this.to, slice) + }; + + RemoveMarkStep.prototype.invert = function invert () { + return new AddMarkStep(this.from, this.to, this.mark) + }; + + RemoveMarkStep.prototype.map = function map (mapping) { + var from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); + if (from.deleted && to.deleted || from.pos >= to.pos) { return null } + return new RemoveMarkStep(from.pos, to.pos, this.mark) + }; + + RemoveMarkStep.prototype.merge = function merge (other) { + if (other instanceof RemoveMarkStep && + other.mark.eq(this.mark) && + this.from <= other.to && this.to >= other.from) + { return new RemoveMarkStep(Math.min(this.from, other.from), + Math.max(this.to, other.to), this.mark) } + }; + + RemoveMarkStep.prototype.toJSON = function toJSON () { + return {stepType: "removeMark", mark: this.mark.toJSON(), + from: this.from, to: this.to} + }; + + RemoveMarkStep.fromJSON = function fromJSON (schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + { throw new RangeError("Invalid input for RemoveMarkStep.fromJSON") } + return new RemoveMarkStep(json.from, json.to, schema.markFromJSON(json.mark)) + }; + + return RemoveMarkStep; +}(Step)); + +Step.jsonID("removeMark", RemoveMarkStep); + +// :: (number, number, Mark) → this +// Add the given mark to the inline content between `from` and `to`. +Transform.prototype.addMark = function(from, to, mark) { + var this$1 = this; + + var removed = [], added = [], removing = null, adding = null; + this.doc.nodesBetween(from, to, function (node, pos, parent) { + if (!node.isInline) { return } + var marks = node.marks; + if (!mark.isInSet(marks) && parent.type.allowsMarkType(mark.type)) { + var start = Math.max(pos, from), end = Math.min(pos + node.nodeSize, to); + var newSet = mark.addToSet(marks); + + for (var i = 0; i < marks.length; i++) { + if (!marks[i].isInSet(newSet)) { + if (removing && removing.to == start && removing.mark.eq(marks[i])) + { removing.to = end; } + else + { removed.push(removing = new RemoveMarkStep(start, end, marks[i])); } + } + } + + if (adding && adding.to == start) + { adding.to = end; } + else + { added.push(adding = new AddMarkStep(start, end, mark)); } + } + }); + + removed.forEach(function (s) { return this$1.step(s); }); + added.forEach(function (s) { return this$1.step(s); }); + return this +}; + +// :: (number, number, ?union) → this +// Remove marks from inline nodes between `from` and `to`. When `mark` +// is a single mark, remove precisely that mark. When it is a mark type, +// remove all marks of that type. When it is null, remove all marks of +// any type. +Transform.prototype.removeMark = function(from, to, mark) { + var this$1 = this; + if ( mark === void 0 ) mark = null; + + var matched = [], step = 0; + this.doc.nodesBetween(from, to, function (node, pos) { + if (!node.isInline) { return } + step++; + var toRemove = null; + if (mark instanceof MarkType) { + var found = mark.isInSet(node.marks); + if (found) { toRemove = [found]; } + } else if (mark) { + if (mark.isInSet(node.marks)) { toRemove = [mark]; } + } else { + toRemove = node.marks; + } + if (toRemove && toRemove.length) { + var end = Math.min(pos + node.nodeSize, to); + for (var i = 0; i < toRemove.length; i++) { + var style = toRemove[i], found$1 = (void 0); + for (var j = 0; j < matched.length; j++) { + var m = matched[j]; + if (m.step == step - 1 && style.eq(matched[j].style)) { found$1 = m; } + } + if (found$1) { + found$1.to = end; + found$1.step = step; + } else { + matched.push({style: style, from: Math.max(pos, from), to: end, step: step}); + } + } + } + }); + matched.forEach(function (m) { return this$1.step(new RemoveMarkStep(m.from, m.to, m.style)); }); + return this +}; + +// :: (number, NodeType, ?ContentMatch) → this +// Removes all marks and nodes from the content of the node at `pos` +// that don't match the given new parent node type. Accepts an +// optional starting [content match](#model.ContentMatch) as third +// argument. +Transform.prototype.clearIncompatible = function(pos, parentType, match) { + if ( match === void 0 ) match = parentType.contentMatch; + + var node = this.doc.nodeAt(pos); + var delSteps = [], cur = pos + 1; + for (var i = 0; i < node.childCount; i++) { + var child = node.child(i), end = cur + child.nodeSize; + var allowed = match.matchType(child.type, child.attrs); + if (!allowed) { + delSteps.push(new ReplaceStep(cur, end, Slice.empty)); + } else { + match = allowed; + for (var j = 0; j < child.marks.length; j++) { if (!parentType.allowsMarkType(child.marks[j].type)) + { this.step(new RemoveMarkStep(cur, end, child.marks[j])); } } + } + cur = end; + } + if (!match.validEnd) { + var fill = match.fillBefore(Fragment.empty, true); + this.replace(cur, cur, new Slice(fill, 0, 0)); + } + for (var i$1 = delSteps.length - 1; i$1 >= 0; i$1--) { this.step(delSteps[i$1]); } + return this +}; + +// :: (Node, number, ?number, ?Slice) → ?Step +// ‘Fit’ a slice into a given position in the document, producing a +// [step](#transform.Step) that inserts it. Will return null if +// there's no meaningful way to insert the slice here, or inserting it +// would be a no-op (an empty slice over an empty range). +function replaceStep(doc, from, to, slice) { + if ( to === void 0 ) to = from; + if ( slice === void 0 ) slice = Slice.empty; + + if (from == to && !slice.size) { return null } + + var $from = doc.resolve(from), $to = doc.resolve(to); + // Optimization -- avoid work if it's obvious that it's not needed. + if (fitsTrivially($from, $to, slice)) { return new ReplaceStep(from, to, slice) } + var placed = placeSlice($from, slice); + + var fittedLeft = fitLeft($from, placed); + var fitted = fitRight($from, $to, fittedLeft); + if (!fitted) { return null } + if (fittedLeft.size != fitted.size && canMoveText($from, $to, fittedLeft)) { + var d = $to.depth, after = $to.after(d); + while (d > 1 && after == $to.end(--d)) { ++after; } + var fittedAfter = fitRight($from, doc.resolve(after), fittedLeft); + if (fittedAfter) + { return new ReplaceAroundStep(from, after, to, $to.end(), fittedAfter, fittedLeft.size) } + } + return fitted.size || from != to ? new ReplaceStep(from, to, fitted) : null +} + +// :: (number, ?number, ?Slice) → this +// Replace the part of the document between `from` and `to` with the +// given `slice`. +Transform.prototype.replace = function(from, to, slice) { + if ( to === void 0 ) to = from; + if ( slice === void 0 ) slice = Slice.empty; + + var step = replaceStep(this.doc, from, to, slice); + if (step) { this.step(step); } + return this +}; + +// :: (number, number, union) → this +// Replace the given range with the given content, which may be a +// fragment, node, or array of nodes. +Transform.prototype.replaceWith = function(from, to, content) { + return this.replace(from, to, new Slice(Fragment.from(content), 0, 0)) +}; + +// :: (number, number) → this +// Delete the content between the given positions. +Transform.prototype.delete = function(from, to) { + return this.replace(from, to, Slice.empty) +}; + +// :: (number, union) → this +// Insert the given content at the given position. +Transform.prototype.insert = function(pos, content) { + return this.replaceWith(pos, pos, content) +}; + + + +function fitLeftInner($from, depth, placed, placedBelow) { + var content = Fragment.empty, openEnd = 0, placedHere = placed[depth]; + if ($from.depth > depth) { + var inner = fitLeftInner($from, depth + 1, placed, placedBelow || placedHere); + openEnd = inner.openEnd + 1; + content = Fragment.from($from.node(depth + 1).copy(inner.content)); + } + + if (placedHere) { + content = content.append(placedHere.content); + openEnd = placedHere.openEnd; + } + if (placedBelow) { + content = content.append($from.node(depth).contentMatchAt($from.indexAfter(depth)).fillBefore(Fragment.empty, true)); + openEnd = 0; + } + + return {content: content, openEnd: openEnd} +} + +function fitLeft($from, placed) { + var ref = fitLeftInner($from, 0, placed, false); + var content = ref.content; + var openEnd = ref.openEnd; + return new Slice(content, $from.depth, openEnd || 0) +} + +function fitRightJoin(content, parent, $from, $to, depth, openStart, openEnd) { + var match, count = content.childCount, matchCount = count - (openEnd > 0 ? 1 : 0); + var parentNode = openStart < 0 ? parent : $from.node(depth); + if (openStart < 0) + { match = parentNode.contentMatchAt(matchCount); } + else if (count == 1 && openEnd > 0) + { match = parentNode.contentMatchAt(openStart ? $from.index(depth) : $from.indexAfter(depth)); } + else + { match = parentNode.contentMatchAt($from.indexAfter(depth)) + .matchFragment(content, count > 0 && openStart ? 1 : 0, matchCount); } + + var toNode = $to.node(depth); + if (openEnd > 0 && depth < $to.depth) { + var after = toNode.content.cutByIndex($to.indexAfter(depth)).addToStart(content.lastChild); + var joinable$1 = match.fillBefore(after, true); + // Can't insert content if there's a single node stretched across this gap + if (joinable$1 && joinable$1.size && openStart > 0 && count == 1) { joinable$1 = null; } + + if (joinable$1) { + var inner = fitRightJoin(content.lastChild.content, content.lastChild, $from, $to, + depth + 1, count == 1 ? openStart - 1 : -1, openEnd - 1); + if (inner) { + var last = content.lastChild.copy(inner); + if (joinable$1.size) + { return content.cutByIndex(0, count - 1).append(joinable$1).addToEnd(last) } + else + { return content.replaceChild(count - 1, last) } + } + } + } + if (openEnd > 0) + { match = match.matchType((count == 1 && openStart > 0 ? $from.node(depth + 1) : content.lastChild).type); } + + // If we're here, the next level can't be joined, so we see what + // happens if we leave it open. + var toIndex = $to.index(depth); + if (toIndex == toNode.childCount && !toNode.type.compatibleContent(parent.type)) { return null } + var joinable = match.fillBefore(toNode.content, true, toIndex); + for (var i = toIndex; joinable && i < toNode.content.childCount; i++) + { if (!parentNode.type.allowsMarks(toNode.content.child(i).marks)) { joinable = null; } } + if (!joinable) { return null } + + if (openEnd > 0) { + var closed = fitRightClosed(content.lastChild, openEnd - 1, $from, depth + 1, + count == 1 ? openStart - 1 : -1); + content = content.replaceChild(count - 1, closed); + } + content = content.append(joinable); + if ($to.depth > depth) + { content = content.addToEnd(fitRightSeparate($to, depth + 1)); } + return content +} + +function fitRightClosed(node, openEnd, $from, depth, openStart) { + var match, content = node.content, count = content.childCount; + if (openStart >= 0) + { match = $from.node(depth).contentMatchAt($from.indexAfter(depth)) + .matchFragment(content, openStart > 0 ? 1 : 0, count); } + else + { match = node.contentMatchAt(count); } + + if (openEnd > 0) { + var closed = fitRightClosed(content.lastChild, openEnd - 1, $from, depth + 1, + count == 1 ? openStart - 1 : -1); + content = content.replaceChild(count - 1, closed); + } + + return node.copy(content.append(match.fillBefore(Fragment.empty, true))) +} + +function fitRightSeparate($to, depth) { + var node = $to.node(depth); + var fill = node.contentMatchAt(0).fillBefore(node.content, true, $to.index(depth)); + if ($to.depth > depth) { fill = fill.addToEnd(fitRightSeparate($to, depth + 1)); } + return node.copy(fill) +} + +function normalizeSlice(content, openStart, openEnd) { + while (openStart > 0 && openEnd > 0 && content.childCount == 1) { + content = content.firstChild.content; + openStart--; + openEnd--; + } + return new Slice(content, openStart, openEnd) +} + +// : (ResolvedPos, ResolvedPos, number, Slice) → Slice +function fitRight($from, $to, slice) { + var fitted = fitRightJoin(slice.content, $from.node(0), $from, $to, 0, slice.openStart, slice.openEnd); + if (!fitted) { return null } + return normalizeSlice(fitted, slice.openStart, $to.depth) +} + +function fitsTrivially($from, $to, slice) { + return !slice.openStart && !slice.openEnd && $from.start() == $to.start() && + $from.parent.canReplace($from.index(), $to.index(), slice.content) +} + +function canMoveText($from, $to, slice) { + if (!$to.parent.isTextblock) { return false } + + var parent = slice.openEnd ? nodeRight(slice.content, slice.openEnd) + : $from.node($from.depth - (slice.openStart - slice.openEnd)); + if (!parent.isTextblock) { return false } + for (var i = $to.index(); i < $to.parent.childCount; i++) + { if (!parent.type.allowsMarks($to.parent.child(i).marks)) { return false } } + var match; + if (slice.openEnd) { + match = parent.contentMatchAt(parent.childCount); + } else { + match = parent.contentMatchAt(parent.childCount); + if (slice.size) { match = match.matchFragment(slice.content, slice.openStart ? 1 : 0); } + } + match = match.matchFragment($to.parent.content, $to.index()); + return match && match.validEnd +} + +function nodeRight(content, depth) { + for (var i = 1; i < depth; i++) { content = content.lastChild.content; } + return content.lastChild +} + +// Algorithm for 'placing' the elements of a slice into a gap: +// +// We consider the content of each node that is open to the left to be +// independently placeable. I.e. in , when the +// paragraph on the left is open, "foo" can be placed (somewhere on +// the left side of the replacement gap) independently from p("bar"). +// +// So placeSlice splits up a slice into a number of sub-slices, +// along with information on where they can be placed on the given +// left-side edge. It works by walking the open side of the slice, +// from the inside out, and trying to find a landing spot for each +// element, by simultaneously scanning over the gap side. When no +// place is found for an open node's content, it is left in that node. + +// : (ResolvedPos, Slice) → [{content: Fragment, openEnd: number, depth: number}] +function placeSlice($from, slice) { + var frontier = new Frontier($from); + for (var pass = 1; slice.size && pass <= 3; pass++) { + var value = frontier.placeSlice(slice.content, slice.openStart, slice.openEnd, pass); + if (pass == 3 && value != slice && value.size) { pass = 0; } // Restart if the 3rd pass made progress but left content + slice = value; + } + while (frontier.open.length) { frontier.closeNode(); } + return frontier.placed +} + +// Helper class that models the open side of the insert position, +// keeping track of the content match and already inserted content +// at each depth. +var Frontier = function Frontier($pos) { + // : [{parent: Node, match: ContentMatch, content: Fragment, wrapper: bool, openEnd: number, depth: number}] + this.open = []; + for (var d = 0; d <= $pos.depth; d++) { + var parent = $pos.node(d), match = parent.contentMatchAt($pos.indexAfter(d)); + this.open.push({parent: parent, match: match, content: Fragment.empty, wrapper: false, openEnd: 0, depth: d}); + } + this.placed = []; +}; + +// : (Fragment, number, number, number, ?Node) → Slice +// Tries to place the content of the given slice, and returns a +// slice containing unplaced content. +// +// pass 1: try to fit directly +// pass 2: allow wrapper nodes to be introduced +// pass 3: allow unwrapping of nodes that aren't open +Frontier.prototype.placeSlice = function placeSlice (fragment, openStart, openEnd, pass, parent) { + if (openStart > 0) { + var first = fragment.firstChild; + var inner = this.placeSlice(first.content, Math.max(0, openStart - 1), + openEnd && fragment.childCount == 1 ? openEnd - 1 : 0, + pass, first); + if (inner.content != first.content) { + if (inner.content.size) { + fragment = fragment.replaceChild(0, first.copy(inner.content)); + openStart = inner.openStart + 1; + } else { + if (fragment.childCount == 1) { openEnd = 0; } + fragment = fragment.cutByIndex(1); + openStart = 0; + } + } + } + var result = this.placeContent(fragment, openStart, openEnd, pass, parent); + if (pass > 2 && result.size && openStart == 0) { + var child = result.content.firstChild, single = result.content.childCount == 1; + this.placeContent(child.content, 0, openEnd && single ? openEnd - 1 : 0, pass, child); + result = single ? Fragment.empty : new Slice(result.content.cutByIndex(1), 0, openEnd); + } + return result +}; + +Frontier.prototype.placeContent = function placeContent (fragment, openStart, openEnd, pass, parent) { + var i = 0; + // Go over the fragment's children + for (; i < fragment.childCount; i++) { + var child = fragment.child(i), placed = false, last = i == fragment.childCount - 1; + // Try each open node in turn, starting from the innermost + for (var d = this.open.length - 1; d >= 0; d--) { + var open = this.open[d], wrap = (void 0); + + // If pass > 1, it is allowed to wrap the node to help find a + // fit, so if findWrapping returns something, we add open + // nodes to the frontier for that wrapping. + if (pass > 1 && (wrap = open.match.findWrapping(child.type)) && + !(parent && wrap.length && wrap[wrap.length - 1] == parent.type)) { + while (this.open.length - 1 > d) { this.closeNode(); } + for (var w = 0; w < wrap.length; w++) { + open.match = open.match.matchType(wrap[w]); + d++; + open = {parent: wrap[w].create(), + match: wrap[w].contentMatch, + content: Fragment.empty, wrapper: true, openEnd: 0, depth: d + w}; + this.open.push(open); + } + } + + // See if the child fits here + var match = open.match.matchType(child.type); + if (!match) { + var fill = open.match.fillBefore(Fragment.from(child)); + if (fill) { + for (var j = 0; j < fill.childCount; j++) { + var ch = fill.child(j); + this.addNode(open, ch, 0); + match = open.match.matchFragment(ch); + } + } else if (parent && open.match.matchType(parent.type)) { + // Don't continue looking further up if the parent node + // would fit here. + break + } else { + continue + } + } + + // Close open nodes above this one, since we're starting to + // add to this. + while (this.open.length - 1 > d) { this.closeNode(); } + // Strip marks from the child or close its start when necessary + child = child.mark(open.parent.type.allowedMarks(child.marks)); + if (openStart) { + child = closeNodeStart(child, openStart, last ? openEnd : 0); + openStart = 0; + } + // Add the child to this open node and adjust its metadata + this.addNode(open, child, last ? openEnd : 0); + open.match = match; + if (last) { openEnd = 0; } + placed = true; + break + } + // As soon as we've failed to place a node we stop looking at + // later nodes + if (!placed) { break } + } + // Close the current open node if it's not the the root and we + // either placed up to the end of the node or the the current + // slice depth's node type matches the open node's type + if (this.open.length > 1 && + (i > 0 && i == fragment.childCount || + parent && this.open[this.open.length - 1].parent.type == parent.type)) + { this.closeNode(); } + + return new Slice(fragment.cutByIndex(i), openStart, openEnd) +}; + +Frontier.prototype.addNode = function addNode (open, node, openEnd) { + open.content = closeFragmentEnd(open.content, open.openEnd).addToEnd(node); + open.openEnd = openEnd; +}; + +Frontier.prototype.closeNode = function closeNode () { + var open = this.open.pop(); + if (open.content.size == 0) ; else if (open.wrapper) { + this.addNode(this.open[this.open.length - 1], open.parent.copy(open.content), open.openEnd + 1); + } else { + this.placed[open.depth] = {depth: open.depth, content: open.content, openEnd: open.openEnd}; + } +}; + +function closeNodeStart(node, openStart, openEnd) { + var content = node.content; + if (openStart > 1) { + var first = closeNodeStart(node.firstChild, openStart - 1, node.childCount == 1 ? openEnd - 1 : 0); + content = node.content.replaceChild(0, first); + } + var fill = node.type.contentMatch.fillBefore(content, openEnd == 0); + return node.copy(fill.append(content)) +} + +function closeNodeEnd(node, depth) { + var content = node.content; + if (depth > 1) { + var last = closeNodeEnd(node.lastChild, depth - 1); + content = node.content.replaceChild(node.childCount - 1, last); + } + var fill = node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true); + return node.copy(content.append(fill)) +} + +function closeFragmentEnd(fragment, depth) { + return depth ? fragment.replaceChild(fragment.childCount - 1, closeNodeEnd(fragment.lastChild, depth)) : fragment +} + +// :: (number, number, Slice) → this +// Replace a range of the document with a given slice, using `from`, +// `to`, and the slice's [`openStart`](#model.Slice.openStart) property +// as hints, rather than fixed start and end points. This method may +// grow the replaced area or close open nodes in the slice in order to +// get a fit that is more in line with WYSIWYG expectations, by +// dropping fully covered parent nodes of the replaced region when +// they are marked [non-defining](#model.NodeSpec.defining), or +// including an open parent node from the slice that _is_ marked as +// [defining](#model.NodeSpec.defining). +// +// This is the method, for example, to handle paste. The similar +// [`replace`](#transform.Transform.replace) method is a more +// primitive tool which will _not_ move the start and end of its given +// range, and is useful in situations where you need more precise +// control over what happens. +Transform.prototype.replaceRange = function(from, to, slice) { + if (!slice.size) { return this.deleteRange(from, to) } + + var $from = this.doc.resolve(from), $to = this.doc.resolve(to); + if (fitsTrivially($from, $to, slice)) + { return this.step(new ReplaceStep(from, to, slice)) } + + var targetDepths = coveredDepths($from, this.doc.resolve(to)); + // Can't replace the whole document, so remove 0 if it's present + if (targetDepths[targetDepths.length - 1] == 0) { targetDepths.pop(); } + // Negative numbers represent not expansion over the whole node at + // that depth, but replacing from $from.before(-D) to $to.pos. + var preferredTarget = -($from.depth + 1); + targetDepths.unshift(preferredTarget); + // This loop picks a preferred target depth, if one of the covering + // depths is not outside of a defining node, and adds negative + // depths for any depth that has $from at its start and does not + // cross a defining node. + for (var d = $from.depth, pos = $from.pos - 1; d > 0; d--, pos--) { + var spec = $from.node(d).type.spec; + if (spec.defining || spec.isolating) { break } + if (targetDepths.indexOf(d) > -1) { preferredTarget = d; } + else if ($from.before(d) == pos) { targetDepths.splice(1, 0, -d); } + } + // Try to fit each possible depth of the slice into each possible + // target depth, starting with the preferred depths. + var preferredTargetIndex = targetDepths.indexOf(preferredTarget); + + var leftNodes = [], preferredDepth = slice.openStart; + for (var content = slice.content, i = 0;; i++) { + var node = content.firstChild; + leftNodes.push(node); + if (i == slice.openStart) { break } + content = node.content; + } + // Back up if the node directly above openStart, or the node above + // that separated only by a non-defining textblock node, is defining. + if (preferredDepth > 0 && leftNodes[preferredDepth - 1].type.spec.defining && + $from.node(preferredTargetIndex).type != leftNodes[preferredDepth - 1].type) + { preferredDepth -= 1; } + else if (preferredDepth >= 2 && leftNodes[preferredDepth - 1].isTextblock && leftNodes[preferredDepth - 2].type.spec.defining && + $from.node(preferredTargetIndex).type != leftNodes[preferredDepth - 2].type) + { preferredDepth -= 2; } + + for (var j = slice.openStart; j >= 0; j--) { + var openDepth = (j + preferredDepth + 1) % (slice.openStart + 1); + var insert = leftNodes[openDepth]; + if (!insert) { continue } + for (var i$1 = 0; i$1 < targetDepths.length; i$1++) { + // Loop over possible expansion levels, starting with the + // preferred one + var targetDepth = targetDepths[(i$1 + preferredTargetIndex) % targetDepths.length], expand = true; + if (targetDepth < 0) { expand = false; targetDepth = -targetDepth; } + var parent = $from.node(targetDepth - 1), index = $from.index(targetDepth - 1); + if (parent.canReplaceWith(index, index, insert.type, insert.marks)) + { return this.replace($from.before(targetDepth), expand ? $to.after(targetDepth) : to, + new Slice(closeFragment(slice.content, 0, slice.openStart, openDepth), + openDepth, slice.openEnd)) } + } + } + + var startSteps = this.steps.length; + for (var i$2 = targetDepths.length - 1; i$2 >= 0; i$2--) { + this.replace(from, to, slice); + if (this.steps.length > startSteps) { break } + var depth = targetDepths[i$2]; + if (i$2 < 0) { continue } + from = $from.before(depth); to = $to.after(depth); + } + return this +}; + +function closeFragment(fragment, depth, oldOpen, newOpen, parent) { + if (depth < oldOpen) { + var first = fragment.firstChild; + fragment = fragment.replaceChild(0, first.copy(closeFragment(first.content, depth + 1, oldOpen, newOpen, first))); + } + if (depth > newOpen) { + var match = parent.contentMatchAt(0); + var start = match.fillBefore(fragment).append(fragment); + fragment = start.append(match.matchFragment(start).fillBefore(Fragment.empty, true)); + } + return fragment +} + +// :: (number, number, Node) → this +// Replace the given range with a node, but use `from` and `to` as +// hints, rather than precise positions. When from and to are the same +// and are at the start or end of a parent node in which the given +// node doesn't fit, this method may _move_ them out towards a parent +// that does allow the given node to be placed. When the given range +// completely covers a parent node, this method may completely replace +// that parent node. +Transform.prototype.replaceRangeWith = function(from, to, node) { + if (!node.isInline && from == to && this.doc.resolve(from).parent.content.size) { + var point = insertPoint(this.doc, from, node.type); + if (point != null) { from = to = point; } + } + return this.replaceRange(from, to, new Slice(Fragment.from(node), 0, 0)) +}; + +// :: (number, number) → this +// Delete the given range, expanding it to cover fully covered +// parent nodes until a valid replace is found. +Transform.prototype.deleteRange = function(from, to) { + var $from = this.doc.resolve(from), $to = this.doc.resolve(to); + var covered = coveredDepths($from, $to); + for (var i = 0; i < covered.length; i++) { + var depth = covered[i], last = i == covered.length - 1; + if ((last && depth == 0) || $from.node(depth).type.contentMatch.validEnd) + { return this.delete($from.start(depth), $to.end(depth)) } + if (depth > 0 && (last || $from.node(depth - 1).canReplace($from.index(depth - 1), $to.indexAfter(depth - 1)))) + { return this.delete($from.before(depth), $to.after(depth)) } + } + for (var d = 1; d <= $from.depth && d <= $to.depth; d++) { + if (from - $from.start(d) == $from.depth - d && to > $from.end(d) && $to.end(d) - to != $to.depth - d) + { return this.delete($from.before(d), to) } + } + return this.delete(from, to) +}; + +// : (ResolvedPos, ResolvedPos) → [number] +// Returns an array of all depths for which $from - $to spans the +// whole content of the nodes at that depth. +function coveredDepths($from, $to) { + var result = [], minDepth = Math.min($from.depth, $to.depth); + for (var d = minDepth; d >= 0; d--) { + var start = $from.start(d); + if (start < $from.pos - ($from.depth - d) || + $to.end(d) > $to.pos + ($to.depth - d) || + $from.node(d).type.spec.isolating || + $to.node(d).type.spec.isolating) { break } + if (start == $to.start(d)) { result.push(d); } + } + return result +} + +export { AddMarkStep, MapResult, Mapping, RemoveMarkStep, ReplaceAroundStep, ReplaceStep, Step, StepMap, StepResult, Transform, TransformError, canJoin, canSplit, dropPoint, findWrapping, insertPoint, joinPoint, liftTarget, replaceStep }; +//# sourceMappingURL=index.es.js.map diff --git a/packages/tiptap-extensions/node_modules/prosemirror-transform/dist/index.es.js.map b/packages/tiptap-extensions/node_modules/prosemirror-transform/dist/index.es.js.map new file mode 100644 index 0000000000..06f30ac132 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-transform/dist/index.es.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.es.js","sources":["../src/map.js","../src/transform.js","../src/step.js","../src/replace_step.js","../src/structure.js","../src/mark_step.js","../src/mark.js","../src/replace.js"],"sourcesContent":["// Mappable:: interface\n// There are several things that positions can be mapped through.\n// Such objects conform to this interface.\n//\n// map:: (pos: number, assoc: ?number) → number\n// Map a position through this object. When given, `assoc` (should\n// be -1 or 1, defaults to 1) determines with which side the\n// position is associated, which determines in which direction to\n// move when a chunk of content is inserted at the mapped position.\n//\n// mapResult:: (pos: number, assoc: ?number) → MapResult\n// Map a position, and return an object containing additional\n// information about the mapping. The result's `deleted` field tells\n// you whether the position was deleted (completely enclosed in a\n// replaced range) during the mapping. When content on only one side\n// is deleted, the position itself is only considered deleted when\n// `assoc` points in the direction of the deleted content.\n\n// Recovery values encode a range index and an offset. They are\n// represented as numbers, because tons of them will be created when\n// mapping, for example, a large number of decorations. The number's\n// lower 16 bits provide the index, the remaining bits the offset.\n//\n// Note: We intentionally don't use bit shift operators to en- and\n// decode these, since those clip to 32 bits, which we might in rare\n// cases want to overflow. A 64-bit float can represent 48-bit\n// integers precisely.\n\nconst lower16 = 0xffff\nconst factor16 = Math.pow(2, 16)\n\nfunction makeRecover(index, offset) { return index + offset * factor16 }\nfunction recoverIndex(value) { return value & lower16 }\nfunction recoverOffset(value) { return (value - (value & lower16)) / factor16 }\n\n// ::- An object representing a mapped position with extra\n// information.\nexport class MapResult {\n constructor(pos, deleted = false, recover = null) {\n // :: number The mapped version of the position.\n this.pos = pos\n // :: bool Tells you whether the position was deleted, that is,\n // whether the step removed its surroundings from the document.\n this.deleted = deleted\n this.recover = recover\n }\n}\n\n// :: class extends Mappable\n// A map describing the deletions and insertions made by a step, which\n// can be used to find the correspondence between positions in the\n// pre-step version of a document and the same position in the\n// post-step version.\nexport class StepMap {\n // :: ([number])\n // Create a position map. The modifications to the document are\n // represented as an array of numbers, in which each group of three\n // represents a modified chunk as `[start, oldSize, newSize]`.\n constructor(ranges, inverted = false) {\n this.ranges = ranges\n this.inverted = inverted\n }\n\n recover(value) {\n let diff = 0, index = recoverIndex(value)\n if (!this.inverted) for (let i = 0; i < index; i++)\n diff += this.ranges[i * 3 + 2] - this.ranges[i * 3 + 1]\n return this.ranges[index * 3] + diff + recoverOffset(value)\n }\n\n // : (number, ?number) → MapResult\n mapResult(pos, assoc = 1) { return this._map(pos, assoc, false) }\n\n // : (number, ?number) → number\n map(pos, assoc = 1) { return this._map(pos, assoc, true) }\n\n _map(pos, assoc, simple) {\n let diff = 0, oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2\n for (let i = 0; i < this.ranges.length; i += 3) {\n let start = this.ranges[i] - (this.inverted ? diff : 0)\n if (start > pos) break\n let oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex], end = start + oldSize\n if (pos <= end) {\n let side = !oldSize ? assoc : pos == start ? -1 : pos == end ? 1 : assoc\n let result = start + diff + (side < 0 ? 0 : newSize)\n if (simple) return result\n let recover = makeRecover(i / 3, pos - start)\n return new MapResult(result, assoc < 0 ? pos != start : pos != end, recover)\n }\n diff += newSize - oldSize\n }\n return simple ? pos + diff : new MapResult(pos + diff)\n }\n\n touches(pos, recover) {\n let diff = 0, index = recoverIndex(recover)\n let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2\n for (let i = 0; i < this.ranges.length; i += 3) {\n let start = this.ranges[i] - (this.inverted ? diff : 0)\n if (start > pos) break\n let oldSize = this.ranges[i + oldIndex], end = start + oldSize\n if (pos <= end && i == index * 3) return true\n diff += this.ranges[i + newIndex] - oldSize\n }\n return false\n }\n\n // :: ((oldStart: number, oldEnd: number, newStart: number, newEnd: number))\n // Calls the given function on each of the changed ranges included in\n // this map.\n forEach(f) {\n let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2\n for (let i = 0, diff = 0; i < this.ranges.length; i += 3) {\n let start = this.ranges[i], oldStart = start - (this.inverted ? diff : 0), newStart = start + (this.inverted ? 0 : diff)\n let oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex]\n f(oldStart, oldStart + oldSize, newStart, newStart + newSize)\n diff += newSize - oldSize\n }\n }\n\n // :: () → StepMap\n // Create an inverted version of this map. The result can be used to\n // map positions in the post-step document to the pre-step document.\n invert() {\n return new StepMap(this.ranges, !this.inverted)\n }\n\n toString() {\n return (this.inverted ? \"-\" : \"\") + JSON.stringify(this.ranges)\n }\n\n // :: (n: number) → StepMap\n // Create a map that moves all positions by offset `n` (which may be\n // negative). This can be useful when applying steps meant for a\n // sub-document to a larger document, or vice-versa.\n static offset(n) {\n return n == 0 ? StepMap.empty : new StepMap(n < 0 ? [0, -n, 0] : [0, 0, n])\n }\n}\n\nStepMap.empty = new StepMap([])\n\n// :: class extends Mappable\n// A mapping represents a pipeline of zero or more [step\n// maps](#transform.StepMap). It has special provisions for losslessly\n// handling mapping positions through a series of steps in which some\n// steps are inverted versions of earlier steps. (This comes up when\n// ‘[rebasing](/docs/guide/#transform.rebasing)’ steps for\n// collaboration or history management.)\nexport class Mapping {\n // :: (?[StepMap])\n // Create a new mapping with the given position maps.\n constructor(maps, mirror, from, to) {\n // :: [StepMap]\n // The step maps in this mapping.\n this.maps = maps || []\n // :: number\n // The starting position in the `maps` array, used when `map` or\n // `mapResult` is called.\n this.from = from || 0\n // :: number\n // The end position in the `maps` array.\n this.to = to == null ? this.maps.length : to\n this.mirror = mirror\n }\n\n // :: (?number, ?number) → Mapping\n // Create a mapping that maps only through a part of this one.\n slice(from = 0, to = this.maps.length) {\n return new Mapping(this.maps, this.mirror, from, to)\n }\n\n copy() {\n return new Mapping(this.maps.slice(), this.mirror && this.mirror.slice(), this.from, this.to)\n }\n\n // :: (StepMap, ?number)\n // Add a step map to the end of this mapping. If `mirrors` is\n // given, it should be the index of the step map that is the mirror\n // image of this one.\n appendMap(map, mirrors) {\n this.to = this.maps.push(map)\n if (mirrors != null) this.setMirror(this.maps.length - 1, mirrors)\n }\n\n // :: (Mapping)\n // Add all the step maps in a given mapping to this one (preserving\n // mirroring information).\n appendMapping(mapping) {\n for (let i = 0, startSize = this.maps.length; i < mapping.maps.length; i++) {\n let mirr = mapping.getMirror(i)\n this.appendMap(mapping.maps[i], mirr != null && mirr < i ? startSize + mirr : null)\n }\n }\n\n // :: (number) → ?number\n // Finds the offset of the step map that mirrors the map at the\n // given offset, in this mapping (as per the second argument to\n // `appendMap`).\n getMirror(n) {\n if (this.mirror) for (let i = 0; i < this.mirror.length; i++)\n if (this.mirror[i] == n) return this.mirror[i + (i % 2 ? -1 : 1)]\n }\n\n setMirror(n, m) {\n if (!this.mirror) this.mirror = []\n this.mirror.push(n, m)\n }\n\n // :: (Mapping)\n // Append the inverse of the given mapping to this one.\n appendMappingInverted(mapping) {\n for (let i = mapping.maps.length - 1, totalSize = this.maps.length + mapping.maps.length; i >= 0; i--) {\n let mirr = mapping.getMirror(i)\n this.appendMap(mapping.maps[i].invert(), mirr != null && mirr > i ? totalSize - mirr - 1 : null)\n }\n }\n\n // :: () → Mapping\n // Create an inverted version of this mapping.\n invert() {\n let inverse = new Mapping\n inverse.appendMappingInverted(this)\n return inverse\n }\n\n // : (number, ?number) → number\n // Map a position through this mapping.\n map(pos, assoc = 1) {\n if (this.mirror) return this._map(pos, assoc, true)\n for (let i = this.from; i < this.to; i++)\n pos = this.maps[i].map(pos, assoc)\n return pos\n }\n\n // : (number, ?number) → MapResult\n // Map a position through this mapping, returning a mapping\n // result.\n mapResult(pos, assoc = 1) { return this._map(pos, assoc, false) }\n\n _map(pos, assoc, simple) {\n let deleted = false, recoverables = null\n\n for (let i = this.from; i < this.to; i++) {\n let map = this.maps[i], rec = recoverables && recoverables[i]\n if (rec != null && map.touches(pos, rec)) {\n pos = map.recover(rec)\n continue\n }\n\n let result = map.mapResult(pos, assoc)\n if (result.recover != null) {\n let corr = this.getMirror(i)\n if (corr != null && corr > i && corr < this.to) {\n if (result.deleted) {\n i = corr\n pos = this.maps[corr].recover(result.recover)\n continue\n } else {\n ;(recoverables || (recoverables = Object.create(null)))[corr] = result.recover\n }\n }\n }\n\n if (result.deleted) deleted = true\n pos = result.pos\n }\n\n return simple ? pos : new MapResult(pos, deleted)\n }\n}\n","import {Mapping} from \"./map\"\n\nexport function TransformError(message) {\n let err = Error.call(this, message)\n err.__proto__ = TransformError.prototype\n return err\n}\n\nTransformError.prototype = Object.create(Error.prototype)\nTransformError.prototype.constructor = TransformError\nTransformError.prototype.name = \"TransformError\"\n\n// ::- Abstraction to build up and track an array of\n// [steps](#transform.Step) representing a document transformation.\n//\n// Most transforming methods return the `Transform` object itself, so\n// that they can be chained.\nexport class Transform {\n // :: (Node)\n // Create a transform that starts with the given document.\n constructor(doc) {\n // :: Node\n // The current document (the result of applying the steps in the\n // transform).\n this.doc = doc\n // :: [Step]\n // The steps in this transform.\n this.steps = []\n // :: [Node]\n // The documents before each of the steps.\n this.docs = []\n // :: Mapping\n // A mapping with the maps for each of the steps in this transform.\n this.mapping = new Mapping\n }\n\n // :: Node The starting document.\n get before() { return this.docs.length ? this.docs[0] : this.doc }\n\n // :: (step: Step) → this\n // Apply a new step in this transform, saving the result. Throws an\n // error when the step fails.\n step(object) {\n let result = this.maybeStep(object)\n if (result.failed) throw new TransformError(result.failed)\n return this\n }\n\n // :: (Step) → StepResult\n // Try to apply a step in this transformation, ignoring it if it\n // fails. Returns the step result.\n maybeStep(step) {\n let result = step.apply(this.doc)\n if (!result.failed) this.addStep(step, result.doc)\n return result\n }\n\n // :: bool\n // True when the document has been changed (when there are any\n // steps).\n get docChanged() {\n return this.steps.length > 0\n }\n\n addStep(step, doc) {\n this.docs.push(this.doc)\n this.steps.push(step)\n this.mapping.appendMap(step.getMap())\n this.doc = doc\n }\n}\n","import {ReplaceError} from \"prosemirror-model\"\n\nimport {StepMap} from \"./map\"\n\nfunction mustOverride() { throw new Error(\"Override me\") }\n\nconst stepsByID = Object.create(null)\n\n// ::- A step object represents an atomic change. It generally applies\n// only to the document it was created for, since the positions\n// stored in it will only make sense for that document.\n//\n// New steps are defined by creating classes that extend `Step`,\n// overriding the `apply`, `invert`, `map`, `getMap` and `fromJSON`\n// methods, and registering your class with a unique\n// JSON-serialization identifier using\n// [`Step.jsonID`](#transform.Step^jsonID).\nexport class Step {\n // :: (doc: Node) → StepResult\n // Applies this step to the given document, returning a result\n // object that either indicates failure, if the step can not be\n // applied to this document, or indicates success by containing a\n // transformed document.\n apply(_doc) { return mustOverride() }\n\n // :: () → StepMap\n // Get the step map that represents the changes made by this step,\n // and which can be used to transform between positions in the old\n // and the new document.\n getMap() { return StepMap.empty }\n\n // :: (doc: Node) → Step\n // Create an inverted version of this step. Needs the document as it\n // was before the step as argument.\n invert(_doc) { return mustOverride() }\n\n // :: (mapping: Mappable) → ?Step\n // Map this step through a mappable thing, returning either a\n // version of that step with its positions adjusted, or `null` if\n // the step was entirely deleted by the mapping.\n map(_mapping) { return mustOverride() }\n\n // :: (other: Step) → ?Step\n // Try to merge this step with another one, to be applied directly\n // after it. Returns the merged step when possible, null if the\n // steps can't be merged.\n merge(_other) { return null }\n\n // :: () → Object\n // Create a JSON-serializeable representation of this step. When\n // defining this for a custom subclass, make sure the result object\n // includes the step type's [JSON id](#transform.Step^jsonID) under\n // the `stepType` property.\n toJSON() { return mustOverride() }\n\n // :: (Schema, Object) → Step\n // Deserialize a step from its JSON representation. Will call\n // through to the step class' own implementation of this method.\n static fromJSON(schema, json) {\n if (!json || !json.stepType) throw new RangeError(\"Invalid input for Step.fromJSON\")\n let type = stepsByID[json.stepType]\n if (!type) throw new RangeError(`No step type ${json.stepType} defined`)\n return type.fromJSON(schema, json)\n }\n\n // :: (string, constructor)\n // To be able to serialize steps to JSON, each step needs a string\n // ID to attach to its JSON representation. Use this method to\n // register an ID for your step classes. Try to pick something\n // that's unlikely to clash with steps from other modules.\n static jsonID(id, stepClass) {\n if (id in stepsByID) throw new RangeError(\"Duplicate use of step JSON ID \" + id)\n stepsByID[id] = stepClass\n stepClass.prototype.jsonID = id\n return stepClass\n }\n}\n\n// ::- The result of [applying](#transform.Step.apply) a step. Contains either a\n// new document or a failure value.\nexport class StepResult {\n // : (?Node, ?string)\n constructor(doc, failed) {\n // :: ?Node The transformed document.\n this.doc = doc\n // :: ?string Text providing information about a failed step.\n this.failed = failed\n }\n\n // :: (Node) → StepResult\n // Create a successful step result.\n static ok(doc) { return new StepResult(doc, null) }\n\n // :: (string) → StepResult\n // Create a failed step result.\n static fail(message) { return new StepResult(null, message) }\n\n // :: (Node, number, number, Slice) → StepResult\n // Call [`Node.replace`](#model.Node.replace) with the given\n // arguments. Create a successful result if it succeeds, and a\n // failed one if it throws a `ReplaceError`.\n static fromReplace(doc, from, to, slice) {\n try {\n return StepResult.ok(doc.replace(from, to, slice))\n } catch (e) {\n if (e instanceof ReplaceError) return StepResult.fail(e.message)\n throw e\n }\n }\n}\n","import {Slice} from \"prosemirror-model\"\n\nimport {Step, StepResult} from \"./step\"\nimport {StepMap} from \"./map\"\n\n// ::- Replace a part of the document with a slice of new content.\nexport class ReplaceStep extends Step {\n // :: (number, number, Slice, ?bool)\n // The given `slice` should fit the 'gap' between `from` and\n // `to`—the depths must line up, and the surrounding nodes must be\n // able to be joined with the open sides of the slice. When\n // `structure` is true, the step will fail if the content between\n // from and to is not just a sequence of closing and then opening\n // tokens (this is to guard against rebased replace steps\n // overwriting something they weren't supposed to).\n constructor(from, to, slice, structure) {\n super()\n this.from = from\n this.to = to\n this.slice = slice\n this.structure = !!structure\n }\n\n apply(doc) {\n if (this.structure && contentBetween(doc, this.from, this.to))\n return StepResult.fail(\"Structure replace would overwrite content\")\n return StepResult.fromReplace(doc, this.from, this.to, this.slice)\n }\n\n getMap() {\n return new StepMap([this.from, this.to - this.from, this.slice.size])\n }\n\n invert(doc) {\n return new ReplaceStep(this.from, this.from + this.slice.size, doc.slice(this.from, this.to))\n }\n\n map(mapping) {\n let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1)\n if (from.deleted && to.deleted) return null\n return new ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice)\n }\n\n merge(other) {\n if (!(other instanceof ReplaceStep) || other.structure != this.structure) return null\n\n if (this.from + this.slice.size == other.from && !this.slice.openEnd && !other.slice.openStart) {\n let slice = this.slice.size + other.slice.size == 0 ? Slice.empty\n : new Slice(this.slice.content.append(other.slice.content), this.slice.openStart, other.slice.openEnd)\n return new ReplaceStep(this.from, this.to + (other.to - other.from), slice, this.structure)\n } else if (other.to == this.from && !this.slice.openStart && !other.slice.openEnd) {\n let slice = this.slice.size + other.slice.size == 0 ? Slice.empty\n : new Slice(other.slice.content.append(this.slice.content), other.slice.openStart, this.slice.openEnd)\n return new ReplaceStep(other.from, this.to, slice, this.structure)\n } else {\n return null\n }\n }\n\n toJSON() {\n let json = {stepType: \"replace\", from: this.from, to: this.to}\n if (this.slice.size) json.slice = this.slice.toJSON()\n if (this.structure) json.structure = true\n return json\n }\n\n static fromJSON(schema, json) {\n if (typeof json.from != \"number\" || typeof json.to != \"number\")\n throw new RangeError(\"Invalid input for ReplaceStep.fromJSON\")\n return new ReplaceStep(json.from, json.to, Slice.fromJSON(schema, json.slice), !!json.structure)\n }\n}\n\nStep.jsonID(\"replace\", ReplaceStep)\n\n// ::- Replace a part of the document with a slice of content, but\n// preserve a range of the replaced content by moving it into the\n// slice.\nexport class ReplaceAroundStep extends Step {\n // :: (number, number, number, number, Slice, number, ?bool)\n // Create a replace-around step with the given range and gap.\n // `insert` should be the point in the slice into which the content\n // of the gap should be moved. `structure` has the same meaning as\n // it has in the [`ReplaceStep`](#transform.ReplaceStep) class.\n constructor(from, to, gapFrom, gapTo, slice, insert, structure) {\n super()\n this.from = from\n this.to = to\n this.gapFrom = gapFrom\n this.gapTo = gapTo\n this.slice = slice\n this.insert = insert\n this.structure = !!structure\n }\n\n apply(doc) {\n if (this.structure && (contentBetween(doc, this.from, this.gapFrom) ||\n contentBetween(doc, this.gapTo, this.to)))\n return StepResult.fail(\"Structure gap-replace would overwrite content\")\n\n let gap = doc.slice(this.gapFrom, this.gapTo)\n if (gap.openStart || gap.openEnd)\n return StepResult.fail(\"Gap is not a flat range\")\n let inserted = this.slice.insertAt(this.insert, gap.content)\n if (!inserted) return StepResult.fail(\"Content does not fit in gap\")\n return StepResult.fromReplace(doc, this.from, this.to, inserted)\n }\n\n getMap() {\n return new StepMap([this.from, this.gapFrom - this.from, this.insert,\n this.gapTo, this.to - this.gapTo, this.slice.size - this.insert])\n }\n\n invert(doc) {\n let gap = this.gapTo - this.gapFrom\n return new ReplaceAroundStep(this.from, this.from + this.slice.size + gap,\n this.from + this.insert, this.from + this.insert + gap,\n doc.slice(this.from, this.to).removeBetween(this.gapFrom - this.from, this.gapTo - this.from),\n this.gapFrom - this.from, this.structure)\n }\n\n map(mapping) {\n let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1)\n let gapFrom = mapping.map(this.gapFrom, -1), gapTo = mapping.map(this.gapTo, 1)\n if ((from.deleted && to.deleted) || gapFrom < from.pos || gapTo > to.pos) return null\n return new ReplaceAroundStep(from.pos, to.pos, gapFrom, gapTo, this.slice, this.insert, this.structure)\n }\n\n toJSON() {\n let json = {stepType: \"replaceAround\", from: this.from, to: this.to,\n gapFrom: this.gapFrom, gapTo: this.gapTo, insert: this.insert}\n if (this.slice.size) json.slice = this.slice.toJSON()\n if (this.structure) json.structure = true\n return json\n }\n\n static fromJSON(schema, json) {\n if (typeof json.from != \"number\" || typeof json.to != \"number\" ||\n typeof json.gapFrom != \"number\" || typeof json.gapTo != \"number\" || typeof json.insert != \"number\")\n throw new RangeError(\"Invalid input for ReplaceAroundStep.fromJSON\")\n return new ReplaceAroundStep(json.from, json.to, json.gapFrom, json.gapTo,\n Slice.fromJSON(schema, json.slice), json.insert, !!json.structure)\n }\n}\n\nStep.jsonID(\"replaceAround\", ReplaceAroundStep)\n\nfunction contentBetween(doc, from, to) {\n let $from = doc.resolve(from), dist = to - from, depth = $from.depth\n while (dist > 0 && depth > 0 && $from.indexAfter(depth) == $from.node(depth).childCount) {\n depth--\n dist--\n }\n if (dist > 0) {\n let next = $from.node(depth).maybeChild($from.indexAfter(depth))\n while (dist > 0) {\n if (!next || next.isLeaf) return true\n next = next.firstChild\n dist--\n }\n }\n return false\n}\n","import {Slice, Fragment} from \"prosemirror-model\"\n\nimport {Transform} from \"./transform\"\nimport {ReplaceStep, ReplaceAroundStep} from \"./replace_step\"\n\nfunction canCut(node, start, end) {\n return (start == 0 || node.canReplace(start, node.childCount)) &&\n (end == node.childCount || node.canReplace(0, end))\n}\n\n// :: (NodeRange) → ?number\n// Try to find a target depth to which the content in the given range\n// can be lifted. Will not go across\n// [isolating](#model.NodeSpec.isolating) parent nodes.\nexport function liftTarget(range) {\n let parent = range.parent\n let content = parent.content.cutByIndex(range.startIndex, range.endIndex)\n for (let depth = range.depth;; --depth) {\n let node = range.$from.node(depth)\n let index = range.$from.index(depth), endIndex = range.$to.indexAfter(depth)\n if (depth < range.depth && node.canReplace(index, endIndex, content))\n return depth\n if (depth == 0 || node.type.spec.isolating || !canCut(node, index, endIndex)) break\n }\n}\n\n// :: (NodeRange, number) → this\n// Split the content in the given range off from its parent, if there\n// is sibling content before or after it, and move it up the tree to\n// the depth specified by `target`. You'll probably want to use\n// [`liftTarget`](#transform.liftTarget) to compute `target`, to make\n// sure the lift is valid.\nTransform.prototype.lift = function(range, target) {\n let {$from, $to, depth} = range\n\n let gapStart = $from.before(depth + 1), gapEnd = $to.after(depth + 1)\n let start = gapStart, end = gapEnd\n\n let before = Fragment.empty, openStart = 0\n for (let d = depth, splitting = false; d > target; d--)\n if (splitting || $from.index(d) > 0) {\n splitting = true\n before = Fragment.from($from.node(d).copy(before))\n openStart++\n } else {\n start--\n }\n let after = Fragment.empty, openEnd = 0\n for (let d = depth, splitting = false; d > target; d--)\n if (splitting || $to.after(d + 1) < $to.end(d)) {\n splitting = true\n after = Fragment.from($to.node(d).copy(after))\n openEnd++\n } else {\n end++\n }\n\n return this.step(new ReplaceAroundStep(start, end, gapStart, gapEnd,\n new Slice(before.append(after), openStart, openEnd),\n before.size - openStart, true))\n}\n\n// :: (NodeRange, NodeType, ?Object, ?NodeRange) → ?[{type: NodeType, attrs: ?Object}]\n// Try to find a valid way to wrap the content in the given range in a\n// node of the given type. May introduce extra nodes around and inside\n// the wrapper node, if necessary. Returns null if no valid wrapping\n// could be found. When `innerRange` is given, that range's content is\n// used as the content to fit into the wrapping, instead of the\n// content of `range`.\nexport function findWrapping(range, nodeType, attrs, innerRange = range) {\n let around = findWrappingOutside(range, nodeType)\n let inner = around && findWrappingInside(innerRange, nodeType)\n if (!inner) return null\n return around.map(withAttrs).concat({type: nodeType, attrs}).concat(inner.map(withAttrs))\n}\n\nfunction withAttrs(type) { return {type, attrs: null} }\n\nfunction findWrappingOutside(range, type) {\n let {parent, startIndex, endIndex} = range\n let around = parent.contentMatchAt(startIndex).findWrapping(type)\n if (!around) return null\n let outer = around.length ? around[0] : type\n return parent.canReplaceWith(startIndex, endIndex, outer) ? around : null\n}\n\nfunction findWrappingInside(range, type) {\n let {parent, startIndex, endIndex} = range\n let inner = parent.child(startIndex)\n let inside = type.contentMatch.findWrapping(inner.type)\n if (!inside) return null\n let lastType = inside.length ? inside[inside.length - 1] : type\n let innerMatch = lastType.contentMatch\n for (let i = startIndex; innerMatch && i < endIndex; i++)\n innerMatch = innerMatch.matchType(parent.child(i).type)\n if (!innerMatch || !innerMatch.validEnd) return null\n return inside\n}\n\n// :: (NodeRange, [{type: NodeType, attrs: ?Object}]) → this\n// Wrap the given [range](#model.NodeRange) in the given set of wrappers.\n// The wrappers are assumed to be valid in this position, and should\n// probably be computed with [`findWrapping`](#transform.findWrapping).\nTransform.prototype.wrap = function(range, wrappers) {\n let content = Fragment.empty\n for (let i = wrappers.length - 1; i >= 0; i--)\n content = Fragment.from(wrappers[i].type.create(wrappers[i].attrs, content))\n\n let start = range.start, end = range.end\n return this.step(new ReplaceAroundStep(start, end, start, end, new Slice(content, 0, 0), wrappers.length, true))\n}\n\n// :: (number, ?number, NodeType, ?Object) → this\n// Set the type of all textblocks (partly) between `from` and `to` to\n// the given node type with the given attributes.\nTransform.prototype.setBlockType = function(from, to = from, type, attrs) {\n if (!type.isTextblock) throw new RangeError(\"Type given to setBlockType should be a textblock\")\n let mapFrom = this.steps.length\n this.doc.nodesBetween(from, to, (node, pos) => {\n if (node.isTextblock && !node.hasMarkup(type, attrs) && canChangeType(this.doc, this.mapping.slice(mapFrom).map(pos), type)) {\n // Ensure all markup that isn't allowed in the new node type is cleared\n this.clearIncompatible(this.mapping.slice(mapFrom).map(pos, 1), type)\n let mapping = this.mapping.slice(mapFrom)\n let startM = mapping.map(pos, 1), endM = mapping.map(pos + node.nodeSize, 1)\n this.step(new ReplaceAroundStep(startM, endM, startM + 1, endM - 1,\n new Slice(Fragment.from(type.create(attrs, null, node.marks)), 0, 0), 1, true))\n return false\n }\n })\n return this\n}\n\nfunction canChangeType(doc, pos, type) {\n let $pos = doc.resolve(pos), index = $pos.index()\n return $pos.parent.canReplaceWith(index, index + 1, type)\n}\n\n// :: (number, ?NodeType, ?Object, ?[Mark]) → this\n// Change the type, attributes, and/or marks of the node at `pos`.\n// When `type` isn't given, the existing node type is preserved,\nTransform.prototype.setNodeMarkup = function(pos, type, attrs, marks) {\n let node = this.doc.nodeAt(pos)\n if (!node) throw new RangeError(\"No node at given position\")\n if (!type) type = node.type\n let newNode = type.create(attrs, null, marks || node.marks)\n if (node.isLeaf)\n return this.replaceWith(pos, pos + node.nodeSize, newNode)\n\n if (!type.validContent(node.content))\n throw new RangeError(\"Invalid content for node type \" + type.name)\n\n return this.step(new ReplaceAroundStep(pos, pos + node.nodeSize, pos + 1, pos + node.nodeSize - 1,\n new Slice(Fragment.from(newNode), 0, 0), 1, true))\n}\n\n// :: (Node, number, number, ?[?{type: NodeType, attrs: ?Object}]) → bool\n// Check whether splitting at the given position is allowed.\nexport function canSplit(doc, pos, depth = 1, typesAfter) {\n let $pos = doc.resolve(pos), base = $pos.depth - depth\n let innerType = (typesAfter && typesAfter[typesAfter.length - 1]) || $pos.parent\n if (base < 0 || $pos.parent.type.spec.isolating ||\n !$pos.parent.canReplace($pos.index(), $pos.parent.childCount) ||\n !innerType.type.validContent($pos.parent.content.cutByIndex($pos.index(), $pos.parent.childCount)))\n return false\n for (let d = $pos.depth - 1, i = depth - 2; d > base; d--, i--) {\n let node = $pos.node(d), index = $pos.index(d)\n if (node.type.spec.isolating) return false\n let rest = node.content.cutByIndex(index, node.childCount)\n let after = (typesAfter && typesAfter[i]) || node\n if (after != node) rest = rest.replaceChild(0, after.type.create(after.attrs))\n if (!node.canReplace(index + 1, node.childCount) || !after.type.validContent(rest))\n return false\n }\n let index = $pos.indexAfter(base)\n let baseType = typesAfter && typesAfter[0]\n return $pos.node(base).canReplaceWith(index, index, baseType ? baseType.type : $pos.node(base + 1).type)\n}\n\n// :: (number, ?number, ?[?{type: NodeType, attrs: ?Object}]) → this\n// Split the node at the given position, and optionally, if `depth` is\n// greater than one, any number of nodes above that. By default, the\n// parts split off will inherit the node type of the original node.\n// This can be changed by passing an array of types and attributes to\n// use after the split.\nTransform.prototype.split = function(pos, depth = 1, typesAfter) {\n let $pos = this.doc.resolve(pos), before = Fragment.empty, after = Fragment.empty\n for (let d = $pos.depth, e = $pos.depth - depth, i = depth - 1; d > e; d--, i--) {\n before = Fragment.from($pos.node(d).copy(before))\n let typeAfter = typesAfter && typesAfter[i]\n after = Fragment.from(typeAfter ? typeAfter.type.create(typeAfter.attrs, after) : $pos.node(d).copy(after))\n }\n return this.step(new ReplaceStep(pos, pos, new Slice(before.append(after), depth, depth), true))\n}\n\n// :: (Node, number) → bool\n// Test whether the blocks before and after a given position can be\n// joined.\nexport function canJoin(doc, pos) {\n let $pos = doc.resolve(pos), index = $pos.index()\n return joinable($pos.nodeBefore, $pos.nodeAfter) &&\n $pos.parent.canReplace(index, index + 1)\n}\n\nfunction joinable(a, b) {\n return a && b && !a.isLeaf && a.canAppend(b)\n}\n\n// :: (Node, number, ?number) → ?number\n// Find an ancestor of the given position that can be joined to the\n// block before (or after if `dir` is positive). Returns the joinable\n// point, if any.\nexport function joinPoint(doc, pos, dir = -1) {\n let $pos = doc.resolve(pos)\n for (let d = $pos.depth;; d--) {\n let before, after\n if (d == $pos.depth) {\n before = $pos.nodeBefore\n after = $pos.nodeAfter\n } else if (dir > 0) {\n before = $pos.node(d + 1)\n after = $pos.node(d).maybeChild($pos.index(d) + 1)\n } else {\n before = $pos.node(d).maybeChild($pos.index(d) - 1)\n after = $pos.node(d + 1)\n }\n if (before && !before.isTextblock && joinable(before, after)) return pos\n if (d == 0) break\n pos = dir < 0 ? $pos.before(d) : $pos.after(d)\n }\n}\n\n// :: (number, ?number) → this\n// Join the blocks around the given position. If depth is 2, their\n// last and first siblings are also joined, and so on.\nTransform.prototype.join = function(pos, depth = 1) {\n let step = new ReplaceStep(pos - depth, pos + depth, Slice.empty, true)\n return this.step(step)\n}\n\n// :: (Node, number, NodeType) → ?number\n// Try to find a point where a node of the given type can be inserted\n// near `pos`, by searching up the node hierarchy when `pos` itself\n// isn't a valid place but is at the start or end of a node. Return\n// null if no position was found.\nexport function insertPoint(doc, pos, nodeType) {\n let $pos = doc.resolve(pos)\n if ($pos.parent.canReplaceWith($pos.index(), $pos.index(), nodeType)) return pos\n\n if ($pos.parentOffset == 0)\n for (let d = $pos.depth - 1; d >= 0; d--) {\n let index = $pos.index(d)\n if ($pos.node(d).canReplaceWith(index, index, nodeType)) return $pos.before(d + 1)\n if (index > 0) return null\n }\n if ($pos.parentOffset == $pos.parent.content.size)\n for (let d = $pos.depth - 1; d >= 0; d--) {\n let index = $pos.indexAfter(d)\n if ($pos.node(d).canReplaceWith(index, index, nodeType)) return $pos.after(d + 1)\n if (index < $pos.node(d).childCount) return null\n }\n}\n\n// :: (Node, number, Slice) → ?number\n// Finds a position at or around the given position where the given\n// slice can be inserted. Will look at parent nodes' nearest boundary\n// and try there, even if the original position wasn't directly at the\n// start or end of that node. Returns null when no position was found.\nexport function dropPoint(doc, pos, slice) {\n let $pos = doc.resolve(pos)\n if (!slice.content.size) return pos\n let content = slice.content\n for (let i = 0; i < slice.openStart; i++) content = content.firstChild.content\n for (let pass = 1; pass <= (slice.openStart == 0 && slice.size ? 2 : 1); pass++) {\n for (let d = $pos.depth; d >= 0; d--) {\n let bias = d == $pos.depth ? 0 : $pos.pos <= ($pos.start(d + 1) + $pos.end(d + 1)) / 2 ? -1 : 1\n let insertPos = $pos.index(d) + (bias > 0 ? 1 : 0)\n if (pass == 1\n ? $pos.node(d).canReplace(insertPos, insertPos, content)\n : $pos.node(d).contentMatchAt(insertPos).findWrapping(content.firstChild.type))\n return bias == 0 ? $pos.pos : bias < 0 ? $pos.before(d + 1) : $pos.after(d + 1)\n }\n }\n return null\n}\n","import {Fragment, Slice} from \"prosemirror-model\"\nimport {Step, StepResult} from \"./step\"\n\nfunction mapFragment(fragment, f, parent) {\n let mapped = []\n for (let i = 0; i < fragment.childCount; i++) {\n let child = fragment.child(i)\n if (child.content.size) child = child.copy(mapFragment(child.content, f, child))\n if (child.isInline) child = f(child, parent, i)\n mapped.push(child)\n }\n return Fragment.fromArray(mapped)\n}\n\n// ::- Add a mark to all inline content between two positions.\nexport class AddMarkStep extends Step {\n // :: (number, number, Mark)\n constructor(from, to, mark) {\n super()\n this.from = from\n this.to = to\n this.mark = mark\n }\n\n apply(doc) {\n let oldSlice = doc.slice(this.from, this.to), $from = doc.resolve(this.from)\n let parent = $from.node($from.sharedDepth(this.to))\n let slice = new Slice(mapFragment(oldSlice.content, (node, parent) => {\n if (!parent.type.allowsMarkType(this.mark.type)) return node\n return node.mark(this.mark.addToSet(node.marks))\n }, parent), oldSlice.openStart, oldSlice.openEnd)\n return StepResult.fromReplace(doc, this.from, this.to, slice)\n }\n\n invert() {\n return new RemoveMarkStep(this.from, this.to, this.mark)\n }\n\n map(mapping) {\n let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1)\n if (from.deleted && to.deleted || from.pos >= to.pos) return null\n return new AddMarkStep(from.pos, to.pos, this.mark)\n }\n\n merge(other) {\n if (other instanceof AddMarkStep &&\n other.mark.eq(this.mark) &&\n this.from <= other.to && this.to >= other.from)\n return new AddMarkStep(Math.min(this.from, other.from),\n Math.max(this.to, other.to), this.mark)\n }\n\n toJSON() {\n return {stepType: \"addMark\", mark: this.mark.toJSON(),\n from: this.from, to: this.to}\n }\n\n static fromJSON(schema, json) {\n if (typeof json.from != \"number\" || typeof json.to != \"number\")\n throw new RangeError(\"Invalid input for AddMarkStep.fromJSON\")\n return new AddMarkStep(json.from, json.to, schema.markFromJSON(json.mark))\n }\n}\n\nStep.jsonID(\"addMark\", AddMarkStep)\n\n// ::- Remove a mark from all inline content between two positions.\nexport class RemoveMarkStep extends Step {\n // :: (number, number, Mark)\n constructor(from, to, mark) {\n super()\n this.from = from\n this.to = to\n this.mark = mark\n }\n\n apply(doc) {\n let oldSlice = doc.slice(this.from, this.to)\n let slice = new Slice(mapFragment(oldSlice.content, node => {\n return node.mark(this.mark.removeFromSet(node.marks))\n }), oldSlice.openStart, oldSlice.openEnd)\n return StepResult.fromReplace(doc, this.from, this.to, slice)\n }\n\n invert() {\n return new AddMarkStep(this.from, this.to, this.mark)\n }\n\n map(mapping) {\n let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1)\n if (from.deleted && to.deleted || from.pos >= to.pos) return null\n return new RemoveMarkStep(from.pos, to.pos, this.mark)\n }\n\n merge(other) {\n if (other instanceof RemoveMarkStep &&\n other.mark.eq(this.mark) &&\n this.from <= other.to && this.to >= other.from)\n return new RemoveMarkStep(Math.min(this.from, other.from),\n Math.max(this.to, other.to), this.mark)\n }\n\n toJSON() {\n return {stepType: \"removeMark\", mark: this.mark.toJSON(),\n from: this.from, to: this.to}\n }\n\n static fromJSON(schema, json) {\n if (typeof json.from != \"number\" || typeof json.to != \"number\")\n throw new RangeError(\"Invalid input for RemoveMarkStep.fromJSON\")\n return new RemoveMarkStep(json.from, json.to, schema.markFromJSON(json.mark))\n }\n}\n\nStep.jsonID(\"removeMark\", RemoveMarkStep)\n","import {MarkType, Slice, Fragment} from \"prosemirror-model\"\n\nimport {Transform} from \"./transform\"\nimport {AddMarkStep, RemoveMarkStep} from \"./mark_step\"\nimport {ReplaceStep} from \"./replace_step\"\n\n// :: (number, number, Mark) → this\n// Add the given mark to the inline content between `from` and `to`.\nTransform.prototype.addMark = function(from, to, mark) {\n let removed = [], added = [], removing = null, adding = null\n this.doc.nodesBetween(from, to, (node, pos, parent) => {\n if (!node.isInline) return\n let marks = node.marks\n if (!mark.isInSet(marks) && parent.type.allowsMarkType(mark.type)) {\n let start = Math.max(pos, from), end = Math.min(pos + node.nodeSize, to)\n let newSet = mark.addToSet(marks)\n\n for (let i = 0; i < marks.length; i++) {\n if (!marks[i].isInSet(newSet)) {\n if (removing && removing.to == start && removing.mark.eq(marks[i]))\n removing.to = end\n else\n removed.push(removing = new RemoveMarkStep(start, end, marks[i]))\n }\n }\n\n if (adding && adding.to == start)\n adding.to = end\n else\n added.push(adding = new AddMarkStep(start, end, mark))\n }\n })\n\n removed.forEach(s => this.step(s))\n added.forEach(s => this.step(s))\n return this\n}\n\n// :: (number, number, ?union) → this\n// Remove marks from inline nodes between `from` and `to`. When `mark`\n// is a single mark, remove precisely that mark. When it is a mark type,\n// remove all marks of that type. When it is null, remove all marks of\n// any type.\nTransform.prototype.removeMark = function(from, to, mark = null) {\n let matched = [], step = 0\n this.doc.nodesBetween(from, to, (node, pos) => {\n if (!node.isInline) return\n step++\n let toRemove = null\n if (mark instanceof MarkType) {\n let found = mark.isInSet(node.marks)\n if (found) toRemove = [found]\n } else if (mark) {\n if (mark.isInSet(node.marks)) toRemove = [mark]\n } else {\n toRemove = node.marks\n }\n if (toRemove && toRemove.length) {\n let end = Math.min(pos + node.nodeSize, to)\n for (let i = 0; i < toRemove.length; i++) {\n let style = toRemove[i], found\n for (let j = 0; j < matched.length; j++) {\n let m = matched[j]\n if (m.step == step - 1 && style.eq(matched[j].style)) found = m\n }\n if (found) {\n found.to = end\n found.step = step\n } else {\n matched.push({style, from: Math.max(pos, from), to: end, step})\n }\n }\n }\n })\n matched.forEach(m => this.step(new RemoveMarkStep(m.from, m.to, m.style)))\n return this\n}\n\n// :: (number, NodeType, ?ContentMatch) → this\n// Removes all marks and nodes from the content of the node at `pos`\n// that don't match the given new parent node type. Accepts an\n// optional starting [content match](#model.ContentMatch) as third\n// argument.\nTransform.prototype.clearIncompatible = function(pos, parentType, match = parentType.contentMatch) {\n let node = this.doc.nodeAt(pos)\n let delSteps = [], cur = pos + 1\n for (let i = 0; i < node.childCount; i++) {\n let child = node.child(i), end = cur + child.nodeSize\n let allowed = match.matchType(child.type, child.attrs)\n if (!allowed) {\n delSteps.push(new ReplaceStep(cur, end, Slice.empty))\n } else {\n match = allowed\n for (let j = 0; j < child.marks.length; j++) if (!parentType.allowsMarkType(child.marks[j].type))\n this.step(new RemoveMarkStep(cur, end, child.marks[j]))\n }\n cur = end\n }\n if (!match.validEnd) {\n let fill = match.fillBefore(Fragment.empty, true)\n this.replace(cur, cur, new Slice(fill, 0, 0))\n }\n for (let i = delSteps.length - 1; i >= 0; i--) this.step(delSteps[i])\n return this\n}\n","import {Fragment, Slice} from \"prosemirror-model\"\n\nimport {ReplaceStep, ReplaceAroundStep} from \"./replace_step\"\nimport {Transform} from \"./transform\"\nimport {insertPoint} from \"./structure\"\n\n// :: (Node, number, ?number, ?Slice) → ?Step\n// ‘Fit’ a slice into a given position in the document, producing a\n// [step](#transform.Step) that inserts it. Will return null if\n// there's no meaningful way to insert the slice here, or inserting it\n// would be a no-op (an empty slice over an empty range).\nexport function replaceStep(doc, from, to = from, slice = Slice.empty) {\n if (from == to && !slice.size) return null\n\n let $from = doc.resolve(from), $to = doc.resolve(to)\n // Optimization -- avoid work if it's obvious that it's not needed.\n if (fitsTrivially($from, $to, slice)) return new ReplaceStep(from, to, slice)\n let placed = placeSlice($from, slice)\n\n let fittedLeft = fitLeft($from, placed)\n let fitted = fitRight($from, $to, fittedLeft)\n if (!fitted) return null\n if (fittedLeft.size != fitted.size && canMoveText($from, $to, fittedLeft)) {\n let d = $to.depth, after = $to.after(d)\n while (d > 1 && after == $to.end(--d)) ++after\n let fittedAfter = fitRight($from, doc.resolve(after), fittedLeft)\n if (fittedAfter)\n return new ReplaceAroundStep(from, after, to, $to.end(), fittedAfter, fittedLeft.size)\n }\n return fitted.size || from != to ? new ReplaceStep(from, to, fitted) : null\n}\n\n// :: (number, ?number, ?Slice) → this\n// Replace the part of the document between `from` and `to` with the\n// given `slice`.\nTransform.prototype.replace = function(from, to = from, slice = Slice.empty) {\n let step = replaceStep(this.doc, from, to, slice)\n if (step) this.step(step)\n return this\n}\n\n// :: (number, number, union) → this\n// Replace the given range with the given content, which may be a\n// fragment, node, or array of nodes.\nTransform.prototype.replaceWith = function(from, to, content) {\n return this.replace(from, to, new Slice(Fragment.from(content), 0, 0))\n}\n\n// :: (number, number) → this\n// Delete the content between the given positions.\nTransform.prototype.delete = function(from, to) {\n return this.replace(from, to, Slice.empty)\n}\n\n// :: (number, union) → this\n// Insert the given content at the given position.\nTransform.prototype.insert = function(pos, content) {\n return this.replaceWith(pos, pos, content)\n}\n\n\n\nfunction fitLeftInner($from, depth, placed, placedBelow) {\n let content = Fragment.empty, openEnd = 0, placedHere = placed[depth]\n if ($from.depth > depth) {\n let inner = fitLeftInner($from, depth + 1, placed, placedBelow || placedHere)\n openEnd = inner.openEnd + 1\n content = Fragment.from($from.node(depth + 1).copy(inner.content))\n }\n\n if (placedHere) {\n content = content.append(placedHere.content)\n openEnd = placedHere.openEnd\n }\n if (placedBelow) {\n content = content.append($from.node(depth).contentMatchAt($from.indexAfter(depth)).fillBefore(Fragment.empty, true))\n openEnd = 0\n }\n\n return {content, openEnd}\n}\n\nfunction fitLeft($from, placed) {\n let {content, openEnd} = fitLeftInner($from, 0, placed, false)\n return new Slice(content, $from.depth, openEnd || 0)\n}\n\nfunction fitRightJoin(content, parent, $from, $to, depth, openStart, openEnd) {\n let match, count = content.childCount, matchCount = count - (openEnd > 0 ? 1 : 0)\n let parentNode = openStart < 0 ? parent : $from.node(depth)\n if (openStart < 0)\n match = parentNode.contentMatchAt(matchCount)\n else if (count == 1 && openEnd > 0)\n match = parentNode.contentMatchAt(openStart ? $from.index(depth) : $from.indexAfter(depth))\n else\n match = parentNode.contentMatchAt($from.indexAfter(depth))\n .matchFragment(content, count > 0 && openStart ? 1 : 0, matchCount)\n\n let toNode = $to.node(depth)\n if (openEnd > 0 && depth < $to.depth) {\n let after = toNode.content.cutByIndex($to.indexAfter(depth)).addToStart(content.lastChild)\n let joinable = match.fillBefore(after, true)\n // Can't insert content if there's a single node stretched across this gap\n if (joinable && joinable.size && openStart > 0 && count == 1) joinable = null\n\n if (joinable) {\n let inner = fitRightJoin(content.lastChild.content, content.lastChild, $from, $to,\n depth + 1, count == 1 ? openStart - 1 : -1, openEnd - 1)\n if (inner) {\n let last = content.lastChild.copy(inner)\n if (joinable.size)\n return content.cutByIndex(0, count - 1).append(joinable).addToEnd(last)\n else\n return content.replaceChild(count - 1, last)\n }\n }\n }\n if (openEnd > 0)\n match = match.matchType((count == 1 && openStart > 0 ? $from.node(depth + 1) : content.lastChild).type)\n\n // If we're here, the next level can't be joined, so we see what\n // happens if we leave it open.\n let toIndex = $to.index(depth)\n if (toIndex == toNode.childCount && !toNode.type.compatibleContent(parent.type)) return null\n let joinable = match.fillBefore(toNode.content, true, toIndex)\n for (let i = toIndex; joinable && i < toNode.content.childCount; i++)\n if (!parentNode.type.allowsMarks(toNode.content.child(i).marks)) joinable = null\n if (!joinable) return null\n\n if (openEnd > 0) {\n let closed = fitRightClosed(content.lastChild, openEnd - 1, $from, depth + 1,\n count == 1 ? openStart - 1 : -1)\n content = content.replaceChild(count - 1, closed)\n }\n content = content.append(joinable)\n if ($to.depth > depth)\n content = content.addToEnd(fitRightSeparate($to, depth + 1))\n return content\n}\n\nfunction fitRightClosed(node, openEnd, $from, depth, openStart) {\n let match, content = node.content, count = content.childCount\n if (openStart >= 0)\n match = $from.node(depth).contentMatchAt($from.indexAfter(depth))\n .matchFragment(content, openStart > 0 ? 1 : 0, count)\n else\n match = node.contentMatchAt(count)\n\n if (openEnd > 0) {\n let closed = fitRightClosed(content.lastChild, openEnd - 1, $from, depth + 1,\n count == 1 ? openStart - 1 : -1)\n content = content.replaceChild(count - 1, closed)\n }\n\n return node.copy(content.append(match.fillBefore(Fragment.empty, true)))\n}\n\nfunction fitRightSeparate($to, depth) {\n let node = $to.node(depth)\n let fill = node.contentMatchAt(0).fillBefore(node.content, true, $to.index(depth))\n if ($to.depth > depth) fill = fill.addToEnd(fitRightSeparate($to, depth + 1))\n return node.copy(fill)\n}\n\nfunction normalizeSlice(content, openStart, openEnd) {\n while (openStart > 0 && openEnd > 0 && content.childCount == 1) {\n content = content.firstChild.content\n openStart--\n openEnd--\n }\n return new Slice(content, openStart, openEnd)\n}\n\n// : (ResolvedPos, ResolvedPos, number, Slice) → Slice\nfunction fitRight($from, $to, slice) {\n let fitted = fitRightJoin(slice.content, $from.node(0), $from, $to, 0, slice.openStart, slice.openEnd)\n if (!fitted) return null\n return normalizeSlice(fitted, slice.openStart, $to.depth)\n}\n\nfunction fitsTrivially($from, $to, slice) {\n return !slice.openStart && !slice.openEnd && $from.start() == $to.start() &&\n $from.parent.canReplace($from.index(), $to.index(), slice.content)\n}\n\nfunction canMoveText($from, $to, slice) {\n if (!$to.parent.isTextblock) return false\n\n let parent = slice.openEnd ? nodeRight(slice.content, slice.openEnd)\n : $from.node($from.depth - (slice.openStart - slice.openEnd))\n if (!parent.isTextblock) return false\n for (let i = $to.index(); i < $to.parent.childCount; i++)\n if (!parent.type.allowsMarks($to.parent.child(i).marks)) return false\n let match\n if (slice.openEnd) {\n match = parent.contentMatchAt(parent.childCount)\n } else {\n match = parent.contentMatchAt(parent.childCount)\n if (slice.size) match = match.matchFragment(slice.content, slice.openStart ? 1 : 0)\n }\n match = match.matchFragment($to.parent.content, $to.index())\n return match && match.validEnd\n}\n\nfunction nodeRight(content, depth) {\n for (let i = 1; i < depth; i++) content = content.lastChild.content\n return content.lastChild\n}\n\n// Algorithm for 'placing' the elements of a slice into a gap:\n//\n// We consider the content of each node that is open to the left to be\n// independently placeable. I.e. in , when the\n// paragraph on the left is open, \"foo\" can be placed (somewhere on\n// the left side of the replacement gap) independently from p(\"bar\").\n//\n// So placeSlice splits up a slice into a number of sub-slices,\n// along with information on where they can be placed on the given\n// left-side edge. It works by walking the open side of the slice,\n// from the inside out, and trying to find a landing spot for each\n// element, by simultaneously scanning over the gap side. When no\n// place is found for an open node's content, it is left in that node.\n\n// : (ResolvedPos, Slice) → [{content: Fragment, openEnd: number, depth: number}]\nfunction placeSlice($from, slice) {\n let frontier = new Frontier($from)\n for (let pass = 1; slice.size && pass <= 3; pass++) {\n let value = frontier.placeSlice(slice.content, slice.openStart, slice.openEnd, pass)\n if (pass == 3 && value != slice && value.size) pass = 0 // Restart if the 3rd pass made progress but left content\n slice = value\n }\n while (frontier.open.length) frontier.closeNode()\n return frontier.placed\n}\n\n// Helper class that models the open side of the insert position,\n// keeping track of the content match and already inserted content\n// at each depth.\nclass Frontier {\n constructor($pos) {\n // : [{parent: Node, match: ContentMatch, content: Fragment, wrapper: bool, openEnd: number, depth: number}]\n this.open = []\n for (let d = 0; d <= $pos.depth; d++) {\n let parent = $pos.node(d), match = parent.contentMatchAt($pos.indexAfter(d))\n this.open.push({parent, match, content: Fragment.empty, wrapper: false, openEnd: 0, depth: d})\n }\n this.placed = []\n }\n\n // : (Fragment, number, number, number, ?Node) → Slice\n // Tries to place the content of the given slice, and returns a\n // slice containing unplaced content.\n //\n // pass 1: try to fit directly\n // pass 2: allow wrapper nodes to be introduced\n // pass 3: allow unwrapping of nodes that aren't open\n placeSlice(fragment, openStart, openEnd, pass, parent) {\n if (openStart > 0) {\n let first = fragment.firstChild\n let inner = this.placeSlice(first.content, Math.max(0, openStart - 1),\n openEnd && fragment.childCount == 1 ? openEnd - 1 : 0,\n pass, first)\n if (inner.content != first.content) {\n if (inner.content.size) {\n fragment = fragment.replaceChild(0, first.copy(inner.content))\n openStart = inner.openStart + 1\n } else {\n if (fragment.childCount == 1) openEnd = 0\n fragment = fragment.cutByIndex(1)\n openStart = 0\n }\n }\n }\n let result = this.placeContent(fragment, openStart, openEnd, pass, parent)\n if (pass > 2 && result.size && openStart == 0) {\n let child = result.content.firstChild, single = result.content.childCount == 1\n this.placeContent(child.content, 0, openEnd && single ? openEnd - 1 : 0, pass, child)\n result = single ? Fragment.empty : new Slice(result.content.cutByIndex(1), 0, openEnd)\n }\n return result\n }\n\n placeContent(fragment, openStart, openEnd, pass, parent) {\n let i = 0\n // Go over the fragment's children\n for (; i < fragment.childCount; i++) {\n let child = fragment.child(i), placed = false, last = i == fragment.childCount - 1\n // Try each open node in turn, starting from the innermost\n for (let d = this.open.length - 1; d >= 0; d--) {\n let open = this.open[d], wrap\n\n // If pass > 1, it is allowed to wrap the node to help find a\n // fit, so if findWrapping returns something, we add open\n // nodes to the frontier for that wrapping.\n if (pass > 1 && (wrap = open.match.findWrapping(child.type)) &&\n !(parent && wrap.length && wrap[wrap.length - 1] == parent.type)) {\n while (this.open.length - 1 > d) this.closeNode()\n for (let w = 0; w < wrap.length; w++) {\n open.match = open.match.matchType(wrap[w])\n d++\n open = {parent: wrap[w].create(),\n match: wrap[w].contentMatch,\n content: Fragment.empty, wrapper: true, openEnd: 0, depth: d + w}\n this.open.push(open)\n }\n }\n\n // See if the child fits here\n let match = open.match.matchType(child.type)\n if (!match) {\n let fill = open.match.fillBefore(Fragment.from(child))\n if (fill) {\n for (let j = 0; j < fill.childCount; j++) {\n let ch = fill.child(j)\n this.addNode(open, ch, 0)\n match = open.match.matchFragment(ch)\n }\n } else if (parent && open.match.matchType(parent.type)) {\n // Don't continue looking further up if the parent node\n // would fit here.\n break\n } else {\n continue\n }\n }\n\n // Close open nodes above this one, since we're starting to\n // add to this.\n while (this.open.length - 1 > d) this.closeNode()\n // Strip marks from the child or close its start when necessary\n child = child.mark(open.parent.type.allowedMarks(child.marks))\n if (openStart) {\n child = closeNodeStart(child, openStart, last ? openEnd : 0)\n openStart = 0\n }\n // Add the child to this open node and adjust its metadata\n this.addNode(open, child, last ? openEnd : 0)\n open.match = match\n if (last) openEnd = 0\n placed = true\n break\n }\n // As soon as we've failed to place a node we stop looking at\n // later nodes\n if (!placed) break\n }\n // Close the current open node if it's not the the root and we\n // either placed up to the end of the node or the the current\n // slice depth's node type matches the open node's type\n if (this.open.length > 1 &&\n (i > 0 && i == fragment.childCount ||\n parent && this.open[this.open.length - 1].parent.type == parent.type))\n this.closeNode()\n\n return new Slice(fragment.cutByIndex(i), openStart, openEnd)\n }\n\n addNode(open, node, openEnd) {\n open.content = closeFragmentEnd(open.content, open.openEnd).addToEnd(node)\n open.openEnd = openEnd\n }\n\n closeNode() {\n let open = this.open.pop()\n if (open.content.size == 0) {\n // Nothing here\n } else if (open.wrapper) {\n this.addNode(this.open[this.open.length - 1], open.parent.copy(open.content), open.openEnd + 1)\n } else {\n this.placed[open.depth] = {depth: open.depth, content: open.content, openEnd: open.openEnd}\n }\n }\n}\n\nfunction closeNodeStart(node, openStart, openEnd) {\n let content = node.content\n if (openStart > 1) {\n let first = closeNodeStart(node.firstChild, openStart - 1, node.childCount == 1 ? openEnd - 1 : 0)\n content = node.content.replaceChild(0, first)\n }\n let fill = node.type.contentMatch.fillBefore(content, openEnd == 0)\n return node.copy(fill.append(content))\n}\n\nfunction closeNodeEnd(node, depth) {\n let content = node.content\n if (depth > 1) {\n let last = closeNodeEnd(node.lastChild, depth - 1)\n content = node.content.replaceChild(node.childCount - 1, last)\n }\n let fill = node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true)\n return node.copy(content.append(fill))\n}\n\nfunction closeFragmentEnd(fragment, depth) {\n return depth ? fragment.replaceChild(fragment.childCount - 1, closeNodeEnd(fragment.lastChild, depth)) : fragment\n}\n\n// :: (number, number, Slice) → this\n// Replace a range of the document with a given slice, using `from`,\n// `to`, and the slice's [`openStart`](#model.Slice.openStart) property\n// as hints, rather than fixed start and end points. This method may\n// grow the replaced area or close open nodes in the slice in order to\n// get a fit that is more in line with WYSIWYG expectations, by\n// dropping fully covered parent nodes of the replaced region when\n// they are marked [non-defining](#model.NodeSpec.defining), or\n// including an open parent node from the slice that _is_ marked as\n// [defining](#model.NodeSpec.defining).\n//\n// This is the method, for example, to handle paste. The similar\n// [`replace`](#transform.Transform.replace) method is a more\n// primitive tool which will _not_ move the start and end of its given\n// range, and is useful in situations where you need more precise\n// control over what happens.\nTransform.prototype.replaceRange = function(from, to, slice) {\n if (!slice.size) return this.deleteRange(from, to)\n\n let $from = this.doc.resolve(from), $to = this.doc.resolve(to)\n if (fitsTrivially($from, $to, slice))\n return this.step(new ReplaceStep(from, to, slice))\n\n let targetDepths = coveredDepths($from, this.doc.resolve(to))\n // Can't replace the whole document, so remove 0 if it's present\n if (targetDepths[targetDepths.length - 1] == 0) targetDepths.pop()\n // Negative numbers represent not expansion over the whole node at\n // that depth, but replacing from $from.before(-D) to $to.pos.\n let preferredTarget = -($from.depth + 1)\n targetDepths.unshift(preferredTarget)\n // This loop picks a preferred target depth, if one of the covering\n // depths is not outside of a defining node, and adds negative\n // depths for any depth that has $from at its start and does not\n // cross a defining node.\n for (let d = $from.depth, pos = $from.pos - 1; d > 0; d--, pos--) {\n let spec = $from.node(d).type.spec\n if (spec.defining || spec.isolating) break\n if (targetDepths.indexOf(d) > -1) preferredTarget = d\n else if ($from.before(d) == pos) targetDepths.splice(1, 0, -d)\n }\n // Try to fit each possible depth of the slice into each possible\n // target depth, starting with the preferred depths.\n let preferredTargetIndex = targetDepths.indexOf(preferredTarget)\n\n let leftNodes = [], preferredDepth = slice.openStart\n for (let content = slice.content, i = 0;; i++) {\n let node = content.firstChild\n leftNodes.push(node)\n if (i == slice.openStart) break\n content = node.content\n }\n // Back up if the node directly above openStart, or the node above\n // that separated only by a non-defining textblock node, is defining.\n if (preferredDepth > 0 && leftNodes[preferredDepth - 1].type.spec.defining &&\n $from.node(preferredTargetIndex).type != leftNodes[preferredDepth - 1].type)\n preferredDepth -= 1\n else if (preferredDepth >= 2 && leftNodes[preferredDepth - 1].isTextblock && leftNodes[preferredDepth - 2].type.spec.defining &&\n $from.node(preferredTargetIndex).type != leftNodes[preferredDepth - 2].type)\n preferredDepth -= 2\n\n for (let j = slice.openStart; j >= 0; j--) {\n let openDepth = (j + preferredDepth + 1) % (slice.openStart + 1)\n let insert = leftNodes[openDepth]\n if (!insert) continue\n for (let i = 0; i < targetDepths.length; i++) {\n // Loop over possible expansion levels, starting with the\n // preferred one\n let targetDepth = targetDepths[(i + preferredTargetIndex) % targetDepths.length], expand = true\n if (targetDepth < 0) { expand = false; targetDepth = -targetDepth }\n let parent = $from.node(targetDepth - 1), index = $from.index(targetDepth - 1)\n if (parent.canReplaceWith(index, index, insert.type, insert.marks))\n return this.replace($from.before(targetDepth), expand ? $to.after(targetDepth) : to,\n new Slice(closeFragment(slice.content, 0, slice.openStart, openDepth),\n openDepth, slice.openEnd))\n }\n }\n\n let startSteps = this.steps.length\n for (let i = targetDepths.length - 1; i >= 0; i--) {\n this.replace(from, to, slice)\n if (this.steps.length > startSteps) break\n let depth = targetDepths[i]\n if (i < 0) continue\n from = $from.before(depth); to = $to.after(depth)\n }\n return this\n}\n\nfunction closeFragment(fragment, depth, oldOpen, newOpen, parent) {\n if (depth < oldOpen) {\n let first = fragment.firstChild\n fragment = fragment.replaceChild(0, first.copy(closeFragment(first.content, depth + 1, oldOpen, newOpen, first)))\n }\n if (depth > newOpen) {\n let match = parent.contentMatchAt(0)\n let start = match.fillBefore(fragment).append(fragment)\n fragment = start.append(match.matchFragment(start).fillBefore(Fragment.empty, true))\n }\n return fragment\n}\n\n// :: (number, number, Node) → this\n// Replace the given range with a node, but use `from` and `to` as\n// hints, rather than precise positions. When from and to are the same\n// and are at the start or end of a parent node in which the given\n// node doesn't fit, this method may _move_ them out towards a parent\n// that does allow the given node to be placed. When the given range\n// completely covers a parent node, this method may completely replace\n// that parent node.\nTransform.prototype.replaceRangeWith = function(from, to, node) {\n if (!node.isInline && from == to && this.doc.resolve(from).parent.content.size) {\n let point = insertPoint(this.doc, from, node.type)\n if (point != null) from = to = point\n }\n return this.replaceRange(from, to, new Slice(Fragment.from(node), 0, 0))\n}\n\n// :: (number, number) → this\n// Delete the given range, expanding it to cover fully covered\n// parent nodes until a valid replace is found.\nTransform.prototype.deleteRange = function(from, to) {\n let $from = this.doc.resolve(from), $to = this.doc.resolve(to)\n let covered = coveredDepths($from, $to)\n for (let i = 0; i < covered.length; i++) {\n let depth = covered[i], last = i == covered.length - 1\n if ((last && depth == 0) || $from.node(depth).type.contentMatch.validEnd)\n return this.delete($from.start(depth), $to.end(depth))\n if (depth > 0 && (last || $from.node(depth - 1).canReplace($from.index(depth - 1), $to.indexAfter(depth - 1))))\n return this.delete($from.before(depth), $to.after(depth))\n }\n for (let d = 1; d <= $from.depth && d <= $to.depth; d++) {\n if (from - $from.start(d) == $from.depth - d && to > $from.end(d) && $to.end(d) - to != $to.depth - d)\n return this.delete($from.before(d), to)\n }\n return this.delete(from, to)\n}\n\n// : (ResolvedPos, ResolvedPos) → [number]\n// Returns an array of all depths for which $from - $to spans the\n// whole content of the nodes at that depth.\nfunction coveredDepths($from, $to) {\n let result = [], minDepth = Math.min($from.depth, $to.depth)\n for (let d = minDepth; d >= 0; d--) {\n let start = $from.start(d)\n if (start < $from.pos - ($from.depth - d) ||\n $to.end(d) > $to.pos + ($to.depth - d) ||\n $from.node(d).type.spec.isolating ||\n $to.node(d).type.spec.isolating) break\n if (start == $to.start(d)) result.push(d)\n }\n return result\n}\n"],"names":["const","let","super","slice","d","splitting","this","index","found","i","joinable"],"mappings":"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"} \ No newline at end of file diff --git a/packages/tiptap-extensions/node_modules/prosemirror-transform/dist/index.js b/packages/tiptap-extensions/node_modules/prosemirror-transform/dist/index.js new file mode 100644 index 0000000000..c71616e456 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-transform/dist/index.js @@ -0,0 +1,1711 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +var prosemirrorModel = require('prosemirror-model'); + +// Mappable:: interface +// There are several things that positions can be mapped through. +// Such objects conform to this interface. +// +// map:: (pos: number, assoc: ?number) → number +// Map a position through this object. When given, `assoc` (should +// be -1 or 1, defaults to 1) determines with which side the +// position is associated, which determines in which direction to +// move when a chunk of content is inserted at the mapped position. +// +// mapResult:: (pos: number, assoc: ?number) → MapResult +// Map a position, and return an object containing additional +// information about the mapping. The result's `deleted` field tells +// you whether the position was deleted (completely enclosed in a +// replaced range) during the mapping. When content on only one side +// is deleted, the position itself is only considered deleted when +// `assoc` points in the direction of the deleted content. + +// Recovery values encode a range index and an offset. They are +// represented as numbers, because tons of them will be created when +// mapping, for example, a large number of decorations. The number's +// lower 16 bits provide the index, the remaining bits the offset. +// +// Note: We intentionally don't use bit shift operators to en- and +// decode these, since those clip to 32 bits, which we might in rare +// cases want to overflow. A 64-bit float can represent 48-bit +// integers precisely. + +var lower16 = 0xffff; +var factor16 = Math.pow(2, 16); + +function makeRecover(index, offset) { return index + offset * factor16 } +function recoverIndex(value) { return value & lower16 } +function recoverOffset(value) { return (value - (value & lower16)) / factor16 } + +// ::- An object representing a mapped position with extra +// information. +var MapResult = function MapResult(pos, deleted, recover) { + if ( deleted === void 0 ) deleted = false; + if ( recover === void 0 ) recover = null; + + // :: number The mapped version of the position. + this.pos = pos; + // :: bool Tells you whether the position was deleted, that is, + // whether the step removed its surroundings from the document. + this.deleted = deleted; + this.recover = recover; +}; + +// :: class extends Mappable +// A map describing the deletions and insertions made by a step, which +// can be used to find the correspondence between positions in the +// pre-step version of a document and the same position in the +// post-step version. +var StepMap = function StepMap(ranges, inverted) { + if ( inverted === void 0 ) inverted = false; + + this.ranges = ranges; + this.inverted = inverted; +}; + +StepMap.prototype.recover = function recover (value) { + var diff = 0, index = recoverIndex(value); + if (!this.inverted) { for (var i = 0; i < index; i++) + { diff += this.ranges[i * 3 + 2] - this.ranges[i * 3 + 1]; } } + return this.ranges[index * 3] + diff + recoverOffset(value) +}; + +// : (number, ?number) → MapResult +StepMap.prototype.mapResult = function mapResult (pos, assoc) { + if ( assoc === void 0 ) assoc = 1; + return this._map(pos, assoc, false) }; + +// : (number, ?number) → number +StepMap.prototype.map = function map (pos, assoc) { + if ( assoc === void 0 ) assoc = 1; + return this._map(pos, assoc, true) }; + +StepMap.prototype._map = function _map (pos, assoc, simple) { + var diff = 0, oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; + for (var i = 0; i < this.ranges.length; i += 3) { + var start = this.ranges[i] - (this.inverted ? diff : 0); + if (start > pos) { break } + var oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex], end = start + oldSize; + if (pos <= end) { + var side = !oldSize ? assoc : pos == start ? -1 : pos == end ? 1 : assoc; + var result = start + diff + (side < 0 ? 0 : newSize); + if (simple) { return result } + var recover = makeRecover(i / 3, pos - start); + return new MapResult(result, assoc < 0 ? pos != start : pos != end, recover) + } + diff += newSize - oldSize; + } + return simple ? pos + diff : new MapResult(pos + diff) +}; + +StepMap.prototype.touches = function touches (pos, recover) { + var diff = 0, index = recoverIndex(recover); + var oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; + for (var i = 0; i < this.ranges.length; i += 3) { + var start = this.ranges[i] - (this.inverted ? diff : 0); + if (start > pos) { break } + var oldSize = this.ranges[i + oldIndex], end = start + oldSize; + if (pos <= end && i == index * 3) { return true } + diff += this.ranges[i + newIndex] - oldSize; + } + return false +}; + +// :: ((oldStart: number, oldEnd: number, newStart: number, newEnd: number)) +// Calls the given function on each of the changed ranges included in +// this map. +StepMap.prototype.forEach = function forEach (f) { + var oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; + for (var i = 0, diff = 0; i < this.ranges.length; i += 3) { + var start = this.ranges[i], oldStart = start - (this.inverted ? diff : 0), newStart = start + (this.inverted ? 0 : diff); + var oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex]; + f(oldStart, oldStart + oldSize, newStart, newStart + newSize); + diff += newSize - oldSize; + } +}; + +// :: () → StepMap +// Create an inverted version of this map. The result can be used to +// map positions in the post-step document to the pre-step document. +StepMap.prototype.invert = function invert () { + return new StepMap(this.ranges, !this.inverted) +}; + +StepMap.prototype.toString = function toString () { + return (this.inverted ? "-" : "") + JSON.stringify(this.ranges) +}; + +// :: (n: number) → StepMap +// Create a map that moves all positions by offset `n` (which may be +// negative). This can be useful when applying steps meant for a +// sub-document to a larger document, or vice-versa. +StepMap.offset = function offset (n) { + return n == 0 ? StepMap.empty : new StepMap(n < 0 ? [0, -n, 0] : [0, 0, n]) +}; + +StepMap.empty = new StepMap([]); + +// :: class extends Mappable +// A mapping represents a pipeline of zero or more [step +// maps](#transform.StepMap). It has special provisions for losslessly +// handling mapping positions through a series of steps in which some +// steps are inverted versions of earlier steps. (This comes up when +// ‘[rebasing](/docs/guide/#transform.rebasing)’ steps for +// collaboration or history management.) +var Mapping = function Mapping(maps, mirror, from, to) { + // :: [StepMap] + // The step maps in this mapping. + this.maps = maps || []; + // :: number + // The starting position in the `maps` array, used when `map` or + // `mapResult` is called. + this.from = from || 0; + // :: number + // The end position in the `maps` array. + this.to = to == null ? this.maps.length : to; + this.mirror = mirror; +}; + +// :: (?number, ?number) → Mapping +// Create a mapping that maps only through a part of this one. +Mapping.prototype.slice = function slice (from, to) { + if ( from === void 0 ) from = 0; + if ( to === void 0 ) to = this.maps.length; + + return new Mapping(this.maps, this.mirror, from, to) +}; + +Mapping.prototype.copy = function copy () { + return new Mapping(this.maps.slice(), this.mirror && this.mirror.slice(), this.from, this.to) +}; + +// :: (StepMap, ?number) +// Add a step map to the end of this mapping. If `mirrors` is +// given, it should be the index of the step map that is the mirror +// image of this one. +Mapping.prototype.appendMap = function appendMap (map, mirrors) { + this.to = this.maps.push(map); + if (mirrors != null) { this.setMirror(this.maps.length - 1, mirrors); } +}; + +// :: (Mapping) +// Add all the step maps in a given mapping to this one (preserving +// mirroring information). +Mapping.prototype.appendMapping = function appendMapping (mapping) { + for (var i = 0, startSize = this.maps.length; i < mapping.maps.length; i++) { + var mirr = mapping.getMirror(i); + this.appendMap(mapping.maps[i], mirr != null && mirr < i ? startSize + mirr : null); + } +}; + +// :: (number) → ?number +// Finds the offset of the step map that mirrors the map at the +// given offset, in this mapping (as per the second argument to +// `appendMap`). +Mapping.prototype.getMirror = function getMirror (n) { + if (this.mirror) { for (var i = 0; i < this.mirror.length; i++) + { if (this.mirror[i] == n) { return this.mirror[i + (i % 2 ? -1 : 1)] } } } +}; + +Mapping.prototype.setMirror = function setMirror (n, m) { + if (!this.mirror) { this.mirror = []; } + this.mirror.push(n, m); +}; + +// :: (Mapping) +// Append the inverse of the given mapping to this one. +Mapping.prototype.appendMappingInverted = function appendMappingInverted (mapping) { + for (var i = mapping.maps.length - 1, totalSize = this.maps.length + mapping.maps.length; i >= 0; i--) { + var mirr = mapping.getMirror(i); + this.appendMap(mapping.maps[i].invert(), mirr != null && mirr > i ? totalSize - mirr - 1 : null); + } +}; + +// :: () → Mapping +// Create an inverted version of this mapping. +Mapping.prototype.invert = function invert () { + var inverse = new Mapping; + inverse.appendMappingInverted(this); + return inverse +}; + +// : (number, ?number) → number +// Map a position through this mapping. +Mapping.prototype.map = function map (pos, assoc) { + if ( assoc === void 0 ) assoc = 1; + + if (this.mirror) { return this._map(pos, assoc, true) } + for (var i = this.from; i < this.to; i++) + { pos = this.maps[i].map(pos, assoc); } + return pos +}; + +// : (number, ?number) → MapResult +// Map a position through this mapping, returning a mapping +// result. +Mapping.prototype.mapResult = function mapResult (pos, assoc) { + if ( assoc === void 0 ) assoc = 1; + return this._map(pos, assoc, false) }; + +Mapping.prototype._map = function _map (pos, assoc, simple) { + var deleted = false, recoverables = null; + + for (var i = this.from; i < this.to; i++) { + var map = this.maps[i], rec = recoverables && recoverables[i]; + if (rec != null && map.touches(pos, rec)) { + pos = map.recover(rec); + continue + } + + var result = map.mapResult(pos, assoc); + if (result.recover != null) { + var corr = this.getMirror(i); + if (corr != null && corr > i && corr < this.to) { + if (result.deleted) { + i = corr; + pos = this.maps[corr].recover(result.recover); + continue + } else { +(recoverables || (recoverables = Object.create(null)))[corr] = result.recover; + } + } + } + + if (result.deleted) { deleted = true; } + pos = result.pos; + } + + return simple ? pos : new MapResult(pos, deleted) +}; + +function TransformError(message) { + var err = Error.call(this, message); + err.__proto__ = TransformError.prototype; + return err +} + +TransformError.prototype = Object.create(Error.prototype); +TransformError.prototype.constructor = TransformError; +TransformError.prototype.name = "TransformError"; + +// ::- Abstraction to build up and track an array of +// [steps](#transform.Step) representing a document transformation. +// +// Most transforming methods return the `Transform` object itself, so +// that they can be chained. +var Transform = function Transform(doc) { + // :: Node + // The current document (the result of applying the steps in the + // transform). + this.doc = doc; + // :: [Step] + // The steps in this transform. + this.steps = []; + // :: [Node] + // The documents before each of the steps. + this.docs = []; + // :: Mapping + // A mapping with the maps for each of the steps in this transform. + this.mapping = new Mapping; +}; + +var prototypeAccessors = { before: { configurable: true },docChanged: { configurable: true } }; + +// :: Node The starting document. +prototypeAccessors.before.get = function () { return this.docs.length ? this.docs[0] : this.doc }; + +// :: (step: Step) → this +// Apply a new step in this transform, saving the result. Throws an +// error when the step fails. +Transform.prototype.step = function step (object) { + var result = this.maybeStep(object); + if (result.failed) { throw new TransformError(result.failed) } + return this +}; + +// :: (Step) → StepResult +// Try to apply a step in this transformation, ignoring it if it +// fails. Returns the step result. +Transform.prototype.maybeStep = function maybeStep (step) { + var result = step.apply(this.doc); + if (!result.failed) { this.addStep(step, result.doc); } + return result +}; + +// :: bool +// True when the document has been changed (when there are any +// steps). +prototypeAccessors.docChanged.get = function () { + return this.steps.length > 0 +}; + +Transform.prototype.addStep = function addStep (step, doc) { + this.docs.push(this.doc); + this.steps.push(step); + this.mapping.appendMap(step.getMap()); + this.doc = doc; +}; + +Object.defineProperties( Transform.prototype, prototypeAccessors ); + +function mustOverride() { throw new Error("Override me") } + +var stepsByID = Object.create(null); + +// ::- A step object represents an atomic change. It generally applies +// only to the document it was created for, since the positions +// stored in it will only make sense for that document. +// +// New steps are defined by creating classes that extend `Step`, +// overriding the `apply`, `invert`, `map`, `getMap` and `fromJSON` +// methods, and registering your class with a unique +// JSON-serialization identifier using +// [`Step.jsonID`](#transform.Step^jsonID). +var Step = function Step () {}; + +Step.prototype.apply = function apply (_doc) { return mustOverride() }; + +// :: () → StepMap +// Get the step map that represents the changes made by this step, +// and which can be used to transform between positions in the old +// and the new document. +Step.prototype.getMap = function getMap () { return StepMap.empty }; + +// :: (doc: Node) → Step +// Create an inverted version of this step. Needs the document as it +// was before the step as argument. +Step.prototype.invert = function invert (_doc) { return mustOverride() }; + +// :: (mapping: Mappable) → ?Step +// Map this step through a mappable thing, returning either a +// version of that step with its positions adjusted, or `null` if +// the step was entirely deleted by the mapping. +Step.prototype.map = function map (_mapping) { return mustOverride() }; + +// :: (other: Step) → ?Step +// Try to merge this step with another one, to be applied directly +// after it. Returns the merged step when possible, null if the +// steps can't be merged. +Step.prototype.merge = function merge (_other) { return null }; + +// :: () → Object +// Create a JSON-serializeable representation of this step. When +// defining this for a custom subclass, make sure the result object +// includes the step type's [JSON id](#transform.Step^jsonID) under +// the `stepType` property. +Step.prototype.toJSON = function toJSON () { return mustOverride() }; + +// :: (Schema, Object) → Step +// Deserialize a step from its JSON representation. Will call +// through to the step class' own implementation of this method. +Step.fromJSON = function fromJSON (schema, json) { + if (!json || !json.stepType) { throw new RangeError("Invalid input for Step.fromJSON") } + var type = stepsByID[json.stepType]; + if (!type) { throw new RangeError(("No step type " + (json.stepType) + " defined")) } + return type.fromJSON(schema, json) +}; + +// :: (string, constructor) +// To be able to serialize steps to JSON, each step needs a string +// ID to attach to its JSON representation. Use this method to +// register an ID for your step classes. Try to pick something +// that's unlikely to clash with steps from other modules. +Step.jsonID = function jsonID (id, stepClass) { + if (id in stepsByID) { throw new RangeError("Duplicate use of step JSON ID " + id) } + stepsByID[id] = stepClass; + stepClass.prototype.jsonID = id; + return stepClass +}; + +// ::- The result of [applying](#transform.Step.apply) a step. Contains either a +// new document or a failure value. +var StepResult = function StepResult(doc, failed) { + // :: ?Node The transformed document. + this.doc = doc; + // :: ?string Text providing information about a failed step. + this.failed = failed; +}; + +// :: (Node) → StepResult +// Create a successful step result. +StepResult.ok = function ok (doc) { return new StepResult(doc, null) }; + +// :: (string) → StepResult +// Create a failed step result. +StepResult.fail = function fail (message) { return new StepResult(null, message) }; + +// :: (Node, number, number, Slice) → StepResult +// Call [`Node.replace`](#model.Node.replace) with the given +// arguments. Create a successful result if it succeeds, and a +// failed one if it throws a `ReplaceError`. +StepResult.fromReplace = function fromReplace (doc, from, to, slice) { + try { + return StepResult.ok(doc.replace(from, to, slice)) + } catch (e) { + if (e instanceof prosemirrorModel.ReplaceError) { return StepResult.fail(e.message) } + throw e + } +}; + +// ::- Replace a part of the document with a slice of new content. +var ReplaceStep = /*@__PURE__*/(function (Step) { + function ReplaceStep(from, to, slice, structure) { + Step.call(this); + this.from = from; + this.to = to; + this.slice = slice; + this.structure = !!structure; + } + + if ( Step ) ReplaceStep.__proto__ = Step; + ReplaceStep.prototype = Object.create( Step && Step.prototype ); + ReplaceStep.prototype.constructor = ReplaceStep; + + ReplaceStep.prototype.apply = function apply (doc) { + if (this.structure && contentBetween(doc, this.from, this.to)) + { return StepResult.fail("Structure replace would overwrite content") } + return StepResult.fromReplace(doc, this.from, this.to, this.slice) + }; + + ReplaceStep.prototype.getMap = function getMap () { + return new StepMap([this.from, this.to - this.from, this.slice.size]) + }; + + ReplaceStep.prototype.invert = function invert (doc) { + return new ReplaceStep(this.from, this.from + this.slice.size, doc.slice(this.from, this.to)) + }; + + ReplaceStep.prototype.map = function map (mapping) { + var from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); + if (from.deleted && to.deleted) { return null } + return new ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice) + }; + + ReplaceStep.prototype.merge = function merge (other) { + if (!(other instanceof ReplaceStep) || other.structure != this.structure) { return null } + + if (this.from + this.slice.size == other.from && !this.slice.openEnd && !other.slice.openStart) { + var slice = this.slice.size + other.slice.size == 0 ? prosemirrorModel.Slice.empty + : new prosemirrorModel.Slice(this.slice.content.append(other.slice.content), this.slice.openStart, other.slice.openEnd); + return new ReplaceStep(this.from, this.to + (other.to - other.from), slice, this.structure) + } else if (other.to == this.from && !this.slice.openStart && !other.slice.openEnd) { + var slice$1 = this.slice.size + other.slice.size == 0 ? prosemirrorModel.Slice.empty + : new prosemirrorModel.Slice(other.slice.content.append(this.slice.content), other.slice.openStart, this.slice.openEnd); + return new ReplaceStep(other.from, this.to, slice$1, this.structure) + } else { + return null + } + }; + + ReplaceStep.prototype.toJSON = function toJSON () { + var json = {stepType: "replace", from: this.from, to: this.to}; + if (this.slice.size) { json.slice = this.slice.toJSON(); } + if (this.structure) { json.structure = true; } + return json + }; + + ReplaceStep.fromJSON = function fromJSON (schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + { throw new RangeError("Invalid input for ReplaceStep.fromJSON") } + return new ReplaceStep(json.from, json.to, prosemirrorModel.Slice.fromJSON(schema, json.slice), !!json.structure) + }; + + return ReplaceStep; +}(Step)); + +Step.jsonID("replace", ReplaceStep); + +// ::- Replace a part of the document with a slice of content, but +// preserve a range of the replaced content by moving it into the +// slice. +var ReplaceAroundStep = /*@__PURE__*/(function (Step) { + function ReplaceAroundStep(from, to, gapFrom, gapTo, slice, insert, structure) { + Step.call(this); + this.from = from; + this.to = to; + this.gapFrom = gapFrom; + this.gapTo = gapTo; + this.slice = slice; + this.insert = insert; + this.structure = !!structure; + } + + if ( Step ) ReplaceAroundStep.__proto__ = Step; + ReplaceAroundStep.prototype = Object.create( Step && Step.prototype ); + ReplaceAroundStep.prototype.constructor = ReplaceAroundStep; + + ReplaceAroundStep.prototype.apply = function apply (doc) { + if (this.structure && (contentBetween(doc, this.from, this.gapFrom) || + contentBetween(doc, this.gapTo, this.to))) + { return StepResult.fail("Structure gap-replace would overwrite content") } + + var gap = doc.slice(this.gapFrom, this.gapTo); + if (gap.openStart || gap.openEnd) + { return StepResult.fail("Gap is not a flat range") } + var inserted = this.slice.insertAt(this.insert, gap.content); + if (!inserted) { return StepResult.fail("Content does not fit in gap") } + return StepResult.fromReplace(doc, this.from, this.to, inserted) + }; + + ReplaceAroundStep.prototype.getMap = function getMap () { + return new StepMap([this.from, this.gapFrom - this.from, this.insert, + this.gapTo, this.to - this.gapTo, this.slice.size - this.insert]) + }; + + ReplaceAroundStep.prototype.invert = function invert (doc) { + var gap = this.gapTo - this.gapFrom; + return new ReplaceAroundStep(this.from, this.from + this.slice.size + gap, + this.from + this.insert, this.from + this.insert + gap, + doc.slice(this.from, this.to).removeBetween(this.gapFrom - this.from, this.gapTo - this.from), + this.gapFrom - this.from, this.structure) + }; + + ReplaceAroundStep.prototype.map = function map (mapping) { + var from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); + var gapFrom = mapping.map(this.gapFrom, -1), gapTo = mapping.map(this.gapTo, 1); + if ((from.deleted && to.deleted) || gapFrom < from.pos || gapTo > to.pos) { return null } + return new ReplaceAroundStep(from.pos, to.pos, gapFrom, gapTo, this.slice, this.insert, this.structure) + }; + + ReplaceAroundStep.prototype.toJSON = function toJSON () { + var json = {stepType: "replaceAround", from: this.from, to: this.to, + gapFrom: this.gapFrom, gapTo: this.gapTo, insert: this.insert}; + if (this.slice.size) { json.slice = this.slice.toJSON(); } + if (this.structure) { json.structure = true; } + return json + }; + + ReplaceAroundStep.fromJSON = function fromJSON (schema, json) { + if (typeof json.from != "number" || typeof json.to != "number" || + typeof json.gapFrom != "number" || typeof json.gapTo != "number" || typeof json.insert != "number") + { throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON") } + return new ReplaceAroundStep(json.from, json.to, json.gapFrom, json.gapTo, + prosemirrorModel.Slice.fromJSON(schema, json.slice), json.insert, !!json.structure) + }; + + return ReplaceAroundStep; +}(Step)); + +Step.jsonID("replaceAround", ReplaceAroundStep); + +function contentBetween(doc, from, to) { + var $from = doc.resolve(from), dist = to - from, depth = $from.depth; + while (dist > 0 && depth > 0 && $from.indexAfter(depth) == $from.node(depth).childCount) { + depth--; + dist--; + } + if (dist > 0) { + var next = $from.node(depth).maybeChild($from.indexAfter(depth)); + while (dist > 0) { + if (!next || next.isLeaf) { return true } + next = next.firstChild; + dist--; + } + } + return false +} + +function canCut(node, start, end) { + return (start == 0 || node.canReplace(start, node.childCount)) && + (end == node.childCount || node.canReplace(0, end)) +} + +// :: (NodeRange) → ?number +// Try to find a target depth to which the content in the given range +// can be lifted. Will not go across +// [isolating](#model.NodeSpec.isolating) parent nodes. +function liftTarget(range) { + var parent = range.parent; + var content = parent.content.cutByIndex(range.startIndex, range.endIndex); + for (var depth = range.depth;; --depth) { + var node = range.$from.node(depth); + var index = range.$from.index(depth), endIndex = range.$to.indexAfter(depth); + if (depth < range.depth && node.canReplace(index, endIndex, content)) + { return depth } + if (depth == 0 || node.type.spec.isolating || !canCut(node, index, endIndex)) { break } + } +} + +// :: (NodeRange, number) → this +// Split the content in the given range off from its parent, if there +// is sibling content before or after it, and move it up the tree to +// the depth specified by `target`. You'll probably want to use +// [`liftTarget`](#transform.liftTarget) to compute `target`, to make +// sure the lift is valid. +Transform.prototype.lift = function(range, target) { + var $from = range.$from; + var $to = range.$to; + var depth = range.depth; + + var gapStart = $from.before(depth + 1), gapEnd = $to.after(depth + 1); + var start = gapStart, end = gapEnd; + + var before = prosemirrorModel.Fragment.empty, openStart = 0; + for (var d = depth, splitting = false; d > target; d--) + { if (splitting || $from.index(d) > 0) { + splitting = true; + before = prosemirrorModel.Fragment.from($from.node(d).copy(before)); + openStart++; + } else { + start--; + } } + var after = prosemirrorModel.Fragment.empty, openEnd = 0; + for (var d$1 = depth, splitting$1 = false; d$1 > target; d$1--) + { if (splitting$1 || $to.after(d$1 + 1) < $to.end(d$1)) { + splitting$1 = true; + after = prosemirrorModel.Fragment.from($to.node(d$1).copy(after)); + openEnd++; + } else { + end++; + } } + + return this.step(new ReplaceAroundStep(start, end, gapStart, gapEnd, + new prosemirrorModel.Slice(before.append(after), openStart, openEnd), + before.size - openStart, true)) +}; + +// :: (NodeRange, NodeType, ?Object, ?NodeRange) → ?[{type: NodeType, attrs: ?Object}] +// Try to find a valid way to wrap the content in the given range in a +// node of the given type. May introduce extra nodes around and inside +// the wrapper node, if necessary. Returns null if no valid wrapping +// could be found. When `innerRange` is given, that range's content is +// used as the content to fit into the wrapping, instead of the +// content of `range`. +function findWrapping(range, nodeType, attrs, innerRange) { + if ( innerRange === void 0 ) innerRange = range; + + var around = findWrappingOutside(range, nodeType); + var inner = around && findWrappingInside(innerRange, nodeType); + if (!inner) { return null } + return around.map(withAttrs).concat({type: nodeType, attrs: attrs}).concat(inner.map(withAttrs)) +} + +function withAttrs(type) { return {type: type, attrs: null} } + +function findWrappingOutside(range, type) { + var parent = range.parent; + var startIndex = range.startIndex; + var endIndex = range.endIndex; + var around = parent.contentMatchAt(startIndex).findWrapping(type); + if (!around) { return null } + var outer = around.length ? around[0] : type; + return parent.canReplaceWith(startIndex, endIndex, outer) ? around : null +} + +function findWrappingInside(range, type) { + var parent = range.parent; + var startIndex = range.startIndex; + var endIndex = range.endIndex; + var inner = parent.child(startIndex); + var inside = type.contentMatch.findWrapping(inner.type); + if (!inside) { return null } + var lastType = inside.length ? inside[inside.length - 1] : type; + var innerMatch = lastType.contentMatch; + for (var i = startIndex; innerMatch && i < endIndex; i++) + { innerMatch = innerMatch.matchType(parent.child(i).type); } + if (!innerMatch || !innerMatch.validEnd) { return null } + return inside +} + +// :: (NodeRange, [{type: NodeType, attrs: ?Object}]) → this +// Wrap the given [range](#model.NodeRange) in the given set of wrappers. +// The wrappers are assumed to be valid in this position, and should +// probably be computed with [`findWrapping`](#transform.findWrapping). +Transform.prototype.wrap = function(range, wrappers) { + var content = prosemirrorModel.Fragment.empty; + for (var i = wrappers.length - 1; i >= 0; i--) + { content = prosemirrorModel.Fragment.from(wrappers[i].type.create(wrappers[i].attrs, content)); } + + var start = range.start, end = range.end; + return this.step(new ReplaceAroundStep(start, end, start, end, new prosemirrorModel.Slice(content, 0, 0), wrappers.length, true)) +}; + +// :: (number, ?number, NodeType, ?Object) → this +// Set the type of all textblocks (partly) between `from` and `to` to +// the given node type with the given attributes. +Transform.prototype.setBlockType = function(from, to, type, attrs) { + var this$1 = this; + if ( to === void 0 ) to = from; + + if (!type.isTextblock) { throw new RangeError("Type given to setBlockType should be a textblock") } + var mapFrom = this.steps.length; + this.doc.nodesBetween(from, to, function (node, pos) { + if (node.isTextblock && !node.hasMarkup(type, attrs) && canChangeType(this$1.doc, this$1.mapping.slice(mapFrom).map(pos), type)) { + // Ensure all markup that isn't allowed in the new node type is cleared + this$1.clearIncompatible(this$1.mapping.slice(mapFrom).map(pos, 1), type); + var mapping = this$1.mapping.slice(mapFrom); + var startM = mapping.map(pos, 1), endM = mapping.map(pos + node.nodeSize, 1); + this$1.step(new ReplaceAroundStep(startM, endM, startM + 1, endM - 1, + new prosemirrorModel.Slice(prosemirrorModel.Fragment.from(type.create(attrs, null, node.marks)), 0, 0), 1, true)); + return false + } + }); + return this +}; + +function canChangeType(doc, pos, type) { + var $pos = doc.resolve(pos), index = $pos.index(); + return $pos.parent.canReplaceWith(index, index + 1, type) +} + +// :: (number, ?NodeType, ?Object, ?[Mark]) → this +// Change the type, attributes, and/or marks of the node at `pos`. +// When `type` isn't given, the existing node type is preserved, +Transform.prototype.setNodeMarkup = function(pos, type, attrs, marks) { + var node = this.doc.nodeAt(pos); + if (!node) { throw new RangeError("No node at given position") } + if (!type) { type = node.type; } + var newNode = type.create(attrs, null, marks || node.marks); + if (node.isLeaf) + { return this.replaceWith(pos, pos + node.nodeSize, newNode) } + + if (!type.validContent(node.content)) + { throw new RangeError("Invalid content for node type " + type.name) } + + return this.step(new ReplaceAroundStep(pos, pos + node.nodeSize, pos + 1, pos + node.nodeSize - 1, + new prosemirrorModel.Slice(prosemirrorModel.Fragment.from(newNode), 0, 0), 1, true)) +}; + +// :: (Node, number, number, ?[?{type: NodeType, attrs: ?Object}]) → bool +// Check whether splitting at the given position is allowed. +function canSplit(doc, pos, depth, typesAfter) { + if ( depth === void 0 ) depth = 1; + + var $pos = doc.resolve(pos), base = $pos.depth - depth; + var innerType = (typesAfter && typesAfter[typesAfter.length - 1]) || $pos.parent; + if (base < 0 || $pos.parent.type.spec.isolating || + !$pos.parent.canReplace($pos.index(), $pos.parent.childCount) || + !innerType.type.validContent($pos.parent.content.cutByIndex($pos.index(), $pos.parent.childCount))) + { return false } + for (var d = $pos.depth - 1, i = depth - 2; d > base; d--, i--) { + var node = $pos.node(d), index$1 = $pos.index(d); + if (node.type.spec.isolating) { return false } + var rest = node.content.cutByIndex(index$1, node.childCount); + var after = (typesAfter && typesAfter[i]) || node; + if (after != node) { rest = rest.replaceChild(0, after.type.create(after.attrs)); } + if (!node.canReplace(index$1 + 1, node.childCount) || !after.type.validContent(rest)) + { return false } + } + var index = $pos.indexAfter(base); + var baseType = typesAfter && typesAfter[0]; + return $pos.node(base).canReplaceWith(index, index, baseType ? baseType.type : $pos.node(base + 1).type) +} + +// :: (number, ?number, ?[?{type: NodeType, attrs: ?Object}]) → this +// Split the node at the given position, and optionally, if `depth` is +// greater than one, any number of nodes above that. By default, the +// parts split off will inherit the node type of the original node. +// This can be changed by passing an array of types and attributes to +// use after the split. +Transform.prototype.split = function(pos, depth, typesAfter) { + if ( depth === void 0 ) depth = 1; + + var $pos = this.doc.resolve(pos), before = prosemirrorModel.Fragment.empty, after = prosemirrorModel.Fragment.empty; + for (var d = $pos.depth, e = $pos.depth - depth, i = depth - 1; d > e; d--, i--) { + before = prosemirrorModel.Fragment.from($pos.node(d).copy(before)); + var typeAfter = typesAfter && typesAfter[i]; + after = prosemirrorModel.Fragment.from(typeAfter ? typeAfter.type.create(typeAfter.attrs, after) : $pos.node(d).copy(after)); + } + return this.step(new ReplaceStep(pos, pos, new prosemirrorModel.Slice(before.append(after), depth, depth), true)) +}; + +// :: (Node, number) → bool +// Test whether the blocks before and after a given position can be +// joined. +function canJoin(doc, pos) { + var $pos = doc.resolve(pos), index = $pos.index(); + return joinable($pos.nodeBefore, $pos.nodeAfter) && + $pos.parent.canReplace(index, index + 1) +} + +function joinable(a, b) { + return a && b && !a.isLeaf && a.canAppend(b) +} + +// :: (Node, number, ?number) → ?number +// Find an ancestor of the given position that can be joined to the +// block before (or after if `dir` is positive). Returns the joinable +// point, if any. +function joinPoint(doc, pos, dir) { + if ( dir === void 0 ) dir = -1; + + var $pos = doc.resolve(pos); + for (var d = $pos.depth;; d--) { + var before = (void 0), after = (void 0); + if (d == $pos.depth) { + before = $pos.nodeBefore; + after = $pos.nodeAfter; + } else if (dir > 0) { + before = $pos.node(d + 1); + after = $pos.node(d).maybeChild($pos.index(d) + 1); + } else { + before = $pos.node(d).maybeChild($pos.index(d) - 1); + after = $pos.node(d + 1); + } + if (before && !before.isTextblock && joinable(before, after)) { return pos } + if (d == 0) { break } + pos = dir < 0 ? $pos.before(d) : $pos.after(d); + } +} + +// :: (number, ?number) → this +// Join the blocks around the given position. If depth is 2, their +// last and first siblings are also joined, and so on. +Transform.prototype.join = function(pos, depth) { + if ( depth === void 0 ) depth = 1; + + var step = new ReplaceStep(pos - depth, pos + depth, prosemirrorModel.Slice.empty, true); + return this.step(step) +}; + +// :: (Node, number, NodeType) → ?number +// Try to find a point where a node of the given type can be inserted +// near `pos`, by searching up the node hierarchy when `pos` itself +// isn't a valid place but is at the start or end of a node. Return +// null if no position was found. +function insertPoint(doc, pos, nodeType) { + var $pos = doc.resolve(pos); + if ($pos.parent.canReplaceWith($pos.index(), $pos.index(), nodeType)) { return pos } + + if ($pos.parentOffset == 0) + { for (var d = $pos.depth - 1; d >= 0; d--) { + var index = $pos.index(d); + if ($pos.node(d).canReplaceWith(index, index, nodeType)) { return $pos.before(d + 1) } + if (index > 0) { return null } + } } + if ($pos.parentOffset == $pos.parent.content.size) + { for (var d$1 = $pos.depth - 1; d$1 >= 0; d$1--) { + var index$1 = $pos.indexAfter(d$1); + if ($pos.node(d$1).canReplaceWith(index$1, index$1, nodeType)) { return $pos.after(d$1 + 1) } + if (index$1 < $pos.node(d$1).childCount) { return null } + } } +} + +// :: (Node, number, Slice) → ?number +// Finds a position at or around the given position where the given +// slice can be inserted. Will look at parent nodes' nearest boundary +// and try there, even if the original position wasn't directly at the +// start or end of that node. Returns null when no position was found. +function dropPoint(doc, pos, slice) { + var $pos = doc.resolve(pos); + if (!slice.content.size) { return pos } + var content = slice.content; + for (var i = 0; i < slice.openStart; i++) { content = content.firstChild.content; } + for (var pass = 1; pass <= (slice.openStart == 0 && slice.size ? 2 : 1); pass++) { + for (var d = $pos.depth; d >= 0; d--) { + var bias = d == $pos.depth ? 0 : $pos.pos <= ($pos.start(d + 1) + $pos.end(d + 1)) / 2 ? -1 : 1; + var insertPos = $pos.index(d) + (bias > 0 ? 1 : 0); + if (pass == 1 + ? $pos.node(d).canReplace(insertPos, insertPos, content) + : $pos.node(d).contentMatchAt(insertPos).findWrapping(content.firstChild.type)) + { return bias == 0 ? $pos.pos : bias < 0 ? $pos.before(d + 1) : $pos.after(d + 1) } + } + } + return null +} + +function mapFragment(fragment, f, parent) { + var mapped = []; + for (var i = 0; i < fragment.childCount; i++) { + var child = fragment.child(i); + if (child.content.size) { child = child.copy(mapFragment(child.content, f, child)); } + if (child.isInline) { child = f(child, parent, i); } + mapped.push(child); + } + return prosemirrorModel.Fragment.fromArray(mapped) +} + +// ::- Add a mark to all inline content between two positions. +var AddMarkStep = /*@__PURE__*/(function (Step) { + function AddMarkStep(from, to, mark) { + Step.call(this); + this.from = from; + this.to = to; + this.mark = mark; + } + + if ( Step ) AddMarkStep.__proto__ = Step; + AddMarkStep.prototype = Object.create( Step && Step.prototype ); + AddMarkStep.prototype.constructor = AddMarkStep; + + AddMarkStep.prototype.apply = function apply (doc) { + var this$1 = this; + + var oldSlice = doc.slice(this.from, this.to), $from = doc.resolve(this.from); + var parent = $from.node($from.sharedDepth(this.to)); + var slice = new prosemirrorModel.Slice(mapFragment(oldSlice.content, function (node, parent) { + if (!parent.type.allowsMarkType(this$1.mark.type)) { return node } + return node.mark(this$1.mark.addToSet(node.marks)) + }, parent), oldSlice.openStart, oldSlice.openEnd); + return StepResult.fromReplace(doc, this.from, this.to, slice) + }; + + AddMarkStep.prototype.invert = function invert () { + return new RemoveMarkStep(this.from, this.to, this.mark) + }; + + AddMarkStep.prototype.map = function map (mapping) { + var from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); + if (from.deleted && to.deleted || from.pos >= to.pos) { return null } + return new AddMarkStep(from.pos, to.pos, this.mark) + }; + + AddMarkStep.prototype.merge = function merge (other) { + if (other instanceof AddMarkStep && + other.mark.eq(this.mark) && + this.from <= other.to && this.to >= other.from) + { return new AddMarkStep(Math.min(this.from, other.from), + Math.max(this.to, other.to), this.mark) } + }; + + AddMarkStep.prototype.toJSON = function toJSON () { + return {stepType: "addMark", mark: this.mark.toJSON(), + from: this.from, to: this.to} + }; + + AddMarkStep.fromJSON = function fromJSON (schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + { throw new RangeError("Invalid input for AddMarkStep.fromJSON") } + return new AddMarkStep(json.from, json.to, schema.markFromJSON(json.mark)) + }; + + return AddMarkStep; +}(Step)); + +Step.jsonID("addMark", AddMarkStep); + +// ::- Remove a mark from all inline content between two positions. +var RemoveMarkStep = /*@__PURE__*/(function (Step) { + function RemoveMarkStep(from, to, mark) { + Step.call(this); + this.from = from; + this.to = to; + this.mark = mark; + } + + if ( Step ) RemoveMarkStep.__proto__ = Step; + RemoveMarkStep.prototype = Object.create( Step && Step.prototype ); + RemoveMarkStep.prototype.constructor = RemoveMarkStep; + + RemoveMarkStep.prototype.apply = function apply (doc) { + var this$1 = this; + + var oldSlice = doc.slice(this.from, this.to); + var slice = new prosemirrorModel.Slice(mapFragment(oldSlice.content, function (node) { + return node.mark(this$1.mark.removeFromSet(node.marks)) + }), oldSlice.openStart, oldSlice.openEnd); + return StepResult.fromReplace(doc, this.from, this.to, slice) + }; + + RemoveMarkStep.prototype.invert = function invert () { + return new AddMarkStep(this.from, this.to, this.mark) + }; + + RemoveMarkStep.prototype.map = function map (mapping) { + var from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); + if (from.deleted && to.deleted || from.pos >= to.pos) { return null } + return new RemoveMarkStep(from.pos, to.pos, this.mark) + }; + + RemoveMarkStep.prototype.merge = function merge (other) { + if (other instanceof RemoveMarkStep && + other.mark.eq(this.mark) && + this.from <= other.to && this.to >= other.from) + { return new RemoveMarkStep(Math.min(this.from, other.from), + Math.max(this.to, other.to), this.mark) } + }; + + RemoveMarkStep.prototype.toJSON = function toJSON () { + return {stepType: "removeMark", mark: this.mark.toJSON(), + from: this.from, to: this.to} + }; + + RemoveMarkStep.fromJSON = function fromJSON (schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + { throw new RangeError("Invalid input for RemoveMarkStep.fromJSON") } + return new RemoveMarkStep(json.from, json.to, schema.markFromJSON(json.mark)) + }; + + return RemoveMarkStep; +}(Step)); + +Step.jsonID("removeMark", RemoveMarkStep); + +// :: (number, number, Mark) → this +// Add the given mark to the inline content between `from` and `to`. +Transform.prototype.addMark = function(from, to, mark) { + var this$1 = this; + + var removed = [], added = [], removing = null, adding = null; + this.doc.nodesBetween(from, to, function (node, pos, parent) { + if (!node.isInline) { return } + var marks = node.marks; + if (!mark.isInSet(marks) && parent.type.allowsMarkType(mark.type)) { + var start = Math.max(pos, from), end = Math.min(pos + node.nodeSize, to); + var newSet = mark.addToSet(marks); + + for (var i = 0; i < marks.length; i++) { + if (!marks[i].isInSet(newSet)) { + if (removing && removing.to == start && removing.mark.eq(marks[i])) + { removing.to = end; } + else + { removed.push(removing = new RemoveMarkStep(start, end, marks[i])); } + } + } + + if (adding && adding.to == start) + { adding.to = end; } + else + { added.push(adding = new AddMarkStep(start, end, mark)); } + } + }); + + removed.forEach(function (s) { return this$1.step(s); }); + added.forEach(function (s) { return this$1.step(s); }); + return this +}; + +// :: (number, number, ?union) → this +// Remove marks from inline nodes between `from` and `to`. When `mark` +// is a single mark, remove precisely that mark. When it is a mark type, +// remove all marks of that type. When it is null, remove all marks of +// any type. +Transform.prototype.removeMark = function(from, to, mark) { + var this$1 = this; + if ( mark === void 0 ) mark = null; + + var matched = [], step = 0; + this.doc.nodesBetween(from, to, function (node, pos) { + if (!node.isInline) { return } + step++; + var toRemove = null; + if (mark instanceof prosemirrorModel.MarkType) { + var found = mark.isInSet(node.marks); + if (found) { toRemove = [found]; } + } else if (mark) { + if (mark.isInSet(node.marks)) { toRemove = [mark]; } + } else { + toRemove = node.marks; + } + if (toRemove && toRemove.length) { + var end = Math.min(pos + node.nodeSize, to); + for (var i = 0; i < toRemove.length; i++) { + var style = toRemove[i], found$1 = (void 0); + for (var j = 0; j < matched.length; j++) { + var m = matched[j]; + if (m.step == step - 1 && style.eq(matched[j].style)) { found$1 = m; } + } + if (found$1) { + found$1.to = end; + found$1.step = step; + } else { + matched.push({style: style, from: Math.max(pos, from), to: end, step: step}); + } + } + } + }); + matched.forEach(function (m) { return this$1.step(new RemoveMarkStep(m.from, m.to, m.style)); }); + return this +}; + +// :: (number, NodeType, ?ContentMatch) → this +// Removes all marks and nodes from the content of the node at `pos` +// that don't match the given new parent node type. Accepts an +// optional starting [content match](#model.ContentMatch) as third +// argument. +Transform.prototype.clearIncompatible = function(pos, parentType, match) { + if ( match === void 0 ) match = parentType.contentMatch; + + var node = this.doc.nodeAt(pos); + var delSteps = [], cur = pos + 1; + for (var i = 0; i < node.childCount; i++) { + var child = node.child(i), end = cur + child.nodeSize; + var allowed = match.matchType(child.type, child.attrs); + if (!allowed) { + delSteps.push(new ReplaceStep(cur, end, prosemirrorModel.Slice.empty)); + } else { + match = allowed; + for (var j = 0; j < child.marks.length; j++) { if (!parentType.allowsMarkType(child.marks[j].type)) + { this.step(new RemoveMarkStep(cur, end, child.marks[j])); } } + } + cur = end; + } + if (!match.validEnd) { + var fill = match.fillBefore(prosemirrorModel.Fragment.empty, true); + this.replace(cur, cur, new prosemirrorModel.Slice(fill, 0, 0)); + } + for (var i$1 = delSteps.length - 1; i$1 >= 0; i$1--) { this.step(delSteps[i$1]); } + return this +}; + +// :: (Node, number, ?number, ?Slice) → ?Step +// ‘Fit’ a slice into a given position in the document, producing a +// [step](#transform.Step) that inserts it. Will return null if +// there's no meaningful way to insert the slice here, or inserting it +// would be a no-op (an empty slice over an empty range). +function replaceStep(doc, from, to, slice) { + if ( to === void 0 ) to = from; + if ( slice === void 0 ) slice = prosemirrorModel.Slice.empty; + + if (from == to && !slice.size) { return null } + + var $from = doc.resolve(from), $to = doc.resolve(to); + // Optimization -- avoid work if it's obvious that it's not needed. + if (fitsTrivially($from, $to, slice)) { return new ReplaceStep(from, to, slice) } + var placed = placeSlice($from, slice); + + var fittedLeft = fitLeft($from, placed); + var fitted = fitRight($from, $to, fittedLeft); + if (!fitted) { return null } + if (fittedLeft.size != fitted.size && canMoveText($from, $to, fittedLeft)) { + var d = $to.depth, after = $to.after(d); + while (d > 1 && after == $to.end(--d)) { ++after; } + var fittedAfter = fitRight($from, doc.resolve(after), fittedLeft); + if (fittedAfter) + { return new ReplaceAroundStep(from, after, to, $to.end(), fittedAfter, fittedLeft.size) } + } + return fitted.size || from != to ? new ReplaceStep(from, to, fitted) : null +} + +// :: (number, ?number, ?Slice) → this +// Replace the part of the document between `from` and `to` with the +// given `slice`. +Transform.prototype.replace = function(from, to, slice) { + if ( to === void 0 ) to = from; + if ( slice === void 0 ) slice = prosemirrorModel.Slice.empty; + + var step = replaceStep(this.doc, from, to, slice); + if (step) { this.step(step); } + return this +}; + +// :: (number, number, union) → this +// Replace the given range with the given content, which may be a +// fragment, node, or array of nodes. +Transform.prototype.replaceWith = function(from, to, content) { + return this.replace(from, to, new prosemirrorModel.Slice(prosemirrorModel.Fragment.from(content), 0, 0)) +}; + +// :: (number, number) → this +// Delete the content between the given positions. +Transform.prototype.delete = function(from, to) { + return this.replace(from, to, prosemirrorModel.Slice.empty) +}; + +// :: (number, union) → this +// Insert the given content at the given position. +Transform.prototype.insert = function(pos, content) { + return this.replaceWith(pos, pos, content) +}; + + + +function fitLeftInner($from, depth, placed, placedBelow) { + var content = prosemirrorModel.Fragment.empty, openEnd = 0, placedHere = placed[depth]; + if ($from.depth > depth) { + var inner = fitLeftInner($from, depth + 1, placed, placedBelow || placedHere); + openEnd = inner.openEnd + 1; + content = prosemirrorModel.Fragment.from($from.node(depth + 1).copy(inner.content)); + } + + if (placedHere) { + content = content.append(placedHere.content); + openEnd = placedHere.openEnd; + } + if (placedBelow) { + content = content.append($from.node(depth).contentMatchAt($from.indexAfter(depth)).fillBefore(prosemirrorModel.Fragment.empty, true)); + openEnd = 0; + } + + return {content: content, openEnd: openEnd} +} + +function fitLeft($from, placed) { + var ref = fitLeftInner($from, 0, placed, false); + var content = ref.content; + var openEnd = ref.openEnd; + return new prosemirrorModel.Slice(content, $from.depth, openEnd || 0) +} + +function fitRightJoin(content, parent, $from, $to, depth, openStart, openEnd) { + var match, count = content.childCount, matchCount = count - (openEnd > 0 ? 1 : 0); + var parentNode = openStart < 0 ? parent : $from.node(depth); + if (openStart < 0) + { match = parentNode.contentMatchAt(matchCount); } + else if (count == 1 && openEnd > 0) + { match = parentNode.contentMatchAt(openStart ? $from.index(depth) : $from.indexAfter(depth)); } + else + { match = parentNode.contentMatchAt($from.indexAfter(depth)) + .matchFragment(content, count > 0 && openStart ? 1 : 0, matchCount); } + + var toNode = $to.node(depth); + if (openEnd > 0 && depth < $to.depth) { + var after = toNode.content.cutByIndex($to.indexAfter(depth)).addToStart(content.lastChild); + var joinable$1 = match.fillBefore(after, true); + // Can't insert content if there's a single node stretched across this gap + if (joinable$1 && joinable$1.size && openStart > 0 && count == 1) { joinable$1 = null; } + + if (joinable$1) { + var inner = fitRightJoin(content.lastChild.content, content.lastChild, $from, $to, + depth + 1, count == 1 ? openStart - 1 : -1, openEnd - 1); + if (inner) { + var last = content.lastChild.copy(inner); + if (joinable$1.size) + { return content.cutByIndex(0, count - 1).append(joinable$1).addToEnd(last) } + else + { return content.replaceChild(count - 1, last) } + } + } + } + if (openEnd > 0) + { match = match.matchType((count == 1 && openStart > 0 ? $from.node(depth + 1) : content.lastChild).type); } + + // If we're here, the next level can't be joined, so we see what + // happens if we leave it open. + var toIndex = $to.index(depth); + if (toIndex == toNode.childCount && !toNode.type.compatibleContent(parent.type)) { return null } + var joinable = match.fillBefore(toNode.content, true, toIndex); + for (var i = toIndex; joinable && i < toNode.content.childCount; i++) + { if (!parentNode.type.allowsMarks(toNode.content.child(i).marks)) { joinable = null; } } + if (!joinable) { return null } + + if (openEnd > 0) { + var closed = fitRightClosed(content.lastChild, openEnd - 1, $from, depth + 1, + count == 1 ? openStart - 1 : -1); + content = content.replaceChild(count - 1, closed); + } + content = content.append(joinable); + if ($to.depth > depth) + { content = content.addToEnd(fitRightSeparate($to, depth + 1)); } + return content +} + +function fitRightClosed(node, openEnd, $from, depth, openStart) { + var match, content = node.content, count = content.childCount; + if (openStart >= 0) + { match = $from.node(depth).contentMatchAt($from.indexAfter(depth)) + .matchFragment(content, openStart > 0 ? 1 : 0, count); } + else + { match = node.contentMatchAt(count); } + + if (openEnd > 0) { + var closed = fitRightClosed(content.lastChild, openEnd - 1, $from, depth + 1, + count == 1 ? openStart - 1 : -1); + content = content.replaceChild(count - 1, closed); + } + + return node.copy(content.append(match.fillBefore(prosemirrorModel.Fragment.empty, true))) +} + +function fitRightSeparate($to, depth) { + var node = $to.node(depth); + var fill = node.contentMatchAt(0).fillBefore(node.content, true, $to.index(depth)); + if ($to.depth > depth) { fill = fill.addToEnd(fitRightSeparate($to, depth + 1)); } + return node.copy(fill) +} + +function normalizeSlice(content, openStart, openEnd) { + while (openStart > 0 && openEnd > 0 && content.childCount == 1) { + content = content.firstChild.content; + openStart--; + openEnd--; + } + return new prosemirrorModel.Slice(content, openStart, openEnd) +} + +// : (ResolvedPos, ResolvedPos, number, Slice) → Slice +function fitRight($from, $to, slice) { + var fitted = fitRightJoin(slice.content, $from.node(0), $from, $to, 0, slice.openStart, slice.openEnd); + if (!fitted) { return null } + return normalizeSlice(fitted, slice.openStart, $to.depth) +} + +function fitsTrivially($from, $to, slice) { + return !slice.openStart && !slice.openEnd && $from.start() == $to.start() && + $from.parent.canReplace($from.index(), $to.index(), slice.content) +} + +function canMoveText($from, $to, slice) { + if (!$to.parent.isTextblock) { return false } + + var parent = slice.openEnd ? nodeRight(slice.content, slice.openEnd) + : $from.node($from.depth - (slice.openStart - slice.openEnd)); + if (!parent.isTextblock) { return false } + for (var i = $to.index(); i < $to.parent.childCount; i++) + { if (!parent.type.allowsMarks($to.parent.child(i).marks)) { return false } } + var match; + if (slice.openEnd) { + match = parent.contentMatchAt(parent.childCount); + } else { + match = parent.contentMatchAt(parent.childCount); + if (slice.size) { match = match.matchFragment(slice.content, slice.openStart ? 1 : 0); } + } + match = match.matchFragment($to.parent.content, $to.index()); + return match && match.validEnd +} + +function nodeRight(content, depth) { + for (var i = 1; i < depth; i++) { content = content.lastChild.content; } + return content.lastChild +} + +// Algorithm for 'placing' the elements of a slice into a gap: +// +// We consider the content of each node that is open to the left to be +// independently placeable. I.e. in , when the +// paragraph on the left is open, "foo" can be placed (somewhere on +// the left side of the replacement gap) independently from p("bar"). +// +// So placeSlice splits up a slice into a number of sub-slices, +// along with information on where they can be placed on the given +// left-side edge. It works by walking the open side of the slice, +// from the inside out, and trying to find a landing spot for each +// element, by simultaneously scanning over the gap side. When no +// place is found for an open node's content, it is left in that node. + +// : (ResolvedPos, Slice) → [{content: Fragment, openEnd: number, depth: number}] +function placeSlice($from, slice) { + var frontier = new Frontier($from); + for (var pass = 1; slice.size && pass <= 3; pass++) { + var value = frontier.placeSlice(slice.content, slice.openStart, slice.openEnd, pass); + if (pass == 3 && value != slice && value.size) { pass = 0; } // Restart if the 3rd pass made progress but left content + slice = value; + } + while (frontier.open.length) { frontier.closeNode(); } + return frontier.placed +} + +// Helper class that models the open side of the insert position, +// keeping track of the content match and already inserted content +// at each depth. +var Frontier = function Frontier($pos) { + // : [{parent: Node, match: ContentMatch, content: Fragment, wrapper: bool, openEnd: number, depth: number}] + this.open = []; + for (var d = 0; d <= $pos.depth; d++) { + var parent = $pos.node(d), match = parent.contentMatchAt($pos.indexAfter(d)); + this.open.push({parent: parent, match: match, content: prosemirrorModel.Fragment.empty, wrapper: false, openEnd: 0, depth: d}); + } + this.placed = []; +}; + +// : (Fragment, number, number, number, ?Node) → Slice +// Tries to place the content of the given slice, and returns a +// slice containing unplaced content. +// +// pass 1: try to fit directly +// pass 2: allow wrapper nodes to be introduced +// pass 3: allow unwrapping of nodes that aren't open +Frontier.prototype.placeSlice = function placeSlice (fragment, openStart, openEnd, pass, parent) { + if (openStart > 0) { + var first = fragment.firstChild; + var inner = this.placeSlice(first.content, Math.max(0, openStart - 1), + openEnd && fragment.childCount == 1 ? openEnd - 1 : 0, + pass, first); + if (inner.content != first.content) { + if (inner.content.size) { + fragment = fragment.replaceChild(0, first.copy(inner.content)); + openStart = inner.openStart + 1; + } else { + if (fragment.childCount == 1) { openEnd = 0; } + fragment = fragment.cutByIndex(1); + openStart = 0; + } + } + } + var result = this.placeContent(fragment, openStart, openEnd, pass, parent); + if (pass > 2 && result.size && openStart == 0) { + var child = result.content.firstChild, single = result.content.childCount == 1; + this.placeContent(child.content, 0, openEnd && single ? openEnd - 1 : 0, pass, child); + result = single ? prosemirrorModel.Fragment.empty : new prosemirrorModel.Slice(result.content.cutByIndex(1), 0, openEnd); + } + return result +}; + +Frontier.prototype.placeContent = function placeContent (fragment, openStart, openEnd, pass, parent) { + var i = 0; + // Go over the fragment's children + for (; i < fragment.childCount; i++) { + var child = fragment.child(i), placed = false, last = i == fragment.childCount - 1; + // Try each open node in turn, starting from the innermost + for (var d = this.open.length - 1; d >= 0; d--) { + var open = this.open[d], wrap = (void 0); + + // If pass > 1, it is allowed to wrap the node to help find a + // fit, so if findWrapping returns something, we add open + // nodes to the frontier for that wrapping. + if (pass > 1 && (wrap = open.match.findWrapping(child.type)) && + !(parent && wrap.length && wrap[wrap.length - 1] == parent.type)) { + while (this.open.length - 1 > d) { this.closeNode(); } + for (var w = 0; w < wrap.length; w++) { + open.match = open.match.matchType(wrap[w]); + d++; + open = {parent: wrap[w].create(), + match: wrap[w].contentMatch, + content: prosemirrorModel.Fragment.empty, wrapper: true, openEnd: 0, depth: d + w}; + this.open.push(open); + } + } + + // See if the child fits here + var match = open.match.matchType(child.type); + if (!match) { + var fill = open.match.fillBefore(prosemirrorModel.Fragment.from(child)); + if (fill) { + for (var j = 0; j < fill.childCount; j++) { + var ch = fill.child(j); + this.addNode(open, ch, 0); + match = open.match.matchFragment(ch); + } + } else if (parent && open.match.matchType(parent.type)) { + // Don't continue looking further up if the parent node + // would fit here. + break + } else { + continue + } + } + + // Close open nodes above this one, since we're starting to + // add to this. + while (this.open.length - 1 > d) { this.closeNode(); } + // Strip marks from the child or close its start when necessary + child = child.mark(open.parent.type.allowedMarks(child.marks)); + if (openStart) { + child = closeNodeStart(child, openStart, last ? openEnd : 0); + openStart = 0; + } + // Add the child to this open node and adjust its metadata + this.addNode(open, child, last ? openEnd : 0); + open.match = match; + if (last) { openEnd = 0; } + placed = true; + break + } + // As soon as we've failed to place a node we stop looking at + // later nodes + if (!placed) { break } + } + // Close the current open node if it's not the the root and we + // either placed up to the end of the node or the the current + // slice depth's node type matches the open node's type + if (this.open.length > 1 && + (i > 0 && i == fragment.childCount || + parent && this.open[this.open.length - 1].parent.type == parent.type)) + { this.closeNode(); } + + return new prosemirrorModel.Slice(fragment.cutByIndex(i), openStart, openEnd) +}; + +Frontier.prototype.addNode = function addNode (open, node, openEnd) { + open.content = closeFragmentEnd(open.content, open.openEnd).addToEnd(node); + open.openEnd = openEnd; +}; + +Frontier.prototype.closeNode = function closeNode () { + var open = this.open.pop(); + if (open.content.size == 0) ; else if (open.wrapper) { + this.addNode(this.open[this.open.length - 1], open.parent.copy(open.content), open.openEnd + 1); + } else { + this.placed[open.depth] = {depth: open.depth, content: open.content, openEnd: open.openEnd}; + } +}; + +function closeNodeStart(node, openStart, openEnd) { + var content = node.content; + if (openStart > 1) { + var first = closeNodeStart(node.firstChild, openStart - 1, node.childCount == 1 ? openEnd - 1 : 0); + content = node.content.replaceChild(0, first); + } + var fill = node.type.contentMatch.fillBefore(content, openEnd == 0); + return node.copy(fill.append(content)) +} + +function closeNodeEnd(node, depth) { + var content = node.content; + if (depth > 1) { + var last = closeNodeEnd(node.lastChild, depth - 1); + content = node.content.replaceChild(node.childCount - 1, last); + } + var fill = node.contentMatchAt(node.childCount).fillBefore(prosemirrorModel.Fragment.empty, true); + return node.copy(content.append(fill)) +} + +function closeFragmentEnd(fragment, depth) { + return depth ? fragment.replaceChild(fragment.childCount - 1, closeNodeEnd(fragment.lastChild, depth)) : fragment +} + +// :: (number, number, Slice) → this +// Replace a range of the document with a given slice, using `from`, +// `to`, and the slice's [`openStart`](#model.Slice.openStart) property +// as hints, rather than fixed start and end points. This method may +// grow the replaced area or close open nodes in the slice in order to +// get a fit that is more in line with WYSIWYG expectations, by +// dropping fully covered parent nodes of the replaced region when +// they are marked [non-defining](#model.NodeSpec.defining), or +// including an open parent node from the slice that _is_ marked as +// [defining](#model.NodeSpec.defining). +// +// This is the method, for example, to handle paste. The similar +// [`replace`](#transform.Transform.replace) method is a more +// primitive tool which will _not_ move the start and end of its given +// range, and is useful in situations where you need more precise +// control over what happens. +Transform.prototype.replaceRange = function(from, to, slice) { + if (!slice.size) { return this.deleteRange(from, to) } + + var $from = this.doc.resolve(from), $to = this.doc.resolve(to); + if (fitsTrivially($from, $to, slice)) + { return this.step(new ReplaceStep(from, to, slice)) } + + var targetDepths = coveredDepths($from, this.doc.resolve(to)); + // Can't replace the whole document, so remove 0 if it's present + if (targetDepths[targetDepths.length - 1] == 0) { targetDepths.pop(); } + // Negative numbers represent not expansion over the whole node at + // that depth, but replacing from $from.before(-D) to $to.pos. + var preferredTarget = -($from.depth + 1); + targetDepths.unshift(preferredTarget); + // This loop picks a preferred target depth, if one of the covering + // depths is not outside of a defining node, and adds negative + // depths for any depth that has $from at its start and does not + // cross a defining node. + for (var d = $from.depth, pos = $from.pos - 1; d > 0; d--, pos--) { + var spec = $from.node(d).type.spec; + if (spec.defining || spec.isolating) { break } + if (targetDepths.indexOf(d) > -1) { preferredTarget = d; } + else if ($from.before(d) == pos) { targetDepths.splice(1, 0, -d); } + } + // Try to fit each possible depth of the slice into each possible + // target depth, starting with the preferred depths. + var preferredTargetIndex = targetDepths.indexOf(preferredTarget); + + var leftNodes = [], preferredDepth = slice.openStart; + for (var content = slice.content, i = 0;; i++) { + var node = content.firstChild; + leftNodes.push(node); + if (i == slice.openStart) { break } + content = node.content; + } + // Back up if the node directly above openStart, or the node above + // that separated only by a non-defining textblock node, is defining. + if (preferredDepth > 0 && leftNodes[preferredDepth - 1].type.spec.defining && + $from.node(preferredTargetIndex).type != leftNodes[preferredDepth - 1].type) + { preferredDepth -= 1; } + else if (preferredDepth >= 2 && leftNodes[preferredDepth - 1].isTextblock && leftNodes[preferredDepth - 2].type.spec.defining && + $from.node(preferredTargetIndex).type != leftNodes[preferredDepth - 2].type) + { preferredDepth -= 2; } + + for (var j = slice.openStart; j >= 0; j--) { + var openDepth = (j + preferredDepth + 1) % (slice.openStart + 1); + var insert = leftNodes[openDepth]; + if (!insert) { continue } + for (var i$1 = 0; i$1 < targetDepths.length; i$1++) { + // Loop over possible expansion levels, starting with the + // preferred one + var targetDepth = targetDepths[(i$1 + preferredTargetIndex) % targetDepths.length], expand = true; + if (targetDepth < 0) { expand = false; targetDepth = -targetDepth; } + var parent = $from.node(targetDepth - 1), index = $from.index(targetDepth - 1); + if (parent.canReplaceWith(index, index, insert.type, insert.marks)) + { return this.replace($from.before(targetDepth), expand ? $to.after(targetDepth) : to, + new prosemirrorModel.Slice(closeFragment(slice.content, 0, slice.openStart, openDepth), + openDepth, slice.openEnd)) } + } + } + + var startSteps = this.steps.length; + for (var i$2 = targetDepths.length - 1; i$2 >= 0; i$2--) { + this.replace(from, to, slice); + if (this.steps.length > startSteps) { break } + var depth = targetDepths[i$2]; + if (i$2 < 0) { continue } + from = $from.before(depth); to = $to.after(depth); + } + return this +}; + +function closeFragment(fragment, depth, oldOpen, newOpen, parent) { + if (depth < oldOpen) { + var first = fragment.firstChild; + fragment = fragment.replaceChild(0, first.copy(closeFragment(first.content, depth + 1, oldOpen, newOpen, first))); + } + if (depth > newOpen) { + var match = parent.contentMatchAt(0); + var start = match.fillBefore(fragment).append(fragment); + fragment = start.append(match.matchFragment(start).fillBefore(prosemirrorModel.Fragment.empty, true)); + } + return fragment +} + +// :: (number, number, Node) → this +// Replace the given range with a node, but use `from` and `to` as +// hints, rather than precise positions. When from and to are the same +// and are at the start or end of a parent node in which the given +// node doesn't fit, this method may _move_ them out towards a parent +// that does allow the given node to be placed. When the given range +// completely covers a parent node, this method may completely replace +// that parent node. +Transform.prototype.replaceRangeWith = function(from, to, node) { + if (!node.isInline && from == to && this.doc.resolve(from).parent.content.size) { + var point = insertPoint(this.doc, from, node.type); + if (point != null) { from = to = point; } + } + return this.replaceRange(from, to, new prosemirrorModel.Slice(prosemirrorModel.Fragment.from(node), 0, 0)) +}; + +// :: (number, number) → this +// Delete the given range, expanding it to cover fully covered +// parent nodes until a valid replace is found. +Transform.prototype.deleteRange = function(from, to) { + var $from = this.doc.resolve(from), $to = this.doc.resolve(to); + var covered = coveredDepths($from, $to); + for (var i = 0; i < covered.length; i++) { + var depth = covered[i], last = i == covered.length - 1; + if ((last && depth == 0) || $from.node(depth).type.contentMatch.validEnd) + { return this.delete($from.start(depth), $to.end(depth)) } + if (depth > 0 && (last || $from.node(depth - 1).canReplace($from.index(depth - 1), $to.indexAfter(depth - 1)))) + { return this.delete($from.before(depth), $to.after(depth)) } + } + for (var d = 1; d <= $from.depth && d <= $to.depth; d++) { + if (from - $from.start(d) == $from.depth - d && to > $from.end(d) && $to.end(d) - to != $to.depth - d) + { return this.delete($from.before(d), to) } + } + return this.delete(from, to) +}; + +// : (ResolvedPos, ResolvedPos) → [number] +// Returns an array of all depths for which $from - $to spans the +// whole content of the nodes at that depth. +function coveredDepths($from, $to) { + var result = [], minDepth = Math.min($from.depth, $to.depth); + for (var d = minDepth; d >= 0; d--) { + var start = $from.start(d); + if (start < $from.pos - ($from.depth - d) || + $to.end(d) > $to.pos + ($to.depth - d) || + $from.node(d).type.spec.isolating || + $to.node(d).type.spec.isolating) { break } + if (start == $to.start(d)) { result.push(d); } + } + return result +} + +exports.AddMarkStep = AddMarkStep; +exports.MapResult = MapResult; +exports.Mapping = Mapping; +exports.RemoveMarkStep = RemoveMarkStep; +exports.ReplaceAroundStep = ReplaceAroundStep; +exports.ReplaceStep = ReplaceStep; +exports.Step = Step; +exports.StepMap = StepMap; +exports.StepResult = StepResult; +exports.Transform = Transform; +exports.TransformError = TransformError; +exports.canJoin = canJoin; +exports.canSplit = canSplit; +exports.dropPoint = dropPoint; +exports.findWrapping = findWrapping; +exports.insertPoint = insertPoint; +exports.joinPoint = joinPoint; +exports.liftTarget = liftTarget; +exports.replaceStep = replaceStep; +//# sourceMappingURL=index.js.map diff --git a/packages/tiptap-extensions/node_modules/prosemirror-transform/dist/index.js.map b/packages/tiptap-extensions/node_modules/prosemirror-transform/dist/index.js.map new file mode 100644 index 0000000000..7c23bb65dd --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-transform/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sources":["../src/map.js","../src/transform.js","../src/step.js","../src/replace_step.js","../src/structure.js","../src/mark_step.js","../src/mark.js","../src/replace.js"],"sourcesContent":["// Mappable:: interface\n// There are several things that positions can be mapped through.\n// Such objects conform to this interface.\n//\n// map:: (pos: number, assoc: ?number) → number\n// Map a position through this object. When given, `assoc` (should\n// be -1 or 1, defaults to 1) determines with which side the\n// position is associated, which determines in which direction to\n// move when a chunk of content is inserted at the mapped position.\n//\n// mapResult:: (pos: number, assoc: ?number) → MapResult\n// Map a position, and return an object containing additional\n// information about the mapping. The result's `deleted` field tells\n// you whether the position was deleted (completely enclosed in a\n// replaced range) during the mapping. When content on only one side\n// is deleted, the position itself is only considered deleted when\n// `assoc` points in the direction of the deleted content.\n\n// Recovery values encode a range index and an offset. They are\n// represented as numbers, because tons of them will be created when\n// mapping, for example, a large number of decorations. The number's\n// lower 16 bits provide the index, the remaining bits the offset.\n//\n// Note: We intentionally don't use bit shift operators to en- and\n// decode these, since those clip to 32 bits, which we might in rare\n// cases want to overflow. A 64-bit float can represent 48-bit\n// integers precisely.\n\nconst lower16 = 0xffff\nconst factor16 = Math.pow(2, 16)\n\nfunction makeRecover(index, offset) { return index + offset * factor16 }\nfunction recoverIndex(value) { return value & lower16 }\nfunction recoverOffset(value) { return (value - (value & lower16)) / factor16 }\n\n// ::- An object representing a mapped position with extra\n// information.\nexport class MapResult {\n constructor(pos, deleted = false, recover = null) {\n // :: number The mapped version of the position.\n this.pos = pos\n // :: bool Tells you whether the position was deleted, that is,\n // whether the step removed its surroundings from the document.\n this.deleted = deleted\n this.recover = recover\n }\n}\n\n// :: class extends Mappable\n// A map describing the deletions and insertions made by a step, which\n// can be used to find the correspondence between positions in the\n// pre-step version of a document and the same position in the\n// post-step version.\nexport class StepMap {\n // :: ([number])\n // Create a position map. The modifications to the document are\n // represented as an array of numbers, in which each group of three\n // represents a modified chunk as `[start, oldSize, newSize]`.\n constructor(ranges, inverted = false) {\n this.ranges = ranges\n this.inverted = inverted\n }\n\n recover(value) {\n let diff = 0, index = recoverIndex(value)\n if (!this.inverted) for (let i = 0; i < index; i++)\n diff += this.ranges[i * 3 + 2] - this.ranges[i * 3 + 1]\n return this.ranges[index * 3] + diff + recoverOffset(value)\n }\n\n // : (number, ?number) → MapResult\n mapResult(pos, assoc = 1) { return this._map(pos, assoc, false) }\n\n // : (number, ?number) → number\n map(pos, assoc = 1) { return this._map(pos, assoc, true) }\n\n _map(pos, assoc, simple) {\n let diff = 0, oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2\n for (let i = 0; i < this.ranges.length; i += 3) {\n let start = this.ranges[i] - (this.inverted ? diff : 0)\n if (start > pos) break\n let oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex], end = start + oldSize\n if (pos <= end) {\n let side = !oldSize ? assoc : pos == start ? -1 : pos == end ? 1 : assoc\n let result = start + diff + (side < 0 ? 0 : newSize)\n if (simple) return result\n let recover = makeRecover(i / 3, pos - start)\n return new MapResult(result, assoc < 0 ? pos != start : pos != end, recover)\n }\n diff += newSize - oldSize\n }\n return simple ? pos + diff : new MapResult(pos + diff)\n }\n\n touches(pos, recover) {\n let diff = 0, index = recoverIndex(recover)\n let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2\n for (let i = 0; i < this.ranges.length; i += 3) {\n let start = this.ranges[i] - (this.inverted ? diff : 0)\n if (start > pos) break\n let oldSize = this.ranges[i + oldIndex], end = start + oldSize\n if (pos <= end && i == index * 3) return true\n diff += this.ranges[i + newIndex] - oldSize\n }\n return false\n }\n\n // :: ((oldStart: number, oldEnd: number, newStart: number, newEnd: number))\n // Calls the given function on each of the changed ranges included in\n // this map.\n forEach(f) {\n let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2\n for (let i = 0, diff = 0; i < this.ranges.length; i += 3) {\n let start = this.ranges[i], oldStart = start - (this.inverted ? diff : 0), newStart = start + (this.inverted ? 0 : diff)\n let oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex]\n f(oldStart, oldStart + oldSize, newStart, newStart + newSize)\n diff += newSize - oldSize\n }\n }\n\n // :: () → StepMap\n // Create an inverted version of this map. The result can be used to\n // map positions in the post-step document to the pre-step document.\n invert() {\n return new StepMap(this.ranges, !this.inverted)\n }\n\n toString() {\n return (this.inverted ? \"-\" : \"\") + JSON.stringify(this.ranges)\n }\n\n // :: (n: number) → StepMap\n // Create a map that moves all positions by offset `n` (which may be\n // negative). This can be useful when applying steps meant for a\n // sub-document to a larger document, or vice-versa.\n static offset(n) {\n return n == 0 ? StepMap.empty : new StepMap(n < 0 ? [0, -n, 0] : [0, 0, n])\n }\n}\n\nStepMap.empty = new StepMap([])\n\n// :: class extends Mappable\n// A mapping represents a pipeline of zero or more [step\n// maps](#transform.StepMap). It has special provisions for losslessly\n// handling mapping positions through a series of steps in which some\n// steps are inverted versions of earlier steps. (This comes up when\n// ‘[rebasing](/docs/guide/#transform.rebasing)’ steps for\n// collaboration or history management.)\nexport class Mapping {\n // :: (?[StepMap])\n // Create a new mapping with the given position maps.\n constructor(maps, mirror, from, to) {\n // :: [StepMap]\n // The step maps in this mapping.\n this.maps = maps || []\n // :: number\n // The starting position in the `maps` array, used when `map` or\n // `mapResult` is called.\n this.from = from || 0\n // :: number\n // The end position in the `maps` array.\n this.to = to == null ? this.maps.length : to\n this.mirror = mirror\n }\n\n // :: (?number, ?number) → Mapping\n // Create a mapping that maps only through a part of this one.\n slice(from = 0, to = this.maps.length) {\n return new Mapping(this.maps, this.mirror, from, to)\n }\n\n copy() {\n return new Mapping(this.maps.slice(), this.mirror && this.mirror.slice(), this.from, this.to)\n }\n\n // :: (StepMap, ?number)\n // Add a step map to the end of this mapping. If `mirrors` is\n // given, it should be the index of the step map that is the mirror\n // image of this one.\n appendMap(map, mirrors) {\n this.to = this.maps.push(map)\n if (mirrors != null) this.setMirror(this.maps.length - 1, mirrors)\n }\n\n // :: (Mapping)\n // Add all the step maps in a given mapping to this one (preserving\n // mirroring information).\n appendMapping(mapping) {\n for (let i = 0, startSize = this.maps.length; i < mapping.maps.length; i++) {\n let mirr = mapping.getMirror(i)\n this.appendMap(mapping.maps[i], mirr != null && mirr < i ? startSize + mirr : null)\n }\n }\n\n // :: (number) → ?number\n // Finds the offset of the step map that mirrors the map at the\n // given offset, in this mapping (as per the second argument to\n // `appendMap`).\n getMirror(n) {\n if (this.mirror) for (let i = 0; i < this.mirror.length; i++)\n if (this.mirror[i] == n) return this.mirror[i + (i % 2 ? -1 : 1)]\n }\n\n setMirror(n, m) {\n if (!this.mirror) this.mirror = []\n this.mirror.push(n, m)\n }\n\n // :: (Mapping)\n // Append the inverse of the given mapping to this one.\n appendMappingInverted(mapping) {\n for (let i = mapping.maps.length - 1, totalSize = this.maps.length + mapping.maps.length; i >= 0; i--) {\n let mirr = mapping.getMirror(i)\n this.appendMap(mapping.maps[i].invert(), mirr != null && mirr > i ? totalSize - mirr - 1 : null)\n }\n }\n\n // :: () → Mapping\n // Create an inverted version of this mapping.\n invert() {\n let inverse = new Mapping\n inverse.appendMappingInverted(this)\n return inverse\n }\n\n // : (number, ?number) → number\n // Map a position through this mapping.\n map(pos, assoc = 1) {\n if (this.mirror) return this._map(pos, assoc, true)\n for (let i = this.from; i < this.to; i++)\n pos = this.maps[i].map(pos, assoc)\n return pos\n }\n\n // : (number, ?number) → MapResult\n // Map a position through this mapping, returning a mapping\n // result.\n mapResult(pos, assoc = 1) { return this._map(pos, assoc, false) }\n\n _map(pos, assoc, simple) {\n let deleted = false, recoverables = null\n\n for (let i = this.from; i < this.to; i++) {\n let map = this.maps[i], rec = recoverables && recoverables[i]\n if (rec != null && map.touches(pos, rec)) {\n pos = map.recover(rec)\n continue\n }\n\n let result = map.mapResult(pos, assoc)\n if (result.recover != null) {\n let corr = this.getMirror(i)\n if (corr != null && corr > i && corr < this.to) {\n if (result.deleted) {\n i = corr\n pos = this.maps[corr].recover(result.recover)\n continue\n } else {\n ;(recoverables || (recoverables = Object.create(null)))[corr] = result.recover\n }\n }\n }\n\n if (result.deleted) deleted = true\n pos = result.pos\n }\n\n return simple ? pos : new MapResult(pos, deleted)\n }\n}\n","import {Mapping} from \"./map\"\n\nexport function TransformError(message) {\n let err = Error.call(this, message)\n err.__proto__ = TransformError.prototype\n return err\n}\n\nTransformError.prototype = Object.create(Error.prototype)\nTransformError.prototype.constructor = TransformError\nTransformError.prototype.name = \"TransformError\"\n\n// ::- Abstraction to build up and track an array of\n// [steps](#transform.Step) representing a document transformation.\n//\n// Most transforming methods return the `Transform` object itself, so\n// that they can be chained.\nexport class Transform {\n // :: (Node)\n // Create a transform that starts with the given document.\n constructor(doc) {\n // :: Node\n // The current document (the result of applying the steps in the\n // transform).\n this.doc = doc\n // :: [Step]\n // The steps in this transform.\n this.steps = []\n // :: [Node]\n // The documents before each of the steps.\n this.docs = []\n // :: Mapping\n // A mapping with the maps for each of the steps in this transform.\n this.mapping = new Mapping\n }\n\n // :: Node The starting document.\n get before() { return this.docs.length ? this.docs[0] : this.doc }\n\n // :: (step: Step) → this\n // Apply a new step in this transform, saving the result. Throws an\n // error when the step fails.\n step(object) {\n let result = this.maybeStep(object)\n if (result.failed) throw new TransformError(result.failed)\n return this\n }\n\n // :: (Step) → StepResult\n // Try to apply a step in this transformation, ignoring it if it\n // fails. Returns the step result.\n maybeStep(step) {\n let result = step.apply(this.doc)\n if (!result.failed) this.addStep(step, result.doc)\n return result\n }\n\n // :: bool\n // True when the document has been changed (when there are any\n // steps).\n get docChanged() {\n return this.steps.length > 0\n }\n\n addStep(step, doc) {\n this.docs.push(this.doc)\n this.steps.push(step)\n this.mapping.appendMap(step.getMap())\n this.doc = doc\n }\n}\n","import {ReplaceError} from \"prosemirror-model\"\n\nimport {StepMap} from \"./map\"\n\nfunction mustOverride() { throw new Error(\"Override me\") }\n\nconst stepsByID = Object.create(null)\n\n// ::- A step object represents an atomic change. It generally applies\n// only to the document it was created for, since the positions\n// stored in it will only make sense for that document.\n//\n// New steps are defined by creating classes that extend `Step`,\n// overriding the `apply`, `invert`, `map`, `getMap` and `fromJSON`\n// methods, and registering your class with a unique\n// JSON-serialization identifier using\n// [`Step.jsonID`](#transform.Step^jsonID).\nexport class Step {\n // :: (doc: Node) → StepResult\n // Applies this step to the given document, returning a result\n // object that either indicates failure, if the step can not be\n // applied to this document, or indicates success by containing a\n // transformed document.\n apply(_doc) { return mustOverride() }\n\n // :: () → StepMap\n // Get the step map that represents the changes made by this step,\n // and which can be used to transform between positions in the old\n // and the new document.\n getMap() { return StepMap.empty }\n\n // :: (doc: Node) → Step\n // Create an inverted version of this step. Needs the document as it\n // was before the step as argument.\n invert(_doc) { return mustOverride() }\n\n // :: (mapping: Mappable) → ?Step\n // Map this step through a mappable thing, returning either a\n // version of that step with its positions adjusted, or `null` if\n // the step was entirely deleted by the mapping.\n map(_mapping) { return mustOverride() }\n\n // :: (other: Step) → ?Step\n // Try to merge this step with another one, to be applied directly\n // after it. Returns the merged step when possible, null if the\n // steps can't be merged.\n merge(_other) { return null }\n\n // :: () → Object\n // Create a JSON-serializeable representation of this step. When\n // defining this for a custom subclass, make sure the result object\n // includes the step type's [JSON id](#transform.Step^jsonID) under\n // the `stepType` property.\n toJSON() { return mustOverride() }\n\n // :: (Schema, Object) → Step\n // Deserialize a step from its JSON representation. Will call\n // through to the step class' own implementation of this method.\n static fromJSON(schema, json) {\n if (!json || !json.stepType) throw new RangeError(\"Invalid input for Step.fromJSON\")\n let type = stepsByID[json.stepType]\n if (!type) throw new RangeError(`No step type ${json.stepType} defined`)\n return type.fromJSON(schema, json)\n }\n\n // :: (string, constructor)\n // To be able to serialize steps to JSON, each step needs a string\n // ID to attach to its JSON representation. Use this method to\n // register an ID for your step classes. Try to pick something\n // that's unlikely to clash with steps from other modules.\n static jsonID(id, stepClass) {\n if (id in stepsByID) throw new RangeError(\"Duplicate use of step JSON ID \" + id)\n stepsByID[id] = stepClass\n stepClass.prototype.jsonID = id\n return stepClass\n }\n}\n\n// ::- The result of [applying](#transform.Step.apply) a step. Contains either a\n// new document or a failure value.\nexport class StepResult {\n // : (?Node, ?string)\n constructor(doc, failed) {\n // :: ?Node The transformed document.\n this.doc = doc\n // :: ?string Text providing information about a failed step.\n this.failed = failed\n }\n\n // :: (Node) → StepResult\n // Create a successful step result.\n static ok(doc) { return new StepResult(doc, null) }\n\n // :: (string) → StepResult\n // Create a failed step result.\n static fail(message) { return new StepResult(null, message) }\n\n // :: (Node, number, number, Slice) → StepResult\n // Call [`Node.replace`](#model.Node.replace) with the given\n // arguments. Create a successful result if it succeeds, and a\n // failed one if it throws a `ReplaceError`.\n static fromReplace(doc, from, to, slice) {\n try {\n return StepResult.ok(doc.replace(from, to, slice))\n } catch (e) {\n if (e instanceof ReplaceError) return StepResult.fail(e.message)\n throw e\n }\n }\n}\n","import {Slice} from \"prosemirror-model\"\n\nimport {Step, StepResult} from \"./step\"\nimport {StepMap} from \"./map\"\n\n// ::- Replace a part of the document with a slice of new content.\nexport class ReplaceStep extends Step {\n // :: (number, number, Slice, ?bool)\n // The given `slice` should fit the 'gap' between `from` and\n // `to`—the depths must line up, and the surrounding nodes must be\n // able to be joined with the open sides of the slice. When\n // `structure` is true, the step will fail if the content between\n // from and to is not just a sequence of closing and then opening\n // tokens (this is to guard against rebased replace steps\n // overwriting something they weren't supposed to).\n constructor(from, to, slice, structure) {\n super()\n this.from = from\n this.to = to\n this.slice = slice\n this.structure = !!structure\n }\n\n apply(doc) {\n if (this.structure && contentBetween(doc, this.from, this.to))\n return StepResult.fail(\"Structure replace would overwrite content\")\n return StepResult.fromReplace(doc, this.from, this.to, this.slice)\n }\n\n getMap() {\n return new StepMap([this.from, this.to - this.from, this.slice.size])\n }\n\n invert(doc) {\n return new ReplaceStep(this.from, this.from + this.slice.size, doc.slice(this.from, this.to))\n }\n\n map(mapping) {\n let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1)\n if (from.deleted && to.deleted) return null\n return new ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice)\n }\n\n merge(other) {\n if (!(other instanceof ReplaceStep) || other.structure != this.structure) return null\n\n if (this.from + this.slice.size == other.from && !this.slice.openEnd && !other.slice.openStart) {\n let slice = this.slice.size + other.slice.size == 0 ? Slice.empty\n : new Slice(this.slice.content.append(other.slice.content), this.slice.openStart, other.slice.openEnd)\n return new ReplaceStep(this.from, this.to + (other.to - other.from), slice, this.structure)\n } else if (other.to == this.from && !this.slice.openStart && !other.slice.openEnd) {\n let slice = this.slice.size + other.slice.size == 0 ? Slice.empty\n : new Slice(other.slice.content.append(this.slice.content), other.slice.openStart, this.slice.openEnd)\n return new ReplaceStep(other.from, this.to, slice, this.structure)\n } else {\n return null\n }\n }\n\n toJSON() {\n let json = {stepType: \"replace\", from: this.from, to: this.to}\n if (this.slice.size) json.slice = this.slice.toJSON()\n if (this.structure) json.structure = true\n return json\n }\n\n static fromJSON(schema, json) {\n if (typeof json.from != \"number\" || typeof json.to != \"number\")\n throw new RangeError(\"Invalid input for ReplaceStep.fromJSON\")\n return new ReplaceStep(json.from, json.to, Slice.fromJSON(schema, json.slice), !!json.structure)\n }\n}\n\nStep.jsonID(\"replace\", ReplaceStep)\n\n// ::- Replace a part of the document with a slice of content, but\n// preserve a range of the replaced content by moving it into the\n// slice.\nexport class ReplaceAroundStep extends Step {\n // :: (number, number, number, number, Slice, number, ?bool)\n // Create a replace-around step with the given range and gap.\n // `insert` should be the point in the slice into which the content\n // of the gap should be moved. `structure` has the same meaning as\n // it has in the [`ReplaceStep`](#transform.ReplaceStep) class.\n constructor(from, to, gapFrom, gapTo, slice, insert, structure) {\n super()\n this.from = from\n this.to = to\n this.gapFrom = gapFrom\n this.gapTo = gapTo\n this.slice = slice\n this.insert = insert\n this.structure = !!structure\n }\n\n apply(doc) {\n if (this.structure && (contentBetween(doc, this.from, this.gapFrom) ||\n contentBetween(doc, this.gapTo, this.to)))\n return StepResult.fail(\"Structure gap-replace would overwrite content\")\n\n let gap = doc.slice(this.gapFrom, this.gapTo)\n if (gap.openStart || gap.openEnd)\n return StepResult.fail(\"Gap is not a flat range\")\n let inserted = this.slice.insertAt(this.insert, gap.content)\n if (!inserted) return StepResult.fail(\"Content does not fit in gap\")\n return StepResult.fromReplace(doc, this.from, this.to, inserted)\n }\n\n getMap() {\n return new StepMap([this.from, this.gapFrom - this.from, this.insert,\n this.gapTo, this.to - this.gapTo, this.slice.size - this.insert])\n }\n\n invert(doc) {\n let gap = this.gapTo - this.gapFrom\n return new ReplaceAroundStep(this.from, this.from + this.slice.size + gap,\n this.from + this.insert, this.from + this.insert + gap,\n doc.slice(this.from, this.to).removeBetween(this.gapFrom - this.from, this.gapTo - this.from),\n this.gapFrom - this.from, this.structure)\n }\n\n map(mapping) {\n let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1)\n let gapFrom = mapping.map(this.gapFrom, -1), gapTo = mapping.map(this.gapTo, 1)\n if ((from.deleted && to.deleted) || gapFrom < from.pos || gapTo > to.pos) return null\n return new ReplaceAroundStep(from.pos, to.pos, gapFrom, gapTo, this.slice, this.insert, this.structure)\n }\n\n toJSON() {\n let json = {stepType: \"replaceAround\", from: this.from, to: this.to,\n gapFrom: this.gapFrom, gapTo: this.gapTo, insert: this.insert}\n if (this.slice.size) json.slice = this.slice.toJSON()\n if (this.structure) json.structure = true\n return json\n }\n\n static fromJSON(schema, json) {\n if (typeof json.from != \"number\" || typeof json.to != \"number\" ||\n typeof json.gapFrom != \"number\" || typeof json.gapTo != \"number\" || typeof json.insert != \"number\")\n throw new RangeError(\"Invalid input for ReplaceAroundStep.fromJSON\")\n return new ReplaceAroundStep(json.from, json.to, json.gapFrom, json.gapTo,\n Slice.fromJSON(schema, json.slice), json.insert, !!json.structure)\n }\n}\n\nStep.jsonID(\"replaceAround\", ReplaceAroundStep)\n\nfunction contentBetween(doc, from, to) {\n let $from = doc.resolve(from), dist = to - from, depth = $from.depth\n while (dist > 0 && depth > 0 && $from.indexAfter(depth) == $from.node(depth).childCount) {\n depth--\n dist--\n }\n if (dist > 0) {\n let next = $from.node(depth).maybeChild($from.indexAfter(depth))\n while (dist > 0) {\n if (!next || next.isLeaf) return true\n next = next.firstChild\n dist--\n }\n }\n return false\n}\n","import {Slice, Fragment} from \"prosemirror-model\"\n\nimport {Transform} from \"./transform\"\nimport {ReplaceStep, ReplaceAroundStep} from \"./replace_step\"\n\nfunction canCut(node, start, end) {\n return (start == 0 || node.canReplace(start, node.childCount)) &&\n (end == node.childCount || node.canReplace(0, end))\n}\n\n// :: (NodeRange) → ?number\n// Try to find a target depth to which the content in the given range\n// can be lifted. Will not go across\n// [isolating](#model.NodeSpec.isolating) parent nodes.\nexport function liftTarget(range) {\n let parent = range.parent\n let content = parent.content.cutByIndex(range.startIndex, range.endIndex)\n for (let depth = range.depth;; --depth) {\n let node = range.$from.node(depth)\n let index = range.$from.index(depth), endIndex = range.$to.indexAfter(depth)\n if (depth < range.depth && node.canReplace(index, endIndex, content))\n return depth\n if (depth == 0 || node.type.spec.isolating || !canCut(node, index, endIndex)) break\n }\n}\n\n// :: (NodeRange, number) → this\n// Split the content in the given range off from its parent, if there\n// is sibling content before or after it, and move it up the tree to\n// the depth specified by `target`. You'll probably want to use\n// [`liftTarget`](#transform.liftTarget) to compute `target`, to make\n// sure the lift is valid.\nTransform.prototype.lift = function(range, target) {\n let {$from, $to, depth} = range\n\n let gapStart = $from.before(depth + 1), gapEnd = $to.after(depth + 1)\n let start = gapStart, end = gapEnd\n\n let before = Fragment.empty, openStart = 0\n for (let d = depth, splitting = false; d > target; d--)\n if (splitting || $from.index(d) > 0) {\n splitting = true\n before = Fragment.from($from.node(d).copy(before))\n openStart++\n } else {\n start--\n }\n let after = Fragment.empty, openEnd = 0\n for (let d = depth, splitting = false; d > target; d--)\n if (splitting || $to.after(d + 1) < $to.end(d)) {\n splitting = true\n after = Fragment.from($to.node(d).copy(after))\n openEnd++\n } else {\n end++\n }\n\n return this.step(new ReplaceAroundStep(start, end, gapStart, gapEnd,\n new Slice(before.append(after), openStart, openEnd),\n before.size - openStart, true))\n}\n\n// :: (NodeRange, NodeType, ?Object, ?NodeRange) → ?[{type: NodeType, attrs: ?Object}]\n// Try to find a valid way to wrap the content in the given range in a\n// node of the given type. May introduce extra nodes around and inside\n// the wrapper node, if necessary. Returns null if no valid wrapping\n// could be found. When `innerRange` is given, that range's content is\n// used as the content to fit into the wrapping, instead of the\n// content of `range`.\nexport function findWrapping(range, nodeType, attrs, innerRange = range) {\n let around = findWrappingOutside(range, nodeType)\n let inner = around && findWrappingInside(innerRange, nodeType)\n if (!inner) return null\n return around.map(withAttrs).concat({type: nodeType, attrs}).concat(inner.map(withAttrs))\n}\n\nfunction withAttrs(type) { return {type, attrs: null} }\n\nfunction findWrappingOutside(range, type) {\n let {parent, startIndex, endIndex} = range\n let around = parent.contentMatchAt(startIndex).findWrapping(type)\n if (!around) return null\n let outer = around.length ? around[0] : type\n return parent.canReplaceWith(startIndex, endIndex, outer) ? around : null\n}\n\nfunction findWrappingInside(range, type) {\n let {parent, startIndex, endIndex} = range\n let inner = parent.child(startIndex)\n let inside = type.contentMatch.findWrapping(inner.type)\n if (!inside) return null\n let lastType = inside.length ? inside[inside.length - 1] : type\n let innerMatch = lastType.contentMatch\n for (let i = startIndex; innerMatch && i < endIndex; i++)\n innerMatch = innerMatch.matchType(parent.child(i).type)\n if (!innerMatch || !innerMatch.validEnd) return null\n return inside\n}\n\n// :: (NodeRange, [{type: NodeType, attrs: ?Object}]) → this\n// Wrap the given [range](#model.NodeRange) in the given set of wrappers.\n// The wrappers are assumed to be valid in this position, and should\n// probably be computed with [`findWrapping`](#transform.findWrapping).\nTransform.prototype.wrap = function(range, wrappers) {\n let content = Fragment.empty\n for (let i = wrappers.length - 1; i >= 0; i--)\n content = Fragment.from(wrappers[i].type.create(wrappers[i].attrs, content))\n\n let start = range.start, end = range.end\n return this.step(new ReplaceAroundStep(start, end, start, end, new Slice(content, 0, 0), wrappers.length, true))\n}\n\n// :: (number, ?number, NodeType, ?Object) → this\n// Set the type of all textblocks (partly) between `from` and `to` to\n// the given node type with the given attributes.\nTransform.prototype.setBlockType = function(from, to = from, type, attrs) {\n if (!type.isTextblock) throw new RangeError(\"Type given to setBlockType should be a textblock\")\n let mapFrom = this.steps.length\n this.doc.nodesBetween(from, to, (node, pos) => {\n if (node.isTextblock && !node.hasMarkup(type, attrs) && canChangeType(this.doc, this.mapping.slice(mapFrom).map(pos), type)) {\n // Ensure all markup that isn't allowed in the new node type is cleared\n this.clearIncompatible(this.mapping.slice(mapFrom).map(pos, 1), type)\n let mapping = this.mapping.slice(mapFrom)\n let startM = mapping.map(pos, 1), endM = mapping.map(pos + node.nodeSize, 1)\n this.step(new ReplaceAroundStep(startM, endM, startM + 1, endM - 1,\n new Slice(Fragment.from(type.create(attrs, null, node.marks)), 0, 0), 1, true))\n return false\n }\n })\n return this\n}\n\nfunction canChangeType(doc, pos, type) {\n let $pos = doc.resolve(pos), index = $pos.index()\n return $pos.parent.canReplaceWith(index, index + 1, type)\n}\n\n// :: (number, ?NodeType, ?Object, ?[Mark]) → this\n// Change the type, attributes, and/or marks of the node at `pos`.\n// When `type` isn't given, the existing node type is preserved,\nTransform.prototype.setNodeMarkup = function(pos, type, attrs, marks) {\n let node = this.doc.nodeAt(pos)\n if (!node) throw new RangeError(\"No node at given position\")\n if (!type) type = node.type\n let newNode = type.create(attrs, null, marks || node.marks)\n if (node.isLeaf)\n return this.replaceWith(pos, pos + node.nodeSize, newNode)\n\n if (!type.validContent(node.content))\n throw new RangeError(\"Invalid content for node type \" + type.name)\n\n return this.step(new ReplaceAroundStep(pos, pos + node.nodeSize, pos + 1, pos + node.nodeSize - 1,\n new Slice(Fragment.from(newNode), 0, 0), 1, true))\n}\n\n// :: (Node, number, number, ?[?{type: NodeType, attrs: ?Object}]) → bool\n// Check whether splitting at the given position is allowed.\nexport function canSplit(doc, pos, depth = 1, typesAfter) {\n let $pos = doc.resolve(pos), base = $pos.depth - depth\n let innerType = (typesAfter && typesAfter[typesAfter.length - 1]) || $pos.parent\n if (base < 0 || $pos.parent.type.spec.isolating ||\n !$pos.parent.canReplace($pos.index(), $pos.parent.childCount) ||\n !innerType.type.validContent($pos.parent.content.cutByIndex($pos.index(), $pos.parent.childCount)))\n return false\n for (let d = $pos.depth - 1, i = depth - 2; d > base; d--, i--) {\n let node = $pos.node(d), index = $pos.index(d)\n if (node.type.spec.isolating) return false\n let rest = node.content.cutByIndex(index, node.childCount)\n let after = (typesAfter && typesAfter[i]) || node\n if (after != node) rest = rest.replaceChild(0, after.type.create(after.attrs))\n if (!node.canReplace(index + 1, node.childCount) || !after.type.validContent(rest))\n return false\n }\n let index = $pos.indexAfter(base)\n let baseType = typesAfter && typesAfter[0]\n return $pos.node(base).canReplaceWith(index, index, baseType ? baseType.type : $pos.node(base + 1).type)\n}\n\n// :: (number, ?number, ?[?{type: NodeType, attrs: ?Object}]) → this\n// Split the node at the given position, and optionally, if `depth` is\n// greater than one, any number of nodes above that. By default, the\n// parts split off will inherit the node type of the original node.\n// This can be changed by passing an array of types and attributes to\n// use after the split.\nTransform.prototype.split = function(pos, depth = 1, typesAfter) {\n let $pos = this.doc.resolve(pos), before = Fragment.empty, after = Fragment.empty\n for (let d = $pos.depth, e = $pos.depth - depth, i = depth - 1; d > e; d--, i--) {\n before = Fragment.from($pos.node(d).copy(before))\n let typeAfter = typesAfter && typesAfter[i]\n after = Fragment.from(typeAfter ? typeAfter.type.create(typeAfter.attrs, after) : $pos.node(d).copy(after))\n }\n return this.step(new ReplaceStep(pos, pos, new Slice(before.append(after), depth, depth), true))\n}\n\n// :: (Node, number) → bool\n// Test whether the blocks before and after a given position can be\n// joined.\nexport function canJoin(doc, pos) {\n let $pos = doc.resolve(pos), index = $pos.index()\n return joinable($pos.nodeBefore, $pos.nodeAfter) &&\n $pos.parent.canReplace(index, index + 1)\n}\n\nfunction joinable(a, b) {\n return a && b && !a.isLeaf && a.canAppend(b)\n}\n\n// :: (Node, number, ?number) → ?number\n// Find an ancestor of the given position that can be joined to the\n// block before (or after if `dir` is positive). Returns the joinable\n// point, if any.\nexport function joinPoint(doc, pos, dir = -1) {\n let $pos = doc.resolve(pos)\n for (let d = $pos.depth;; d--) {\n let before, after\n if (d == $pos.depth) {\n before = $pos.nodeBefore\n after = $pos.nodeAfter\n } else if (dir > 0) {\n before = $pos.node(d + 1)\n after = $pos.node(d).maybeChild($pos.index(d) + 1)\n } else {\n before = $pos.node(d).maybeChild($pos.index(d) - 1)\n after = $pos.node(d + 1)\n }\n if (before && !before.isTextblock && joinable(before, after)) return pos\n if (d == 0) break\n pos = dir < 0 ? $pos.before(d) : $pos.after(d)\n }\n}\n\n// :: (number, ?number) → this\n// Join the blocks around the given position. If depth is 2, their\n// last and first siblings are also joined, and so on.\nTransform.prototype.join = function(pos, depth = 1) {\n let step = new ReplaceStep(pos - depth, pos + depth, Slice.empty, true)\n return this.step(step)\n}\n\n// :: (Node, number, NodeType) → ?number\n// Try to find a point where a node of the given type can be inserted\n// near `pos`, by searching up the node hierarchy when `pos` itself\n// isn't a valid place but is at the start or end of a node. Return\n// null if no position was found.\nexport function insertPoint(doc, pos, nodeType) {\n let $pos = doc.resolve(pos)\n if ($pos.parent.canReplaceWith($pos.index(), $pos.index(), nodeType)) return pos\n\n if ($pos.parentOffset == 0)\n for (let d = $pos.depth - 1; d >= 0; d--) {\n let index = $pos.index(d)\n if ($pos.node(d).canReplaceWith(index, index, nodeType)) return $pos.before(d + 1)\n if (index > 0) return null\n }\n if ($pos.parentOffset == $pos.parent.content.size)\n for (let d = $pos.depth - 1; d >= 0; d--) {\n let index = $pos.indexAfter(d)\n if ($pos.node(d).canReplaceWith(index, index, nodeType)) return $pos.after(d + 1)\n if (index < $pos.node(d).childCount) return null\n }\n}\n\n// :: (Node, number, Slice) → ?number\n// Finds a position at or around the given position where the given\n// slice can be inserted. Will look at parent nodes' nearest boundary\n// and try there, even if the original position wasn't directly at the\n// start or end of that node. Returns null when no position was found.\nexport function dropPoint(doc, pos, slice) {\n let $pos = doc.resolve(pos)\n if (!slice.content.size) return pos\n let content = slice.content\n for (let i = 0; i < slice.openStart; i++) content = content.firstChild.content\n for (let pass = 1; pass <= (slice.openStart == 0 && slice.size ? 2 : 1); pass++) {\n for (let d = $pos.depth; d >= 0; d--) {\n let bias = d == $pos.depth ? 0 : $pos.pos <= ($pos.start(d + 1) + $pos.end(d + 1)) / 2 ? -1 : 1\n let insertPos = $pos.index(d) + (bias > 0 ? 1 : 0)\n if (pass == 1\n ? $pos.node(d).canReplace(insertPos, insertPos, content)\n : $pos.node(d).contentMatchAt(insertPos).findWrapping(content.firstChild.type))\n return bias == 0 ? $pos.pos : bias < 0 ? $pos.before(d + 1) : $pos.after(d + 1)\n }\n }\n return null\n}\n","import {Fragment, Slice} from \"prosemirror-model\"\nimport {Step, StepResult} from \"./step\"\n\nfunction mapFragment(fragment, f, parent) {\n let mapped = []\n for (let i = 0; i < fragment.childCount; i++) {\n let child = fragment.child(i)\n if (child.content.size) child = child.copy(mapFragment(child.content, f, child))\n if (child.isInline) child = f(child, parent, i)\n mapped.push(child)\n }\n return Fragment.fromArray(mapped)\n}\n\n// ::- Add a mark to all inline content between two positions.\nexport class AddMarkStep extends Step {\n // :: (number, number, Mark)\n constructor(from, to, mark) {\n super()\n this.from = from\n this.to = to\n this.mark = mark\n }\n\n apply(doc) {\n let oldSlice = doc.slice(this.from, this.to), $from = doc.resolve(this.from)\n let parent = $from.node($from.sharedDepth(this.to))\n let slice = new Slice(mapFragment(oldSlice.content, (node, parent) => {\n if (!parent.type.allowsMarkType(this.mark.type)) return node\n return node.mark(this.mark.addToSet(node.marks))\n }, parent), oldSlice.openStart, oldSlice.openEnd)\n return StepResult.fromReplace(doc, this.from, this.to, slice)\n }\n\n invert() {\n return new RemoveMarkStep(this.from, this.to, this.mark)\n }\n\n map(mapping) {\n let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1)\n if (from.deleted && to.deleted || from.pos >= to.pos) return null\n return new AddMarkStep(from.pos, to.pos, this.mark)\n }\n\n merge(other) {\n if (other instanceof AddMarkStep &&\n other.mark.eq(this.mark) &&\n this.from <= other.to && this.to >= other.from)\n return new AddMarkStep(Math.min(this.from, other.from),\n Math.max(this.to, other.to), this.mark)\n }\n\n toJSON() {\n return {stepType: \"addMark\", mark: this.mark.toJSON(),\n from: this.from, to: this.to}\n }\n\n static fromJSON(schema, json) {\n if (typeof json.from != \"number\" || typeof json.to != \"number\")\n throw new RangeError(\"Invalid input for AddMarkStep.fromJSON\")\n return new AddMarkStep(json.from, json.to, schema.markFromJSON(json.mark))\n }\n}\n\nStep.jsonID(\"addMark\", AddMarkStep)\n\n// ::- Remove a mark from all inline content between two positions.\nexport class RemoveMarkStep extends Step {\n // :: (number, number, Mark)\n constructor(from, to, mark) {\n super()\n this.from = from\n this.to = to\n this.mark = mark\n }\n\n apply(doc) {\n let oldSlice = doc.slice(this.from, this.to)\n let slice = new Slice(mapFragment(oldSlice.content, node => {\n return node.mark(this.mark.removeFromSet(node.marks))\n }), oldSlice.openStart, oldSlice.openEnd)\n return StepResult.fromReplace(doc, this.from, this.to, slice)\n }\n\n invert() {\n return new AddMarkStep(this.from, this.to, this.mark)\n }\n\n map(mapping) {\n let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1)\n if (from.deleted && to.deleted || from.pos >= to.pos) return null\n return new RemoveMarkStep(from.pos, to.pos, this.mark)\n }\n\n merge(other) {\n if (other instanceof RemoveMarkStep &&\n other.mark.eq(this.mark) &&\n this.from <= other.to && this.to >= other.from)\n return new RemoveMarkStep(Math.min(this.from, other.from),\n Math.max(this.to, other.to), this.mark)\n }\n\n toJSON() {\n return {stepType: \"removeMark\", mark: this.mark.toJSON(),\n from: this.from, to: this.to}\n }\n\n static fromJSON(schema, json) {\n if (typeof json.from != \"number\" || typeof json.to != \"number\")\n throw new RangeError(\"Invalid input for RemoveMarkStep.fromJSON\")\n return new RemoveMarkStep(json.from, json.to, schema.markFromJSON(json.mark))\n }\n}\n\nStep.jsonID(\"removeMark\", RemoveMarkStep)\n","import {MarkType, Slice, Fragment} from \"prosemirror-model\"\n\nimport {Transform} from \"./transform\"\nimport {AddMarkStep, RemoveMarkStep} from \"./mark_step\"\nimport {ReplaceStep} from \"./replace_step\"\n\n// :: (number, number, Mark) → this\n// Add the given mark to the inline content between `from` and `to`.\nTransform.prototype.addMark = function(from, to, mark) {\n let removed = [], added = [], removing = null, adding = null\n this.doc.nodesBetween(from, to, (node, pos, parent) => {\n if (!node.isInline) return\n let marks = node.marks\n if (!mark.isInSet(marks) && parent.type.allowsMarkType(mark.type)) {\n let start = Math.max(pos, from), end = Math.min(pos + node.nodeSize, to)\n let newSet = mark.addToSet(marks)\n\n for (let i = 0; i < marks.length; i++) {\n if (!marks[i].isInSet(newSet)) {\n if (removing && removing.to == start && removing.mark.eq(marks[i]))\n removing.to = end\n else\n removed.push(removing = new RemoveMarkStep(start, end, marks[i]))\n }\n }\n\n if (adding && adding.to == start)\n adding.to = end\n else\n added.push(adding = new AddMarkStep(start, end, mark))\n }\n })\n\n removed.forEach(s => this.step(s))\n added.forEach(s => this.step(s))\n return this\n}\n\n// :: (number, number, ?union) → this\n// Remove marks from inline nodes between `from` and `to`. When `mark`\n// is a single mark, remove precisely that mark. When it is a mark type,\n// remove all marks of that type. When it is null, remove all marks of\n// any type.\nTransform.prototype.removeMark = function(from, to, mark = null) {\n let matched = [], step = 0\n this.doc.nodesBetween(from, to, (node, pos) => {\n if (!node.isInline) return\n step++\n let toRemove = null\n if (mark instanceof MarkType) {\n let found = mark.isInSet(node.marks)\n if (found) toRemove = [found]\n } else if (mark) {\n if (mark.isInSet(node.marks)) toRemove = [mark]\n } else {\n toRemove = node.marks\n }\n if (toRemove && toRemove.length) {\n let end = Math.min(pos + node.nodeSize, to)\n for (let i = 0; i < toRemove.length; i++) {\n let style = toRemove[i], found\n for (let j = 0; j < matched.length; j++) {\n let m = matched[j]\n if (m.step == step - 1 && style.eq(matched[j].style)) found = m\n }\n if (found) {\n found.to = end\n found.step = step\n } else {\n matched.push({style, from: Math.max(pos, from), to: end, step})\n }\n }\n }\n })\n matched.forEach(m => this.step(new RemoveMarkStep(m.from, m.to, m.style)))\n return this\n}\n\n// :: (number, NodeType, ?ContentMatch) → this\n// Removes all marks and nodes from the content of the node at `pos`\n// that don't match the given new parent node type. Accepts an\n// optional starting [content match](#model.ContentMatch) as third\n// argument.\nTransform.prototype.clearIncompatible = function(pos, parentType, match = parentType.contentMatch) {\n let node = this.doc.nodeAt(pos)\n let delSteps = [], cur = pos + 1\n for (let i = 0; i < node.childCount; i++) {\n let child = node.child(i), end = cur + child.nodeSize\n let allowed = match.matchType(child.type, child.attrs)\n if (!allowed) {\n delSteps.push(new ReplaceStep(cur, end, Slice.empty))\n } else {\n match = allowed\n for (let j = 0; j < child.marks.length; j++) if (!parentType.allowsMarkType(child.marks[j].type))\n this.step(new RemoveMarkStep(cur, end, child.marks[j]))\n }\n cur = end\n }\n if (!match.validEnd) {\n let fill = match.fillBefore(Fragment.empty, true)\n this.replace(cur, cur, new Slice(fill, 0, 0))\n }\n for (let i = delSteps.length - 1; i >= 0; i--) this.step(delSteps[i])\n return this\n}\n","import {Fragment, Slice} from \"prosemirror-model\"\n\nimport {ReplaceStep, ReplaceAroundStep} from \"./replace_step\"\nimport {Transform} from \"./transform\"\nimport {insertPoint} from \"./structure\"\n\n// :: (Node, number, ?number, ?Slice) → ?Step\n// ‘Fit’ a slice into a given position in the document, producing a\n// [step](#transform.Step) that inserts it. Will return null if\n// there's no meaningful way to insert the slice here, or inserting it\n// would be a no-op (an empty slice over an empty range).\nexport function replaceStep(doc, from, to = from, slice = Slice.empty) {\n if (from == to && !slice.size) return null\n\n let $from = doc.resolve(from), $to = doc.resolve(to)\n // Optimization -- avoid work if it's obvious that it's not needed.\n if (fitsTrivially($from, $to, slice)) return new ReplaceStep(from, to, slice)\n let placed = placeSlice($from, slice)\n\n let fittedLeft = fitLeft($from, placed)\n let fitted = fitRight($from, $to, fittedLeft)\n if (!fitted) return null\n if (fittedLeft.size != fitted.size && canMoveText($from, $to, fittedLeft)) {\n let d = $to.depth, after = $to.after(d)\n while (d > 1 && after == $to.end(--d)) ++after\n let fittedAfter = fitRight($from, doc.resolve(after), fittedLeft)\n if (fittedAfter)\n return new ReplaceAroundStep(from, after, to, $to.end(), fittedAfter, fittedLeft.size)\n }\n return fitted.size || from != to ? new ReplaceStep(from, to, fitted) : null\n}\n\n// :: (number, ?number, ?Slice) → this\n// Replace the part of the document between `from` and `to` with the\n// given `slice`.\nTransform.prototype.replace = function(from, to = from, slice = Slice.empty) {\n let step = replaceStep(this.doc, from, to, slice)\n if (step) this.step(step)\n return this\n}\n\n// :: (number, number, union) → this\n// Replace the given range with the given content, which may be a\n// fragment, node, or array of nodes.\nTransform.prototype.replaceWith = function(from, to, content) {\n return this.replace(from, to, new Slice(Fragment.from(content), 0, 0))\n}\n\n// :: (number, number) → this\n// Delete the content between the given positions.\nTransform.prototype.delete = function(from, to) {\n return this.replace(from, to, Slice.empty)\n}\n\n// :: (number, union) → this\n// Insert the given content at the given position.\nTransform.prototype.insert = function(pos, content) {\n return this.replaceWith(pos, pos, content)\n}\n\n\n\nfunction fitLeftInner($from, depth, placed, placedBelow) {\n let content = Fragment.empty, openEnd = 0, placedHere = placed[depth]\n if ($from.depth > depth) {\n let inner = fitLeftInner($from, depth + 1, placed, placedBelow || placedHere)\n openEnd = inner.openEnd + 1\n content = Fragment.from($from.node(depth + 1).copy(inner.content))\n }\n\n if (placedHere) {\n content = content.append(placedHere.content)\n openEnd = placedHere.openEnd\n }\n if (placedBelow) {\n content = content.append($from.node(depth).contentMatchAt($from.indexAfter(depth)).fillBefore(Fragment.empty, true))\n openEnd = 0\n }\n\n return {content, openEnd}\n}\n\nfunction fitLeft($from, placed) {\n let {content, openEnd} = fitLeftInner($from, 0, placed, false)\n return new Slice(content, $from.depth, openEnd || 0)\n}\n\nfunction fitRightJoin(content, parent, $from, $to, depth, openStart, openEnd) {\n let match, count = content.childCount, matchCount = count - (openEnd > 0 ? 1 : 0)\n let parentNode = openStart < 0 ? parent : $from.node(depth)\n if (openStart < 0)\n match = parentNode.contentMatchAt(matchCount)\n else if (count == 1 && openEnd > 0)\n match = parentNode.contentMatchAt(openStart ? $from.index(depth) : $from.indexAfter(depth))\n else\n match = parentNode.contentMatchAt($from.indexAfter(depth))\n .matchFragment(content, count > 0 && openStart ? 1 : 0, matchCount)\n\n let toNode = $to.node(depth)\n if (openEnd > 0 && depth < $to.depth) {\n let after = toNode.content.cutByIndex($to.indexAfter(depth)).addToStart(content.lastChild)\n let joinable = match.fillBefore(after, true)\n // Can't insert content if there's a single node stretched across this gap\n if (joinable && joinable.size && openStart > 0 && count == 1) joinable = null\n\n if (joinable) {\n let inner = fitRightJoin(content.lastChild.content, content.lastChild, $from, $to,\n depth + 1, count == 1 ? openStart - 1 : -1, openEnd - 1)\n if (inner) {\n let last = content.lastChild.copy(inner)\n if (joinable.size)\n return content.cutByIndex(0, count - 1).append(joinable).addToEnd(last)\n else\n return content.replaceChild(count - 1, last)\n }\n }\n }\n if (openEnd > 0)\n match = match.matchType((count == 1 && openStart > 0 ? $from.node(depth + 1) : content.lastChild).type)\n\n // If we're here, the next level can't be joined, so we see what\n // happens if we leave it open.\n let toIndex = $to.index(depth)\n if (toIndex == toNode.childCount && !toNode.type.compatibleContent(parent.type)) return null\n let joinable = match.fillBefore(toNode.content, true, toIndex)\n for (let i = toIndex; joinable && i < toNode.content.childCount; i++)\n if (!parentNode.type.allowsMarks(toNode.content.child(i).marks)) joinable = null\n if (!joinable) return null\n\n if (openEnd > 0) {\n let closed = fitRightClosed(content.lastChild, openEnd - 1, $from, depth + 1,\n count == 1 ? openStart - 1 : -1)\n content = content.replaceChild(count - 1, closed)\n }\n content = content.append(joinable)\n if ($to.depth > depth)\n content = content.addToEnd(fitRightSeparate($to, depth + 1))\n return content\n}\n\nfunction fitRightClosed(node, openEnd, $from, depth, openStart) {\n let match, content = node.content, count = content.childCount\n if (openStart >= 0)\n match = $from.node(depth).contentMatchAt($from.indexAfter(depth))\n .matchFragment(content, openStart > 0 ? 1 : 0, count)\n else\n match = node.contentMatchAt(count)\n\n if (openEnd > 0) {\n let closed = fitRightClosed(content.lastChild, openEnd - 1, $from, depth + 1,\n count == 1 ? openStart - 1 : -1)\n content = content.replaceChild(count - 1, closed)\n }\n\n return node.copy(content.append(match.fillBefore(Fragment.empty, true)))\n}\n\nfunction fitRightSeparate($to, depth) {\n let node = $to.node(depth)\n let fill = node.contentMatchAt(0).fillBefore(node.content, true, $to.index(depth))\n if ($to.depth > depth) fill = fill.addToEnd(fitRightSeparate($to, depth + 1))\n return node.copy(fill)\n}\n\nfunction normalizeSlice(content, openStart, openEnd) {\n while (openStart > 0 && openEnd > 0 && content.childCount == 1) {\n content = content.firstChild.content\n openStart--\n openEnd--\n }\n return new Slice(content, openStart, openEnd)\n}\n\n// : (ResolvedPos, ResolvedPos, number, Slice) → Slice\nfunction fitRight($from, $to, slice) {\n let fitted = fitRightJoin(slice.content, $from.node(0), $from, $to, 0, slice.openStart, slice.openEnd)\n if (!fitted) return null\n return normalizeSlice(fitted, slice.openStart, $to.depth)\n}\n\nfunction fitsTrivially($from, $to, slice) {\n return !slice.openStart && !slice.openEnd && $from.start() == $to.start() &&\n $from.parent.canReplace($from.index(), $to.index(), slice.content)\n}\n\nfunction canMoveText($from, $to, slice) {\n if (!$to.parent.isTextblock) return false\n\n let parent = slice.openEnd ? nodeRight(slice.content, slice.openEnd)\n : $from.node($from.depth - (slice.openStart - slice.openEnd))\n if (!parent.isTextblock) return false\n for (let i = $to.index(); i < $to.parent.childCount; i++)\n if (!parent.type.allowsMarks($to.parent.child(i).marks)) return false\n let match\n if (slice.openEnd) {\n match = parent.contentMatchAt(parent.childCount)\n } else {\n match = parent.contentMatchAt(parent.childCount)\n if (slice.size) match = match.matchFragment(slice.content, slice.openStart ? 1 : 0)\n }\n match = match.matchFragment($to.parent.content, $to.index())\n return match && match.validEnd\n}\n\nfunction nodeRight(content, depth) {\n for (let i = 1; i < depth; i++) content = content.lastChild.content\n return content.lastChild\n}\n\n// Algorithm for 'placing' the elements of a slice into a gap:\n//\n// We consider the content of each node that is open to the left to be\n// independently placeable. I.e. in , when the\n// paragraph on the left is open, \"foo\" can be placed (somewhere on\n// the left side of the replacement gap) independently from p(\"bar\").\n//\n// So placeSlice splits up a slice into a number of sub-slices,\n// along with information on where they can be placed on the given\n// left-side edge. It works by walking the open side of the slice,\n// from the inside out, and trying to find a landing spot for each\n// element, by simultaneously scanning over the gap side. When no\n// place is found for an open node's content, it is left in that node.\n\n// : (ResolvedPos, Slice) → [{content: Fragment, openEnd: number, depth: number}]\nfunction placeSlice($from, slice) {\n let frontier = new Frontier($from)\n for (let pass = 1; slice.size && pass <= 3; pass++) {\n let value = frontier.placeSlice(slice.content, slice.openStart, slice.openEnd, pass)\n if (pass == 3 && value != slice && value.size) pass = 0 // Restart if the 3rd pass made progress but left content\n slice = value\n }\n while (frontier.open.length) frontier.closeNode()\n return frontier.placed\n}\n\n// Helper class that models the open side of the insert position,\n// keeping track of the content match and already inserted content\n// at each depth.\nclass Frontier {\n constructor($pos) {\n // : [{parent: Node, match: ContentMatch, content: Fragment, wrapper: bool, openEnd: number, depth: number}]\n this.open = []\n for (let d = 0; d <= $pos.depth; d++) {\n let parent = $pos.node(d), match = parent.contentMatchAt($pos.indexAfter(d))\n this.open.push({parent, match, content: Fragment.empty, wrapper: false, openEnd: 0, depth: d})\n }\n this.placed = []\n }\n\n // : (Fragment, number, number, number, ?Node) → Slice\n // Tries to place the content of the given slice, and returns a\n // slice containing unplaced content.\n //\n // pass 1: try to fit directly\n // pass 2: allow wrapper nodes to be introduced\n // pass 3: allow unwrapping of nodes that aren't open\n placeSlice(fragment, openStart, openEnd, pass, parent) {\n if (openStart > 0) {\n let first = fragment.firstChild\n let inner = this.placeSlice(first.content, Math.max(0, openStart - 1),\n openEnd && fragment.childCount == 1 ? openEnd - 1 : 0,\n pass, first)\n if (inner.content != first.content) {\n if (inner.content.size) {\n fragment = fragment.replaceChild(0, first.copy(inner.content))\n openStart = inner.openStart + 1\n } else {\n if (fragment.childCount == 1) openEnd = 0\n fragment = fragment.cutByIndex(1)\n openStart = 0\n }\n }\n }\n let result = this.placeContent(fragment, openStart, openEnd, pass, parent)\n if (pass > 2 && result.size && openStart == 0) {\n let child = result.content.firstChild, single = result.content.childCount == 1\n this.placeContent(child.content, 0, openEnd && single ? openEnd - 1 : 0, pass, child)\n result = single ? Fragment.empty : new Slice(result.content.cutByIndex(1), 0, openEnd)\n }\n return result\n }\n\n placeContent(fragment, openStart, openEnd, pass, parent) {\n let i = 0\n // Go over the fragment's children\n for (; i < fragment.childCount; i++) {\n let child = fragment.child(i), placed = false, last = i == fragment.childCount - 1\n // Try each open node in turn, starting from the innermost\n for (let d = this.open.length - 1; d >= 0; d--) {\n let open = this.open[d], wrap\n\n // If pass > 1, it is allowed to wrap the node to help find a\n // fit, so if findWrapping returns something, we add open\n // nodes to the frontier for that wrapping.\n if (pass > 1 && (wrap = open.match.findWrapping(child.type)) &&\n !(parent && wrap.length && wrap[wrap.length - 1] == parent.type)) {\n while (this.open.length - 1 > d) this.closeNode()\n for (let w = 0; w < wrap.length; w++) {\n open.match = open.match.matchType(wrap[w])\n d++\n open = {parent: wrap[w].create(),\n match: wrap[w].contentMatch,\n content: Fragment.empty, wrapper: true, openEnd: 0, depth: d + w}\n this.open.push(open)\n }\n }\n\n // See if the child fits here\n let match = open.match.matchType(child.type)\n if (!match) {\n let fill = open.match.fillBefore(Fragment.from(child))\n if (fill) {\n for (let j = 0; j < fill.childCount; j++) {\n let ch = fill.child(j)\n this.addNode(open, ch, 0)\n match = open.match.matchFragment(ch)\n }\n } else if (parent && open.match.matchType(parent.type)) {\n // Don't continue looking further up if the parent node\n // would fit here.\n break\n } else {\n continue\n }\n }\n\n // Close open nodes above this one, since we're starting to\n // add to this.\n while (this.open.length - 1 > d) this.closeNode()\n // Strip marks from the child or close its start when necessary\n child = child.mark(open.parent.type.allowedMarks(child.marks))\n if (openStart) {\n child = closeNodeStart(child, openStart, last ? openEnd : 0)\n openStart = 0\n }\n // Add the child to this open node and adjust its metadata\n this.addNode(open, child, last ? openEnd : 0)\n open.match = match\n if (last) openEnd = 0\n placed = true\n break\n }\n // As soon as we've failed to place a node we stop looking at\n // later nodes\n if (!placed) break\n }\n // Close the current open node if it's not the the root and we\n // either placed up to the end of the node or the the current\n // slice depth's node type matches the open node's type\n if (this.open.length > 1 &&\n (i > 0 && i == fragment.childCount ||\n parent && this.open[this.open.length - 1].parent.type == parent.type))\n this.closeNode()\n\n return new Slice(fragment.cutByIndex(i), openStart, openEnd)\n }\n\n addNode(open, node, openEnd) {\n open.content = closeFragmentEnd(open.content, open.openEnd).addToEnd(node)\n open.openEnd = openEnd\n }\n\n closeNode() {\n let open = this.open.pop()\n if (open.content.size == 0) {\n // Nothing here\n } else if (open.wrapper) {\n this.addNode(this.open[this.open.length - 1], open.parent.copy(open.content), open.openEnd + 1)\n } else {\n this.placed[open.depth] = {depth: open.depth, content: open.content, openEnd: open.openEnd}\n }\n }\n}\n\nfunction closeNodeStart(node, openStart, openEnd) {\n let content = node.content\n if (openStart > 1) {\n let first = closeNodeStart(node.firstChild, openStart - 1, node.childCount == 1 ? openEnd - 1 : 0)\n content = node.content.replaceChild(0, first)\n }\n let fill = node.type.contentMatch.fillBefore(content, openEnd == 0)\n return node.copy(fill.append(content))\n}\n\nfunction closeNodeEnd(node, depth) {\n let content = node.content\n if (depth > 1) {\n let last = closeNodeEnd(node.lastChild, depth - 1)\n content = node.content.replaceChild(node.childCount - 1, last)\n }\n let fill = node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true)\n return node.copy(content.append(fill))\n}\n\nfunction closeFragmentEnd(fragment, depth) {\n return depth ? fragment.replaceChild(fragment.childCount - 1, closeNodeEnd(fragment.lastChild, depth)) : fragment\n}\n\n// :: (number, number, Slice) → this\n// Replace a range of the document with a given slice, using `from`,\n// `to`, and the slice's [`openStart`](#model.Slice.openStart) property\n// as hints, rather than fixed start and end points. This method may\n// grow the replaced area or close open nodes in the slice in order to\n// get a fit that is more in line with WYSIWYG expectations, by\n// dropping fully covered parent nodes of the replaced region when\n// they are marked [non-defining](#model.NodeSpec.defining), or\n// including an open parent node from the slice that _is_ marked as\n// [defining](#model.NodeSpec.defining).\n//\n// This is the method, for example, to handle paste. The similar\n// [`replace`](#transform.Transform.replace) method is a more\n// primitive tool which will _not_ move the start and end of its given\n// range, and is useful in situations where you need more precise\n// control over what happens.\nTransform.prototype.replaceRange = function(from, to, slice) {\n if (!slice.size) return this.deleteRange(from, to)\n\n let $from = this.doc.resolve(from), $to = this.doc.resolve(to)\n if (fitsTrivially($from, $to, slice))\n return this.step(new ReplaceStep(from, to, slice))\n\n let targetDepths = coveredDepths($from, this.doc.resolve(to))\n // Can't replace the whole document, so remove 0 if it's present\n if (targetDepths[targetDepths.length - 1] == 0) targetDepths.pop()\n // Negative numbers represent not expansion over the whole node at\n // that depth, but replacing from $from.before(-D) to $to.pos.\n let preferredTarget = -($from.depth + 1)\n targetDepths.unshift(preferredTarget)\n // This loop picks a preferred target depth, if one of the covering\n // depths is not outside of a defining node, and adds negative\n // depths for any depth that has $from at its start and does not\n // cross a defining node.\n for (let d = $from.depth, pos = $from.pos - 1; d > 0; d--, pos--) {\n let spec = $from.node(d).type.spec\n if (spec.defining || spec.isolating) break\n if (targetDepths.indexOf(d) > -1) preferredTarget = d\n else if ($from.before(d) == pos) targetDepths.splice(1, 0, -d)\n }\n // Try to fit each possible depth of the slice into each possible\n // target depth, starting with the preferred depths.\n let preferredTargetIndex = targetDepths.indexOf(preferredTarget)\n\n let leftNodes = [], preferredDepth = slice.openStart\n for (let content = slice.content, i = 0;; i++) {\n let node = content.firstChild\n leftNodes.push(node)\n if (i == slice.openStart) break\n content = node.content\n }\n // Back up if the node directly above openStart, or the node above\n // that separated only by a non-defining textblock node, is defining.\n if (preferredDepth > 0 && leftNodes[preferredDepth - 1].type.spec.defining &&\n $from.node(preferredTargetIndex).type != leftNodes[preferredDepth - 1].type)\n preferredDepth -= 1\n else if (preferredDepth >= 2 && leftNodes[preferredDepth - 1].isTextblock && leftNodes[preferredDepth - 2].type.spec.defining &&\n $from.node(preferredTargetIndex).type != leftNodes[preferredDepth - 2].type)\n preferredDepth -= 2\n\n for (let j = slice.openStart; j >= 0; j--) {\n let openDepth = (j + preferredDepth + 1) % (slice.openStart + 1)\n let insert = leftNodes[openDepth]\n if (!insert) continue\n for (let i = 0; i < targetDepths.length; i++) {\n // Loop over possible expansion levels, starting with the\n // preferred one\n let targetDepth = targetDepths[(i + preferredTargetIndex) % targetDepths.length], expand = true\n if (targetDepth < 0) { expand = false; targetDepth = -targetDepth }\n let parent = $from.node(targetDepth - 1), index = $from.index(targetDepth - 1)\n if (parent.canReplaceWith(index, index, insert.type, insert.marks))\n return this.replace($from.before(targetDepth), expand ? $to.after(targetDepth) : to,\n new Slice(closeFragment(slice.content, 0, slice.openStart, openDepth),\n openDepth, slice.openEnd))\n }\n }\n\n let startSteps = this.steps.length\n for (let i = targetDepths.length - 1; i >= 0; i--) {\n this.replace(from, to, slice)\n if (this.steps.length > startSteps) break\n let depth = targetDepths[i]\n if (i < 0) continue\n from = $from.before(depth); to = $to.after(depth)\n }\n return this\n}\n\nfunction closeFragment(fragment, depth, oldOpen, newOpen, parent) {\n if (depth < oldOpen) {\n let first = fragment.firstChild\n fragment = fragment.replaceChild(0, first.copy(closeFragment(first.content, depth + 1, oldOpen, newOpen, first)))\n }\n if (depth > newOpen) {\n let match = parent.contentMatchAt(0)\n let start = match.fillBefore(fragment).append(fragment)\n fragment = start.append(match.matchFragment(start).fillBefore(Fragment.empty, true))\n }\n return fragment\n}\n\n// :: (number, number, Node) → this\n// Replace the given range with a node, but use `from` and `to` as\n// hints, rather than precise positions. When from and to are the same\n// and are at the start or end of a parent node in which the given\n// node doesn't fit, this method may _move_ them out towards a parent\n// that does allow the given node to be placed. When the given range\n// completely covers a parent node, this method may completely replace\n// that parent node.\nTransform.prototype.replaceRangeWith = function(from, to, node) {\n if (!node.isInline && from == to && this.doc.resolve(from).parent.content.size) {\n let point = insertPoint(this.doc, from, node.type)\n if (point != null) from = to = point\n }\n return this.replaceRange(from, to, new Slice(Fragment.from(node), 0, 0))\n}\n\n// :: (number, number) → this\n// Delete the given range, expanding it to cover fully covered\n// parent nodes until a valid replace is found.\nTransform.prototype.deleteRange = function(from, to) {\n let $from = this.doc.resolve(from), $to = this.doc.resolve(to)\n let covered = coveredDepths($from, $to)\n for (let i = 0; i < covered.length; i++) {\n let depth = covered[i], last = i == covered.length - 1\n if ((last && depth == 0) || $from.node(depth).type.contentMatch.validEnd)\n return this.delete($from.start(depth), $to.end(depth))\n if (depth > 0 && (last || $from.node(depth - 1).canReplace($from.index(depth - 1), $to.indexAfter(depth - 1))))\n return this.delete($from.before(depth), $to.after(depth))\n }\n for (let d = 1; d <= $from.depth && d <= $to.depth; d++) {\n if (from - $from.start(d) == $from.depth - d && to > $from.end(d) && $to.end(d) - to != $to.depth - d)\n return this.delete($from.before(d), to)\n }\n return this.delete(from, to)\n}\n\n// : (ResolvedPos, ResolvedPos) → [number]\n// Returns an array of all depths for which $from - $to spans the\n// whole content of the nodes at that depth.\nfunction coveredDepths($from, $to) {\n let result = [], minDepth = Math.min($from.depth, $to.depth)\n for (let d = minDepth; d >= 0; d--) {\n let start = $from.start(d)\n if (start < $from.pos - ($from.depth - d) ||\n $to.end(d) > $to.pos + ($to.depth - d) ||\n $from.node(d).type.spec.isolating ||\n $to.node(d).type.spec.isolating) break\n if (start == $to.start(d)) result.push(d)\n }\n return result\n}\n"],"names":["const","let","ReplaceError","super","Slice","slice","Fragment","d","splitting","this","index","MarkType","found","i","joinable"],"mappings":"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"} \ No newline at end of file diff --git a/packages/tiptap-extensions/node_modules/prosemirror-transform/package.json b/packages/tiptap-extensions/node_modules/prosemirror-transform/package.json new file mode 100644 index 0000000000..73ee9d39d5 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-transform/package.json @@ -0,0 +1,35 @@ +{ + "name": "prosemirror-transform", + "version": "1.2.3", + "description": "ProseMirror document transformations", + "main": "dist/index.js", + "module": "dist/index.es.js", + "license": "MIT", + "maintainers": [ + { + "name": "Marijn Haverbeke", + "email": "marijnh@gmail.com", + "web": "http://marijnhaverbeke.nl" + } + ], + "repository": { + "type": "git", + "url": "git://github.com/prosemirror/prosemirror-transform.git" + }, + "dependencies": { + "prosemirror-model": "^1.0.0" + }, + "devDependencies": { + "mocha": "^3.0.2", + "ist": "^1.0.0", + "prosemirror-test-builder": "^1.0.0", + "rollup": "^1.26.3", + "@rollup/plugin-buble": "^0.20.0" + }, + "scripts": { + "test": "mocha test/test-*.js", + "build": "rollup -c", + "watch": "rollup -c -w", + "prepare": "npm run build" + } +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-transform/rollup.config.js b/packages/tiptap-extensions/node_modules/prosemirror-transform/rollup.config.js new file mode 100644 index 0000000000..156b12a278 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-transform/rollup.config.js @@ -0,0 +1,14 @@ +module.exports = { + input: './src/index.js', + output: [{ + file: 'dist/index.js', + format: 'cjs', + sourcemap: true + }, { + file: 'dist/index.es.js', + format: 'es', + sourcemap: true + }], + plugins: [require('@rollup/plugin-buble')()], + external(id) { return !/^[\.\/]/.test(id) } +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-transform/src/README.md b/packages/tiptap-extensions/node_modules/prosemirror-transform/src/README.md new file mode 100644 index 0000000000..757498cbd7 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-transform/src/README.md @@ -0,0 +1,55 @@ +This module defines a way of modifying documents that allows changes +to be recorded, replayed, and reordered. You can read more about +transformations in [the guide](/docs/guide/#transform). + +### Steps + +Transforming happens in `Step`s, which are atomic, well-defined +modifications to a document. [Applying](#transform.Step.apply) a step +produces a new document. + +Each step provides a [change map](#transform.StepMap) that maps +positions in the old document to position in the transformed document. +Steps can be [inverted](#transform.Step.invert) to create a step that +undoes their effect, and chained together in a convenience object +called a [`Transform`](#transform.Transform). + +@Step +@StepResult +@ReplaceStep +@ReplaceAroundStep +@AddMarkStep +@RemoveMarkStep + +### Position Mapping + +Mapping positions from one document to another by running through the +[step maps](#transform.StepMap) produced by steps is an important +operation in ProseMirror. It is used, for example, for updating the +selection when the document changes. + +@Mappable +@MapResult +@StepMap +@Mapping + +### Document transforms + +Because you often need to collect a number of steps together to effect +a composite change, ProseMirror provides an abstraction to make this +easy. [State transactions](#state.Transaction) are a subclass of +transforms. + +@Transform + +The following helper functions can be useful when creating +transformations or determining whether they are even possible. + +@replaceStep +@liftTarget +@findWrapping +@canSplit +@canJoin +@joinPoint +@insertPoint +@dropPoint diff --git a/packages/tiptap-extensions/node_modules/prosemirror-transform/src/index.js b/packages/tiptap-extensions/node_modules/prosemirror-transform/src/index.js new file mode 100644 index 0000000000..b870143729 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-transform/src/index.js @@ -0,0 +1,8 @@ +export {Transform, TransformError} from "./transform" +export {Step, StepResult} from "./step" +export {joinPoint, canJoin, canSplit, insertPoint, dropPoint, liftTarget, findWrapping} from "./structure" +export {StepMap, MapResult, Mapping} from "./map" +export {AddMarkStep, RemoveMarkStep} from "./mark_step" +export {ReplaceStep, ReplaceAroundStep} from "./replace_step" +import "./mark" +export {replaceStep} from "./replace" diff --git a/packages/tiptap-extensions/node_modules/prosemirror-transform/src/map.js b/packages/tiptap-extensions/node_modules/prosemirror-transform/src/map.js new file mode 100644 index 0000000000..257cb0a2ea --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-transform/src/map.js @@ -0,0 +1,271 @@ +// Mappable:: interface +// There are several things that positions can be mapped through. +// Such objects conform to this interface. +// +// map:: (pos: number, assoc: ?number) → number +// Map a position through this object. When given, `assoc` (should +// be -1 or 1, defaults to 1) determines with which side the +// position is associated, which determines in which direction to +// move when a chunk of content is inserted at the mapped position. +// +// mapResult:: (pos: number, assoc: ?number) → MapResult +// Map a position, and return an object containing additional +// information about the mapping. The result's `deleted` field tells +// you whether the position was deleted (completely enclosed in a +// replaced range) during the mapping. When content on only one side +// is deleted, the position itself is only considered deleted when +// `assoc` points in the direction of the deleted content. + +// Recovery values encode a range index and an offset. They are +// represented as numbers, because tons of them will be created when +// mapping, for example, a large number of decorations. The number's +// lower 16 bits provide the index, the remaining bits the offset. +// +// Note: We intentionally don't use bit shift operators to en- and +// decode these, since those clip to 32 bits, which we might in rare +// cases want to overflow. A 64-bit float can represent 48-bit +// integers precisely. + +const lower16 = 0xffff +const factor16 = Math.pow(2, 16) + +function makeRecover(index, offset) { return index + offset * factor16 } +function recoverIndex(value) { return value & lower16 } +function recoverOffset(value) { return (value - (value & lower16)) / factor16 } + +// ::- An object representing a mapped position with extra +// information. +export class MapResult { + constructor(pos, deleted = false, recover = null) { + // :: number The mapped version of the position. + this.pos = pos + // :: bool Tells you whether the position was deleted, that is, + // whether the step removed its surroundings from the document. + this.deleted = deleted + this.recover = recover + } +} + +// :: class extends Mappable +// A map describing the deletions and insertions made by a step, which +// can be used to find the correspondence between positions in the +// pre-step version of a document and the same position in the +// post-step version. +export class StepMap { + // :: ([number]) + // Create a position map. The modifications to the document are + // represented as an array of numbers, in which each group of three + // represents a modified chunk as `[start, oldSize, newSize]`. + constructor(ranges, inverted = false) { + this.ranges = ranges + this.inverted = inverted + } + + recover(value) { + let diff = 0, index = recoverIndex(value) + if (!this.inverted) for (let i = 0; i < index; i++) + diff += this.ranges[i * 3 + 2] - this.ranges[i * 3 + 1] + return this.ranges[index * 3] + diff + recoverOffset(value) + } + + // : (number, ?number) → MapResult + mapResult(pos, assoc = 1) { return this._map(pos, assoc, false) } + + // : (number, ?number) → number + map(pos, assoc = 1) { return this._map(pos, assoc, true) } + + _map(pos, assoc, simple) { + let diff = 0, oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2 + for (let i = 0; i < this.ranges.length; i += 3) { + let start = this.ranges[i] - (this.inverted ? diff : 0) + if (start > pos) break + let oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex], end = start + oldSize + if (pos <= end) { + let side = !oldSize ? assoc : pos == start ? -1 : pos == end ? 1 : assoc + let result = start + diff + (side < 0 ? 0 : newSize) + if (simple) return result + let recover = makeRecover(i / 3, pos - start) + return new MapResult(result, assoc < 0 ? pos != start : pos != end, recover) + } + diff += newSize - oldSize + } + return simple ? pos + diff : new MapResult(pos + diff) + } + + touches(pos, recover) { + let diff = 0, index = recoverIndex(recover) + let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2 + for (let i = 0; i < this.ranges.length; i += 3) { + let start = this.ranges[i] - (this.inverted ? diff : 0) + if (start > pos) break + let oldSize = this.ranges[i + oldIndex], end = start + oldSize + if (pos <= end && i == index * 3) return true + diff += this.ranges[i + newIndex] - oldSize + } + return false + } + + // :: ((oldStart: number, oldEnd: number, newStart: number, newEnd: number)) + // Calls the given function on each of the changed ranges included in + // this map. + forEach(f) { + let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2 + for (let i = 0, diff = 0; i < this.ranges.length; i += 3) { + let start = this.ranges[i], oldStart = start - (this.inverted ? diff : 0), newStart = start + (this.inverted ? 0 : diff) + let oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex] + f(oldStart, oldStart + oldSize, newStart, newStart + newSize) + diff += newSize - oldSize + } + } + + // :: () → StepMap + // Create an inverted version of this map. The result can be used to + // map positions in the post-step document to the pre-step document. + invert() { + return new StepMap(this.ranges, !this.inverted) + } + + toString() { + return (this.inverted ? "-" : "") + JSON.stringify(this.ranges) + } + + // :: (n: number) → StepMap + // Create a map that moves all positions by offset `n` (which may be + // negative). This can be useful when applying steps meant for a + // sub-document to a larger document, or vice-versa. + static offset(n) { + return n == 0 ? StepMap.empty : new StepMap(n < 0 ? [0, -n, 0] : [0, 0, n]) + } +} + +StepMap.empty = new StepMap([]) + +// :: class extends Mappable +// A mapping represents a pipeline of zero or more [step +// maps](#transform.StepMap). It has special provisions for losslessly +// handling mapping positions through a series of steps in which some +// steps are inverted versions of earlier steps. (This comes up when +// ‘[rebasing](/docs/guide/#transform.rebasing)’ steps for +// collaboration or history management.) +export class Mapping { + // :: (?[StepMap]) + // Create a new mapping with the given position maps. + constructor(maps, mirror, from, to) { + // :: [StepMap] + // The step maps in this mapping. + this.maps = maps || [] + // :: number + // The starting position in the `maps` array, used when `map` or + // `mapResult` is called. + this.from = from || 0 + // :: number + // The end position in the `maps` array. + this.to = to == null ? this.maps.length : to + this.mirror = mirror + } + + // :: (?number, ?number) → Mapping + // Create a mapping that maps only through a part of this one. + slice(from = 0, to = this.maps.length) { + return new Mapping(this.maps, this.mirror, from, to) + } + + copy() { + return new Mapping(this.maps.slice(), this.mirror && this.mirror.slice(), this.from, this.to) + } + + // :: (StepMap, ?number) + // Add a step map to the end of this mapping. If `mirrors` is + // given, it should be the index of the step map that is the mirror + // image of this one. + appendMap(map, mirrors) { + this.to = this.maps.push(map) + if (mirrors != null) this.setMirror(this.maps.length - 1, mirrors) + } + + // :: (Mapping) + // Add all the step maps in a given mapping to this one (preserving + // mirroring information). + appendMapping(mapping) { + for (let i = 0, startSize = this.maps.length; i < mapping.maps.length; i++) { + let mirr = mapping.getMirror(i) + this.appendMap(mapping.maps[i], mirr != null && mirr < i ? startSize + mirr : null) + } + } + + // :: (number) → ?number + // Finds the offset of the step map that mirrors the map at the + // given offset, in this mapping (as per the second argument to + // `appendMap`). + getMirror(n) { + if (this.mirror) for (let i = 0; i < this.mirror.length; i++) + if (this.mirror[i] == n) return this.mirror[i + (i % 2 ? -1 : 1)] + } + + setMirror(n, m) { + if (!this.mirror) this.mirror = [] + this.mirror.push(n, m) + } + + // :: (Mapping) + // Append the inverse of the given mapping to this one. + appendMappingInverted(mapping) { + for (let i = mapping.maps.length - 1, totalSize = this.maps.length + mapping.maps.length; i >= 0; i--) { + let mirr = mapping.getMirror(i) + this.appendMap(mapping.maps[i].invert(), mirr != null && mirr > i ? totalSize - mirr - 1 : null) + } + } + + // :: () → Mapping + // Create an inverted version of this mapping. + invert() { + let inverse = new Mapping + inverse.appendMappingInverted(this) + return inverse + } + + // : (number, ?number) → number + // Map a position through this mapping. + map(pos, assoc = 1) { + if (this.mirror) return this._map(pos, assoc, true) + for (let i = this.from; i < this.to; i++) + pos = this.maps[i].map(pos, assoc) + return pos + } + + // : (number, ?number) → MapResult + // Map a position through this mapping, returning a mapping + // result. + mapResult(pos, assoc = 1) { return this._map(pos, assoc, false) } + + _map(pos, assoc, simple) { + let deleted = false, recoverables = null + + for (let i = this.from; i < this.to; i++) { + let map = this.maps[i], rec = recoverables && recoverables[i] + if (rec != null && map.touches(pos, rec)) { + pos = map.recover(rec) + continue + } + + let result = map.mapResult(pos, assoc) + if (result.recover != null) { + let corr = this.getMirror(i) + if (corr != null && corr > i && corr < this.to) { + if (result.deleted) { + i = corr + pos = this.maps[corr].recover(result.recover) + continue + } else { + ;(recoverables || (recoverables = Object.create(null)))[corr] = result.recover + } + } + } + + if (result.deleted) deleted = true + pos = result.pos + } + + return simple ? pos : new MapResult(pos, deleted) + } +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-transform/src/mark.js b/packages/tiptap-extensions/node_modules/prosemirror-transform/src/mark.js new file mode 100644 index 0000000000..2cdbccb5b0 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-transform/src/mark.js @@ -0,0 +1,105 @@ +import {MarkType, Slice, Fragment} from "prosemirror-model" + +import {Transform} from "./transform" +import {AddMarkStep, RemoveMarkStep} from "./mark_step" +import {ReplaceStep} from "./replace_step" + +// :: (number, number, Mark) → this +// Add the given mark to the inline content between `from` and `to`. +Transform.prototype.addMark = function(from, to, mark) { + let removed = [], added = [], removing = null, adding = null + this.doc.nodesBetween(from, to, (node, pos, parent) => { + if (!node.isInline) return + let marks = node.marks + if (!mark.isInSet(marks) && parent.type.allowsMarkType(mark.type)) { + let start = Math.max(pos, from), end = Math.min(pos + node.nodeSize, to) + let newSet = mark.addToSet(marks) + + for (let i = 0; i < marks.length; i++) { + if (!marks[i].isInSet(newSet)) { + if (removing && removing.to == start && removing.mark.eq(marks[i])) + removing.to = end + else + removed.push(removing = new RemoveMarkStep(start, end, marks[i])) + } + } + + if (adding && adding.to == start) + adding.to = end + else + added.push(adding = new AddMarkStep(start, end, mark)) + } + }) + + removed.forEach(s => this.step(s)) + added.forEach(s => this.step(s)) + return this +} + +// :: (number, number, ?union) → this +// Remove marks from inline nodes between `from` and `to`. When `mark` +// is a single mark, remove precisely that mark. When it is a mark type, +// remove all marks of that type. When it is null, remove all marks of +// any type. +Transform.prototype.removeMark = function(from, to, mark = null) { + let matched = [], step = 0 + this.doc.nodesBetween(from, to, (node, pos) => { + if (!node.isInline) return + step++ + let toRemove = null + if (mark instanceof MarkType) { + let found = mark.isInSet(node.marks) + if (found) toRemove = [found] + } else if (mark) { + if (mark.isInSet(node.marks)) toRemove = [mark] + } else { + toRemove = node.marks + } + if (toRemove && toRemove.length) { + let end = Math.min(pos + node.nodeSize, to) + for (let i = 0; i < toRemove.length; i++) { + let style = toRemove[i], found + for (let j = 0; j < matched.length; j++) { + let m = matched[j] + if (m.step == step - 1 && style.eq(matched[j].style)) found = m + } + if (found) { + found.to = end + found.step = step + } else { + matched.push({style, from: Math.max(pos, from), to: end, step}) + } + } + } + }) + matched.forEach(m => this.step(new RemoveMarkStep(m.from, m.to, m.style))) + return this +} + +// :: (number, NodeType, ?ContentMatch) → this +// Removes all marks and nodes from the content of the node at `pos` +// that don't match the given new parent node type. Accepts an +// optional starting [content match](#model.ContentMatch) as third +// argument. +Transform.prototype.clearIncompatible = function(pos, parentType, match = parentType.contentMatch) { + let node = this.doc.nodeAt(pos) + let delSteps = [], cur = pos + 1 + for (let i = 0; i < node.childCount; i++) { + let child = node.child(i), end = cur + child.nodeSize + let allowed = match.matchType(child.type, child.attrs) + if (!allowed) { + delSteps.push(new ReplaceStep(cur, end, Slice.empty)) + } else { + match = allowed + for (let j = 0; j < child.marks.length; j++) if (!parentType.allowsMarkType(child.marks[j].type)) + this.step(new RemoveMarkStep(cur, end, child.marks[j])) + } + cur = end + } + if (!match.validEnd) { + let fill = match.fillBefore(Fragment.empty, true) + this.replace(cur, cur, new Slice(fill, 0, 0)) + } + for (let i = delSteps.length - 1; i >= 0; i--) this.step(delSteps[i]) + return this +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-transform/src/mark_step.js b/packages/tiptap-extensions/node_modules/prosemirror-transform/src/mark_step.js new file mode 100644 index 0000000000..76d7533753 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-transform/src/mark_step.js @@ -0,0 +1,115 @@ +import {Fragment, Slice} from "prosemirror-model" +import {Step, StepResult} from "./step" + +function mapFragment(fragment, f, parent) { + let mapped = [] + for (let i = 0; i < fragment.childCount; i++) { + let child = fragment.child(i) + if (child.content.size) child = child.copy(mapFragment(child.content, f, child)) + if (child.isInline) child = f(child, parent, i) + mapped.push(child) + } + return Fragment.fromArray(mapped) +} + +// ::- Add a mark to all inline content between two positions. +export class AddMarkStep extends Step { + // :: (number, number, Mark) + constructor(from, to, mark) { + super() + this.from = from + this.to = to + this.mark = mark + } + + apply(doc) { + let oldSlice = doc.slice(this.from, this.to), $from = doc.resolve(this.from) + let parent = $from.node($from.sharedDepth(this.to)) + let slice = new Slice(mapFragment(oldSlice.content, (node, parent) => { + if (!parent.type.allowsMarkType(this.mark.type)) return node + return node.mark(this.mark.addToSet(node.marks)) + }, parent), oldSlice.openStart, oldSlice.openEnd) + return StepResult.fromReplace(doc, this.from, this.to, slice) + } + + invert() { + return new RemoveMarkStep(this.from, this.to, this.mark) + } + + map(mapping) { + let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1) + if (from.deleted && to.deleted || from.pos >= to.pos) return null + return new AddMarkStep(from.pos, to.pos, this.mark) + } + + merge(other) { + if (other instanceof AddMarkStep && + other.mark.eq(this.mark) && + this.from <= other.to && this.to >= other.from) + return new AddMarkStep(Math.min(this.from, other.from), + Math.max(this.to, other.to), this.mark) + } + + toJSON() { + return {stepType: "addMark", mark: this.mark.toJSON(), + from: this.from, to: this.to} + } + + static fromJSON(schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + throw new RangeError("Invalid input for AddMarkStep.fromJSON") + return new AddMarkStep(json.from, json.to, schema.markFromJSON(json.mark)) + } +} + +Step.jsonID("addMark", AddMarkStep) + +// ::- Remove a mark from all inline content between two positions. +export class RemoveMarkStep extends Step { + // :: (number, number, Mark) + constructor(from, to, mark) { + super() + this.from = from + this.to = to + this.mark = mark + } + + apply(doc) { + let oldSlice = doc.slice(this.from, this.to) + let slice = new Slice(mapFragment(oldSlice.content, node => { + return node.mark(this.mark.removeFromSet(node.marks)) + }), oldSlice.openStart, oldSlice.openEnd) + return StepResult.fromReplace(doc, this.from, this.to, slice) + } + + invert() { + return new AddMarkStep(this.from, this.to, this.mark) + } + + map(mapping) { + let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1) + if (from.deleted && to.deleted || from.pos >= to.pos) return null + return new RemoveMarkStep(from.pos, to.pos, this.mark) + } + + merge(other) { + if (other instanceof RemoveMarkStep && + other.mark.eq(this.mark) && + this.from <= other.to && this.to >= other.from) + return new RemoveMarkStep(Math.min(this.from, other.from), + Math.max(this.to, other.to), this.mark) + } + + toJSON() { + return {stepType: "removeMark", mark: this.mark.toJSON(), + from: this.from, to: this.to} + } + + static fromJSON(schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + throw new RangeError("Invalid input for RemoveMarkStep.fromJSON") + return new RemoveMarkStep(json.from, json.to, schema.markFromJSON(json.mark)) + } +} + +Step.jsonID("removeMark", RemoveMarkStep) diff --git a/packages/tiptap-extensions/node_modules/prosemirror-transform/src/replace.js b/packages/tiptap-extensions/node_modules/prosemirror-transform/src/replace.js new file mode 100644 index 0000000000..3da9f658ba --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-transform/src/replace.js @@ -0,0 +1,550 @@ +import {Fragment, Slice} from "prosemirror-model" + +import {ReplaceStep, ReplaceAroundStep} from "./replace_step" +import {Transform} from "./transform" +import {insertPoint} from "./structure" + +// :: (Node, number, ?number, ?Slice) → ?Step +// ‘Fit’ a slice into a given position in the document, producing a +// [step](#transform.Step) that inserts it. Will return null if +// there's no meaningful way to insert the slice here, or inserting it +// would be a no-op (an empty slice over an empty range). +export function replaceStep(doc, from, to = from, slice = Slice.empty) { + if (from == to && !slice.size) return null + + let $from = doc.resolve(from), $to = doc.resolve(to) + // Optimization -- avoid work if it's obvious that it's not needed. + if (fitsTrivially($from, $to, slice)) return new ReplaceStep(from, to, slice) + let placed = placeSlice($from, slice) + + let fittedLeft = fitLeft($from, placed) + let fitted = fitRight($from, $to, fittedLeft) + if (!fitted) return null + if (fittedLeft.size != fitted.size && canMoveText($from, $to, fittedLeft)) { + let d = $to.depth, after = $to.after(d) + while (d > 1 && after == $to.end(--d)) ++after + let fittedAfter = fitRight($from, doc.resolve(after), fittedLeft) + if (fittedAfter) + return new ReplaceAroundStep(from, after, to, $to.end(), fittedAfter, fittedLeft.size) + } + return fitted.size || from != to ? new ReplaceStep(from, to, fitted) : null +} + +// :: (number, ?number, ?Slice) → this +// Replace the part of the document between `from` and `to` with the +// given `slice`. +Transform.prototype.replace = function(from, to = from, slice = Slice.empty) { + let step = replaceStep(this.doc, from, to, slice) + if (step) this.step(step) + return this +} + +// :: (number, number, union) → this +// Replace the given range with the given content, which may be a +// fragment, node, or array of nodes. +Transform.prototype.replaceWith = function(from, to, content) { + return this.replace(from, to, new Slice(Fragment.from(content), 0, 0)) +} + +// :: (number, number) → this +// Delete the content between the given positions. +Transform.prototype.delete = function(from, to) { + return this.replace(from, to, Slice.empty) +} + +// :: (number, union) → this +// Insert the given content at the given position. +Transform.prototype.insert = function(pos, content) { + return this.replaceWith(pos, pos, content) +} + + + +function fitLeftInner($from, depth, placed, placedBelow) { + let content = Fragment.empty, openEnd = 0, placedHere = placed[depth] + if ($from.depth > depth) { + let inner = fitLeftInner($from, depth + 1, placed, placedBelow || placedHere) + openEnd = inner.openEnd + 1 + content = Fragment.from($from.node(depth + 1).copy(inner.content)) + } + + if (placedHere) { + content = content.append(placedHere.content) + openEnd = placedHere.openEnd + } + if (placedBelow) { + content = content.append($from.node(depth).contentMatchAt($from.indexAfter(depth)).fillBefore(Fragment.empty, true)) + openEnd = 0 + } + + return {content, openEnd} +} + +function fitLeft($from, placed) { + let {content, openEnd} = fitLeftInner($from, 0, placed, false) + return new Slice(content, $from.depth, openEnd || 0) +} + +function fitRightJoin(content, parent, $from, $to, depth, openStart, openEnd) { + let match, count = content.childCount, matchCount = count - (openEnd > 0 ? 1 : 0) + let parentNode = openStart < 0 ? parent : $from.node(depth) + if (openStart < 0) + match = parentNode.contentMatchAt(matchCount) + else if (count == 1 && openEnd > 0) + match = parentNode.contentMatchAt(openStart ? $from.index(depth) : $from.indexAfter(depth)) + else + match = parentNode.contentMatchAt($from.indexAfter(depth)) + .matchFragment(content, count > 0 && openStart ? 1 : 0, matchCount) + + let toNode = $to.node(depth) + if (openEnd > 0 && depth < $to.depth) { + let after = toNode.content.cutByIndex($to.indexAfter(depth)).addToStart(content.lastChild) + let joinable = match.fillBefore(after, true) + // Can't insert content if there's a single node stretched across this gap + if (joinable && joinable.size && openStart > 0 && count == 1) joinable = null + + if (joinable) { + let inner = fitRightJoin(content.lastChild.content, content.lastChild, $from, $to, + depth + 1, count == 1 ? openStart - 1 : -1, openEnd - 1) + if (inner) { + let last = content.lastChild.copy(inner) + if (joinable.size) + return content.cutByIndex(0, count - 1).append(joinable).addToEnd(last) + else + return content.replaceChild(count - 1, last) + } + } + } + if (openEnd > 0) + match = match.matchType((count == 1 && openStart > 0 ? $from.node(depth + 1) : content.lastChild).type) + + // If we're here, the next level can't be joined, so we see what + // happens if we leave it open. + let toIndex = $to.index(depth) + if (toIndex == toNode.childCount && !toNode.type.compatibleContent(parent.type)) return null + let joinable = match.fillBefore(toNode.content, true, toIndex) + for (let i = toIndex; joinable && i < toNode.content.childCount; i++) + if (!parentNode.type.allowsMarks(toNode.content.child(i).marks)) joinable = null + if (!joinable) return null + + if (openEnd > 0) { + let closed = fitRightClosed(content.lastChild, openEnd - 1, $from, depth + 1, + count == 1 ? openStart - 1 : -1) + content = content.replaceChild(count - 1, closed) + } + content = content.append(joinable) + if ($to.depth > depth) + content = content.addToEnd(fitRightSeparate($to, depth + 1)) + return content +} + +function fitRightClosed(node, openEnd, $from, depth, openStart) { + let match, content = node.content, count = content.childCount + if (openStart >= 0) + match = $from.node(depth).contentMatchAt($from.indexAfter(depth)) + .matchFragment(content, openStart > 0 ? 1 : 0, count) + else + match = node.contentMatchAt(count) + + if (openEnd > 0) { + let closed = fitRightClosed(content.lastChild, openEnd - 1, $from, depth + 1, + count == 1 ? openStart - 1 : -1) + content = content.replaceChild(count - 1, closed) + } + + return node.copy(content.append(match.fillBefore(Fragment.empty, true))) +} + +function fitRightSeparate($to, depth) { + let node = $to.node(depth) + let fill = node.contentMatchAt(0).fillBefore(node.content, true, $to.index(depth)) + if ($to.depth > depth) fill = fill.addToEnd(fitRightSeparate($to, depth + 1)) + return node.copy(fill) +} + +function normalizeSlice(content, openStart, openEnd) { + while (openStart > 0 && openEnd > 0 && content.childCount == 1) { + content = content.firstChild.content + openStart-- + openEnd-- + } + return new Slice(content, openStart, openEnd) +} + +// : (ResolvedPos, ResolvedPos, number, Slice) → Slice +function fitRight($from, $to, slice) { + let fitted = fitRightJoin(slice.content, $from.node(0), $from, $to, 0, slice.openStart, slice.openEnd) + if (!fitted) return null + return normalizeSlice(fitted, slice.openStart, $to.depth) +} + +function fitsTrivially($from, $to, slice) { + return !slice.openStart && !slice.openEnd && $from.start() == $to.start() && + $from.parent.canReplace($from.index(), $to.index(), slice.content) +} + +function canMoveText($from, $to, slice) { + if (!$to.parent.isTextblock) return false + + let parent = slice.openEnd ? nodeRight(slice.content, slice.openEnd) + : $from.node($from.depth - (slice.openStart - slice.openEnd)) + if (!parent.isTextblock) return false + for (let i = $to.index(); i < $to.parent.childCount; i++) + if (!parent.type.allowsMarks($to.parent.child(i).marks)) return false + let match + if (slice.openEnd) { + match = parent.contentMatchAt(parent.childCount) + } else { + match = parent.contentMatchAt(parent.childCount) + if (slice.size) match = match.matchFragment(slice.content, slice.openStart ? 1 : 0) + } + match = match.matchFragment($to.parent.content, $to.index()) + return match && match.validEnd +} + +function nodeRight(content, depth) { + for (let i = 1; i < depth; i++) content = content.lastChild.content + return content.lastChild +} + +// Algorithm for 'placing' the elements of a slice into a gap: +// +// We consider the content of each node that is open to the left to be +// independently placeable. I.e. in , when the +// paragraph on the left is open, "foo" can be placed (somewhere on +// the left side of the replacement gap) independently from p("bar"). +// +// So placeSlice splits up a slice into a number of sub-slices, +// along with information on where they can be placed on the given +// left-side edge. It works by walking the open side of the slice, +// from the inside out, and trying to find a landing spot for each +// element, by simultaneously scanning over the gap side. When no +// place is found for an open node's content, it is left in that node. + +// : (ResolvedPos, Slice) → [{content: Fragment, openEnd: number, depth: number}] +function placeSlice($from, slice) { + let frontier = new Frontier($from) + for (let pass = 1; slice.size && pass <= 3; pass++) { + let value = frontier.placeSlice(slice.content, slice.openStart, slice.openEnd, pass) + if (pass == 3 && value != slice && value.size) pass = 0 // Restart if the 3rd pass made progress but left content + slice = value + } + while (frontier.open.length) frontier.closeNode() + return frontier.placed +} + +// Helper class that models the open side of the insert position, +// keeping track of the content match and already inserted content +// at each depth. +class Frontier { + constructor($pos) { + // : [{parent: Node, match: ContentMatch, content: Fragment, wrapper: bool, openEnd: number, depth: number}] + this.open = [] + for (let d = 0; d <= $pos.depth; d++) { + let parent = $pos.node(d), match = parent.contentMatchAt($pos.indexAfter(d)) + this.open.push({parent, match, content: Fragment.empty, wrapper: false, openEnd: 0, depth: d}) + } + this.placed = [] + } + + // : (Fragment, number, number, number, ?Node) → Slice + // Tries to place the content of the given slice, and returns a + // slice containing unplaced content. + // + // pass 1: try to fit directly + // pass 2: allow wrapper nodes to be introduced + // pass 3: allow unwrapping of nodes that aren't open + placeSlice(fragment, openStart, openEnd, pass, parent) { + if (openStart > 0) { + let first = fragment.firstChild + let inner = this.placeSlice(first.content, Math.max(0, openStart - 1), + openEnd && fragment.childCount == 1 ? openEnd - 1 : 0, + pass, first) + if (inner.content != first.content) { + if (inner.content.size) { + fragment = fragment.replaceChild(0, first.copy(inner.content)) + openStart = inner.openStart + 1 + } else { + if (fragment.childCount == 1) openEnd = 0 + fragment = fragment.cutByIndex(1) + openStart = 0 + } + } + } + let result = this.placeContent(fragment, openStart, openEnd, pass, parent) + if (pass > 2 && result.size && openStart == 0) { + let child = result.content.firstChild, single = result.content.childCount == 1 + this.placeContent(child.content, 0, openEnd && single ? openEnd - 1 : 0, pass, child) + result = single ? Fragment.empty : new Slice(result.content.cutByIndex(1), 0, openEnd) + } + return result + } + + placeContent(fragment, openStart, openEnd, pass, parent) { + let i = 0 + // Go over the fragment's children + for (; i < fragment.childCount; i++) { + let child = fragment.child(i), placed = false, last = i == fragment.childCount - 1 + // Try each open node in turn, starting from the innermost + for (let d = this.open.length - 1; d >= 0; d--) { + let open = this.open[d], wrap + + // If pass > 1, it is allowed to wrap the node to help find a + // fit, so if findWrapping returns something, we add open + // nodes to the frontier for that wrapping. + if (pass > 1 && (wrap = open.match.findWrapping(child.type)) && + !(parent && wrap.length && wrap[wrap.length - 1] == parent.type)) { + while (this.open.length - 1 > d) this.closeNode() + for (let w = 0; w < wrap.length; w++) { + open.match = open.match.matchType(wrap[w]) + d++ + open = {parent: wrap[w].create(), + match: wrap[w].contentMatch, + content: Fragment.empty, wrapper: true, openEnd: 0, depth: d + w} + this.open.push(open) + } + } + + // See if the child fits here + let match = open.match.matchType(child.type) + if (!match) { + let fill = open.match.fillBefore(Fragment.from(child)) + if (fill) { + for (let j = 0; j < fill.childCount; j++) { + let ch = fill.child(j) + this.addNode(open, ch, 0) + match = open.match.matchFragment(ch) + } + } else if (parent && open.match.matchType(parent.type)) { + // Don't continue looking further up if the parent node + // would fit here. + break + } else { + continue + } + } + + // Close open nodes above this one, since we're starting to + // add to this. + while (this.open.length - 1 > d) this.closeNode() + // Strip marks from the child or close its start when necessary + child = child.mark(open.parent.type.allowedMarks(child.marks)) + if (openStart) { + child = closeNodeStart(child, openStart, last ? openEnd : 0) + openStart = 0 + } + // Add the child to this open node and adjust its metadata + this.addNode(open, child, last ? openEnd : 0) + open.match = match + if (last) openEnd = 0 + placed = true + break + } + // As soon as we've failed to place a node we stop looking at + // later nodes + if (!placed) break + } + // Close the current open node if it's not the the root and we + // either placed up to the end of the node or the the current + // slice depth's node type matches the open node's type + if (this.open.length > 1 && + (i > 0 && i == fragment.childCount || + parent && this.open[this.open.length - 1].parent.type == parent.type)) + this.closeNode() + + return new Slice(fragment.cutByIndex(i), openStart, openEnd) + } + + addNode(open, node, openEnd) { + open.content = closeFragmentEnd(open.content, open.openEnd).addToEnd(node) + open.openEnd = openEnd + } + + closeNode() { + let open = this.open.pop() + if (open.content.size == 0) { + // Nothing here + } else if (open.wrapper) { + this.addNode(this.open[this.open.length - 1], open.parent.copy(open.content), open.openEnd + 1) + } else { + this.placed[open.depth] = {depth: open.depth, content: open.content, openEnd: open.openEnd} + } + } +} + +function closeNodeStart(node, openStart, openEnd) { + let content = node.content + if (openStart > 1) { + let first = closeNodeStart(node.firstChild, openStart - 1, node.childCount == 1 ? openEnd - 1 : 0) + content = node.content.replaceChild(0, first) + } + let fill = node.type.contentMatch.fillBefore(content, openEnd == 0) + return node.copy(fill.append(content)) +} + +function closeNodeEnd(node, depth) { + let content = node.content + if (depth > 1) { + let last = closeNodeEnd(node.lastChild, depth - 1) + content = node.content.replaceChild(node.childCount - 1, last) + } + let fill = node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true) + return node.copy(content.append(fill)) +} + +function closeFragmentEnd(fragment, depth) { + return depth ? fragment.replaceChild(fragment.childCount - 1, closeNodeEnd(fragment.lastChild, depth)) : fragment +} + +// :: (number, number, Slice) → this +// Replace a range of the document with a given slice, using `from`, +// `to`, and the slice's [`openStart`](#model.Slice.openStart) property +// as hints, rather than fixed start and end points. This method may +// grow the replaced area or close open nodes in the slice in order to +// get a fit that is more in line with WYSIWYG expectations, by +// dropping fully covered parent nodes of the replaced region when +// they are marked [non-defining](#model.NodeSpec.defining), or +// including an open parent node from the slice that _is_ marked as +// [defining](#model.NodeSpec.defining). +// +// This is the method, for example, to handle paste. The similar +// [`replace`](#transform.Transform.replace) method is a more +// primitive tool which will _not_ move the start and end of its given +// range, and is useful in situations where you need more precise +// control over what happens. +Transform.prototype.replaceRange = function(from, to, slice) { + if (!slice.size) return this.deleteRange(from, to) + + let $from = this.doc.resolve(from), $to = this.doc.resolve(to) + if (fitsTrivially($from, $to, slice)) + return this.step(new ReplaceStep(from, to, slice)) + + let targetDepths = coveredDepths($from, this.doc.resolve(to)) + // Can't replace the whole document, so remove 0 if it's present + if (targetDepths[targetDepths.length - 1] == 0) targetDepths.pop() + // Negative numbers represent not expansion over the whole node at + // that depth, but replacing from $from.before(-D) to $to.pos. + let preferredTarget = -($from.depth + 1) + targetDepths.unshift(preferredTarget) + // This loop picks a preferred target depth, if one of the covering + // depths is not outside of a defining node, and adds negative + // depths for any depth that has $from at its start and does not + // cross a defining node. + for (let d = $from.depth, pos = $from.pos - 1; d > 0; d--, pos--) { + let spec = $from.node(d).type.spec + if (spec.defining || spec.isolating) break + if (targetDepths.indexOf(d) > -1) preferredTarget = d + else if ($from.before(d) == pos) targetDepths.splice(1, 0, -d) + } + // Try to fit each possible depth of the slice into each possible + // target depth, starting with the preferred depths. + let preferredTargetIndex = targetDepths.indexOf(preferredTarget) + + let leftNodes = [], preferredDepth = slice.openStart + for (let content = slice.content, i = 0;; i++) { + let node = content.firstChild + leftNodes.push(node) + if (i == slice.openStart) break + content = node.content + } + // Back up if the node directly above openStart, or the node above + // that separated only by a non-defining textblock node, is defining. + if (preferredDepth > 0 && leftNodes[preferredDepth - 1].type.spec.defining && + $from.node(preferredTargetIndex).type != leftNodes[preferredDepth - 1].type) + preferredDepth -= 1 + else if (preferredDepth >= 2 && leftNodes[preferredDepth - 1].isTextblock && leftNodes[preferredDepth - 2].type.spec.defining && + $from.node(preferredTargetIndex).type != leftNodes[preferredDepth - 2].type) + preferredDepth -= 2 + + for (let j = slice.openStart; j >= 0; j--) { + let openDepth = (j + preferredDepth + 1) % (slice.openStart + 1) + let insert = leftNodes[openDepth] + if (!insert) continue + for (let i = 0; i < targetDepths.length; i++) { + // Loop over possible expansion levels, starting with the + // preferred one + let targetDepth = targetDepths[(i + preferredTargetIndex) % targetDepths.length], expand = true + if (targetDepth < 0) { expand = false; targetDepth = -targetDepth } + let parent = $from.node(targetDepth - 1), index = $from.index(targetDepth - 1) + if (parent.canReplaceWith(index, index, insert.type, insert.marks)) + return this.replace($from.before(targetDepth), expand ? $to.after(targetDepth) : to, + new Slice(closeFragment(slice.content, 0, slice.openStart, openDepth), + openDepth, slice.openEnd)) + } + } + + let startSteps = this.steps.length + for (let i = targetDepths.length - 1; i >= 0; i--) { + this.replace(from, to, slice) + if (this.steps.length > startSteps) break + let depth = targetDepths[i] + if (i < 0) continue + from = $from.before(depth); to = $to.after(depth) + } + return this +} + +function closeFragment(fragment, depth, oldOpen, newOpen, parent) { + if (depth < oldOpen) { + let first = fragment.firstChild + fragment = fragment.replaceChild(0, first.copy(closeFragment(first.content, depth + 1, oldOpen, newOpen, first))) + } + if (depth > newOpen) { + let match = parent.contentMatchAt(0) + let start = match.fillBefore(fragment).append(fragment) + fragment = start.append(match.matchFragment(start).fillBefore(Fragment.empty, true)) + } + return fragment +} + +// :: (number, number, Node) → this +// Replace the given range with a node, but use `from` and `to` as +// hints, rather than precise positions. When from and to are the same +// and are at the start or end of a parent node in which the given +// node doesn't fit, this method may _move_ them out towards a parent +// that does allow the given node to be placed. When the given range +// completely covers a parent node, this method may completely replace +// that parent node. +Transform.prototype.replaceRangeWith = function(from, to, node) { + if (!node.isInline && from == to && this.doc.resolve(from).parent.content.size) { + let point = insertPoint(this.doc, from, node.type) + if (point != null) from = to = point + } + return this.replaceRange(from, to, new Slice(Fragment.from(node), 0, 0)) +} + +// :: (number, number) → this +// Delete the given range, expanding it to cover fully covered +// parent nodes until a valid replace is found. +Transform.prototype.deleteRange = function(from, to) { + let $from = this.doc.resolve(from), $to = this.doc.resolve(to) + let covered = coveredDepths($from, $to) + for (let i = 0; i < covered.length; i++) { + let depth = covered[i], last = i == covered.length - 1 + if ((last && depth == 0) || $from.node(depth).type.contentMatch.validEnd) + return this.delete($from.start(depth), $to.end(depth)) + if (depth > 0 && (last || $from.node(depth - 1).canReplace($from.index(depth - 1), $to.indexAfter(depth - 1)))) + return this.delete($from.before(depth), $to.after(depth)) + } + for (let d = 1; d <= $from.depth && d <= $to.depth; d++) { + if (from - $from.start(d) == $from.depth - d && to > $from.end(d) && $to.end(d) - to != $to.depth - d) + return this.delete($from.before(d), to) + } + return this.delete(from, to) +} + +// : (ResolvedPos, ResolvedPos) → [number] +// Returns an array of all depths for which $from - $to spans the +// whole content of the nodes at that depth. +function coveredDepths($from, $to) { + let result = [], minDepth = Math.min($from.depth, $to.depth) + for (let d = minDepth; d >= 0; d--) { + let start = $from.start(d) + if (start < $from.pos - ($from.depth - d) || + $to.end(d) > $to.pos + ($to.depth - d) || + $from.node(d).type.spec.isolating || + $to.node(d).type.spec.isolating) break + if (start == $to.start(d)) result.push(d) + } + return result +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-transform/src/replace_step.js b/packages/tiptap-extensions/node_modules/prosemirror-transform/src/replace_step.js new file mode 100644 index 0000000000..ac3840cb35 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-transform/src/replace_step.js @@ -0,0 +1,163 @@ +import {Slice} from "prosemirror-model" + +import {Step, StepResult} from "./step" +import {StepMap} from "./map" + +// ::- Replace a part of the document with a slice of new content. +export class ReplaceStep extends Step { + // :: (number, number, Slice, ?bool) + // The given `slice` should fit the 'gap' between `from` and + // `to`—the depths must line up, and the surrounding nodes must be + // able to be joined with the open sides of the slice. When + // `structure` is true, the step will fail if the content between + // from and to is not just a sequence of closing and then opening + // tokens (this is to guard against rebased replace steps + // overwriting something they weren't supposed to). + constructor(from, to, slice, structure) { + super() + this.from = from + this.to = to + this.slice = slice + this.structure = !!structure + } + + apply(doc) { + if (this.structure && contentBetween(doc, this.from, this.to)) + return StepResult.fail("Structure replace would overwrite content") + return StepResult.fromReplace(doc, this.from, this.to, this.slice) + } + + getMap() { + return new StepMap([this.from, this.to - this.from, this.slice.size]) + } + + invert(doc) { + return new ReplaceStep(this.from, this.from + this.slice.size, doc.slice(this.from, this.to)) + } + + map(mapping) { + let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1) + if (from.deleted && to.deleted) return null + return new ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice) + } + + merge(other) { + if (!(other instanceof ReplaceStep) || other.structure != this.structure) return null + + if (this.from + this.slice.size == other.from && !this.slice.openEnd && !other.slice.openStart) { + let slice = this.slice.size + other.slice.size == 0 ? Slice.empty + : new Slice(this.slice.content.append(other.slice.content), this.slice.openStart, other.slice.openEnd) + return new ReplaceStep(this.from, this.to + (other.to - other.from), slice, this.structure) + } else if (other.to == this.from && !this.slice.openStart && !other.slice.openEnd) { + let slice = this.slice.size + other.slice.size == 0 ? Slice.empty + : new Slice(other.slice.content.append(this.slice.content), other.slice.openStart, this.slice.openEnd) + return new ReplaceStep(other.from, this.to, slice, this.structure) + } else { + return null + } + } + + toJSON() { + let json = {stepType: "replace", from: this.from, to: this.to} + if (this.slice.size) json.slice = this.slice.toJSON() + if (this.structure) json.structure = true + return json + } + + static fromJSON(schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + throw new RangeError("Invalid input for ReplaceStep.fromJSON") + return new ReplaceStep(json.from, json.to, Slice.fromJSON(schema, json.slice), !!json.structure) + } +} + +Step.jsonID("replace", ReplaceStep) + +// ::- Replace a part of the document with a slice of content, but +// preserve a range of the replaced content by moving it into the +// slice. +export class ReplaceAroundStep extends Step { + // :: (number, number, number, number, Slice, number, ?bool) + // Create a replace-around step with the given range and gap. + // `insert` should be the point in the slice into which the content + // of the gap should be moved. `structure` has the same meaning as + // it has in the [`ReplaceStep`](#transform.ReplaceStep) class. + constructor(from, to, gapFrom, gapTo, slice, insert, structure) { + super() + this.from = from + this.to = to + this.gapFrom = gapFrom + this.gapTo = gapTo + this.slice = slice + this.insert = insert + this.structure = !!structure + } + + apply(doc) { + if (this.structure && (contentBetween(doc, this.from, this.gapFrom) || + contentBetween(doc, this.gapTo, this.to))) + return StepResult.fail("Structure gap-replace would overwrite content") + + let gap = doc.slice(this.gapFrom, this.gapTo) + if (gap.openStart || gap.openEnd) + return StepResult.fail("Gap is not a flat range") + let inserted = this.slice.insertAt(this.insert, gap.content) + if (!inserted) return StepResult.fail("Content does not fit in gap") + return StepResult.fromReplace(doc, this.from, this.to, inserted) + } + + getMap() { + return new StepMap([this.from, this.gapFrom - this.from, this.insert, + this.gapTo, this.to - this.gapTo, this.slice.size - this.insert]) + } + + invert(doc) { + let gap = this.gapTo - this.gapFrom + return new ReplaceAroundStep(this.from, this.from + this.slice.size + gap, + this.from + this.insert, this.from + this.insert + gap, + doc.slice(this.from, this.to).removeBetween(this.gapFrom - this.from, this.gapTo - this.from), + this.gapFrom - this.from, this.structure) + } + + map(mapping) { + let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1) + let gapFrom = mapping.map(this.gapFrom, -1), gapTo = mapping.map(this.gapTo, 1) + if ((from.deleted && to.deleted) || gapFrom < from.pos || gapTo > to.pos) return null + return new ReplaceAroundStep(from.pos, to.pos, gapFrom, gapTo, this.slice, this.insert, this.structure) + } + + toJSON() { + let json = {stepType: "replaceAround", from: this.from, to: this.to, + gapFrom: this.gapFrom, gapTo: this.gapTo, insert: this.insert} + if (this.slice.size) json.slice = this.slice.toJSON() + if (this.structure) json.structure = true + return json + } + + static fromJSON(schema, json) { + if (typeof json.from != "number" || typeof json.to != "number" || + typeof json.gapFrom != "number" || typeof json.gapTo != "number" || typeof json.insert != "number") + throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON") + return new ReplaceAroundStep(json.from, json.to, json.gapFrom, json.gapTo, + Slice.fromJSON(schema, json.slice), json.insert, !!json.structure) + } +} + +Step.jsonID("replaceAround", ReplaceAroundStep) + +function contentBetween(doc, from, to) { + let $from = doc.resolve(from), dist = to - from, depth = $from.depth + while (dist > 0 && depth > 0 && $from.indexAfter(depth) == $from.node(depth).childCount) { + depth-- + dist-- + } + if (dist > 0) { + let next = $from.node(depth).maybeChild($from.indexAfter(depth)) + while (dist > 0) { + if (!next || next.isLeaf) return true + next = next.firstChild + dist-- + } + } + return false +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-transform/src/step.js b/packages/tiptap-extensions/node_modules/prosemirror-transform/src/step.js new file mode 100644 index 0000000000..a15485fd6a --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-transform/src/step.js @@ -0,0 +1,110 @@ +import {ReplaceError} from "prosemirror-model" + +import {StepMap} from "./map" + +function mustOverride() { throw new Error("Override me") } + +const stepsByID = Object.create(null) + +// ::- A step object represents an atomic change. It generally applies +// only to the document it was created for, since the positions +// stored in it will only make sense for that document. +// +// New steps are defined by creating classes that extend `Step`, +// overriding the `apply`, `invert`, `map`, `getMap` and `fromJSON` +// methods, and registering your class with a unique +// JSON-serialization identifier using +// [`Step.jsonID`](#transform.Step^jsonID). +export class Step { + // :: (doc: Node) → StepResult + // Applies this step to the given document, returning a result + // object that either indicates failure, if the step can not be + // applied to this document, or indicates success by containing a + // transformed document. + apply(_doc) { return mustOverride() } + + // :: () → StepMap + // Get the step map that represents the changes made by this step, + // and which can be used to transform between positions in the old + // and the new document. + getMap() { return StepMap.empty } + + // :: (doc: Node) → Step + // Create an inverted version of this step. Needs the document as it + // was before the step as argument. + invert(_doc) { return mustOverride() } + + // :: (mapping: Mappable) → ?Step + // Map this step through a mappable thing, returning either a + // version of that step with its positions adjusted, or `null` if + // the step was entirely deleted by the mapping. + map(_mapping) { return mustOverride() } + + // :: (other: Step) → ?Step + // Try to merge this step with another one, to be applied directly + // after it. Returns the merged step when possible, null if the + // steps can't be merged. + merge(_other) { return null } + + // :: () → Object + // Create a JSON-serializeable representation of this step. When + // defining this for a custom subclass, make sure the result object + // includes the step type's [JSON id](#transform.Step^jsonID) under + // the `stepType` property. + toJSON() { return mustOverride() } + + // :: (Schema, Object) → Step + // Deserialize a step from its JSON representation. Will call + // through to the step class' own implementation of this method. + static fromJSON(schema, json) { + if (!json || !json.stepType) throw new RangeError("Invalid input for Step.fromJSON") + let type = stepsByID[json.stepType] + if (!type) throw new RangeError(`No step type ${json.stepType} defined`) + return type.fromJSON(schema, json) + } + + // :: (string, constructor) + // To be able to serialize steps to JSON, each step needs a string + // ID to attach to its JSON representation. Use this method to + // register an ID for your step classes. Try to pick something + // that's unlikely to clash with steps from other modules. + static jsonID(id, stepClass) { + if (id in stepsByID) throw new RangeError("Duplicate use of step JSON ID " + id) + stepsByID[id] = stepClass + stepClass.prototype.jsonID = id + return stepClass + } +} + +// ::- The result of [applying](#transform.Step.apply) a step. Contains either a +// new document or a failure value. +export class StepResult { + // : (?Node, ?string) + constructor(doc, failed) { + // :: ?Node The transformed document. + this.doc = doc + // :: ?string Text providing information about a failed step. + this.failed = failed + } + + // :: (Node) → StepResult + // Create a successful step result. + static ok(doc) { return new StepResult(doc, null) } + + // :: (string) → StepResult + // Create a failed step result. + static fail(message) { return new StepResult(null, message) } + + // :: (Node, number, number, Slice) → StepResult + // Call [`Node.replace`](#model.Node.replace) with the given + // arguments. Create a successful result if it succeeds, and a + // failed one if it throws a `ReplaceError`. + static fromReplace(doc, from, to, slice) { + try { + return StepResult.ok(doc.replace(from, to, slice)) + } catch (e) { + if (e instanceof ReplaceError) return StepResult.fail(e.message) + throw e + } + } +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-transform/src/structure.js b/packages/tiptap-extensions/node_modules/prosemirror-transform/src/structure.js new file mode 100644 index 0000000000..8e1fb7b5df --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-transform/src/structure.js @@ -0,0 +1,284 @@ +import {Slice, Fragment} from "prosemirror-model" + +import {Transform} from "./transform" +import {ReplaceStep, ReplaceAroundStep} from "./replace_step" + +function canCut(node, start, end) { + return (start == 0 || node.canReplace(start, node.childCount)) && + (end == node.childCount || node.canReplace(0, end)) +} + +// :: (NodeRange) → ?number +// Try to find a target depth to which the content in the given range +// can be lifted. Will not go across +// [isolating](#model.NodeSpec.isolating) parent nodes. +export function liftTarget(range) { + let parent = range.parent + let content = parent.content.cutByIndex(range.startIndex, range.endIndex) + for (let depth = range.depth;; --depth) { + let node = range.$from.node(depth) + let index = range.$from.index(depth), endIndex = range.$to.indexAfter(depth) + if (depth < range.depth && node.canReplace(index, endIndex, content)) + return depth + if (depth == 0 || node.type.spec.isolating || !canCut(node, index, endIndex)) break + } +} + +// :: (NodeRange, number) → this +// Split the content in the given range off from its parent, if there +// is sibling content before or after it, and move it up the tree to +// the depth specified by `target`. You'll probably want to use +// [`liftTarget`](#transform.liftTarget) to compute `target`, to make +// sure the lift is valid. +Transform.prototype.lift = function(range, target) { + let {$from, $to, depth} = range + + let gapStart = $from.before(depth + 1), gapEnd = $to.after(depth + 1) + let start = gapStart, end = gapEnd + + let before = Fragment.empty, openStart = 0 + for (let d = depth, splitting = false; d > target; d--) + if (splitting || $from.index(d) > 0) { + splitting = true + before = Fragment.from($from.node(d).copy(before)) + openStart++ + } else { + start-- + } + let after = Fragment.empty, openEnd = 0 + for (let d = depth, splitting = false; d > target; d--) + if (splitting || $to.after(d + 1) < $to.end(d)) { + splitting = true + after = Fragment.from($to.node(d).copy(after)) + openEnd++ + } else { + end++ + } + + return this.step(new ReplaceAroundStep(start, end, gapStart, gapEnd, + new Slice(before.append(after), openStart, openEnd), + before.size - openStart, true)) +} + +// :: (NodeRange, NodeType, ?Object, ?NodeRange) → ?[{type: NodeType, attrs: ?Object}] +// Try to find a valid way to wrap the content in the given range in a +// node of the given type. May introduce extra nodes around and inside +// the wrapper node, if necessary. Returns null if no valid wrapping +// could be found. When `innerRange` is given, that range's content is +// used as the content to fit into the wrapping, instead of the +// content of `range`. +export function findWrapping(range, nodeType, attrs, innerRange = range) { + let around = findWrappingOutside(range, nodeType) + let inner = around && findWrappingInside(innerRange, nodeType) + if (!inner) return null + return around.map(withAttrs).concat({type: nodeType, attrs}).concat(inner.map(withAttrs)) +} + +function withAttrs(type) { return {type, attrs: null} } + +function findWrappingOutside(range, type) { + let {parent, startIndex, endIndex} = range + let around = parent.contentMatchAt(startIndex).findWrapping(type) + if (!around) return null + let outer = around.length ? around[0] : type + return parent.canReplaceWith(startIndex, endIndex, outer) ? around : null +} + +function findWrappingInside(range, type) { + let {parent, startIndex, endIndex} = range + let inner = parent.child(startIndex) + let inside = type.contentMatch.findWrapping(inner.type) + if (!inside) return null + let lastType = inside.length ? inside[inside.length - 1] : type + let innerMatch = lastType.contentMatch + for (let i = startIndex; innerMatch && i < endIndex; i++) + innerMatch = innerMatch.matchType(parent.child(i).type) + if (!innerMatch || !innerMatch.validEnd) return null + return inside +} + +// :: (NodeRange, [{type: NodeType, attrs: ?Object}]) → this +// Wrap the given [range](#model.NodeRange) in the given set of wrappers. +// The wrappers are assumed to be valid in this position, and should +// probably be computed with [`findWrapping`](#transform.findWrapping). +Transform.prototype.wrap = function(range, wrappers) { + let content = Fragment.empty + for (let i = wrappers.length - 1; i >= 0; i--) + content = Fragment.from(wrappers[i].type.create(wrappers[i].attrs, content)) + + let start = range.start, end = range.end + return this.step(new ReplaceAroundStep(start, end, start, end, new Slice(content, 0, 0), wrappers.length, true)) +} + +// :: (number, ?number, NodeType, ?Object) → this +// Set the type of all textblocks (partly) between `from` and `to` to +// the given node type with the given attributes. +Transform.prototype.setBlockType = function(from, to = from, type, attrs) { + if (!type.isTextblock) throw new RangeError("Type given to setBlockType should be a textblock") + let mapFrom = this.steps.length + this.doc.nodesBetween(from, to, (node, pos) => { + if (node.isTextblock && !node.hasMarkup(type, attrs) && canChangeType(this.doc, this.mapping.slice(mapFrom).map(pos), type)) { + // Ensure all markup that isn't allowed in the new node type is cleared + this.clearIncompatible(this.mapping.slice(mapFrom).map(pos, 1), type) + let mapping = this.mapping.slice(mapFrom) + let startM = mapping.map(pos, 1), endM = mapping.map(pos + node.nodeSize, 1) + this.step(new ReplaceAroundStep(startM, endM, startM + 1, endM - 1, + new Slice(Fragment.from(type.create(attrs, null, node.marks)), 0, 0), 1, true)) + return false + } + }) + return this +} + +function canChangeType(doc, pos, type) { + let $pos = doc.resolve(pos), index = $pos.index() + return $pos.parent.canReplaceWith(index, index + 1, type) +} + +// :: (number, ?NodeType, ?Object, ?[Mark]) → this +// Change the type, attributes, and/or marks of the node at `pos`. +// When `type` isn't given, the existing node type is preserved, +Transform.prototype.setNodeMarkup = function(pos, type, attrs, marks) { + let node = this.doc.nodeAt(pos) + if (!node) throw new RangeError("No node at given position") + if (!type) type = node.type + let newNode = type.create(attrs, null, marks || node.marks) + if (node.isLeaf) + return this.replaceWith(pos, pos + node.nodeSize, newNode) + + if (!type.validContent(node.content)) + throw new RangeError("Invalid content for node type " + type.name) + + return this.step(new ReplaceAroundStep(pos, pos + node.nodeSize, pos + 1, pos + node.nodeSize - 1, + new Slice(Fragment.from(newNode), 0, 0), 1, true)) +} + +// :: (Node, number, number, ?[?{type: NodeType, attrs: ?Object}]) → bool +// Check whether splitting at the given position is allowed. +export function canSplit(doc, pos, depth = 1, typesAfter) { + let $pos = doc.resolve(pos), base = $pos.depth - depth + let innerType = (typesAfter && typesAfter[typesAfter.length - 1]) || $pos.parent + if (base < 0 || $pos.parent.type.spec.isolating || + !$pos.parent.canReplace($pos.index(), $pos.parent.childCount) || + !innerType.type.validContent($pos.parent.content.cutByIndex($pos.index(), $pos.parent.childCount))) + return false + for (let d = $pos.depth - 1, i = depth - 2; d > base; d--, i--) { + let node = $pos.node(d), index = $pos.index(d) + if (node.type.spec.isolating) return false + let rest = node.content.cutByIndex(index, node.childCount) + let after = (typesAfter && typesAfter[i]) || node + if (after != node) rest = rest.replaceChild(0, after.type.create(after.attrs)) + if (!node.canReplace(index + 1, node.childCount) || !after.type.validContent(rest)) + return false + } + let index = $pos.indexAfter(base) + let baseType = typesAfter && typesAfter[0] + return $pos.node(base).canReplaceWith(index, index, baseType ? baseType.type : $pos.node(base + 1).type) +} + +// :: (number, ?number, ?[?{type: NodeType, attrs: ?Object}]) → this +// Split the node at the given position, and optionally, if `depth` is +// greater than one, any number of nodes above that. By default, the +// parts split off will inherit the node type of the original node. +// This can be changed by passing an array of types and attributes to +// use after the split. +Transform.prototype.split = function(pos, depth = 1, typesAfter) { + let $pos = this.doc.resolve(pos), before = Fragment.empty, after = Fragment.empty + for (let d = $pos.depth, e = $pos.depth - depth, i = depth - 1; d > e; d--, i--) { + before = Fragment.from($pos.node(d).copy(before)) + let typeAfter = typesAfter && typesAfter[i] + after = Fragment.from(typeAfter ? typeAfter.type.create(typeAfter.attrs, after) : $pos.node(d).copy(after)) + } + return this.step(new ReplaceStep(pos, pos, new Slice(before.append(after), depth, depth), true)) +} + +// :: (Node, number) → bool +// Test whether the blocks before and after a given position can be +// joined. +export function canJoin(doc, pos) { + let $pos = doc.resolve(pos), index = $pos.index() + return joinable($pos.nodeBefore, $pos.nodeAfter) && + $pos.parent.canReplace(index, index + 1) +} + +function joinable(a, b) { + return a && b && !a.isLeaf && a.canAppend(b) +} + +// :: (Node, number, ?number) → ?number +// Find an ancestor of the given position that can be joined to the +// block before (or after if `dir` is positive). Returns the joinable +// point, if any. +export function joinPoint(doc, pos, dir = -1) { + let $pos = doc.resolve(pos) + for (let d = $pos.depth;; d--) { + let before, after + if (d == $pos.depth) { + before = $pos.nodeBefore + after = $pos.nodeAfter + } else if (dir > 0) { + before = $pos.node(d + 1) + after = $pos.node(d).maybeChild($pos.index(d) + 1) + } else { + before = $pos.node(d).maybeChild($pos.index(d) - 1) + after = $pos.node(d + 1) + } + if (before && !before.isTextblock && joinable(before, after)) return pos + if (d == 0) break + pos = dir < 0 ? $pos.before(d) : $pos.after(d) + } +} + +// :: (number, ?number) → this +// Join the blocks around the given position. If depth is 2, their +// last and first siblings are also joined, and so on. +Transform.prototype.join = function(pos, depth = 1) { + let step = new ReplaceStep(pos - depth, pos + depth, Slice.empty, true) + return this.step(step) +} + +// :: (Node, number, NodeType) → ?number +// Try to find a point where a node of the given type can be inserted +// near `pos`, by searching up the node hierarchy when `pos` itself +// isn't a valid place but is at the start or end of a node. Return +// null if no position was found. +export function insertPoint(doc, pos, nodeType) { + let $pos = doc.resolve(pos) + if ($pos.parent.canReplaceWith($pos.index(), $pos.index(), nodeType)) return pos + + if ($pos.parentOffset == 0) + for (let d = $pos.depth - 1; d >= 0; d--) { + let index = $pos.index(d) + if ($pos.node(d).canReplaceWith(index, index, nodeType)) return $pos.before(d + 1) + if (index > 0) return null + } + if ($pos.parentOffset == $pos.parent.content.size) + for (let d = $pos.depth - 1; d >= 0; d--) { + let index = $pos.indexAfter(d) + if ($pos.node(d).canReplaceWith(index, index, nodeType)) return $pos.after(d + 1) + if (index < $pos.node(d).childCount) return null + } +} + +// :: (Node, number, Slice) → ?number +// Finds a position at or around the given position where the given +// slice can be inserted. Will look at parent nodes' nearest boundary +// and try there, even if the original position wasn't directly at the +// start or end of that node. Returns null when no position was found. +export function dropPoint(doc, pos, slice) { + let $pos = doc.resolve(pos) + if (!slice.content.size) return pos + let content = slice.content + for (let i = 0; i < slice.openStart; i++) content = content.firstChild.content + for (let pass = 1; pass <= (slice.openStart == 0 && slice.size ? 2 : 1); pass++) { + for (let d = $pos.depth; d >= 0; d--) { + let bias = d == $pos.depth ? 0 : $pos.pos <= ($pos.start(d + 1) + $pos.end(d + 1)) / 2 ? -1 : 1 + let insertPos = $pos.index(d) + (bias > 0 ? 1 : 0) + if (pass == 1 + ? $pos.node(d).canReplace(insertPos, insertPos, content) + : $pos.node(d).contentMatchAt(insertPos).findWrapping(content.firstChild.type)) + return bias == 0 ? $pos.pos : bias < 0 ? $pos.before(d + 1) : $pos.after(d + 1) + } + } + return null +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-transform/src/transform.js b/packages/tiptap-extensions/node_modules/prosemirror-transform/src/transform.js new file mode 100644 index 0000000000..f52d3387ec --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-transform/src/transform.js @@ -0,0 +1,71 @@ +import {Mapping} from "./map" + +export function TransformError(message) { + let err = Error.call(this, message) + err.__proto__ = TransformError.prototype + return err +} + +TransformError.prototype = Object.create(Error.prototype) +TransformError.prototype.constructor = TransformError +TransformError.prototype.name = "TransformError" + +// ::- Abstraction to build up and track an array of +// [steps](#transform.Step) representing a document transformation. +// +// Most transforming methods return the `Transform` object itself, so +// that they can be chained. +export class Transform { + // :: (Node) + // Create a transform that starts with the given document. + constructor(doc) { + // :: Node + // The current document (the result of applying the steps in the + // transform). + this.doc = doc + // :: [Step] + // The steps in this transform. + this.steps = [] + // :: [Node] + // The documents before each of the steps. + this.docs = [] + // :: Mapping + // A mapping with the maps for each of the steps in this transform. + this.mapping = new Mapping + } + + // :: Node The starting document. + get before() { return this.docs.length ? this.docs[0] : this.doc } + + // :: (step: Step) → this + // Apply a new step in this transform, saving the result. Throws an + // error when the step fails. + step(object) { + let result = this.maybeStep(object) + if (result.failed) throw new TransformError(result.failed) + return this + } + + // :: (Step) → StepResult + // Try to apply a step in this transformation, ignoring it if it + // fails. Returns the step result. + maybeStep(step) { + let result = step.apply(this.doc) + if (!result.failed) this.addStep(step, result.doc) + return result + } + + // :: bool + // True when the document has been changed (when there are any + // steps). + get docChanged() { + return this.steps.length > 0 + } + + addStep(step, doc) { + this.docs.push(this.doc) + this.steps.push(step) + this.mapping.appendMap(step.getMap()) + this.doc = doc + } +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/.tern-project b/packages/tiptap-extensions/node_modules/prosemirror-view/.tern-project new file mode 100644 index 0000000000..dde39765e5 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/.tern-project @@ -0,0 +1,8 @@ +{ + "libs": ["browser"], + "plugins": { + "node": {}, + "complete_strings": {}, + "es_modules": {} + } +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/CHANGELOG.md b/packages/tiptap-extensions/node_modules/prosemirror-view/CHANGELOG.md new file mode 100644 index 0000000000..7147b7ac3f --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/CHANGELOG.md @@ -0,0 +1,1233 @@ +## 1.13.7 (2019-12-16) + +### Bug fixes + +Fix a bug that caused the DOM to go out of sync with the decorations when updating inline decorations that added multiple wrapping nodes to a piece of content. + +## 1.13.6 (2019-12-13) + +### Bug fixes + +Fix a crash when deleting a list item in Safari while using a parse rule with a `context` property for `
  • ` elements. + +Work around another case where Chrome reports an incorrect selection. + +Work around issue where Firefox will insert a stray BR node when deleting a text node in some types of DOM structure. + +## 1.13.5 (2019-12-09) + +### Bug fixes + +Fix the way decorations update node styles to allow removing CSS custom properties. Link to https in readme and changelog + +The `root` accessor on views now makes sure that, when it returns a shadow root, that object has a `getSelection` method. + +Fix an issue where the DOM selection could get out of sync with ProseMirror's selection state in Edge. + +## 1.13.4 (2019-11-20) + +### Bug fixes + +Rename ES module files to use a .js extension, since Webpack gets confused by .mjs + +## 1.13.3 (2019-11-19) + +### Bug fixes + +Fix issue where the editor wouldn't update its internal selection when the editor was blurred, its selection was changed programatically, and then the editor was re-focused with its old DOM selection. + +The file referred to in the package's `module` field now is compiled down to ES5. + +## 1.13.2 (2019-11-14) + +### Bug fixes + +Fix issue where `EditorView.focus` would scroll the top of the document into view on Safari. + +## 1.13.1 (2019-11-12) + +### Bug fixes + +Work around selection jumping that sometimes occurs on Chrome when focusing the editor. + +## 1.13.0 (2019-11-08) + +### New features + +Add a `module` field to package json file. + +## 1.12.3 (2019-11-07) + +### Bug fixes + +Fix issue where paste events were stopped when the clipboard parser failed to make sense of the content. + +Fix issue where the `handlePaste` prop might be called multiple times for a single paste. + +## 1.12.2 (2019-11-05) + +### Bug fixes + +Set the editable element to use a `white-space: break-spaces` style so that whitespace at the end of a line properly moves the cursor to the next line. + +Fix issue where `posAtCoords` could throw an error in some circumstances on Firefox. + +Don't force focus back on the editor if a node view moves focus in its `setSelection` method. + +## 1.12.1 (2019-10-28) + +### Bug fixes + +Reduce unnecessary redraws when typing creates a new text node on Chrome. + +The default prosemirror.css now also turns off ligatures in Edge. + +Fix issue where the cursor stays before the typed text in Edge, when typing in an empty paragraph or between hard break nodes. + +## 1.12.0 (2019-10-21) + +### New features + +The mutation records passed to [`ignoreMutation`](https://prosemirror.net/docs/ref/#view.NodeView.ignoreMutation) now contain the old attribute value. + +## 1.11.7 (2019-10-15) + +### Bug fixes + +Enabling a mark and then starting a composition, on Chrome Android, will no longer cause the cursor to jump to the start of the composition. + +## 1.11.6 (2019-10-07) + +### Bug fixes + +Fix workaround for broken IE11 DOM change records when inserting between `
    ` nodes to handle more cases. + +## 1.11.5 (2019-10-04) + +### Bug fixes + +Don't leave DOM selection in place when it is inside a node view but not inside its content DOM element. + +## 1.11.4 (2019-09-27) + +### Bug fixes + +Fix an IE11 issue where marks would sometimes unexpectedly get dropped when inserting a space after marked text. + +Fixes an issue where `handleTextInput` wasn't called when typing over a single character with the same character. + +## 1.11.3 (2019-09-20) + +### Bug fixes + +Fix an issue where the DOM node representing a mark could be corrupted when the browser decides to replace it with another node but ProseMirror restored the old node after the change. + +Handle another case where typing over a selection in IE11 confused the editor. + +## 1.11.2 (2019-09-17) + +### Bug fixes + +Fix an issue where typing over a decorated piece of text would sometimes just act like deletion. + +Fix another problem in IE11 with typing over content, where typing over a decorated bit of text caused a crash. + +## 1.11.1 (2019-09-16) + +### Bug fixes + +Fix issue where typing over the entire contents of an inline node on IE11 would insert the typed content in the wrong position. + +## 1.11.0 (2019-09-16) + +### Bug fixes + +Fix an issue where IE11 would select the entire textblock after deleting content at its start. + +### New features + +View instances now have a public `editable` property that indicates whether they are in editable mode. + +## 1.10.3 (2019-09-04) + +### Bug fixes + +Fix a regression in 1.10.2 that broke copying on IE11. + +## 1.10.2 (2019-09-03) + +### Bug fixes + +Fix an issue where `posAtCoords` could crash by dereferencing undefined in some circumstances. + +Fix inserting text next to a hard break in IE11. + +Fix an issue where typing over a selection would result in two different transactions (once for the deletion, once for the insertion) on IE11. + +Selecting the word at the start of the document and typing over it no longer causes the text input to appear at the end of the document in IE11. + +## 1.10.1 (2019-08-28) + +### Bug fixes + +Copying content will no longer create elements in the main document, which prevents images from loading just because they appear in clipboard content. + +## 1.10.0 (2019-08-13) + +### Bug fixes + +Fix an issue that caused the cursor to be scrolled into view when `focus()` was called on IE11. + +Fix problem where the cursor cycled through pieces of right-to-left text on Firefox during horizontal motion when the gapcursor plugin was enabled. + +Fix spurious mutation events in Firefox causing mark replacement at end of composition. Restore call to dom.focus on view.focus + +Fix a bug that could cause node views in front of marked nodes to not be destroyed when deleted, and caused confusion in composition handling in some situations. + +Cursor wrappers (a kludge to make sure typed text gets wrapping DOM structure corresponding to the current marks) are now created less eagerly, and in a less invasive way, which resolves a number of problems with composition (especially on Safari) and bidirectional text. + +### New features + +Node views can now ignore selection change events through their [`ignoreMutation`](https://prosemirror.net/docs/ref/#view.NodeView.ignoreMutation) callback. + +## 1.9.13 (2019-07-29) + +### Bug fixes + +Fix an issue where copying content from a ProseMirror instance into an instance using another schema could, in some circumstances, insert schema-violating content. + +Fix comparison of decoration sets, which should solve unneccesary re-renders when updating decorations with an identical but newly allocated set. Don't update DOM selection in uneditable editors when the focus is elsewhere + +Fix a bug where the editor would steal focus from child elements when in non-editable mode. + +Fix error and corruption in IE11 when backspacing out a single character after a br node. + +## 1.9.12 (2019-07-16) + +### Bug fixes + +Fix a crash `posAtCoords` in Firefox when the coordinates are above a text input field. + +## 1.9.11 (2019-07-03) + +### Bug fixes + +Fix an issue where the DOM change handler would treat the parsed content as the wrong part of the document. + +Fix an issue in IE11 where deleting the last character in a textblock causes a crash. + +Fix an issue where backspacing out the first character in a textblock would cause IE11 to move the selection to some incorrect position. + +## 1.9.10 (2019-06-12) + +### Bug fixes + +Fix a crash in `coordsAtPos` caused by use of an incorrect variable name. + +## 1.9.9 (2019-06-09) + +### Bug fixes + +Fix arrowing over unselectable inline nodes in Chrome and Safari, which by default introduce an extra needless cursor position before the node. + +Fix a bug that caused DOM changes to be ignored when happening directly in front of some types of DOM events (such as focus/blur). + +## 1.9.8 (2019-05-29) + +### Bug fixes + +Fix an issue where moving focus from a node inside of the editor to the editor itself could sometimes lead to a node selection around the inner node rather than the intended selection (on Chrome). + +## 1.9.7 (2019-05-28) + +### Bug fixes + +ProseMirror will no longer try to stabilize the scroll position during updates on browsers that support [scroll anchoring](https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-anchor), since it'd inadvertently cancel the browser's behavior. + +Fix an issue in Safari where the editor would interrupt the composition spacebar menu because it incorrectly interpreted the mutation events fired by the browser as representing a replacement of the selection with identical text. + +Work around an issue where, on Safari, an IME composition started in an empty textblock would vanish when you press enter. + +## 1.9.6 (2019-05-17) + +### Bug fixes + +Fix bug in composition handling when the composition's parent node has an extra wrapper node around its content. + +## 1.9.5 (2019-05-14) + +### Bug fixes + +Fix regression in handling text editing events on IE11. + +## 1.9.4 (2019-05-13) + +### Bug fixes + +Fix a regression where all plugin views were recreated when calling [`setProps`](https://prosemirror.net/docs/ref/#view.EditorView.setProps). + +## 1.9.3 (2019-05-10) + +### Bug fixes + +Fix a bug where, if the document was changed at exactly the right moment, `handleClickOn` could be called with `null` as the node. + +## 1.9.2 (2019-05-08) + +### Bug fixes + +Fix a bug where updating to a reconfigured state would not recreate the view's plugin views. + +## 1.9.1 (2019-05-04) + +### Bug fixes + +Fix a regression where mouse selection would sometimes raise an error. + +## 1.9.0 (2019-05-03) + +### New features + +Changes made during compositions now immediately fire transactions on each update, rather than only a single one at the end of the composition. + +The view now immediately shows changes to the document or decorations during composition, even if they come from transactions not directly generated by the use's editing. The only exception is decorations that affect the focused text node—those are still delayed to avoid unneccesarily canceling the composition. + +## 1.8.9 (2019-04-18) + +### Bug fixes + +Improve display update times for nodes with thousands of children by fix an accidental piece of quadratic complexity. + +Fixes an issue where changes to the [`nodeViews` prop](https://prosemirror.net/docs/ref/#view.EditorProps.nodeViews) weren't noticed when using [`updateState`](https://prosemirror.net/docs/ref/#view.EditorView.updateState) to update the view. + +Fix issue where sometimes moving the selection back its last position with the mouse failed to update ProseMirror's selection state. + +No longer call [`deselectNode`](https://prosemirror.net/docs/ref/#view.NodeView.deselectNode) on already-destroyed node views. + +## 1.8.8 (2019-04-11) + +### Bug fixes + +Fix a regression from 1.8.4 that made it return unreasonable rectangles for positions between blocks. + +## 1.8.7 (2019-04-09) + +### Bug fixes + +The [`handlePaste`](https://prosemirror.net/docs/ref/#view.EditorProps.handlePaste) prop is now activated even when the default parser can't make any sense of the clipboard content. + +## 1.8.6 (2019-04-08) + +### Bug fixes + +Fix a bug where decorations splitting a text node would sometimes confuse the display updater and make decorated nodes disappear. + +## 1.8.5 (2019-04-08) + +### Bug fixes + +Multiple [`transformPastedHTML`](https://prosemirror.net/docs/ref/#view.EditorProps.transformPastedHTML) props are now all properly called in order, rather than only the first one. + +Fixes an issue where invalid change positions were computed when a composition happened concurrently with a change that inserted content at the same position. + +## 1.8.4 (2019-03-20) + +### Bug fixes + +[`EditorView.coordsAtPos`](https://prosemirror.net/docs/ref/#view.EditorView.coordsAtPos) is now more accurate in right-to-left text on Chrome and Firefox. + +[`EditorView.coordsAtPos`](https://prosemirror.net/docs/ref/#view.EditorView.coordsAtPos) returns more accurate coordinates when querying the position directly after a line wrap point. + +Fix an issue where clicking directly in front of a node selection doesn't clear the node selection markup. + +## 1.8.3 (2019-03-04) + +### Bug fixes + +Fix an issue where clicking when there's a non-text selection active sometimes doesn't cause the appropriate new selection. + +## 1.8.2 (2019-02-28) + +### Bug fixes + +Fix an issue where a view state update happening between a change to the DOM selection and the corresponding browser event could disrupt mouse selection. + +## 1.8.1 (2019-02-22) + +### Bug fixes + +Fix infinite loop in `coordsAtPos`. + +## 1.8.0 (2019-02-21) + +### Bug fixes + +Fix a bug where [`endOfTextblock`](https://prosemirror.net/docs/ref/#view.EditorView.endOfTextblock) spuriously returns true when the cursor is in a mark. + +### New features + +[`posAtCoords`](https://prosemirror.net/docs/ref/#view.EditorView.posAtCoords) will no longer return `null` when called with coordinates outside the browser's viewport. (It _will_ still return null for coordinates outside of the editor's bounding box.) + +## 1.7.3 (2019-02-20) + +### Bug fixes + +[`endOfTextblock`](https://prosemirror.net/docs/ref/#view.EditorView.endOfTextblock) now works on textblocks that are the editor's top-level node. + +## 1.7.2 (2019-02-20) + +### Bug fixes + +Pressing shift-left/right next to a selectable node no longer selects the node instead of creating a text selection across it. + +## 1.7.1 (2019-02-04) + +### Bug fixes + +Fix an issue on Safari where an Enter key events that was part of a composition is interpreted as stand-alone Enter press. + +## 1.7.0 (2019-01-29) + +### Bug fixes + +Fix an issue where node selections on uneditable nodes couldn't be copied or cut on Chrome. + +### New features + +The editable view now recognizes the [`spanning`](https://prosemirror.net/docs/ref/#model.MarkSpec.spanning) mark property. + +## 1.6.8 (2019-01-03) + +### Bug fixes + +When replacing a selection by typing over it with a letter that matches its start or end, the editor now generates a step that covers the whole replacement. + +Fixes dragging a node when the mouse is in a child DOM element that doesn't represent a document node. Work around Chrome bug in selection management + +Fixes an issue in Chrome where clicking at the start of a textblock after a selected node would sometimes not move the cursor there. + +Fix issue where a node view's `getPos` callback could sometimes return `NaN`. + +Fix an issue where deleting more than 5 nodes might cause the nodes after that to be needlessly redrawn. + +## 1.6.7 (2018-11-26) + +### Bug fixes + +Avoids redrawing of content with marks when other content in front of it is deleted. + +## 1.6.6 (2018-11-15) + +### Bug fixes + +Work around a Chrome bug where programmatic changes near the cursor sometimes cause the visible and reported selection to disagree. + +Changing the `nodeView` prop will no longer leave outdated node views in the DOM. + +Work around an issue where Chrome unfocuses the editor or scrolls way down when pressing down arrow with the cursor between the start of a textblock and an uneditable element. + +Fix a bug where mapping decoration sets through changes that changed the structure of decorated subtrees sometimes produced corrupted output. + +## 1.6.5 (2018-10-29) + +### Bug fixes + +Work around Safari issue where deleting the last bit of text in a table cell creates weird HTML with a BR in a table row. + +## 1.6.4 (2018-10-19) + +### Bug fixes + +Fix pasting when both text and files are present on the clipboard. + +## 1.6.3 (2018-10-12) + +### Bug fixes + +The editor will no longer try to handle file paste events with the old-browser compatibility kludge (which might cause scrolling and focus flickering). + +## 1.6.2 (2018-10-08) + +### Bug fixes + +Fixes an issue where event handlers were leaked when destroying an editor + +## 1.6.1 (2018-10-01) + +### Bug fixes + +Fixes situation where a vertical [`endOfTextblock`](https://prosemirror.net/docs/ref/#view.EditorView.endOfTextblock) query could get confused by nearby widgets or complex parent node representation. + +## 1.6.0 (2018-09-27) + +### Bug fixes + +Fixes a corner case in which DecorationSet.map would map decorations to incorrect new positions. + +When the editor contains scrollable elements, scrolling the cursor into view also scrolls those. + +### New features + +The `scrollMargin` and `scrollThreshold` props may now hold `{left, right, top, bottom}` objects to set different margins and thresholds for different sides. Make scrolling from a given start node more robust + +## 1.5.3 (2018-09-24) + +### Bug fixes + +The cursor is now scrolled into view after keyboard driven selection changes even when they were handled by the browser. + +## 1.5.2 (2018-09-07) + +### Bug fixes + +Improves selection management around widgets with no actual HTML content (possibly drawn using CSS pseudo elements). + +Fix extra whitespace in pasted HTML caused by previously-collapsed spacing. + +Slow triple-clicks are no longer treated as two double-clicks in a row. + +## 1.5.1 (2018-08-24) + +### Bug fixes + +Fix issue where some DOM selections would cause a non-editable view to crash when reading the selection. + +## 1.5.0 (2018-08-21) + +### New features + +Mark views are now passed a boolean that indicates whether the mark's content is inline as third argument. + +## 1.4.4 (2018-08-13) + +### Bug fixes + +Fix an issue where a non-empty DOM selection could stick around even though the state's selection is empty. + +Fix an issue where Firefox would create an extra cursor position when arrow-keying through a widget. + +## 1.4.3 (2018-08-12) + +### Bug fixes + +Fix an issue where the editor got stuck believing shift was down (and hence pasting as plain text) when it was unfocused with shift held down. + +## 1.4.2 (2018-08-03) + +### Bug fixes + +Fix an issue where reading the selection from the DOM might crash in non-editable mode. + +## 1.4.1 (2018-08-02) + +### Bug fixes + +Fixes an issue where backspacing out the last character between the start of a textblock and a widget in Chrome would insert a random hard break. + +## 1.4.0 (2018-07-26) + +### New features + +The `dispatchTransaction` prop is now called with `this` bound to the editor view. + +## 1.3.8 (2018-07-24) + +### Bug fixes + +Fix an issue where Chrome Android would move the cursor forward by one after backspace-joining two paragraphs. + +## 1.3.7 (2018-07-02) + +### Bug fixes + +Fix a crash when scrolling things into view when the editor isn't a child of `document.body`. + +## 1.3.6 (2018-06-21) + +### Bug fixes + +Make sure Safari version detection for clipboard support also works in iOS webview. + +## 1.3.5 (2018-06-20) + +### Bug fixes + +Use shared implementation of [`dropPoint`](https://prosemirror.net/docs/ref/#transform.dropPoint) to handle finding a drop position. + +## 1.3.4 (2018-06-20) + +### Bug fixes + +Enable use of browser clipboard API on Mobile Safari version 11 and up, which makes cut work on that platform and should generally improve clipboard handling. + +## 1.3.3 (2018-06-15) + +### Bug fixes + +Fix arrow-left cursor motion from cursor wrapper (for example after a link). + +Fix selection glitches when shift-selecting around widget decorations. + +Fix issue where a parsing a code block from the editor DOM might drop newlines in the code. + +## 1.3.2 (2018-06-15) + +### Bug fixes + +[`handleKeyDown`](https://prosemirror.net/docs/ref/#view.EditorProps.handleKeyDown) will now get notified of key events happening directly after a composition ends. + +## 1.3.1 (2018-06-08) + +### Bug fixes + +The package can now be loaded in a web worker context (where `navigator` is defined but `document` isn't) without crashing. + +Dropping something like a list item into a textblock will no longer split the textblock. + +## 1.3.0 (2018-04-24) + +### Bug fixes + +Fix mouse-selecting (in IE and Edge) from the end of links and other positions that cause a cursor wrapper. + +[Widget decorations](https://prosemirror.net/docs/ref/#view.Decoration^widget) with the same [key](https://prosemirror.net/docs/ref/#view.Decoration^widget^spec.key) are now considered equivalent, even if their other spec fields differ. + +### New features + +The new [`EditorView.posAtDOM` method](https://prosemirror.net/docs/ref/#view.EditorView.posAtDOM) can be used to find the document position corresponding to a given DOM position. + +The new [`EditorView.nodeDOM` method](https://prosemirror.net/docs/ref/#view.EditorView.nodeDOM) gives you the DOM node that is used to represent a specific node in the document. + +[`Decoration.widget`](https://prosemirror.net/docs/ref/#view.Decoration^widget) now accepts a function as second argument, which can be used to delay rendering of the widget until the document is drawn (at which point a reference to the view is available). + +The `getPos` function passed to a [node view constructor](https://prosemirror.net/docs/ref/#view.editorProps.nodeViews) can now be called immediately (it used to return undefined until rendering had finished). + +The function used to render a [widget](https://prosemirror.net/docs/ref/#view.Decoration^widget) is now passed a `getPos` method that event handlers can use to figure out where in the DOM the widget is. + +## 1.2.0 (2018-03-14) + +### Bug fixes + +Fix a problem where updating the state of a non-editable view would not set the selection, causing problems when the DOM was updated in a way that disrupted the DOM selection. + +Fix an issue where, on IE and Chrome, starting a drag selection in a position that required a cursor wrapper (on a mark boundary) would sometimes fail to work. + +Fix crash in key handling when the editor is focused but there is no DOM selection. + +Fixes a bug that prevented decorations inside node views with a [`contentDOM` property](https://prosemirror.net/docs/ref/#view.NodeView.contentDOM) from being drawn. + +Fixes an issue where, on Firefox, depending on a race condition, the skipping over insignificant DOM nodes done at keypress was canceled again before the keypress took effect. + +Fixes an issue where an `:after` pseudo-element on a non-inclusive mark could block the cursor, making it impossible to arrow past it. + +### New features + +The DOM structure for marks is no longer constrained to a single node. [Mark views](https://prosemirror.net/docs/ref/#view.NodeView) can have a `contentDOM` property, and [mark spec](https://prosemirror.net/docs/ref/#model.MarkSpec) `toDOM` methods can return structures with holes. + +[Widget decorations](https://prosemirror.net/docs/ref/#view.Decoration^widget) are now wrapped in the marks of the node after them when their [`side` option](https://prosemirror.net/docs/ref/#view.Decoration^widget^spec.side) is >= 0. + +[Widget decorations](https://prosemirror.net/docs/ref/#view.Decoration^widget) may now specify a [`marks` option](https://prosemirror.net/docs/ref/#view.Decoration^widget^spec.marks) to set the precise set of marks they should be wrapped in. + +## 1.1.1 (2018-03-01) + +### Bug fixes + +Fixes typo that broke paste. + +## 1.1.0 (2018-02-28) + +### Bug fixes + +Fixes issue where dragging a draggable node directly below a selected node would move the old selection rather than the target node. + +A drop that can't fit the dropped content will no longer dispatch an empty transaction. + +### New features + +Transactions generated for drop now have a `"uiEvent"` metadata field holding `"drop"`. Paste and cut transactions get that field set to `"paste"` or `"cut"`. + +## 1.0.11 (2018-02-16) + +### Bug fixes + +Fix issue where the cursor was visible when a node was selected on recent Chrome versions. + +## 1.0.10 (2018-01-24) + +### Bug fixes + +Improve preservation of open and closed nodes in slices taken from the clipboard. + +## 1.0.9 (2018-01-17) + +### Bug fixes + +Work around a Chrome cursor motion bug by making sure
    nodes don't get a contenteditable=false attribute. + +## 1.0.8 (2018-01-09) + +### Bug fixes + +Fix issue where [`Decoration.map`](https://prosemirror.net/docs/ref/#view.DecorationSet.map) would in some situations with nested nodes incorrectly map decoration positions. + +## 1.0.7 (2018-01-05) + +### Bug fixes + +Pasting from an external source no longer opens isolating nodes like table cells. + +## 1.0.6 (2017-12-26) + +### Bug fixes + +[`DecorationSet.remove`](https://prosemirror.net/docs/ref/#view.DecorationSet.remove) now uses a proper deep compare to determine if widgets are the same (it used to compare by identity). + +## 1.0.5 (2017-12-05) + +### Bug fixes + +Fix an issue where deeply nested decorations were mapped incorrectly in corner cases. + +## 1.0.4 (2017-11-27) + +### Bug fixes + +Fix a corner-case crash during drop. + +## 1.0.3 (2017-11-23) + +### Bug fixes + +Pressing backspace between two identical characters will no longer generate a transaction that deletes the second one. + +## 1.0.2 (2017-11-20) + +### Bug fixes + +Fix test for whether a node can be selected when arrowing onto it from the right. + +Calling [`posAtCoords`](https://prosemirror.net/docs/ref/#view.EditorView.posAtCoords) while a read from the DOM is pending will no longer return a malformed result. + +## 1.0.1 (2017-11-10) + +### Bug fixes + +Deleting the last character in a list item no longer results in a spurious hard_break node on Safari. + +Fixes a crash on IE11 when starting to drag. + +## 1.0.0 (2017-10-13) + +### Bug fixes + +Dragging nodes with a node view that handles its own mouse events should work better now. + +List item DOM nodes are no longer assigned `pointer-events: none` in the default style. Ctrl-clicking list markers now properly selects the list item again. + +Arrow-down through an empty textblock no longer causes the browser to forget the cursor's horizontal position. + +Copy-dragging on OS X is now done by holding option, rather than control, following the convention on that system. + +Fixes a crash related to decoration management. + +Fixes a problem where using cut on IE11 wouldn't actually remove the selected text. + +Copy/paste on Edge 15 and up now uses the clipboard API, fixing a problem that made them fail entirely. + +### New features + +The [`dragging`](https://prosemirror.net/docs/ref/#view.EditorView.dragging) property of a view, which contains information about editor content being dragged, is now part of the public interface. + +## 0.24.0 (2017-09-25) + +### New features + +The [`clipboardTextParser`](https://prosemirror.net/docs/ref/version/0.24.0.html#view.EditorProps.clipboardTextParser) prop is now passed a context position. + +## 0.23.0 (2017-09-13) + +### Breaking changes + +The `onFocus`, `onBlur`, and `handleContextMenu` props are no longer supported. You can achieve their effect with the [`handleDOMEvents`](https://prosemirror.net/docs/ref/version/0.23.0.html#view.EditorProps.handleDOMEvents) prop. + +### Bug fixes + +Fixes occasional crash when reading the selection in Firefox. + +Putting a table cell on the clipboard now properly wraps it in a table. + +The view will no longer scroll into view when receiving a state that isn't derived from its previous state. + +### New features + +Transactions caused by a paste now have their "paste" meta property set to true. + +Adds a new view prop, [`handleScrollToSelection`](https://prosemirror.net/docs/ref/version/0.23.0.html#view.EditorProps.handleScrollToSelection) to override the behavior of scrolling the selection into view. + +The new editor prop [`clipboardTextSerializer`](https://prosemirror.net/docs/ref/version/0.23.0.html#view.EditorProps.clipboardTextSerializer) allows you to override the way a piece of document is converted to clipboard text. + +Adds the editor prop [`clipboardTextParser`](https://prosemirror.net/docs/ref/version/0.23.0.html#view.EditorProps.clipboardTextParser), which can be used to define your own parsing strategy for clipboard text content. + +[`DecorationSet.find`](https://prosemirror.net/docs/ref/version/0.23.0.html#view.DecorationSet.find) now supports passing a predicate to filter decorations by spec. + +## 0.22.1 (2017-08-16) + +### Bug fixes + +Invisible selections that don't cover any content (i.e., a cursor) are now properly hidden. + +Initializing the editor view non-editable no longer causes a crash. + +## 0.22.0 (2017-06-29) + +### Bug fixes + +Fix an issue where moving the cursor through a text widget causes the editor to lose the selection in Chrome. + +Fixes an issue where down-arrow in front of a widget would sometimes not cause any cursor motion on Chrome. + +[Destroying](https://prosemirror.net/docs/ref/version/0.22.0.html#view.EditorView.destroy) a [mounted](https://prosemirror.net/docs/ref/version/0.22.0.html#view.EditorView.constructor) editor view no longer leaks event handlers. + +Display updates for regular, non-composition input are now synchronous, which should reduce flickering when, for example, updating decorations in response to typing. + +### New features + +The editor can now be initialized in a document other than the global document (say, an `iframe`). + +Editor views now have a [`domAtPos` method](https://prosemirror.net/docs/ref/version/0.22.0.html#view.EditorView.domAtPos), which gives you the DOM position corresponding to a given document position. + +## 0.21.1 (2017-05-09) + +### Bug fixes + +Copying and pasting table cells on Edge no longer strips the table structure. + +## 0.21.0 (2017-05-03) + +### Breaking changes + +The `associative` option to widget decorations is no longer supported. To make a widget left-associative, set its `side` option to a negative number. `associative` will continue to work with a warning until the next release. + +### New features + +[Widget decorations](https://prosemirror.net/docs/ref/version/0.21.0.html#view.Decoration^widget) now support a `side` option that controls which side of them the cursor is drawn, where they move when content is inserted at their position, and the order in which they appear relative to other widgets at the same position. + +## 0.20.5 (2017-05-02) + +### Bug fixes + +Fixes an issue where the DOM selection could be shown on the wrong side of hard break or image nodes. + +## 0.20.4 (2017-04-24) + +### Bug fixes + +Fix a bug that prevented the DOM selection from being updated when the new position was near the old one in some circumstances. + +Stop interfering with alt-d keypresses on OS X. + +Fix issue where reading a DOM change in a previously empty node could crash. + +Fixes crash when reading a change that removed a decorated text node from the DOM. + +## 0.20.3 (2017-04-12) + +### Bug fixes + +Shift-pasting and pasting into a code block now does the right thing on IE and Edge. + +## 0.20.2 (2017-04-05) + +### Bug fixes + +Fixes a bug that broke dragging from the editor. + +## 0.20.1 (2017-04-04) + +### Bug fixes + +Typing in code blocks no longer replaces newlines with spaces. + +Copy and paste on Internet Explorer, Edge, and mobile Safari should now behave more like it does on other browsers. Handlers are called, and the changes to the document are made by ProseMirror's code, not the browser. + +Fixes a problem where triple-clicking the editor would sometimes cause the scroll position to inexplicably jump around on IE11. + +## 0.20.0 (2017-04-03) + +### Breaking changes + +The `inclusiveLeft` and `inclusiveRight` options to inline decorations were renamed to [`inclusiveStart`](https://prosemirror.net/docs/ref/version/0.20.0.html#view.Decoration^inline^spec.inclusiveStart) and [`inclusiveEnd`](https://prosemirror.net/docs/ref/version/0.20.0.html#view.Decoration^inline^spec.inclusiveEnd) so that they also make sense in right-to-left text. The old names work with a warning until the next release. + +The default styling for lists and blockquotes was removed from `prosemirror.css`. (They were moved to the [`example-setup`](https://github.com/ProseMirror/prosemirror-example-setup) module.) + +### Bug fixes + +Fixes reading of selection in Chrome in a shadow DOM. + +Registering DOM event handlers that the editor doesn't listen to by default with the `handleDOMEvents` prop should work again. + +Backspacing after turning off a mark now works again in Firefox. + +### New features + +The new props [`handlePaste`](https://prosemirror.net/docs/ref/version/0.20.0.html#view.EditorProps.handlePaste) and [`handleDrop`](https://prosemirror.net/docs/ref/version/0.20.0.html#view.EditorProps.handleDrop) can be used to override drop and paste behavior. + +## 0.19.1 (2017-03-18) + +### Bug fixes + +Fixes a number of issues with characters being duplicated or disappearing when typing on mark boundaries. + +## 0.19.0 (2017-03-16) + +### Breaking changes + +[`endOfTextblock`](https://prosemirror.net/docs/ref/version/0.19.0.html#view.EditorView.endOfTextblock) no longer always returns false for horizontal motion on non-cursor selections, but checks the position of the selection head instead. + +### Bug fixes + +Typing after adding/removing a mark no longer briefly shows the new text with the wrong marks. + +[`posAtCoords`](https://prosemirror.net/docs/ref/version/0.19.0.html#view.EditorView.posAtCoords) is now more reliable on modern browsers by using browser APIs. + +Fix a bug where the view would in some circumstances leave superfluous DOM nodes around inside marks. + +### New features + +You can now override the selection the editor creates for a given DOM selection with the [`createSelectionBetween`](https://prosemirror.net/docs/ref/version/0.19.0.html#view.EditorProps.createSelectionBetween) prop. + +## 0.18.0 (2017-02-24) + +### Breaking changes + +`Decoration` objects now store their definition object under [`spec`](https://prosemirror.net/docs/ref/version/0.18.0.html#Decoration.spec), not `options`. The old property name still works, with a warning, until the next release. + +### Bug fixes + +Fix bug where calling [`focus`](https://prosemirror.net/docs/ref/version/0.18.0.html#view.EditorView.focus) when there was a text selection would sometimes result in `state.selection` receiving an incorrect value. + +[`EditorView.props`](https://prosemirror.net/docs/ref/version/0.18.0.html#view.EditorView.props) now has its `state` property updated when you call `updateState`. + +Putting decorations on or inside a node view with an `update` method now works. + +### New features + +[Plugin view](https://prosemirror.net/docs/ref/version/0.18.0.html#state.PluginSpec.view) update methods are now passed the view's previous state as second argument. + +The `place` agument to the [`EditorView` constructor](https://prosemirror.net/docs/ref/version/0.18.0.html#view.EditorView) can now be an object with a `mount` property to directly provide the node that should be made editable. + +The new [`EditorView.setProps` method](https://prosemirror.net/docs/ref/version/0.18.0.html#view.EditorView.setProps) makes it easier to update individual props. + +## 0.17.7 (2017-02-08) + +### Bug fixes + +Fixes crash in the code that maintains the scroll position when the document is empty or hidden. + +## 0.17.6 (2017-02-08) + +### Bug fixes + +Transactions that shouldn't [scroll the selection into view](https://prosemirror.net/docs/ref/version/0.17.0.html#state.transaction.scrollIntoView) now no longer do so. + +## 0.17.4 (2017-02-02) + +### Bug fixes + +Fixes bug where widget decorations would sometimes get parsed as content when editing near them. + +The editor now prevents the behavior of Ctrl-d and Ctrl-h on textblock boundaries on OS X, as intended. + +Make sure long words don't cause a horizontal scrollbar in Firefox + +Various behavior fixes for IE11. + +## 0.17.3 (2017-01-19) + +### Bug fixes + +DOM changes deleting a node's inner wrapping DOM element (for example the `` tag in a schema-basic code block) no longer break the editor. + +## 0.17.2 (2017-01-16) + +### Bug fixes + +Call custom click handlers before applying select-node behavior for a ctrl/cmd-click. + +Fix failure to apply DOM changes that start at document position 0. + +## 0.17.1 (2017-01-07) + +### Bug fixes + +Fix issue where a document update that left the selection in the same place sometimes led to an incorrect DOM selection. + +Make sure [`EditorView.focus`](https://prosemirror.net/docs/ref/version/0.17.0.html#view.EditorView.focus) doesn't cause the browser to scroll the top of the editor into view. + +## 0.17.0 (2017-01-05) + +### Breaking changes + +The `handleDOMEvent` prop has been dropped in favor of the [`handleDOMEvents`](https://prosemirror.net/docs/ref/version/0.17.0.html#view.EditorProps.handleDOMEvents) (plural) prop. + +The `onChange` prop has been replaced by a [`dispatchTransaction`](https://prosemirror.net/docs/ref/version/0.17.0.html#view.EditorProps.dispatchTransaction) prop (which takes a transaction instead of an action). + +### New features + +Added support for a [`handleDOMEvents` prop](https://prosemirror.net/docs/ref/version/0.17.0.html#view.EditorProps.handleDOMEvents), which allows you to provide handler functions per DOM event, and works even for events that the editor doesn't normally add a handler for. + +Add view method [`dispatch`](https://prosemirror.net/docs/ref/version/0.17.0.html#view.EditorView.dispatch), which provides a convenient way to dispatch transactions. + +The [`dispatchTransaction`](https://prosemirror.net/docs/ref/version/0.17.0.html#view.EditorProps.dispatchTransaction) (used to be `onAction`) prop is now optional, and will default to simply applying the transaction to the current view state. + +[Widget decorations](https://prosemirror.net/docs/ref/version/0.17.0.html#view.Decoration.widget) now accept an option `associative` which can be used to configure on which side of content inserted at their position they end up. + +Typing immediately after deleting text now preserves the marks of the deleted text. + +Transactions that update the selection because of mouse or touch input now get a metadata property `pointer` with the value `true`. + +## 0.16.0 (2016-12-23) + +### Bug fixes + +Solve problem where setting a node selection would trigger a DOM read, leading to the selection being reset. + +## 0.16.0 (2016-12-23) + +### Breaking changes + +The `spellcheck`, `label`, and `class` props are now replaced by an [`attributes` prop](https://prosemirror.net/docs/ref/version/0.16.0.html#view.EditorProps.attributes). + +### Bug fixes + +Ignoring/aborting an action should no longer lead to the DOM being stuck in an outdated state. + +Typing at the end of a textblock which ends in a non-text node now actually works. + +DOM nodes for leaf document nodes are now set as non-editable to prevent various issues such as stray cursors inside of them and Firefox adding image resize controls. + +Inserting a node no longer causes nodes of the same type after it to be neednessly redrawn. + +### New features + +Add a new editor prop [`editable`](https://prosemirror.net/docs/ref/version/0.16.0.html#view.EditorProps.editable) which controls whether the editor's `contentEditable` behavior is enabled. + +Plugins and props can now set any DOM attribute on the outer editor node using the [`attributes` prop](https://prosemirror.net/docs/ref/version/0.16.0.html#view.EditorProps.attributes). + +Node view constructors and update methods now have access to the node's wrapping decorations, which can be used to pass information to a node view without encoding it in the document. + +Attributes added or removed by node and inline [decorations](https://prosemirror.net/docs/ref/version/0.16.0.html#view.Decoration) no longer cause the nodes inside of them to be fully redrawn, making node views more stable and allowing CSS transitions to be used. + +## 0.15.2 (2016-12-10) + +### Bug fixes + +The native selection is now appropriately hidden when there is a node selection. + +## 0.15.1 (2016-12-10) + +### Bug fixes + +Fix DOM parsing for decorated text nodes. + +## 0.15.0 (2016-12-10) + +### Breaking changes + +The editor view no longer wraps its editable DOM element in a wrapper element. The `ProseMirror` CSS class now applies directly to the editable element. The `ProseMirror-content` CSS class is still present for ease of upgrading but will be dropped in the next release. + +The editor view no longer draws a drop cursor when dragging content over the editor. The new [`prosemirror-dropcursor`](https://github.com/prosemirror/prosemirror-dropcursor) module implements this as a plugin. + +### Bug fixes + +Simple typing and backspacing now gets handled by the browser without ProseMirror redrawing the touched nodes, making spell-checking and various platform-specific input tricks (long-press on OS X, double space on iOS) work in the editor. + +Improve tracking of DOM nodes that have been touched by user changes, so that [`updateState`](https://prosemirror.net/docs/ref/version/0.15.0.html#view.EditorView.updateState) can reliably fix them. + +Changes to the document that happen while dragging editor content no longer break moving of the content. + +Adding or removing a mark directly in the DOM (for example with the bold/italic buttons in iOS' context menu) now produces mark steps, rather than replace steps. + +Pressing backspace at the start of a paragraph on Android now allows key handlers for backspace to fire. + +Toggling a mark when there is no selection now works better on mobile platforms. + +### New features + +Introduces an [`endOfTextblock`](https://prosemirror.net/docs/ref/version/0.15.0.html#view.EditorView.endOfTextblock) method on views, which can be used to find out in a bidi- and layout-aware way whether the selection is on the edge of a textblock. + +## 0.14.4 (2016-12-02) + +### Bug fixes + +Fix issue where node decorations would stick around in the DOM after the decoration was removed. + +Setting or removing a node selection in an unfocused editor now properly updates the DOM to show that selection. + +## 0.14.2 (2016-11-30) + +### Bug fixes + +FIX: Avoid unneeded selection resets which sometimes confused browsers. + +## 0.14.2 (2016-11-29) + +### Bug fixes + +Fix a bug where inverted selections weren't created in the DOM correctly. + +## 0.14.1 (2016-11-29) + +### Bug fixes + +Restores previously broken kludge that allows the cursor to appear after non-text content at the end of a line. + +## 0.14.0 (2016-11-28) + +### Breaking changes + +Wrapping decorations are now created using the [`nodeName`](https://prosemirror.net/docs/ref/version/0.14.0.html#view.DecorationAttrs.nodeName) property. The `wrapper` property is no longer supported. + +The `onUnmountDOM` prop is no longer supported (use a node view with a [`destroy`](https://prosemirror.net/docs/ref/version/0.14.0.html#view.NodeView.destroy) method instead). + +The `domSerializer` prop is no longer supported. Use [node views](https://prosemirror.net/docs/ref/version/0.14.0.html#view.EditorProps.nodeViews) to configure editor-specific node representations. + +### New features + +Widget decorations can now be given a [`key`](https://prosemirror.net/docs/ref/version/0.14.0.html#view.Decoration.widget^options.key) property to prevent unneccesary redraws. + +The `EditorView` class now has a [`destroy`](https://prosemirror.net/docs/ref/version/0.14.0.html#view.EditorView.destroy) method for cleaning up. + +The [`handleClickOn`](https://prosemirror.net/docs/ref/version/0.14.0.html#view.EditorProps.handleClickOn) prop and friends now receive a `direct` boolean argument that indicates whether the node was clicked directly. + +[Widget decorations](https://prosemirror.net/docs/ref/version/0.14.0.html#view.Decoration^widget) now support a `stopEvent` option that can be used to control which DOM events that pass through them should be ignored by the editor view. + +You can now [specify](https://prosemirror.net/docs/ref/version/0.14.0.html#view.EditorProps.nodeViews) custom [node views](https://prosemirror.net/docs/ref/version/0.14.0.html#view.NodeView) for an editor view, which give you control over the way node of a given type are represented in the DOM. See the related [RFC](https://discuss.prosemirror.net/t/rfc-node-views-to-manage-the-representation-of-nodes/463). + +## 0.13.2 (2016-11-15) + +### Bug fixes + +Fixes an issue where widget decorations in the middle of text nodes would sometimes disappear. + +## 0.13.1 (2016-11-15) + +### Bug fixes + +Fixes event handler crash (and subsequent bad default behavior) when pasting some types of external HTML into an editor. + +## 0.13.0 (2016-11-11) + +### Breaking changes + +Selecting nodes on OS X is now done with cmd-leftclick rather than ctrl-leftclick. + +### Bug fixes + +Pasting text into a code block will now insert the raw text. + +Widget decorations at the start or end of a textblock no longer block horizontal cursor motion through them. + +Widget nodes at the end of textblocks are now reliably drawn during display updates. + +### New features + +[`DecorationSet.map`](https://prosemirror.net/docs/ref/version/0.13.0.html#view.DecorationSet.map) now takes an options object which allows you to specify an `onRemove` callback to be notified when remapping drops decorations. + +The [`transformPastedHTML`](https://prosemirror.net/docs/ref/version/0.13.0.html#view.EditorProps.transformPastedHTML) and [`transformPastedText`](https://prosemirror.net/docs/ref/version/0.13.0.html#view.EditorProps.transformPastedText) props were (re-)added, and can be used to clean up pasted content. + +## 0.12.2 (2016-11-02) + +### Bug fixes + +Inline decorations that span across an empty textblock no longer crash the display drawing code. + +## 0.12.1 (2016-11-01) + +### Bug fixes + +Use a separate document to parse pasted HTML to better protect +against cross-site scripting attacks. + +Specifying multiple classes in a decoration now actually works. + +Ignore empty inline decorations when building a decoration set. + +## 0.12.0 (2016-10-21) + +### Breaking changes + +The return value of +[`EditorView.posAtCoords`](https://prosemirror.net/docs/ref/version/0.12.0.html#view.EditorView.posAtCoords) changed to +contain an `inside` property pointing at the innermost node that the +coordinates are inside of. (Note that the docs for this method were +wrong in the previous release.) + +### Bug fixes + +Reduce reliance on shift-state tracking to minimize damage when +it gets out of sync. + +Fix bug that'd produce bogus document positions for DOM positions +inside non-document nodes. + +Don't treat fast ctrl-clicks as double or triple clicks. + +### New features + +Implement [decorations](https://prosemirror.net/docs/ref/version/0.12.0.html#view.Decoration), a way to +influence the way the document is drawn. Add the [`decorations` +prop](https://prosemirror.net/docs/ref/version/0.12.0.html#view.EditorProps.decorations) to specify them. + +## 0.11.2 (2016-10-04) + +### Bug fixes + +Pass actual event object to [`handleDOMEvent`](https://prosemirror.net/docs/ref/version/0.11.0.html#view.EditorProps.handleDOMEvent), rather than just its name. + +Fix display corruption caused by using the wrong state as previous version during IME. + +## 0.11.0 (2016-09-21) + +### Breaking changes + +Moved into a separate module from the old `edit` submodule. Completely +new approach to managing the editor's DOM representation and input. + +Event handlers and options are now replaced by +[props](https://prosemirror.net/docs/ref/version/0.11.0.html#view.EditorProps). The view's state is now 'shallow', +represented entirely by a set of props, one of which holds an editor +state value from the [state](https://prosemirror.net/docs/ref/version/0.11.0.html#state) module. + +When the user interacts with the editor, it will pass an +[action](https://prosemirror.net/docs/ref/version/0.11.0.html#state.Action) to its +[`onAction`](https://prosemirror.net/docs/ref/version/0.11.0.html#view.EditorProps.onAction) prop, which is responsible +for triggering an view update. + +The `markRange` system was dropped, to be replaced in the next release +by a 'decoration' system. + +There is no keymap support in the view module anymore. Use a +[keymap](https://prosemirror.net/docs/ref/version/0.11.0.html#keymap) plugin for that. + +The undo [history](https://prosemirror.net/docs/ref/version/0.11.0.html#history) is now a separate plugin. + +CSS needed by the editor is no longer injected implicitly into the +page. Instead, you should arrange for the `style/prosemirror.css` file +to be loaded into your page. + +### New features + +The DOM [parser](https://prosemirror.net/docs/ref/version/0.11.0.html#model.DOMParser) and +[serializer](https://prosemirror.net/docs/ref/version/0.11.0.html#model.DOMSerializer) used to interact with the visible +DOM and the clipboard can now be customized through +[props](https://prosemirror.net/docs/ref/version/0.11.0.html#view.EditorProps). + +You can now provide a catch-all DOM +[event handler](https://prosemirror.net/docs/ref/version/0.11.0.html#view.EditorProps.handleDOMEvent) to get a first +chance at handling DOM events. + +The [`onUnmountDOM`](https://prosemirror.net/docs/ref/version/0.11.0.html#view.EditorProps.onUnmountDOM) can be used to +be notified when a piece of the document DOM is thrown away (in case +cleanup is needed). + diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/CONTRIBUTING.md b/packages/tiptap-extensions/node_modules/prosemirror-view/CONTRIBUTING.md new file mode 100644 index 0000000000..f2a345d830 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/CONTRIBUTING.md @@ -0,0 +1,104 @@ +# How to contribute + +- [Getting help](#getting-help) +- [Submitting bug reports](#submitting-bug-reports) +- [Contributing code](#contributing-code) + +## Getting help + +Community discussion, questions, and informal bug reporting is done on the +[discuss.ProseMirror forum](http://discuss.prosemirror.net). + +## Submitting bug reports + +Report bugs on the +[GitHub issue tracker](http://github.com/prosemirror/prosemirror/issues). +Before reporting a bug, please read these pointers. + +- The issue tracker is for *bugs*, not requests for help. Questions + should be asked on the [forum](http://discuss.prosemirror.net). + +- Include information about the version of the code that exhibits the + problem. For browser-related issues, include the browser and browser + version on which the problem occurred. + +- Mention very precisely what went wrong. "X is broken" is not a good + bug report. What did you expect to happen? What happened instead? + Describe the exact steps a maintainer has to take to make the + problem occur. A screencast can be useful, but is no substitute for + a textual description. + +- A great way to make it easy to reproduce your problem, if it can not + be trivially reproduced on the website demos, is to submit a script + that triggers the issue. + +## Contributing code + +If you want to make a change that involves a significant overhaul of +the code or introduces a user-visible new feature, create an +[RFC](https://github.com/ProseMirror/rfcs/) first with your proposal. + +- Make sure you have a [GitHub Account](https://github.com/signup/free) + +- Fork the relevant repository + ([how to fork a repo](https://help.github.com/articles/fork-a-repo)) + +- Create a local checkout of the code. You can use the + [main repository](https://github.com/prosemirror/prosemirror) to + easily check out all core modules. + +- Make your changes, and commit them + +- Follow the code style of the rest of the project (see below). Run + `npm run lint` (in the main repository checkout) to make sure that + the linter is happy. + +- If your changes are easy to test or likely to regress, add tests in + the relevant `test/` directory. Either put them in an existing + `test-*.js` file, if they fit there, or add a new file. + +- Make sure all tests pass. Run `npm run test` to verify tests pass + (you will need Node.js v6+). + +- Submit a pull request ([how to create a pull request](https://help.github.com/articles/fork-a-repo)). + Don't put more than one feature/fix in a single pull request. + +By contributing code to ProseMirror you + + - Agree to license the contributed code under the project's [MIT + license](https://github.com/ProseMirror/prosemirror/blob/master/LICENSE). + + - Confirm that you have the right to contribute and license the code + in question. (Either you hold all rights on the code, or the rights + holder has explicitly granted the right to use it like this, + through a compatible open source license or through a direct + agreement with you.) + +### Coding standards + +- ES6 syntax, targeting an ES5 runtime (i.e. don't use library + elements added by ES6, don't use ES7/ES.next syntax). + +- 2 spaces per indentation level, no tabs. + +- No semicolons except when necessary. + +- Follow the surrounding code when it comes to spacing, brace + placement, etc. + +- Brace-less single-statement bodies are encouraged (whenever they + don't impact readability). + +- [getdocs](https://github.com/marijnh/getdocs)-style doc comments + above items that are part of the public API. + +- When documenting non-public items, you can put the type after a + single colon, so that getdocs doesn't pick it up and add it to the + API reference. + +- The linter (`npm run lint`) complains about unused variables and + functions. Prefix their names with an underscore to muffle it. + +- ProseMirror does *not* follow JSHint or JSLint prescribed style. + Patches that try to 'fix' code to pass one of these linters will not + be accepted. diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/LICENSE b/packages/tiptap-extensions/node_modules/prosemirror-view/LICENSE new file mode 100644 index 0000000000..ef9326c512 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2015-2017 by Marijn Haverbeke and others + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/README.md b/packages/tiptap-extensions/node_modules/prosemirror-view/README.md new file mode 100644 index 0000000000..e83dfb7e06 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/README.md @@ -0,0 +1,28 @@ +# prosemirror-view + +[ [**WEBSITE**](https://prosemirror.net) | [**ISSUES**](https://github.com/prosemirror/prosemirror/issues) | [**FORUM**](https://discuss.prosemirror.net) | [**GITTER**](https://gitter.im/ProseMirror/prosemirror) | [**CHANGELOG**](https://github.com/ProseMirror/prosemirror-view/blob/master/CHANGELOG.md) ] + +This is a [core module](https://prosemirror.net/docs/ref/#view) of [ProseMirror](https://prosemirror.net). +ProseMirror is a well-behaved rich semantic content editor based on +contentEditable, with support for collaborative editing and custom +document schemas. + +This [module](https://prosemirror.net/docs/ref/#view) exports the editor +view, which renders the current document in the browser, and handles +user events. + +The [project page](https://prosemirror.net) has more information, a +number of [examples](https://prosemirror.net/examples/) and the +[documentation](https://prosemirror.net/docs/). + +This code is released under an +[MIT license](https://github.com/prosemirror/prosemirror/tree/master/LICENSE). +There's a [forum](http://discuss.prosemirror.net) for general +discussion and support requests, and the +[Github bug tracker](https://github.com/prosemirror/prosemirror/issues) +is the place to report issues. + +We aim to be an inclusive, welcoming community. To make that explicit, +we have a [code of +conduct](http://contributor-covenant.org/version/1/1/0/) that applies +to communication around the project. diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/dist/index.es.js b/packages/tiptap-extensions/node_modules/prosemirror-view/dist/index.es.js new file mode 100644 index 0000000000..e4084e773c --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/dist/index.es.js @@ -0,0 +1,4966 @@ +import { TextSelection, Selection, NodeSelection } from 'prosemirror-state'; +import { DOMSerializer, Fragment, Mark, DOMParser, Slice } from 'prosemirror-model'; +import { dropPoint } from 'prosemirror-transform'; + +var result = {}; + +if (typeof navigator != "undefined" && typeof document != "undefined") { + var ie_edge = /Edge\/(\d+)/.exec(navigator.userAgent); + var ie_upto10 = /MSIE \d/.test(navigator.userAgent); + var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent); + + result.mac = /Mac/.test(navigator.platform); + var ie = result.ie = !!(ie_upto10 || ie_11up || ie_edge); + result.ie_version = ie_upto10 ? document.documentMode || 6 : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : null; + result.gecko = !ie && /gecko\/(\d+)/i.test(navigator.userAgent); + result.gecko_version = result.gecko && +(/Firefox\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1]; + var chrome = !ie && /Chrome\/(\d+)/.exec(navigator.userAgent); + result.chrome = !!chrome; + result.chrome_version = chrome && +chrome[1]; + result.ios = !ie && /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent); + result.android = /Android \d/.test(navigator.userAgent); + result.webkit = !ie && 'WebkitAppearance' in document.documentElement.style; + result.safari = /Apple Computer/.test(navigator.vendor); + result.webkit_version = result.webkit && +(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1]; +} + +var domIndex = function(node) { + for (var index = 0;; index++) { + node = node.previousSibling; + if (!node) { return index } + } +}; + +var parentNode = function(node) { + var parent = node.parentNode; + return parent && parent.nodeType == 11 ? parent.host : parent +}; + +var textRange = function(node, from, to) { + var range = document.createRange(); + range.setEnd(node, to == null ? node.nodeValue.length : to); + range.setStart(node, from || 0); + return range +}; + +// Scans forward and backward through DOM positions equivalent to the +// given one to see if the two are in the same place (i.e. after a +// text node vs at the end of that text node) +var isEquivalentPosition = function(node, off, targetNode, targetOff) { + return targetNode && (scanFor(node, off, targetNode, targetOff, -1) || + scanFor(node, off, targetNode, targetOff, 1)) +}; + +var atomElements = /^(img|br|input|textarea|hr)$/i; + +function scanFor(node, off, targetNode, targetOff, dir) { + for (;;) { + if (node == targetNode && off == targetOff) { return true } + if (off == (dir < 0 ? 0 : nodeSize(node))) { + var parent = node.parentNode; + if (parent.nodeType != 1 || hasBlockDesc(node) || atomElements.test(node.nodeName) || node.contentEditable == "false") + { return false } + off = domIndex(node) + (dir < 0 ? 0 : 1); + node = parent; + } else if (node.nodeType == 1) { + node = node.childNodes[off + (dir < 0 ? -1 : 0)]; + off = dir < 0 ? nodeSize(node) : 0; + } else { + return false + } + } +} + +function nodeSize(node) { + return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length +} + +function hasBlockDesc(dom) { + var desc; + for (var cur = dom; cur; cur = cur.parentNode) { if (desc = cur.pmViewDesc) { break } } + return desc && desc.node && desc.node.isBlock && (desc.dom == dom || desc.contentDOM == dom) +} + +// Work around Chrome issue https://bugs.chromium.org/p/chromium/issues/detail?id=447523 +// (isCollapsed inappropriately returns true in shadow dom) +var selectionCollapsed = function(domSel) { + var collapsed = domSel.isCollapsed; + if (collapsed && result.chrome && domSel.rangeCount && !domSel.getRangeAt(0).collapsed) + { collapsed = false; } + return collapsed +}; + +function keyEvent(keyCode, key) { + var event = document.createEvent("Event"); + event.initEvent("keydown", true, true); + event.keyCode = keyCode; + event.key = event.code = key; + return event +} + +function windowRect(win) { + return {left: 0, right: win.innerWidth, + top: 0, bottom: win.innerHeight} +} + +function getSide(value, side) { + return typeof value == "number" ? value : value[side] +} + +function scrollRectIntoView(view, rect, startDOM) { + var scrollThreshold = view.someProp("scrollThreshold") || 0, scrollMargin = view.someProp("scrollMargin") || 5; + var doc = view.dom.ownerDocument, win = doc.defaultView; + for (var parent = startDOM || view.dom;; parent = parentNode(parent)) { + if (!parent) { break } + if (parent.nodeType != 1) { continue } + var atTop = parent == doc.body || parent.nodeType != 1; + var bounding = atTop ? windowRect(win) : parent.getBoundingClientRect(); + var moveX = 0, moveY = 0; + if (rect.top < bounding.top + getSide(scrollThreshold, "top")) + { moveY = -(bounding.top - rect.top + getSide(scrollMargin, "top")); } + else if (rect.bottom > bounding.bottom - getSide(scrollThreshold, "bottom")) + { moveY = rect.bottom - bounding.bottom + getSide(scrollMargin, "bottom"); } + if (rect.left < bounding.left + getSide(scrollThreshold, "left")) + { moveX = -(bounding.left - rect.left + getSide(scrollMargin, "left")); } + else if (rect.right > bounding.right - getSide(scrollThreshold, "right")) + { moveX = rect.right - bounding.right + getSide(scrollMargin, "right"); } + if (moveX || moveY) { + if (atTop) { + win.scrollBy(moveX, moveY); + } else { + if (moveY) { parent.scrollTop += moveY; } + if (moveX) { parent.scrollLeft += moveX; } + } + } + if (atTop) { break } + } +} + +// Store the scroll position of the editor's parent nodes, along with +// the top position of an element near the top of the editor, which +// will be used to make sure the visible viewport remains stable even +// when the size of the content above changes. +function storeScrollPos(view) { + var rect = view.dom.getBoundingClientRect(), startY = Math.max(0, rect.top); + var refDOM, refTop; + for (var x = (rect.left + rect.right) / 2, y = startY + 1; + y < Math.min(innerHeight, rect.bottom); y += 5) { + var dom = view.root.elementFromPoint(x, y); + if (dom == view.dom || !view.dom.contains(dom)) { continue } + var localRect = dom.getBoundingClientRect(); + if (localRect.top >= startY - 20) { + refDOM = dom; + refTop = localRect.top; + break + } + } + return {refDOM: refDOM, refTop: refTop, stack: scrollStack(view.dom)} +} + +function scrollStack(dom) { + var stack = [], doc = dom.ownerDocument; + for (; dom; dom = parentNode(dom)) { + stack.push({dom: dom, top: dom.scrollTop, left: dom.scrollLeft}); + if (dom == doc) { break } + } + return stack +} + +// Reset the scroll position of the editor's parent nodes to that what +// it was before, when storeScrollPos was called. +function resetScrollPos(ref) { + var refDOM = ref.refDOM; + var refTop = ref.refTop; + var stack = ref.stack; + + var newRefTop = refDOM ? refDOM.getBoundingClientRect().top : 0; + restoreScrollStack(stack, newRefTop == 0 ? 0 : newRefTop - refTop); +} + +function restoreScrollStack(stack, dTop) { + for (var i = 0; i < stack.length; i++) { + var ref = stack[i]; + var dom = ref.dom; + var top = ref.top; + var left = ref.left; + if (dom.scrollTop != top + dTop) { dom.scrollTop = top + dTop; } + if (dom.scrollLeft != left) { dom.scrollLeft = left; } + } +} + +var preventScrollSupported = null; +// Feature-detects support for .focus({preventScroll: true}), and uses +// a fallback kludge when not supported. +function focusPreventScroll(dom) { + if (dom.setActive) { return dom.setActive() } // in IE + if (preventScrollSupported) { return dom.focus(preventScrollSupported) } + + var stored = scrollStack(dom); + dom.focus(preventScrollSupported == null ? { + get preventScroll() { + preventScrollSupported = {preventScroll: true}; + return true + } + } : undefined); + if (!preventScrollSupported) { + preventScrollSupported = false; + restoreScrollStack(stored, 0); + } +} + +function findOffsetInNode(node, coords) { + var closest, dxClosest = 2e8, coordsClosest, offset = 0; + var rowBot = coords.top, rowTop = coords.top; + for (var child = node.firstChild, childIndex = 0; child; child = child.nextSibling, childIndex++) { + var rects = (void 0); + if (child.nodeType == 1) { rects = child.getClientRects(); } + else if (child.nodeType == 3) { rects = textRange(child).getClientRects(); } + else { continue } + + for (var i = 0; i < rects.length; i++) { + var rect = rects[i]; + if (rect.top <= rowBot && rect.bottom >= rowTop) { + rowBot = Math.max(rect.bottom, rowBot); + rowTop = Math.min(rect.top, rowTop); + var dx = rect.left > coords.left ? rect.left - coords.left + : rect.right < coords.left ? coords.left - rect.right : 0; + if (dx < dxClosest) { + closest = child; + dxClosest = dx; + coordsClosest = dx && closest.nodeType == 3 ? {left: rect.right < coords.left ? rect.right : rect.left, top: coords.top} : coords; + if (child.nodeType == 1 && dx) + { offset = childIndex + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0); } + continue + } + } + if (!closest && (coords.left >= rect.right && coords.top >= rect.top || + coords.left >= rect.left && coords.top >= rect.bottom)) + { offset = childIndex + 1; } + } + } + if (closest && closest.nodeType == 3) { return findOffsetInText(closest, coordsClosest) } + if (!closest || (dxClosest && closest.nodeType == 1)) { return {node: node, offset: offset} } + return findOffsetInNode(closest, coordsClosest) +} + +function findOffsetInText(node, coords) { + var len = node.nodeValue.length; + var range = document.createRange(); + for (var i = 0; i < len; i++) { + range.setEnd(node, i + 1); + range.setStart(node, i); + var rect = singleRect(range, 1); + if (rect.top == rect.bottom) { continue } + if (inRect(coords, rect)) + { return {node: node, offset: i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0)} } + } + return {node: node, offset: 0} +} + +function inRect(coords, rect) { + return coords.left >= rect.left - 1 && coords.left <= rect.right + 1&& + coords.top >= rect.top - 1 && coords.top <= rect.bottom + 1 +} + +function targetKludge(dom, coords) { + var parent = dom.parentNode; + if (parent && /^li$/i.test(parent.nodeName) && coords.left < dom.getBoundingClientRect().left) + { return parent } + return dom +} + +function posFromElement(view, elt, coords) { + var ref = findOffsetInNode(elt, coords); + var node = ref.node; + var offset = ref.offset; + var bias = -1; + if (node.nodeType == 1 && !node.firstChild) { + var rect = node.getBoundingClientRect(); + bias = rect.left != rect.right && coords.left > (rect.left + rect.right) / 2 ? 1 : -1; + } + return view.docView.posFromDOM(node, offset, bias) +} + +function posFromCaret(view, node, offset, coords) { + // Browser (in caretPosition/RangeFromPoint) will agressively + // normalize towards nearby inline nodes. Since we are interested in + // positions between block nodes too, we first walk up the hierarchy + // of nodes to see if there are block nodes that the coordinates + // fall outside of. If so, we take the position before/after that + // block. If not, we call `posFromDOM` on the raw node/offset. + var outside = -1; + for (var cur = node;;) { + if (cur == view.dom) { break } + var desc = view.docView.nearestDesc(cur, true); + if (!desc) { return null } + if (desc.node.isBlock && desc.parent) { + var rect = desc.dom.getBoundingClientRect(); + if (rect.left > coords.left || rect.top > coords.top) { outside = desc.posBefore; } + else if (rect.right < coords.left || rect.bottom < coords.top) { outside = desc.posAfter; } + else { break } + } + cur = desc.dom.parentNode; + } + return outside > -1 ? outside : view.docView.posFromDOM(node, offset) +} + +function elementFromPoint(element, coords, box) { + var len = element.childNodes.length; + if (len && box.top < box.bottom) { + for (var startI = Math.max(0, Math.min(len - 1, Math.floor(len * (coords.top - box.top) / (box.bottom - box.top)) - 2)), i = startI;;) { + var child = element.childNodes[i]; + if (child.nodeType == 1) { + var rects = child.getClientRects(); + for (var j = 0; j < rects.length; j++) { + var rect = rects[j]; + if (inRect(coords, rect)) { return elementFromPoint(child, coords, rect) } + } + } + if ((i = (i + 1) % len) == startI) { break } + } + } + return element +} + +// Given an x,y position on the editor, get the position in the document. +function posAtCoords(view, coords) { + var assign, assign$1; + + var root = view.root, node, offset; + if (root.caretPositionFromPoint) { + try { // Firefox throws for this call in hard-to-predict circumstances (#994) + var pos$1 = root.caretPositionFromPoint(coords.left, coords.top); + if (pos$1) { ((assign = pos$1, node = assign.offsetNode, offset = assign.offset)); } + } catch (_) {} + } + if (!node && root.caretRangeFromPoint) { + var range = root.caretRangeFromPoint(coords.left, coords.top); + if (range) { ((assign$1 = range, node = assign$1.startContainer, offset = assign$1.startOffset)); } + } + + var elt = root.elementFromPoint(coords.left, coords.top + 1), pos; + if (!elt || !view.dom.contains(elt.nodeType != 1 ? elt.parentNode : elt)) { + var box = view.dom.getBoundingClientRect(); + if (!inRect(coords, box)) { return null } + elt = elementFromPoint(view.dom, coords, box); + if (!elt) { return null } + } + elt = targetKludge(elt, coords); + if (node) { + if (result.gecko && node.nodeType == 1) { + // Firefox will sometimes return offsets into nodes, which + // have no actual children, from caretPositionFromPoint (#953) + offset = Math.min(offset, node.childNodes.length); + // It'll also move the returned position before image nodes, + // even if those are behind it. + if (offset < node.childNodes.length) { + var next = node.childNodes[offset], box$1; + if (next.nodeName == "IMG" && (box$1 = next.getBoundingClientRect()).right <= coords.left && + box$1.bottom > coords.top) + { offset++; } + } + } + // Suspiciously specific kludge to work around caret*FromPoint + // never returning a position at the end of the document + if (node == view.dom && offset == node.childNodes.length - 1 && node.lastChild.nodeType == 1 && + coords.top > node.lastChild.getBoundingClientRect().bottom) + { pos = view.state.doc.content.size; } + // Ignore positions directly after a BR, since caret*FromPoint + // 'round up' positions that would be more accurately placed + // before the BR node. + else if (offset == 0 || node.nodeType != 1 || node.childNodes[offset - 1].nodeName != "BR") + { pos = posFromCaret(view, node, offset, coords); } + } + if (pos == null) { pos = posFromElement(view, elt, coords); } + + var desc = view.docView.nearestDesc(elt, true); + return {pos: pos, inside: desc ? desc.posAtStart - desc.border : -1} +} + +function singleRect(object, bias) { + var rects = object.getClientRects(); + return !rects.length ? object.getBoundingClientRect() : rects[bias < 0 ? 0 : rects.length - 1] +} + +// : (EditorView, number) → {left: number, top: number, right: number, bottom: number} +// Given a position in the document model, get a bounding box of the +// character at that position, relative to the window. +function coordsAtPos(view, pos) { + var ref = view.docView.domFromPos(pos); + var node = ref.node; + var offset = ref.offset; + + // These browsers support querying empty text ranges + if (node.nodeType == 3 && (result.chrome || result.gecko)) { + var rect = singleRect(textRange(node, offset, offset), 0); + // Firefox returns bad results (the position before the space) + // when querying a position directly after line-broken + // whitespace. Detect this situation and and kludge around it + if (result.gecko && offset && /\s/.test(node.nodeValue[offset - 1]) && offset < node.nodeValue.length) { + var rectBefore = singleRect(textRange(node, offset - 1, offset - 1), -1); + if (Math.abs(rectBefore.left - rect.left) < 1 && rectBefore.top == rect.top) { + var rectAfter = singleRect(textRange(node, offset, offset + 1), -1); + return flattenV(rectAfter, rectAfter.left < rectBefore.left) + } + } + return rect + } + + if (node.nodeType == 1 && !view.state.doc.resolve(pos).parent.inlineContent) { + // Return a horizontal line in block context + var top = true, rect$1; + if (offset < node.childNodes.length) { + var after = node.childNodes[offset]; + if (after.nodeType == 1) { rect$1 = after.getBoundingClientRect(); } + } + if (!rect$1 && offset) { + var before = node.childNodes[offset - 1]; + if (before.nodeType == 1) { rect$1 = before.getBoundingClientRect(); top = false; } + } + return flattenH(rect$1 || node.getBoundingClientRect(), top) + } + + // Not Firefox/Chrome, or not in a text node, so we have to use + // actual element/character rectangles to get a solution (this part + // is not very bidi-safe) + // + // Try the left side first, fall back to the right one if that + // doesn't work. + for (var dir = -1; dir < 2; dir += 2) { + if (dir < 0 && offset) { + var prev = (void 0), target = node.nodeType == 3 ? textRange(node, offset - 1, offset) + : (prev = node.childNodes[offset - 1]).nodeType == 3 ? textRange(prev) + : prev.nodeType == 1 && prev.nodeName != "BR" ? prev : null; // BR nodes tend to only return the rectangle before them + if (target) { + var rect$2 = singleRect(target, 1); + if (rect$2.top < rect$2.bottom) { return flattenV(rect$2, false) } + } + } else if (dir > 0 && offset < nodeSize(node)) { + var next = (void 0), target$1 = node.nodeType == 3 ? textRange(node, offset, offset + 1) + : (next = node.childNodes[offset]).nodeType == 3 ? textRange(next) + : next.nodeType == 1 ? next : null; + if (target$1) { + var rect$3 = singleRect(target$1, -1); + if (rect$3.top < rect$3.bottom) { return flattenV(rect$3, true) } + } + } + } + // All else failed, just try to get a rectangle for the target node + return flattenV(singleRect(node.nodeType == 3 ? textRange(node) : node, 0), false) +} + +function flattenV(rect, left) { + if (rect.width == 0) { return rect } + var x = left ? rect.left : rect.right; + return {top: rect.top, bottom: rect.bottom, left: x, right: x} +} + +function flattenH(rect, top) { + if (rect.height == 0) { return rect } + var y = top ? rect.top : rect.bottom; + return {top: y, bottom: y, left: rect.left, right: rect.right} +} + +function withFlushedState(view, state, f) { + var viewState = view.state, active = view.root.activeElement; + if (viewState != state) { view.updateState(state); } + if (active != view.dom) { view.focus(); } + try { + return f() + } finally { + if (viewState != state) { view.updateState(viewState); } + if (active != view.dom) { active.focus(); } + } +} + +// : (EditorView, number, number) +// Whether vertical position motion in a given direction +// from a position would leave a text block. +function endOfTextblockVertical(view, state, dir) { + var sel = state.selection; + var $pos = dir == "up" ? sel.$anchor.min(sel.$head) : sel.$anchor.max(sel.$head); + return withFlushedState(view, state, function () { + var ref = view.docView.domFromPos($pos.pos); + var dom = ref.node; + for (;;) { + var nearest = view.docView.nearestDesc(dom, true); + if (!nearest) { break } + if (nearest.node.isBlock) { dom = nearest.dom; break } + dom = nearest.dom.parentNode; + } + var coords = coordsAtPos(view, $pos.pos); + for (var child = dom.firstChild; child; child = child.nextSibling) { + var boxes = (void 0); + if (child.nodeType == 1) { boxes = child.getClientRects(); } + else if (child.nodeType == 3) { boxes = textRange(child, 0, child.nodeValue.length).getClientRects(); } + else { continue } + for (var i = 0; i < boxes.length; i++) { + var box = boxes[i]; + if (box.bottom > box.top && (dir == "up" ? box.bottom < coords.top + 1 : box.top > coords.bottom - 1)) + { return false } + } + } + return true + }) +} + +var maybeRTL = /[\u0590-\u08ac]/; + +function endOfTextblockHorizontal(view, state, dir) { + var ref = state.selection; + var $head = ref.$head; + if (!$head.parent.isTextblock) { return false } + var offset = $head.parentOffset, atStart = !offset, atEnd = offset == $head.parent.content.size; + var sel = getSelection(); + // If the textblock is all LTR, or the browser doesn't support + // Selection.modify (Edge), fall back to a primitive approach + if (!maybeRTL.test($head.parent.textContent) || !sel.modify) + { return dir == "left" || dir == "backward" ? atStart : atEnd } + + return withFlushedState(view, state, function () { + // This is a huge hack, but appears to be the best we can + // currently do: use `Selection.modify` to move the selection by + // one character, and see if that moves the cursor out of the + // textblock (or doesn't move it at all, when at the start/end of + // the document). + var oldRange = sel.getRangeAt(0), oldNode = sel.focusNode, oldOff = sel.focusOffset; + var oldBidiLevel = sel.caretBidiLevel; // Only for Firefox + sel.modify("move", dir, "character"); + var parentDOM = $head.depth ? view.docView.domAfterPos($head.before()) : view.dom; + var result = !parentDOM.contains(sel.focusNode.nodeType == 1 ? sel.focusNode : sel.focusNode.parentNode) || + (oldNode == sel.focusNode && oldOff == sel.focusOffset); + // Restore the previous selection + sel.removeAllRanges(); + sel.addRange(oldRange); + if (oldBidiLevel != null) { sel.caretBidiLevel = oldBidiLevel; } + return result + }) +} + +var cachedState = null, cachedDir = null, cachedResult = false; +function endOfTextblock(view, state, dir) { + if (cachedState == state && cachedDir == dir) { return cachedResult } + cachedState = state; cachedDir = dir; + return cachedResult = dir == "up" || dir == "down" + ? endOfTextblockVertical(view, state, dir) + : endOfTextblockHorizontal(view, state, dir) +} + +// NodeView:: interface +// +// By default, document nodes are rendered using the result of the +// [`toDOM`](#model.NodeSpec.toDOM) method of their spec, and managed +// entirely by the editor. For some use cases, such as embedded +// node-specific editing interfaces, you want more control over +// the behavior of a node's in-editor representation, and need to +// [define](#view.EditorProps.nodeViews) a custom node view. +// +// Objects returned as node views must conform to this interface. +// +// dom:: ?dom.Node +// The outer DOM node that represents the document node. When not +// given, the default strategy is used to create a DOM node. +// +// contentDOM:: ?dom.Node +// The DOM node that should hold the node's content. Only meaningful +// if the node view also defines a `dom` property and if its node +// type is not a leaf node type. When this is present, ProseMirror +// will take care of rendering the node's children into it. When it +// is not present, the node view itself is responsible for rendering +// (or deciding not to render) its child nodes. +// +// update:: ?(node: Node, decorations: [Decoration]) → bool +// When given, this will be called when the view is updating itself. +// It will be given a node (possibly of a different type), and an +// array of active decorations (which are automatically drawn, and +// the node view may ignore if it isn't interested in them), and +// should return true if it was able to update to that node, and +// false otherwise. If the node view has a `contentDOM` property (or +// no `dom` property), updating its child nodes will be handled by +// ProseMirror. +// +// selectNode:: ?() +// Can be used to override the way the node's selected status (as a +// node selection) is displayed. +// +// deselectNode:: ?() +// When defining a `selectNode` method, you should also provide a +// `deselectNode` method to remove the effect again. +// +// setSelection:: ?(anchor: number, head: number, root: dom.Document) +// This will be called to handle setting the selection inside the +// node. The `anchor` and `head` positions are relative to the start +// of the node. By default, a DOM selection will be created between +// the DOM positions corresponding to those positions, but if you +// override it you can do something else. +// +// stopEvent:: ?(event: dom.Event) → bool +// Can be used to prevent the editor view from trying to handle some +// or all DOM events that bubble up from the node view. Events for +// which this returns true are not handled by the editor. +// +// ignoreMutation:: ?(dom.MutationRecord) → bool +// Called when a DOM +// [mutation](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) +// or a selection change happens within the view. When the change is +// a selection change, the record will have a `type` property of +// `"selection"` (which doesn't occur for native mutation records). +// Return false if the editor should re-read the selection or +// re-parse the range around the mutation, true if it can safely be +// ignored. +// +// destroy:: ?() +// Called when the node view is removed from the editor or the whole +// editor is destroyed. + +// View descriptions are data structures that describe the DOM that is +// used to represent the editor's content. They are used for: +// +// - Incremental redrawing when the document changes +// +// - Figuring out what part of the document a given DOM position +// corresponds to +// +// - Wiring in custom implementations of the editing interface for a +// given node +// +// They form a doubly-linked mutable tree, starting at `view.docView`. + +var NOT_DIRTY = 0, CHILD_DIRTY = 1, CONTENT_DIRTY = 2, NODE_DIRTY = 3; + +// Superclass for the various kinds of descriptions. Defines their +// basic structure and shared methods. +var ViewDesc = function ViewDesc(parent, children, dom, contentDOM) { + this.parent = parent; + this.children = children; + this.dom = dom; + // An expando property on the DOM node provides a link back to its + // description. + dom.pmViewDesc = this; + // This is the node that holds the child views. It may be null for + // descs that don't have children. + this.contentDOM = contentDOM; + this.dirty = NOT_DIRTY; +}; + +var prototypeAccessors = { beforePosition: { configurable: true },size: { configurable: true },border: { configurable: true },posBefore: { configurable: true },posAtStart: { configurable: true },posAfter: { configurable: true },posAtEnd: { configurable: true },contentLost: { configurable: true } }; + +// Used to check whether a given description corresponds to a +// widget/mark/node. +ViewDesc.prototype.matchesWidget = function matchesWidget () { return false }; +ViewDesc.prototype.matchesMark = function matchesMark () { return false }; +ViewDesc.prototype.matchesNode = function matchesNode () { return false }; +ViewDesc.prototype.matchesHack = function matchesHack () { return false }; + +prototypeAccessors.beforePosition.get = function () { return false }; + +// : () → ?ParseRule +// When parsing in-editor content (in domchange.js), we allow +// descriptions to determine the parse rules that should be used to +// parse them. +ViewDesc.prototype.parseRule = function parseRule () { return null }; + +// : (dom.Event) → bool +// Used by the editor's event handler to ignore events that come +// from certain descs. +ViewDesc.prototype.stopEvent = function stopEvent () { return false }; + +// The size of the content represented by this desc. +prototypeAccessors.size.get = function () { + var size = 0; + for (var i = 0; i < this.children.length; i++) { size += this.children[i].size; } + return size +}; + +// For block nodes, this represents the space taken up by their +// start/end tokens. +prototypeAccessors.border.get = function () { return 0 }; + +ViewDesc.prototype.destroy = function destroy () { + this.parent = null; + if (this.dom.pmViewDesc == this) { this.dom.pmViewDesc = null; } + for (var i = 0; i < this.children.length; i++) + { this.children[i].destroy(); } +}; + +ViewDesc.prototype.posBeforeChild = function posBeforeChild (child) { + for (var i = 0, pos = this.posAtStart; i < this.children.length; i++) { + var cur = this.children[i]; + if (cur == child) { return pos } + pos += cur.size; + } +}; + +prototypeAccessors.posBefore.get = function () { + return this.parent.posBeforeChild(this) +}; + +prototypeAccessors.posAtStart.get = function () { + return this.parent ? this.parent.posBeforeChild(this) + this.border : 0 +}; + +prototypeAccessors.posAfter.get = function () { + return this.posBefore + this.size +}; + +prototypeAccessors.posAtEnd.get = function () { + return this.posAtStart + this.size - 2 * this.border +}; + +// : (dom.Node, number, ?number) → number +ViewDesc.prototype.localPosFromDOM = function localPosFromDOM (dom, offset, bias) { + // If the DOM position is in the content, use the child desc after + // it to figure out a position. + if (this.contentDOM && this.contentDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode)) { + if (bias < 0) { + var domBefore, desc; + if (dom == this.contentDOM) { + domBefore = dom.childNodes[offset - 1]; + } else { + while (dom.parentNode != this.contentDOM) { dom = dom.parentNode; } + domBefore = dom.previousSibling; + } + while (domBefore && !((desc = domBefore.pmViewDesc) && desc.parent == this)) { domBefore = domBefore.previousSibling; } + return domBefore ? this.posBeforeChild(desc) + desc.size : this.posAtStart + } else { + var domAfter, desc$1; + if (dom == this.contentDOM) { + domAfter = dom.childNodes[offset]; + } else { + while (dom.parentNode != this.contentDOM) { dom = dom.parentNode; } + domAfter = dom.nextSibling; + } + while (domAfter && !((desc$1 = domAfter.pmViewDesc) && desc$1.parent == this)) { domAfter = domAfter.nextSibling; } + return domAfter ? this.posBeforeChild(desc$1) : this.posAtEnd + } + } + // Otherwise, use various heuristics, falling back on the bias + // parameter, to determine whether to return the position at the + // start or at the end of this view desc. + var atEnd; + if (this.contentDOM && this.contentDOM != this.dom && this.dom.contains(this.contentDOM)) { + atEnd = dom.compareDocumentPosition(this.contentDOM) & 2; + } else if (this.dom.firstChild) { + if (offset == 0) { for (var search = dom;; search = search.parentNode) { + if (search == this.dom) { atEnd = false; break } + if (search.parentNode.firstChild != search) { break } + } } + if (atEnd == null && offset == dom.childNodes.length) { for (var search$1 = dom;; search$1 = search$1.parentNode) { + if (search$1 == this.dom) { atEnd = true; break } + if (search$1.parentNode.lastChild != search$1) { break } + } } + } + return (atEnd == null ? bias > 0 : atEnd) ? this.posAtEnd : this.posAtStart +}; + +// Scan up the dom finding the first desc that is a descendant of +// this one. +ViewDesc.prototype.nearestDesc = function nearestDesc (dom, onlyNodes) { + for (var first = true, cur = dom; cur; cur = cur.parentNode) { + var desc = this.getDesc(cur); + if (desc && (!onlyNodes || desc.node)) { + // If dom is outside of this desc's nodeDOM, don't count it. + if (first && desc.nodeDOM && !(desc.nodeDOM.nodeType == 1 ? desc.nodeDOM.contains(dom) : desc.nodeDOM == dom)) { first = false; } + else { return desc } + } + } +}; + +ViewDesc.prototype.getDesc = function getDesc (dom) { + var desc = dom.pmViewDesc; + for (var cur = desc; cur; cur = cur.parent) { if (cur == this) { return desc } } +}; + +ViewDesc.prototype.posFromDOM = function posFromDOM (dom, offset, bias) { + for (var scan = dom;; scan = scan.parentNode) { + var desc = this.getDesc(scan); + if (desc) { return desc.localPosFromDOM(dom, offset, bias) } + } +}; + +// : (number) → ?NodeViewDesc +// Find the desc for the node after the given pos, if any. (When a +// parent node overrode rendering, there might not be one.) +ViewDesc.prototype.descAt = function descAt (pos) { + for (var i = 0, offset = 0; i < this.children.length; i++) { + var child = this.children[i], end = offset + child.size; + if (offset == pos && end != offset) { + while (!child.border && child.children.length) { child = child.children[0]; } + return child + } + if (pos < end) { return child.descAt(pos - offset - child.border) } + offset = end; + } +}; + +// : (number) → {node: dom.Node, offset: number} +ViewDesc.prototype.domFromPos = function domFromPos (pos) { + if (!this.contentDOM) { return {node: this.dom, offset: 0} } + for (var offset = 0, i = 0;; i++) { + if (offset == pos) { + while (i < this.children.length && (this.children[i].beforePosition || this.children[i].dom.parentNode != this.contentDOM)) { i++; } + return {node: this.contentDOM, + offset: i == this.children.length ? this.contentDOM.childNodes.length : domIndex(this.children[i].dom)} + } + if (i == this.children.length) { throw new Error("Invalid position " + pos) } + var child = this.children[i], end = offset + child.size; + if (pos < end) { return child.domFromPos(pos - offset - child.border) } + offset = end; + } +}; + +// Used to find a DOM range in a single parent for a given changed +// range. +ViewDesc.prototype.parseRange = function parseRange (from, to, base) { + if ( base === void 0 ) base = 0; + + if (this.children.length == 0) + { return {node: this.contentDOM, from: from, to: to, fromOffset: 0, toOffset: this.contentDOM.childNodes.length} } + + var fromOffset = -1, toOffset = -1; + for (var offset = base, i = 0;; i++) { + var child = this.children[i], end = offset + child.size; + if (fromOffset == -1 && from <= end) { + var childBase = offset + child.border; + // FIXME maybe descend mark views to parse a narrower range? + if (from >= childBase && to <= end - child.border && child.node && + child.contentDOM && this.contentDOM.contains(child.contentDOM)) + { return child.parseRange(from, to, childBase) } + + from = offset; + for (var j = i; j > 0; j--) { + var prev = this.children[j - 1]; + if (prev.size && prev.dom.parentNode == this.contentDOM && !prev.emptyChildAt(1)) { + fromOffset = domIndex(prev.dom) + 1; + break + } + from -= prev.size; + } + if (fromOffset == -1) { fromOffset = 0; } + } + if (fromOffset > -1 && to <= end) { + to = end; + for (var j$1 = i + 1; j$1 < this.children.length; j$1++) { + var next = this.children[j$1]; + if (next.size && next.dom.parentNode == this.contentDOM && !next.emptyChildAt(-1)) { + toOffset = domIndex(next.dom); + break + } + to += next.size; + } + if (toOffset == -1) { toOffset = this.contentDOM.childNodes.length; } + break + } + offset = end; + } + return {node: this.contentDOM, from: from, to: to, fromOffset: fromOffset, toOffset: toOffset} +}; + +ViewDesc.prototype.emptyChildAt = function emptyChildAt (side) { + if (this.border || !this.contentDOM || !this.children.length) { return false } + var child = this.children[side < 0 ? 0 : this.children.length - 1]; + return child.size == 0 || child.emptyChildAt(side) +}; + +// : (number) → dom.Node +ViewDesc.prototype.domAfterPos = function domAfterPos (pos) { + var ref = this.domFromPos(pos); + var node = ref.node; + var offset = ref.offset; + if (node.nodeType != 1 || offset == node.childNodes.length) + { throw new RangeError("No node after pos " + pos) } + return node.childNodes[offset] +}; + +// : (number, number, dom.Document) +// View descs are responsible for setting any selection that falls +// entirely inside of them, so that custom implementations can do +// custom things with the selection. Note that this falls apart when +// a selection starts in such a node and ends in another, in which +// case we just use whatever domFromPos produces as a best effort. +ViewDesc.prototype.setSelection = function setSelection (anchor, head, root, force) { + // If the selection falls entirely in a child, give it to that child + var from = Math.min(anchor, head), to = Math.max(anchor, head); + for (var i = 0, offset = 0; i < this.children.length; i++) { + var child = this.children[i], end = offset + child.size; + if (from > offset && to < end) + { return child.setSelection(anchor - offset - child.border, head - offset - child.border, root, force) } + offset = end; + } + + var anchorDOM = this.domFromPos(anchor), headDOM = this.domFromPos(head); + var domSel = root.getSelection(), range = document.createRange(); + if (!force && + isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset) && + isEquivalentPosition(headDOM.node, headDOM.offset, domSel.focusNode, domSel.focusOffset)) + { return } + + // Selection.extend can be used to create an 'inverted' selection + // (one where the focus is before the anchor), but not all + // browsers support it yet. + if (domSel.extend) { + range.setEnd(anchorDOM.node, anchorDOM.offset); + range.collapse(false); + } else { + if (anchor > head) { var tmp = anchorDOM; anchorDOM = headDOM; headDOM = tmp; } + range.setEnd(headDOM.node, headDOM.offset); + range.setStart(anchorDOM.node, anchorDOM.offset); + } + domSel.removeAllRanges(); + domSel.addRange(range); + if (domSel.extend) + { domSel.extend(headDOM.node, headDOM.offset); } +}; + +// : (dom.MutationRecord) → bool +ViewDesc.prototype.ignoreMutation = function ignoreMutation (_mutation) { + return !this.contentDOM +}; + +prototypeAccessors.contentLost.get = function () { + return this.contentDOM && this.contentDOM != this.dom && !this.dom.contains(this.contentDOM) +}; + +// Remove a subtree of the element tree that has been touched +// by a DOM change, so that the next update will redraw it. +ViewDesc.prototype.markDirty = function markDirty (from, to) { + for (var offset = 0, i = 0; i < this.children.length; i++) { + var child = this.children[i], end = offset + child.size; + if (offset == end ? from <= end && to >= offset : from < end && to > offset) { + var startInside = offset + child.border, endInside = end - child.border; + if (from >= startInside && to <= endInside) { + this.dirty = from == offset || to == end ? CONTENT_DIRTY : CHILD_DIRTY; + if (from == startInside && to == endInside && + (child.contentLost || child.dom.parentNode != this.contentDOM)) { child.dirty = NODE_DIRTY; } + else { child.markDirty(from - startInside, to - startInside); } + return + } else { + child.dirty = NODE_DIRTY; + } + } + offset = end; + } + this.dirty = CONTENT_DIRTY; +}; + +ViewDesc.prototype.markParentsDirty = function markParentsDirty () { + for (var node = this.parent; node; node = node.parent) { + var dirty = CONTENT_DIRTY ; + if (node.dirty < dirty) { node.dirty = dirty; } + } +}; + +Object.defineProperties( ViewDesc.prototype, prototypeAccessors ); + +// Reused array to avoid allocating fresh arrays for things that will +// stay empty anyway. +var nothing = []; + +// A widget desc represents a widget decoration, which is a DOM node +// drawn between the document nodes. +var WidgetViewDesc = /*@__PURE__*/(function (ViewDesc) { + function WidgetViewDesc(parent, widget, view, pos) { + var self, dom = widget.type.toDOM; + if (typeof dom == "function") { dom = dom(view, function () { + if (!self) { return pos } + if (self.parent) { return self.parent.posBeforeChild(self) } + }); } + if (!widget.type.spec.raw) { + if (dom.nodeType != 1) { + var wrap = document.createElement("span"); + wrap.appendChild(dom); + dom = wrap; + } + dom.contentEditable = false; + dom.classList.add("ProseMirror-widget"); + } + ViewDesc.call(this, parent, nothing, dom, null); + this.widget = widget; + self = this; + } + + if ( ViewDesc ) WidgetViewDesc.__proto__ = ViewDesc; + WidgetViewDesc.prototype = Object.create( ViewDesc && ViewDesc.prototype ); + WidgetViewDesc.prototype.constructor = WidgetViewDesc; + + var prototypeAccessors$1 = { beforePosition: { configurable: true } }; + + prototypeAccessors$1.beforePosition.get = function () { + return this.widget.type.side < 0 + }; + + WidgetViewDesc.prototype.matchesWidget = function matchesWidget (widget) { + return this.dirty == NOT_DIRTY && widget.type.eq(this.widget.type) + }; + + WidgetViewDesc.prototype.parseRule = function parseRule () { return {ignore: true} }; + + WidgetViewDesc.prototype.stopEvent = function stopEvent (event) { + var stop = this.widget.spec.stopEvent; + return stop ? stop(event) : false + }; + + Object.defineProperties( WidgetViewDesc.prototype, prototypeAccessors$1 ); + + return WidgetViewDesc; +}(ViewDesc)); + +var CompositionViewDesc = /*@__PURE__*/(function (ViewDesc) { + function CompositionViewDesc(parent, dom, textDOM, text) { + ViewDesc.call(this, parent, nothing, dom, null); + this.textDOM = textDOM; + this.text = text; + } + + if ( ViewDesc ) CompositionViewDesc.__proto__ = ViewDesc; + CompositionViewDesc.prototype = Object.create( ViewDesc && ViewDesc.prototype ); + CompositionViewDesc.prototype.constructor = CompositionViewDesc; + + var prototypeAccessors$2 = { size: { configurable: true } }; + + prototypeAccessors$2.size.get = function () { return this.text.length }; + + CompositionViewDesc.prototype.localPosFromDOM = function localPosFromDOM (dom, offset) { + if (dom != this.textDOM) { return this.posAtStart + (offset ? this.size : 0) } + return this.posAtStart + offset + }; + + CompositionViewDesc.prototype.domFromPos = function domFromPos (pos) { + return {node: this.textDOM, offset: pos} + }; + + CompositionViewDesc.prototype.ignoreMutation = function ignoreMutation (mut) { + return mut.type === 'characterData' && mut.target.nodeValue == mut.oldValue + }; + + Object.defineProperties( CompositionViewDesc.prototype, prototypeAccessors$2 ); + + return CompositionViewDesc; +}(ViewDesc)); + +// A mark desc represents a mark. May have multiple children, +// depending on how the mark is split. Note that marks are drawn using +// a fixed nesting order, for simplicity and predictability, so in +// some cases they will be split more often than would appear +// necessary. +var MarkViewDesc = /*@__PURE__*/(function (ViewDesc) { + function MarkViewDesc(parent, mark, dom, contentDOM) { + ViewDesc.call(this, parent, [], dom, contentDOM); + this.mark = mark; + } + + if ( ViewDesc ) MarkViewDesc.__proto__ = ViewDesc; + MarkViewDesc.prototype = Object.create( ViewDesc && ViewDesc.prototype ); + MarkViewDesc.prototype.constructor = MarkViewDesc; + + MarkViewDesc.create = function create (parent, mark, inline, view) { + var custom = view.nodeViews[mark.type.name]; + var spec = custom && custom(mark, view, inline); + if (!spec || !spec.dom) + { spec = DOMSerializer.renderSpec(document, mark.type.spec.toDOM(mark, inline)); } + return new MarkViewDesc(parent, mark, spec.dom, spec.contentDOM || spec.dom) + }; + + MarkViewDesc.prototype.parseRule = function parseRule () { return {mark: this.mark.type.name, attrs: this.mark.attrs, contentElement: this.contentDOM} }; + + MarkViewDesc.prototype.matchesMark = function matchesMark (mark) { return this.dirty != NODE_DIRTY && this.mark.eq(mark) }; + + MarkViewDesc.prototype.markDirty = function markDirty (from, to) { + ViewDesc.prototype.markDirty.call(this, from, to); + // Move dirty info to nearest node view + if (this.dirty != NOT_DIRTY) { + var parent = this.parent; + while (!parent.node) { parent = parent.parent; } + if (parent.dirty < this.dirty) { parent.dirty = this.dirty; } + this.dirty = NOT_DIRTY; + } + }; + + MarkViewDesc.prototype.slice = function slice (from, to, view) { + var copy = MarkViewDesc.create(this.parent, this.mark, true, view); + var nodes = this.children, size = this.size; + if (to < size) { nodes = replaceNodes(nodes, to, size, view); } + if (from > 0) { nodes = replaceNodes(nodes, 0, from, view); } + for (var i = 0; i < nodes.length; i++) { nodes[i].parent = copy; } + copy.children = nodes; + return copy + }; + + return MarkViewDesc; +}(ViewDesc)); + +// Node view descs are the main, most common type of view desc, and +// correspond to an actual node in the document. Unlike mark descs, +// they populate their child array themselves. +var NodeViewDesc = /*@__PURE__*/(function (ViewDesc) { + function NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos) { + ViewDesc.call(this, parent, node.isLeaf ? nothing : [], dom, contentDOM); + this.nodeDOM = nodeDOM; + this.node = node; + this.outerDeco = outerDeco; + this.innerDeco = innerDeco; + if (contentDOM) { this.updateChildren(view, pos); } + } + + if ( ViewDesc ) NodeViewDesc.__proto__ = ViewDesc; + NodeViewDesc.prototype = Object.create( ViewDesc && ViewDesc.prototype ); + NodeViewDesc.prototype.constructor = NodeViewDesc; + + var prototypeAccessors$3 = { size: { configurable: true },border: { configurable: true } }; + + // By default, a node is rendered using the `toDOM` method from the + // node type spec. But client code can use the `nodeViews` spec to + // supply a custom node view, which can influence various aspects of + // the way the node works. + // + // (Using subclassing for this was intentionally decided against, + // since it'd require exposing a whole slew of finnicky + // implementation details to the user code that they probably will + // never need.) + NodeViewDesc.create = function create (parent, node, outerDeco, innerDeco, view, pos) { + var assign; + + var custom = view.nodeViews[node.type.name], descObj; + var spec = custom && custom(node, view, function () { + // (This is a function that allows the custom view to find its + // own position) + if (!descObj) { return pos } + if (descObj.parent) { return descObj.parent.posBeforeChild(descObj) } + }, outerDeco); + + var dom = spec && spec.dom, contentDOM = spec && spec.contentDOM; + if (node.isText) { + if (!dom) { dom = document.createTextNode(node.text); } + else if (dom.nodeType != 3) { throw new RangeError("Text must be rendered as a DOM text node") } + } else if (!dom) { +((assign = DOMSerializer.renderSpec(document, node.type.spec.toDOM(node)), dom = assign.dom, contentDOM = assign.contentDOM)); + } + if (!contentDOM && !node.isText && dom.nodeName != "BR") { // Chrome gets confused by
    + if (!dom.hasAttribute("contenteditable")) { dom.contentEditable = false; } + if (node.type.spec.draggable) { dom.draggable = true; } + } + + var nodeDOM = dom; + dom = applyOuterDeco(dom, outerDeco, node); + + if (spec) + { return descObj = new CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, + spec, view, pos + 1) } + else if (node.isText) + { return new TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM, view) } + else + { return new NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos + 1) } + }; + + NodeViewDesc.prototype.parseRule = function parseRule () { + var this$1 = this; + + // Experimental kludge to allow opt-in re-parsing of nodes + if (this.node.type.spec.reparseInView) { return null } + // FIXME the assumption that this can always return the current + // attrs means that if the user somehow manages to change the + // attrs in the dom, that won't be picked up. Not entirely sure + // whether this is a problem + var rule = {node: this.node.type.name, attrs: this.node.attrs}; + if (this.node.type.spec.code) { rule.preserveWhitespace = "full"; } + if (this.contentDOM && !this.contentLost) { rule.contentElement = this.contentDOM; } + else { rule.getContent = function () { return this$1.contentDOM ? Fragment.empty : this$1.node.content; }; } + return rule + }; + + NodeViewDesc.prototype.matchesNode = function matchesNode (node, outerDeco, innerDeco) { + return this.dirty == NOT_DIRTY && node.eq(this.node) && + sameOuterDeco(outerDeco, this.outerDeco) && innerDeco.eq(this.innerDeco) + }; + + prototypeAccessors$3.size.get = function () { return this.node.nodeSize }; + + prototypeAccessors$3.border.get = function () { return this.node.isLeaf ? 0 : 1 }; + + // Syncs `this.children` to match `this.node.content` and the local + // decorations, possibly introducing nesting for marks. Then, in a + // separate step, syncs the DOM inside `this.contentDOM` to + // `this.children`. + NodeViewDesc.prototype.updateChildren = function updateChildren (view, pos) { + var this$1 = this; + + var inline = this.node.inlineContent, off = pos; + var composition = inline && view.composing && this.localCompositionNode(view, pos); + var updater = new ViewTreeUpdater(this, composition && composition.node); + iterDeco(this.node, this.innerDeco, function (widget, i) { + if (widget.spec.marks) + { updater.syncToMarks(widget.spec.marks, inline, view); } + else if (widget.type.side >= 0) + { updater.syncToMarks(i == this$1.node.childCount ? Mark.none : this$1.node.child(i).marks, inline, view); } + // If the next node is a desc matching this widget, reuse it, + // otherwise insert the widget as a new view desc. + updater.placeWidget(widget, view, off); + }, function (child, outerDeco, innerDeco, i) { + // Make sure the wrapping mark descs match the node's marks. + updater.syncToMarks(child.marks, inline, view); + // Either find an existing desc that exactly matches this node, + // and drop the descs before it. + updater.findNodeMatch(child, outerDeco, innerDeco, i) || + // Or try updating the next desc to reflect this node. + updater.updateNextNode(child, outerDeco, innerDeco, view, i) || + // Or just add it as a new desc. + updater.addNode(child, outerDeco, innerDeco, view, off); + off += child.nodeSize; + }); + // Drop all remaining descs after the current position. + updater.syncToMarks(nothing, inline, view); + if (this.node.isTextblock) { updater.addTextblockHacks(); } + updater.destroyRest(); + + // Sync the DOM if anything changed + if (updater.changed || this.dirty == CONTENT_DIRTY) { + // May have to protect focused DOM from being changed if a composition is active + if (composition) { this.protectLocalComposition(view, composition); } + this.renderChildren(); + } + }; + + NodeViewDesc.prototype.renderChildren = function renderChildren () { + renderDescs(this.contentDOM, this.children); + if (result.ios) { iosHacks(this.dom); } + }; + + NodeViewDesc.prototype.localCompositionNode = function localCompositionNode (view, pos) { + // Only do something if both the selection and a focused text node + // are inside of this node, and the node isn't already part of a + // view that's a child of this view + var ref = view.state.selection; + var from = ref.from; + var to = ref.to; + if (!(view.state.selection instanceof TextSelection) || from < pos || to > pos + this.node.content.size) { return } + var sel = view.root.getSelection(); + var textNode = nearbyTextNode(sel.focusNode, sel.focusOffset); + if (!textNode || !this.dom.contains(textNode.parentNode)) { return } + + // Find the text in the focused node in the node, stop if it's not + // there (may have been modified through other means, in which + // case it should overwritten) + var text = textNode.nodeValue; + var textPos = findTextInFragment(this.node.content, text, from - pos, to - pos); + + return textPos < 0 ? null : {node: textNode, pos: textPos, text: text} + }; + + NodeViewDesc.prototype.protectLocalComposition = function protectLocalComposition (view, ref) { + var node = ref.node; + var pos = ref.pos; + var text = ref.text; + + // The node is already part of a local view desc, leave it there + if (this.getDesc(node)) { return } + + // Create a composition view for the orphaned nodes + var topNode = node; + for (;; topNode = topNode.parentNode) { + if (topNode.parentNode == this.contentDOM) { break } + while (topNode.previousSibling) { topNode.parentNode.removeChild(topNode.previousSibling); } + while (topNode.nextSibling) { topNode.parentNode.removeChild(topNode.nextSibling); } + if (topNode.pmViewDesc) { topNode.pmViewDesc = null; } + } + var desc = new CompositionViewDesc(this, topNode, node, text); + view.compositionNodes.push(desc); + + // Patch up this.children to contain the composition view + this.children = replaceNodes(this.children, pos, pos + text.length, view, desc); + }; + + // : (Node, [Decoration], DecorationSet, EditorView) → bool + // If this desc be updated to match the given node decoration, + // do so and return true. + NodeViewDesc.prototype.update = function update (node, outerDeco, innerDeco, view) { + if (this.dirty == NODE_DIRTY || + !node.sameMarkup(this.node)) { return false } + this.updateInner(node, outerDeco, innerDeco, view); + return true + }; + + NodeViewDesc.prototype.updateInner = function updateInner (node, outerDeco, innerDeco, view) { + this.updateOuterDeco(outerDeco); + this.node = node; + this.innerDeco = innerDeco; + if (this.contentDOM) { this.updateChildren(view, this.posAtStart); } + this.dirty = NOT_DIRTY; + }; + + NodeViewDesc.prototype.updateOuterDeco = function updateOuterDeco (outerDeco) { + if (sameOuterDeco(outerDeco, this.outerDeco)) { return } + var needsWrap = this.nodeDOM.nodeType != 1; + var oldDOM = this.dom; + this.dom = patchOuterDeco(this.dom, this.nodeDOM, + computeOuterDeco(this.outerDeco, this.node, needsWrap), + computeOuterDeco(outerDeco, this.node, needsWrap)); + if (this.dom != oldDOM) { + oldDOM.pmViewDesc = null; + this.dom.pmViewDesc = this; + } + this.outerDeco = outerDeco; + }; + + // Mark this node as being the selected node. + NodeViewDesc.prototype.selectNode = function selectNode () { + this.nodeDOM.classList.add("ProseMirror-selectednode"); + if (this.contentDOM || !this.node.type.spec.draggable) { this.dom.draggable = true; } + }; + + // Remove selected node marking from this node. + NodeViewDesc.prototype.deselectNode = function deselectNode () { + this.nodeDOM.classList.remove("ProseMirror-selectednode"); + if (this.contentDOM || !this.node.type.spec.draggable) { this.dom.draggable = false; } + }; + + Object.defineProperties( NodeViewDesc.prototype, prototypeAccessors$3 ); + + return NodeViewDesc; +}(ViewDesc)); + +// Create a view desc for the top-level document node, to be exported +// and used by the view class. +function docViewDesc(doc, outerDeco, innerDeco, dom, view) { + applyOuterDeco(dom, outerDeco, doc); + return new NodeViewDesc(null, doc, outerDeco, innerDeco, dom, dom, dom, view, 0) +} + +var TextViewDesc = /*@__PURE__*/(function (NodeViewDesc) { + function TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM, view) { + NodeViewDesc.call(this, parent, node, outerDeco, innerDeco, dom, null, nodeDOM, view); + } + + if ( NodeViewDesc ) TextViewDesc.__proto__ = NodeViewDesc; + TextViewDesc.prototype = Object.create( NodeViewDesc && NodeViewDesc.prototype ); + TextViewDesc.prototype.constructor = TextViewDesc; + + TextViewDesc.prototype.parseRule = function parseRule () { + return {skip: this.nodeDOM.parentNode || true} + }; + + TextViewDesc.prototype.update = function update (node, outerDeco) { + if (this.dirty == NODE_DIRTY || (this.dirty != NOT_DIRTY && !this.inParent()) || + !node.sameMarkup(this.node)) { return false } + this.updateOuterDeco(outerDeco); + if ((this.dirty != NOT_DIRTY || node.text != this.node.text) && node.text != this.nodeDOM.nodeValue) + { this.nodeDOM.nodeValue = node.text; } + this.node = node; + this.dirty = NOT_DIRTY; + return true + }; + + TextViewDesc.prototype.inParent = function inParent () { + var parentDOM = this.parent.contentDOM; + for (var n = this.nodeDOM; n; n = n.parentNode) { if (n == parentDOM) { return true } } + return false + }; + + TextViewDesc.prototype.domFromPos = function domFromPos (pos) { + return {node: this.nodeDOM, offset: pos} + }; + + TextViewDesc.prototype.localPosFromDOM = function localPosFromDOM (dom, offset, bias) { + if (dom == this.nodeDOM) { return this.posAtStart + Math.min(offset, this.node.text.length) } + return NodeViewDesc.prototype.localPosFromDOM.call(this, dom, offset, bias) + }; + + TextViewDesc.prototype.ignoreMutation = function ignoreMutation (mutation) { + return mutation.type != "characterData" && mutation.type != "selection" + }; + + TextViewDesc.prototype.slice = function slice (from, to, view) { + var node = this.node.cut(from, to), dom = document.createTextNode(node.text); + return new TextViewDesc(this.parent, node, this.outerDeco, this.innerDeco, dom, dom, view) + }; + + return TextViewDesc; +}(NodeViewDesc)); + +// A dummy desc used to tag trailing BR or span nodes created to work +// around contentEditable terribleness. +var BRHackViewDesc = /*@__PURE__*/(function (ViewDesc) { + function BRHackViewDesc () { + ViewDesc.apply(this, arguments); + } + + if ( ViewDesc ) BRHackViewDesc.__proto__ = ViewDesc; + BRHackViewDesc.prototype = Object.create( ViewDesc && ViewDesc.prototype ); + BRHackViewDesc.prototype.constructor = BRHackViewDesc; + + BRHackViewDesc.prototype.parseRule = function parseRule () { return {ignore: true} }; + BRHackViewDesc.prototype.matchesHack = function matchesHack () { return this.dirty == NOT_DIRTY }; + + return BRHackViewDesc; +}(ViewDesc)); + +// A separate subclass is used for customized node views, so that the +// extra checks only have to be made for nodes that are actually +// customized. +var CustomNodeViewDesc = /*@__PURE__*/(function (NodeViewDesc) { + function CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, spec, view, pos) { + NodeViewDesc.call(this, parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos); + this.spec = spec; + } + + if ( NodeViewDesc ) CustomNodeViewDesc.__proto__ = NodeViewDesc; + CustomNodeViewDesc.prototype = Object.create( NodeViewDesc && NodeViewDesc.prototype ); + CustomNodeViewDesc.prototype.constructor = CustomNodeViewDesc; + + // A custom `update` method gets to decide whether the update goes + // through. If it does, and there's a `contentDOM` node, our logic + // updates the children. + CustomNodeViewDesc.prototype.update = function update (node, outerDeco, innerDeco, view) { + if (this.dirty == NODE_DIRTY) { return false } + if (this.spec.update) { + var result = this.spec.update(node, outerDeco); + if (result) { this.updateInner(node, outerDeco, innerDeco, view); } + return result + } else if (!this.contentDOM && !node.isLeaf) { + return false + } else { + return NodeViewDesc.prototype.update.call(this, node, outerDeco, innerDeco, view) + } + }; + + CustomNodeViewDesc.prototype.selectNode = function selectNode () { + this.spec.selectNode ? this.spec.selectNode() : NodeViewDesc.prototype.selectNode.call(this); + }; + + CustomNodeViewDesc.prototype.deselectNode = function deselectNode () { + this.spec.deselectNode ? this.spec.deselectNode() : NodeViewDesc.prototype.deselectNode.call(this); + }; + + CustomNodeViewDesc.prototype.setSelection = function setSelection (anchor, head, root, force) { + this.spec.setSelection ? this.spec.setSelection(anchor, head, root) + : NodeViewDesc.prototype.setSelection.call(this, anchor, head, root, force); + }; + + CustomNodeViewDesc.prototype.destroy = function destroy () { + if (this.spec.destroy) { this.spec.destroy(); } + NodeViewDesc.prototype.destroy.call(this); + }; + + CustomNodeViewDesc.prototype.stopEvent = function stopEvent (event) { + return this.spec.stopEvent ? this.spec.stopEvent(event) : false + }; + + CustomNodeViewDesc.prototype.ignoreMutation = function ignoreMutation (mutation) { + return this.spec.ignoreMutation ? this.spec.ignoreMutation(mutation) : NodeViewDesc.prototype.ignoreMutation.call(this, mutation) + }; + + return CustomNodeViewDesc; +}(NodeViewDesc)); + +// : (dom.Node, [ViewDesc]) +// Sync the content of the given DOM node with the nodes associated +// with the given array of view descs, recursing into mark descs +// because this should sync the subtree for a whole node at a time. +function renderDescs(parentDOM, descs) { + var dom = parentDOM.firstChild; + for (var i = 0; i < descs.length; i++) { + var desc = descs[i], childDOM = desc.dom; + if (childDOM.parentNode == parentDOM) { + while (childDOM != dom) { dom = rm(dom); } + dom = dom.nextSibling; + } else { + parentDOM.insertBefore(childDOM, dom); + } + if (desc instanceof MarkViewDesc) { + var pos = dom ? dom.previousSibling : parentDOM.lastChild; + renderDescs(desc.contentDOM, desc.children); + dom = pos ? pos.nextSibling : parentDOM.firstChild; + } + } + while (dom) { dom = rm(dom); } +} + +function OuterDecoLevel(nodeName) { + if (nodeName) { this.nodeName = nodeName; } +} +OuterDecoLevel.prototype = Object.create(null); + +var noDeco = [new OuterDecoLevel]; + +function computeOuterDeco(outerDeco, node, needsWrap) { + if (outerDeco.length == 0) { return noDeco } + + var top = needsWrap ? noDeco[0] : new OuterDecoLevel, result = [top]; + + for (var i = 0; i < outerDeco.length; i++) { + var attrs = outerDeco[i].type.attrs, cur = top; + if (!attrs) { continue } + if (attrs.nodeName) + { result.push(cur = new OuterDecoLevel(attrs.nodeName)); } + + for (var name in attrs) { + var val = attrs[name]; + if (val == null) { continue } + if (needsWrap && result.length == 1) + { result.push(cur = top = new OuterDecoLevel(node.isInline ? "span" : "div")); } + if (name == "class") { cur.class = (cur.class ? cur.class + " " : "") + val; } + else if (name == "style") { cur.style = (cur.style ? cur.style + ";" : "") + val; } + else if (name != "nodeName") { cur[name] = val; } + } + } + + return result +} + +function patchOuterDeco(outerDOM, nodeDOM, prevComputed, curComputed) { + // Shortcut for trivial case + if (prevComputed == noDeco && curComputed == noDeco) { return nodeDOM } + + var curDOM = nodeDOM; + for (var i = 0; i < curComputed.length; i++) { + var deco = curComputed[i], prev = prevComputed[i]; + if (i) { + var parent = (void 0); + if (prev && prev.nodeName == deco.nodeName && curDOM != outerDOM && + (parent = curDOM.parentNode) && parent.tagName.toLowerCase() == deco.nodeName) { + curDOM = parent; + } else { + parent = document.createElement(deco.nodeName); + parent.appendChild(curDOM); + prev = noDeco[0]; + curDOM = parent; + } + } + patchAttributes(curDOM, prev || noDeco[0], deco); + } + return curDOM +} + +function patchAttributes(dom, prev, cur) { + for (var name in prev) + { if (name != "class" && name != "style" && name != "nodeName" && !(name in cur)) + { dom.removeAttribute(name); } } + for (var name$1 in cur) + { if (name$1 != "class" && name$1 != "style" && name$1 != "nodeName" && cur[name$1] != prev[name$1]) + { dom.setAttribute(name$1, cur[name$1]); } } + if (prev.class != cur.class) { + var prevList = prev.class ? prev.class.split(" ") : nothing; + var curList = cur.class ? cur.class.split(" ") : nothing; + for (var i = 0; i < prevList.length; i++) { if (curList.indexOf(prevList[i]) == -1) + { dom.classList.remove(prevList[i]); } } + for (var i$1 = 0; i$1 < curList.length; i$1++) { if (prevList.indexOf(curList[i$1]) == -1) + { dom.classList.add(curList[i$1]); } } + } + if (prev.style != cur.style) { + if (prev.style) { + var prop = /\s*([\w\-\xa1-\uffff]+)\s*:(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*'|\(.*?\)|[^;])*/g, m; + while (m = prop.exec(prev.style)) + { dom.style.removeProperty(m[1]); } + } + if (cur.style) + { dom.style.cssText += cur.style; } + } +} + +function applyOuterDeco(dom, deco, node) { + return patchOuterDeco(dom, dom, noDeco, computeOuterDeco(deco, node, dom.nodeType != 1)) +} + +// : ([Decoration], [Decoration]) → bool +function sameOuterDeco(a, b) { + if (a.length != b.length) { return false } + for (var i = 0; i < a.length; i++) { if (!a[i].type.eq(b[i].type)) { return false } } + return true +} + +// Remove a DOM node and return its next sibling. +function rm(dom) { + var next = dom.nextSibling; + dom.parentNode.removeChild(dom); + return next +} + +// Helper class for incrementally updating a tree of mark descs and +// the widget and node descs inside of them. +var ViewTreeUpdater = function ViewTreeUpdater(top, lockedNode) { + this.top = top; + this.lock = lockedNode; + // Index into `this.top`'s child array, represents the current + // update position. + this.index = 0; + // When entering a mark, the current top and index are pushed + // onto this. + this.stack = []; + // Tracks whether anything was changed + this.changed = false; + + var pre = preMatch(top.node.content, top.children); + this.preMatched = pre.nodes; + this.preMatchOffset = pre.offset; +}; + +ViewTreeUpdater.prototype.getPreMatch = function getPreMatch (index) { + return index >= this.preMatchOffset ? this.preMatched[index - this.preMatchOffset] : null +}; + +// Destroy and remove the children between the given indices in +// `this.top`. +ViewTreeUpdater.prototype.destroyBetween = function destroyBetween (start, end) { + if (start == end) { return } + for (var i = start; i < end; i++) { this.top.children[i].destroy(); } + this.top.children.splice(start, end - start); + this.changed = true; +}; + +// Destroy all remaining children in `this.top`. +ViewTreeUpdater.prototype.destroyRest = function destroyRest () { + this.destroyBetween(this.index, this.top.children.length); +}; + +// : ([Mark], EditorView) +// Sync the current stack of mark descs with the given array of +// marks, reusing existing mark descs when possible. +ViewTreeUpdater.prototype.syncToMarks = function syncToMarks (marks, inline, view) { + var keep = 0, depth = this.stack.length >> 1; + var maxKeep = Math.min(depth, marks.length); + while (keep < maxKeep && + (keep == depth - 1 ? this.top : this.stack[(keep + 1) << 1]).matchesMark(marks[keep]) && marks[keep].type.spec.spanning !== false) + { keep++; } + + while (keep < depth) { + this.destroyRest(); + this.top.dirty = NOT_DIRTY; + this.index = this.stack.pop(); + this.top = this.stack.pop(); + depth--; + } + while (depth < marks.length) { + this.stack.push(this.top, this.index + 1); + var found = -1; + for (var i = this.index; i < Math.min(this.index + 3, this.top.children.length); i++) { + if (this.top.children[i].matchesMark(marks[depth])) { found = i; break } + } + if (found > -1) { + if (found > this.index) { + this.changed = true; + this.destroyBetween(this.index, found); + } + this.top = this.top.children[this.index]; + } else { + var markDesc = MarkViewDesc.create(this.top, marks[depth], inline, view); + this.top.children.splice(this.index, 0, markDesc); + this.top = markDesc; + this.changed = true; + } + this.index = 0; + depth++; + } +}; + +// : (Node, [Decoration], DecorationSet) → bool +// Try to find a node desc matching the given data. Skip over it and +// return true when successful. +ViewTreeUpdater.prototype.findNodeMatch = function findNodeMatch (node, outerDeco, innerDeco, index) { + var found = -1, preMatch = index < 0 ? undefined : this.getPreMatch(index), children = this.top.children; + if (preMatch && preMatch.matchesNode(node, outerDeco, innerDeco)) { + found = children.indexOf(preMatch); + } else { + for (var i = this.index, e = Math.min(children.length, i + 5); i < e; i++) { + var child = children[i]; + if (child.matchesNode(node, outerDeco, innerDeco) && this.preMatched.indexOf(child) < 0) { + found = i; + break + } + } + } + if (found < 0) { return false } + this.destroyBetween(this.index, found); + this.index++; + return true +}; + +// : (Node, [Decoration], DecorationSet, EditorView, Fragment, number) → bool +// Try to update the next node, if any, to the given data. Checks +// pre-matches to avoid overwriting nodes that could still be used. +ViewTreeUpdater.prototype.updateNextNode = function updateNextNode (node, outerDeco, innerDeco, view, index) { + if (this.index == this.top.children.length) { return false } + var next = this.top.children[this.index]; + if (next instanceof NodeViewDesc) { + var preMatch = this.preMatched.indexOf(next); + if (preMatch > -1 && preMatch + this.preMatchOffset != index) { return false } + var nextDOM = next.dom; + + // Can't update if nextDOM is or contains this.lock, except if + // it's a text node whose content already matches the new text + // and whose decorations match the new ones. + var locked = this.lock && (nextDOM == this.lock || nextDOM.nodeType == 1 && nextDOM.contains(this.lock.parentNode)) && + !(node.isText && next.node && next.node.isText && next.nodeDOM.nodeValue == node.text && + next.dirty != NODE_DIRTY && sameOuterDeco(outerDeco, next.outerDeco)); + if (!locked && next.update(node, outerDeco, innerDeco, view)) { + if (next.dom != nextDOM) { this.changed = true; } + this.index++; + return true + } + } + return false +}; + +// : (Node, [Decoration], DecorationSet, EditorView) +// Insert the node as a newly created node desc. +ViewTreeUpdater.prototype.addNode = function addNode (node, outerDeco, innerDeco, view, pos) { + this.top.children.splice(this.index++, 0, NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos)); + this.changed = true; +}; + +ViewTreeUpdater.prototype.placeWidget = function placeWidget (widget, view, pos) { + if (this.index < this.top.children.length && this.top.children[this.index].matchesWidget(widget)) { + this.index++; + } else { + var desc = new WidgetViewDesc(this.top, widget, view, pos); + this.top.children.splice(this.index++, 0, desc); + this.changed = true; + } +}; + +// Make sure a textblock looks and behaves correctly in +// contentEditable. +ViewTreeUpdater.prototype.addTextblockHacks = function addTextblockHacks () { + var lastChild = this.top.children[this.index - 1]; + while (lastChild instanceof MarkViewDesc) { lastChild = lastChild.children[lastChild.children.length - 1]; } + + if (!lastChild || // Empty textblock + !(lastChild instanceof TextViewDesc) || + /\n$/.test(lastChild.node.text)) { + if (this.index < this.top.children.length && this.top.children[this.index].matchesHack()) { + this.index++; + } else { + var dom = document.createElement("br"); + this.top.children.splice(this.index++, 0, new BRHackViewDesc(this.top, nothing, dom, null)); + this.changed = true; + } + } +}; + +// : (Fragment, [ViewDesc]) → [ViewDesc] +// Iterate from the end of the fragment and array of descs to find +// directly matching ones, in order to avoid overeagerly reusing +// those for other nodes. Returns an array whose positions correspond +// to node positions in the fragment, and whose elements are either +// descs matched to the child at that index, or empty. +function preMatch(frag, descs) { + var result = [], end = frag.childCount; + for (var i = descs.length - 1; end > 0 && i >= 0; i--) { + var desc = descs[i], node = desc.node; + if (!node) { continue } + if (node != frag.child(end - 1)) { break } + result.push(desc); + --end; + } + return {nodes: result.reverse(), offset: end} +} + +function compareSide(a, b) { return a.type.side - b.type.side } + +// : (ViewDesc, DecorationSet, (Decoration, number), (Node, [Decoration], DecorationSet, number)) +// This function abstracts iterating over the nodes and decorations in +// a fragment. Calls `onNode` for each node, with its local and child +// decorations. Splits text nodes when there is a decoration starting +// or ending inside of them. Calls `onWidget` for each widget. +function iterDeco(parent, deco, onWidget, onNode) { + var locals = deco.locals(parent), offset = 0; + // Simple, cheap variant for when there are no local decorations + if (locals.length == 0) { + for (var i = 0; i < parent.childCount; i++) { + var child = parent.child(i); + onNode(child, locals, deco.forChild(offset, child), i); + offset += child.nodeSize; + } + return + } + + var decoIndex = 0, active = [], restNode = null; + for (var parentIndex = 0;;) { + if (decoIndex < locals.length && locals[decoIndex].to == offset) { + var widget = locals[decoIndex++], widgets = (void 0); + while (decoIndex < locals.length && locals[decoIndex].to == offset) + { (widgets || (widgets = [widget])).push(locals[decoIndex++]); } + if (widgets) { + widgets.sort(compareSide); + for (var i$1 = 0; i$1 < widgets.length; i$1++) { onWidget(widgets[i$1], parentIndex); } + } else { + onWidget(widget, parentIndex); + } + } + + var child$1 = (void 0), index = (void 0); + if (restNode) { + index = -1; + child$1 = restNode; + restNode = null; + } else if (parentIndex < parent.childCount) { + index = parentIndex; + child$1 = parent.child(parentIndex++); + } else { + break + } + + for (var i$2 = 0; i$2 < active.length; i$2++) { if (active[i$2].to <= offset) { active.splice(i$2--, 1); } } + while (decoIndex < locals.length && locals[decoIndex].from == offset) { active.push(locals[decoIndex++]); } + + var end = offset + child$1.nodeSize; + if (child$1.isText) { + var cutAt = end; + if (decoIndex < locals.length && locals[decoIndex].from < cutAt) { cutAt = locals[decoIndex].from; } + for (var i$3 = 0; i$3 < active.length; i$3++) { if (active[i$3].to < cutAt) { cutAt = active[i$3].to; } } + if (cutAt < end) { + restNode = child$1.cut(cutAt - offset); + child$1 = child$1.cut(0, cutAt - offset); + end = cutAt; + index = -1; + } + } + + onNode(child$1, active.length ? active.slice() : nothing, deco.forChild(offset, child$1), index); + offset = end; + } +} + +// List markers in Mobile Safari will mysteriously disappear +// sometimes. This works around that. +function iosHacks(dom) { + if (dom.nodeName == "UL" || dom.nodeName == "OL") { + var oldCSS = dom.style.cssText; + dom.style.cssText = oldCSS + "; list-style: square !important"; + window.getComputedStyle(dom).listStyle; + dom.style.cssText = oldCSS; + } +} + +function nearbyTextNode(node, offset) { + for (;;) { + if (node.nodeType == 3) { return node } + if (node.nodeType == 1 && offset > 0) { + if (node.childNodes.length > offset && node.childNodes[offset].nodeType == 3) + { return node.childNodes[offset] } + node = node.childNodes[offset - 1]; + offset = nodeSize(node); + } else if (node.nodeType == 1 && offset < node.childNodes.length) { + node = node.childNodes[offset]; + offset = 0; + } else { + return null + } + } +} + +// Find a piece of text in an inline fragment, overlapping from-to +function findTextInFragment(frag, text, from, to) { + for (var str = "", i = 0, childPos = 0; i < frag.childCount; i++) { + var child = frag.child(i), end = childPos + child.nodeSize; + if (child.isText) { + str += child.text; + if (end >= to) { + var strStart = end - str.length, found = str.lastIndexOf(text); + while (found > -1 && strStart + found > from) { found = str.lastIndexOf(text, found - 1); } + if (found > -1 && strStart + found + text.length >= to) { + return strStart + found + } else if (end > to) { + break + } + } + } else { + str = ""; + } + childPos = end; + } + return -1 +} + +// Replace range from-to in an array of view descs with replacement +// (may be null to just delete). This goes very much against the grain +// of the rest of this code, which tends to create nodes with the +// right shape in one go, rather than messing with them after +// creation, but is necessary in the composition hack. +function replaceNodes(nodes, from, to, view, replacement) { + var result = []; + for (var i = 0, off = 0; i < nodes.length; i++) { + var child = nodes[i], start = off, end = off += child.size; + if (start >= to || end <= from) { + result.push(child); + } else { + if (start < from) { result.push(child.slice(0, from - start, view)); } + if (replacement) { + result.push(replacement); + replacement = null; + } + if (end > to) { result.push(child.slice(to - start, child.size, view)); } + } + } + return result +} + +function moveSelectionBlock(state, dir) { + var ref = state.selection; + var $anchor = ref.$anchor; + var $head = ref.$head; + var $side = dir > 0 ? $anchor.max($head) : $anchor.min($head); + var $start = !$side.parent.inlineContent ? $side : $side.depth ? state.doc.resolve(dir > 0 ? $side.after() : $side.before()) : null; + return $start && Selection.findFrom($start, dir) +} + +function apply(view, sel) { + view.dispatch(view.state.tr.setSelection(sel).scrollIntoView()); + return true +} + +function selectHorizontally(view, dir, mods) { + var sel = view.state.selection; + if (sel instanceof TextSelection) { + if (!sel.empty || mods.indexOf("s") > -1) { + return false + } else if (view.endOfTextblock(dir > 0 ? "right" : "left")) { + var next = moveSelectionBlock(view.state, dir); + if (next && (next instanceof NodeSelection)) { return apply(view, next) } + return false + } else { + var $head = sel.$head, node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter, desc; + if (!node || node.isText) { return false } + var nodePos = dir < 0 ? $head.pos - node.nodeSize : $head.pos; + if (!(node.isAtom || (desc = view.docView.descAt(nodePos)) && !desc.contentDOM)) { return false } + if (NodeSelection.isSelectable(node)) { + return apply(view, new NodeSelection(dir < 0 ? view.state.doc.resolve($head.pos - node.nodeSize) : $head)) + } else if (result.webkit) { + // Chrome and Safari will introduce extra pointless cursor + // positions around inline uneditable nodes, so we have to + // take over and move the cursor past them (#937) + return apply(view, new TextSelection(view.state.doc.resolve(dir < 0 ? nodePos : nodePos + node.nodeSize))) + } else { + return false + } + } + } else if (sel instanceof NodeSelection && sel.node.isInline) { + return apply(view, new TextSelection(dir > 0 ? sel.$to : sel.$from)) + } else { + var next$1 = moveSelectionBlock(view.state, dir); + if (next$1) { return apply(view, next$1) } + return false + } +} + +function nodeLen(node) { + return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length +} + +function isIgnorable(dom) { + var desc = dom.pmViewDesc; + return desc && desc.size == 0 && (dom.nextSibling || dom.nodeName != "BR") +} + +// Make sure the cursor isn't directly after one or more ignored +// nodes, which will confuse the browser's cursor motion logic. +function skipIgnoredNodesLeft(view) { + var sel = view.root.getSelection(); + var node = sel.focusNode, offset = sel.focusOffset; + if (!node) { return } + var moveNode, moveOffset, force = false; + // Gecko will do odd things when the selection is directly in front + // of a non-editable node, so in that case, move it into the next + // node if possible. Issue prosemirror/prosemirror#832. + if (result.gecko && node.nodeType == 1 && offset < nodeLen(node) && isIgnorable(node.childNodes[offset])) { force = true; } + for (;;) { + if (offset > 0) { + if (node.nodeType != 1) { + break + } else { + var before = node.childNodes[offset - 1]; + if (isIgnorable(before)) { + moveNode = node; + moveOffset = --offset; + } else if (before.nodeType == 3) { + node = before; + offset = node.nodeValue.length; + } else { break } + } + } else if (isBlockNode(node)) { + break + } else { + var prev = node.previousSibling; + while (prev && isIgnorable(prev)) { + moveNode = node.parentNode; + moveOffset = domIndex(prev); + prev = prev.previousSibling; + } + if (!prev) { + node = node.parentNode; + if (node == view.dom) { break } + offset = 0; + } else { + node = prev; + offset = nodeLen(node); + } + } + } + if (force) { setSelFocus(view, sel, node, offset); } + else if (moveNode) { setSelFocus(view, sel, moveNode, moveOffset); } +} + +// Make sure the cursor isn't directly before one or more ignored +// nodes. +function skipIgnoredNodesRight(view) { + var sel = view.root.getSelection(); + var node = sel.focusNode, offset = sel.focusOffset; + if (!node) { return } + var len = nodeLen(node); + var moveNode, moveOffset; + for (;;) { + if (offset < len) { + if (node.nodeType != 1) { break } + var after = node.childNodes[offset]; + if (isIgnorable(after)) { + moveNode = node; + moveOffset = ++offset; + } + else { break } + } else if (isBlockNode(node)) { + break + } else { + var next = node.nextSibling; + while (next && isIgnorable(next)) { + moveNode = next.parentNode; + moveOffset = domIndex(next) + 1; + next = next.nextSibling; + } + if (!next) { + node = node.parentNode; + if (node == view.dom) { break } + offset = len = 0; + } else { + node = next; + offset = 0; + len = nodeLen(node); + } + } + } + if (moveNode) { setSelFocus(view, sel, moveNode, moveOffset); } +} + +function isBlockNode(dom) { + var desc = dom.pmViewDesc; + return desc && desc.node && desc.node.isBlock +} + +function setSelFocus(view, sel, node, offset) { + if (selectionCollapsed(sel)) { + var range = document.createRange(); + range.setEnd(node, offset); + range.setStart(node, offset); + sel.removeAllRanges(); + sel.addRange(range); + } else if (sel.extend) { + sel.extend(node, offset); + } + view.domObserver.setCurSelection(); +} + +// : (EditorState, number) +// Check whether vertical selection motion would involve node +// selections. If so, apply it (if not, the result is left to the +// browser) +function selectVertically(view, dir, mods) { + var sel = view.state.selection; + if (sel instanceof TextSelection && !sel.empty || mods.indexOf("s") > -1) { return false } + var $from = sel.$from; + var $to = sel.$to; + + if (!$from.parent.inlineContent || view.endOfTextblock(dir < 0 ? "up" : "down")) { + var next = moveSelectionBlock(view.state, dir); + if (next && (next instanceof NodeSelection)) + { return apply(view, next) } + } + if (!$from.parent.inlineContent) { + var beyond = Selection.findFrom(dir < 0 ? $from : $to, dir); + return beyond ? apply(view, beyond) : true + } + return false +} + +function stopNativeHorizontalDelete(view, dir) { + if (!(view.state.selection instanceof TextSelection)) { return true } + var ref = view.state.selection; + var $head = ref.$head; + var $anchor = ref.$anchor; + var empty = ref.empty; + if (!$head.sameParent($anchor)) { return true } + if (!empty) { return false } + if (view.endOfTextblock(dir > 0 ? "forward" : "backward")) { return true } + var nextNode = !$head.textOffset && (dir < 0 ? $head.nodeBefore : $head.nodeAfter); + if (nextNode && !nextNode.isText) { + var tr = view.state.tr; + if (dir < 0) { tr.delete($head.pos - nextNode.nodeSize, $head.pos); } + else { tr.delete($head.pos, $head.pos + nextNode.nodeSize); } + view.dispatch(tr); + return true + } + return false +} + +function switchEditable(view, node, state) { + view.domObserver.stop(); + node.contentEditable = state; + view.domObserver.start(); +} + +// Issue #867 / https://bugs.chromium.org/p/chromium/issues/detail?id=903821 +// In which Chrome does really wrong things when the down arrow is +// pressed when the cursor is directly at the start of a textblock and +// has an uneditable node after it +function chromeDownArrowBug(view) { + if (!result.chrome || view.state.selection.$head.parentOffset > 0) { return } + var ref = view.root.getSelection(); + var focusNode = ref.focusNode; + var focusOffset = ref.focusOffset; + if (focusNode && focusNode.nodeType == 1 && focusOffset == 0 && + focusNode.firstChild && focusNode.firstChild.contentEditable == "false") { + var child = focusNode.firstChild; + switchEditable(view, child, true); + setTimeout(function () { return switchEditable(view, child, false); }, 20); + } +} + +// A backdrop key mapping used to make sure we always suppress keys +// that have a dangerous default effect, even if the commands they are +// bound to return false, and to make sure that cursor-motion keys +// find a cursor (as opposed to a node selection) when pressed. For +// cursor-motion keys, the code in the handlers also takes care of +// block selections. + +function getMods(event) { + var result = ""; + if (event.ctrlKey) { result += "c"; } + if (event.metaKey) { result += "m"; } + if (event.altKey) { result += "a"; } + if (event.shiftKey) { result += "s"; } + return result +} + +function captureKeyDown(view, event) { + var code = event.keyCode, mods = getMods(event); + if (code == 8 || (result.mac && code == 72 && mods == "c")) { // Backspace, Ctrl-h on Mac + return stopNativeHorizontalDelete(view, -1) || skipIgnoredNodesLeft(view) + } else if (code == 46 || (result.mac && code == 68 && mods == "c")) { // Delete, Ctrl-d on Mac + return stopNativeHorizontalDelete(view, 1) || skipIgnoredNodesRight(view) + } else if (code == 13 || code == 27) { // Enter, Esc + return true + } else if (code == 37) { // Left arrow + return selectHorizontally(view, -1, mods) || skipIgnoredNodesLeft(view) + } else if (code == 39) { // Right arrow + return selectHorizontally(view, 1, mods) || skipIgnoredNodesRight(view) + } else if (code == 38) { // Up arrow + return selectVertically(view, -1, mods) || skipIgnoredNodesLeft(view) + } else if (code == 40) { // Down arrow + return chromeDownArrowBug(view) || selectVertically(view, 1, mods) || skipIgnoredNodesRight(view) + } else if (mods == (result.mac ? "m" : "c") && + (code == 66 || code == 73 || code == 89 || code == 90)) { // Mod-[biyz] + return true + } + return false +} + +function selectionFromDOM(view, origin) { + var domSel = view.root.getSelection(), doc = view.state.doc; + var nearestDesc = view.docView.nearestDesc(domSel.focusNode), inWidget = nearestDesc && nearestDesc.size == 0; + var head = view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset); + var $head = doc.resolve(head), $anchor, selection; + if (selectionCollapsed(domSel)) { + $anchor = $head; + while (nearestDesc && !nearestDesc.node) { nearestDesc = nearestDesc.parent; } + if (nearestDesc && nearestDesc.node.isAtom && NodeSelection.isSelectable(nearestDesc.node) && nearestDesc.parent) { + var pos = nearestDesc.posBefore; + selection = new NodeSelection(head == pos ? $head : doc.resolve(pos)); + } + } else { + $anchor = doc.resolve(view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset)); + } + + if (!selection) { + var bias = origin == "pointer" || (view.state.selection.head < $head.pos && !inWidget) ? 1 : -1; + selection = selectionBetween(view, $anchor, $head, bias); + } + return selection +} + +function selectionToDOM(view, force) { + var sel = view.state.selection; + syncNodeSelection(view, sel); + + if (view.editable ? !view.hasFocus() : !(hasSelection(view) && document.activeElement.contains(view.dom))) { return } + + view.domObserver.disconnectSelection(); + + if (view.cursorWrapper) { + selectCursorWrapper(view); + } else { + var anchor = sel.anchor; + var head = sel.head; + var resetEditableFrom, resetEditableTo; + if (brokenSelectBetweenUneditable && !(sel instanceof TextSelection)) { + if (!sel.$from.parent.inlineContent) + { resetEditableFrom = temporarilyEditableNear(view, sel.from); } + if (!sel.empty && !sel.$from.parent.inlineContent) + { resetEditableTo = temporarilyEditableNear(view, sel.to); } + } + view.docView.setSelection(anchor, head, view.root, force); + if (brokenSelectBetweenUneditable) { + if (resetEditableFrom) { resetEditableFrom.contentEditable = "false"; } + if (resetEditableTo) { resetEditableTo.contentEditable = "false"; } + } + if (sel.visible) { + view.dom.classList.remove("ProseMirror-hideselection"); + } else if (anchor != head) { + view.dom.classList.add("ProseMirror-hideselection"); + if ("onselectionchange" in document) { removeClassOnSelectionChange(view); } + } + } + + view.domObserver.setCurSelection(); + view.domObserver.connectSelection(); +} + +// Kludge to work around Webkit not allowing a selection to start/end +// between non-editable block nodes. We briefly make something +// editable, set the selection, then set it uneditable again. + +var brokenSelectBetweenUneditable = result.safari || result.chrome && result.chrome_version < 63; + +function temporarilyEditableNear(view, pos) { + var ref = view.docView.domFromPos(pos); + var node = ref.node; + var offset = ref.offset; + var after = offset < node.childNodes.length ? node.childNodes[offset] : null; + var before = offset ? node.childNodes[offset - 1] : null; + if ((!after || after.contentEditable == "false") && (!before || before.contentEditable == "false")) { + if (after) { + after.contentEditable = "true"; + return after + } else if (before) { + before.contentEditable = "true"; + return before + } + } +} + +function removeClassOnSelectionChange(view) { + var doc = view.dom.ownerDocument; + doc.removeEventListener("selectionchange", view.hideSelectionGuard); + var domSel = view.root.getSelection(); + var node = domSel.anchorNode, offset = domSel.anchorOffset; + doc.addEventListener("selectionchange", view.hideSelectionGuard = function () { + if (domSel.anchorNode != node || domSel.anchorOffset != offset) { + doc.removeEventListener("selectionchange", view.hideSelectionGuard); + view.dom.classList.remove("ProseMirror-hideselection"); + } + }); +} + +function selectCursorWrapper(view) { + var domSel = view.root.getSelection(), range = document.createRange(); + var node = view.cursorWrapper.dom, img = node.nodeName == "IMG"; + if (img) { range.setEnd(node.parentNode, domIndex(node) + 1); } + else { range.setEnd(node, 0); } + range.collapse(false); + domSel.removeAllRanges(); + domSel.addRange(range); + // Kludge to kill 'control selection' in IE11 when selecting an + // invisible cursor wrapper, since that would result in those weird + // resize handles and a selection that considers the absolutely + // positioned wrapper, rather than the root editable node, the + // focused element. + if (!img && !view.state.selection.visible && result.ie && result.ie_version <= 11) { + node.disabled = true; + node.disabled = false; + } +} + +function syncNodeSelection(view, sel) { + if (sel instanceof NodeSelection) { + var desc = view.docView.descAt(sel.from); + if (desc != view.lastSelectedViewDesc) { + clearNodeSelection(view); + if (desc) { desc.selectNode(); } + view.lastSelectedViewDesc = desc; + } + } else { + clearNodeSelection(view); + } +} + +// Clear all DOM statefulness of the last node selection. +function clearNodeSelection(view) { + if (view.lastSelectedViewDesc) { + if (view.lastSelectedViewDesc.parent) + { view.lastSelectedViewDesc.deselectNode(); } + view.lastSelectedViewDesc = null; + } +} + +function selectionBetween(view, $anchor, $head, bias) { + return view.someProp("createSelectionBetween", function (f) { return f(view, $anchor, $head); }) + || TextSelection.between($anchor, $head, bias) +} + +function hasFocusAndSelection(view) { + if (view.editable && view.root.activeElement != view.dom) { return false } + return hasSelection(view) +} + +function hasSelection(view) { + var sel = view.root.getSelection(); + if (!sel.anchorNode) { return false } + try { + // Firefox will raise 'permission denied' errors when accessing + // properties of `sel.anchorNode` when it's in a generated CSS + // element. + return view.dom.contains(sel.anchorNode.nodeType == 3 ? sel.anchorNode.parentNode : sel.anchorNode) && + (view.editable || view.dom.contains(sel.focusNode.nodeType == 3 ? sel.focusNode.parentNode : sel.focusNode)) + } catch(_) { + return false + } +} + +function anchorInRightPlace(view) { + var anchorDOM = view.docView.domFromPos(view.state.selection.anchor); + var domSel = view.root.getSelection(); + return isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset) +} + +// Note that all referencing and parsing is done with the +// start-of-operation selection and document, since that's the one +// that the DOM represents. If any changes came in in the meantime, +// the modification is mapped over those before it is applied, in +// readDOMChange. + +function parseBetween(view, from_, to_) { + var ref = view.docView.parseRange(from_, to_); + var parent = ref.node; + var fromOffset = ref.fromOffset; + var toOffset = ref.toOffset; + var from = ref.from; + var to = ref.to; + + var domSel = view.root.getSelection(), find = null, anchor = domSel.anchorNode; + if (anchor && view.dom.contains(anchor.nodeType == 1 ? anchor : anchor.parentNode)) { + find = [{node: anchor, offset: domSel.anchorOffset}]; + if (!selectionCollapsed(domSel)) + { find.push({node: domSel.focusNode, offset: domSel.focusOffset}); } + } + // Work around issue in Chrome where backspacing sometimes replaces + // the deleted content with a random BR node (issues #799, #831) + if (result.chrome && view.lastKeyCode === 8) { + for (var off = toOffset; off > fromOffset; off--) { + var node = parent.childNodes[off - 1], desc = node.pmViewDesc; + if (node.nodeType == "BR" && !desc) { toOffset = off; break } + if (!desc || desc.size) { break } + } + } + var startDoc = view.state.doc; + var parser = view.someProp("domParser") || DOMParser.fromSchema(view.state.schema); + var $from = startDoc.resolve(from); + + var sel = null, doc = parser.parse(parent, { + topNode: $from.parent, + topMatch: $from.parent.contentMatchAt($from.index()), + topOpen: true, + from: fromOffset, + to: toOffset, + preserveWhitespace: $from.parent.type.spec.code ? "full" : true, + editableContent: true, + findPositions: find, + ruleFromNode: ruleFromNode, + context: $from + }); + if (find && find[0].pos != null) { + var anchor$1 = find[0].pos, head = find[1] && find[1].pos; + if (head == null) { head = anchor$1; } + sel = {anchor: anchor$1 + from, head: head + from}; + } + return {doc: doc, sel: sel, from: from, to: to} +} + +function ruleFromNode(dom) { + var desc = dom.pmViewDesc; + if (desc) { + return desc.parseRule() + } else if (dom.nodeName == "BR" && dom.parentNode) { + // Safari replaces the list item or table cell with a BR + // directly in the list node (?!) if you delete the last + // character in a list item or table cell (#708, #862) + if (result.safari && /^(ul|ol)$/i.test(dom.parentNode.nodeName)) { + var skip = document.createElement("div"); + skip.appendChild(document.createElement("li")); + return {skip: skip} + } else if (dom.parentNode.lastChild == dom || result.safari && /^(tr|table)$/i.test(dom.parentNode.nodeName)) { + return {ignore: true} + } + } else if (dom.nodeName == "IMG" && dom.getAttribute("mark-placeholder")) { + return {ignore: true} + } +} + +function readDOMChange(view, from, to, typeOver) { + if (from < 0) { + var origin = view.lastSelectionTime > Date.now() - 50 ? view.lastSelectionOrigin : null; + var newSel = selectionFromDOM(view, origin); + if (!view.state.selection.eq(newSel)) { + var tr$1 = view.state.tr.setSelection(newSel); + if (origin == "pointer") { tr$1.setMeta("pointer", true); } + else if (origin == "key") { tr$1.scrollIntoView(); } + view.dispatch(tr$1); + } + return + } + + var $before = view.state.doc.resolve(from); + var shared = $before.sharedDepth(to); + from = $before.before(shared + 1); + to = view.state.doc.resolve(to).after(shared + 1); + + var sel = view.state.selection; + var parse = parseBetween(view, from, to); + + var doc = view.state.doc, compare = doc.slice(parse.from, parse.to); + var preferredPos, preferredSide; + // Prefer anchoring to end when Backspace is pressed + if (view.lastKeyCode === 8 && Date.now() - 100 < view.lastKeyCodeTime) { + preferredPos = view.state.selection.to; + preferredSide = "end"; + } else { + preferredPos = view.state.selection.from; + preferredSide = "start"; + } + view.lastKeyCode = null; + + var change = findDiff(compare.content, parse.doc.content, parse.from, preferredPos, preferredSide); + if (!change) { + if (typeOver && sel instanceof TextSelection && !sel.empty && sel.$head.sameParent(sel.$anchor) && + !view.composing && !(parse.sel && parse.sel.anchor != parse.sel.head)) { + change = {start: sel.from, endA: sel.to, endB: sel.to}; + } else { + if (parse.sel) { + var sel$1 = resolveSelection(view, view.state.doc, parse.sel); + if (sel$1 && !sel$1.eq(view.state.selection)) { view.dispatch(view.state.tr.setSelection(sel$1)); } + } + return + } + } + view.domChangeCount++; + // Handle the case where overwriting a selection by typing matches + // the start or end of the selected content, creating a change + // that's smaller than what was actually overwritten. + if (view.state.selection.from < view.state.selection.to && + change.start == change.endB && + view.state.selection instanceof TextSelection) { + if (change.start > view.state.selection.from && change.start <= view.state.selection.from + 2) { + change.start = view.state.selection.from; + } else if (change.endA < view.state.selection.to && change.endA >= view.state.selection.to - 2) { + change.endB += (view.state.selection.to - change.endA); + change.endA = view.state.selection.to; + } + } + + // IE11 will insert a non-breaking space _ahead_ of the space after + // the cursor space when adding a space before another space. When + // that happened, adjust the change to cover the space instead. + if (result.ie && result.ie_version <= 11 && change.endB == change.start + 1 && + change.endA == change.start && change.start > parse.from && + parse.doc.textBetween(change.start - parse.from - 1, change.start - parse.from + 1) == " \u00a0") { + change.start--; + change.endA--; + change.endB--; + } + + var $from = parse.doc.resolveNoCache(change.start - parse.from); + var $to = parse.doc.resolveNoCache(change.endB - parse.from); + var nextSel; + // If this looks like the effect of pressing Enter, just dispatch an + // Enter key instead. + if (!$from.sameParent($to) && $from.pos < parse.doc.content.size && + (nextSel = Selection.findFrom(parse.doc.resolve($from.pos + 1), 1, true)) && + nextSel.head == $to.pos && + view.someProp("handleKeyDown", function (f) { return f(view, keyEvent(13, "Enter")); })) + { return } + // Same for backspace + if (view.state.selection.anchor > change.start && + looksLikeJoin(doc, change.start, change.endA, $from, $to) && + view.someProp("handleKeyDown", function (f) { return f(view, keyEvent(8, "Backspace")); })) { + if (result.android && result.chrome) { view.domObserver.suppressSelectionUpdates(); } // #820 + return + } + + var chFrom = change.start, chTo = change.endA; + + var tr, storedMarks, markChange, $from1; + if ($from.sameParent($to) && $from.parent.inlineContent) { + if ($from.pos == $to.pos) { // Deletion + // IE11 sometimes weirdly moves the DOM selection around after + // backspacing out the first element in a textblock + if (result.ie && result.ie_version <= 11 && $from.parentOffset == 0) { + view.domObserver.suppressSelectionUpdates(); + setTimeout(function () { return selectionToDOM(view); }, 20); + } + tr = view.state.tr.delete(chFrom, chTo); + storedMarks = doc.resolve(change.start).marksAcross(doc.resolve(change.endA)); + } else if ( // Adding or removing a mark + change.endA == change.endB && ($from1 = doc.resolve(change.start)) && + (markChange = isMarkChange($from.parent.content.cut($from.parentOffset, $to.parentOffset), + $from1.parent.content.cut($from1.parentOffset, change.endA - $from1.start()))) + ) { + tr = view.state.tr; + if (markChange.type == "add") { tr.addMark(chFrom, chTo, markChange.mark); } + else { tr.removeMark(chFrom, chTo, markChange.mark); } + } else if ($from.parent.child($from.index()).isText && $from.index() == $to.index() - ($to.textOffset ? 0 : 1)) { + // Both positions in the same text node -- simply insert text + var text = $from.parent.textBetween($from.parentOffset, $to.parentOffset); + if (view.someProp("handleTextInput", function (f) { return f(view, chFrom, chTo, text); })) { return } + tr = view.state.tr.insertText(text, chFrom, chTo); + } + } + + if (!tr) + { tr = view.state.tr.replace(chFrom, chTo, parse.doc.slice(change.start - parse.from, change.endB - parse.from)); } + if (parse.sel) { + var sel$2 = resolveSelection(view, tr.doc, parse.sel); + // Chrome Android will sometimes, during composition, report the + // selection in the wrong place. If it looks like that is + // happening, don't update the selection. + // Edge just doesn't move the cursor forward when you start typing + // in an empty block or between br nodes. + if (sel$2 && !(result.chrome && result.android && view.composing && sel$2.empty && sel$2.head == chFrom || + result.ie && sel$2.empty && sel$2.head == chFrom)) + { tr.setSelection(sel$2); } + } + if (storedMarks) { tr.ensureMarks(storedMarks); } + view.dispatch(tr.scrollIntoView()); +} + +function resolveSelection(view, doc, parsedSel) { + if (Math.max(parsedSel.anchor, parsedSel.head) > doc.content.size) { return null } + return selectionBetween(view, doc.resolve(parsedSel.anchor), doc.resolve(parsedSel.head)) +} + +// : (Fragment, Fragment) → ?{mark: Mark, type: string} +// Given two same-length, non-empty fragments of inline content, +// determine whether the first could be created from the second by +// removing or adding a single mark type. +function isMarkChange(cur, prev) { + var curMarks = cur.firstChild.marks, prevMarks = prev.firstChild.marks; + var added = curMarks, removed = prevMarks, type, mark, update; + for (var i = 0; i < prevMarks.length; i++) { added = prevMarks[i].removeFromSet(added); } + for (var i$1 = 0; i$1 < curMarks.length; i$1++) { removed = curMarks[i$1].removeFromSet(removed); } + if (added.length == 1 && removed.length == 0) { + mark = added[0]; + type = "add"; + update = function (node) { return node.mark(mark.addToSet(node.marks)); }; + } else if (added.length == 0 && removed.length == 1) { + mark = removed[0]; + type = "remove"; + update = function (node) { return node.mark(mark.removeFromSet(node.marks)); }; + } else { + return null + } + var updated = []; + for (var i$2 = 0; i$2 < prev.childCount; i$2++) { updated.push(update(prev.child(i$2))); } + if (Fragment.from(updated).eq(cur)) { return {mark: mark, type: type} } +} + +function looksLikeJoin(old, start, end, $newStart, $newEnd) { + if (!$newStart.parent.isTextblock || + // The content must have shrunk + end - start <= $newEnd.pos - $newStart.pos || + // newEnd must point directly at or after the end of the block that newStart points into + skipClosingAndOpening($newStart, true, false) < $newEnd.pos) + { return false } + + var $start = old.resolve(start); + // Start must be at the end of a block + if ($start.parentOffset < $start.parent.content.size || !$start.parent.isTextblock) + { return false } + var $next = old.resolve(skipClosingAndOpening($start, true, true)); + // The next textblock must start before end and end near it + if (!$next.parent.isTextblock || $next.pos > end || + skipClosingAndOpening($next, true, false) < end) + { return false } + + // The fragments after the join point must match + return $newStart.parent.content.cut($newStart.parentOffset).eq($next.parent.content) +} + +function skipClosingAndOpening($pos, fromEnd, mayOpen) { + var depth = $pos.depth, end = fromEnd ? $pos.end() : $pos.pos; + while (depth > 0 && (fromEnd || $pos.indexAfter(depth) == $pos.node(depth).childCount)) { + depth--; + end++; + fromEnd = false; + } + if (mayOpen) { + var next = $pos.node(depth).maybeChild($pos.indexAfter(depth)); + while (next && !next.isLeaf) { + next = next.firstChild; + end++; + } + } + return end +} + +function findDiff(a, b, pos, preferredPos, preferredSide) { + var start = a.findDiffStart(b, pos); + if (start == null) { return null } + var ref = a.findDiffEnd(b, pos + a.size, pos + b.size); + var endA = ref.a; + var endB = ref.b; + if (preferredSide == "end") { + var adjust = Math.max(0, start - Math.min(endA, endB)); + preferredPos -= endA + adjust - start; + } + if (endA < start && a.size < b.size) { + var move = preferredPos <= start && preferredPos >= endA ? start - preferredPos : 0; + start -= move; + endB = start + (endB - endA); + endA = start; + } else if (endB < start) { + var move$1 = preferredPos <= start && preferredPos >= endB ? start - preferredPos : 0; + start -= move$1; + endA = start + (endA - endB); + endB = start; + } + return {start: start, endA: endA, endB: endB} +} + +function serializeForClipboard(view, slice) { + var context = []; + var content = slice.content; + var openStart = slice.openStart; + var openEnd = slice.openEnd; + while (openStart > 1 && openEnd > 1 && content.childCount == 1 && content.firstChild.childCount == 1) { + openStart--; + openEnd--; + var node = content.firstChild; + context.push(node.type.name, node.type.hasRequiredAttrs() ? node.attrs : null); + content = node.content; + } + + var serializer = view.someProp("clipboardSerializer") || DOMSerializer.fromSchema(view.state.schema); + var doc = detachedDoc(), wrap = doc.createElement("div"); + wrap.appendChild(serializer.serializeFragment(content, {document: doc})); + + var firstChild = wrap.firstChild, needsWrap; + while (firstChild && firstChild.nodeType == 1 && (needsWrap = wrapMap[firstChild.nodeName.toLowerCase()])) { + for (var i = needsWrap.length - 1; i >= 0; i--) { + var wrapper = doc.createElement(needsWrap[i]); + while (wrap.firstChild) { wrapper.appendChild(wrap.firstChild); } + wrap.appendChild(wrapper); + } + firstChild = wrap.firstChild; + } + + if (firstChild && firstChild.nodeType == 1) + { firstChild.setAttribute("data-pm-slice", (openStart + " " + openEnd + " " + (JSON.stringify(context)))); } + + var text = view.someProp("clipboardTextSerializer", function (f) { return f(slice); }) || + slice.content.textBetween(0, slice.content.size, "\n\n"); + + return {dom: wrap, text: text} +} + +// : (EditorView, string, string, ?bool, ResolvedPos) → ?Slice +// Read a slice of content from the clipboard (or drop data). +function parseFromClipboard(view, text, html, plainText, $context) { + var dom, inCode = $context.parent.type.spec.code, slice; + if (!html && !text) { return null } + var asText = text && (plainText || inCode || !html); + if (asText) { + view.someProp("transformPastedText", function (f) { text = f(text); }); + if (inCode) { return new Slice(Fragment.from(view.state.schema.text(text)), 0, 0) } + var parsed = view.someProp("clipboardTextParser", function (f) { return f(text, $context); }); + if (parsed) { + slice = parsed; + } else { + dom = document.createElement("div"); + text.trim().split(/(?:\r\n?|\n)+/).forEach(function (block) { + dom.appendChild(document.createElement("p")).textContent = block; + }); + } + } else { + view.someProp("transformPastedHTML", function (f) { html = f(html); }); + dom = readHTML(html); + } + + var contextNode = dom && dom.querySelector("[data-pm-slice]"); + var sliceData = contextNode && /^(\d+) (\d+) (.*)/.exec(contextNode.getAttribute("data-pm-slice")); + if (!slice) { + var parser = view.someProp("clipboardParser") || view.someProp("domParser") || DOMParser.fromSchema(view.state.schema); + slice = parser.parseSlice(dom, {preserveWhitespace: !!(asText || sliceData), context: $context}); + } + if (sliceData) + { slice = addContext(closeSlice(slice, +sliceData[1], +sliceData[2]), sliceData[3]); } + else // HTML wasn't created by ProseMirror. Make sure top-level siblings are coherent + { slice = Slice.maxOpen(normalizeSiblings(slice.content, $context), false); } + + view.someProp("transformPasted", function (f) { slice = f(slice); }); + return slice +} + +// Takes a slice parsed with parseSlice, which means there hasn't been +// any content-expression checking done on the top nodes, tries to +// find a parent node in the current context that might fit the nodes, +// and if successful, rebuilds the slice so that it fits into that parent. +// +// This addresses the problem that Transform.replace expects a +// coherent slice, and will fail to place a set of siblings that don't +// fit anywhere in the schema. +function normalizeSiblings(fragment, $context) { + if (fragment.childCount < 2) { return fragment } + var loop = function ( d ) { + var parent = $context.node(d); + var match = parent.contentMatchAt($context.index(d)); + var lastWrap = (void 0), result = []; + fragment.forEach(function (node) { + if (!result) { return } + var wrap = match.findWrapping(node.type), inLast; + if (!wrap) { return result = null } + if (inLast = result.length && lastWrap.length && addToSibling(wrap, lastWrap, node, result[result.length - 1], 0)) { + result[result.length - 1] = inLast; + } else { + if (result.length) { result[result.length - 1] = closeRight(result[result.length - 1], lastWrap.length); } + var wrapped = withWrappers(node, wrap); + result.push(wrapped); + match = match.matchType(wrapped.type, wrapped.attrs); + lastWrap = wrap; + } + }); + if (result) { return { v: Fragment.from(result) } } + }; + + for (var d = $context.depth; d >= 0; d--) { + var returned = loop( d ); + + if ( returned ) return returned.v; + } + return fragment +} + +function withWrappers(node, wrap, from) { + if ( from === void 0 ) from = 0; + + for (var i = wrap.length - 1; i >= from; i--) + { node = wrap[i].create(null, Fragment.from(node)); } + return node +} + +// Used to group adjacent nodes wrapped in similar parents by +// normalizeSiblings into the same parent node +function addToSibling(wrap, lastWrap, node, sibling, depth) { + if (depth < wrap.length && depth < lastWrap.length && wrap[depth] == lastWrap[depth]) { + var inner = addToSibling(wrap, lastWrap, node, sibling.lastChild, depth + 1); + if (inner) { return sibling.copy(sibling.content.replaceChild(sibling.childCount - 1, inner)) } + var match = sibling.contentMatchAt(sibling.childCount); + if (match.matchType(depth == wrap.length - 1 ? node.type : wrap[depth + 1])) + { return sibling.copy(sibling.content.append(Fragment.from(withWrappers(node, wrap, depth + 1)))) } + } +} + +function closeRight(node, depth) { + if (depth == 0) { return node } + var fragment = node.content.replaceChild(node.childCount - 1, closeRight(node.lastChild, depth - 1)); + var fill = node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true); + return node.copy(fragment.append(fill)) +} + +function closeRange(fragment, side, from, to, depth, openEnd) { + var node = side < 0 ? fragment.firstChild : fragment.lastChild, inner = node.content; + if (depth < to - 1) { inner = closeRange(inner, side, from, to, depth + 1, openEnd); } + if (depth >= from) + { inner = side < 0 ? node.contentMatchAt(0).fillBefore(inner, fragment.childCount > 1 || openEnd <= depth).append(inner) + : inner.append(node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true)); } + return fragment.replaceChild(side < 0 ? 0 : fragment.childCount - 1, node.copy(inner)) +} + +function closeSlice(slice, openStart, openEnd) { + if (openStart < slice.openStart) + { slice = new Slice(closeRange(slice.content, -1, openStart, slice.openStart, 0, slice.openEnd), openStart, slice.openEnd); } + if (openEnd < slice.openEnd) + { slice = new Slice(closeRange(slice.content, 1, openEnd, slice.openEnd, 0, 0), slice.openStart, openEnd); } + return slice +} + +// Trick from jQuery -- some elements must be wrapped in other +// elements for innerHTML to work. I.e. if you do `div.innerHTML = +// ".."` the table cells are ignored. +var wrapMap = {thead: ["table"], colgroup: ["table"], col: ["table", "colgroup"], + tr: ["table", "tbody"], td: ["table", "tbody", "tr"], th: ["table", "tbody", "tr"]}; + +var _detachedDoc = null; +function detachedDoc() { + return _detachedDoc || (_detachedDoc = document.implementation.createHTMLDocument("title")) +} + +function readHTML(html) { + var metas = /(\s*]*>)*/.exec(html); + if (metas) { html = html.slice(metas[0].length); } + var elt = detachedDoc().createElement("div"); + var firstTag = /(?:]*>)*<([a-z][^>\s]+)/i.exec(html), wrap, depth = 0; + if (wrap = firstTag && wrapMap[firstTag[1].toLowerCase()]) { + html = wrap.map(function (n) { return "<" + n + ">"; }).join("") + html + wrap.map(function (n) { return ""; }).reverse().join(""); + depth = wrap.length; + } + elt.innerHTML = html; + for (var i = 0; i < depth; i++) { elt = elt.firstChild; } + return elt +} + +function addContext(slice, context) { + if (!slice.size) { return slice } + var schema = slice.content.firstChild.type.schema, array; + try { array = JSON.parse(context); } + catch(e) { return slice } + var content = slice.content; + var openStart = slice.openStart; + var openEnd = slice.openEnd; + for (var i = array.length - 2; i >= 0; i -= 2) { + var type = schema.nodes[array[i]]; + if (!type || type.hasRequiredAttrs()) { break } + content = Fragment.from(type.create(array[i + 1], content)); + openStart++; openEnd++; + } + return new Slice(content, openStart, openEnd) +} + +var observeOptions = { + childList: true, + characterData: true, + characterDataOldValue: true, + attributes: true, + attributeOldValue: true, + subtree: true +}; +// IE11 has very broken mutation observers, so we also listen to DOMCharacterDataModified +var useCharData = result.ie && result.ie_version <= 11; + +var SelectionState = function SelectionState() { + this.anchorNode = this.anchorOffset = this.focusNode = this.focusOffset = null; +}; + +SelectionState.prototype.set = function set (sel) { + this.anchorNode = sel.anchorNode; this.anchorOffset = sel.anchorOffset; + this.focusNode = sel.focusNode; this.focusOffset = sel.focusOffset; +}; + +SelectionState.prototype.eq = function eq (sel) { + return sel.anchorNode == this.anchorNode && sel.anchorOffset == this.anchorOffset && + sel.focusNode == this.focusNode && sel.focusOffset == this.focusOffset +}; + +var DOMObserver = function DOMObserver(view, handleDOMChange) { + var this$1 = this; + + this.view = view; + this.handleDOMChange = handleDOMChange; + this.queue = []; + this.flushingSoon = false; + this.observer = window.MutationObserver && + new window.MutationObserver(function (mutations) { + for (var i = 0; i < mutations.length; i++) { this$1.queue.push(mutations[i]); } + // IE11 will sometimes (on backspacing out a single character + // text node after a BR node) call the observer callback + // before actually updating the DOM, which will cause + // ProseMirror to miss the change (see #930) + if (result.ie && result.ie_version <= 11 && mutations.some( + function (m) { return m.type == "childList" && m.removedNodes.length || + m.type == "characterData" && m.oldValue.length > m.target.nodeValue.length; })) + { this$1.flushSoon(); } + else + { this$1.flush(); } + }); + this.currentSelection = new SelectionState; + if (useCharData) { + this.onCharData = function (e) { + this$1.queue.push({target: e.target, type: "characterData", oldValue: e.prevValue}); + this$1.flushSoon(); + }; + } + this.onSelectionChange = this.onSelectionChange.bind(this); + this.suppressingSelectionUpdates = false; +}; + +DOMObserver.prototype.flushSoon = function flushSoon () { + var this$1 = this; + + if (!this.flushingSoon) { + this.flushingSoon = true; + window.setTimeout(function () { this$1.flushingSoon = false; this$1.flush(); }, 20); + } +}; + +DOMObserver.prototype.start = function start () { + if (this.observer) + { this.observer.observe(this.view.dom, observeOptions); } + if (useCharData) + { this.view.dom.addEventListener("DOMCharacterDataModified", this.onCharData); } + this.connectSelection(); +}; + +DOMObserver.prototype.stop = function stop () { + var this$1 = this; + + if (this.observer) { + var take = this.observer.takeRecords(); + if (take.length) { + for (var i = 0; i < take.length; i++) { this.queue.push(take[i]); } + window.setTimeout(function () { return this$1.flush(); }, 20); + } + this.observer.disconnect(); + } + if (useCharData) { this.view.dom.removeEventListener("DOMCharacterDataModified", this.onCharData); } + this.disconnectSelection(); +}; + +DOMObserver.prototype.connectSelection = function connectSelection () { + this.view.dom.ownerDocument.addEventListener("selectionchange", this.onSelectionChange); +}; + +DOMObserver.prototype.disconnectSelection = function disconnectSelection () { + this.view.dom.ownerDocument.removeEventListener("selectionchange", this.onSelectionChange); +}; + +DOMObserver.prototype.suppressSelectionUpdates = function suppressSelectionUpdates () { + var this$1 = this; + + this.suppressingSelectionUpdates = true; + setTimeout(function () { return this$1.suppressingSelectionUpdates = false; }, 50); +}; + +DOMObserver.prototype.onSelectionChange = function onSelectionChange () { + if (!hasFocusAndSelection(this.view)) { return } + if (this.suppressingSelectionUpdates) { return selectionToDOM(this.view) } + // Deletions on IE11 fire their events in the wrong order, giving + // us a selection change event before the DOM changes are + // reported. + if (result.ie && result.ie_version <= 11 && !this.view.state.selection.empty) { + var sel = this.view.root.getSelection(); + // Selection.isCollapsed isn't reliable on IE + if (sel.focusNode && isEquivalentPosition(sel.focusNode, sel.focusOffset, sel.anchorNode, sel.anchorOffset)) + { return this.flushSoon() } + } + this.flush(); +}; + +DOMObserver.prototype.setCurSelection = function setCurSelection () { + this.currentSelection.set(this.view.root.getSelection()); +}; + +DOMObserver.prototype.ignoreSelectionChange = function ignoreSelectionChange (sel) { + if (sel.rangeCount == 0) { return true } + var container = sel.getRangeAt(0).commonAncestorContainer; + var desc = this.view.docView.nearestDesc(container); + return desc && desc.ignoreMutation({type: "selection", target: container.nodeType == 3 ? container.parentNode : container}) +}; + +DOMObserver.prototype.flush = function flush () { + if (!this.view.docView || this.flushingSoon) { return } + var mutations = this.observer ? this.observer.takeRecords() : []; + if (this.queue.length) { + mutations = this.queue.concat(mutations); + this.queue.length = 0; + } + + var sel = this.view.root.getSelection(); + var newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasSelection(this.view) && !this.ignoreSelectionChange(sel); + + var from = -1, to = -1, typeOver = false, added = []; + if (this.view.editable) { + for (var i = 0; i < mutations.length; i++) { + var result$1 = this.registerMutation(mutations[i], added); + if (result$1) { + from = from < 0 ? result$1.from : Math.min(result$1.from, from); + to = to < 0 ? result$1.to : Math.max(result$1.to, to); + if (result$1.typeOver && !this.view.composing) { typeOver = true; } + } + } + } + + if (result.gecko && added.length > 1) { + var brs = added.filter(function (n) { return n.nodeName == "BR"; }); + if (brs.length == 2) { + var a = brs[0]; + var b = brs[1]; + if (a.parentNode && a.parentNode.parentNode == b.parentNode) { b.remove(); } + else { a.remove(); } + } + } + + if (from > -1 || newSel) { + if (from > -1) { + this.view.docView.markDirty(from, to); + checkCSS(this.view); + } + this.handleDOMChange(from, to, typeOver); + if (this.view.docView.dirty) { this.view.updateState(this.view.state); } + else if (!this.currentSelection.eq(sel)) { selectionToDOM(this.view); } + } +}; + +DOMObserver.prototype.registerMutation = function registerMutation (mut, added) { + // Ignore mutations inside nodes that were already noted as inserted + if (added.indexOf(mut.target) > -1) { return null } + var desc = this.view.docView.nearestDesc(mut.target); + if (mut.type == "attributes" && + (desc == this.view.docView || mut.attributeName == "contenteditable" || + // Firefox sometimes fires spurious events for null/empty styles + (mut.attributeName == "style" && !mut.oldValue && !mut.target.getAttribute("style")))) + { return null } + if (!desc || desc.ignoreMutation(mut)) { return null } + + if (mut.type == "childList") { + var prev = mut.previousSibling, next = mut.nextSibling; + if (result.ie && result.ie_version <= 11 && mut.addedNodes.length) { + // IE11 gives us incorrect next/prev siblings for some + // insertions, so if there are added nodes, recompute those + for (var i = 0; i < mut.addedNodes.length; i++) { + var ref = mut.addedNodes[i]; + var previousSibling = ref.previousSibling; + var nextSibling = ref.nextSibling; + if (!previousSibling || Array.prototype.indexOf.call(mut.addedNodes, previousSibling) < 0) { prev = previousSibling; } + if (!nextSibling || Array.prototype.indexOf.call(mut.addedNodes, nextSibling) < 0) { next = nextSibling; } + } + } + var fromOffset = prev && prev.parentNode == mut.target + ? domIndex(prev) + 1 : 0; + var from = desc.localPosFromDOM(mut.target, fromOffset, -1); + var toOffset = next && next.parentNode == mut.target + ? domIndex(next) : mut.target.childNodes.length; + for (var i$1 = 0; i$1 < mut.addedNodes.length; i$1++) { added.push(mut.addedNodes[i$1]); } + var to = desc.localPosFromDOM(mut.target, toOffset, 1); + return {from: from, to: to} + } else if (mut.type == "attributes") { + return {from: desc.posAtStart - desc.border, to: desc.posAtEnd + desc.border} + } else { // "characterData" + return { + from: desc.posAtStart, + to: desc.posAtEnd, + // An event was generated for a text change that didn't change + // any text. Mark the dom change to fall back to assuming the + // selection was typed over with an identical value if it can't + // find another change. + typeOver: mut.target.nodeValue == mut.oldValue + } + } +}; + +var cssChecked = false; + +function checkCSS(view) { + if (cssChecked) { return } + cssChecked = true; + if (getComputedStyle(view.dom).whiteSpace == "normal") + { console["warn"]("ProseMirror expects the CSS white-space property to be set, preferably to 'pre-wrap'. It is recommended to load style/prosemirror.css from the prosemirror-view package."); } +} + +// A collection of DOM events that occur within the editor, and callback functions +// to invoke when the event fires. +var handlers = {}, editHandlers = {}; + +function initInput(view) { + view.shiftKey = false; + view.mouseDown = null; + view.lastKeyCode = null; + view.lastKeyCodeTime = 0; + view.lastClick = {time: 0, x: 0, y: 0, type: ""}; + view.lastSelectionOrigin = null; + view.lastSelectionTime = 0; + + view.composing = false; + view.composingTimeout = null; + view.compositionNodes = []; + view.compositionEndedAt = -2e8; + + view.domObserver = new DOMObserver(view, function (from, to, typeOver) { return readDOMChange(view, from, to, typeOver); }); + view.domObserver.start(); + // Used by hacks like the beforeinput handler to check whether anything happened in the DOM + view.domChangeCount = 0; + + view.eventHandlers = Object.create(null); + var loop = function ( event ) { + var handler = handlers[event]; + view.dom.addEventListener(event, view.eventHandlers[event] = function (event) { + if (eventBelongsToView(view, event) && !runCustomHandler(view, event) && + (view.editable || !(event.type in editHandlers))) + { handler(view, event); } + }); + }; + + for (var event in handlers) loop( event ); + // On Safari, for reasons beyond my understanding, adding an input + // event handler makes an issue where the composition vanishes when + // you press enter go away. + if (result.safari) { view.dom.addEventListener("input", function () { return null; }); } + + ensureListeners(view); +} + +function setSelectionOrigin(view, origin) { + view.lastSelectionOrigin = origin; + view.lastSelectionTime = Date.now(); +} + +function destroyInput(view) { + view.domObserver.stop(); + for (var type in view.eventHandlers) + { view.dom.removeEventListener(type, view.eventHandlers[type]); } + clearTimeout(view.composingTimeout); +} + +function ensureListeners(view) { + view.someProp("handleDOMEvents", function (currentHandlers) { + for (var type in currentHandlers) { if (!view.eventHandlers[type]) + { view.dom.addEventListener(type, view.eventHandlers[type] = function (event) { return runCustomHandler(view, event); }); } } + }); +} + +function runCustomHandler(view, event) { + return view.someProp("handleDOMEvents", function (handlers) { + var handler = handlers[event.type]; + return handler ? handler(view, event) || event.defaultPrevented : false + }) +} + +function eventBelongsToView(view, event) { + if (!event.bubbles) { return true } + if (event.defaultPrevented) { return false } + for (var node = event.target; node != view.dom; node = node.parentNode) + { if (!node || node.nodeType == 11 || + (node.pmViewDesc && node.pmViewDesc.stopEvent(event))) + { return false } } + return true +} + +function dispatchEvent(view, event) { + if (!runCustomHandler(view, event) && handlers[event.type] && + (view.editable || !(event.type in editHandlers))) + { handlers[event.type](view, event); } +} + +editHandlers.keydown = function (view, event) { + view.shiftKey = event.keyCode == 16 || event.shiftKey; + if (inOrNearComposition(view, event)) { return } + view.lastKeyCode = event.keyCode; + view.lastKeyCodeTime = Date.now(); + if (view.someProp("handleKeyDown", function (f) { return f(view, event); }) || captureKeyDown(view, event)) + { event.preventDefault(); } + else + { setSelectionOrigin(view, "key"); } +}; + +editHandlers.keyup = function (view, e) { + if (e.keyCode == 16) { view.shiftKey = false; } +}; + +editHandlers.keypress = function (view, event) { + if (inOrNearComposition(view, event) || !event.charCode || + event.ctrlKey && !event.altKey || result.mac && event.metaKey) { return } + + if (view.someProp("handleKeyPress", function (f) { return f(view, event); })) { + event.preventDefault(); + return + } + + var sel = view.state.selection; + if (!(sel instanceof TextSelection) || !sel.$from.sameParent(sel.$to)) { + var text = String.fromCharCode(event.charCode); + if (!view.someProp("handleTextInput", function (f) { return f(view, sel.$from.pos, sel.$to.pos, text); })) + { view.dispatch(view.state.tr.insertText(text).scrollIntoView()); } + event.preventDefault(); + } +}; + +function eventCoords(event) { return {left: event.clientX, top: event.clientY} } + +function isNear(event, click) { + var dx = click.x - event.clientX, dy = click.y - event.clientY; + return dx * dx + dy * dy < 100 +} + +function runHandlerOnContext(view, propName, pos, inside, event) { + if (inside == -1) { return false } + var $pos = view.state.doc.resolve(inside); + var loop = function ( i ) { + if (view.someProp(propName, function (f) { return i > $pos.depth ? f(view, pos, $pos.nodeAfter, $pos.before(i), event, true) + : f(view, pos, $pos.node(i), $pos.before(i), event, false); })) + { return { v: true } } + }; + + for (var i = $pos.depth + 1; i > 0; i--) { + var returned = loop( i ); + + if ( returned ) return returned.v; + } + return false +} + +function updateSelection(view, selection, origin) { + if (!view.focused) { view.focus(); } + var tr = view.state.tr.setSelection(selection); + if (origin == "pointer") { tr.setMeta("pointer", true); } + view.dispatch(tr); +} + +function selectClickedLeaf(view, inside) { + if (inside == -1) { return false } + var $pos = view.state.doc.resolve(inside), node = $pos.nodeAfter; + if (node && node.isAtom && NodeSelection.isSelectable(node)) { + updateSelection(view, new NodeSelection($pos), "pointer"); + return true + } + return false +} + +function selectClickedNode(view, inside) { + if (inside == -1) { return false } + var sel = view.state.selection, selectedNode, selectAt; + if (sel instanceof NodeSelection) { selectedNode = sel.node; } + + var $pos = view.state.doc.resolve(inside); + for (var i = $pos.depth + 1; i > 0; i--) { + var node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i); + if (NodeSelection.isSelectable(node)) { + if (selectedNode && sel.$from.depth > 0 && + i >= sel.$from.depth && $pos.before(sel.$from.depth + 1) == sel.$from.pos) + { selectAt = $pos.before(sel.$from.depth); } + else + { selectAt = $pos.before(i); } + break + } + } + + if (selectAt != null) { + updateSelection(view, NodeSelection.create(view.state.doc, selectAt), "pointer"); + return true + } else { + return false + } +} + +function handleSingleClick(view, pos, inside, event, selectNode) { + return runHandlerOnContext(view, "handleClickOn", pos, inside, event) || + view.someProp("handleClick", function (f) { return f(view, pos, event); }) || + (selectNode ? selectClickedNode(view, inside) : selectClickedLeaf(view, inside)) +} + +function handleDoubleClick(view, pos, inside, event) { + return runHandlerOnContext(view, "handleDoubleClickOn", pos, inside, event) || + view.someProp("handleDoubleClick", function (f) { return f(view, pos, event); }) +} + +function handleTripleClick(view, pos, inside, event) { + return runHandlerOnContext(view, "handleTripleClickOn", pos, inside, event) || + view.someProp("handleTripleClick", function (f) { return f(view, pos, event); }) || + defaultTripleClick(view, inside) +} + +function defaultTripleClick(view, inside) { + var doc = view.state.doc; + if (inside == -1) { + if (doc.inlineContent) { + updateSelection(view, TextSelection.create(doc, 0, doc.content.size), "pointer"); + return true + } + return false + } + + var $pos = doc.resolve(inside); + for (var i = $pos.depth + 1; i > 0; i--) { + var node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i); + var nodePos = $pos.before(i); + if (node.inlineContent) + { updateSelection(view, TextSelection.create(doc, nodePos + 1, nodePos + 1 + node.content.size), "pointer"); } + else if (NodeSelection.isSelectable(node)) + { updateSelection(view, NodeSelection.create(doc, nodePos), "pointer"); } + else + { continue } + return true + } +} + +function forceDOMFlush(view) { + return endComposition(view) +} + +var selectNodeModifier = result.mac ? "metaKey" : "ctrlKey"; + +handlers.mousedown = function (view, event) { + view.shiftKey = event.shiftKey; + var flushed = forceDOMFlush(view); + var now = Date.now(), type = "singleClick"; + if (now - view.lastClick.time < 500 && isNear(event, view.lastClick) && !event[selectNodeModifier]) { + if (view.lastClick.type == "singleClick") { type = "doubleClick"; } + else if (view.lastClick.type == "doubleClick") { type = "tripleClick"; } + } + view.lastClick = {time: now, x: event.clientX, y: event.clientY, type: type}; + + var pos = view.posAtCoords(eventCoords(event)); + if (!pos) { return } + + if (type == "singleClick") + { view.mouseDown = new MouseDown(view, pos, event, flushed); } + else if ((type == "doubleClick" ? handleDoubleClick : handleTripleClick)(view, pos.pos, pos.inside, event)) + { event.preventDefault(); } + else + { setSelectionOrigin(view, "pointer"); } +}; + +var MouseDown = function MouseDown(view, pos, event, flushed) { + var this$1 = this; + + this.view = view; + this.startDoc = view.state.doc; + this.pos = pos; + this.event = event; + this.flushed = flushed; + this.selectNode = event[selectNodeModifier]; + this.allowDefault = event.shiftKey; + + var targetNode, targetPos; + if (pos.inside > -1) { + targetNode = view.state.doc.nodeAt(pos.inside); + targetPos = pos.inside; + } else { + var $pos = view.state.doc.resolve(pos.pos); + targetNode = $pos.parent; + targetPos = $pos.depth ? $pos.before() : 0; + } + + this.mightDrag = null; + + var target = flushed ? null : event.target; + var targetDesc = target ? view.docView.nearestDesc(target, true) : null; + this.target = targetDesc ? targetDesc.dom : null; + + if (targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false || + view.state.selection instanceof NodeSelection && targetPos == view.state.selection.from) + { this.mightDrag = {node: targetNode, + pos: targetPos, + addAttr: this.target && !this.target.draggable, + setUneditable: this.target && result.gecko && !this.target.hasAttribute("contentEditable")}; } + + if (this.target && this.mightDrag && (this.mightDrag.addAttr || this.mightDrag.setUneditable)) { + this.view.domObserver.stop(); + if (this.mightDrag.addAttr) { this.target.draggable = true; } + if (this.mightDrag.setUneditable) + { setTimeout(function () { return this$1.target.setAttribute("contentEditable", "false"); }, 20); } + this.view.domObserver.start(); + } + + view.root.addEventListener("mouseup", this.up = this.up.bind(this)); + view.root.addEventListener("mousemove", this.move = this.move.bind(this)); + setSelectionOrigin(view, "pointer"); +}; + +MouseDown.prototype.done = function done () { + this.view.root.removeEventListener("mouseup", this.up); + this.view.root.removeEventListener("mousemove", this.move); + if (this.mightDrag && this.target) { + this.view.domObserver.stop(); + if (this.mightDrag.addAttr) { this.target.draggable = false; } + if (this.mightDrag.setUneditable) { this.target.removeAttribute("contentEditable"); } + this.view.domObserver.start(); + } + this.view.mouseDown = null; +}; + +MouseDown.prototype.up = function up (event) { + this.done(); + + if (!this.view.dom.contains(event.target.nodeType == 3 ? event.target.parentNode : event.target)) + { return } + + var pos = this.pos; + if (this.view.state.doc != this.startDoc) { pos = this.view.posAtCoords(eventCoords(event)); } + + if (this.allowDefault || !pos) { + setSelectionOrigin(this.view, "pointer"); + } else if (handleSingleClick(this.view, pos.pos, pos.inside, event, this.selectNode)) { + event.preventDefault(); + } else if (this.flushed || + // Chrome will sometimes treat a node selection as a + // cursor, but still report that the node is selected + // when asked through getSelection. You'll then get a + // situation where clicking at the point where that + // (hidden) cursor is doesn't change the selection, and + // thus doesn't get a reaction from ProseMirror. This + // works around that. + (result.chrome && !(this.view.state.selection instanceof TextSelection) && + (pos.pos == this.view.state.selection.from || pos.pos == this.view.state.selection.to))) { + updateSelection(this.view, Selection.near(this.view.state.doc.resolve(pos.pos)), "pointer"); + event.preventDefault(); + } else { + setSelectionOrigin(this.view, "pointer"); + } +}; + +MouseDown.prototype.move = function move (event) { + if (!this.allowDefault && (Math.abs(this.event.x - event.clientX) > 4 || + Math.abs(this.event.y - event.clientY) > 4)) + { this.allowDefault = true; } + setSelectionOrigin(this.view, "pointer"); +}; + +handlers.touchdown = function (view) { + forceDOMFlush(view); + setSelectionOrigin(view, "pointer"); +}; + +handlers.contextmenu = function (view) { return forceDOMFlush(view); }; + +function inOrNearComposition(view, event) { + if (view.composing) { return true } + // See https://www.stum.de/2016/06/24/handling-ime-events-in-javascript/. + // On Japanese input method editors (IMEs), the Enter key is used to confirm character + // selection. On Safari, when Enter is pressed, compositionend and keydown events are + // emitted. The keydown event triggers newline insertion, which we don't want. + // This method returns true if the keydown event should be ignored. + // We only ignore it once, as pressing Enter a second time *should* insert a newline. + // Furthermore, the keydown event timestamp must be close to the compositionEndedAt timestamp. + // This guards against the case where compositionend is triggered without the keyboard + // (e.g. character confirmation may be done with the mouse), and keydown is triggered + // afterwards- we wouldn't want to ignore the keydown event in this case. + if (result.safari && Math.abs(event.timeStamp - view.compositionEndedAt) < 500) { + view.compositionEndedAt = -2e8; + return true + } + return false +} + +// Drop active composition after 5 seconds of inactivity on Android +var timeoutComposition = result.android ? 5000 : -1; + +editHandlers.compositionstart = editHandlers.compositionupdate = function (view) { + if (!view.composing) { + view.domObserver.flush(); + var state = view.state; + var $pos = state.selection.$from; + if (state.selection.empty && + (state.storedMarks || (!$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some(function (m) { return m.type.spec.inclusive === false; })))) { + // Need to wrap the cursor in mark nodes different from the ones in the DOM context + view.markCursor = view.state.storedMarks || $pos.marks(); + endComposition(view, true); + view.markCursor = null; + } else { + endComposition(view); + // In firefox, if the cursor is after but outside a marked node, + // the inserted text won't inherit the marks. So this moves it + // inside if necessary. + if (result.gecko && state.selection.empty && $pos.parentOffset && !$pos.textOffset && $pos.nodeBefore.marks.length) { + var sel = view.root.getSelection(); + for (var node = sel.focusNode, offset = sel.focusOffset; node && node.nodeType == 1 && offset != 0;) { + var before = offset < 0 ? node.lastChild : node.childNodes[offset - 1]; + if (before.nodeType == 3) { + sel.collapse(before, before.nodeValue.length); + break + } else { + node = before; + offset = -1; + } + } + } + } + view.composing = true; + } + scheduleComposeEnd(view, timeoutComposition); +}; + +editHandlers.compositionend = function (view, event) { + if (view.composing) { + view.composing = false; + view.compositionEndedAt = event.timeStamp; + scheduleComposeEnd(view, 20); + } +}; + +function scheduleComposeEnd(view, delay) { + clearTimeout(view.composingTimeout); + if (delay > -1) { view.composingTimeout = setTimeout(function () { return endComposition(view); }, delay); } +} + +function endComposition(view, forceUpdate) { + view.composing = false; + while (view.compositionNodes.length > 0) { view.compositionNodes.pop().markParentsDirty(); } + if (forceUpdate || view.docView.dirty) { + view.updateState(view.state); + return true + } + return false +} + +function captureCopy(view, dom) { + // The extra wrapper is somehow necessary on IE/Edge to prevent the + // content from being mangled when it is put onto the clipboard + var doc = view.dom.ownerDocument; + var wrap = doc.body.appendChild(doc.createElement("div")); + wrap.appendChild(dom); + wrap.style.cssText = "position: fixed; left: -10000px; top: 10px"; + var sel = getSelection(), range = doc.createRange(); + range.selectNodeContents(dom); + // Done because IE will fire a selectionchange moving the selection + // to its start when removeAllRanges is called and the editor still + // has focus (which will mess up the editor's selection state). + view.dom.blur(); + sel.removeAllRanges(); + sel.addRange(range); + setTimeout(function () { + doc.body.removeChild(wrap); + view.focus(); + }, 50); +} + +// This is very crude, but unfortunately both these browsers _pretend_ +// that they have a clipboard API—all the objects and methods are +// there, they just don't work, and they are hard to test. +var brokenClipboardAPI = (result.ie && result.ie_version < 15) || + (result.ios && result.webkit_version < 604); + +handlers.copy = editHandlers.cut = function (view, e) { + var sel = view.state.selection, cut = e.type == "cut"; + if (sel.empty) { return } + + // IE and Edge's clipboard interface is completely broken + var data = brokenClipboardAPI ? null : e.clipboardData; + var slice = sel.content(); + var ref = serializeForClipboard(view, slice); + var dom = ref.dom; + var text = ref.text; + if (data) { + e.preventDefault(); + data.clearData(); + data.setData("text/html", dom.innerHTML); + data.setData("text/plain", text); + } else { + captureCopy(view, dom); + } + if (cut) { view.dispatch(view.state.tr.deleteSelection().scrollIntoView().setMeta("uiEvent", "cut")); } +}; + +function sliceSingleNode(slice) { + return slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1 ? slice.content.firstChild : null +} + +function capturePaste(view, e) { + var doc = view.dom.ownerDocument; + var plainText = view.shiftKey || view.state.selection.$from.parent.type.spec.code; + var target = doc.body.appendChild(doc.createElement(plainText ? "textarea" : "div")); + if (!plainText) { target.contentEditable = "true"; } + target.style.cssText = "position: fixed; left: -10000px; top: 10px"; + target.focus(); + setTimeout(function () { + view.focus(); + doc.body.removeChild(target); + if (plainText) { doPaste(view, target.value, null, e); } + else { doPaste(view, target.textContent, target.innerHTML, e); } + }, 50); +} + +function doPaste(view, text, html, e) { + var slice = parseFromClipboard(view, text, html, view.shiftKey, view.state.selection.$from); + if (view.someProp("handlePaste", function (f) { return f(view, e, slice || Slice.empty); }) || !slice) { return } + + var singleNode = sliceSingleNode(slice); + var tr = singleNode ? view.state.tr.replaceSelectionWith(singleNode, view.shiftKey) : view.state.tr.replaceSelection(slice); + view.dispatch(tr.scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste")); +} + +editHandlers.paste = function (view, e) { + var data = brokenClipboardAPI ? null : e.clipboardData; + var html = data && data.getData("text/html"), text = data && data.getData("text/plain"); + if (data && (html || text || data.files.length)) { + doPaste(view, text, html, e); + e.preventDefault(); + } else { + capturePaste(view, e); + } +}; + +var Dragging = function Dragging(slice, move) { + this.slice = slice; + this.move = move; +}; + +var dragCopyModifier = result.mac ? "altKey" : "ctrlKey"; + +handlers.dragstart = function (view, e) { + var mouseDown = view.mouseDown; + if (mouseDown) { mouseDown.done(); } + if (!e.dataTransfer) { return } + + var sel = view.state.selection; + var pos = sel.empty ? null : view.posAtCoords(eventCoords(e)); + if (pos && pos.pos >= sel.from && pos.pos <= (sel instanceof NodeSelection ? sel.to - 1: sel.to)) ; else if (mouseDown && mouseDown.mightDrag) { + view.dispatch(view.state.tr.setSelection(NodeSelection.create(view.state.doc, mouseDown.mightDrag.pos))); + } else if (e.target && e.target.nodeType == 1) { + var desc = view.docView.nearestDesc(e.target, true); + if (!desc || !desc.node.type.spec.draggable || desc == view.docView) { return } + view.dispatch(view.state.tr.setSelection(NodeSelection.create(view.state.doc, desc.posBefore))); + } + var slice = view.state.selection.content(); + var ref = serializeForClipboard(view, slice); + var dom = ref.dom; + var text = ref.text; + e.dataTransfer.clearData(); + e.dataTransfer.setData(brokenClipboardAPI ? "Text" : "text/html", dom.innerHTML); + if (!brokenClipboardAPI) { e.dataTransfer.setData("text/plain", text); } + view.dragging = new Dragging(slice, !e[dragCopyModifier]); +}; + +handlers.dragend = function (view) { + window.setTimeout(function () { return view.dragging = null; }, 50); +}; + +editHandlers.dragover = editHandlers.dragenter = function (_, e) { return e.preventDefault(); }; + +editHandlers.drop = function (view, e) { + var dragging = view.dragging; + view.dragging = null; + + if (!e.dataTransfer) { return } + + var eventPos = view.posAtCoords(eventCoords(e)); + if (!eventPos) { return } + var $mouse = view.state.doc.resolve(eventPos.pos); + if (!$mouse) { return } + var slice = dragging && dragging.slice || + parseFromClipboard(view, e.dataTransfer.getData(brokenClipboardAPI ? "Text" : "text/plain"), + brokenClipboardAPI ? null : e.dataTransfer.getData("text/html"), false, $mouse); + if (!slice) { return } + + e.preventDefault(); + if (view.someProp("handleDrop", function (f) { return f(view, e, slice, dragging && dragging.move); })) { return } + var insertPos = slice ? dropPoint(view.state.doc, $mouse.pos, slice) : $mouse.pos; + if (insertPos == null) { insertPos = $mouse.pos; } + + var tr = view.state.tr; + if (dragging && dragging.move) { tr.deleteSelection(); } + + var pos = tr.mapping.map(insertPos); + var isNode = slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1; + var beforeInsert = tr.doc; + if (isNode) + { tr.replaceRangeWith(pos, pos, slice.content.firstChild); } + else + { tr.replaceRange(pos, pos, slice); } + if (tr.doc.eq(beforeInsert)) { return } + + var $pos = tr.doc.resolve(pos); + if (isNode && NodeSelection.isSelectable(slice.content.firstChild) && + $pos.nodeAfter && $pos.nodeAfter.sameMarkup(slice.content.firstChild)) + { tr.setSelection(new NodeSelection($pos)); } + else + { tr.setSelection(selectionBetween(view, $pos, tr.doc.resolve(tr.mapping.map(insertPos)))); } + view.focus(); + view.dispatch(tr.setMeta("uiEvent", "drop")); +}; + +handlers.focus = function (view) { + if (!view.focused) { + view.domObserver.stop(); + view.dom.classList.add("ProseMirror-focused"); + view.domObserver.start(); + view.focused = true; + } +}; + +handlers.blur = function (view) { + if (view.focused) { + view.domObserver.stop(); + view.dom.classList.remove("ProseMirror-focused"); + view.domObserver.start(); + view.domObserver.currentSelection.set({}); + view.focused = false; + } +}; + +handlers.beforeinput = function (view, event) { + // We should probably do more with beforeinput events, but support + // is so spotty that I'm still waiting to see where they are going. + + // Very specific hack to deal with backspace sometimes failing on + // Chrome Android when after an uneditable node. + if (result.chrome && result.android && event.inputType == "deleteContentBackward") { + var domChangeCount = view.domChangeCount; + setTimeout(function () { + if (view.domChangeCount != domChangeCount) { return } // Event already had some effect + // This bug tends to close the virtual keyboard, so we refocus + view.dom.blur(); + view.focus(); + if (view.someProp("handleKeyDown", function (f) { return f(view, keyEvent(8, "Backspace")); })) { return } + var ref = view.state.selection; + var $cursor = ref.$cursor; + // Crude approximation of backspace behavior when no command handled it + if ($cursor && $cursor.pos > 0) { view.dispatch(view.state.tr.delete($cursor.pos - 1, $cursor.pos).scrollIntoView()); } + }, 50); + } +}; + +// Make sure all handlers get registered +for (var prop in editHandlers) { handlers[prop] = editHandlers[prop]; } + +function compareObjs(a, b) { + if (a == b) { return true } + for (var p in a) { if (a[p] !== b[p]) { return false } } + for (var p$1 in b) { if (!(p$1 in a)) { return false } } + return true +} + +var WidgetType = function WidgetType(toDOM, spec) { + this.spec = spec || noSpec; + this.side = this.spec.side || 0; + this.toDOM = toDOM; +}; + +WidgetType.prototype.map = function map (mapping, span, offset, oldOffset) { + var ref = mapping.mapResult(span.from + oldOffset, this.side < 0 ? -1 : 1); + var pos = ref.pos; + var deleted = ref.deleted; + return deleted ? null : new Decoration(pos - offset, pos - offset, this) +}; + +WidgetType.prototype.valid = function valid () { return true }; + +WidgetType.prototype.eq = function eq (other) { + return this == other || + (other instanceof WidgetType && + (this.spec.key && this.spec.key == other.spec.key || + this.toDOM == other.toDOM && compareObjs(this.spec, other.spec))) +}; + +var InlineType = function InlineType(attrs, spec) { + this.spec = spec || noSpec; + this.attrs = attrs; +}; + +InlineType.prototype.map = function map (mapping, span, offset, oldOffset) { + var from = mapping.map(span.from + oldOffset, this.spec.inclusiveStart ? -1 : 1) - offset; + var to = mapping.map(span.to + oldOffset, this.spec.inclusiveEnd ? 1 : -1) - offset; + return from >= to ? null : new Decoration(from, to, this) +}; + +InlineType.prototype.valid = function valid (_, span) { return span.from < span.to }; + +InlineType.prototype.eq = function eq (other) { + return this == other || + (other instanceof InlineType && compareObjs(this.attrs, other.attrs) && + compareObjs(this.spec, other.spec)) +}; + +InlineType.is = function is (span) { return span.type instanceof InlineType }; + +var NodeType = function NodeType(attrs, spec) { + this.spec = spec || noSpec; + this.attrs = attrs; +}; + +NodeType.prototype.map = function map (mapping, span, offset, oldOffset) { + var from = mapping.mapResult(span.from + oldOffset, 1); + if (from.deleted) { return null } + var to = mapping.mapResult(span.to + oldOffset, -1); + if (to.deleted || to.pos <= from.pos) { return null } + return new Decoration(from.pos - offset, to.pos - offset, this) +}; + +NodeType.prototype.valid = function valid (node, span) { + var ref = node.content.findIndex(span.from); + var index = ref.index; + var offset = ref.offset; + return offset == span.from && offset + node.child(index).nodeSize == span.to +}; + +NodeType.prototype.eq = function eq (other) { + return this == other || + (other instanceof NodeType && compareObjs(this.attrs, other.attrs) && + compareObjs(this.spec, other.spec)) +}; + +// ::- Decoration objects can be provided to the view through the +// [`decorations` prop](#view.EditorProps.decorations). They come in +// several variants—see the static members of this class for details. +var Decoration = function Decoration(from, to, type) { + // :: number + // The start position of the decoration. + this.from = from; + // :: number + // The end position. Will be the same as `from` for [widget + // decorations](#view.Decoration^widget). + this.to = to; + this.type = type; +}; + +var prototypeAccessors$1 = { spec: { configurable: true } }; + +Decoration.prototype.copy = function copy (from, to) { + return new Decoration(from, to, this.type) +}; + +Decoration.prototype.eq = function eq (other) { + return this.type.eq(other.type) && this.from == other.from && this.to == other.to +}; + +Decoration.prototype.map = function map (mapping, offset, oldOffset) { + return this.type.map(mapping, this, offset, oldOffset) +}; + +// :: (number, union<(view: EditorView, getPos: () → number) → dom.Node, dom.Node>, ?Object) → Decoration +// Creates a widget decoration, which is a DOM node that's shown in +// the document at the given position. It is recommended that you +// delay rendering the widget by passing a function that will be +// called when the widget is actually drawn in a view, but you can +// also directly pass a DOM node. `getPos` can be used to find the +// widget's current document position. +// +// spec::- These options are supported: +// +// side:: ?number +// Controls which side of the document position this widget is +// associated with. When negative, it is drawn before a cursor +// at its position, and content inserted at that position ends +// up after the widget. When zero (the default) or positive, the +// widget is drawn after the cursor and content inserted there +// ends up before the widget. +// +// When there are multiple widgets at a given position, their +// `side` values determine the order in which they appear. Those +// with lower values appear first. The ordering of widgets with +// the same `side` value is unspecified. +// +// When `marks` is null, `side` also determines the marks that +// the widget is wrapped in—those of the node before when +// negative, those of the node after when positive. +// +// marks:: ?[Mark] +// The precise set of marks to draw around the widget. +// +// stopEvent:: ?(event: dom.Event) → bool +// Can be used to control which DOM events, when they bubble out +// of this widget, the editor view should ignore. +// +// key:: ?string +// When comparing decorations of this type (in order to decide +// whether it needs to be redrawn), ProseMirror will by default +// compare the widget DOM node by identity. If you pass a key, +// that key will be compared instead, which can be useful when +// you generate decorations on the fly and don't want to store +// and reuse DOM nodes. Make sure that any widgets with the same +// key are interchangeable—if widgets differ in, for example, +// the behavior of some event handler, they should get +// different keys. +Decoration.widget = function widget (pos, toDOM, spec) { + return new Decoration(pos, pos, new WidgetType(toDOM, spec)) +}; + +// :: (number, number, DecorationAttrs, ?Object) → Decoration +// Creates an inline decoration, which adds the given attributes to +// each inline node between `from` and `to`. +// +// spec::- These options are recognized: +// +// inclusiveStart:: ?bool +// Determines how the left side of the decoration is +// [mapped](#transform.Position_Mapping) when content is +// inserted directly at that position. By default, the decoration +// won't include the new content, but you can set this to `true` +// to make it inclusive. +// +// inclusiveEnd:: ?bool +// Determines how the right side of the decoration is mapped. +// See +// [`inclusiveStart`](#view.Decoration^inline^spec.inclusiveStart). +Decoration.inline = function inline (from, to, attrs, spec) { + return new Decoration(from, to, new InlineType(attrs, spec)) +}; + +// :: (number, number, DecorationAttrs, ?Object) → Decoration +// Creates a node decoration. `from` and `to` should point precisely +// before and after a node in the document. That node, and only that +// node, will receive the given attributes. +// +// spec::- +// +// Optional information to store with the decoration. It +// is also used when comparing decorators for equality. +Decoration.node = function node (from, to, attrs, spec) { + return new Decoration(from, to, new NodeType(attrs, spec)) +}; + +// :: Object +// The spec provided when creating this decoration. Can be useful +// if you've stored extra information in that object. +prototypeAccessors$1.spec.get = function () { return this.type.spec }; + +Object.defineProperties( Decoration.prototype, prototypeAccessors$1 ); + +// DecorationAttrs:: interface +// A set of attributes to add to a decorated node. Most properties +// simply directly correspond to DOM attributes of the same name, +// which will be set to the property's value. These are exceptions: +// +// class:: ?string +// A CSS class name or a space-separated set of class names to be +// _added_ to the classes that the node already had. +// +// style:: ?string +// A string of CSS to be _added_ to the node's existing `style` property. +// +// nodeName:: ?string +// When non-null, the target node is wrapped in a DOM element of +// this type (and the other attributes are applied to this element). + +var none = [], noSpec = {}; + +// ::- A collection of [decorations](#view.Decoration), organized in +// such a way that the drawing algorithm can efficiently use and +// compare them. This is a persistent data structure—it is not +// modified, updates create a new value. +var DecorationSet = function DecorationSet(local, children) { + this.local = local && local.length ? local : none; + this.children = children && children.length ? children : none; +}; + +// :: (Node, [Decoration]) → DecorationSet +// Create a set of decorations, using the structure of the given +// document. +DecorationSet.create = function create (doc, decorations) { + return decorations.length ? buildTree(decorations, doc, 0, noSpec) : empty +}; + +// :: (?number, ?number, ?(spec: Object) → bool) → [Decoration] +// Find all decorations in this set which touch the given range +// (including decorations that start or end directly at the +// boundaries) and match the given predicate on their spec. When +// `start` and `end` are omitted, all decorations in the set are +// considered. When `predicate` isn't given, all decorations are +// assumed to match. +DecorationSet.prototype.find = function find (start, end, predicate) { + var result = []; + this.findInner(start == null ? 0 : start, end == null ? 1e9 : end, result, 0, predicate); + return result +}; + +DecorationSet.prototype.findInner = function findInner (start, end, result, offset, predicate) { + for (var i = 0; i < this.local.length; i++) { + var span = this.local[i]; + if (span.from <= end && span.to >= start && (!predicate || predicate(span.spec))) + { result.push(span.copy(span.from + offset, span.to + offset)); } + } + for (var i$1 = 0; i$1 < this.children.length; i$1 += 3) { + if (this.children[i$1] < end && this.children[i$1 + 1] > start) { + var childOff = this.children[i$1] + 1; + this.children[i$1 + 2].findInner(start - childOff, end - childOff, result, offset + childOff, predicate); + } + } +}; + +// :: (Mapping, Node, ?Object) → DecorationSet +// Map the set of decorations in response to a change in the +// document. +// +// options::- An optional set of options. +// +// onRemove:: ?(decorationSpec: Object) +// When given, this function will be called for each decoration +// that gets dropped as a result of the mapping, passing the +// spec of that decoration. +DecorationSet.prototype.map = function map (mapping, doc, options) { + if (this == empty || mapping.maps.length == 0) { return this } + return this.mapInner(mapping, doc, 0, 0, options || noSpec) +}; + +DecorationSet.prototype.mapInner = function mapInner (mapping, node, offset, oldOffset, options) { + var newLocal; + for (var i = 0; i < this.local.length; i++) { + var mapped = this.local[i].map(mapping, offset, oldOffset); + if (mapped && mapped.type.valid(node, mapped)) { (newLocal || (newLocal = [])).push(mapped); } + else if (options.onRemove) { options.onRemove(this.local[i].spec); } + } + + if (this.children.length) + { return mapChildren(this.children, newLocal, mapping, node, offset, oldOffset, options) } + else + { return newLocal ? new DecorationSet(newLocal.sort(byPos)) : empty } +}; + +// :: (Node, [Decoration]) → DecorationSet +// Add the given array of decorations to the ones in the set, +// producing a new set. Needs access to the current document to +// create the appropriate tree structure. +DecorationSet.prototype.add = function add (doc, decorations) { + if (!decorations.length) { return this } + if (this == empty) { return DecorationSet.create(doc, decorations) } + return this.addInner(doc, decorations, 0) +}; + +DecorationSet.prototype.addInner = function addInner (doc, decorations, offset) { + var this$1 = this; + + var children, childIndex = 0; + doc.forEach(function (childNode, childOffset) { + var baseOffset = childOffset + offset, found; + if (!(found = takeSpansForNode(decorations, childNode, baseOffset))) { return } + + if (!children) { children = this$1.children.slice(); } + while (childIndex < children.length && children[childIndex] < childOffset) { childIndex += 3; } + if (children[childIndex] == childOffset) + { children[childIndex + 2] = children[childIndex + 2].addInner(childNode, found, baseOffset + 1); } + else + { children.splice(childIndex, 0, childOffset, childOffset + childNode.nodeSize, buildTree(found, childNode, baseOffset + 1, noSpec)); } + childIndex += 3; + }); + + var local = moveSpans(childIndex ? withoutNulls(decorations) : decorations, -offset); + return new DecorationSet(local.length ? this.local.concat(local).sort(byPos) : this.local, + children || this.children) +}; + +// :: ([Decoration]) → DecorationSet +// Create a new set that contains the decorations in this set, minus +// the ones in the given array. +DecorationSet.prototype.remove = function remove (decorations) { + if (decorations.length == 0 || this == empty) { return this } + return this.removeInner(decorations, 0) +}; + +DecorationSet.prototype.removeInner = function removeInner (decorations, offset) { + var children = this.children, local = this.local; + for (var i = 0; i < children.length; i += 3) { + var found = (void 0), from = children[i] + offset, to = children[i + 1] + offset; + for (var j = 0, span = (void 0); j < decorations.length; j++) { if (span = decorations[j]) { + if (span.from > from && span.to < to) { + decorations[j] = null + ;(found || (found = [])).push(span); + } + } } + if (!found) { continue } + if (children == this.children) { children = this.children.slice(); } + var removed = children[i + 2].removeInner(found, from + 1); + if (removed != empty) { + children[i + 2] = removed; + } else { + children.splice(i, 3); + i -= 3; + } + } + if (local.length) { for (var i$1 = 0, span$1 = (void 0); i$1 < decorations.length; i$1++) { if (span$1 = decorations[i$1]) { + for (var j$1 = 0; j$1 < local.length; j$1++) { if (local[j$1].type.eq(span$1.type)) { + if (local == this.local) { local = this.local.slice(); } + local.splice(j$1--, 1); + } } + } } } + if (children == this.children && local == this.local) { return this } + return local.length || children.length ? new DecorationSet(local, children) : empty +}; + +DecorationSet.prototype.forChild = function forChild (offset, node) { + if (this == empty) { return this } + if (node.isLeaf) { return DecorationSet.empty } + + var child, local; + for (var i = 0; i < this.children.length; i += 3) { if (this.children[i] >= offset) { + if (this.children[i] == offset) { child = this.children[i + 2]; } + break + } } + var start = offset + 1, end = start + node.content.size; + for (var i$1 = 0; i$1 < this.local.length; i$1++) { + var dec = this.local[i$1]; + if (dec.from < end && dec.to > start && (dec.type instanceof InlineType)) { + var from = Math.max(start, dec.from) - start, to = Math.min(end, dec.to) - start; + if (from < to) { (local || (local = [])).push(dec.copy(from, to)); } + } + } + if (local) { + var localSet = new DecorationSet(local.sort(byPos)); + return child ? new DecorationGroup([localSet, child]) : localSet + } + return child || empty +}; + +DecorationSet.prototype.eq = function eq (other) { + if (this == other) { return true } + if (!(other instanceof DecorationSet) || + this.local.length != other.local.length || + this.children.length != other.children.length) { return false } + for (var i = 0; i < this.local.length; i++) + { if (!this.local[i].eq(other.local[i])) { return false } } + for (var i$1 = 0; i$1 < this.children.length; i$1 += 3) + { if (this.children[i$1] != other.children[i$1] || + this.children[i$1 + 1] != other.children[i$1 + 1] || + !this.children[i$1 + 2].eq(other.children[i$1 + 2])) { return false } } + return true +}; + +DecorationSet.prototype.locals = function locals (node) { + return removeOverlap(this.localsInner(node)) +}; + +DecorationSet.prototype.localsInner = function localsInner (node) { + if (this == empty) { return none } + if (node.inlineContent || !this.local.some(InlineType.is)) { return this.local } + var result = []; + for (var i = 0; i < this.local.length; i++) { + if (!(this.local[i].type instanceof InlineType)) + { result.push(this.local[i]); } + } + return result +}; + +var empty = new DecorationSet(); + +// :: DecorationSet +// The empty set of decorations. +DecorationSet.empty = empty; + +DecorationSet.removeOverlap = removeOverlap; + +// :- An abstraction that allows the code dealing with decorations to +// treat multiple DecorationSet objects as if it were a single object +// with (a subset of) the same interface. +var DecorationGroup = function DecorationGroup(members) { + this.members = members; +}; + +DecorationGroup.prototype.forChild = function forChild (offset, child) { + if (child.isLeaf) { return DecorationSet.empty } + var found = []; + for (var i = 0; i < this.members.length; i++) { + var result = this.members[i].forChild(offset, child); + if (result == empty) { continue } + if (result instanceof DecorationGroup) { found = found.concat(result.members); } + else { found.push(result); } + } + return DecorationGroup.from(found) +}; + +DecorationGroup.prototype.eq = function eq (other) { + if (!(other instanceof DecorationGroup) || + other.members.length != this.members.length) { return false } + for (var i = 0; i < this.members.length; i++) + { if (!this.members[i].eq(other.members[i])) { return false } } + return true +}; + +DecorationGroup.prototype.locals = function locals (node) { + var result, sorted = true; + for (var i = 0; i < this.members.length; i++) { + var locals = this.members[i].localsInner(node); + if (!locals.length) { continue } + if (!result) { + result = locals; + } else { + if (sorted) { + result = result.slice(); + sorted = false; + } + for (var j = 0; j < locals.length; j++) { result.push(locals[j]); } + } + } + return result ? removeOverlap(sorted ? result : result.sort(byPos)) : none +}; + +// : ([DecorationSet]) → union +// Create a group for the given array of decoration sets, or return +// a single set when possible. +DecorationGroup.from = function from (members) { + switch (members.length) { + case 0: return empty + case 1: return members[0] + default: return new DecorationGroup(members) + } +}; + +function mapChildren(oldChildren, newLocal, mapping, node, offset, oldOffset, options) { + var children = oldChildren.slice(); + + // Mark the children that are directly touched by changes, and + // move those that are after the changes. + var shift = function (oldStart, oldEnd, newStart, newEnd) { + for (var i = 0; i < children.length; i += 3) { + var end = children[i + 1], dSize = (void 0); + if (end == -1 || oldStart > end + oldOffset) { continue } + if (oldEnd >= children[i] + oldOffset) { + children[i + 1] = -1; + } else if (dSize = (newEnd - newStart) - (oldEnd - oldStart) + (oldOffset - offset)) { + children[i] += dSize; + children[i + 1] += dSize; + } + } + }; + for (var i = 0; i < mapping.maps.length; i++) { mapping.maps[i].forEach(shift); } + + // Find the child nodes that still correspond to a single node, + // recursively call mapInner on them and update their positions. + var mustRebuild = false; + for (var i$1 = 0; i$1 < children.length; i$1 += 3) { if (children[i$1 + 1] == -1) { // Touched nodes + var from = mapping.map(children[i$1] + oldOffset), fromLocal = from - offset; + if (fromLocal < 0 || fromLocal >= node.content.size) { + mustRebuild = true; + continue + } + // Must read oldChildren because children was tagged with -1 + var to = mapping.map(oldChildren[i$1 + 1] + oldOffset, -1), toLocal = to - offset; + var ref = node.content.findIndex(fromLocal); + var index = ref.index; + var childOffset = ref.offset; + var childNode = node.maybeChild(index); + if (childNode && childOffset == fromLocal && childOffset + childNode.nodeSize == toLocal) { + var mapped = children[i$1 + 2].mapInner(mapping, childNode, from + 1, children[i$1] + oldOffset + 1, options); + if (mapped != empty) { + children[i$1] = fromLocal; + children[i$1 + 1] = toLocal; + children[i$1 + 2] = mapped; + } else { + children[i$1 + 1] = -2; + mustRebuild = true; + } + } else { + mustRebuild = true; + } + } } + + // Remaining children must be collected and rebuilt into the appropriate structure + if (mustRebuild) { + var decorations = mapAndGatherRemainingDecorations(children, oldChildren, newLocal || [], mapping, + offset, oldOffset, options); + var built = buildTree(decorations, node, 0, options); + newLocal = built.local; + for (var i$2 = 0; i$2 < children.length; i$2 += 3) { if (children[i$2 + 1] < 0) { + children.splice(i$2, 3); + i$2 -= 3; + } } + for (var i$3 = 0, j = 0; i$3 < built.children.length; i$3 += 3) { + var from$1 = built.children[i$3]; + while (j < children.length && children[j] < from$1) { j += 3; } + children.splice(j, 0, built.children[i$3], built.children[i$3 + 1], built.children[i$3 + 2]); + } + } + + return new DecorationSet(newLocal && newLocal.sort(byPos), children) +} + +function moveSpans(spans, offset) { + if (!offset || !spans.length) { return spans } + var result = []; + for (var i = 0; i < spans.length; i++) { + var span = spans[i]; + result.push(new Decoration(span.from + offset, span.to + offset, span.type)); + } + return result +} + +function mapAndGatherRemainingDecorations(children, oldChildren, decorations, mapping, offset, oldOffset, options) { + // Gather all decorations from the remaining marked children + function gather(set, oldOffset) { + for (var i = 0; i < set.local.length; i++) { + var mapped = set.local[i].map(mapping, offset, oldOffset); + if (mapped) { decorations.push(mapped); } + else if (options.onRemove) { options.onRemove(set.local[i].spec); } + } + for (var i$1 = 0; i$1 < set.children.length; i$1 += 3) + { gather(set.children[i$1 + 2], set.children[i$1] + oldOffset + 1); } + } + for (var i = 0; i < children.length; i += 3) { if (children[i + 1] == -1) + { gather(children[i + 2], oldChildren[i] + oldOffset + 1); } } + + return decorations +} + +function takeSpansForNode(spans, node, offset) { + if (node.isLeaf) { return null } + var end = offset + node.nodeSize, found = null; + for (var i = 0, span = (void 0); i < spans.length; i++) { + if ((span = spans[i]) && span.from > offset && span.to < end) { +(found || (found = [])).push(span); + spans[i] = null; + } + } + return found +} + +function withoutNulls(array) { + var result = []; + for (var i = 0; i < array.length; i++) + { if (array[i] != null) { result.push(array[i]); } } + return result +} + +// : ([Decoration], Node, number) → DecorationSet +// Build up a tree that corresponds to a set of decorations. `offset` +// is a base offset that should be subtractet from the `from` and `to` +// positions in the spans (so that we don't have to allocate new spans +// for recursive calls). +function buildTree(spans, node, offset, options) { + var children = [], hasNulls = false; + node.forEach(function (childNode, localStart) { + var found = takeSpansForNode(spans, childNode, localStart + offset); + if (found) { + hasNulls = true; + var subtree = buildTree(found, childNode, offset + localStart + 1, options); + if (subtree != empty) + { children.push(localStart, localStart + childNode.nodeSize, subtree); } + } + }); + var locals = moveSpans(hasNulls ? withoutNulls(spans) : spans, -offset).sort(byPos); + for (var i = 0; i < locals.length; i++) { if (!locals[i].type.valid(node, locals[i])) { + if (options.onRemove) { options.onRemove(locals[i].spec); } + locals.splice(i--, 1); + } } + return locals.length || children.length ? new DecorationSet(locals, children) : empty +} + +// : (Decoration, Decoration) → number +// Used to sort decorations so that ones with a low start position +// come first, and within a set with the same start position, those +// with an smaller end position come first. +function byPos(a, b) { + return a.from - b.from || a.to - b.to +} + +// : ([Decoration]) → [Decoration] +// Scan a sorted array of decorations for partially overlapping spans, +// and split those so that only fully overlapping spans are left (to +// make subsequent rendering easier). Will return the input array if +// no partially overlapping spans are found (the common case). +function removeOverlap(spans) { + var working = spans; + for (var i = 0; i < working.length - 1; i++) { + var span = working[i]; + if (span.from != span.to) { for (var j = i + 1; j < working.length; j++) { + var next = working[j]; + if (next.from == span.from) { + if (next.to != span.to) { + if (working == spans) { working = spans.slice(); } + // Followed by a partially overlapping larger span. Split that + // span. + working[j] = next.copy(next.from, span.to); + insertAhead(working, j + 1, next.copy(span.to, next.to)); + } + continue + } else { + if (next.from < span.to) { + if (working == spans) { working = spans.slice(); } + // The end of this one overlaps with a subsequent span. Split + // this one. + working[i] = span.copy(span.from, next.from); + insertAhead(working, j, span.copy(next.from, span.to)); + } + break + } + } } + } + return working +} + +function insertAhead(array, i, deco) { + while (i < array.length && byPos(deco, array[i]) > 0) { i++; } + array.splice(i, 0, deco); +} + +// : (EditorView) → union +// Get the decorations associated with the current props of a view. +function viewDecorations(view) { + var found = []; + view.someProp("decorations", function (f) { + var result = f(view.state); + if (result && result != empty) { found.push(result); } + }); + if (view.cursorWrapper) + { found.push(DecorationSet.create(view.state.doc, [view.cursorWrapper.deco])); } + return DecorationGroup.from(found) +} + +// ::- An editor view manages the DOM structure that represents an +// editable document. Its state and behavior are determined by its +// [props](#view.DirectEditorProps). +var EditorView = function EditorView(place, props) { + this._props = props; + // :: EditorState + // The view's current [state](#state.EditorState). + this.state = props.state; + + this.dispatch = this.dispatch.bind(this); + + this._root = null; + this.focused = false; + + // :: dom.Element + // An editable DOM node containing the document. (You probably + // should not directly interfere with its content.) + this.dom = (place && place.mount) || document.createElement("div"); + if (place) { + if (place.appendChild) { place.appendChild(this.dom); } + else if (place.apply) { place(this.dom); } + else if (place.mount) { this.mounted = true; } + } + + // :: bool + // Indicates whether the editor is currently [editable](#view.EditorProps.editable). + this.editable = getEditable(this); + this.markCursor = null; + this.cursorWrapper = null; + updateCursorWrapper(this); + this.nodeViews = buildNodeViews(this); + this.docView = docViewDesc(this.state.doc, computeDocDeco(this), viewDecorations(this), this.dom, this); + + this.lastSelectedViewDesc = null; + // :: ?{slice: Slice, move: bool} + // When editor content is being dragged, this object contains + // information about the dragged slice and whether it is being + // copied or moved. At any other time, it is null. + this.dragging = null; + + initInput(this); + + this.pluginViews = []; + this.updatePluginViews(); +}; + +var prototypeAccessors$2 = { props: { configurable: true },root: { configurable: true } }; + +// composing:: boolean +// Holds `true` when a +// [composition](https://developer.mozilla.org/en-US/docs/Mozilla/IME_handling_guide) +// is active. + +// :: DirectEditorProps +// The view's current [props](#view.EditorProps). +prototypeAccessors$2.props.get = function () { + if (this._props.state != this.state) { + var prev = this._props; + this._props = {}; + for (var name in prev) { this._props[name] = prev[name]; } + this._props.state = this.state; + } + return this._props +}; + +// :: (DirectEditorProps) +// Update the view's props. Will immediately cause an update to +// the DOM. +EditorView.prototype.update = function update (props) { + if (props.handleDOMEvents != this._props.handleDOMEvents) { ensureListeners(this); } + this._props = props; + this.updateStateInner(props.state, true); +}; + +// :: (DirectEditorProps) +// Update the view by updating existing props object with the object +// given as argument. Equivalent to `view.update(Object.assign({}, +// view.props, props))`. +EditorView.prototype.setProps = function setProps (props) { + var updated = {}; + for (var name in this._props) { updated[name] = this._props[name]; } + updated.state = this.state; + for (var name$1 in props) { updated[name$1] = props[name$1]; } + this.update(updated); +}; + +// :: (EditorState) +// Update the editor's `state` prop, without touching any of the +// other props. +EditorView.prototype.updateState = function updateState (state) { + this.updateStateInner(state, this.state.plugins != state.plugins); +}; + +EditorView.prototype.updateStateInner = function updateStateInner (state, reconfigured) { + var this$1 = this; + + var prev = this.state, redraw = false; + this.state = state; + if (reconfigured) { + var nodeViews = buildNodeViews(this); + if (changedNodeViews(nodeViews, this.nodeViews)) { + this.nodeViews = nodeViews; + redraw = true; + } + ensureListeners(this); + } + + this.editable = getEditable(this); + updateCursorWrapper(this); + var innerDeco = viewDecorations(this), outerDeco = computeDocDeco(this); + + var scroll = reconfigured ? "reset" + : state.scrollToSelection > prev.scrollToSelection ? "to selection" : "preserve"; + var updateDoc = redraw || !this.docView.matchesNode(state.doc, outerDeco, innerDeco); + var updateSel = updateDoc || !state.selection.eq(prev.selection); + var oldScrollPos = scroll == "preserve" && updateSel && this.dom.style.overflowAnchor == null && storeScrollPos(this); + + if (updateSel) { + this.domObserver.stop(); + // Work around an issue in Chrome, IE, and Edge where changing + // the DOM around an active selection puts it into a broken + // state where the thing the user sees differs from the + // selection reported by the Selection object (#710, #973, + // #1011, #1013). + var forceSelUpdate = updateDoc && (result.ie || result.chrome) && + !prev.selection.empty && !state.selection.empty && selectionContextChanged(prev.selection, state.selection); + if (updateDoc) { + if (redraw || !this.docView.update(state.doc, outerDeco, innerDeco, this)) { + this.docView.destroy(); + this.docView = docViewDesc(state.doc, outerDeco, innerDeco, this.dom, this); + } + } + // Work around for an issue where an update arriving right between + // a DOM selection change and the "selectionchange" event for it + // can cause a spurious DOM selection update, disrupting mouse + // drag selection. + if (forceSelUpdate || + !(this.mouseDown && this.domObserver.currentSelection.eq(this.root.getSelection()) && anchorInRightPlace(this))) { + selectionToDOM(this, forceSelUpdate); + } else { + syncNodeSelection(this, state.selection); + this.domObserver.setCurSelection(); + } + this.domObserver.start(); + } + + this.updatePluginViews(prev); + + if (scroll == "reset") { + this.dom.scrollTop = 0; + } else if (scroll == "to selection") { + var startDOM = this.root.getSelection().focusNode; + if (this.someProp("handleScrollToSelection", function (f) { return f(this$1); })) + ; // Handled + else if (state.selection instanceof NodeSelection) + { scrollRectIntoView(this, this.docView.domAfterPos(state.selection.from).getBoundingClientRect(), startDOM); } + else + { scrollRectIntoView(this, this.coordsAtPos(state.selection.head), startDOM); } + } else if (oldScrollPos) { + resetScrollPos(oldScrollPos); + } +}; + +EditorView.prototype.destroyPluginViews = function destroyPluginViews () { + var view; + while (view = this.pluginViews.pop()) { if (view.destroy) { view.destroy(); } } +}; + +EditorView.prototype.updatePluginViews = function updatePluginViews (prevState) { + if (!prevState || prevState.plugins != this.state.plugins) { + this.destroyPluginViews(); + for (var i = 0; i < this.state.plugins.length; i++) { + var plugin = this.state.plugins[i]; + if (plugin.spec.view) { this.pluginViews.push(plugin.spec.view(this)); } + } + } else { + for (var i$1 = 0; i$1 < this.pluginViews.length; i$1++) { + var pluginView = this.pluginViews[i$1]; + if (pluginView.update) { pluginView.update(this, prevState); } + } + } +}; + +// :: (string, ?(prop: *) → *) → * +// Goes over the values of a prop, first those provided directly, +// then those from plugins (in order), and calls `f` every time a +// non-undefined value is found. When `f` returns a truthy value, +// that is immediately returned. When `f` isn't provided, it is +// treated as the identity function (the prop value is returned +// directly). +EditorView.prototype.someProp = function someProp (propName, f) { + var prop = this._props && this._props[propName], value; + if (prop != null && (value = f ? f(prop) : prop)) { return value } + var plugins = this.state.plugins; + if (plugins) { for (var i = 0; i < plugins.length; i++) { + var prop$1 = plugins[i].props[propName]; + if (prop$1 != null && (value = f ? f(prop$1) : prop$1)) { return value } + } } +}; + +// :: () → bool +// Query whether the view has focus. +EditorView.prototype.hasFocus = function hasFocus () { + return this.root.activeElement == this.dom +}; + +// :: () +// Focus the editor. +EditorView.prototype.focus = function focus () { + this.domObserver.stop(); + if (this.editable) { focusPreventScroll(this.dom); } + selectionToDOM(this); + this.domObserver.start(); +}; + +// :: union +// Get the document root in which the editor exists. This will +// usually be the top-level `document`, but might be a [shadow +// DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Shadow_DOM) +// root if the editor is inside one. +prototypeAccessors$2.root.get = function () { + var cached = this._root; + if (cached == null) { for (var search = this.dom.parentNode; search; search = search.parentNode) { + if (search.nodeType == 9 || (search.nodeType == 11 && search.host)) { + if (!search.getSelection) { Object.getPrototypeOf(search).getSelection = function () { return document.getSelection(); }; } + return this._root = search + } + } } + return cached || document +}; + +// :: ({left: number, top: number}) → ?{pos: number, inside: number} +// Given a pair of viewport coordinates, return the document +// position that corresponds to them. May return null if the given +// coordinates aren't inside of the editor. When an object is +// returned, its `pos` property is the position nearest to the +// coordinates, and its `inside` property holds the position of the +// inner node that the position falls inside of, or -1 if it is at +// the top level, not in any node. +EditorView.prototype.posAtCoords = function posAtCoords$1 (coords) { + return posAtCoords(this, coords) +}; + +// :: (number) → {left: number, right: number, top: number, bottom: number} +// Returns the viewport rectangle at a given document position. `left` +// and `right` will be the same number, as this returns a flat +// cursor-ish rectangle. +EditorView.prototype.coordsAtPos = function coordsAtPos$1 (pos) { + return coordsAtPos(this, pos) +}; + +// :: (number) → {node: dom.Node, offset: number} +// Find the DOM position that corresponds to the given document +// position. Note that you should **not** mutate the editor's +// internal DOM, only inspect it (and even that is usually not +// necessary). +EditorView.prototype.domAtPos = function domAtPos (pos) { + return this.docView.domFromPos(pos) +}; + +// :: (number) → ?dom.Node +// Find the DOM node that represents the document node after the +// given position. May return `null` when the position doesn't point +// in front of a node or if the node is inside an opaque node view. +// +// This is intended to be able to call things like +// `getBoundingClientRect` on that DOM node. Do **not** mutate the +// editor DOM directly, or add styling this way, since that will be +// immediately overriden by the editor as it redraws the node. +EditorView.prototype.nodeDOM = function nodeDOM (pos) { + var desc = this.docView.descAt(pos); + return desc ? desc.nodeDOM : null +}; + +// :: (dom.Node, number, ?number) → number +// Find the document position that corresponds to a given DOM +// position. (Whenever possible, it is preferable to inspect the +// document structure directly, rather than poking around in the +// DOM, but sometimes—for example when interpreting an event +// target—you don't have a choice.) +// +// The `bias` parameter can be used to influence which side of a DOM +// node to use when the position is inside a leaf node. +EditorView.prototype.posAtDOM = function posAtDOM (node, offset, bias) { + if ( bias === void 0 ) bias = -1; + + var pos = this.docView.posFromDOM(node, offset, bias); + if (pos == null) { throw new RangeError("DOM position not inside the editor") } + return pos +}; + +// :: (union<"up", "down", "left", "right", "forward", "backward">, ?EditorState) → bool +// Find out whether the selection is at the end of a textblock when +// moving in a given direction. When, for example, given `"left"`, +// it will return true if moving left from the current cursor +// position would leave that position's parent textblock. Will apply +// to the view's current state by default, but it is possible to +// pass a different state. +EditorView.prototype.endOfTextblock = function endOfTextblock$1 (dir, state) { + return endOfTextblock(this, state || this.state, dir) +}; + +// :: () +// Removes the editor from the DOM and destroys all [node +// views](#view.NodeView). +EditorView.prototype.destroy = function destroy () { + if (!this.docView) { return } + destroyInput(this); + this.destroyPluginViews(); + if (this.mounted) { + this.docView.update(this.state.doc, [], viewDecorations(this), this); + this.dom.textContent = ""; + } else if (this.dom.parentNode) { + this.dom.parentNode.removeChild(this.dom); + } + this.docView.destroy(); + this.docView = null; +}; + +// Used for testing. +EditorView.prototype.dispatchEvent = function dispatchEvent$1 (event) { + return dispatchEvent(this, event) +}; + +// :: (Transaction) +// Dispatch a transaction. Will call +// [`dispatchTransaction`](#view.DirectEditorProps.dispatchTransaction) +// when given, and otherwise defaults to applying the transaction to +// the current state and calling +// [`updateState`](#view.EditorView.updateState) with the result. +// This method is bound to the view instance, so that it can be +// easily passed around. +EditorView.prototype.dispatch = function dispatch (tr) { + var dispatchTransaction = this._props.dispatchTransaction; + if (dispatchTransaction) { dispatchTransaction.call(this, tr); } + else { this.updateState(this.state.apply(tr)); } +}; + +Object.defineProperties( EditorView.prototype, prototypeAccessors$2 ); + +function computeDocDeco(view) { + var attrs = Object.create(null); + attrs.class = "ProseMirror"; + attrs.contenteditable = String(view.editable); + + view.someProp("attributes", function (value) { + if (typeof value == "function") { value = value(view.state); } + if (value) { for (var attr in value) { + if (attr == "class") + { attrs.class += " " + value[attr]; } + else if (!attrs[attr] && attr != "contenteditable" && attr != "nodeName") + { attrs[attr] = String(value[attr]); } + } } + }); + + return [Decoration.node(0, view.state.doc.content.size, attrs)] +} + +function updateCursorWrapper(view) { + var ref = view.state.selection; + var $head = ref.$head; + var $anchor = ref.$anchor; + var visible = ref.visible; + if (view.markCursor) { + var dom = document.createElement("img"); + dom.setAttribute("mark-placeholder", "true"); + view.cursorWrapper = {dom: dom, deco: Decoration.widget($head.pos, dom, {raw: true, marks: view.markCursor})}; + } else if (visible || $head.pos != $anchor.pos) { + view.cursorWrapper = null; + } else { + var dom$1; + if (!view.cursorWrapper || view.cursorWrapper.dom.childNodes.length) { + dom$1 = document.createElement("div"); + dom$1.style.position = "absolute"; + dom$1.style.left = "-100000px"; + } else if (view.cursorWrapper.deco.pos != $head.pos) { + dom$1 = view.cursorWrapper.dom; + } + if (dom$1) + { view.cursorWrapper = {dom: dom$1, deco: Decoration.widget($head.pos, dom$1, {raw: true})}; } + } +} + +function getEditable(view) { + return !view.someProp("editable", function (value) { return value(view.state) === false; }) +} + +function selectionContextChanged(sel1, sel2) { + var depth = Math.min(sel1.$anchor.sharedDepth(sel1.head), sel2.$anchor.sharedDepth(sel2.head)); + return sel1.$anchor.node(depth) != sel2.$anchor.node(depth) +} + +function buildNodeViews(view) { + var result = {}; + view.someProp("nodeViews", function (obj) { + for (var prop in obj) { if (!Object.prototype.hasOwnProperty.call(result, prop)) + { result[prop] = obj[prop]; } } + }); + return result +} + +function changedNodeViews(a, b) { + var nA = 0, nB = 0; + for (var prop in a) { + if (a[prop] != b[prop]) { return true } + nA++; + } + for (var _ in b) { nB++; } + return nA != nB +} + +// EditorProps:: interface +// +// Props are configuration values that can be passed to an editor view +// or included in a plugin. This interface lists the supported props. +// +// The various event-handling functions may all return `true` to +// indicate that they handled the given event. The view will then take +// care to call `preventDefault` on the event, except with +// `handleDOMEvents`, where the handler itself is responsible for that. +// +// How a prop is resolved depends on the prop. Handler functions are +// called one at a time, starting with the base props and then +// searching through the plugins (in order of appearance) until one of +// them returns true. For some props, the first plugin that yields a +// value gets precedence. +// +// handleDOMEvents:: ?Object<(view: EditorView, event: dom.Event) → bool> +// Can be an object mapping DOM event type names to functions that +// handle them. Such functions will be called before any handling +// ProseMirror does of events fired on the editable DOM element. +// Contrary to the other event handling props, when returning true +// from such a function, you are responsible for calling +// `preventDefault` yourself (or not, if you want to allow the +// default behavior). +// +// handleKeyDown:: ?(view: EditorView, event: dom.KeyboardEvent) → bool +// Called when the editor receives a `keydown` event. +// +// handleKeyPress:: ?(view: EditorView, event: dom.KeyboardEvent) → bool +// Handler for `keypress` events. +// +// handleTextInput:: ?(view: EditorView, from: number, to: number, text: string) → bool +// Whenever the user directly input text, this handler is called +// before the input is applied. If it returns `true`, the default +// behavior of actually inserting the text is suppressed. +// +// handleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool +// Called for each node around a click, from the inside out. The +// `direct` flag will be true for the inner node. +// +// handleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool +// Called when the editor is clicked, after `handleClickOn` handlers +// have been called. +// +// handleDoubleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool +// Called for each node around a double click. +// +// handleDoubleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool +// Called when the editor is double-clicked, after `handleDoubleClickOn`. +// +// handleTripleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool +// Called for each node around a triple click. +// +// handleTripleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool +// Called when the editor is triple-clicked, after `handleTripleClickOn`. +// +// handlePaste:: ?(view: EditorView, event: dom.Event, slice: Slice) → bool +// Can be used to override the behavior of pasting. `slice` is the +// pasted content parsed by the editor, but you can directly access +// the event to get at the raw content. +// +// handleDrop:: ?(view: EditorView, event: dom.Event, slice: Slice, moved: bool) → bool +// Called when something is dropped on the editor. `moved` will be +// true if this drop moves from the current selection (which should +// thus be deleted). +// +// handleScrollToSelection:: ?(view: EditorView) → bool +// Called when the view, after updating its state, tries to scroll +// the selection into view. A handler function may return false to +// indicate that it did not handle the scrolling and further +// handlers or the default behavior should be tried. +// +// createSelectionBetween:: ?(view: EditorView, anchor: ResolvedPos, head: ResolvedPos) → ?Selection +// Can be used to override the way a selection is created when +// reading a DOM selection between the given anchor and head. +// +// domParser:: ?DOMParser +// The [parser](#model.DOMParser) to use when reading editor changes +// from the DOM. Defaults to calling +// [`DOMParser.fromSchema`](#model.DOMParser^fromSchema) on the +// editor's schema. +// +// transformPastedHTML:: ?(html: string) → string +// Can be used to transform pasted HTML text, _before_ it is parsed, +// for example to clean it up. +// +// clipboardParser:: ?DOMParser +// The [parser](#model.DOMParser) to use when reading content from +// the clipboard. When not given, the value of the +// [`domParser`](#view.EditorProps.domParser) prop is used. +// +// transformPastedText:: ?(text: string) → string +// Transform pasted plain text. +// +// clipboardTextParser:: ?(text: string, $context: ResolvedPos) → Slice +// A function to parse text from the clipboard into a document +// slice. Called after +// [`transformPastedText`](#view.EditorProps.transformPastedText). +// The default behavior is to split the text into lines, wrap them +// in `

    ` tags, and call +// [`clipboardParser`](#view.EditorProps.clipboardParser) on it. +// +// transformPasted:: ?(Slice) → Slice +// Can be used to transform pasted content before it is applied to +// the document. +// +// nodeViews:: ?Object<(node: Node, view: EditorView, getPos: () → number, decorations: [Decoration]) → NodeView> +// Allows you to pass custom rendering and behavior logic for nodes +// and marks. Should map node and mark names to constructor +// functions that produce a [`NodeView`](#view.NodeView) object +// implementing the node's display behavior. For nodes, the third +// argument `getPos` is a function that can be called to get the +// node's current position, which can be useful when creating +// transactions to update it. For marks, the third argument is a +// boolean that indicates whether the mark's content is inline. +// +// `decorations` is an array of node or inline decorations that are +// active around the node. They are automatically drawn in the +// normal way, and you will usually just want to ignore this, but +// they can also be used as a way to provide context information to +// the node view without adding it to the document itself. +// +// clipboardSerializer:: ?DOMSerializer +// The DOM serializer to use when putting content onto the +// clipboard. If not given, the result of +// [`DOMSerializer.fromSchema`](#model.DOMSerializer^fromSchema) +// will be used. +// +// clipboardTextSerializer:: ?(Slice) → string +// A function that will be called to get the text for the current +// selection when copying text to the clipboard. By default, the +// editor will use [`textBetween`](#model.Node.textBetween) on the +// selected range. +// +// decorations:: ?(state: EditorState) → ?DecorationSet +// A set of [document decorations](#view.Decoration) to show in the +// view. +// +// editable:: ?(state: EditorState) → bool +// When this returns false, the content of the view is not directly +// editable. +// +// attributes:: ?union, (EditorState) → ?Object> +// Control the DOM attributes of the editable element. May be either +// an object or a function going from an editor state to an object. +// By default, the element will get a class `"ProseMirror"`, and +// will have its `contentEditable` attribute determined by the +// [`editable` prop](#view.EditorProps.editable). Additional classes +// provided here will be added to the class. For other attributes, +// the value provided first (as in +// [`someProp`](#view.EditorView.someProp)) will be used. +// +// scrollThreshold:: ?union +// Determines the distance (in pixels) between the cursor and the +// end of the visible viewport at which point, when scrolling the +// cursor into view, scrolling takes place. Defaults to 0. +// +// scrollMargin:: ?union +// Determines the extra space (in pixels) that is left above or +// below the cursor when it is scrolled into view. Defaults to 5. + +// DirectEditorProps:: interface extends EditorProps +// +// The props object given directly to the editor view supports two +// fields that can't be used in plugins: +// +// state:: EditorState +// The current state of the editor. +// +// dispatchTransaction:: ?(tr: Transaction) +// The callback over which to send transactions (state updates) +// produced by the view. If you specify this, you probably want to +// make sure this ends up calling the view's +// [`updateState`](#view.EditorView.updateState) method with a new +// state that has the transaction +// [applied](#state.EditorState.apply). The callback will be bound to have +// the view instance as its `this` binding. + +export { Decoration, DecorationSet, EditorView, endComposition as __endComposition, parseFromClipboard as __parseFromClipboard, serializeForClipboard as __serializeForClipboard }; +//# sourceMappingURL=index.es.js.map diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/dist/index.es.js.map b/packages/tiptap-extensions/node_modules/prosemirror-view/dist/index.es.js.map new file mode 100644 index 0000000000..1d34e1aed9 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/dist/index.es.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.es.js","sources":["../src/browser.js","../src/dom.js","../src/domcoords.js","../src/viewdesc.js","../src/capturekeys.js","../src/selection.js","../src/domchange.js","../src/clipboard.js","../src/domobserver.js","../src/input.js","../src/decoration.js","../src/index.js"],"sourcesContent":["const result = {}\nexport default result\n\nif (typeof navigator != \"undefined\" && typeof document != \"undefined\") {\n const ie_edge = /Edge\\/(\\d+)/.exec(navigator.userAgent)\n const ie_upto10 = /MSIE \\d/.test(navigator.userAgent)\n const ie_11up = /Trident\\/(?:[7-9]|\\d{2,})\\..*rv:(\\d+)/.exec(navigator.userAgent)\n\n result.mac = /Mac/.test(navigator.platform)\n let ie = result.ie = !!(ie_upto10 || ie_11up || ie_edge)\n result.ie_version = ie_upto10 ? document.documentMode || 6 : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : null\n result.gecko = !ie && /gecko\\/(\\d+)/i.test(navigator.userAgent)\n result.gecko_version = result.gecko && +(/Firefox\\/(\\d+)/.exec(navigator.userAgent) || [0, 0])[1]\n let chrome = !ie && /Chrome\\/(\\d+)/.exec(navigator.userAgent)\n result.chrome = !!chrome\n result.chrome_version = chrome && +chrome[1]\n result.ios = !ie && /AppleWebKit/.test(navigator.userAgent) && /Mobile\\/\\w+/.test(navigator.userAgent)\n result.android = /Android \\d/.test(navigator.userAgent)\n result.webkit = !ie && 'WebkitAppearance' in document.documentElement.style\n result.safari = /Apple Computer/.test(navigator.vendor)\n result.webkit_version = result.webkit && +(/\\bAppleWebKit\\/(\\d+)/.exec(navigator.userAgent) || [0, 0])[1]\n}\n","import browser from \"./browser\"\n\nexport const domIndex = function(node) {\n for (var index = 0;; index++) {\n node = node.previousSibling\n if (!node) return index\n }\n}\n\nexport const parentNode = function(node) {\n let parent = node.parentNode\n return parent && parent.nodeType == 11 ? parent.host : parent\n}\n\nexport const textRange = function(node, from, to) {\n let range = document.createRange()\n range.setEnd(node, to == null ? node.nodeValue.length : to)\n range.setStart(node, from || 0)\n return range\n}\n\n// Scans forward and backward through DOM positions equivalent to the\n// given one to see if the two are in the same place (i.e. after a\n// text node vs at the end of that text node)\nexport const isEquivalentPosition = function(node, off, targetNode, targetOff) {\n return targetNode && (scanFor(node, off, targetNode, targetOff, -1) ||\n scanFor(node, off, targetNode, targetOff, 1))\n}\n\nconst atomElements = /^(img|br|input|textarea|hr)$/i\n\nfunction scanFor(node, off, targetNode, targetOff, dir) {\n for (;;) {\n if (node == targetNode && off == targetOff) return true\n if (off == (dir < 0 ? 0 : nodeSize(node))) {\n let parent = node.parentNode\n if (parent.nodeType != 1 || hasBlockDesc(node) || atomElements.test(node.nodeName) || node.contentEditable == \"false\")\n return false\n off = domIndex(node) + (dir < 0 ? 0 : 1)\n node = parent\n } else if (node.nodeType == 1) {\n node = node.childNodes[off + (dir < 0 ? -1 : 0)]\n off = dir < 0 ? nodeSize(node) : 0\n } else {\n return false\n }\n }\n}\n\nexport function nodeSize(node) {\n return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length\n}\n\nfunction hasBlockDesc(dom) {\n let desc\n for (let cur = dom; cur; cur = cur.parentNode) if (desc = cur.pmViewDesc) break\n return desc && desc.node && desc.node.isBlock && (desc.dom == dom || desc.contentDOM == dom)\n}\n\n// Work around Chrome issue https://bugs.chromium.org/p/chromium/issues/detail?id=447523\n// (isCollapsed inappropriately returns true in shadow dom)\nexport const selectionCollapsed = function(domSel) {\n let collapsed = domSel.isCollapsed\n if (collapsed && browser.chrome && domSel.rangeCount && !domSel.getRangeAt(0).collapsed)\n collapsed = false\n return collapsed\n}\n\nexport function keyEvent(keyCode, key) {\n let event = document.createEvent(\"Event\")\n event.initEvent(\"keydown\", true, true)\n event.keyCode = keyCode\n event.key = event.code = key\n return event\n}\n","import {nodeSize, textRange, parentNode} from \"./dom\"\nimport browser from \"./browser\"\n\nfunction windowRect(win) {\n return {left: 0, right: win.innerWidth,\n top: 0, bottom: win.innerHeight}\n}\n\nfunction getSide(value, side) {\n return typeof value == \"number\" ? value : value[side]\n}\n\nexport function scrollRectIntoView(view, rect, startDOM) {\n let scrollThreshold = view.someProp(\"scrollThreshold\") || 0, scrollMargin = view.someProp(\"scrollMargin\") || 5\n let doc = view.dom.ownerDocument, win = doc.defaultView\n for (let parent = startDOM || view.dom;; parent = parentNode(parent)) {\n if (!parent) break\n if (parent.nodeType != 1) continue\n let atTop = parent == doc.body || parent.nodeType != 1\n let bounding = atTop ? windowRect(win) : parent.getBoundingClientRect()\n let moveX = 0, moveY = 0\n if (rect.top < bounding.top + getSide(scrollThreshold, \"top\"))\n moveY = -(bounding.top - rect.top + getSide(scrollMargin, \"top\"))\n else if (rect.bottom > bounding.bottom - getSide(scrollThreshold, \"bottom\"))\n moveY = rect.bottom - bounding.bottom + getSide(scrollMargin, \"bottom\")\n if (rect.left < bounding.left + getSide(scrollThreshold, \"left\"))\n moveX = -(bounding.left - rect.left + getSide(scrollMargin, \"left\"))\n else if (rect.right > bounding.right - getSide(scrollThreshold, \"right\"))\n moveX = rect.right - bounding.right + getSide(scrollMargin, \"right\")\n if (moveX || moveY) {\n if (atTop) {\n win.scrollBy(moveX, moveY)\n } else {\n if (moveY) parent.scrollTop += moveY\n if (moveX) parent.scrollLeft += moveX\n }\n }\n if (atTop) break\n }\n}\n\n// Store the scroll position of the editor's parent nodes, along with\n// the top position of an element near the top of the editor, which\n// will be used to make sure the visible viewport remains stable even\n// when the size of the content above changes.\nexport function storeScrollPos(view) {\n let rect = view.dom.getBoundingClientRect(), startY = Math.max(0, rect.top)\n let refDOM, refTop\n for (let x = (rect.left + rect.right) / 2, y = startY + 1;\n y < Math.min(innerHeight, rect.bottom); y += 5) {\n let dom = view.root.elementFromPoint(x, y)\n if (dom == view.dom || !view.dom.contains(dom)) continue\n let localRect = dom.getBoundingClientRect()\n if (localRect.top >= startY - 20) {\n refDOM = dom\n refTop = localRect.top\n break\n }\n }\n return {refDOM, refTop, stack: scrollStack(view.dom)}\n}\n\nfunction scrollStack(dom) {\n let stack = [], doc = dom.ownerDocument\n for (; dom; dom = parentNode(dom)) {\n stack.push({dom, top: dom.scrollTop, left: dom.scrollLeft})\n if (dom == doc) break\n }\n return stack\n}\n\n// Reset the scroll position of the editor's parent nodes to that what\n// it was before, when storeScrollPos was called.\nexport function resetScrollPos({refDOM, refTop, stack}) {\n let newRefTop = refDOM ? refDOM.getBoundingClientRect().top : 0\n restoreScrollStack(stack, newRefTop == 0 ? 0 : newRefTop - refTop)\n}\n\nfunction restoreScrollStack(stack, dTop) {\n for (let i = 0; i < stack.length; i++) {\n let {dom, top, left} = stack[i]\n if (dom.scrollTop != top + dTop) dom.scrollTop = top + dTop\n if (dom.scrollLeft != left) dom.scrollLeft = left\n }\n}\n\nlet preventScrollSupported = null\n// Feature-detects support for .focus({preventScroll: true}), and uses\n// a fallback kludge when not supported.\nexport function focusPreventScroll(dom) {\n if (dom.setActive) return dom.setActive() // in IE\n if (preventScrollSupported) return dom.focus(preventScrollSupported)\n\n let stored = scrollStack(dom)\n dom.focus(preventScrollSupported == null ? {\n get preventScroll() {\n preventScrollSupported = {preventScroll: true}\n return true\n }\n } : undefined)\n if (!preventScrollSupported) {\n preventScrollSupported = false\n restoreScrollStack(stored, 0)\n }\n}\n\nfunction findOffsetInNode(node, coords) {\n let closest, dxClosest = 2e8, coordsClosest, offset = 0\n let rowBot = coords.top, rowTop = coords.top\n for (let child = node.firstChild, childIndex = 0; child; child = child.nextSibling, childIndex++) {\n let rects\n if (child.nodeType == 1) rects = child.getClientRects()\n else if (child.nodeType == 3) rects = textRange(child).getClientRects()\n else continue\n\n for (let i = 0; i < rects.length; i++) {\n let rect = rects[i]\n if (rect.top <= rowBot && rect.bottom >= rowTop) {\n rowBot = Math.max(rect.bottom, rowBot)\n rowTop = Math.min(rect.top, rowTop)\n let dx = rect.left > coords.left ? rect.left - coords.left\n : rect.right < coords.left ? coords.left - rect.right : 0\n if (dx < dxClosest) {\n closest = child\n dxClosest = dx\n coordsClosest = dx && closest.nodeType == 3 ? {left: rect.right < coords.left ? rect.right : rect.left, top: coords.top} : coords\n if (child.nodeType == 1 && dx)\n offset = childIndex + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0)\n continue\n }\n }\n if (!closest && (coords.left >= rect.right && coords.top >= rect.top ||\n coords.left >= rect.left && coords.top >= rect.bottom))\n offset = childIndex + 1\n }\n }\n if (closest && closest.nodeType == 3) return findOffsetInText(closest, coordsClosest)\n if (!closest || (dxClosest && closest.nodeType == 1)) return {node, offset}\n return findOffsetInNode(closest, coordsClosest)\n}\n\nfunction findOffsetInText(node, coords) {\n let len = node.nodeValue.length\n let range = document.createRange()\n for (let i = 0; i < len; i++) {\n range.setEnd(node, i + 1)\n range.setStart(node, i)\n let rect = singleRect(range, 1)\n if (rect.top == rect.bottom) continue\n if (inRect(coords, rect))\n return {node, offset: i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0)}\n }\n return {node, offset: 0}\n}\n\nfunction inRect(coords, rect) {\n return coords.left >= rect.left - 1 && coords.left <= rect.right + 1&&\n coords.top >= rect.top - 1 && coords.top <= rect.bottom + 1\n}\n\nfunction targetKludge(dom, coords) {\n let parent = dom.parentNode\n if (parent && /^li$/i.test(parent.nodeName) && coords.left < dom.getBoundingClientRect().left)\n return parent\n return dom\n}\n\nfunction posFromElement(view, elt, coords) {\n let {node, offset} = findOffsetInNode(elt, coords), bias = -1\n if (node.nodeType == 1 && !node.firstChild) {\n let rect = node.getBoundingClientRect()\n bias = rect.left != rect.right && coords.left > (rect.left + rect.right) / 2 ? 1 : -1\n }\n return view.docView.posFromDOM(node, offset, bias)\n}\n\nfunction posFromCaret(view, node, offset, coords) {\n // Browser (in caretPosition/RangeFromPoint) will agressively\n // normalize towards nearby inline nodes. Since we are interested in\n // positions between block nodes too, we first walk up the hierarchy\n // of nodes to see if there are block nodes that the coordinates\n // fall outside of. If so, we take the position before/after that\n // block. If not, we call `posFromDOM` on the raw node/offset.\n let outside = -1\n for (let cur = node;;) {\n if (cur == view.dom) break\n let desc = view.docView.nearestDesc(cur, true)\n if (!desc) return null\n if (desc.node.isBlock && desc.parent) {\n let rect = desc.dom.getBoundingClientRect()\n if (rect.left > coords.left || rect.top > coords.top) outside = desc.posBefore\n else if (rect.right < coords.left || rect.bottom < coords.top) outside = desc.posAfter\n else break\n }\n cur = desc.dom.parentNode\n }\n return outside > -1 ? outside : view.docView.posFromDOM(node, offset)\n}\n\nfunction elementFromPoint(element, coords, box) {\n let len = element.childNodes.length\n if (len && box.top < box.bottom) {\n for (let startI = Math.max(0, Math.min(len - 1, Math.floor(len * (coords.top - box.top) / (box.bottom - box.top)) - 2)), i = startI;;) {\n let child = element.childNodes[i]\n if (child.nodeType == 1) {\n let rects = child.getClientRects()\n for (let j = 0; j < rects.length; j++) {\n let rect = rects[j]\n if (inRect(coords, rect)) return elementFromPoint(child, coords, rect)\n }\n }\n if ((i = (i + 1) % len) == startI) break\n }\n }\n return element\n}\n\n// Given an x,y position on the editor, get the position in the document.\nexport function posAtCoords(view, coords) {\n let root = view.root, node, offset\n if (root.caretPositionFromPoint) {\n try { // Firefox throws for this call in hard-to-predict circumstances (#994)\n let pos = root.caretPositionFromPoint(coords.left, coords.top)\n if (pos) ({offsetNode: node, offset} = pos)\n } catch (_) {}\n }\n if (!node && root.caretRangeFromPoint) {\n let range = root.caretRangeFromPoint(coords.left, coords.top)\n if (range) ({startContainer: node, startOffset: offset} = range)\n }\n\n let elt = root.elementFromPoint(coords.left, coords.top + 1), pos\n if (!elt || !view.dom.contains(elt.nodeType != 1 ? elt.parentNode : elt)) {\n let box = view.dom.getBoundingClientRect()\n if (!inRect(coords, box)) return null\n elt = elementFromPoint(view.dom, coords, box)\n if (!elt) return null\n }\n elt = targetKludge(elt, coords)\n if (node) {\n if (browser.gecko && node.nodeType == 1) {\n // Firefox will sometimes return offsets into nodes, which\n // have no actual children, from caretPositionFromPoint (#953)\n offset = Math.min(offset, node.childNodes.length)\n // It'll also move the returned position before image nodes,\n // even if those are behind it.\n if (offset < node.childNodes.length) {\n let next = node.childNodes[offset], box\n if (next.nodeName == \"IMG\" && (box = next.getBoundingClientRect()).right <= coords.left &&\n box.bottom > coords.top)\n offset++\n }\n }\n // Suspiciously specific kludge to work around caret*FromPoint\n // never returning a position at the end of the document\n if (node == view.dom && offset == node.childNodes.length - 1 && node.lastChild.nodeType == 1 &&\n coords.top > node.lastChild.getBoundingClientRect().bottom)\n pos = view.state.doc.content.size\n // Ignore positions directly after a BR, since caret*FromPoint\n // 'round up' positions that would be more accurately placed\n // before the BR node.\n else if (offset == 0 || node.nodeType != 1 || node.childNodes[offset - 1].nodeName != \"BR\")\n pos = posFromCaret(view, node, offset, coords)\n }\n if (pos == null) pos = posFromElement(view, elt, coords)\n\n let desc = view.docView.nearestDesc(elt, true)\n return {pos, inside: desc ? desc.posAtStart - desc.border : -1}\n}\n\nfunction singleRect(object, bias) {\n let rects = object.getClientRects()\n return !rects.length ? object.getBoundingClientRect() : rects[bias < 0 ? 0 : rects.length - 1]\n}\n\n// : (EditorView, number) → {left: number, top: number, right: number, bottom: number}\n// Given a position in the document model, get a bounding box of the\n// character at that position, relative to the window.\nexport function coordsAtPos(view, pos) {\n let {node, offset} = view.docView.domFromPos(pos)\n\n // These browsers support querying empty text ranges\n if (node.nodeType == 3 && (browser.chrome || browser.gecko)) {\n let rect = singleRect(textRange(node, offset, offset), 0)\n // Firefox returns bad results (the position before the space)\n // when querying a position directly after line-broken\n // whitespace. Detect this situation and and kludge around it\n if (browser.gecko && offset && /\\s/.test(node.nodeValue[offset - 1]) && offset < node.nodeValue.length) {\n let rectBefore = singleRect(textRange(node, offset - 1, offset - 1), -1)\n if (Math.abs(rectBefore.left - rect.left) < 1 && rectBefore.top == rect.top) {\n let rectAfter = singleRect(textRange(node, offset, offset + 1), -1)\n return flattenV(rectAfter, rectAfter.left < rectBefore.left)\n }\n }\n return rect\n }\n\n if (node.nodeType == 1 && !view.state.doc.resolve(pos).parent.inlineContent) {\n // Return a horizontal line in block context\n let top = true, rect\n if (offset < node.childNodes.length) {\n let after = node.childNodes[offset]\n if (after.nodeType == 1) rect = after.getBoundingClientRect()\n }\n if (!rect && offset) {\n let before = node.childNodes[offset - 1]\n if (before.nodeType == 1) { rect = before.getBoundingClientRect(); top = false }\n }\n return flattenH(rect || node.getBoundingClientRect(), top)\n }\n\n // Not Firefox/Chrome, or not in a text node, so we have to use\n // actual element/character rectangles to get a solution (this part\n // is not very bidi-safe)\n //\n // Try the left side first, fall back to the right one if that\n // doesn't work.\n for (let dir = -1; dir < 2; dir += 2) {\n if (dir < 0 && offset) {\n let prev, target = node.nodeType == 3 ? textRange(node, offset - 1, offset)\n : (prev = node.childNodes[offset - 1]).nodeType == 3 ? textRange(prev)\n : prev.nodeType == 1 && prev.nodeName != \"BR\" ? prev : null // BR nodes tend to only return the rectangle before them\n if (target) {\n let rect = singleRect(target, 1)\n if (rect.top < rect.bottom) return flattenV(rect, false)\n }\n } else if (dir > 0 && offset < nodeSize(node)) {\n let next, target = node.nodeType == 3 ? textRange(node, offset, offset + 1)\n : (next = node.childNodes[offset]).nodeType == 3 ? textRange(next)\n : next.nodeType == 1 ? next : null\n if (target) {\n let rect = singleRect(target, -1)\n if (rect.top < rect.bottom) return flattenV(rect, true)\n }\n }\n }\n // All else failed, just try to get a rectangle for the target node\n return flattenV(singleRect(node.nodeType == 3 ? textRange(node) : node, 0), false)\n}\n\nfunction flattenV(rect, left) {\n if (rect.width == 0) return rect\n let x = left ? rect.left : rect.right\n return {top: rect.top, bottom: rect.bottom, left: x, right: x}\n}\n\nfunction flattenH(rect, top) {\n if (rect.height == 0) return rect\n let y = top ? rect.top : rect.bottom\n return {top: y, bottom: y, left: rect.left, right: rect.right}\n}\n\nfunction withFlushedState(view, state, f) {\n let viewState = view.state, active = view.root.activeElement\n if (viewState != state) view.updateState(state)\n if (active != view.dom) view.focus()\n try {\n return f()\n } finally {\n if (viewState != state) view.updateState(viewState)\n if (active != view.dom) active.focus()\n }\n}\n\n// : (EditorView, number, number)\n// Whether vertical position motion in a given direction\n// from a position would leave a text block.\nfunction endOfTextblockVertical(view, state, dir) {\n let sel = state.selection\n let $pos = dir == \"up\" ? sel.$anchor.min(sel.$head) : sel.$anchor.max(sel.$head)\n return withFlushedState(view, state, () => {\n let {node: dom} = view.docView.domFromPos($pos.pos)\n for (;;) {\n let nearest = view.docView.nearestDesc(dom, true)\n if (!nearest) break\n if (nearest.node.isBlock) { dom = nearest.dom; break }\n dom = nearest.dom.parentNode\n }\n let coords = coordsAtPos(view, $pos.pos)\n for (let child = dom.firstChild; child; child = child.nextSibling) {\n let boxes\n if (child.nodeType == 1) boxes = child.getClientRects()\n else if (child.nodeType == 3) boxes = textRange(child, 0, child.nodeValue.length).getClientRects()\n else continue\n for (let i = 0; i < boxes.length; i++) {\n let box = boxes[i]\n if (box.bottom > box.top && (dir == \"up\" ? box.bottom < coords.top + 1 : box.top > coords.bottom - 1))\n return false\n }\n }\n return true\n })\n}\n\nconst maybeRTL = /[\\u0590-\\u08ac]/\n\nfunction endOfTextblockHorizontal(view, state, dir) {\n let {$head} = state.selection\n if (!$head.parent.isTextblock) return false\n let offset = $head.parentOffset, atStart = !offset, atEnd = offset == $head.parent.content.size\n let sel = getSelection()\n // If the textblock is all LTR, or the browser doesn't support\n // Selection.modify (Edge), fall back to a primitive approach\n if (!maybeRTL.test($head.parent.textContent) || !sel.modify)\n return dir == \"left\" || dir == \"backward\" ? atStart : atEnd\n\n return withFlushedState(view, state, () => {\n // This is a huge hack, but appears to be the best we can\n // currently do: use `Selection.modify` to move the selection by\n // one character, and see if that moves the cursor out of the\n // textblock (or doesn't move it at all, when at the start/end of\n // the document).\n let oldRange = sel.getRangeAt(0), oldNode = sel.focusNode, oldOff = sel.focusOffset\n let oldBidiLevel = sel.caretBidiLevel // Only for Firefox\n sel.modify(\"move\", dir, \"character\")\n let parentDOM = $head.depth ? view.docView.domAfterPos($head.before()) : view.dom\n let result = !parentDOM.contains(sel.focusNode.nodeType == 1 ? sel.focusNode : sel.focusNode.parentNode) ||\n (oldNode == sel.focusNode && oldOff == sel.focusOffset)\n // Restore the previous selection\n sel.removeAllRanges()\n sel.addRange(oldRange)\n if (oldBidiLevel != null) sel.caretBidiLevel = oldBidiLevel\n return result\n })\n}\n\nlet cachedState = null, cachedDir = null, cachedResult = false\nexport function endOfTextblock(view, state, dir) {\n if (cachedState == state && cachedDir == dir) return cachedResult\n cachedState = state; cachedDir = dir\n return cachedResult = dir == \"up\" || dir == \"down\"\n ? endOfTextblockVertical(view, state, dir)\n : endOfTextblockHorizontal(view, state, dir)\n}\n","import {DOMSerializer, Fragment, Mark} from \"prosemirror-model\"\nimport {TextSelection} from \"prosemirror-state\"\n\nimport {domIndex, isEquivalentPosition, nodeSize} from \"./dom\"\nimport browser from \"./browser\"\n\n// NodeView:: interface\n//\n// By default, document nodes are rendered using the result of the\n// [`toDOM`](#model.NodeSpec.toDOM) method of their spec, and managed\n// entirely by the editor. For some use cases, such as embedded\n// node-specific editing interfaces, you want more control over\n// the behavior of a node's in-editor representation, and need to\n// [define](#view.EditorProps.nodeViews) a custom node view.\n//\n// Objects returned as node views must conform to this interface.\n//\n// dom:: ?dom.Node\n// The outer DOM node that represents the document node. When not\n// given, the default strategy is used to create a DOM node.\n//\n// contentDOM:: ?dom.Node\n// The DOM node that should hold the node's content. Only meaningful\n// if the node view also defines a `dom` property and if its node\n// type is not a leaf node type. When this is present, ProseMirror\n// will take care of rendering the node's children into it. When it\n// is not present, the node view itself is responsible for rendering\n// (or deciding not to render) its child nodes.\n//\n// update:: ?(node: Node, decorations: [Decoration]) → bool\n// When given, this will be called when the view is updating itself.\n// It will be given a node (possibly of a different type), and an\n// array of active decorations (which are automatically drawn, and\n// the node view may ignore if it isn't interested in them), and\n// should return true if it was able to update to that node, and\n// false otherwise. If the node view has a `contentDOM` property (or\n// no `dom` property), updating its child nodes will be handled by\n// ProseMirror.\n//\n// selectNode:: ?()\n// Can be used to override the way the node's selected status (as a\n// node selection) is displayed.\n//\n// deselectNode:: ?()\n// When defining a `selectNode` method, you should also provide a\n// `deselectNode` method to remove the effect again.\n//\n// setSelection:: ?(anchor: number, head: number, root: dom.Document)\n// This will be called to handle setting the selection inside the\n// node. The `anchor` and `head` positions are relative to the start\n// of the node. By default, a DOM selection will be created between\n// the DOM positions corresponding to those positions, but if you\n// override it you can do something else.\n//\n// stopEvent:: ?(event: dom.Event) → bool\n// Can be used to prevent the editor view from trying to handle some\n// or all DOM events that bubble up from the node view. Events for\n// which this returns true are not handled by the editor.\n//\n// ignoreMutation:: ?(dom.MutationRecord) → bool\n// Called when a DOM\n// [mutation](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver)\n// or a selection change happens within the view. When the change is\n// a selection change, the record will have a `type` property of\n// `\"selection\"` (which doesn't occur for native mutation records).\n// Return false if the editor should re-read the selection or\n// re-parse the range around the mutation, true if it can safely be\n// ignored.\n//\n// destroy:: ?()\n// Called when the node view is removed from the editor or the whole\n// editor is destroyed.\n\n// View descriptions are data structures that describe the DOM that is\n// used to represent the editor's content. They are used for:\n//\n// - Incremental redrawing when the document changes\n//\n// - Figuring out what part of the document a given DOM position\n// corresponds to\n//\n// - Wiring in custom implementations of the editing interface for a\n// given node\n//\n// They form a doubly-linked mutable tree, starting at `view.docView`.\n\nconst NOT_DIRTY = 0, CHILD_DIRTY = 1, CONTENT_DIRTY = 2, NODE_DIRTY = 3\n\n// Superclass for the various kinds of descriptions. Defines their\n// basic structure and shared methods.\nclass ViewDesc {\n // : (?ViewDesc, [ViewDesc], dom.Node, ?dom.Node)\n constructor(parent, children, dom, contentDOM) {\n this.parent = parent\n this.children = children\n this.dom = dom\n // An expando property on the DOM node provides a link back to its\n // description.\n dom.pmViewDesc = this\n // This is the node that holds the child views. It may be null for\n // descs that don't have children.\n this.contentDOM = contentDOM\n this.dirty = NOT_DIRTY\n }\n\n // Used to check whether a given description corresponds to a\n // widget/mark/node.\n matchesWidget() { return false }\n matchesMark() { return false }\n matchesNode() { return false }\n matchesHack() { return false }\n\n get beforePosition() { return false }\n\n // : () → ?ParseRule\n // When parsing in-editor content (in domchange.js), we allow\n // descriptions to determine the parse rules that should be used to\n // parse them.\n parseRule() { return null }\n\n // : (dom.Event) → bool\n // Used by the editor's event handler to ignore events that come\n // from certain descs.\n stopEvent() { return false }\n\n // The size of the content represented by this desc.\n get size() {\n let size = 0\n for (let i = 0; i < this.children.length; i++) size += this.children[i].size\n return size\n }\n\n // For block nodes, this represents the space taken up by their\n // start/end tokens.\n get border() { return 0 }\n\n destroy() {\n this.parent = null\n if (this.dom.pmViewDesc == this) this.dom.pmViewDesc = null\n for (let i = 0; i < this.children.length; i++)\n this.children[i].destroy()\n }\n\n posBeforeChild(child) {\n for (let i = 0, pos = this.posAtStart; i < this.children.length; i++) {\n let cur = this.children[i]\n if (cur == child) return pos\n pos += cur.size\n }\n }\n\n get posBefore() {\n return this.parent.posBeforeChild(this)\n }\n\n get posAtStart() {\n return this.parent ? this.parent.posBeforeChild(this) + this.border : 0\n }\n\n get posAfter() {\n return this.posBefore + this.size\n }\n\n get posAtEnd() {\n return this.posAtStart + this.size - 2 * this.border\n }\n\n // : (dom.Node, number, ?number) → number\n localPosFromDOM(dom, offset, bias) {\n // If the DOM position is in the content, use the child desc after\n // it to figure out a position.\n if (this.contentDOM && this.contentDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode)) {\n if (bias < 0) {\n let domBefore, desc\n if (dom == this.contentDOM) {\n domBefore = dom.childNodes[offset - 1]\n } else {\n while (dom.parentNode != this.contentDOM) dom = dom.parentNode\n domBefore = dom.previousSibling\n }\n while (domBefore && !((desc = domBefore.pmViewDesc) && desc.parent == this)) domBefore = domBefore.previousSibling\n return domBefore ? this.posBeforeChild(desc) + desc.size : this.posAtStart\n } else {\n let domAfter, desc\n if (dom == this.contentDOM) {\n domAfter = dom.childNodes[offset]\n } else {\n while (dom.parentNode != this.contentDOM) dom = dom.parentNode\n domAfter = dom.nextSibling\n }\n while (domAfter && !((desc = domAfter.pmViewDesc) && desc.parent == this)) domAfter = domAfter.nextSibling\n return domAfter ? this.posBeforeChild(desc) : this.posAtEnd\n }\n }\n // Otherwise, use various heuristics, falling back on the bias\n // parameter, to determine whether to return the position at the\n // start or at the end of this view desc.\n let atEnd\n if (this.contentDOM && this.contentDOM != this.dom && this.dom.contains(this.contentDOM)) {\n atEnd = dom.compareDocumentPosition(this.contentDOM) & 2\n } else if (this.dom.firstChild) {\n if (offset == 0) for (let search = dom;; search = search.parentNode) {\n if (search == this.dom) { atEnd = false; break }\n if (search.parentNode.firstChild != search) break\n }\n if (atEnd == null && offset == dom.childNodes.length) for (let search = dom;; search = search.parentNode) {\n if (search == this.dom) { atEnd = true; break }\n if (search.parentNode.lastChild != search) break\n }\n }\n return (atEnd == null ? bias > 0 : atEnd) ? this.posAtEnd : this.posAtStart\n }\n\n // Scan up the dom finding the first desc that is a descendant of\n // this one.\n nearestDesc(dom, onlyNodes) {\n for (let first = true, cur = dom; cur; cur = cur.parentNode) {\n let desc = this.getDesc(cur)\n if (desc && (!onlyNodes || desc.node)) {\n // If dom is outside of this desc's nodeDOM, don't count it.\n if (first && desc.nodeDOM && !(desc.nodeDOM.nodeType == 1 ? desc.nodeDOM.contains(dom) : desc.nodeDOM == dom)) first = false\n else return desc\n }\n }\n }\n\n getDesc(dom) {\n let desc = dom.pmViewDesc\n for (let cur = desc; cur; cur = cur.parent) if (cur == this) return desc\n }\n\n posFromDOM(dom, offset, bias) {\n for (let scan = dom;; scan = scan.parentNode) {\n let desc = this.getDesc(scan)\n if (desc) return desc.localPosFromDOM(dom, offset, bias)\n }\n }\n\n // : (number) → ?NodeViewDesc\n // Find the desc for the node after the given pos, if any. (When a\n // parent node overrode rendering, there might not be one.)\n descAt(pos) {\n for (let i = 0, offset = 0; i < this.children.length; i++) {\n let child = this.children[i], end = offset + child.size\n if (offset == pos && end != offset) {\n while (!child.border && child.children.length) child = child.children[0]\n return child\n }\n if (pos < end) return child.descAt(pos - offset - child.border)\n offset = end\n }\n }\n\n // : (number) → {node: dom.Node, offset: number}\n domFromPos(pos) {\n if (!this.contentDOM) return {node: this.dom, offset: 0}\n for (let offset = 0, i = 0;; i++) {\n if (offset == pos) {\n while (i < this.children.length && (this.children[i].beforePosition || this.children[i].dom.parentNode != this.contentDOM)) i++\n return {node: this.contentDOM,\n offset: i == this.children.length ? this.contentDOM.childNodes.length : domIndex(this.children[i].dom)}\n }\n if (i == this.children.length) throw new Error(\"Invalid position \" + pos)\n let child = this.children[i], end = offset + child.size\n if (pos < end) return child.domFromPos(pos - offset - child.border)\n offset = end\n }\n }\n\n // Used to find a DOM range in a single parent for a given changed\n // range.\n parseRange(from, to, base = 0) {\n if (this.children.length == 0)\n return {node: this.contentDOM, from, to, fromOffset: 0, toOffset: this.contentDOM.childNodes.length}\n\n let fromOffset = -1, toOffset = -1\n for (let offset = base, i = 0;; i++) {\n let child = this.children[i], end = offset + child.size\n if (fromOffset == -1 && from <= end) {\n let childBase = offset + child.border\n // FIXME maybe descend mark views to parse a narrower range?\n if (from >= childBase && to <= end - child.border && child.node &&\n child.contentDOM && this.contentDOM.contains(child.contentDOM))\n return child.parseRange(from, to, childBase)\n\n from = offset\n for (let j = i; j > 0; j--) {\n let prev = this.children[j - 1]\n if (prev.size && prev.dom.parentNode == this.contentDOM && !prev.emptyChildAt(1)) {\n fromOffset = domIndex(prev.dom) + 1\n break\n }\n from -= prev.size\n }\n if (fromOffset == -1) fromOffset = 0\n }\n if (fromOffset > -1 && to <= end) {\n to = end\n for (let j = i + 1; j < this.children.length; j++) {\n let next = this.children[j]\n if (next.size && next.dom.parentNode == this.contentDOM && !next.emptyChildAt(-1)) {\n toOffset = domIndex(next.dom)\n break\n }\n to += next.size\n }\n if (toOffset == -1) toOffset = this.contentDOM.childNodes.length\n break\n }\n offset = end\n }\n return {node: this.contentDOM, from, to, fromOffset, toOffset}\n }\n\n emptyChildAt(side) {\n if (this.border || !this.contentDOM || !this.children.length) return false\n let child = this.children[side < 0 ? 0 : this.children.length - 1]\n return child.size == 0 || child.emptyChildAt(side)\n }\n\n // : (number) → dom.Node\n domAfterPos(pos) {\n let {node, offset} = this.domFromPos(pos)\n if (node.nodeType != 1 || offset == node.childNodes.length)\n throw new RangeError(\"No node after pos \" + pos)\n return node.childNodes[offset]\n }\n\n // : (number, number, dom.Document)\n // View descs are responsible for setting any selection that falls\n // entirely inside of them, so that custom implementations can do\n // custom things with the selection. Note that this falls apart when\n // a selection starts in such a node and ends in another, in which\n // case we just use whatever domFromPos produces as a best effort.\n setSelection(anchor, head, root, force) {\n // If the selection falls entirely in a child, give it to that child\n let from = Math.min(anchor, head), to = Math.max(anchor, head)\n for (let i = 0, offset = 0; i < this.children.length; i++) {\n let child = this.children[i], end = offset + child.size\n if (from > offset && to < end)\n return child.setSelection(anchor - offset - child.border, head - offset - child.border, root, force)\n offset = end\n }\n\n let anchorDOM = this.domFromPos(anchor), headDOM = this.domFromPos(head)\n let domSel = root.getSelection(), range = document.createRange()\n if (!force &&\n isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset) &&\n isEquivalentPosition(headDOM.node, headDOM.offset, domSel.focusNode, domSel.focusOffset))\n return\n\n // Selection.extend can be used to create an 'inverted' selection\n // (one where the focus is before the anchor), but not all\n // browsers support it yet.\n if (domSel.extend) {\n range.setEnd(anchorDOM.node, anchorDOM.offset)\n range.collapse(false)\n } else {\n if (anchor > head) { let tmp = anchorDOM; anchorDOM = headDOM; headDOM = tmp }\n range.setEnd(headDOM.node, headDOM.offset)\n range.setStart(anchorDOM.node, anchorDOM.offset)\n }\n domSel.removeAllRanges()\n domSel.addRange(range)\n if (domSel.extend)\n domSel.extend(headDOM.node, headDOM.offset)\n }\n\n // : (dom.MutationRecord) → bool\n ignoreMutation(_mutation) {\n return !this.contentDOM\n }\n\n get contentLost() {\n return this.contentDOM && this.contentDOM != this.dom && !this.dom.contains(this.contentDOM)\n }\n\n // Remove a subtree of the element tree that has been touched\n // by a DOM change, so that the next update will redraw it.\n markDirty(from, to) {\n for (let offset = 0, i = 0; i < this.children.length; i++) {\n let child = this.children[i], end = offset + child.size\n if (offset == end ? from <= end && to >= offset : from < end && to > offset) {\n let startInside = offset + child.border, endInside = end - child.border\n if (from >= startInside && to <= endInside) {\n this.dirty = from == offset || to == end ? CONTENT_DIRTY : CHILD_DIRTY\n if (from == startInside && to == endInside &&\n (child.contentLost || child.dom.parentNode != this.contentDOM)) child.dirty = NODE_DIRTY\n else child.markDirty(from - startInside, to - startInside)\n return\n } else {\n child.dirty = NODE_DIRTY\n }\n }\n offset = end\n }\n this.dirty = CONTENT_DIRTY\n }\n\n markParentsDirty() {\n let level = 1\n for (let node = this.parent; node; node = node.parent) {\n let dirty = level == 1 ? CONTENT_DIRTY : CHILD_DIRTY\n if (node.dirty < dirty) node.dirty = dirty\n }\n }\n}\n\n// Reused array to avoid allocating fresh arrays for things that will\n// stay empty anyway.\nconst nothing = []\n\n// A widget desc represents a widget decoration, which is a DOM node\n// drawn between the document nodes.\nclass WidgetViewDesc extends ViewDesc {\n // : (ViewDesc, Decoration)\n constructor(parent, widget, view, pos) {\n let self, dom = widget.type.toDOM\n if (typeof dom == \"function\") dom = dom(view, () => {\n if (!self) return pos\n if (self.parent) return self.parent.posBeforeChild(self)\n })\n if (!widget.type.spec.raw) {\n if (dom.nodeType != 1) {\n let wrap = document.createElement(\"span\")\n wrap.appendChild(dom)\n dom = wrap\n }\n dom.contentEditable = false\n dom.classList.add(\"ProseMirror-widget\")\n }\n super(parent, nothing, dom, null)\n this.widget = widget\n self = this\n }\n\n get beforePosition() {\n return this.widget.type.side < 0\n }\n\n matchesWidget(widget) {\n return this.dirty == NOT_DIRTY && widget.type.eq(this.widget.type)\n }\n\n parseRule() { return {ignore: true} }\n\n stopEvent(event) {\n let stop = this.widget.spec.stopEvent\n return stop ? stop(event) : false\n }\n}\n\nclass CompositionViewDesc extends ViewDesc {\n constructor(parent, dom, textDOM, text) {\n super(parent, nothing, dom, null)\n this.textDOM = textDOM\n this.text = text\n }\n\n get size() { return this.text.length }\n\n localPosFromDOM(dom, offset) {\n if (dom != this.textDOM) return this.posAtStart + (offset ? this.size : 0)\n return this.posAtStart + offset\n }\n\n domFromPos(pos) {\n return {node: this.textDOM, offset: pos}\n }\n\n ignoreMutation(mut) {\n return mut.type === 'characterData' && mut.target.nodeValue == mut.oldValue\n }\n}\n\n// A mark desc represents a mark. May have multiple children,\n// depending on how the mark is split. Note that marks are drawn using\n// a fixed nesting order, for simplicity and predictability, so in\n// some cases they will be split more often than would appear\n// necessary.\nclass MarkViewDesc extends ViewDesc {\n // : (ViewDesc, Mark, dom.Node)\n constructor(parent, mark, dom, contentDOM) {\n super(parent, [], dom, contentDOM)\n this.mark = mark\n }\n\n static create(parent, mark, inline, view) {\n let custom = view.nodeViews[mark.type.name]\n let spec = custom && custom(mark, view, inline)\n if (!spec || !spec.dom)\n spec = DOMSerializer.renderSpec(document, mark.type.spec.toDOM(mark, inline))\n return new MarkViewDesc(parent, mark, spec.dom, spec.contentDOM || spec.dom)\n }\n\n parseRule() { return {mark: this.mark.type.name, attrs: this.mark.attrs, contentElement: this.contentDOM} }\n\n matchesMark(mark) { return this.dirty != NODE_DIRTY && this.mark.eq(mark) }\n\n markDirty(from, to) {\n super.markDirty(from, to)\n // Move dirty info to nearest node view\n if (this.dirty != NOT_DIRTY) {\n let parent = this.parent\n while (!parent.node) parent = parent.parent\n if (parent.dirty < this.dirty) parent.dirty = this.dirty\n this.dirty = NOT_DIRTY\n }\n }\n\n slice(from, to, view) {\n let copy = MarkViewDesc.create(this.parent, this.mark, true, view)\n let nodes = this.children, size = this.size\n if (to < size) nodes = replaceNodes(nodes, to, size, view)\n if (from > 0) nodes = replaceNodes(nodes, 0, from, view)\n for (let i = 0; i < nodes.length; i++) nodes[i].parent = copy\n copy.children = nodes\n return copy\n }\n}\n\n// Node view descs are the main, most common type of view desc, and\n// correspond to an actual node in the document. Unlike mark descs,\n// they populate their child array themselves.\nclass NodeViewDesc extends ViewDesc {\n // : (?ViewDesc, Node, [Decoration], DecorationSet, dom.Node, ?dom.Node, EditorView)\n constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos) {\n super(parent, node.isLeaf ? nothing : [], dom, contentDOM)\n this.nodeDOM = nodeDOM\n this.node = node\n this.outerDeco = outerDeco\n this.innerDeco = innerDeco\n if (contentDOM) this.updateChildren(view, pos)\n }\n\n // By default, a node is rendered using the `toDOM` method from the\n // node type spec. But client code can use the `nodeViews` spec to\n // supply a custom node view, which can influence various aspects of\n // the way the node works.\n //\n // (Using subclassing for this was intentionally decided against,\n // since it'd require exposing a whole slew of finnicky\n // implementation details to the user code that they probably will\n // never need.)\n static create(parent, node, outerDeco, innerDeco, view, pos) {\n let custom = view.nodeViews[node.type.name], descObj\n let spec = custom && custom(node, view, () => {\n // (This is a function that allows the custom view to find its\n // own position)\n if (!descObj) return pos\n if (descObj.parent) return descObj.parent.posBeforeChild(descObj)\n }, outerDeco)\n\n let dom = spec && spec.dom, contentDOM = spec && spec.contentDOM\n if (node.isText) {\n if (!dom) dom = document.createTextNode(node.text)\n else if (dom.nodeType != 3) throw new RangeError(\"Text must be rendered as a DOM text node\")\n } else if (!dom) {\n ;({dom, contentDOM} = DOMSerializer.renderSpec(document, node.type.spec.toDOM(node)))\n }\n if (!contentDOM && !node.isText && dom.nodeName != \"BR\") { // Chrome gets confused by
    \n if (!dom.hasAttribute(\"contenteditable\")) dom.contentEditable = false\n if (node.type.spec.draggable) dom.draggable = true\n }\n\n let nodeDOM = dom\n dom = applyOuterDeco(dom, outerDeco, node)\n\n if (spec)\n return descObj = new CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM,\n spec, view, pos + 1)\n else if (node.isText)\n return new TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM, view)\n else\n return new NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos + 1)\n }\n\n parseRule() {\n // Experimental kludge to allow opt-in re-parsing of nodes\n if (this.node.type.spec.reparseInView) return null\n // FIXME the assumption that this can always return the current\n // attrs means that if the user somehow manages to change the\n // attrs in the dom, that won't be picked up. Not entirely sure\n // whether this is a problem\n let rule = {node: this.node.type.name, attrs: this.node.attrs}\n if (this.node.type.spec.code) rule.preserveWhitespace = \"full\"\n if (this.contentDOM && !this.contentLost) rule.contentElement = this.contentDOM\n else rule.getContent = () => this.contentDOM ? Fragment.empty : this.node.content\n return rule\n }\n\n matchesNode(node, outerDeco, innerDeco) {\n return this.dirty == NOT_DIRTY && node.eq(this.node) &&\n sameOuterDeco(outerDeco, this.outerDeco) && innerDeco.eq(this.innerDeco)\n }\n\n get size() { return this.node.nodeSize }\n\n get border() { return this.node.isLeaf ? 0 : 1 }\n\n // Syncs `this.children` to match `this.node.content` and the local\n // decorations, possibly introducing nesting for marks. Then, in a\n // separate step, syncs the DOM inside `this.contentDOM` to\n // `this.children`.\n updateChildren(view, pos) {\n let inline = this.node.inlineContent, off = pos\n let composition = inline && view.composing && this.localCompositionNode(view, pos)\n let updater = new ViewTreeUpdater(this, composition && composition.node)\n iterDeco(this.node, this.innerDeco, (widget, i) => {\n if (widget.spec.marks)\n updater.syncToMarks(widget.spec.marks, inline, view)\n else if (widget.type.side >= 0)\n updater.syncToMarks(i == this.node.childCount ? Mark.none : this.node.child(i).marks, inline, view)\n // If the next node is a desc matching this widget, reuse it,\n // otherwise insert the widget as a new view desc.\n updater.placeWidget(widget, view, off)\n }, (child, outerDeco, innerDeco, i) => {\n // Make sure the wrapping mark descs match the node's marks.\n updater.syncToMarks(child.marks, inline, view)\n // Either find an existing desc that exactly matches this node,\n // and drop the descs before it.\n updater.findNodeMatch(child, outerDeco, innerDeco, i) ||\n // Or try updating the next desc to reflect this node.\n updater.updateNextNode(child, outerDeco, innerDeco, view, i) ||\n // Or just add it as a new desc.\n updater.addNode(child, outerDeco, innerDeco, view, off)\n off += child.nodeSize\n })\n // Drop all remaining descs after the current position.\n updater.syncToMarks(nothing, inline, view)\n if (this.node.isTextblock) updater.addTextblockHacks()\n updater.destroyRest()\n\n // Sync the DOM if anything changed\n if (updater.changed || this.dirty == CONTENT_DIRTY) {\n // May have to protect focused DOM from being changed if a composition is active\n if (composition) this.protectLocalComposition(view, composition)\n this.renderChildren()\n }\n }\n\n renderChildren() {\n renderDescs(this.contentDOM, this.children, NodeViewDesc.is)\n if (browser.ios) iosHacks(this.dom)\n }\n\n localCompositionNode(view, pos) {\n // Only do something if both the selection and a focused text node\n // are inside of this node, and the node isn't already part of a\n // view that's a child of this view\n let {from, to} = view.state.selection\n if (!(view.state.selection instanceof TextSelection) || from < pos || to > pos + this.node.content.size) return\n let sel = view.root.getSelection()\n let textNode = nearbyTextNode(sel.focusNode, sel.focusOffset)\n if (!textNode || !this.dom.contains(textNode.parentNode)) return\n\n // Find the text in the focused node in the node, stop if it's not\n // there (may have been modified through other means, in which\n // case it should overwritten)\n let text = textNode.nodeValue\n let textPos = findTextInFragment(this.node.content, text, from - pos, to - pos)\n\n return textPos < 0 ? null : {node: textNode, pos: textPos, text}\n }\n\n protectLocalComposition(view, {node, pos, text}) {\n // The node is already part of a local view desc, leave it there\n if (this.getDesc(node)) return\n\n // Create a composition view for the orphaned nodes\n let topNode = node\n for (;; topNode = topNode.parentNode) {\n if (topNode.parentNode == this.contentDOM) break\n while (topNode.previousSibling) topNode.parentNode.removeChild(topNode.previousSibling)\n while (topNode.nextSibling) topNode.parentNode.removeChild(topNode.nextSibling)\n if (topNode.pmViewDesc) topNode.pmViewDesc = null\n }\n let desc = new CompositionViewDesc(this, topNode, node, text)\n view.compositionNodes.push(desc)\n\n // Patch up this.children to contain the composition view\n this.children = replaceNodes(this.children, pos, pos + text.length, view, desc)\n }\n\n // : (Node, [Decoration], DecorationSet, EditorView) → bool\n // If this desc be updated to match the given node decoration,\n // do so and return true.\n update(node, outerDeco, innerDeco, view) {\n if (this.dirty == NODE_DIRTY ||\n !node.sameMarkup(this.node)) return false\n this.updateInner(node, outerDeco, innerDeco, view)\n return true\n }\n\n updateInner(node, outerDeco, innerDeco, view) {\n this.updateOuterDeco(outerDeco)\n this.node = node\n this.innerDeco = innerDeco\n if (this.contentDOM) this.updateChildren(view, this.posAtStart)\n this.dirty = NOT_DIRTY\n }\n\n updateOuterDeco(outerDeco) {\n if (sameOuterDeco(outerDeco, this.outerDeco)) return\n let needsWrap = this.nodeDOM.nodeType != 1\n let oldDOM = this.dom\n this.dom = patchOuterDeco(this.dom, this.nodeDOM,\n computeOuterDeco(this.outerDeco, this.node, needsWrap),\n computeOuterDeco(outerDeco, this.node, needsWrap))\n if (this.dom != oldDOM) {\n oldDOM.pmViewDesc = null\n this.dom.pmViewDesc = this\n }\n this.outerDeco = outerDeco\n }\n\n // Mark this node as being the selected node.\n selectNode() {\n this.nodeDOM.classList.add(\"ProseMirror-selectednode\")\n if (this.contentDOM || !this.node.type.spec.draggable) this.dom.draggable = true\n }\n\n // Remove selected node marking from this node.\n deselectNode() {\n this.nodeDOM.classList.remove(\"ProseMirror-selectednode\")\n if (this.contentDOM || !this.node.type.spec.draggable) this.dom.draggable = false\n }\n}\n\n// Create a view desc for the top-level document node, to be exported\n// and used by the view class.\nexport function docViewDesc(doc, outerDeco, innerDeco, dom, view) {\n applyOuterDeco(dom, outerDeco, doc)\n return new NodeViewDesc(null, doc, outerDeco, innerDeco, dom, dom, dom, view, 0)\n}\n\nclass TextViewDesc extends NodeViewDesc {\n constructor(parent, node, outerDeco, innerDeco, dom, nodeDOM, view) {\n super(parent, node, outerDeco, innerDeco, dom, null, nodeDOM, view)\n }\n\n parseRule() {\n return {skip: this.nodeDOM.parentNode || true}\n }\n\n update(node, outerDeco) {\n if (this.dirty == NODE_DIRTY || (this.dirty != NOT_DIRTY && !this.inParent()) ||\n !node.sameMarkup(this.node)) return false\n this.updateOuterDeco(outerDeco)\n if ((this.dirty != NOT_DIRTY || node.text != this.node.text) && node.text != this.nodeDOM.nodeValue)\n this.nodeDOM.nodeValue = node.text\n this.node = node\n this.dirty = NOT_DIRTY\n return true\n }\n\n inParent() {\n let parentDOM = this.parent.contentDOM\n for (let n = this.nodeDOM; n; n = n.parentNode) if (n == parentDOM) return true\n return false\n }\n\n domFromPos(pos) {\n return {node: this.nodeDOM, offset: pos}\n }\n\n localPosFromDOM(dom, offset, bias) {\n if (dom == this.nodeDOM) return this.posAtStart + Math.min(offset, this.node.text.length)\n return super.localPosFromDOM(dom, offset, bias)\n }\n\n ignoreMutation(mutation) {\n return mutation.type != \"characterData\" && mutation.type != \"selection\"\n }\n\n slice(from, to, view) {\n let node = this.node.cut(from, to), dom = document.createTextNode(node.text)\n return new TextViewDesc(this.parent, node, this.outerDeco, this.innerDeco, dom, dom, view)\n }\n}\n\n// A dummy desc used to tag trailing BR or span nodes created to work\n// around contentEditable terribleness.\nclass BRHackViewDesc extends ViewDesc {\n parseRule() { return {ignore: true} }\n matchesHack() { return this.dirty == NOT_DIRTY }\n}\n\n// A separate subclass is used for customized node views, so that the\n// extra checks only have to be made for nodes that are actually\n// customized.\nclass CustomNodeViewDesc extends NodeViewDesc {\n // : (?ViewDesc, Node, [Decoration], DecorationSet, dom.Node, ?dom.Node, NodeView, EditorView)\n constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, spec, view, pos) {\n super(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos)\n this.spec = spec\n }\n\n // A custom `update` method gets to decide whether the update goes\n // through. If it does, and there's a `contentDOM` node, our logic\n // updates the children.\n update(node, outerDeco, innerDeco, view) {\n if (this.dirty == NODE_DIRTY) return false\n if (this.spec.update) {\n let result = this.spec.update(node, outerDeco)\n if (result) this.updateInner(node, outerDeco, innerDeco, view)\n return result\n } else if (!this.contentDOM && !node.isLeaf) {\n return false\n } else {\n return super.update(node, outerDeco, innerDeco, view)\n }\n }\n\n selectNode() {\n this.spec.selectNode ? this.spec.selectNode() : super.selectNode()\n }\n\n deselectNode() {\n this.spec.deselectNode ? this.spec.deselectNode() : super.deselectNode()\n }\n\n setSelection(anchor, head, root, force) {\n this.spec.setSelection ? this.spec.setSelection(anchor, head, root)\n : super.setSelection(anchor, head, root, force)\n }\n\n destroy() {\n if (this.spec.destroy) this.spec.destroy()\n super.destroy()\n }\n\n stopEvent(event) {\n return this.spec.stopEvent ? this.spec.stopEvent(event) : false\n }\n\n ignoreMutation(mutation) {\n return this.spec.ignoreMutation ? this.spec.ignoreMutation(mutation) : super.ignoreMutation(mutation)\n }\n}\n\n// : (dom.Node, [ViewDesc])\n// Sync the content of the given DOM node with the nodes associated\n// with the given array of view descs, recursing into mark descs\n// because this should sync the subtree for a whole node at a time.\nfunction renderDescs(parentDOM, descs) {\n let dom = parentDOM.firstChild\n for (let i = 0; i < descs.length; i++) {\n let desc = descs[i], childDOM = desc.dom\n if (childDOM.parentNode == parentDOM) {\n while (childDOM != dom) dom = rm(dom)\n dom = dom.nextSibling\n } else {\n parentDOM.insertBefore(childDOM, dom)\n }\n if (desc instanceof MarkViewDesc) {\n let pos = dom ? dom.previousSibling : parentDOM.lastChild\n renderDescs(desc.contentDOM, desc.children)\n dom = pos ? pos.nextSibling : parentDOM.firstChild\n }\n }\n while (dom) dom = rm(dom)\n}\n\nfunction OuterDecoLevel(nodeName) {\n if (nodeName) this.nodeName = nodeName\n}\nOuterDecoLevel.prototype = Object.create(null)\n\nconst noDeco = [new OuterDecoLevel]\n\nfunction computeOuterDeco(outerDeco, node, needsWrap) {\n if (outerDeco.length == 0) return noDeco\n\n let top = needsWrap ? noDeco[0] : new OuterDecoLevel, result = [top]\n\n for (let i = 0; i < outerDeco.length; i++) {\n let attrs = outerDeco[i].type.attrs, cur = top\n if (!attrs) continue\n if (attrs.nodeName)\n result.push(cur = new OuterDecoLevel(attrs.nodeName))\n\n for (let name in attrs) {\n let val = attrs[name]\n if (val == null) continue\n if (needsWrap && result.length == 1)\n result.push(cur = top = new OuterDecoLevel(node.isInline ? \"span\" : \"div\"))\n if (name == \"class\") cur.class = (cur.class ? cur.class + \" \" : \"\") + val\n else if (name == \"style\") cur.style = (cur.style ? cur.style + \";\" : \"\") + val\n else if (name != \"nodeName\") cur[name] = val\n }\n }\n\n return result\n}\n\nfunction patchOuterDeco(outerDOM, nodeDOM, prevComputed, curComputed) {\n // Shortcut for trivial case\n if (prevComputed == noDeco && curComputed == noDeco) return nodeDOM\n\n let curDOM = nodeDOM\n for (let i = 0; i < curComputed.length; i++) {\n let deco = curComputed[i], prev = prevComputed[i]\n if (i) {\n let parent\n if (prev && prev.nodeName == deco.nodeName && curDOM != outerDOM &&\n (parent = curDOM.parentNode) && parent.tagName.toLowerCase() == deco.nodeName) {\n curDOM = parent\n } else {\n parent = document.createElement(deco.nodeName)\n parent.appendChild(curDOM)\n prev = noDeco[0]\n curDOM = parent\n }\n }\n patchAttributes(curDOM, prev || noDeco[0], deco)\n }\n return curDOM\n}\n\nfunction patchAttributes(dom, prev, cur) {\n for (let name in prev)\n if (name != \"class\" && name != \"style\" && name != \"nodeName\" && !(name in cur))\n dom.removeAttribute(name)\n for (let name in cur)\n if (name != \"class\" && name != \"style\" && name != \"nodeName\" && cur[name] != prev[name])\n dom.setAttribute(name, cur[name])\n if (prev.class != cur.class) {\n let prevList = prev.class ? prev.class.split(\" \") : nothing\n let curList = cur.class ? cur.class.split(\" \") : nothing\n for (let i = 0; i < prevList.length; i++) if (curList.indexOf(prevList[i]) == -1)\n dom.classList.remove(prevList[i])\n for (let i = 0; i < curList.length; i++) if (prevList.indexOf(curList[i]) == -1)\n dom.classList.add(curList[i])\n }\n if (prev.style != cur.style) {\n if (prev.style) {\n let prop = /\\s*([\\w\\-\\xa1-\\uffff]+)\\s*:(?:\"(?:\\\\.|[^\"])*\"|'(?:\\\\.|[^'])*'|\\(.*?\\)|[^;])*/g, m\n while (m = prop.exec(prev.style))\n dom.style.removeProperty(m[1])\n }\n if (cur.style)\n dom.style.cssText += cur.style\n }\n}\n\nfunction applyOuterDeco(dom, deco, node) {\n return patchOuterDeco(dom, dom, noDeco, computeOuterDeco(deco, node, dom.nodeType != 1))\n}\n\n// : ([Decoration], [Decoration]) → bool\nfunction sameOuterDeco(a, b) {\n if (a.length != b.length) return false\n for (let i = 0; i < a.length; i++) if (!a[i].type.eq(b[i].type)) return false\n return true\n}\n\n// Remove a DOM node and return its next sibling.\nfunction rm(dom) {\n let next = dom.nextSibling\n dom.parentNode.removeChild(dom)\n return next\n}\n\n// Helper class for incrementally updating a tree of mark descs and\n// the widget and node descs inside of them.\nclass ViewTreeUpdater {\n // : (NodeViewDesc)\n constructor(top, lockedNode) {\n this.top = top\n this.lock = lockedNode\n // Index into `this.top`'s child array, represents the current\n // update position.\n this.index = 0\n // When entering a mark, the current top and index are pushed\n // onto this.\n this.stack = []\n // Tracks whether anything was changed\n this.changed = false\n\n let pre = preMatch(top.node.content, top.children)\n this.preMatched = pre.nodes\n this.preMatchOffset = pre.offset\n }\n\n getPreMatch(index) {\n return index >= this.preMatchOffset ? this.preMatched[index - this.preMatchOffset] : null\n }\n\n // Destroy and remove the children between the given indices in\n // `this.top`.\n destroyBetween(start, end) {\n if (start == end) return\n for (let i = start; i < end; i++) this.top.children[i].destroy()\n this.top.children.splice(start, end - start)\n this.changed = true\n }\n\n // Destroy all remaining children in `this.top`.\n destroyRest() {\n this.destroyBetween(this.index, this.top.children.length)\n }\n\n // : ([Mark], EditorView)\n // Sync the current stack of mark descs with the given array of\n // marks, reusing existing mark descs when possible.\n syncToMarks(marks, inline, view) {\n let keep = 0, depth = this.stack.length >> 1\n let maxKeep = Math.min(depth, marks.length)\n while (keep < maxKeep &&\n (keep == depth - 1 ? this.top : this.stack[(keep + 1) << 1]).matchesMark(marks[keep]) && marks[keep].type.spec.spanning !== false)\n keep++\n\n while (keep < depth) {\n this.destroyRest()\n this.top.dirty = NOT_DIRTY\n this.index = this.stack.pop()\n this.top = this.stack.pop()\n depth--\n }\n while (depth < marks.length) {\n this.stack.push(this.top, this.index + 1)\n let found = -1\n for (let i = this.index; i < Math.min(this.index + 3, this.top.children.length); i++) {\n if (this.top.children[i].matchesMark(marks[depth])) { found = i; break }\n }\n if (found > -1) {\n if (found > this.index) {\n this.changed = true\n this.destroyBetween(this.index, found)\n }\n this.top = this.top.children[this.index]\n } else {\n let markDesc = MarkViewDesc.create(this.top, marks[depth], inline, view)\n this.top.children.splice(this.index, 0, markDesc)\n this.top = markDesc\n this.changed = true\n }\n this.index = 0\n depth++\n }\n }\n\n // : (Node, [Decoration], DecorationSet) → bool\n // Try to find a node desc matching the given data. Skip over it and\n // return true when successful.\n findNodeMatch(node, outerDeco, innerDeco, index) {\n let found = -1, preMatch = index < 0 ? undefined : this.getPreMatch(index), children = this.top.children\n if (preMatch && preMatch.matchesNode(node, outerDeco, innerDeco)) {\n found = children.indexOf(preMatch)\n } else {\n for (let i = this.index, e = Math.min(children.length, i + 5); i < e; i++) {\n let child = children[i]\n if (child.matchesNode(node, outerDeco, innerDeco) && this.preMatched.indexOf(child) < 0) {\n found = i\n break\n }\n }\n }\n if (found < 0) return false\n this.destroyBetween(this.index, found)\n this.index++\n return true\n }\n\n // : (Node, [Decoration], DecorationSet, EditorView, Fragment, number) → bool\n // Try to update the next node, if any, to the given data. Checks\n // pre-matches to avoid overwriting nodes that could still be used.\n updateNextNode(node, outerDeco, innerDeco, view, index) {\n if (this.index == this.top.children.length) return false\n let next = this.top.children[this.index]\n if (next instanceof NodeViewDesc) {\n let preMatch = this.preMatched.indexOf(next)\n if (preMatch > -1 && preMatch + this.preMatchOffset != index) return false\n let nextDOM = next.dom\n\n // Can't update if nextDOM is or contains this.lock, except if\n // it's a text node whose content already matches the new text\n // and whose decorations match the new ones.\n let locked = this.lock && (nextDOM == this.lock || nextDOM.nodeType == 1 && nextDOM.contains(this.lock.parentNode)) &&\n !(node.isText && next.node && next.node.isText && next.nodeDOM.nodeValue == node.text &&\n next.dirty != NODE_DIRTY && sameOuterDeco(outerDeco, next.outerDeco))\n if (!locked && next.update(node, outerDeco, innerDeco, view)) {\n if (next.dom != nextDOM) this.changed = true\n this.index++\n return true\n }\n }\n return false\n }\n\n // : (Node, [Decoration], DecorationSet, EditorView)\n // Insert the node as a newly created node desc.\n addNode(node, outerDeco, innerDeco, view, pos) {\n this.top.children.splice(this.index++, 0, NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos))\n this.changed = true\n }\n\n placeWidget(widget, view, pos) {\n if (this.index < this.top.children.length && this.top.children[this.index].matchesWidget(widget)) {\n this.index++\n } else {\n let desc = new WidgetViewDesc(this.top, widget, view, pos)\n this.top.children.splice(this.index++, 0, desc)\n this.changed = true\n }\n }\n\n // Make sure a textblock looks and behaves correctly in\n // contentEditable.\n addTextblockHacks() {\n let lastChild = this.top.children[this.index - 1]\n while (lastChild instanceof MarkViewDesc) lastChild = lastChild.children[lastChild.children.length - 1]\n\n if (!lastChild || // Empty textblock\n !(lastChild instanceof TextViewDesc) ||\n /\\n$/.test(lastChild.node.text)) {\n if (this.index < this.top.children.length && this.top.children[this.index].matchesHack()) {\n this.index++\n } else {\n let dom = document.createElement(\"br\")\n this.top.children.splice(this.index++, 0, new BRHackViewDesc(this.top, nothing, dom, null))\n this.changed = true\n }\n }\n }\n}\n\n// : (Fragment, [ViewDesc]) → [ViewDesc]\n// Iterate from the end of the fragment and array of descs to find\n// directly matching ones, in order to avoid overeagerly reusing\n// those for other nodes. Returns an array whose positions correspond\n// to node positions in the fragment, and whose elements are either\n// descs matched to the child at that index, or empty.\nfunction preMatch(frag, descs) {\n let result = [], end = frag.childCount\n for (let i = descs.length - 1; end > 0 && i >= 0; i--) {\n let desc = descs[i], node = desc.node\n if (!node) continue\n if (node != frag.child(end - 1)) break\n result.push(desc)\n --end\n }\n return {nodes: result.reverse(), offset: end}\n}\n\nfunction compareSide(a, b) { return a.type.side - b.type.side }\n\n// : (ViewDesc, DecorationSet, (Decoration, number), (Node, [Decoration], DecorationSet, number))\n// This function abstracts iterating over the nodes and decorations in\n// a fragment. Calls `onNode` for each node, with its local and child\n// decorations. Splits text nodes when there is a decoration starting\n// or ending inside of them. Calls `onWidget` for each widget.\nfunction iterDeco(parent, deco, onWidget, onNode) {\n let locals = deco.locals(parent), offset = 0\n // Simple, cheap variant for when there are no local decorations\n if (locals.length == 0) {\n for (let i = 0; i < parent.childCount; i++) {\n let child = parent.child(i)\n onNode(child, locals, deco.forChild(offset, child), i)\n offset += child.nodeSize\n }\n return\n }\n\n let decoIndex = 0, active = [], restNode = null\n for (let parentIndex = 0;;) {\n if (decoIndex < locals.length && locals[decoIndex].to == offset) {\n let widget = locals[decoIndex++], widgets\n while (decoIndex < locals.length && locals[decoIndex].to == offset)\n (widgets || (widgets = [widget])).push(locals[decoIndex++])\n if (widgets) {\n widgets.sort(compareSide)\n for (let i = 0; i < widgets.length; i++) onWidget(widgets[i], parentIndex)\n } else {\n onWidget(widget, parentIndex)\n }\n }\n\n let child, index\n if (restNode) {\n index = -1\n child = restNode\n restNode = null\n } else if (parentIndex < parent.childCount) {\n index = parentIndex\n child = parent.child(parentIndex++)\n } else {\n break\n }\n\n for (let i = 0; i < active.length; i++) if (active[i].to <= offset) active.splice(i--, 1)\n while (decoIndex < locals.length && locals[decoIndex].from == offset) active.push(locals[decoIndex++])\n\n let end = offset + child.nodeSize\n if (child.isText) {\n let cutAt = end\n if (decoIndex < locals.length && locals[decoIndex].from < cutAt) cutAt = locals[decoIndex].from\n for (let i = 0; i < active.length; i++) if (active[i].to < cutAt) cutAt = active[i].to\n if (cutAt < end) {\n restNode = child.cut(cutAt - offset)\n child = child.cut(0, cutAt - offset)\n end = cutAt\n index = -1\n }\n }\n\n onNode(child, active.length ? active.slice() : nothing, deco.forChild(offset, child), index)\n offset = end\n }\n}\n\n// List markers in Mobile Safari will mysteriously disappear\n// sometimes. This works around that.\nfunction iosHacks(dom) {\n if (dom.nodeName == \"UL\" || dom.nodeName == \"OL\") {\n let oldCSS = dom.style.cssText\n dom.style.cssText = oldCSS + \"; list-style: square !important\"\n window.getComputedStyle(dom).listStyle\n dom.style.cssText = oldCSS\n }\n}\n\nfunction nearbyTextNode(node, offset) {\n for (;;) {\n if (node.nodeType == 3) return node\n if (node.nodeType == 1 && offset > 0) {\n if (node.childNodes.length > offset && node.childNodes[offset].nodeType == 3)\n return node.childNodes[offset]\n node = node.childNodes[offset - 1]\n offset = nodeSize(node)\n } else if (node.nodeType == 1 && offset < node.childNodes.length) {\n node = node.childNodes[offset]\n offset = 0\n } else {\n return null\n }\n }\n}\n\n// Find a piece of text in an inline fragment, overlapping from-to\nfunction findTextInFragment(frag, text, from, to) {\n for (let str = \"\", i = 0, childPos = 0; i < frag.childCount; i++) {\n let child = frag.child(i), end = childPos + child.nodeSize\n if (child.isText) {\n str += child.text\n if (end >= to) {\n let strStart = end - str.length, found = str.lastIndexOf(text)\n while (found > -1 && strStart + found > from) found = str.lastIndexOf(text, found - 1)\n if (found > -1 && strStart + found + text.length >= to) {\n return strStart + found\n } else if (end > to) {\n break\n }\n }\n } else {\n str = \"\"\n }\n childPos = end\n }\n return -1\n}\n\n// Replace range from-to in an array of view descs with replacement\n// (may be null to just delete). This goes very much against the grain\n// of the rest of this code, which tends to create nodes with the\n// right shape in one go, rather than messing with them after\n// creation, but is necessary in the composition hack.\nfunction replaceNodes(nodes, from, to, view, replacement) {\n let result = []\n for (let i = 0, off = 0; i < nodes.length; i++) {\n let child = nodes[i], start = off, end = off += child.size\n if (start >= to || end <= from) {\n result.push(child)\n } else {\n if (start < from) result.push(child.slice(0, from - start, view))\n if (replacement) {\n result.push(replacement)\n replacement = null\n }\n if (end > to) result.push(child.slice(to - start, child.size, view))\n }\n }\n return result\n}\n","import {Selection, NodeSelection, TextSelection} from \"prosemirror-state\"\nimport browser from \"./browser\"\nimport {domIndex, selectionCollapsed} from \"./dom\"\n\nfunction moveSelectionBlock(state, dir) {\n let {$anchor, $head} = state.selection\n let $side = dir > 0 ? $anchor.max($head) : $anchor.min($head)\n let $start = !$side.parent.inlineContent ? $side : $side.depth ? state.doc.resolve(dir > 0 ? $side.after() : $side.before()) : null\n return $start && Selection.findFrom($start, dir)\n}\n\nfunction apply(view, sel) {\n view.dispatch(view.state.tr.setSelection(sel).scrollIntoView())\n return true\n}\n\nfunction selectHorizontally(view, dir, mods) {\n let sel = view.state.selection\n if (sel instanceof TextSelection) {\n if (!sel.empty || mods.indexOf(\"s\") > -1) {\n return false\n } else if (view.endOfTextblock(dir > 0 ? \"right\" : \"left\")) {\n let next = moveSelectionBlock(view.state, dir)\n if (next && (next instanceof NodeSelection)) return apply(view, next)\n return false\n } else {\n let $head = sel.$head, node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter, desc\n if (!node || node.isText) return false\n let nodePos = dir < 0 ? $head.pos - node.nodeSize : $head.pos\n if (!(node.isAtom || (desc = view.docView.descAt(nodePos)) && !desc.contentDOM)) return false\n if (NodeSelection.isSelectable(node)) {\n return apply(view, new NodeSelection(dir < 0 ? view.state.doc.resolve($head.pos - node.nodeSize) : $head))\n } else if (browser.webkit) {\n // Chrome and Safari will introduce extra pointless cursor\n // positions around inline uneditable nodes, so we have to\n // take over and move the cursor past them (#937)\n return apply(view, new TextSelection(view.state.doc.resolve(dir < 0 ? nodePos : nodePos + node.nodeSize)))\n } else {\n return false\n }\n }\n } else if (sel instanceof NodeSelection && sel.node.isInline) {\n return apply(view, new TextSelection(dir > 0 ? sel.$to : sel.$from))\n } else {\n let next = moveSelectionBlock(view.state, dir)\n if (next) return apply(view, next)\n return false\n }\n}\n\nfunction nodeLen(node) {\n return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length\n}\n\nfunction isIgnorable(dom) {\n let desc = dom.pmViewDesc\n return desc && desc.size == 0 && (dom.nextSibling || dom.nodeName != \"BR\")\n}\n\n// Make sure the cursor isn't directly after one or more ignored\n// nodes, which will confuse the browser's cursor motion logic.\nfunction skipIgnoredNodesLeft(view) {\n let sel = view.root.getSelection()\n let node = sel.focusNode, offset = sel.focusOffset\n if (!node) return\n let moveNode, moveOffset, force = false\n // Gecko will do odd things when the selection is directly in front\n // of a non-editable node, so in that case, move it into the next\n // node if possible. Issue prosemirror/prosemirror#832.\n if (browser.gecko && node.nodeType == 1 && offset < nodeLen(node) && isIgnorable(node.childNodes[offset])) force = true\n for (;;) {\n if (offset > 0) {\n if (node.nodeType != 1) {\n break\n } else {\n let before = node.childNodes[offset - 1]\n if (isIgnorable(before)) {\n moveNode = node\n moveOffset = --offset\n } else if (before.nodeType == 3) {\n node = before\n offset = node.nodeValue.length\n } else break\n }\n } else if (isBlockNode(node)) {\n break\n } else {\n let prev = node.previousSibling\n while (prev && isIgnorable(prev)) {\n moveNode = node.parentNode\n moveOffset = domIndex(prev)\n prev = prev.previousSibling\n }\n if (!prev) {\n node = node.parentNode\n if (node == view.dom) break\n offset = 0\n } else {\n node = prev\n offset = nodeLen(node)\n }\n }\n }\n if (force) setSelFocus(view, sel, node, offset)\n else if (moveNode) setSelFocus(view, sel, moveNode, moveOffset)\n}\n\n// Make sure the cursor isn't directly before one or more ignored\n// nodes.\nfunction skipIgnoredNodesRight(view) {\n let sel = view.root.getSelection()\n let node = sel.focusNode, offset = sel.focusOffset\n if (!node) return\n let len = nodeLen(node)\n let moveNode, moveOffset\n for (;;) {\n if (offset < len) {\n if (node.nodeType != 1) break\n let after = node.childNodes[offset]\n if (isIgnorable(after)) {\n moveNode = node\n moveOffset = ++offset\n }\n else break\n } else if (isBlockNode(node)) {\n break\n } else {\n let next = node.nextSibling\n while (next && isIgnorable(next)) {\n moveNode = next.parentNode\n moveOffset = domIndex(next) + 1\n next = next.nextSibling\n }\n if (!next) {\n node = node.parentNode\n if (node == view.dom) break\n offset = len = 0\n } else {\n node = next\n offset = 0\n len = nodeLen(node)\n }\n }\n }\n if (moveNode) setSelFocus(view, sel, moveNode, moveOffset)\n}\n\nfunction isBlockNode(dom) {\n let desc = dom.pmViewDesc\n return desc && desc.node && desc.node.isBlock\n}\n\nfunction setSelFocus(view, sel, node, offset) {\n if (selectionCollapsed(sel)) {\n let range = document.createRange()\n range.setEnd(node, offset)\n range.setStart(node, offset)\n sel.removeAllRanges()\n sel.addRange(range)\n } else if (sel.extend) {\n sel.extend(node, offset)\n }\n view.domObserver.setCurSelection()\n}\n\n// : (EditorState, number)\n// Check whether vertical selection motion would involve node\n// selections. If so, apply it (if not, the result is left to the\n// browser)\nfunction selectVertically(view, dir, mods) {\n let sel = view.state.selection\n if (sel instanceof TextSelection && !sel.empty || mods.indexOf(\"s\") > -1) return false\n let {$from, $to} = sel\n\n if (!$from.parent.inlineContent || view.endOfTextblock(dir < 0 ? \"up\" : \"down\")) {\n let next = moveSelectionBlock(view.state, dir)\n if (next && (next instanceof NodeSelection))\n return apply(view, next)\n }\n if (!$from.parent.inlineContent) {\n let beyond = Selection.findFrom(dir < 0 ? $from : $to, dir)\n return beyond ? apply(view, beyond) : true\n }\n return false\n}\n\nfunction stopNativeHorizontalDelete(view, dir) {\n if (!(view.state.selection instanceof TextSelection)) return true\n let {$head, $anchor, empty} = view.state.selection\n if (!$head.sameParent($anchor)) return true\n if (!empty) return false\n if (view.endOfTextblock(dir > 0 ? \"forward\" : \"backward\")) return true\n let nextNode = !$head.textOffset && (dir < 0 ? $head.nodeBefore : $head.nodeAfter)\n if (nextNode && !nextNode.isText) {\n let tr = view.state.tr\n if (dir < 0) tr.delete($head.pos - nextNode.nodeSize, $head.pos)\n else tr.delete($head.pos, $head.pos + nextNode.nodeSize)\n view.dispatch(tr)\n return true\n }\n return false\n}\n\nfunction switchEditable(view, node, state) {\n view.domObserver.stop()\n node.contentEditable = state\n view.domObserver.start()\n}\n\n// Issue #867 / https://bugs.chromium.org/p/chromium/issues/detail?id=903821\n// In which Chrome does really wrong things when the down arrow is\n// pressed when the cursor is directly at the start of a textblock and\n// has an uneditable node after it\nfunction chromeDownArrowBug(view) {\n if (!browser.chrome || view.state.selection.$head.parentOffset > 0) return\n let {focusNode, focusOffset} = view.root.getSelection()\n if (focusNode && focusNode.nodeType == 1 && focusOffset == 0 &&\n focusNode.firstChild && focusNode.firstChild.contentEditable == \"false\") {\n let child = focusNode.firstChild\n switchEditable(view, child, true)\n setTimeout(() => switchEditable(view, child, false), 20)\n }\n}\n\n// A backdrop key mapping used to make sure we always suppress keys\n// that have a dangerous default effect, even if the commands they are\n// bound to return false, and to make sure that cursor-motion keys\n// find a cursor (as opposed to a node selection) when pressed. For\n// cursor-motion keys, the code in the handlers also takes care of\n// block selections.\n\nfunction getMods(event) {\n let result = \"\"\n if (event.ctrlKey) result += \"c\"\n if (event.metaKey) result += \"m\"\n if (event.altKey) result += \"a\"\n if (event.shiftKey) result += \"s\"\n return result\n}\n\nexport function captureKeyDown(view, event) {\n let code = event.keyCode, mods = getMods(event)\n if (code == 8 || (browser.mac && code == 72 && mods == \"c\")) { // Backspace, Ctrl-h on Mac\n return stopNativeHorizontalDelete(view, -1) || skipIgnoredNodesLeft(view)\n } else if (code == 46 || (browser.mac && code == 68 && mods == \"c\")) { // Delete, Ctrl-d on Mac\n return stopNativeHorizontalDelete(view, 1) || skipIgnoredNodesRight(view)\n } else if (code == 13 || code == 27) { // Enter, Esc\n return true\n } else if (code == 37) { // Left arrow\n return selectHorizontally(view, -1, mods) || skipIgnoredNodesLeft(view)\n } else if (code == 39) { // Right arrow\n return selectHorizontally(view, 1, mods) || skipIgnoredNodesRight(view)\n } else if (code == 38) { // Up arrow\n return selectVertically(view, -1, mods) || skipIgnoredNodesLeft(view)\n } else if (code == 40) { // Down arrow\n return chromeDownArrowBug(view) || selectVertically(view, 1, mods) || skipIgnoredNodesRight(view)\n } else if (mods == (browser.mac ? \"m\" : \"c\") &&\n (code == 66 || code == 73 || code == 89 || code == 90)) { // Mod-[biyz]\n return true\n }\n return false\n}\n","import {TextSelection, NodeSelection} from \"prosemirror-state\"\n\nimport browser from \"./browser\"\nimport {selectionCollapsed, isEquivalentPosition, domIndex} from \"./dom\"\n\nexport function selectionFromDOM(view, origin) {\n let domSel = view.root.getSelection(), doc = view.state.doc\n let nearestDesc = view.docView.nearestDesc(domSel.focusNode), inWidget = nearestDesc && nearestDesc.size == 0\n let head = view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset)\n let $head = doc.resolve(head), $anchor, selection\n if (selectionCollapsed(domSel)) {\n $anchor = $head\n while (nearestDesc && !nearestDesc.node) nearestDesc = nearestDesc.parent\n if (nearestDesc && nearestDesc.node.isAtom && NodeSelection.isSelectable(nearestDesc.node) && nearestDesc.parent) {\n let pos = nearestDesc.posBefore\n selection = new NodeSelection(head == pos ? $head : doc.resolve(pos))\n }\n } else {\n $anchor = doc.resolve(view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset))\n }\n\n if (!selection) {\n let bias = origin == \"pointer\" || (view.state.selection.head < $head.pos && !inWidget) ? 1 : -1\n selection = selectionBetween(view, $anchor, $head, bias)\n }\n return selection\n}\n\nexport function selectionToDOM(view, force) {\n let sel = view.state.selection\n syncNodeSelection(view, sel)\n\n if (view.editable ? !view.hasFocus() : !(hasSelection(view) && document.activeElement.contains(view.dom))) return\n\n view.domObserver.disconnectSelection()\n\n if (view.cursorWrapper) {\n selectCursorWrapper(view)\n } else {\n let {anchor, head} = sel, resetEditableFrom, resetEditableTo\n if (brokenSelectBetweenUneditable && !(sel instanceof TextSelection)) {\n if (!sel.$from.parent.inlineContent)\n resetEditableFrom = temporarilyEditableNear(view, sel.from)\n if (!sel.empty && !sel.$from.parent.inlineContent)\n resetEditableTo = temporarilyEditableNear(view, sel.to)\n }\n view.docView.setSelection(anchor, head, view.root, force)\n if (brokenSelectBetweenUneditable) {\n if (resetEditableFrom) resetEditableFrom.contentEditable = \"false\"\n if (resetEditableTo) resetEditableTo.contentEditable = \"false\"\n }\n if (sel.visible) {\n view.dom.classList.remove(\"ProseMirror-hideselection\")\n } else if (anchor != head) {\n view.dom.classList.add(\"ProseMirror-hideselection\")\n if (\"onselectionchange\" in document) removeClassOnSelectionChange(view)\n }\n }\n\n view.domObserver.setCurSelection()\n view.domObserver.connectSelection()\n}\n\n// Kludge to work around Webkit not allowing a selection to start/end\n// between non-editable block nodes. We briefly make something\n// editable, set the selection, then set it uneditable again.\n\nconst brokenSelectBetweenUneditable = browser.safari || browser.chrome && browser.chrome_version < 63\n\nfunction temporarilyEditableNear(view, pos) {\n let {node, offset} = view.docView.domFromPos(pos)\n let after = offset < node.childNodes.length ? node.childNodes[offset] : null\n let before = offset ? node.childNodes[offset - 1] : null\n if ((!after || after.contentEditable == \"false\") && (!before || before.contentEditable == \"false\")) {\n if (after) {\n after.contentEditable = \"true\"\n return after\n } else if (before) {\n before.contentEditable = \"true\"\n return before\n }\n }\n}\n\nfunction removeClassOnSelectionChange(view) {\n let doc = view.dom.ownerDocument\n doc.removeEventListener(\"selectionchange\", view.hideSelectionGuard)\n let domSel = view.root.getSelection()\n let node = domSel.anchorNode, offset = domSel.anchorOffset\n doc.addEventListener(\"selectionchange\", view.hideSelectionGuard = () => {\n if (domSel.anchorNode != node || domSel.anchorOffset != offset) {\n doc.removeEventListener(\"selectionchange\", view.hideSelectionGuard)\n view.dom.classList.remove(\"ProseMirror-hideselection\")\n }\n })\n}\n\nfunction selectCursorWrapper(view) {\n let domSel = view.root.getSelection(), range = document.createRange()\n let node = view.cursorWrapper.dom, img = node.nodeName == \"IMG\"\n if (img) range.setEnd(node.parentNode, domIndex(node) + 1)\n else range.setEnd(node, 0)\n range.collapse(false)\n domSel.removeAllRanges()\n domSel.addRange(range)\n // Kludge to kill 'control selection' in IE11 when selecting an\n // invisible cursor wrapper, since that would result in those weird\n // resize handles and a selection that considers the absolutely\n // positioned wrapper, rather than the root editable node, the\n // focused element.\n if (!img && !view.state.selection.visible && browser.ie && browser.ie_version <= 11) {\n node.disabled = true\n node.disabled = false\n }\n}\n\nexport function syncNodeSelection(view, sel) {\n if (sel instanceof NodeSelection) {\n let desc = view.docView.descAt(sel.from)\n if (desc != view.lastSelectedViewDesc) {\n clearNodeSelection(view)\n if (desc) desc.selectNode()\n view.lastSelectedViewDesc = desc\n }\n } else {\n clearNodeSelection(view)\n }\n}\n\n// Clear all DOM statefulness of the last node selection.\nfunction clearNodeSelection(view) {\n if (view.lastSelectedViewDesc) {\n if (view.lastSelectedViewDesc.parent)\n view.lastSelectedViewDesc.deselectNode()\n view.lastSelectedViewDesc = null\n }\n}\n\nexport function selectionBetween(view, $anchor, $head, bias) {\n return view.someProp(\"createSelectionBetween\", f => f(view, $anchor, $head))\n || TextSelection.between($anchor, $head, bias)\n}\n\nexport function hasFocusAndSelection(view) {\n if (view.editable && view.root.activeElement != view.dom) return false\n return hasSelection(view)\n}\n\nexport function hasSelection(view) {\n let sel = view.root.getSelection()\n if (!sel.anchorNode) return false\n try {\n // Firefox will raise 'permission denied' errors when accessing\n // properties of `sel.anchorNode` when it's in a generated CSS\n // element.\n return view.dom.contains(sel.anchorNode.nodeType == 3 ? sel.anchorNode.parentNode : sel.anchorNode) &&\n (view.editable || view.dom.contains(sel.focusNode.nodeType == 3 ? sel.focusNode.parentNode : sel.focusNode))\n } catch(_) {\n return false\n }\n}\n\nexport function anchorInRightPlace(view) {\n let anchorDOM = view.docView.domFromPos(view.state.selection.anchor)\n let domSel = view.root.getSelection()\n return isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset)\n}\n","import {Fragment, DOMParser} from \"prosemirror-model\"\nimport {Selection, TextSelection} from \"prosemirror-state\"\n\nimport {selectionBetween, selectionFromDOM, selectionToDOM} from \"./selection\"\nimport {selectionCollapsed, keyEvent} from \"./dom\"\nimport browser from \"./browser\"\n\n// Note that all referencing and parsing is done with the\n// start-of-operation selection and document, since that's the one\n// that the DOM represents. If any changes came in in the meantime,\n// the modification is mapped over those before it is applied, in\n// readDOMChange.\n\nfunction parseBetween(view, from_, to_) {\n let {node: parent, fromOffset, toOffset, from, to} = view.docView.parseRange(from_, to_)\n\n let domSel = view.root.getSelection(), find = null, anchor = domSel.anchorNode\n if (anchor && view.dom.contains(anchor.nodeType == 1 ? anchor : anchor.parentNode)) {\n find = [{node: anchor, offset: domSel.anchorOffset}]\n if (!selectionCollapsed(domSel))\n find.push({node: domSel.focusNode, offset: domSel.focusOffset})\n }\n // Work around issue in Chrome where backspacing sometimes replaces\n // the deleted content with a random BR node (issues #799, #831)\n if (browser.chrome && view.lastKeyCode === 8) {\n for (let off = toOffset; off > fromOffset; off--) {\n let node = parent.childNodes[off - 1], desc = node.pmViewDesc\n if (node.nodeType == \"BR\" && !desc) { toOffset = off; break }\n if (!desc || desc.size) break\n }\n }\n let startDoc = view.state.doc\n let parser = view.someProp(\"domParser\") || DOMParser.fromSchema(view.state.schema)\n let $from = startDoc.resolve(from)\n\n let sel = null, doc = parser.parse(parent, {\n topNode: $from.parent,\n topMatch: $from.parent.contentMatchAt($from.index()),\n topOpen: true,\n from: fromOffset,\n to: toOffset,\n preserveWhitespace: $from.parent.type.spec.code ? \"full\" : true,\n editableContent: true,\n findPositions: find,\n ruleFromNode,\n context: $from\n })\n if (find && find[0].pos != null) {\n let anchor = find[0].pos, head = find[1] && find[1].pos\n if (head == null) head = anchor\n sel = {anchor: anchor + from, head: head + from}\n }\n return {doc, sel, from, to}\n}\n\nfunction ruleFromNode(dom) {\n let desc = dom.pmViewDesc\n if (desc) {\n return desc.parseRule()\n } else if (dom.nodeName == \"BR\" && dom.parentNode) {\n // Safari replaces the list item or table cell with a BR\n // directly in the list node (?!) if you delete the last\n // character in a list item or table cell (#708, #862)\n if (browser.safari && /^(ul|ol)$/i.test(dom.parentNode.nodeName)) {\n let skip = document.createElement(\"div\")\n skip.appendChild(document.createElement(\"li\"))\n return {skip}\n } else if (dom.parentNode.lastChild == dom || browser.safari && /^(tr|table)$/i.test(dom.parentNode.nodeName)) {\n return {ignore: true}\n }\n } else if (dom.nodeName == \"IMG\" && dom.getAttribute(\"mark-placeholder\")) {\n return {ignore: true}\n }\n}\n\nexport function readDOMChange(view, from, to, typeOver) {\n if (from < 0) {\n let origin = view.lastSelectionTime > Date.now() - 50 ? view.lastSelectionOrigin : null\n let newSel = selectionFromDOM(view, origin)\n if (!view.state.selection.eq(newSel)) {\n let tr = view.state.tr.setSelection(newSel)\n if (origin == \"pointer\") tr.setMeta(\"pointer\", true)\n else if (origin == \"key\") tr.scrollIntoView()\n view.dispatch(tr)\n }\n return\n }\n\n let $before = view.state.doc.resolve(from)\n let shared = $before.sharedDepth(to)\n from = $before.before(shared + 1)\n to = view.state.doc.resolve(to).after(shared + 1)\n\n let sel = view.state.selection\n let parse = parseBetween(view, from, to)\n\n let doc = view.state.doc, compare = doc.slice(parse.from, parse.to)\n let preferredPos, preferredSide\n // Prefer anchoring to end when Backspace is pressed\n if (view.lastKeyCode === 8 && Date.now() - 100 < view.lastKeyCodeTime) {\n preferredPos = view.state.selection.to\n preferredSide = \"end\"\n } else {\n preferredPos = view.state.selection.from\n preferredSide = \"start\"\n }\n view.lastKeyCode = null\n\n let change = findDiff(compare.content, parse.doc.content, parse.from, preferredPos, preferredSide)\n if (!change) {\n if (typeOver && sel instanceof TextSelection && !sel.empty && sel.$head.sameParent(sel.$anchor) &&\n !view.composing && !(parse.sel && parse.sel.anchor != parse.sel.head)) {\n change = {start: sel.from, endA: sel.to, endB: sel.to}\n } else {\n if (parse.sel) {\n let sel = resolveSelection(view, view.state.doc, parse.sel)\n if (sel && !sel.eq(view.state.selection)) view.dispatch(view.state.tr.setSelection(sel))\n }\n return\n }\n }\n view.domChangeCount++\n // Handle the case where overwriting a selection by typing matches\n // the start or end of the selected content, creating a change\n // that's smaller than what was actually overwritten.\n if (view.state.selection.from < view.state.selection.to &&\n change.start == change.endB &&\n view.state.selection instanceof TextSelection) {\n if (change.start > view.state.selection.from && change.start <= view.state.selection.from + 2) {\n change.start = view.state.selection.from\n } else if (change.endA < view.state.selection.to && change.endA >= view.state.selection.to - 2) {\n change.endB += (view.state.selection.to - change.endA)\n change.endA = view.state.selection.to\n }\n }\n\n // IE11 will insert a non-breaking space _ahead_ of the space after\n // the cursor space when adding a space before another space. When\n // that happened, adjust the change to cover the space instead.\n if (browser.ie && browser.ie_version <= 11 && change.endB == change.start + 1 &&\n change.endA == change.start && change.start > parse.from &&\n parse.doc.textBetween(change.start - parse.from - 1, change.start - parse.from + 1) == \" \\u00a0\") {\n change.start--\n change.endA--\n change.endB--\n }\n\n let $from = parse.doc.resolveNoCache(change.start - parse.from)\n let $to = parse.doc.resolveNoCache(change.endB - parse.from)\n let nextSel\n // If this looks like the effect of pressing Enter, just dispatch an\n // Enter key instead.\n if (!$from.sameParent($to) && $from.pos < parse.doc.content.size &&\n (nextSel = Selection.findFrom(parse.doc.resolve($from.pos + 1), 1, true)) &&\n nextSel.head == $to.pos &&\n view.someProp(\"handleKeyDown\", f => f(view, keyEvent(13, \"Enter\"))))\n return\n // Same for backspace\n if (view.state.selection.anchor > change.start &&\n looksLikeJoin(doc, change.start, change.endA, $from, $to) &&\n view.someProp(\"handleKeyDown\", f => f(view, keyEvent(8, \"Backspace\")))) {\n if (browser.android && browser.chrome) view.domObserver.suppressSelectionUpdates() // #820\n return\n }\n\n let chFrom = change.start, chTo = change.endA\n\n let tr, storedMarks, markChange, $from1\n if ($from.sameParent($to) && $from.parent.inlineContent) {\n if ($from.pos == $to.pos) { // Deletion\n // IE11 sometimes weirdly moves the DOM selection around after\n // backspacing out the first element in a textblock\n if (browser.ie && browser.ie_version <= 11 && $from.parentOffset == 0) {\n view.domObserver.suppressSelectionUpdates()\n setTimeout(() => selectionToDOM(view), 20)\n }\n tr = view.state.tr.delete(chFrom, chTo)\n storedMarks = doc.resolve(change.start).marksAcross(doc.resolve(change.endA))\n } else if ( // Adding or removing a mark\n change.endA == change.endB && ($from1 = doc.resolve(change.start)) &&\n (markChange = isMarkChange($from.parent.content.cut($from.parentOffset, $to.parentOffset),\n $from1.parent.content.cut($from1.parentOffset, change.endA - $from1.start())))\n ) {\n tr = view.state.tr\n if (markChange.type == \"add\") tr.addMark(chFrom, chTo, markChange.mark)\n else tr.removeMark(chFrom, chTo, markChange.mark)\n } else if ($from.parent.child($from.index()).isText && $from.index() == $to.index() - ($to.textOffset ? 0 : 1)) {\n // Both positions in the same text node -- simply insert text\n let text = $from.parent.textBetween($from.parentOffset, $to.parentOffset)\n if (view.someProp(\"handleTextInput\", f => f(view, chFrom, chTo, text))) return\n tr = view.state.tr.insertText(text, chFrom, chTo)\n }\n }\n\n if (!tr)\n tr = view.state.tr.replace(chFrom, chTo, parse.doc.slice(change.start - parse.from, change.endB - parse.from))\n if (parse.sel) {\n let sel = resolveSelection(view, tr.doc, parse.sel)\n // Chrome Android will sometimes, during composition, report the\n // selection in the wrong place. If it looks like that is\n // happening, don't update the selection.\n // Edge just doesn't move the cursor forward when you start typing\n // in an empty block or between br nodes.\n if (sel && !(browser.chrome && browser.android && view.composing && sel.empty && sel.head == chFrom ||\n browser.ie && sel.empty && sel.head == chFrom))\n tr.setSelection(sel)\n }\n if (storedMarks) tr.ensureMarks(storedMarks)\n view.dispatch(tr.scrollIntoView())\n}\n\nfunction resolveSelection(view, doc, parsedSel) {\n if (Math.max(parsedSel.anchor, parsedSel.head) > doc.content.size) return null\n return selectionBetween(view, doc.resolve(parsedSel.anchor), doc.resolve(parsedSel.head))\n}\n\n// : (Fragment, Fragment) → ?{mark: Mark, type: string}\n// Given two same-length, non-empty fragments of inline content,\n// determine whether the first could be created from the second by\n// removing or adding a single mark type.\nfunction isMarkChange(cur, prev) {\n let curMarks = cur.firstChild.marks, prevMarks = prev.firstChild.marks\n let added = curMarks, removed = prevMarks, type, mark, update\n for (let i = 0; i < prevMarks.length; i++) added = prevMarks[i].removeFromSet(added)\n for (let i = 0; i < curMarks.length; i++) removed = curMarks[i].removeFromSet(removed)\n if (added.length == 1 && removed.length == 0) {\n mark = added[0]\n type = \"add\"\n update = node => node.mark(mark.addToSet(node.marks))\n } else if (added.length == 0 && removed.length == 1) {\n mark = removed[0]\n type = \"remove\"\n update = node => node.mark(mark.removeFromSet(node.marks))\n } else {\n return null\n }\n let updated = []\n for (let i = 0; i < prev.childCount; i++) updated.push(update(prev.child(i)))\n if (Fragment.from(updated).eq(cur)) return {mark, type}\n}\n\nfunction looksLikeJoin(old, start, end, $newStart, $newEnd) {\n if (!$newStart.parent.isTextblock ||\n // The content must have shrunk\n end - start <= $newEnd.pos - $newStart.pos ||\n // newEnd must point directly at or after the end of the block that newStart points into\n skipClosingAndOpening($newStart, true, false) < $newEnd.pos)\n return false\n\n let $start = old.resolve(start)\n // Start must be at the end of a block\n if ($start.parentOffset < $start.parent.content.size || !$start.parent.isTextblock)\n return false\n let $next = old.resolve(skipClosingAndOpening($start, true, true))\n // The next textblock must start before end and end near it\n if (!$next.parent.isTextblock || $next.pos > end ||\n skipClosingAndOpening($next, true, false) < end)\n return false\n\n // The fragments after the join point must match\n return $newStart.parent.content.cut($newStart.parentOffset).eq($next.parent.content)\n}\n\nfunction skipClosingAndOpening($pos, fromEnd, mayOpen) {\n let depth = $pos.depth, end = fromEnd ? $pos.end() : $pos.pos\n while (depth > 0 && (fromEnd || $pos.indexAfter(depth) == $pos.node(depth).childCount)) {\n depth--\n end++\n fromEnd = false\n }\n if (mayOpen) {\n let next = $pos.node(depth).maybeChild($pos.indexAfter(depth))\n while (next && !next.isLeaf) {\n next = next.firstChild\n end++\n }\n }\n return end\n}\n\nfunction findDiff(a, b, pos, preferredPos, preferredSide) {\n let start = a.findDiffStart(b, pos)\n if (start == null) return null\n let {a: endA, b: endB} = a.findDiffEnd(b, pos + a.size, pos + b.size)\n if (preferredSide == \"end\") {\n let adjust = Math.max(0, start - Math.min(endA, endB))\n preferredPos -= endA + adjust - start\n }\n if (endA < start && a.size < b.size) {\n let move = preferredPos <= start && preferredPos >= endA ? start - preferredPos : 0\n start -= move\n endB = start + (endB - endA)\n endA = start\n } else if (endB < start) {\n let move = preferredPos <= start && preferredPos >= endB ? start - preferredPos : 0\n start -= move\n endA = start + (endA - endB)\n endB = start\n }\n return {start, endA, endB}\n}\n","import {Slice, Fragment, DOMParser, DOMSerializer} from \"prosemirror-model\"\n\nexport function serializeForClipboard(view, slice) {\n let context = [], {content, openStart, openEnd} = slice\n while (openStart > 1 && openEnd > 1 && content.childCount == 1 && content.firstChild.childCount == 1) {\n openStart--\n openEnd--\n let node = content.firstChild\n context.push(node.type.name, node.type.hasRequiredAttrs() ? node.attrs : null)\n content = node.content\n }\n\n let serializer = view.someProp(\"clipboardSerializer\") || DOMSerializer.fromSchema(view.state.schema)\n let doc = detachedDoc(), wrap = doc.createElement(\"div\")\n wrap.appendChild(serializer.serializeFragment(content, {document: doc}))\n\n let firstChild = wrap.firstChild, needsWrap\n while (firstChild && firstChild.nodeType == 1 && (needsWrap = wrapMap[firstChild.nodeName.toLowerCase()])) {\n for (let i = needsWrap.length - 1; i >= 0; i--) {\n let wrapper = doc.createElement(needsWrap[i])\n while (wrap.firstChild) wrapper.appendChild(wrap.firstChild)\n wrap.appendChild(wrapper)\n }\n firstChild = wrap.firstChild\n }\n\n if (firstChild && firstChild.nodeType == 1)\n firstChild.setAttribute(\"data-pm-slice\", `${openStart} ${openEnd} ${JSON.stringify(context)}`)\n\n let text = view.someProp(\"clipboardTextSerializer\", f => f(slice)) ||\n slice.content.textBetween(0, slice.content.size, \"\\n\\n\")\n\n return {dom: wrap, text}\n}\n\n// : (EditorView, string, string, ?bool, ResolvedPos) → ?Slice\n// Read a slice of content from the clipboard (or drop data).\nexport function parseFromClipboard(view, text, html, plainText, $context) {\n let dom, inCode = $context.parent.type.spec.code, slice\n if (!html && !text) return null\n let asText = text && (plainText || inCode || !html)\n if (asText) {\n view.someProp(\"transformPastedText\", f => { text = f(text) })\n if (inCode) return new Slice(Fragment.from(view.state.schema.text(text)), 0, 0)\n let parsed = view.someProp(\"clipboardTextParser\", f => f(text, $context))\n if (parsed) {\n slice = parsed\n } else {\n dom = document.createElement(\"div\")\n text.trim().split(/(?:\\r\\n?|\\n)+/).forEach(block => {\n dom.appendChild(document.createElement(\"p\")).textContent = block\n })\n }\n } else {\n view.someProp(\"transformPastedHTML\", f => { html = f(html) })\n dom = readHTML(html)\n }\n\n let contextNode = dom && dom.querySelector(\"[data-pm-slice]\")\n let sliceData = contextNode && /^(\\d+) (\\d+) (.*)/.exec(contextNode.getAttribute(\"data-pm-slice\"))\n if (!slice) {\n let parser = view.someProp(\"clipboardParser\") || view.someProp(\"domParser\") || DOMParser.fromSchema(view.state.schema)\n slice = parser.parseSlice(dom, {preserveWhitespace: !!(asText || sliceData), context: $context})\n }\n if (sliceData)\n slice = addContext(closeSlice(slice, +sliceData[1], +sliceData[2]), sliceData[3])\n else // HTML wasn't created by ProseMirror. Make sure top-level siblings are coherent\n slice = Slice.maxOpen(normalizeSiblings(slice.content, $context), false)\n\n view.someProp(\"transformPasted\", f => { slice = f(slice) })\n return slice\n}\n\n// Takes a slice parsed with parseSlice, which means there hasn't been\n// any content-expression checking done on the top nodes, tries to\n// find a parent node in the current context that might fit the nodes,\n// and if successful, rebuilds the slice so that it fits into that parent.\n//\n// This addresses the problem that Transform.replace expects a\n// coherent slice, and will fail to place a set of siblings that don't\n// fit anywhere in the schema.\nfunction normalizeSiblings(fragment, $context) {\n if (fragment.childCount < 2) return fragment\n for (let d = $context.depth; d >= 0; d--) {\n let parent = $context.node(d)\n let match = parent.contentMatchAt($context.index(d))\n let lastWrap, result = []\n fragment.forEach(node => {\n if (!result) return\n let wrap = match.findWrapping(node.type), inLast\n if (!wrap) return result = null\n if (inLast = result.length && lastWrap.length && addToSibling(wrap, lastWrap, node, result[result.length - 1], 0)) {\n result[result.length - 1] = inLast\n } else {\n if (result.length) result[result.length - 1] = closeRight(result[result.length - 1], lastWrap.length)\n let wrapped = withWrappers(node, wrap)\n result.push(wrapped)\n match = match.matchType(wrapped.type, wrapped.attrs)\n lastWrap = wrap\n }\n })\n if (result) return Fragment.from(result)\n }\n return fragment\n}\n\nfunction withWrappers(node, wrap, from = 0) {\n for (let i = wrap.length - 1; i >= from; i--)\n node = wrap[i].create(null, Fragment.from(node))\n return node\n}\n\n// Used to group adjacent nodes wrapped in similar parents by\n// normalizeSiblings into the same parent node\nfunction addToSibling(wrap, lastWrap, node, sibling, depth) {\n if (depth < wrap.length && depth < lastWrap.length && wrap[depth] == lastWrap[depth]) {\n let inner = addToSibling(wrap, lastWrap, node, sibling.lastChild, depth + 1)\n if (inner) return sibling.copy(sibling.content.replaceChild(sibling.childCount - 1, inner))\n let match = sibling.contentMatchAt(sibling.childCount)\n if (match.matchType(depth == wrap.length - 1 ? node.type : wrap[depth + 1]))\n return sibling.copy(sibling.content.append(Fragment.from(withWrappers(node, wrap, depth + 1))))\n }\n}\n\nfunction closeRight(node, depth) {\n if (depth == 0) return node\n let fragment = node.content.replaceChild(node.childCount - 1, closeRight(node.lastChild, depth - 1))\n let fill = node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true)\n return node.copy(fragment.append(fill))\n}\n\nfunction closeRange(fragment, side, from, to, depth, openEnd) {\n let node = side < 0 ? fragment.firstChild : fragment.lastChild, inner = node.content\n if (depth < to - 1) inner = closeRange(inner, side, from, to, depth + 1, openEnd)\n if (depth >= from)\n inner = side < 0 ? node.contentMatchAt(0).fillBefore(inner, fragment.childCount > 1 || openEnd <= depth).append(inner)\n : inner.append(node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true))\n return fragment.replaceChild(side < 0 ? 0 : fragment.childCount - 1, node.copy(inner))\n}\n\nfunction closeSlice(slice, openStart, openEnd) {\n if (openStart < slice.openStart)\n slice = new Slice(closeRange(slice.content, -1, openStart, slice.openStart, 0, slice.openEnd), openStart, slice.openEnd)\n if (openEnd < slice.openEnd)\n slice = new Slice(closeRange(slice.content, 1, openEnd, slice.openEnd, 0, 0), slice.openStart, openEnd)\n return slice\n}\n\n// Trick from jQuery -- some elements must be wrapped in other\n// elements for innerHTML to work. I.e. if you do `div.innerHTML =\n// \"..\"` the table cells are ignored.\nconst wrapMap = {thead: [\"table\"], colgroup: [\"table\"], col: [\"table\", \"colgroup\"],\n tr: [\"table\", \"tbody\"], td: [\"table\", \"tbody\", \"tr\"], th: [\"table\", \"tbody\", \"tr\"]}\n\nlet _detachedDoc = null\nfunction detachedDoc() {\n return _detachedDoc || (_detachedDoc = document.implementation.createHTMLDocument(\"title\"))\n}\n\nfunction readHTML(html) {\n let metas = /(\\s*]*>)*/.exec(html)\n if (metas) html = html.slice(metas[0].length)\n let elt = detachedDoc().createElement(\"div\")\n let firstTag = /(?:]*>)*<([a-z][^>\\s]+)/i.exec(html), wrap, depth = 0\n if (wrap = firstTag && wrapMap[firstTag[1].toLowerCase()]) {\n html = wrap.map(n => \"<\" + n + \">\").join(\"\") + html + wrap.map(n => \"\").reverse().join(\"\")\n depth = wrap.length\n }\n elt.innerHTML = html\n for (let i = 0; i < depth; i++) elt = elt.firstChild\n return elt\n}\n\nfunction addContext(slice, context) {\n if (!slice.size) return slice\n let schema = slice.content.firstChild.type.schema, array\n try { array = JSON.parse(context) }\n catch(e) { return slice }\n let {content, openStart, openEnd} = slice\n for (let i = array.length - 2; i >= 0; i -= 2) {\n let type = schema.nodes[array[i]]\n if (!type || type.hasRequiredAttrs()) break\n content = Fragment.from(type.create(array[i + 1], content))\n openStart++; openEnd++\n }\n return new Slice(content, openStart, openEnd)\n}\n","import browser from \"./browser\"\nimport {domIndex, isEquivalentPosition} from \"./dom\"\nimport {hasFocusAndSelection, hasSelection, selectionToDOM} from \"./selection\"\n\nconst observeOptions = {\n childList: true,\n characterData: true,\n characterDataOldValue: true,\n attributes: true,\n attributeOldValue: true,\n subtree: true\n}\n// IE11 has very broken mutation observers, so we also listen to DOMCharacterDataModified\nconst useCharData = browser.ie && browser.ie_version <= 11\n\nclass SelectionState {\n constructor() {\n this.anchorNode = this.anchorOffset = this.focusNode = this.focusOffset = null\n }\n\n set(sel) {\n this.anchorNode = sel.anchorNode; this.anchorOffset = sel.anchorOffset\n this.focusNode = sel.focusNode; this.focusOffset = sel.focusOffset\n }\n\n eq(sel) {\n return sel.anchorNode == this.anchorNode && sel.anchorOffset == this.anchorOffset &&\n sel.focusNode == this.focusNode && sel.focusOffset == this.focusOffset\n }\n}\n\nexport class DOMObserver {\n constructor(view, handleDOMChange) {\n this.view = view\n this.handleDOMChange = handleDOMChange\n this.queue = []\n this.flushingSoon = false\n this.observer = window.MutationObserver &&\n new window.MutationObserver(mutations => {\n for (let i = 0; i < mutations.length; i++) this.queue.push(mutations[i])\n // IE11 will sometimes (on backspacing out a single character\n // text node after a BR node) call the observer callback\n // before actually updating the DOM, which will cause\n // ProseMirror to miss the change (see #930)\n if (browser.ie && browser.ie_version <= 11 && mutations.some(\n m => m.type == \"childList\" && m.removedNodes.length ||\n m.type == \"characterData\" && m.oldValue.length > m.target.nodeValue.length))\n this.flushSoon()\n else\n this.flush()\n })\n this.currentSelection = new SelectionState\n if (useCharData) {\n this.onCharData = e => {\n this.queue.push({target: e.target, type: \"characterData\", oldValue: e.prevValue})\n this.flushSoon()\n }\n }\n this.onSelectionChange = this.onSelectionChange.bind(this)\n this.suppressingSelectionUpdates = false\n }\n\n flushSoon() {\n if (!this.flushingSoon) {\n this.flushingSoon = true\n window.setTimeout(() => { this.flushingSoon = false; this.flush() }, 20)\n }\n }\n\n start() {\n if (this.observer)\n this.observer.observe(this.view.dom, observeOptions)\n if (useCharData)\n this.view.dom.addEventListener(\"DOMCharacterDataModified\", this.onCharData)\n this.connectSelection()\n }\n\n stop() {\n if (this.observer) {\n let take = this.observer.takeRecords()\n if (take.length) {\n for (let i = 0; i < take.length; i++) this.queue.push(take[i])\n window.setTimeout(() => this.flush(), 20)\n }\n this.observer.disconnect()\n }\n if (useCharData) this.view.dom.removeEventListener(\"DOMCharacterDataModified\", this.onCharData)\n this.disconnectSelection()\n }\n\n connectSelection() {\n this.view.dom.ownerDocument.addEventListener(\"selectionchange\", this.onSelectionChange)\n }\n\n disconnectSelection() {\n this.view.dom.ownerDocument.removeEventListener(\"selectionchange\", this.onSelectionChange)\n }\n\n suppressSelectionUpdates() {\n this.suppressingSelectionUpdates = true\n setTimeout(() => this.suppressingSelectionUpdates = false, 50)\n }\n\n onSelectionChange() {\n if (!hasFocusAndSelection(this.view)) return\n if (this.suppressingSelectionUpdates) return selectionToDOM(this.view)\n // Deletions on IE11 fire their events in the wrong order, giving\n // us a selection change event before the DOM changes are\n // reported.\n if (browser.ie && browser.ie_version <= 11 && !this.view.state.selection.empty) {\n let sel = this.view.root.getSelection()\n // Selection.isCollapsed isn't reliable on IE\n if (sel.focusNode && isEquivalentPosition(sel.focusNode, sel.focusOffset, sel.anchorNode, sel.anchorOffset))\n return this.flushSoon()\n }\n this.flush()\n }\n\n setCurSelection() {\n this.currentSelection.set(this.view.root.getSelection())\n }\n\n ignoreSelectionChange(sel) {\n if (sel.rangeCount == 0) return true\n let container = sel.getRangeAt(0).commonAncestorContainer\n let desc = this.view.docView.nearestDesc(container)\n return desc && desc.ignoreMutation({type: \"selection\", target: container.nodeType == 3 ? container.parentNode : container})\n }\n\n flush() {\n if (!this.view.docView || this.flushingSoon) return\n let mutations = this.observer ? this.observer.takeRecords() : []\n if (this.queue.length) {\n mutations = this.queue.concat(mutations)\n this.queue.length = 0\n }\n\n let sel = this.view.root.getSelection()\n let newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasSelection(this.view) && !this.ignoreSelectionChange(sel)\n\n let from = -1, to = -1, typeOver = false, added = []\n if (this.view.editable) {\n for (let i = 0; i < mutations.length; i++) {\n let result = this.registerMutation(mutations[i], added)\n if (result) {\n from = from < 0 ? result.from : Math.min(result.from, from)\n to = to < 0 ? result.to : Math.max(result.to, to)\n if (result.typeOver && !this.view.composing) typeOver = true\n }\n }\n }\n\n if (browser.gecko && added.length > 1) {\n let brs = added.filter(n => n.nodeName == \"BR\")\n if (brs.length == 2) {\n let [a, b] = brs\n if (a.parentNode && a.parentNode.parentNode == b.parentNode) b.remove()\n else a.remove()\n }\n }\n\n if (from > -1 || newSel) {\n if (from > -1) {\n this.view.docView.markDirty(from, to)\n checkCSS(this.view)\n }\n this.handleDOMChange(from, to, typeOver)\n if (this.view.docView.dirty) this.view.updateState(this.view.state)\n else if (!this.currentSelection.eq(sel)) selectionToDOM(this.view)\n }\n }\n\n registerMutation(mut, added) {\n // Ignore mutations inside nodes that were already noted as inserted\n if (added.indexOf(mut.target) > -1) return null\n let desc = this.view.docView.nearestDesc(mut.target)\n if (mut.type == \"attributes\" &&\n (desc == this.view.docView || mut.attributeName == \"contenteditable\" ||\n // Firefox sometimes fires spurious events for null/empty styles\n (mut.attributeName == \"style\" && !mut.oldValue && !mut.target.getAttribute(\"style\"))))\n return null\n if (!desc || desc.ignoreMutation(mut)) return null\n\n if (mut.type == \"childList\") {\n let prev = mut.previousSibling, next = mut.nextSibling\n if (browser.ie && browser.ie_version <= 11 && mut.addedNodes.length) {\n // IE11 gives us incorrect next/prev siblings for some\n // insertions, so if there are added nodes, recompute those\n for (let i = 0; i < mut.addedNodes.length; i++) {\n let {previousSibling, nextSibling} = mut.addedNodes[i]\n if (!previousSibling || Array.prototype.indexOf.call(mut.addedNodes, previousSibling) < 0) prev = previousSibling\n if (!nextSibling || Array.prototype.indexOf.call(mut.addedNodes, nextSibling) < 0) next = nextSibling\n }\n }\n let fromOffset = prev && prev.parentNode == mut.target\n ? domIndex(prev) + 1 : 0\n let from = desc.localPosFromDOM(mut.target, fromOffset, -1)\n let toOffset = next && next.parentNode == mut.target\n ? domIndex(next) : mut.target.childNodes.length\n for (let i = 0; i < mut.addedNodes.length; i++) added.push(mut.addedNodes[i])\n let to = desc.localPosFromDOM(mut.target, toOffset, 1)\n return {from, to}\n } else if (mut.type == \"attributes\") {\n return {from: desc.posAtStart - desc.border, to: desc.posAtEnd + desc.border}\n } else { // \"characterData\"\n return {\n from: desc.posAtStart,\n to: desc.posAtEnd,\n // An event was generated for a text change that didn't change\n // any text. Mark the dom change to fall back to assuming the\n // selection was typed over with an identical value if it can't\n // find another change.\n typeOver: mut.target.nodeValue == mut.oldValue\n }\n }\n }\n}\n\nlet cssChecked = false\n\nfunction checkCSS(view) {\n if (cssChecked) return\n cssChecked = true\n if (getComputedStyle(view.dom).whiteSpace == \"normal\")\n console[\"warn\"](\"ProseMirror expects the CSS white-space property to be set, preferably to 'pre-wrap'. It is recommended to load style/prosemirror.css from the prosemirror-view package.\")\n}\n","import {Selection, NodeSelection, TextSelection} from \"prosemirror-state\"\nimport {dropPoint} from \"prosemirror-transform\"\nimport {Slice} from \"prosemirror-model\"\n\nimport browser from \"./browser\"\nimport {captureKeyDown} from \"./capturekeys\"\nimport {readDOMChange} from \"./domchange\"\nimport {parseFromClipboard, serializeForClipboard} from \"./clipboard\"\nimport {DOMObserver} from \"./domobserver\"\nimport {selectionBetween} from \"./selection\"\nimport {keyEvent} from \"./dom\"\n\n// A collection of DOM events that occur within the editor, and callback functions\n// to invoke when the event fires.\nconst handlers = {}, editHandlers = {}\n\nexport function initInput(view) {\n view.shiftKey = false\n view.mouseDown = null\n view.lastKeyCode = null\n view.lastKeyCodeTime = 0\n view.lastClick = {time: 0, x: 0, y: 0, type: \"\"}\n view.lastSelectionOrigin = null\n view.lastSelectionTime = 0\n\n view.composing = false\n view.composingTimeout = null\n view.compositionNodes = []\n view.compositionEndedAt = -2e8\n\n view.domObserver = new DOMObserver(view, (from, to, typeOver) => readDOMChange(view, from, to, typeOver))\n view.domObserver.start()\n // Used by hacks like the beforeinput handler to check whether anything happened in the DOM\n view.domChangeCount = 0\n\n view.eventHandlers = Object.create(null)\n for (let event in handlers) {\n let handler = handlers[event]\n view.dom.addEventListener(event, view.eventHandlers[event] = event => {\n if (eventBelongsToView(view, event) && !runCustomHandler(view, event) &&\n (view.editable || !(event.type in editHandlers)))\n handler(view, event)\n })\n }\n // On Safari, for reasons beyond my understanding, adding an input\n // event handler makes an issue where the composition vanishes when\n // you press enter go away.\n if (browser.safari) view.dom.addEventListener(\"input\", () => null)\n\n ensureListeners(view)\n}\n\nfunction setSelectionOrigin(view, origin) {\n view.lastSelectionOrigin = origin\n view.lastSelectionTime = Date.now()\n}\n\nexport function destroyInput(view) {\n view.domObserver.stop()\n for (let type in view.eventHandlers)\n view.dom.removeEventListener(type, view.eventHandlers[type])\n clearTimeout(view.composingTimeout)\n}\n\nexport function ensureListeners(view) {\n view.someProp(\"handleDOMEvents\", currentHandlers => {\n for (let type in currentHandlers) if (!view.eventHandlers[type])\n view.dom.addEventListener(type, view.eventHandlers[type] = event => runCustomHandler(view, event))\n })\n}\n\nfunction runCustomHandler(view, event) {\n return view.someProp(\"handleDOMEvents\", handlers => {\n let handler = handlers[event.type]\n return handler ? handler(view, event) || event.defaultPrevented : false\n })\n}\n\nfunction eventBelongsToView(view, event) {\n if (!event.bubbles) return true\n if (event.defaultPrevented) return false\n for (let node = event.target; node != view.dom; node = node.parentNode)\n if (!node || node.nodeType == 11 ||\n (node.pmViewDesc && node.pmViewDesc.stopEvent(event)))\n return false\n return true\n}\n\nexport function dispatchEvent(view, event) {\n if (!runCustomHandler(view, event) && handlers[event.type] &&\n (view.editable || !(event.type in editHandlers)))\n handlers[event.type](view, event)\n}\n\neditHandlers.keydown = (view, event) => {\n view.shiftKey = event.keyCode == 16 || event.shiftKey\n if (inOrNearComposition(view, event)) return\n view.lastKeyCode = event.keyCode\n view.lastKeyCodeTime = Date.now()\n if (view.someProp(\"handleKeyDown\", f => f(view, event)) || captureKeyDown(view, event))\n event.preventDefault()\n else\n setSelectionOrigin(view, \"key\")\n}\n\neditHandlers.keyup = (view, e) => {\n if (e.keyCode == 16) view.shiftKey = false\n}\n\neditHandlers.keypress = (view, event) => {\n if (inOrNearComposition(view, event) || !event.charCode ||\n event.ctrlKey && !event.altKey || browser.mac && event.metaKey) return\n\n if (view.someProp(\"handleKeyPress\", f => f(view, event))) {\n event.preventDefault()\n return\n }\n\n let sel = view.state.selection\n if (!(sel instanceof TextSelection) || !sel.$from.sameParent(sel.$to)) {\n let text = String.fromCharCode(event.charCode)\n if (!view.someProp(\"handleTextInput\", f => f(view, sel.$from.pos, sel.$to.pos, text)))\n view.dispatch(view.state.tr.insertText(text).scrollIntoView())\n event.preventDefault()\n }\n}\n\nfunction eventCoords(event) { return {left: event.clientX, top: event.clientY} }\n\nfunction isNear(event, click) {\n let dx = click.x - event.clientX, dy = click.y - event.clientY\n return dx * dx + dy * dy < 100\n}\n\nfunction runHandlerOnContext(view, propName, pos, inside, event) {\n if (inside == -1) return false\n let $pos = view.state.doc.resolve(inside)\n for (let i = $pos.depth + 1; i > 0; i--) {\n if (view.someProp(propName, f => i > $pos.depth ? f(view, pos, $pos.nodeAfter, $pos.before(i), event, true)\n : f(view, pos, $pos.node(i), $pos.before(i), event, false)))\n return true\n }\n return false\n}\n\nfunction updateSelection(view, selection, origin) {\n if (!view.focused) view.focus()\n let tr = view.state.tr.setSelection(selection)\n if (origin == \"pointer\") tr.setMeta(\"pointer\", true)\n view.dispatch(tr)\n}\n\nfunction selectClickedLeaf(view, inside) {\n if (inside == -1) return false\n let $pos = view.state.doc.resolve(inside), node = $pos.nodeAfter\n if (node && node.isAtom && NodeSelection.isSelectable(node)) {\n updateSelection(view, new NodeSelection($pos), \"pointer\")\n return true\n }\n return false\n}\n\nfunction selectClickedNode(view, inside) {\n if (inside == -1) return false\n let sel = view.state.selection, selectedNode, selectAt\n if (sel instanceof NodeSelection) selectedNode = sel.node\n\n let $pos = view.state.doc.resolve(inside)\n for (let i = $pos.depth + 1; i > 0; i--) {\n let node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i)\n if (NodeSelection.isSelectable(node)) {\n if (selectedNode && sel.$from.depth > 0 &&\n i >= sel.$from.depth && $pos.before(sel.$from.depth + 1) == sel.$from.pos)\n selectAt = $pos.before(sel.$from.depth)\n else\n selectAt = $pos.before(i)\n break\n }\n }\n\n if (selectAt != null) {\n updateSelection(view, NodeSelection.create(view.state.doc, selectAt), \"pointer\")\n return true\n } else {\n return false\n }\n}\n\nfunction handleSingleClick(view, pos, inside, event, selectNode) {\n return runHandlerOnContext(view, \"handleClickOn\", pos, inside, event) ||\n view.someProp(\"handleClick\", f => f(view, pos, event)) ||\n (selectNode ? selectClickedNode(view, inside) : selectClickedLeaf(view, inside))\n}\n\nfunction handleDoubleClick(view, pos, inside, event) {\n return runHandlerOnContext(view, \"handleDoubleClickOn\", pos, inside, event) ||\n view.someProp(\"handleDoubleClick\", f => f(view, pos, event))\n}\n\nfunction handleTripleClick(view, pos, inside, event) {\n return runHandlerOnContext(view, \"handleTripleClickOn\", pos, inside, event) ||\n view.someProp(\"handleTripleClick\", f => f(view, pos, event)) ||\n defaultTripleClick(view, inside)\n}\n\nfunction defaultTripleClick(view, inside) {\n let doc = view.state.doc\n if (inside == -1) {\n if (doc.inlineContent) {\n updateSelection(view, TextSelection.create(doc, 0, doc.content.size), \"pointer\")\n return true\n }\n return false\n }\n\n let $pos = doc.resolve(inside)\n for (let i = $pos.depth + 1; i > 0; i--) {\n let node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i)\n let nodePos = $pos.before(i)\n if (node.inlineContent)\n updateSelection(view, TextSelection.create(doc, nodePos + 1, nodePos + 1 + node.content.size), \"pointer\")\n else if (NodeSelection.isSelectable(node))\n updateSelection(view, NodeSelection.create(doc, nodePos), \"pointer\")\n else\n continue\n return true\n }\n}\n\nfunction forceDOMFlush(view) {\n return endComposition(view)\n}\n\nconst selectNodeModifier = browser.mac ? \"metaKey\" : \"ctrlKey\"\n\nhandlers.mousedown = (view, event) => {\n view.shiftKey = event.shiftKey\n let flushed = forceDOMFlush(view)\n let now = Date.now(), type = \"singleClick\"\n if (now - view.lastClick.time < 500 && isNear(event, view.lastClick) && !event[selectNodeModifier]) {\n if (view.lastClick.type == \"singleClick\") type = \"doubleClick\"\n else if (view.lastClick.type == \"doubleClick\") type = \"tripleClick\"\n }\n view.lastClick = {time: now, x: event.clientX, y: event.clientY, type}\n\n let pos = view.posAtCoords(eventCoords(event))\n if (!pos) return\n\n if (type == \"singleClick\")\n view.mouseDown = new MouseDown(view, pos, event, flushed)\n else if ((type == \"doubleClick\" ? handleDoubleClick : handleTripleClick)(view, pos.pos, pos.inside, event))\n event.preventDefault()\n else\n setSelectionOrigin(view, \"pointer\")\n}\n\nclass MouseDown {\n constructor(view, pos, event, flushed) {\n this.view = view\n this.startDoc = view.state.doc\n this.pos = pos\n this.event = event\n this.flushed = flushed\n this.selectNode = event[selectNodeModifier]\n this.allowDefault = event.shiftKey\n\n let targetNode, targetPos\n if (pos.inside > -1) {\n targetNode = view.state.doc.nodeAt(pos.inside)\n targetPos = pos.inside\n } else {\n let $pos = view.state.doc.resolve(pos.pos)\n targetNode = $pos.parent\n targetPos = $pos.depth ? $pos.before() : 0\n }\n\n this.mightDrag = null\n\n const target = flushed ? null : event.target\n const targetDesc = target ? view.docView.nearestDesc(target, true) : null\n this.target = targetDesc ? targetDesc.dom : null\n\n if (targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false ||\n view.state.selection instanceof NodeSelection && targetPos == view.state.selection.from)\n this.mightDrag = {node: targetNode,\n pos: targetPos,\n addAttr: this.target && !this.target.draggable,\n setUneditable: this.target && browser.gecko && !this.target.hasAttribute(\"contentEditable\")}\n\n if (this.target && this.mightDrag && (this.mightDrag.addAttr || this.mightDrag.setUneditable)) {\n this.view.domObserver.stop()\n if (this.mightDrag.addAttr) this.target.draggable = true\n if (this.mightDrag.setUneditable)\n setTimeout(() => this.target.setAttribute(\"contentEditable\", \"false\"), 20)\n this.view.domObserver.start()\n }\n\n view.root.addEventListener(\"mouseup\", this.up = this.up.bind(this))\n view.root.addEventListener(\"mousemove\", this.move = this.move.bind(this))\n setSelectionOrigin(view, \"pointer\")\n }\n\n done() {\n this.view.root.removeEventListener(\"mouseup\", this.up)\n this.view.root.removeEventListener(\"mousemove\", this.move)\n if (this.mightDrag && this.target) {\n this.view.domObserver.stop()\n if (this.mightDrag.addAttr) this.target.draggable = false\n if (this.mightDrag.setUneditable) this.target.removeAttribute(\"contentEditable\")\n this.view.domObserver.start()\n }\n this.view.mouseDown = null\n }\n\n up(event) {\n this.done()\n\n if (!this.view.dom.contains(event.target.nodeType == 3 ? event.target.parentNode : event.target))\n return\n\n let pos = this.pos\n if (this.view.state.doc != this.startDoc) pos = this.view.posAtCoords(eventCoords(event))\n\n if (this.allowDefault || !pos) {\n setSelectionOrigin(this.view, \"pointer\")\n } else if (handleSingleClick(this.view, pos.pos, pos.inside, event, this.selectNode)) {\n event.preventDefault()\n } else if (this.flushed ||\n // Chrome will sometimes treat a node selection as a\n // cursor, but still report that the node is selected\n // when asked through getSelection. You'll then get a\n // situation where clicking at the point where that\n // (hidden) cursor is doesn't change the selection, and\n // thus doesn't get a reaction from ProseMirror. This\n // works around that.\n (browser.chrome && !(this.view.state.selection instanceof TextSelection) &&\n (pos.pos == this.view.state.selection.from || pos.pos == this.view.state.selection.to))) {\n updateSelection(this.view, Selection.near(this.view.state.doc.resolve(pos.pos)), \"pointer\")\n event.preventDefault()\n } else {\n setSelectionOrigin(this.view, \"pointer\")\n }\n }\n\n move(event) {\n if (!this.allowDefault && (Math.abs(this.event.x - event.clientX) > 4 ||\n Math.abs(this.event.y - event.clientY) > 4))\n this.allowDefault = true\n setSelectionOrigin(this.view, \"pointer\")\n }\n}\n\nhandlers.touchdown = view => {\n forceDOMFlush(view)\n setSelectionOrigin(view, \"pointer\")\n}\n\nhandlers.contextmenu = view => forceDOMFlush(view)\n\nfunction inOrNearComposition(view, event) {\n if (view.composing) return true\n // See https://www.stum.de/2016/06/24/handling-ime-events-in-javascript/.\n // On Japanese input method editors (IMEs), the Enter key is used to confirm character\n // selection. On Safari, when Enter is pressed, compositionend and keydown events are\n // emitted. The keydown event triggers newline insertion, which we don't want.\n // This method returns true if the keydown event should be ignored.\n // We only ignore it once, as pressing Enter a second time *should* insert a newline.\n // Furthermore, the keydown event timestamp must be close to the compositionEndedAt timestamp.\n // This guards against the case where compositionend is triggered without the keyboard\n // (e.g. character confirmation may be done with the mouse), and keydown is triggered\n // afterwards- we wouldn't want to ignore the keydown event in this case.\n if (browser.safari && Math.abs(event.timeStamp - view.compositionEndedAt) < 500) {\n view.compositionEndedAt = -2e8\n return true\n }\n return false\n}\n\n// Drop active composition after 5 seconds of inactivity on Android\nconst timeoutComposition = browser.android ? 5000 : -1\n\neditHandlers.compositionstart = editHandlers.compositionupdate = view => {\n if (!view.composing) {\n view.domObserver.flush()\n let {state} = view, $pos = state.selection.$from\n if (state.selection.empty &&\n (state.storedMarks || (!$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some(m => m.type.spec.inclusive === false)))) {\n // Need to wrap the cursor in mark nodes different from the ones in the DOM context\n view.markCursor = view.state.storedMarks || $pos.marks()\n endComposition(view, true)\n view.markCursor = null\n } else {\n endComposition(view)\n // In firefox, if the cursor is after but outside a marked node,\n // the inserted text won't inherit the marks. So this moves it\n // inside if necessary.\n if (browser.gecko && state.selection.empty && $pos.parentOffset && !$pos.textOffset && $pos.nodeBefore.marks.length) {\n let sel = view.root.getSelection()\n for (let node = sel.focusNode, offset = sel.focusOffset; node && node.nodeType == 1 && offset != 0;) {\n let before = offset < 0 ? node.lastChild : node.childNodes[offset - 1]\n if (before.nodeType == 3) {\n sel.collapse(before, before.nodeValue.length)\n break\n } else {\n node = before\n offset = -1\n }\n }\n }\n }\n view.composing = true\n }\n scheduleComposeEnd(view, timeoutComposition)\n}\n\neditHandlers.compositionend = (view, event) => {\n if (view.composing) {\n view.composing = false\n view.compositionEndedAt = event.timeStamp\n scheduleComposeEnd(view, 20)\n }\n}\n\nfunction scheduleComposeEnd(view, delay) {\n clearTimeout(view.composingTimeout)\n if (delay > -1) view.composingTimeout = setTimeout(() => endComposition(view), delay)\n}\n\nexport function endComposition(view, forceUpdate) {\n view.composing = false\n while (view.compositionNodes.length > 0) view.compositionNodes.pop().markParentsDirty()\n if (forceUpdate || view.docView.dirty) {\n view.updateState(view.state)\n return true\n }\n return false\n}\n\nfunction captureCopy(view, dom) {\n // The extra wrapper is somehow necessary on IE/Edge to prevent the\n // content from being mangled when it is put onto the clipboard\n let doc = view.dom.ownerDocument\n let wrap = doc.body.appendChild(doc.createElement(\"div\"))\n wrap.appendChild(dom)\n wrap.style.cssText = \"position: fixed; left: -10000px; top: 10px\"\n let sel = getSelection(), range = doc.createRange()\n range.selectNodeContents(dom)\n // Done because IE will fire a selectionchange moving the selection\n // to its start when removeAllRanges is called and the editor still\n // has focus (which will mess up the editor's selection state).\n view.dom.blur()\n sel.removeAllRanges()\n sel.addRange(range)\n setTimeout(() => {\n doc.body.removeChild(wrap)\n view.focus()\n }, 50)\n}\n\n// This is very crude, but unfortunately both these browsers _pretend_\n// that they have a clipboard API—all the objects and methods are\n// there, they just don't work, and they are hard to test.\nconst brokenClipboardAPI = (browser.ie && browser.ie_version < 15) ||\n (browser.ios && browser.webkit_version < 604)\n\nhandlers.copy = editHandlers.cut = (view, e) => {\n let sel = view.state.selection, cut = e.type == \"cut\"\n if (sel.empty) return\n\n // IE and Edge's clipboard interface is completely broken\n let data = brokenClipboardAPI ? null : e.clipboardData\n let slice = sel.content(), {dom, text} = serializeForClipboard(view, slice)\n if (data) {\n e.preventDefault()\n data.clearData()\n data.setData(\"text/html\", dom.innerHTML)\n data.setData(\"text/plain\", text)\n } else {\n captureCopy(view, dom)\n }\n if (cut) view.dispatch(view.state.tr.deleteSelection().scrollIntoView().setMeta(\"uiEvent\", \"cut\"))\n}\n\nfunction sliceSingleNode(slice) {\n return slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1 ? slice.content.firstChild : null\n}\n\nfunction capturePaste(view, e) {\n let doc = view.dom.ownerDocument\n let plainText = view.shiftKey || view.state.selection.$from.parent.type.spec.code\n let target = doc.body.appendChild(doc.createElement(plainText ? \"textarea\" : \"div\"))\n if (!plainText) target.contentEditable = \"true\"\n target.style.cssText = \"position: fixed; left: -10000px; top: 10px\"\n target.focus()\n setTimeout(() => {\n view.focus()\n doc.body.removeChild(target)\n if (plainText) doPaste(view, target.value, null, e)\n else doPaste(view, target.textContent, target.innerHTML, e)\n }, 50)\n}\n\nfunction doPaste(view, text, html, e) {\n let slice = parseFromClipboard(view, text, html, view.shiftKey, view.state.selection.$from)\n if (view.someProp(\"handlePaste\", f => f(view, e, slice || Slice.empty)) || !slice) return\n\n let singleNode = sliceSingleNode(slice)\n let tr = singleNode ? view.state.tr.replaceSelectionWith(singleNode, view.shiftKey) : view.state.tr.replaceSelection(slice)\n view.dispatch(tr.scrollIntoView().setMeta(\"paste\", true).setMeta(\"uiEvent\", \"paste\"))\n}\n\neditHandlers.paste = (view, e) => {\n let data = brokenClipboardAPI ? null : e.clipboardData\n let html = data && data.getData(\"text/html\"), text = data && data.getData(\"text/plain\")\n if (data && (html || text || data.files.length)) {\n doPaste(view, text, html, e)\n e.preventDefault()\n } else {\n capturePaste(view, e)\n }\n}\n\nclass Dragging {\n constructor(slice, move) {\n this.slice = slice\n this.move = move\n }\n}\n\nconst dragCopyModifier = browser.mac ? \"altKey\" : \"ctrlKey\"\n\nhandlers.dragstart = (view, e) => {\n let mouseDown = view.mouseDown\n if (mouseDown) mouseDown.done()\n if (!e.dataTransfer) return\n\n let sel = view.state.selection\n let pos = sel.empty ? null : view.posAtCoords(eventCoords(e))\n if (pos && pos.pos >= sel.from && pos.pos <= (sel instanceof NodeSelection ? sel.to - 1: sel.to)) {\n // In selection\n } else if (mouseDown && mouseDown.mightDrag) {\n view.dispatch(view.state.tr.setSelection(NodeSelection.create(view.state.doc, mouseDown.mightDrag.pos)))\n } else if (e.target && e.target.nodeType == 1) {\n let desc = view.docView.nearestDesc(e.target, true)\n if (!desc || !desc.node.type.spec.draggable || desc == view.docView) return\n view.dispatch(view.state.tr.setSelection(NodeSelection.create(view.state.doc, desc.posBefore)))\n }\n let slice = view.state.selection.content(), {dom, text} = serializeForClipboard(view, slice)\n e.dataTransfer.clearData()\n e.dataTransfer.setData(brokenClipboardAPI ? \"Text\" : \"text/html\", dom.innerHTML)\n if (!brokenClipboardAPI) e.dataTransfer.setData(\"text/plain\", text)\n view.dragging = new Dragging(slice, !e[dragCopyModifier])\n}\n\nhandlers.dragend = view => {\n window.setTimeout(() => view.dragging = null, 50)\n}\n\neditHandlers.dragover = editHandlers.dragenter = (_, e) => e.preventDefault()\n\neditHandlers.drop = (view, e) => {\n let dragging = view.dragging\n view.dragging = null\n\n if (!e.dataTransfer) return\n\n let eventPos = view.posAtCoords(eventCoords(e))\n if (!eventPos) return\n let $mouse = view.state.doc.resolve(eventPos.pos)\n if (!$mouse) return\n let slice = dragging && dragging.slice ||\n parseFromClipboard(view, e.dataTransfer.getData(brokenClipboardAPI ? \"Text\" : \"text/plain\"),\n brokenClipboardAPI ? null : e.dataTransfer.getData(\"text/html\"), false, $mouse)\n if (!slice) return\n\n e.preventDefault()\n if (view.someProp(\"handleDrop\", f => f(view, e, slice, dragging && dragging.move))) return\n let insertPos = slice ? dropPoint(view.state.doc, $mouse.pos, slice) : $mouse.pos\n if (insertPos == null) insertPos = $mouse.pos\n\n let tr = view.state.tr\n if (dragging && dragging.move) tr.deleteSelection()\n\n let pos = tr.mapping.map(insertPos)\n let isNode = slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1\n let beforeInsert = tr.doc\n if (isNode)\n tr.replaceRangeWith(pos, pos, slice.content.firstChild)\n else\n tr.replaceRange(pos, pos, slice)\n if (tr.doc.eq(beforeInsert)) return\n\n let $pos = tr.doc.resolve(pos)\n if (isNode && NodeSelection.isSelectable(slice.content.firstChild) &&\n $pos.nodeAfter && $pos.nodeAfter.sameMarkup(slice.content.firstChild))\n tr.setSelection(new NodeSelection($pos))\n else\n tr.setSelection(selectionBetween(view, $pos, tr.doc.resolve(tr.mapping.map(insertPos))))\n view.focus()\n view.dispatch(tr.setMeta(\"uiEvent\", \"drop\"))\n}\n\nhandlers.focus = view => {\n if (!view.focused) {\n view.domObserver.stop()\n view.dom.classList.add(\"ProseMirror-focused\")\n view.domObserver.start()\n view.focused = true\n }\n}\n\nhandlers.blur = view => {\n if (view.focused) {\n view.domObserver.stop()\n view.dom.classList.remove(\"ProseMirror-focused\")\n view.domObserver.start()\n view.domObserver.currentSelection.set({})\n view.focused = false\n }\n}\n\nhandlers.beforeinput = (view, event) => {\n // We should probably do more with beforeinput events, but support\n // is so spotty that I'm still waiting to see where they are going.\n\n // Very specific hack to deal with backspace sometimes failing on\n // Chrome Android when after an uneditable node.\n if (browser.chrome && browser.android && event.inputType == \"deleteContentBackward\") {\n let {domChangeCount} = view\n setTimeout(() => {\n if (view.domChangeCount != domChangeCount) return // Event already had some effect\n // This bug tends to close the virtual keyboard, so we refocus\n view.dom.blur()\n view.focus()\n if (view.someProp(\"handleKeyDown\", f => f(view, keyEvent(8, \"Backspace\")))) return\n let {$cursor} = view.state.selection\n // Crude approximation of backspace behavior when no command handled it\n if ($cursor && $cursor.pos > 0) view.dispatch(view.state.tr.delete($cursor.pos - 1, $cursor.pos).scrollIntoView())\n }, 50)\n }\n}\n\n// Make sure all handlers get registered\nfor (let prop in editHandlers) handlers[prop] = editHandlers[prop]\n","function compareObjs(a, b) {\n if (a == b) return true\n for (let p in a) if (a[p] !== b[p]) return false\n for (let p in b) if (!(p in a)) return false\n return true\n}\n\nclass WidgetType {\n constructor(toDOM, spec) {\n this.spec = spec || noSpec\n this.side = this.spec.side || 0\n this.toDOM = toDOM\n }\n\n map(mapping, span, offset, oldOffset) {\n let {pos, deleted} = mapping.mapResult(span.from + oldOffset, this.side < 0 ? -1 : 1)\n return deleted ? null : new Decoration(pos - offset, pos - offset, this)\n }\n\n valid() { return true }\n\n eq(other) {\n return this == other ||\n (other instanceof WidgetType &&\n (this.spec.key && this.spec.key == other.spec.key ||\n this.toDOM == other.toDOM && compareObjs(this.spec, other.spec)))\n }\n}\n\nclass InlineType {\n constructor(attrs, spec) {\n this.spec = spec || noSpec\n this.attrs = attrs\n }\n\n map(mapping, span, offset, oldOffset) {\n let from = mapping.map(span.from + oldOffset, this.spec.inclusiveStart ? -1 : 1) - offset\n let to = mapping.map(span.to + oldOffset, this.spec.inclusiveEnd ? 1 : -1) - offset\n return from >= to ? null : new Decoration(from, to, this)\n }\n\n valid(_, span) { return span.from < span.to }\n\n eq(other) {\n return this == other ||\n (other instanceof InlineType && compareObjs(this.attrs, other.attrs) &&\n compareObjs(this.spec, other.spec))\n }\n\n static is(span) { return span.type instanceof InlineType }\n}\n\nclass NodeType {\n constructor(attrs, spec) {\n this.spec = spec || noSpec\n this.attrs = attrs\n }\n\n map(mapping, span, offset, oldOffset) {\n let from = mapping.mapResult(span.from + oldOffset, 1)\n if (from.deleted) return null\n let to = mapping.mapResult(span.to + oldOffset, -1)\n if (to.deleted || to.pos <= from.pos) return null\n return new Decoration(from.pos - offset, to.pos - offset, this)\n }\n\n valid(node, span) {\n let {index, offset} = node.content.findIndex(span.from)\n return offset == span.from && offset + node.child(index).nodeSize == span.to\n }\n\n eq(other) {\n return this == other ||\n (other instanceof NodeType && compareObjs(this.attrs, other.attrs) &&\n compareObjs(this.spec, other.spec))\n }\n}\n\n// ::- Decoration objects can be provided to the view through the\n// [`decorations` prop](#view.EditorProps.decorations). They come in\n// several variants—see the static members of this class for details.\nexport class Decoration {\n constructor(from, to, type) {\n // :: number\n // The start position of the decoration.\n this.from = from\n // :: number\n // The end position. Will be the same as `from` for [widget\n // decorations](#view.Decoration^widget).\n this.to = to\n this.type = type\n }\n\n copy(from, to) {\n return new Decoration(from, to, this.type)\n }\n\n eq(other) {\n return this.type.eq(other.type) && this.from == other.from && this.to == other.to\n }\n\n map(mapping, offset, oldOffset) {\n return this.type.map(mapping, this, offset, oldOffset)\n }\n\n // :: (number, union<(view: EditorView, getPos: () → number) → dom.Node, dom.Node>, ?Object) → Decoration\n // Creates a widget decoration, which is a DOM node that's shown in\n // the document at the given position. It is recommended that you\n // delay rendering the widget by passing a function that will be\n // called when the widget is actually drawn in a view, but you can\n // also directly pass a DOM node. `getPos` can be used to find the\n // widget's current document position.\n //\n // spec::- These options are supported:\n //\n // side:: ?number\n // Controls which side of the document position this widget is\n // associated with. When negative, it is drawn before a cursor\n // at its position, and content inserted at that position ends\n // up after the widget. When zero (the default) or positive, the\n // widget is drawn after the cursor and content inserted there\n // ends up before the widget.\n //\n // When there are multiple widgets at a given position, their\n // `side` values determine the order in which they appear. Those\n // with lower values appear first. The ordering of widgets with\n // the same `side` value is unspecified.\n //\n // When `marks` is null, `side` also determines the marks that\n // the widget is wrapped in—those of the node before when\n // negative, those of the node after when positive.\n //\n // marks:: ?[Mark]\n // The precise set of marks to draw around the widget.\n //\n // stopEvent:: ?(event: dom.Event) → bool\n // Can be used to control which DOM events, when they bubble out\n // of this widget, the editor view should ignore.\n //\n // key:: ?string\n // When comparing decorations of this type (in order to decide\n // whether it needs to be redrawn), ProseMirror will by default\n // compare the widget DOM node by identity. If you pass a key,\n // that key will be compared instead, which can be useful when\n // you generate decorations on the fly and don't want to store\n // and reuse DOM nodes. Make sure that any widgets with the same\n // key are interchangeable—if widgets differ in, for example,\n // the behavior of some event handler, they should get\n // different keys.\n static widget(pos, toDOM, spec) {\n return new Decoration(pos, pos, new WidgetType(toDOM, spec))\n }\n\n // :: (number, number, DecorationAttrs, ?Object) → Decoration\n // Creates an inline decoration, which adds the given attributes to\n // each inline node between `from` and `to`.\n //\n // spec::- These options are recognized:\n //\n // inclusiveStart:: ?bool\n // Determines how the left side of the decoration is\n // [mapped](#transform.Position_Mapping) when content is\n // inserted directly at that position. By default, the decoration\n // won't include the new content, but you can set this to `true`\n // to make it inclusive.\n //\n // inclusiveEnd:: ?bool\n // Determines how the right side of the decoration is mapped.\n // See\n // [`inclusiveStart`](#view.Decoration^inline^spec.inclusiveStart).\n static inline(from, to, attrs, spec) {\n return new Decoration(from, to, new InlineType(attrs, spec))\n }\n\n // :: (number, number, DecorationAttrs, ?Object) → Decoration\n // Creates a node decoration. `from` and `to` should point precisely\n // before and after a node in the document. That node, and only that\n // node, will receive the given attributes.\n //\n // spec::-\n //\n // Optional information to store with the decoration. It\n // is also used when comparing decorators for equality.\n static node(from, to, attrs, spec) {\n return new Decoration(from, to, new NodeType(attrs, spec))\n }\n\n // :: Object\n // The spec provided when creating this decoration. Can be useful\n // if you've stored extra information in that object.\n get spec() { return this.type.spec }\n}\n\n// DecorationAttrs:: interface\n// A set of attributes to add to a decorated node. Most properties\n// simply directly correspond to DOM attributes of the same name,\n// which will be set to the property's value. These are exceptions:\n//\n// class:: ?string\n// A CSS class name or a space-separated set of class names to be\n// _added_ to the classes that the node already had.\n//\n// style:: ?string\n// A string of CSS to be _added_ to the node's existing `style` property.\n//\n// nodeName:: ?string\n// When non-null, the target node is wrapped in a DOM element of\n// this type (and the other attributes are applied to this element).\n\nconst none = [], noSpec = {}\n\n// ::- A collection of [decorations](#view.Decoration), organized in\n// such a way that the drawing algorithm can efficiently use and\n// compare them. This is a persistent data structure—it is not\n// modified, updates create a new value.\nexport class DecorationSet {\n constructor(local, children) {\n this.local = local && local.length ? local : none\n this.children = children && children.length ? children : none\n }\n\n // :: (Node, [Decoration]) → DecorationSet\n // Create a set of decorations, using the structure of the given\n // document.\n static create(doc, decorations) {\n return decorations.length ? buildTree(decorations, doc, 0, noSpec) : empty\n }\n\n // :: (?number, ?number, ?(spec: Object) → bool) → [Decoration]\n // Find all decorations in this set which touch the given range\n // (including decorations that start or end directly at the\n // boundaries) and match the given predicate on their spec. When\n // `start` and `end` are omitted, all decorations in the set are\n // considered. When `predicate` isn't given, all decorations are\n // assumed to match.\n find(start, end, predicate) {\n let result = []\n this.findInner(start == null ? 0 : start, end == null ? 1e9 : end, result, 0, predicate)\n return result\n }\n\n findInner(start, end, result, offset, predicate) {\n for (let i = 0; i < this.local.length; i++) {\n let span = this.local[i]\n if (span.from <= end && span.to >= start && (!predicate || predicate(span.spec)))\n result.push(span.copy(span.from + offset, span.to + offset))\n }\n for (let i = 0; i < this.children.length; i += 3) {\n if (this.children[i] < end && this.children[i + 1] > start) {\n let childOff = this.children[i] + 1\n this.children[i + 2].findInner(start - childOff, end - childOff, result, offset + childOff, predicate)\n }\n }\n }\n\n // :: (Mapping, Node, ?Object) → DecorationSet\n // Map the set of decorations in response to a change in the\n // document.\n //\n // options::- An optional set of options.\n //\n // onRemove:: ?(decorationSpec: Object)\n // When given, this function will be called for each decoration\n // that gets dropped as a result of the mapping, passing the\n // spec of that decoration.\n map(mapping, doc, options) {\n if (this == empty || mapping.maps.length == 0) return this\n return this.mapInner(mapping, doc, 0, 0, options || noSpec)\n }\n\n mapInner(mapping, node, offset, oldOffset, options) {\n let newLocal\n for (let i = 0; i < this.local.length; i++) {\n let mapped = this.local[i].map(mapping, offset, oldOffset)\n if (mapped && mapped.type.valid(node, mapped)) (newLocal || (newLocal = [])).push(mapped)\n else if (options.onRemove) options.onRemove(this.local[i].spec)\n }\n\n if (this.children.length)\n return mapChildren(this.children, newLocal, mapping, node, offset, oldOffset, options)\n else\n return newLocal ? new DecorationSet(newLocal.sort(byPos)) : empty\n }\n\n // :: (Node, [Decoration]) → DecorationSet\n // Add the given array of decorations to the ones in the set,\n // producing a new set. Needs access to the current document to\n // create the appropriate tree structure.\n add(doc, decorations) {\n if (!decorations.length) return this\n if (this == empty) return DecorationSet.create(doc, decorations)\n return this.addInner(doc, decorations, 0)\n }\n\n addInner(doc, decorations, offset) {\n let children, childIndex = 0\n doc.forEach((childNode, childOffset) => {\n let baseOffset = childOffset + offset, found\n if (!(found = takeSpansForNode(decorations, childNode, baseOffset))) return\n\n if (!children) children = this.children.slice()\n while (childIndex < children.length && children[childIndex] < childOffset) childIndex += 3\n if (children[childIndex] == childOffset)\n children[childIndex + 2] = children[childIndex + 2].addInner(childNode, found, baseOffset + 1)\n else\n children.splice(childIndex, 0, childOffset, childOffset + childNode.nodeSize, buildTree(found, childNode, baseOffset + 1, noSpec))\n childIndex += 3\n })\n\n let local = moveSpans(childIndex ? withoutNulls(decorations) : decorations, -offset)\n return new DecorationSet(local.length ? this.local.concat(local).sort(byPos) : this.local,\n children || this.children)\n }\n\n // :: ([Decoration]) → DecorationSet\n // Create a new set that contains the decorations in this set, minus\n // the ones in the given array.\n remove(decorations) {\n if (decorations.length == 0 || this == empty) return this\n return this.removeInner(decorations, 0)\n }\n\n removeInner(decorations, offset) {\n let children = this.children, local = this.local\n for (let i = 0; i < children.length; i += 3) {\n let found, from = children[i] + offset, to = children[i + 1] + offset\n for (let j = 0, span; j < decorations.length; j++) if (span = decorations[j]) {\n if (span.from > from && span.to < to) {\n decorations[j] = null\n ;(found || (found = [])).push(span)\n }\n }\n if (!found) continue\n if (children == this.children) children = this.children.slice()\n let removed = children[i + 2].removeInner(found, from + 1)\n if (removed != empty) {\n children[i + 2] = removed\n } else {\n children.splice(i, 3)\n i -= 3\n }\n }\n if (local.length) for (let i = 0, span; i < decorations.length; i++) if (span = decorations[i]) {\n for (let j = 0; j < local.length; j++) if (local[j].type.eq(span.type)) {\n if (local == this.local) local = this.local.slice()\n local.splice(j--, 1)\n }\n }\n if (children == this.children && local == this.local) return this\n return local.length || children.length ? new DecorationSet(local, children) : empty\n }\n\n forChild(offset, node) {\n if (this == empty) return this\n if (node.isLeaf) return DecorationSet.empty\n\n let child, local\n for (let i = 0; i < this.children.length; i += 3) if (this.children[i] >= offset) {\n if (this.children[i] == offset) child = this.children[i + 2]\n break\n }\n let start = offset + 1, end = start + node.content.size\n for (let i = 0; i < this.local.length; i++) {\n let dec = this.local[i]\n if (dec.from < end && dec.to > start && (dec.type instanceof InlineType)) {\n let from = Math.max(start, dec.from) - start, to = Math.min(end, dec.to) - start\n if (from < to) (local || (local = [])).push(dec.copy(from, to))\n }\n }\n if (local) {\n let localSet = new DecorationSet(local.sort(byPos))\n return child ? new DecorationGroup([localSet, child]) : localSet\n }\n return child || empty\n }\n\n eq(other) {\n if (this == other) return true\n if (!(other instanceof DecorationSet) ||\n this.local.length != other.local.length ||\n this.children.length != other.children.length) return false\n for (let i = 0; i < this.local.length; i++)\n if (!this.local[i].eq(other.local[i])) return false\n for (let i = 0; i < this.children.length; i += 3)\n if (this.children[i] != other.children[i] ||\n this.children[i + 1] != other.children[i + 1] ||\n !this.children[i + 2].eq(other.children[i + 2])) return false\n return true\n }\n\n locals(node) {\n return removeOverlap(this.localsInner(node))\n }\n\n localsInner(node) {\n if (this == empty) return none\n if (node.inlineContent || !this.local.some(InlineType.is)) return this.local\n let result = []\n for (let i = 0; i < this.local.length; i++) {\n if (!(this.local[i].type instanceof InlineType))\n result.push(this.local[i])\n }\n return result\n }\n}\n\nconst empty = new DecorationSet()\n\n// :: DecorationSet\n// The empty set of decorations.\nDecorationSet.empty = empty\n\nDecorationSet.removeOverlap = removeOverlap\n\n// :- An abstraction that allows the code dealing with decorations to\n// treat multiple DecorationSet objects as if it were a single object\n// with (a subset of) the same interface.\nclass DecorationGroup {\n constructor(members) {\n this.members = members\n }\n\n forChild(offset, child) {\n if (child.isLeaf) return DecorationSet.empty\n let found = []\n for (let i = 0; i < this.members.length; i++) {\n let result = this.members[i].forChild(offset, child)\n if (result == empty) continue\n if (result instanceof DecorationGroup) found = found.concat(result.members)\n else found.push(result)\n }\n return DecorationGroup.from(found)\n }\n\n eq(other) {\n if (!(other instanceof DecorationGroup) ||\n other.members.length != this.members.length) return false\n for (let i = 0; i < this.members.length; i++)\n if (!this.members[i].eq(other.members[i])) return false\n return true\n }\n\n locals(node) {\n let result, sorted = true\n for (let i = 0; i < this.members.length; i++) {\n let locals = this.members[i].localsInner(node)\n if (!locals.length) continue\n if (!result) {\n result = locals\n } else {\n if (sorted) {\n result = result.slice()\n sorted = false\n }\n for (let j = 0; j < locals.length; j++) result.push(locals[j])\n }\n }\n return result ? removeOverlap(sorted ? result : result.sort(byPos)) : none\n }\n\n // : ([DecorationSet]) → union\n // Create a group for the given array of decoration sets, or return\n // a single set when possible.\n static from(members) {\n switch (members.length) {\n case 0: return empty\n case 1: return members[0]\n default: return new DecorationGroup(members)\n }\n }\n}\n\nfunction mapChildren(oldChildren, newLocal, mapping, node, offset, oldOffset, options) {\n let children = oldChildren.slice()\n\n // Mark the children that are directly touched by changes, and\n // move those that are after the changes.\n let shift = (oldStart, oldEnd, newStart, newEnd) => {\n for (let i = 0; i < children.length; i += 3) {\n let end = children[i + 1], dSize\n if (end == -1 || oldStart > end + oldOffset) continue\n if (oldEnd >= children[i] + oldOffset) {\n children[i + 1] = -1\n } else if (dSize = (newEnd - newStart) - (oldEnd - oldStart) + (oldOffset - offset)) {\n children[i] += dSize\n children[i + 1] += dSize\n }\n }\n }\n for (let i = 0; i < mapping.maps.length; i++) mapping.maps[i].forEach(shift)\n\n // Find the child nodes that still correspond to a single node,\n // recursively call mapInner on them and update their positions.\n let mustRebuild = false\n for (let i = 0; i < children.length; i += 3) if (children[i + 1] == -1) { // Touched nodes\n let from = mapping.map(children[i] + oldOffset), fromLocal = from - offset\n if (fromLocal < 0 || fromLocal >= node.content.size) {\n mustRebuild = true\n continue\n }\n // Must read oldChildren because children was tagged with -1\n let to = mapping.map(oldChildren[i + 1] + oldOffset, -1), toLocal = to - offset\n let {index, offset: childOffset} = node.content.findIndex(fromLocal)\n let childNode = node.maybeChild(index)\n if (childNode && childOffset == fromLocal && childOffset + childNode.nodeSize == toLocal) {\n let mapped = children[i + 2].mapInner(mapping, childNode, from + 1, children[i] + oldOffset + 1, options)\n if (mapped != empty) {\n children[i] = fromLocal\n children[i + 1] = toLocal\n children[i + 2] = mapped\n } else {\n children[i + 1] = -2\n mustRebuild = true\n }\n } else {\n mustRebuild = true\n }\n }\n\n // Remaining children must be collected and rebuilt into the appropriate structure\n if (mustRebuild) {\n let decorations = mapAndGatherRemainingDecorations(children, oldChildren, newLocal || [], mapping,\n offset, oldOffset, options)\n let built = buildTree(decorations, node, 0, options)\n newLocal = built.local\n for (let i = 0; i < children.length; i += 3) if (children[i + 1] < 0) {\n children.splice(i, 3)\n i -= 3\n }\n for (let i = 0, j = 0; i < built.children.length; i += 3) {\n let from = built.children[i]\n while (j < children.length && children[j] < from) j += 3\n children.splice(j, 0, built.children[i], built.children[i + 1], built.children[i + 2])\n }\n }\n\n return new DecorationSet(newLocal && newLocal.sort(byPos), children)\n}\n\nfunction moveSpans(spans, offset) {\n if (!offset || !spans.length) return spans\n let result = []\n for (let i = 0; i < spans.length; i++) {\n let span = spans[i]\n result.push(new Decoration(span.from + offset, span.to + offset, span.type))\n }\n return result\n}\n\nfunction mapAndGatherRemainingDecorations(children, oldChildren, decorations, mapping, offset, oldOffset, options) {\n // Gather all decorations from the remaining marked children\n function gather(set, oldOffset) {\n for (let i = 0; i < set.local.length; i++) {\n let mapped = set.local[i].map(mapping, offset, oldOffset)\n if (mapped) decorations.push(mapped)\n else if (options.onRemove) options.onRemove(set.local[i].spec)\n }\n for (let i = 0; i < set.children.length; i += 3)\n gather(set.children[i + 2], set.children[i] + oldOffset + 1)\n }\n for (let i = 0; i < children.length; i += 3) if (children[i + 1] == -1)\n gather(children[i + 2], oldChildren[i] + oldOffset + 1)\n\n return decorations\n}\n\nfunction takeSpansForNode(spans, node, offset) {\n if (node.isLeaf) return null\n let end = offset + node.nodeSize, found = null\n for (let i = 0, span; i < spans.length; i++) {\n if ((span = spans[i]) && span.from > offset && span.to < end) {\n ;(found || (found = [])).push(span)\n spans[i] = null\n }\n }\n return found\n}\n\nfunction withoutNulls(array) {\n let result = []\n for (let i = 0; i < array.length; i++)\n if (array[i] != null) result.push(array[i])\n return result\n}\n\n// : ([Decoration], Node, number) → DecorationSet\n// Build up a tree that corresponds to a set of decorations. `offset`\n// is a base offset that should be subtractet from the `from` and `to`\n// positions in the spans (so that we don't have to allocate new spans\n// for recursive calls).\nfunction buildTree(spans, node, offset, options) {\n let children = [], hasNulls = false\n node.forEach((childNode, localStart) => {\n let found = takeSpansForNode(spans, childNode, localStart + offset)\n if (found) {\n hasNulls = true\n let subtree = buildTree(found, childNode, offset + localStart + 1, options)\n if (subtree != empty)\n children.push(localStart, localStart + childNode.nodeSize, subtree)\n }\n })\n let locals = moveSpans(hasNulls ? withoutNulls(spans) : spans, -offset).sort(byPos)\n for (let i = 0; i < locals.length; i++) if (!locals[i].type.valid(node, locals[i])) {\n if (options.onRemove) options.onRemove(locals[i].spec)\n locals.splice(i--, 1)\n }\n return locals.length || children.length ? new DecorationSet(locals, children) : empty\n}\n\n// : (Decoration, Decoration) → number\n// Used to sort decorations so that ones with a low start position\n// come first, and within a set with the same start position, those\n// with an smaller end position come first.\nfunction byPos(a, b) {\n return a.from - b.from || a.to - b.to\n}\n\n// : ([Decoration]) → [Decoration]\n// Scan a sorted array of decorations for partially overlapping spans,\n// and split those so that only fully overlapping spans are left (to\n// make subsequent rendering easier). Will return the input array if\n// no partially overlapping spans are found (the common case).\nfunction removeOverlap(spans) {\n let working = spans\n for (let i = 0; i < working.length - 1; i++) {\n let span = working[i]\n if (span.from != span.to) for (let j = i + 1; j < working.length; j++) {\n let next = working[j]\n if (next.from == span.from) {\n if (next.to != span.to) {\n if (working == spans) working = spans.slice()\n // Followed by a partially overlapping larger span. Split that\n // span.\n working[j] = next.copy(next.from, span.to)\n insertAhead(working, j + 1, next.copy(span.to, next.to))\n }\n continue\n } else {\n if (next.from < span.to) {\n if (working == spans) working = spans.slice()\n // The end of this one overlaps with a subsequent span. Split\n // this one.\n working[i] = span.copy(span.from, next.from)\n insertAhead(working, j, span.copy(next.from, span.to))\n }\n break\n }\n }\n }\n return working\n}\n\nfunction insertAhead(array, i, deco) {\n while (i < array.length && byPos(deco, array[i]) > 0) i++\n array.splice(i, 0, deco)\n}\n\n// : (EditorView) → union\n// Get the decorations associated with the current props of a view.\nexport function viewDecorations(view) {\n let found = []\n view.someProp(\"decorations\", f => {\n let result = f(view.state)\n if (result && result != empty) found.push(result)\n })\n if (view.cursorWrapper)\n found.push(DecorationSet.create(view.state.doc, [view.cursorWrapper.deco]))\n return DecorationGroup.from(found)\n}\n","import {NodeSelection} from \"prosemirror-state\"\n\nimport {scrollRectIntoView, posAtCoords, coordsAtPos, endOfTextblock, storeScrollPos,\n resetScrollPos, focusPreventScroll} from \"./domcoords\"\nimport {docViewDesc} from \"./viewdesc\"\nimport {initInput, destroyInput, dispatchEvent, ensureListeners} from \"./input\"\nimport {selectionToDOM, anchorInRightPlace, syncNodeSelection} from \"./selection\"\nimport {Decoration, viewDecorations} from \"./decoration\"\nimport browser from \"./browser\"\n\nexport {Decoration, DecorationSet} from \"./decoration\"\n\n// Exported for testing\nexport {serializeForClipboard as __serializeForClipboard, parseFromClipboard as __parseFromClipboard} from \"./clipboard\"\nexport {endComposition as __endComposition} from \"./input\"\n\n// ::- An editor view manages the DOM structure that represents an\n// editable document. Its state and behavior are determined by its\n// [props](#view.DirectEditorProps).\nexport class EditorView {\n // :: (?union, DirectEditorProps)\n // Create a view. `place` may be a DOM node that the editor should\n // be appended to, a function that will place it into the document,\n // or an object whose `mount` property holds the node to use as the\n // document container. If it is `null`, the editor will not be added\n // to the document.\n constructor(place, props) {\n this._props = props\n // :: EditorState\n // The view's current [state](#state.EditorState).\n this.state = props.state\n\n this.dispatch = this.dispatch.bind(this)\n\n this._root = null\n this.focused = false\n\n // :: dom.Element\n // An editable DOM node containing the document. (You probably\n // should not directly interfere with its content.)\n this.dom = (place && place.mount) || document.createElement(\"div\")\n if (place) {\n if (place.appendChild) place.appendChild(this.dom)\n else if (place.apply) place(this.dom)\n else if (place.mount) this.mounted = true\n }\n\n // :: bool\n // Indicates whether the editor is currently [editable](#view.EditorProps.editable).\n this.editable = getEditable(this)\n this.markCursor = null\n this.cursorWrapper = null\n updateCursorWrapper(this)\n this.nodeViews = buildNodeViews(this)\n this.docView = docViewDesc(this.state.doc, computeDocDeco(this), viewDecorations(this), this.dom, this)\n\n this.lastSelectedViewDesc = null\n // :: ?{slice: Slice, move: bool}\n // When editor content is being dragged, this object contains\n // information about the dragged slice and whether it is being\n // copied or moved. At any other time, it is null.\n this.dragging = null\n\n initInput(this)\n\n this.pluginViews = []\n this.updatePluginViews()\n }\n\n // composing:: boolean\n // Holds `true` when a\n // [composition](https://developer.mozilla.org/en-US/docs/Mozilla/IME_handling_guide)\n // is active.\n\n // :: DirectEditorProps\n // The view's current [props](#view.EditorProps).\n get props() {\n if (this._props.state != this.state) {\n let prev = this._props\n this._props = {}\n for (let name in prev) this._props[name] = prev[name]\n this._props.state = this.state\n }\n return this._props\n }\n\n // :: (DirectEditorProps)\n // Update the view's props. Will immediately cause an update to\n // the DOM.\n update(props) {\n if (props.handleDOMEvents != this._props.handleDOMEvents) ensureListeners(this)\n this._props = props\n this.updateStateInner(props.state, true)\n }\n\n // :: (DirectEditorProps)\n // Update the view by updating existing props object with the object\n // given as argument. Equivalent to `view.update(Object.assign({},\n // view.props, props))`.\n setProps(props) {\n let updated = {}\n for (let name in this._props) updated[name] = this._props[name]\n updated.state = this.state\n for (let name in props) updated[name] = props[name]\n this.update(updated)\n }\n\n // :: (EditorState)\n // Update the editor's `state` prop, without touching any of the\n // other props.\n updateState(state) {\n this.updateStateInner(state, this.state.plugins != state.plugins)\n }\n\n updateStateInner(state, reconfigured) {\n let prev = this.state, redraw = false\n this.state = state\n if (reconfigured) {\n let nodeViews = buildNodeViews(this)\n if (changedNodeViews(nodeViews, this.nodeViews)) {\n this.nodeViews = nodeViews\n redraw = true\n }\n ensureListeners(this)\n }\n\n this.editable = getEditable(this)\n updateCursorWrapper(this)\n let innerDeco = viewDecorations(this), outerDeco = computeDocDeco(this)\n\n let scroll = reconfigured ? \"reset\"\n : state.scrollToSelection > prev.scrollToSelection ? \"to selection\" : \"preserve\"\n let updateDoc = redraw || !this.docView.matchesNode(state.doc, outerDeco, innerDeco)\n let updateSel = updateDoc || !state.selection.eq(prev.selection)\n let oldScrollPos = scroll == \"preserve\" && updateSel && this.dom.style.overflowAnchor == null && storeScrollPos(this)\n\n if (updateSel) {\n this.domObserver.stop()\n // Work around an issue in Chrome, IE, and Edge where changing\n // the DOM around an active selection puts it into a broken\n // state where the thing the user sees differs from the\n // selection reported by the Selection object (#710, #973,\n // #1011, #1013).\n let forceSelUpdate = updateDoc && (browser.ie || browser.chrome) &&\n !prev.selection.empty && !state.selection.empty && selectionContextChanged(prev.selection, state.selection)\n if (updateDoc) {\n if (redraw || !this.docView.update(state.doc, outerDeco, innerDeco, this)) {\n this.docView.destroy()\n this.docView = docViewDesc(state.doc, outerDeco, innerDeco, this.dom, this)\n }\n }\n // Work around for an issue where an update arriving right between\n // a DOM selection change and the \"selectionchange\" event for it\n // can cause a spurious DOM selection update, disrupting mouse\n // drag selection.\n if (forceSelUpdate ||\n !(this.mouseDown && this.domObserver.currentSelection.eq(this.root.getSelection()) && anchorInRightPlace(this))) {\n selectionToDOM(this, forceSelUpdate)\n } else {\n syncNodeSelection(this, state.selection)\n this.domObserver.setCurSelection()\n }\n this.domObserver.start()\n }\n\n this.updatePluginViews(prev)\n\n if (scroll == \"reset\") {\n this.dom.scrollTop = 0\n } else if (scroll == \"to selection\") {\n let startDOM = this.root.getSelection().focusNode\n if (this.someProp(\"handleScrollToSelection\", f => f(this)))\n {} // Handled\n else if (state.selection instanceof NodeSelection)\n scrollRectIntoView(this, this.docView.domAfterPos(state.selection.from).getBoundingClientRect(), startDOM)\n else\n scrollRectIntoView(this, this.coordsAtPos(state.selection.head), startDOM)\n } else if (oldScrollPos) {\n resetScrollPos(oldScrollPos)\n }\n }\n\n destroyPluginViews() {\n let view\n while (view = this.pluginViews.pop()) if (view.destroy) view.destroy()\n }\n\n updatePluginViews(prevState) {\n if (!prevState || prevState.plugins != this.state.plugins) {\n this.destroyPluginViews()\n for (let i = 0; i < this.state.plugins.length; i++) {\n let plugin = this.state.plugins[i]\n if (plugin.spec.view) this.pluginViews.push(plugin.spec.view(this))\n }\n } else {\n for (let i = 0; i < this.pluginViews.length; i++) {\n let pluginView = this.pluginViews[i]\n if (pluginView.update) pluginView.update(this, prevState)\n }\n }\n }\n\n // :: (string, ?(prop: *) → *) → *\n // Goes over the values of a prop, first those provided directly,\n // then those from plugins (in order), and calls `f` every time a\n // non-undefined value is found. When `f` returns a truthy value,\n // that is immediately returned. When `f` isn't provided, it is\n // treated as the identity function (the prop value is returned\n // directly).\n someProp(propName, f) {\n let prop = this._props && this._props[propName], value\n if (prop != null && (value = f ? f(prop) : prop)) return value\n let plugins = this.state.plugins\n if (plugins) for (let i = 0; i < plugins.length; i++) {\n let prop = plugins[i].props[propName]\n if (prop != null && (value = f ? f(prop) : prop)) return value\n }\n }\n\n // :: () → bool\n // Query whether the view has focus.\n hasFocus() {\n return this.root.activeElement == this.dom\n }\n\n // :: ()\n // Focus the editor.\n focus() {\n this.domObserver.stop()\n if (this.editable) focusPreventScroll(this.dom)\n selectionToDOM(this)\n this.domObserver.start()\n }\n\n // :: union\n // Get the document root in which the editor exists. This will\n // usually be the top-level `document`, but might be a [shadow\n // DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Shadow_DOM)\n // root if the editor is inside one.\n get root() {\n let cached = this._root\n if (cached == null) for (let search = this.dom.parentNode; search; search = search.parentNode) {\n if (search.nodeType == 9 || (search.nodeType == 11 && search.host)) {\n if (!search.getSelection) Object.getPrototypeOf(search).getSelection = () => document.getSelection()\n return this._root = search\n }\n }\n return cached || document\n }\n\n // :: ({left: number, top: number}) → ?{pos: number, inside: number}\n // Given a pair of viewport coordinates, return the document\n // position that corresponds to them. May return null if the given\n // coordinates aren't inside of the editor. When an object is\n // returned, its `pos` property is the position nearest to the\n // coordinates, and its `inside` property holds the position of the\n // inner node that the position falls inside of, or -1 if it is at\n // the top level, not in any node.\n posAtCoords(coords) {\n return posAtCoords(this, coords)\n }\n\n // :: (number) → {left: number, right: number, top: number, bottom: number}\n // Returns the viewport rectangle at a given document position. `left`\n // and `right` will be the same number, as this returns a flat\n // cursor-ish rectangle.\n coordsAtPos(pos) {\n return coordsAtPos(this, pos)\n }\n\n // :: (number) → {node: dom.Node, offset: number}\n // Find the DOM position that corresponds to the given document\n // position. Note that you should **not** mutate the editor's\n // internal DOM, only inspect it (and even that is usually not\n // necessary).\n domAtPos(pos) {\n return this.docView.domFromPos(pos)\n }\n\n // :: (number) → ?dom.Node\n // Find the DOM node that represents the document node after the\n // given position. May return `null` when the position doesn't point\n // in front of a node or if the node is inside an opaque node view.\n //\n // This is intended to be able to call things like\n // `getBoundingClientRect` on that DOM node. Do **not** mutate the\n // editor DOM directly, or add styling this way, since that will be\n // immediately overriden by the editor as it redraws the node.\n nodeDOM(pos) {\n let desc = this.docView.descAt(pos)\n return desc ? desc.nodeDOM : null\n }\n\n // :: (dom.Node, number, ?number) → number\n // Find the document position that corresponds to a given DOM\n // position. (Whenever possible, it is preferable to inspect the\n // document structure directly, rather than poking around in the\n // DOM, but sometimes—for example when interpreting an event\n // target—you don't have a choice.)\n //\n // The `bias` parameter can be used to influence which side of a DOM\n // node to use when the position is inside a leaf node.\n posAtDOM(node, offset, bias = -1) {\n let pos = this.docView.posFromDOM(node, offset, bias)\n if (pos == null) throw new RangeError(\"DOM position not inside the editor\")\n return pos\n }\n\n // :: (union<\"up\", \"down\", \"left\", \"right\", \"forward\", \"backward\">, ?EditorState) → bool\n // Find out whether the selection is at the end of a textblock when\n // moving in a given direction. When, for example, given `\"left\"`,\n // it will return true if moving left from the current cursor\n // position would leave that position's parent textblock. Will apply\n // to the view's current state by default, but it is possible to\n // pass a different state.\n endOfTextblock(dir, state) {\n return endOfTextblock(this, state || this.state, dir)\n }\n\n // :: ()\n // Removes the editor from the DOM and destroys all [node\n // views](#view.NodeView).\n destroy() {\n if (!this.docView) return\n destroyInput(this)\n this.destroyPluginViews()\n if (this.mounted) {\n this.docView.update(this.state.doc, [], viewDecorations(this), this)\n this.dom.textContent = \"\"\n } else if (this.dom.parentNode) {\n this.dom.parentNode.removeChild(this.dom)\n }\n this.docView.destroy()\n this.docView = null\n }\n\n // Used for testing.\n dispatchEvent(event) {\n return dispatchEvent(this, event)\n }\n\n // :: (Transaction)\n // Dispatch a transaction. Will call\n // [`dispatchTransaction`](#view.DirectEditorProps.dispatchTransaction)\n // when given, and otherwise defaults to applying the transaction to\n // the current state and calling\n // [`updateState`](#view.EditorView.updateState) with the result.\n // This method is bound to the view instance, so that it can be\n // easily passed around.\n dispatch(tr) {\n let dispatchTransaction = this._props.dispatchTransaction\n if (dispatchTransaction) dispatchTransaction.call(this, tr)\n else this.updateState(this.state.apply(tr))\n }\n}\n\nfunction computeDocDeco(view) {\n let attrs = Object.create(null)\n attrs.class = \"ProseMirror\"\n attrs.contenteditable = String(view.editable)\n\n view.someProp(\"attributes\", value => {\n if (typeof value == \"function\") value = value(view.state)\n if (value) for (let attr in value) {\n if (attr == \"class\")\n attrs.class += \" \" + value[attr]\n else if (!attrs[attr] && attr != \"contenteditable\" && attr != \"nodeName\")\n attrs[attr] = String(value[attr])\n }\n })\n\n return [Decoration.node(0, view.state.doc.content.size, attrs)]\n}\n\nfunction updateCursorWrapper(view) {\n let {$head, $anchor, visible} = view.state.selection\n if (view.markCursor) {\n let dom = document.createElement(\"img\")\n dom.setAttribute(\"mark-placeholder\", \"true\")\n view.cursorWrapper = {dom, deco: Decoration.widget($head.pos, dom, {raw: true, marks: view.markCursor})}\n } else if (visible || $head.pos != $anchor.pos) {\n view.cursorWrapper = null\n } else {\n let dom\n if (!view.cursorWrapper || view.cursorWrapper.dom.childNodes.length) {\n dom = document.createElement(\"div\")\n dom.style.position = \"absolute\"\n dom.style.left = \"-100000px\"\n } else if (view.cursorWrapper.deco.pos != $head.pos) {\n dom = view.cursorWrapper.dom\n }\n if (dom)\n view.cursorWrapper = {dom, deco: Decoration.widget($head.pos, dom, {raw: true})}\n }\n}\n\nfunction getEditable(view) {\n return !view.someProp(\"editable\", value => value(view.state) === false)\n}\n\nfunction selectionContextChanged(sel1, sel2) {\n let depth = Math.min(sel1.$anchor.sharedDepth(sel1.head), sel2.$anchor.sharedDepth(sel2.head))\n return sel1.$anchor.node(depth) != sel2.$anchor.node(depth)\n}\n\nfunction buildNodeViews(view) {\n let result = {}\n view.someProp(\"nodeViews\", obj => {\n for (let prop in obj) if (!Object.prototype.hasOwnProperty.call(result, prop))\n result[prop] = obj[prop]\n })\n return result\n}\n\nfunction changedNodeViews(a, b) {\n let nA = 0, nB = 0\n for (let prop in a) {\n if (a[prop] != b[prop]) return true\n nA++\n }\n for (let _ in b) nB++\n return nA != nB\n}\n\n// EditorProps:: interface\n//\n// Props are configuration values that can be passed to an editor view\n// or included in a plugin. This interface lists the supported props.\n//\n// The various event-handling functions may all return `true` to\n// indicate that they handled the given event. The view will then take\n// care to call `preventDefault` on the event, except with\n// `handleDOMEvents`, where the handler itself is responsible for that.\n//\n// How a prop is resolved depends on the prop. Handler functions are\n// called one at a time, starting with the base props and then\n// searching through the plugins (in order of appearance) until one of\n// them returns true. For some props, the first plugin that yields a\n// value gets precedence.\n//\n// handleDOMEvents:: ?Object<(view: EditorView, event: dom.Event) → bool>\n// Can be an object mapping DOM event type names to functions that\n// handle them. Such functions will be called before any handling\n// ProseMirror does of events fired on the editable DOM element.\n// Contrary to the other event handling props, when returning true\n// from such a function, you are responsible for calling\n// `preventDefault` yourself (or not, if you want to allow the\n// default behavior).\n//\n// handleKeyDown:: ?(view: EditorView, event: dom.KeyboardEvent) → bool\n// Called when the editor receives a `keydown` event.\n//\n// handleKeyPress:: ?(view: EditorView, event: dom.KeyboardEvent) → bool\n// Handler for `keypress` events.\n//\n// handleTextInput:: ?(view: EditorView, from: number, to: number, text: string) → bool\n// Whenever the user directly input text, this handler is called\n// before the input is applied. If it returns `true`, the default\n// behavior of actually inserting the text is suppressed.\n//\n// handleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool\n// Called for each node around a click, from the inside out. The\n// `direct` flag will be true for the inner node.\n//\n// handleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool\n// Called when the editor is clicked, after `handleClickOn` handlers\n// have been called.\n//\n// handleDoubleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool\n// Called for each node around a double click.\n//\n// handleDoubleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool\n// Called when the editor is double-clicked, after `handleDoubleClickOn`.\n//\n// handleTripleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool\n// Called for each node around a triple click.\n//\n// handleTripleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool\n// Called when the editor is triple-clicked, after `handleTripleClickOn`.\n//\n// handlePaste:: ?(view: EditorView, event: dom.Event, slice: Slice) → bool\n// Can be used to override the behavior of pasting. `slice` is the\n// pasted content parsed by the editor, but you can directly access\n// the event to get at the raw content.\n//\n// handleDrop:: ?(view: EditorView, event: dom.Event, slice: Slice, moved: bool) → bool\n// Called when something is dropped on the editor. `moved` will be\n// true if this drop moves from the current selection (which should\n// thus be deleted).\n//\n// handleScrollToSelection:: ?(view: EditorView) → bool\n// Called when the view, after updating its state, tries to scroll\n// the selection into view. A handler function may return false to\n// indicate that it did not handle the scrolling and further\n// handlers or the default behavior should be tried.\n//\n// createSelectionBetween:: ?(view: EditorView, anchor: ResolvedPos, head: ResolvedPos) → ?Selection\n// Can be used to override the way a selection is created when\n// reading a DOM selection between the given anchor and head.\n//\n// domParser:: ?DOMParser\n// The [parser](#model.DOMParser) to use when reading editor changes\n// from the DOM. Defaults to calling\n// [`DOMParser.fromSchema`](#model.DOMParser^fromSchema) on the\n// editor's schema.\n//\n// transformPastedHTML:: ?(html: string) → string\n// Can be used to transform pasted HTML text, _before_ it is parsed,\n// for example to clean it up.\n//\n// clipboardParser:: ?DOMParser\n// The [parser](#model.DOMParser) to use when reading content from\n// the clipboard. When not given, the value of the\n// [`domParser`](#view.EditorProps.domParser) prop is used.\n//\n// transformPastedText:: ?(text: string) → string\n// Transform pasted plain text.\n//\n// clipboardTextParser:: ?(text: string, $context: ResolvedPos) → Slice\n// A function to parse text from the clipboard into a document\n// slice. Called after\n// [`transformPastedText`](#view.EditorProps.transformPastedText).\n// The default behavior is to split the text into lines, wrap them\n// in `

    ` tags, and call\n// [`clipboardParser`](#view.EditorProps.clipboardParser) on it.\n//\n// transformPasted:: ?(Slice) → Slice\n// Can be used to transform pasted content before it is applied to\n// the document.\n//\n// nodeViews:: ?Object<(node: Node, view: EditorView, getPos: () → number, decorations: [Decoration]) → NodeView>\n// Allows you to pass custom rendering and behavior logic for nodes\n// and marks. Should map node and mark names to constructor\n// functions that produce a [`NodeView`](#view.NodeView) object\n// implementing the node's display behavior. For nodes, the third\n// argument `getPos` is a function that can be called to get the\n// node's current position, which can be useful when creating\n// transactions to update it. For marks, the third argument is a\n// boolean that indicates whether the mark's content is inline.\n//\n// `decorations` is an array of node or inline decorations that are\n// active around the node. They are automatically drawn in the\n// normal way, and you will usually just want to ignore this, but\n// they can also be used as a way to provide context information to\n// the node view without adding it to the document itself.\n//\n// clipboardSerializer:: ?DOMSerializer\n// The DOM serializer to use when putting content onto the\n// clipboard. If not given, the result of\n// [`DOMSerializer.fromSchema`](#model.DOMSerializer^fromSchema)\n// will be used.\n//\n// clipboardTextSerializer:: ?(Slice) → string\n// A function that will be called to get the text for the current\n// selection when copying text to the clipboard. By default, the\n// editor will use [`textBetween`](#model.Node.textBetween) on the\n// selected range.\n//\n// decorations:: ?(state: EditorState) → ?DecorationSet\n// A set of [document decorations](#view.Decoration) to show in the\n// view.\n//\n// editable:: ?(state: EditorState) → bool\n// When this returns false, the content of the view is not directly\n// editable.\n//\n// attributes:: ?union, (EditorState) → ?Object>\n// Control the DOM attributes of the editable element. May be either\n// an object or a function going from an editor state to an object.\n// By default, the element will get a class `\"ProseMirror\"`, and\n// will have its `contentEditable` attribute determined by the\n// [`editable` prop](#view.EditorProps.editable). Additional classes\n// provided here will be added to the class. For other attributes,\n// the value provided first (as in\n// [`someProp`](#view.EditorView.someProp)) will be used.\n//\n// scrollThreshold:: ?union\n// Determines the distance (in pixels) between the cursor and the\n// end of the visible viewport at which point, when scrolling the\n// cursor into view, scrolling takes place. Defaults to 0.\n//\n// scrollMargin:: ?union\n// Determines the extra space (in pixels) that is left above or\n// below the cursor when it is scrolled into view. Defaults to 5.\n\n// DirectEditorProps:: interface extends EditorProps\n//\n// The props object given directly to the editor view supports two\n// fields that can't be used in plugins:\n//\n// state:: EditorState\n// The current state of the editor.\n//\n// dispatchTransaction:: ?(tr: Transaction)\n// The callback over which to send transactions (state updates)\n// produced by the view. If you specify this, you probably want to\n// make sure this ends up calling the view's\n// [`updateState`](#view.EditorView.updateState) method with a new\n// state that has the transaction\n// [applied](#state.EditorState.apply). The callback will be bound to have\n// the view instance as its `this` binding.\n"],"names":["const","let","browser","pos","box","rect","target","desc","search","j","super","this","name","i","child","next","anchor","tr","sel","move","d","result","p","prototypeAccessors","span","from","prop","dom"],"mappings":"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"} \ No newline at end of file diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/dist/index.js b/packages/tiptap-extensions/node_modules/prosemirror-view/dist/index.js new file mode 100644 index 0000000000..2a678bfdc1 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/dist/index.js @@ -0,0 +1,4975 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +var prosemirrorState = require('prosemirror-state'); +var prosemirrorModel = require('prosemirror-model'); +var prosemirrorTransform = require('prosemirror-transform'); + +var result = {}; + +if (typeof navigator != "undefined" && typeof document != "undefined") { + var ie_edge = /Edge\/(\d+)/.exec(navigator.userAgent); + var ie_upto10 = /MSIE \d/.test(navigator.userAgent); + var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent); + + result.mac = /Mac/.test(navigator.platform); + var ie = result.ie = !!(ie_upto10 || ie_11up || ie_edge); + result.ie_version = ie_upto10 ? document.documentMode || 6 : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : null; + result.gecko = !ie && /gecko\/(\d+)/i.test(navigator.userAgent); + result.gecko_version = result.gecko && +(/Firefox\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1]; + var chrome = !ie && /Chrome\/(\d+)/.exec(navigator.userAgent); + result.chrome = !!chrome; + result.chrome_version = chrome && +chrome[1]; + result.ios = !ie && /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent); + result.android = /Android \d/.test(navigator.userAgent); + result.webkit = !ie && 'WebkitAppearance' in document.documentElement.style; + result.safari = /Apple Computer/.test(navigator.vendor); + result.webkit_version = result.webkit && +(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1]; +} + +var domIndex = function(node) { + for (var index = 0;; index++) { + node = node.previousSibling; + if (!node) { return index } + } +}; + +var parentNode = function(node) { + var parent = node.parentNode; + return parent && parent.nodeType == 11 ? parent.host : parent +}; + +var textRange = function(node, from, to) { + var range = document.createRange(); + range.setEnd(node, to == null ? node.nodeValue.length : to); + range.setStart(node, from || 0); + return range +}; + +// Scans forward and backward through DOM positions equivalent to the +// given one to see if the two are in the same place (i.e. after a +// text node vs at the end of that text node) +var isEquivalentPosition = function(node, off, targetNode, targetOff) { + return targetNode && (scanFor(node, off, targetNode, targetOff, -1) || + scanFor(node, off, targetNode, targetOff, 1)) +}; + +var atomElements = /^(img|br|input|textarea|hr)$/i; + +function scanFor(node, off, targetNode, targetOff, dir) { + for (;;) { + if (node == targetNode && off == targetOff) { return true } + if (off == (dir < 0 ? 0 : nodeSize(node))) { + var parent = node.parentNode; + if (parent.nodeType != 1 || hasBlockDesc(node) || atomElements.test(node.nodeName) || node.contentEditable == "false") + { return false } + off = domIndex(node) + (dir < 0 ? 0 : 1); + node = parent; + } else if (node.nodeType == 1) { + node = node.childNodes[off + (dir < 0 ? -1 : 0)]; + off = dir < 0 ? nodeSize(node) : 0; + } else { + return false + } + } +} + +function nodeSize(node) { + return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length +} + +function hasBlockDesc(dom) { + var desc; + for (var cur = dom; cur; cur = cur.parentNode) { if (desc = cur.pmViewDesc) { break } } + return desc && desc.node && desc.node.isBlock && (desc.dom == dom || desc.contentDOM == dom) +} + +// Work around Chrome issue https://bugs.chromium.org/p/chromium/issues/detail?id=447523 +// (isCollapsed inappropriately returns true in shadow dom) +var selectionCollapsed = function(domSel) { + var collapsed = domSel.isCollapsed; + if (collapsed && result.chrome && domSel.rangeCount && !domSel.getRangeAt(0).collapsed) + { collapsed = false; } + return collapsed +}; + +function keyEvent(keyCode, key) { + var event = document.createEvent("Event"); + event.initEvent("keydown", true, true); + event.keyCode = keyCode; + event.key = event.code = key; + return event +} + +function windowRect(win) { + return {left: 0, right: win.innerWidth, + top: 0, bottom: win.innerHeight} +} + +function getSide(value, side) { + return typeof value == "number" ? value : value[side] +} + +function scrollRectIntoView(view, rect, startDOM) { + var scrollThreshold = view.someProp("scrollThreshold") || 0, scrollMargin = view.someProp("scrollMargin") || 5; + var doc = view.dom.ownerDocument, win = doc.defaultView; + for (var parent = startDOM || view.dom;; parent = parentNode(parent)) { + if (!parent) { break } + if (parent.nodeType != 1) { continue } + var atTop = parent == doc.body || parent.nodeType != 1; + var bounding = atTop ? windowRect(win) : parent.getBoundingClientRect(); + var moveX = 0, moveY = 0; + if (rect.top < bounding.top + getSide(scrollThreshold, "top")) + { moveY = -(bounding.top - rect.top + getSide(scrollMargin, "top")); } + else if (rect.bottom > bounding.bottom - getSide(scrollThreshold, "bottom")) + { moveY = rect.bottom - bounding.bottom + getSide(scrollMargin, "bottom"); } + if (rect.left < bounding.left + getSide(scrollThreshold, "left")) + { moveX = -(bounding.left - rect.left + getSide(scrollMargin, "left")); } + else if (rect.right > bounding.right - getSide(scrollThreshold, "right")) + { moveX = rect.right - bounding.right + getSide(scrollMargin, "right"); } + if (moveX || moveY) { + if (atTop) { + win.scrollBy(moveX, moveY); + } else { + if (moveY) { parent.scrollTop += moveY; } + if (moveX) { parent.scrollLeft += moveX; } + } + } + if (atTop) { break } + } +} + +// Store the scroll position of the editor's parent nodes, along with +// the top position of an element near the top of the editor, which +// will be used to make sure the visible viewport remains stable even +// when the size of the content above changes. +function storeScrollPos(view) { + var rect = view.dom.getBoundingClientRect(), startY = Math.max(0, rect.top); + var refDOM, refTop; + for (var x = (rect.left + rect.right) / 2, y = startY + 1; + y < Math.min(innerHeight, rect.bottom); y += 5) { + var dom = view.root.elementFromPoint(x, y); + if (dom == view.dom || !view.dom.contains(dom)) { continue } + var localRect = dom.getBoundingClientRect(); + if (localRect.top >= startY - 20) { + refDOM = dom; + refTop = localRect.top; + break + } + } + return {refDOM: refDOM, refTop: refTop, stack: scrollStack(view.dom)} +} + +function scrollStack(dom) { + var stack = [], doc = dom.ownerDocument; + for (; dom; dom = parentNode(dom)) { + stack.push({dom: dom, top: dom.scrollTop, left: dom.scrollLeft}); + if (dom == doc) { break } + } + return stack +} + +// Reset the scroll position of the editor's parent nodes to that what +// it was before, when storeScrollPos was called. +function resetScrollPos(ref) { + var refDOM = ref.refDOM; + var refTop = ref.refTop; + var stack = ref.stack; + + var newRefTop = refDOM ? refDOM.getBoundingClientRect().top : 0; + restoreScrollStack(stack, newRefTop == 0 ? 0 : newRefTop - refTop); +} + +function restoreScrollStack(stack, dTop) { + for (var i = 0; i < stack.length; i++) { + var ref = stack[i]; + var dom = ref.dom; + var top = ref.top; + var left = ref.left; + if (dom.scrollTop != top + dTop) { dom.scrollTop = top + dTop; } + if (dom.scrollLeft != left) { dom.scrollLeft = left; } + } +} + +var preventScrollSupported = null; +// Feature-detects support for .focus({preventScroll: true}), and uses +// a fallback kludge when not supported. +function focusPreventScroll(dom) { + if (dom.setActive) { return dom.setActive() } // in IE + if (preventScrollSupported) { return dom.focus(preventScrollSupported) } + + var stored = scrollStack(dom); + dom.focus(preventScrollSupported == null ? { + get preventScroll() { + preventScrollSupported = {preventScroll: true}; + return true + } + } : undefined); + if (!preventScrollSupported) { + preventScrollSupported = false; + restoreScrollStack(stored, 0); + } +} + +function findOffsetInNode(node, coords) { + var closest, dxClosest = 2e8, coordsClosest, offset = 0; + var rowBot = coords.top, rowTop = coords.top; + for (var child = node.firstChild, childIndex = 0; child; child = child.nextSibling, childIndex++) { + var rects = (void 0); + if (child.nodeType == 1) { rects = child.getClientRects(); } + else if (child.nodeType == 3) { rects = textRange(child).getClientRects(); } + else { continue } + + for (var i = 0; i < rects.length; i++) { + var rect = rects[i]; + if (rect.top <= rowBot && rect.bottom >= rowTop) { + rowBot = Math.max(rect.bottom, rowBot); + rowTop = Math.min(rect.top, rowTop); + var dx = rect.left > coords.left ? rect.left - coords.left + : rect.right < coords.left ? coords.left - rect.right : 0; + if (dx < dxClosest) { + closest = child; + dxClosest = dx; + coordsClosest = dx && closest.nodeType == 3 ? {left: rect.right < coords.left ? rect.right : rect.left, top: coords.top} : coords; + if (child.nodeType == 1 && dx) + { offset = childIndex + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0); } + continue + } + } + if (!closest && (coords.left >= rect.right && coords.top >= rect.top || + coords.left >= rect.left && coords.top >= rect.bottom)) + { offset = childIndex + 1; } + } + } + if (closest && closest.nodeType == 3) { return findOffsetInText(closest, coordsClosest) } + if (!closest || (dxClosest && closest.nodeType == 1)) { return {node: node, offset: offset} } + return findOffsetInNode(closest, coordsClosest) +} + +function findOffsetInText(node, coords) { + var len = node.nodeValue.length; + var range = document.createRange(); + for (var i = 0; i < len; i++) { + range.setEnd(node, i + 1); + range.setStart(node, i); + var rect = singleRect(range, 1); + if (rect.top == rect.bottom) { continue } + if (inRect(coords, rect)) + { return {node: node, offset: i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0)} } + } + return {node: node, offset: 0} +} + +function inRect(coords, rect) { + return coords.left >= rect.left - 1 && coords.left <= rect.right + 1&& + coords.top >= rect.top - 1 && coords.top <= rect.bottom + 1 +} + +function targetKludge(dom, coords) { + var parent = dom.parentNode; + if (parent && /^li$/i.test(parent.nodeName) && coords.left < dom.getBoundingClientRect().left) + { return parent } + return dom +} + +function posFromElement(view, elt, coords) { + var ref = findOffsetInNode(elt, coords); + var node = ref.node; + var offset = ref.offset; + var bias = -1; + if (node.nodeType == 1 && !node.firstChild) { + var rect = node.getBoundingClientRect(); + bias = rect.left != rect.right && coords.left > (rect.left + rect.right) / 2 ? 1 : -1; + } + return view.docView.posFromDOM(node, offset, bias) +} + +function posFromCaret(view, node, offset, coords) { + // Browser (in caretPosition/RangeFromPoint) will agressively + // normalize towards nearby inline nodes. Since we are interested in + // positions between block nodes too, we first walk up the hierarchy + // of nodes to see if there are block nodes that the coordinates + // fall outside of. If so, we take the position before/after that + // block. If not, we call `posFromDOM` on the raw node/offset. + var outside = -1; + for (var cur = node;;) { + if (cur == view.dom) { break } + var desc = view.docView.nearestDesc(cur, true); + if (!desc) { return null } + if (desc.node.isBlock && desc.parent) { + var rect = desc.dom.getBoundingClientRect(); + if (rect.left > coords.left || rect.top > coords.top) { outside = desc.posBefore; } + else if (rect.right < coords.left || rect.bottom < coords.top) { outside = desc.posAfter; } + else { break } + } + cur = desc.dom.parentNode; + } + return outside > -1 ? outside : view.docView.posFromDOM(node, offset) +} + +function elementFromPoint(element, coords, box) { + var len = element.childNodes.length; + if (len && box.top < box.bottom) { + for (var startI = Math.max(0, Math.min(len - 1, Math.floor(len * (coords.top - box.top) / (box.bottom - box.top)) - 2)), i = startI;;) { + var child = element.childNodes[i]; + if (child.nodeType == 1) { + var rects = child.getClientRects(); + for (var j = 0; j < rects.length; j++) { + var rect = rects[j]; + if (inRect(coords, rect)) { return elementFromPoint(child, coords, rect) } + } + } + if ((i = (i + 1) % len) == startI) { break } + } + } + return element +} + +// Given an x,y position on the editor, get the position in the document. +function posAtCoords(view, coords) { + var assign, assign$1; + + var root = view.root, node, offset; + if (root.caretPositionFromPoint) { + try { // Firefox throws for this call in hard-to-predict circumstances (#994) + var pos$1 = root.caretPositionFromPoint(coords.left, coords.top); + if (pos$1) { ((assign = pos$1, node = assign.offsetNode, offset = assign.offset)); } + } catch (_) {} + } + if (!node && root.caretRangeFromPoint) { + var range = root.caretRangeFromPoint(coords.left, coords.top); + if (range) { ((assign$1 = range, node = assign$1.startContainer, offset = assign$1.startOffset)); } + } + + var elt = root.elementFromPoint(coords.left, coords.top + 1), pos; + if (!elt || !view.dom.contains(elt.nodeType != 1 ? elt.parentNode : elt)) { + var box = view.dom.getBoundingClientRect(); + if (!inRect(coords, box)) { return null } + elt = elementFromPoint(view.dom, coords, box); + if (!elt) { return null } + } + elt = targetKludge(elt, coords); + if (node) { + if (result.gecko && node.nodeType == 1) { + // Firefox will sometimes return offsets into nodes, which + // have no actual children, from caretPositionFromPoint (#953) + offset = Math.min(offset, node.childNodes.length); + // It'll also move the returned position before image nodes, + // even if those are behind it. + if (offset < node.childNodes.length) { + var next = node.childNodes[offset], box$1; + if (next.nodeName == "IMG" && (box$1 = next.getBoundingClientRect()).right <= coords.left && + box$1.bottom > coords.top) + { offset++; } + } + } + // Suspiciously specific kludge to work around caret*FromPoint + // never returning a position at the end of the document + if (node == view.dom && offset == node.childNodes.length - 1 && node.lastChild.nodeType == 1 && + coords.top > node.lastChild.getBoundingClientRect().bottom) + { pos = view.state.doc.content.size; } + // Ignore positions directly after a BR, since caret*FromPoint + // 'round up' positions that would be more accurately placed + // before the BR node. + else if (offset == 0 || node.nodeType != 1 || node.childNodes[offset - 1].nodeName != "BR") + { pos = posFromCaret(view, node, offset, coords); } + } + if (pos == null) { pos = posFromElement(view, elt, coords); } + + var desc = view.docView.nearestDesc(elt, true); + return {pos: pos, inside: desc ? desc.posAtStart - desc.border : -1} +} + +function singleRect(object, bias) { + var rects = object.getClientRects(); + return !rects.length ? object.getBoundingClientRect() : rects[bias < 0 ? 0 : rects.length - 1] +} + +// : (EditorView, number) → {left: number, top: number, right: number, bottom: number} +// Given a position in the document model, get a bounding box of the +// character at that position, relative to the window. +function coordsAtPos(view, pos) { + var ref = view.docView.domFromPos(pos); + var node = ref.node; + var offset = ref.offset; + + // These browsers support querying empty text ranges + if (node.nodeType == 3 && (result.chrome || result.gecko)) { + var rect = singleRect(textRange(node, offset, offset), 0); + // Firefox returns bad results (the position before the space) + // when querying a position directly after line-broken + // whitespace. Detect this situation and and kludge around it + if (result.gecko && offset && /\s/.test(node.nodeValue[offset - 1]) && offset < node.nodeValue.length) { + var rectBefore = singleRect(textRange(node, offset - 1, offset - 1), -1); + if (Math.abs(rectBefore.left - rect.left) < 1 && rectBefore.top == rect.top) { + var rectAfter = singleRect(textRange(node, offset, offset + 1), -1); + return flattenV(rectAfter, rectAfter.left < rectBefore.left) + } + } + return rect + } + + if (node.nodeType == 1 && !view.state.doc.resolve(pos).parent.inlineContent) { + // Return a horizontal line in block context + var top = true, rect$1; + if (offset < node.childNodes.length) { + var after = node.childNodes[offset]; + if (after.nodeType == 1) { rect$1 = after.getBoundingClientRect(); } + } + if (!rect$1 && offset) { + var before = node.childNodes[offset - 1]; + if (before.nodeType == 1) { rect$1 = before.getBoundingClientRect(); top = false; } + } + return flattenH(rect$1 || node.getBoundingClientRect(), top) + } + + // Not Firefox/Chrome, or not in a text node, so we have to use + // actual element/character rectangles to get a solution (this part + // is not very bidi-safe) + // + // Try the left side first, fall back to the right one if that + // doesn't work. + for (var dir = -1; dir < 2; dir += 2) { + if (dir < 0 && offset) { + var prev = (void 0), target = node.nodeType == 3 ? textRange(node, offset - 1, offset) + : (prev = node.childNodes[offset - 1]).nodeType == 3 ? textRange(prev) + : prev.nodeType == 1 && prev.nodeName != "BR" ? prev : null; // BR nodes tend to only return the rectangle before them + if (target) { + var rect$2 = singleRect(target, 1); + if (rect$2.top < rect$2.bottom) { return flattenV(rect$2, false) } + } + } else if (dir > 0 && offset < nodeSize(node)) { + var next = (void 0), target$1 = node.nodeType == 3 ? textRange(node, offset, offset + 1) + : (next = node.childNodes[offset]).nodeType == 3 ? textRange(next) + : next.nodeType == 1 ? next : null; + if (target$1) { + var rect$3 = singleRect(target$1, -1); + if (rect$3.top < rect$3.bottom) { return flattenV(rect$3, true) } + } + } + } + // All else failed, just try to get a rectangle for the target node + return flattenV(singleRect(node.nodeType == 3 ? textRange(node) : node, 0), false) +} + +function flattenV(rect, left) { + if (rect.width == 0) { return rect } + var x = left ? rect.left : rect.right; + return {top: rect.top, bottom: rect.bottom, left: x, right: x} +} + +function flattenH(rect, top) { + if (rect.height == 0) { return rect } + var y = top ? rect.top : rect.bottom; + return {top: y, bottom: y, left: rect.left, right: rect.right} +} + +function withFlushedState(view, state, f) { + var viewState = view.state, active = view.root.activeElement; + if (viewState != state) { view.updateState(state); } + if (active != view.dom) { view.focus(); } + try { + return f() + } finally { + if (viewState != state) { view.updateState(viewState); } + if (active != view.dom) { active.focus(); } + } +} + +// : (EditorView, number, number) +// Whether vertical position motion in a given direction +// from a position would leave a text block. +function endOfTextblockVertical(view, state, dir) { + var sel = state.selection; + var $pos = dir == "up" ? sel.$anchor.min(sel.$head) : sel.$anchor.max(sel.$head); + return withFlushedState(view, state, function () { + var ref = view.docView.domFromPos($pos.pos); + var dom = ref.node; + for (;;) { + var nearest = view.docView.nearestDesc(dom, true); + if (!nearest) { break } + if (nearest.node.isBlock) { dom = nearest.dom; break } + dom = nearest.dom.parentNode; + } + var coords = coordsAtPos(view, $pos.pos); + for (var child = dom.firstChild; child; child = child.nextSibling) { + var boxes = (void 0); + if (child.nodeType == 1) { boxes = child.getClientRects(); } + else if (child.nodeType == 3) { boxes = textRange(child, 0, child.nodeValue.length).getClientRects(); } + else { continue } + for (var i = 0; i < boxes.length; i++) { + var box = boxes[i]; + if (box.bottom > box.top && (dir == "up" ? box.bottom < coords.top + 1 : box.top > coords.bottom - 1)) + { return false } + } + } + return true + }) +} + +var maybeRTL = /[\u0590-\u08ac]/; + +function endOfTextblockHorizontal(view, state, dir) { + var ref = state.selection; + var $head = ref.$head; + if (!$head.parent.isTextblock) { return false } + var offset = $head.parentOffset, atStart = !offset, atEnd = offset == $head.parent.content.size; + var sel = getSelection(); + // If the textblock is all LTR, or the browser doesn't support + // Selection.modify (Edge), fall back to a primitive approach + if (!maybeRTL.test($head.parent.textContent) || !sel.modify) + { return dir == "left" || dir == "backward" ? atStart : atEnd } + + return withFlushedState(view, state, function () { + // This is a huge hack, but appears to be the best we can + // currently do: use `Selection.modify` to move the selection by + // one character, and see if that moves the cursor out of the + // textblock (or doesn't move it at all, when at the start/end of + // the document). + var oldRange = sel.getRangeAt(0), oldNode = sel.focusNode, oldOff = sel.focusOffset; + var oldBidiLevel = sel.caretBidiLevel; // Only for Firefox + sel.modify("move", dir, "character"); + var parentDOM = $head.depth ? view.docView.domAfterPos($head.before()) : view.dom; + var result = !parentDOM.contains(sel.focusNode.nodeType == 1 ? sel.focusNode : sel.focusNode.parentNode) || + (oldNode == sel.focusNode && oldOff == sel.focusOffset); + // Restore the previous selection + sel.removeAllRanges(); + sel.addRange(oldRange); + if (oldBidiLevel != null) { sel.caretBidiLevel = oldBidiLevel; } + return result + }) +} + +var cachedState = null, cachedDir = null, cachedResult = false; +function endOfTextblock(view, state, dir) { + if (cachedState == state && cachedDir == dir) { return cachedResult } + cachedState = state; cachedDir = dir; + return cachedResult = dir == "up" || dir == "down" + ? endOfTextblockVertical(view, state, dir) + : endOfTextblockHorizontal(view, state, dir) +} + +// NodeView:: interface +// +// By default, document nodes are rendered using the result of the +// [`toDOM`](#model.NodeSpec.toDOM) method of their spec, and managed +// entirely by the editor. For some use cases, such as embedded +// node-specific editing interfaces, you want more control over +// the behavior of a node's in-editor representation, and need to +// [define](#view.EditorProps.nodeViews) a custom node view. +// +// Objects returned as node views must conform to this interface. +// +// dom:: ?dom.Node +// The outer DOM node that represents the document node. When not +// given, the default strategy is used to create a DOM node. +// +// contentDOM:: ?dom.Node +// The DOM node that should hold the node's content. Only meaningful +// if the node view also defines a `dom` property and if its node +// type is not a leaf node type. When this is present, ProseMirror +// will take care of rendering the node's children into it. When it +// is not present, the node view itself is responsible for rendering +// (or deciding not to render) its child nodes. +// +// update:: ?(node: Node, decorations: [Decoration]) → bool +// When given, this will be called when the view is updating itself. +// It will be given a node (possibly of a different type), and an +// array of active decorations (which are automatically drawn, and +// the node view may ignore if it isn't interested in them), and +// should return true if it was able to update to that node, and +// false otherwise. If the node view has a `contentDOM` property (or +// no `dom` property), updating its child nodes will be handled by +// ProseMirror. +// +// selectNode:: ?() +// Can be used to override the way the node's selected status (as a +// node selection) is displayed. +// +// deselectNode:: ?() +// When defining a `selectNode` method, you should also provide a +// `deselectNode` method to remove the effect again. +// +// setSelection:: ?(anchor: number, head: number, root: dom.Document) +// This will be called to handle setting the selection inside the +// node. The `anchor` and `head` positions are relative to the start +// of the node. By default, a DOM selection will be created between +// the DOM positions corresponding to those positions, but if you +// override it you can do something else. +// +// stopEvent:: ?(event: dom.Event) → bool +// Can be used to prevent the editor view from trying to handle some +// or all DOM events that bubble up from the node view. Events for +// which this returns true are not handled by the editor. +// +// ignoreMutation:: ?(dom.MutationRecord) → bool +// Called when a DOM +// [mutation](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) +// or a selection change happens within the view. When the change is +// a selection change, the record will have a `type` property of +// `"selection"` (which doesn't occur for native mutation records). +// Return false if the editor should re-read the selection or +// re-parse the range around the mutation, true if it can safely be +// ignored. +// +// destroy:: ?() +// Called when the node view is removed from the editor or the whole +// editor is destroyed. + +// View descriptions are data structures that describe the DOM that is +// used to represent the editor's content. They are used for: +// +// - Incremental redrawing when the document changes +// +// - Figuring out what part of the document a given DOM position +// corresponds to +// +// - Wiring in custom implementations of the editing interface for a +// given node +// +// They form a doubly-linked mutable tree, starting at `view.docView`. + +var NOT_DIRTY = 0, CHILD_DIRTY = 1, CONTENT_DIRTY = 2, NODE_DIRTY = 3; + +// Superclass for the various kinds of descriptions. Defines their +// basic structure and shared methods. +var ViewDesc = function ViewDesc(parent, children, dom, contentDOM) { + this.parent = parent; + this.children = children; + this.dom = dom; + // An expando property on the DOM node provides a link back to its + // description. + dom.pmViewDesc = this; + // This is the node that holds the child views. It may be null for + // descs that don't have children. + this.contentDOM = contentDOM; + this.dirty = NOT_DIRTY; +}; + +var prototypeAccessors = { beforePosition: { configurable: true },size: { configurable: true },border: { configurable: true },posBefore: { configurable: true },posAtStart: { configurable: true },posAfter: { configurable: true },posAtEnd: { configurable: true },contentLost: { configurable: true } }; + +// Used to check whether a given description corresponds to a +// widget/mark/node. +ViewDesc.prototype.matchesWidget = function matchesWidget () { return false }; +ViewDesc.prototype.matchesMark = function matchesMark () { return false }; +ViewDesc.prototype.matchesNode = function matchesNode () { return false }; +ViewDesc.prototype.matchesHack = function matchesHack () { return false }; + +prototypeAccessors.beforePosition.get = function () { return false }; + +// : () → ?ParseRule +// When parsing in-editor content (in domchange.js), we allow +// descriptions to determine the parse rules that should be used to +// parse them. +ViewDesc.prototype.parseRule = function parseRule () { return null }; + +// : (dom.Event) → bool +// Used by the editor's event handler to ignore events that come +// from certain descs. +ViewDesc.prototype.stopEvent = function stopEvent () { return false }; + +// The size of the content represented by this desc. +prototypeAccessors.size.get = function () { + var size = 0; + for (var i = 0; i < this.children.length; i++) { size += this.children[i].size; } + return size +}; + +// For block nodes, this represents the space taken up by their +// start/end tokens. +prototypeAccessors.border.get = function () { return 0 }; + +ViewDesc.prototype.destroy = function destroy () { + this.parent = null; + if (this.dom.pmViewDesc == this) { this.dom.pmViewDesc = null; } + for (var i = 0; i < this.children.length; i++) + { this.children[i].destroy(); } +}; + +ViewDesc.prototype.posBeforeChild = function posBeforeChild (child) { + for (var i = 0, pos = this.posAtStart; i < this.children.length; i++) { + var cur = this.children[i]; + if (cur == child) { return pos } + pos += cur.size; + } +}; + +prototypeAccessors.posBefore.get = function () { + return this.parent.posBeforeChild(this) +}; + +prototypeAccessors.posAtStart.get = function () { + return this.parent ? this.parent.posBeforeChild(this) + this.border : 0 +}; + +prototypeAccessors.posAfter.get = function () { + return this.posBefore + this.size +}; + +prototypeAccessors.posAtEnd.get = function () { + return this.posAtStart + this.size - 2 * this.border +}; + +// : (dom.Node, number, ?number) → number +ViewDesc.prototype.localPosFromDOM = function localPosFromDOM (dom, offset, bias) { + // If the DOM position is in the content, use the child desc after + // it to figure out a position. + if (this.contentDOM && this.contentDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode)) { + if (bias < 0) { + var domBefore, desc; + if (dom == this.contentDOM) { + domBefore = dom.childNodes[offset - 1]; + } else { + while (dom.parentNode != this.contentDOM) { dom = dom.parentNode; } + domBefore = dom.previousSibling; + } + while (domBefore && !((desc = domBefore.pmViewDesc) && desc.parent == this)) { domBefore = domBefore.previousSibling; } + return domBefore ? this.posBeforeChild(desc) + desc.size : this.posAtStart + } else { + var domAfter, desc$1; + if (dom == this.contentDOM) { + domAfter = dom.childNodes[offset]; + } else { + while (dom.parentNode != this.contentDOM) { dom = dom.parentNode; } + domAfter = dom.nextSibling; + } + while (domAfter && !((desc$1 = domAfter.pmViewDesc) && desc$1.parent == this)) { domAfter = domAfter.nextSibling; } + return domAfter ? this.posBeforeChild(desc$1) : this.posAtEnd + } + } + // Otherwise, use various heuristics, falling back on the bias + // parameter, to determine whether to return the position at the + // start or at the end of this view desc. + var atEnd; + if (this.contentDOM && this.contentDOM != this.dom && this.dom.contains(this.contentDOM)) { + atEnd = dom.compareDocumentPosition(this.contentDOM) & 2; + } else if (this.dom.firstChild) { + if (offset == 0) { for (var search = dom;; search = search.parentNode) { + if (search == this.dom) { atEnd = false; break } + if (search.parentNode.firstChild != search) { break } + } } + if (atEnd == null && offset == dom.childNodes.length) { for (var search$1 = dom;; search$1 = search$1.parentNode) { + if (search$1 == this.dom) { atEnd = true; break } + if (search$1.parentNode.lastChild != search$1) { break } + } } + } + return (atEnd == null ? bias > 0 : atEnd) ? this.posAtEnd : this.posAtStart +}; + +// Scan up the dom finding the first desc that is a descendant of +// this one. +ViewDesc.prototype.nearestDesc = function nearestDesc (dom, onlyNodes) { + for (var first = true, cur = dom; cur; cur = cur.parentNode) { + var desc = this.getDesc(cur); + if (desc && (!onlyNodes || desc.node)) { + // If dom is outside of this desc's nodeDOM, don't count it. + if (first && desc.nodeDOM && !(desc.nodeDOM.nodeType == 1 ? desc.nodeDOM.contains(dom) : desc.nodeDOM == dom)) { first = false; } + else { return desc } + } + } +}; + +ViewDesc.prototype.getDesc = function getDesc (dom) { + var desc = dom.pmViewDesc; + for (var cur = desc; cur; cur = cur.parent) { if (cur == this) { return desc } } +}; + +ViewDesc.prototype.posFromDOM = function posFromDOM (dom, offset, bias) { + for (var scan = dom;; scan = scan.parentNode) { + var desc = this.getDesc(scan); + if (desc) { return desc.localPosFromDOM(dom, offset, bias) } + } +}; + +// : (number) → ?NodeViewDesc +// Find the desc for the node after the given pos, if any. (When a +// parent node overrode rendering, there might not be one.) +ViewDesc.prototype.descAt = function descAt (pos) { + for (var i = 0, offset = 0; i < this.children.length; i++) { + var child = this.children[i], end = offset + child.size; + if (offset == pos && end != offset) { + while (!child.border && child.children.length) { child = child.children[0]; } + return child + } + if (pos < end) { return child.descAt(pos - offset - child.border) } + offset = end; + } +}; + +// : (number) → {node: dom.Node, offset: number} +ViewDesc.prototype.domFromPos = function domFromPos (pos) { + if (!this.contentDOM) { return {node: this.dom, offset: 0} } + for (var offset = 0, i = 0;; i++) { + if (offset == pos) { + while (i < this.children.length && (this.children[i].beforePosition || this.children[i].dom.parentNode != this.contentDOM)) { i++; } + return {node: this.contentDOM, + offset: i == this.children.length ? this.contentDOM.childNodes.length : domIndex(this.children[i].dom)} + } + if (i == this.children.length) { throw new Error("Invalid position " + pos) } + var child = this.children[i], end = offset + child.size; + if (pos < end) { return child.domFromPos(pos - offset - child.border) } + offset = end; + } +}; + +// Used to find a DOM range in a single parent for a given changed +// range. +ViewDesc.prototype.parseRange = function parseRange (from, to, base) { + if ( base === void 0 ) base = 0; + + if (this.children.length == 0) + { return {node: this.contentDOM, from: from, to: to, fromOffset: 0, toOffset: this.contentDOM.childNodes.length} } + + var fromOffset = -1, toOffset = -1; + for (var offset = base, i = 0;; i++) { + var child = this.children[i], end = offset + child.size; + if (fromOffset == -1 && from <= end) { + var childBase = offset + child.border; + // FIXME maybe descend mark views to parse a narrower range? + if (from >= childBase && to <= end - child.border && child.node && + child.contentDOM && this.contentDOM.contains(child.contentDOM)) + { return child.parseRange(from, to, childBase) } + + from = offset; + for (var j = i; j > 0; j--) { + var prev = this.children[j - 1]; + if (prev.size && prev.dom.parentNode == this.contentDOM && !prev.emptyChildAt(1)) { + fromOffset = domIndex(prev.dom) + 1; + break + } + from -= prev.size; + } + if (fromOffset == -1) { fromOffset = 0; } + } + if (fromOffset > -1 && to <= end) { + to = end; + for (var j$1 = i + 1; j$1 < this.children.length; j$1++) { + var next = this.children[j$1]; + if (next.size && next.dom.parentNode == this.contentDOM && !next.emptyChildAt(-1)) { + toOffset = domIndex(next.dom); + break + } + to += next.size; + } + if (toOffset == -1) { toOffset = this.contentDOM.childNodes.length; } + break + } + offset = end; + } + return {node: this.contentDOM, from: from, to: to, fromOffset: fromOffset, toOffset: toOffset} +}; + +ViewDesc.prototype.emptyChildAt = function emptyChildAt (side) { + if (this.border || !this.contentDOM || !this.children.length) { return false } + var child = this.children[side < 0 ? 0 : this.children.length - 1]; + return child.size == 0 || child.emptyChildAt(side) +}; + +// : (number) → dom.Node +ViewDesc.prototype.domAfterPos = function domAfterPos (pos) { + var ref = this.domFromPos(pos); + var node = ref.node; + var offset = ref.offset; + if (node.nodeType != 1 || offset == node.childNodes.length) + { throw new RangeError("No node after pos " + pos) } + return node.childNodes[offset] +}; + +// : (number, number, dom.Document) +// View descs are responsible for setting any selection that falls +// entirely inside of them, so that custom implementations can do +// custom things with the selection. Note that this falls apart when +// a selection starts in such a node and ends in another, in which +// case we just use whatever domFromPos produces as a best effort. +ViewDesc.prototype.setSelection = function setSelection (anchor, head, root, force) { + // If the selection falls entirely in a child, give it to that child + var from = Math.min(anchor, head), to = Math.max(anchor, head); + for (var i = 0, offset = 0; i < this.children.length; i++) { + var child = this.children[i], end = offset + child.size; + if (from > offset && to < end) + { return child.setSelection(anchor - offset - child.border, head - offset - child.border, root, force) } + offset = end; + } + + var anchorDOM = this.domFromPos(anchor), headDOM = this.domFromPos(head); + var domSel = root.getSelection(), range = document.createRange(); + if (!force && + isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset) && + isEquivalentPosition(headDOM.node, headDOM.offset, domSel.focusNode, domSel.focusOffset)) + { return } + + // Selection.extend can be used to create an 'inverted' selection + // (one where the focus is before the anchor), but not all + // browsers support it yet. + if (domSel.extend) { + range.setEnd(anchorDOM.node, anchorDOM.offset); + range.collapse(false); + } else { + if (anchor > head) { var tmp = anchorDOM; anchorDOM = headDOM; headDOM = tmp; } + range.setEnd(headDOM.node, headDOM.offset); + range.setStart(anchorDOM.node, anchorDOM.offset); + } + domSel.removeAllRanges(); + domSel.addRange(range); + if (domSel.extend) + { domSel.extend(headDOM.node, headDOM.offset); } +}; + +// : (dom.MutationRecord) → bool +ViewDesc.prototype.ignoreMutation = function ignoreMutation (_mutation) { + return !this.contentDOM +}; + +prototypeAccessors.contentLost.get = function () { + return this.contentDOM && this.contentDOM != this.dom && !this.dom.contains(this.contentDOM) +}; + +// Remove a subtree of the element tree that has been touched +// by a DOM change, so that the next update will redraw it. +ViewDesc.prototype.markDirty = function markDirty (from, to) { + for (var offset = 0, i = 0; i < this.children.length; i++) { + var child = this.children[i], end = offset + child.size; + if (offset == end ? from <= end && to >= offset : from < end && to > offset) { + var startInside = offset + child.border, endInside = end - child.border; + if (from >= startInside && to <= endInside) { + this.dirty = from == offset || to == end ? CONTENT_DIRTY : CHILD_DIRTY; + if (from == startInside && to == endInside && + (child.contentLost || child.dom.parentNode != this.contentDOM)) { child.dirty = NODE_DIRTY; } + else { child.markDirty(from - startInside, to - startInside); } + return + } else { + child.dirty = NODE_DIRTY; + } + } + offset = end; + } + this.dirty = CONTENT_DIRTY; +}; + +ViewDesc.prototype.markParentsDirty = function markParentsDirty () { + for (var node = this.parent; node; node = node.parent) { + var dirty = CONTENT_DIRTY ; + if (node.dirty < dirty) { node.dirty = dirty; } + } +}; + +Object.defineProperties( ViewDesc.prototype, prototypeAccessors ); + +// Reused array to avoid allocating fresh arrays for things that will +// stay empty anyway. +var nothing = []; + +// A widget desc represents a widget decoration, which is a DOM node +// drawn between the document nodes. +var WidgetViewDesc = /*@__PURE__*/(function (ViewDesc) { + function WidgetViewDesc(parent, widget, view, pos) { + var self, dom = widget.type.toDOM; + if (typeof dom == "function") { dom = dom(view, function () { + if (!self) { return pos } + if (self.parent) { return self.parent.posBeforeChild(self) } + }); } + if (!widget.type.spec.raw) { + if (dom.nodeType != 1) { + var wrap = document.createElement("span"); + wrap.appendChild(dom); + dom = wrap; + } + dom.contentEditable = false; + dom.classList.add("ProseMirror-widget"); + } + ViewDesc.call(this, parent, nothing, dom, null); + this.widget = widget; + self = this; + } + + if ( ViewDesc ) WidgetViewDesc.__proto__ = ViewDesc; + WidgetViewDesc.prototype = Object.create( ViewDesc && ViewDesc.prototype ); + WidgetViewDesc.prototype.constructor = WidgetViewDesc; + + var prototypeAccessors$1 = { beforePosition: { configurable: true } }; + + prototypeAccessors$1.beforePosition.get = function () { + return this.widget.type.side < 0 + }; + + WidgetViewDesc.prototype.matchesWidget = function matchesWidget (widget) { + return this.dirty == NOT_DIRTY && widget.type.eq(this.widget.type) + }; + + WidgetViewDesc.prototype.parseRule = function parseRule () { return {ignore: true} }; + + WidgetViewDesc.prototype.stopEvent = function stopEvent (event) { + var stop = this.widget.spec.stopEvent; + return stop ? stop(event) : false + }; + + Object.defineProperties( WidgetViewDesc.prototype, prototypeAccessors$1 ); + + return WidgetViewDesc; +}(ViewDesc)); + +var CompositionViewDesc = /*@__PURE__*/(function (ViewDesc) { + function CompositionViewDesc(parent, dom, textDOM, text) { + ViewDesc.call(this, parent, nothing, dom, null); + this.textDOM = textDOM; + this.text = text; + } + + if ( ViewDesc ) CompositionViewDesc.__proto__ = ViewDesc; + CompositionViewDesc.prototype = Object.create( ViewDesc && ViewDesc.prototype ); + CompositionViewDesc.prototype.constructor = CompositionViewDesc; + + var prototypeAccessors$2 = { size: { configurable: true } }; + + prototypeAccessors$2.size.get = function () { return this.text.length }; + + CompositionViewDesc.prototype.localPosFromDOM = function localPosFromDOM (dom, offset) { + if (dom != this.textDOM) { return this.posAtStart + (offset ? this.size : 0) } + return this.posAtStart + offset + }; + + CompositionViewDesc.prototype.domFromPos = function domFromPos (pos) { + return {node: this.textDOM, offset: pos} + }; + + CompositionViewDesc.prototype.ignoreMutation = function ignoreMutation (mut) { + return mut.type === 'characterData' && mut.target.nodeValue == mut.oldValue + }; + + Object.defineProperties( CompositionViewDesc.prototype, prototypeAccessors$2 ); + + return CompositionViewDesc; +}(ViewDesc)); + +// A mark desc represents a mark. May have multiple children, +// depending on how the mark is split. Note that marks are drawn using +// a fixed nesting order, for simplicity and predictability, so in +// some cases they will be split more often than would appear +// necessary. +var MarkViewDesc = /*@__PURE__*/(function (ViewDesc) { + function MarkViewDesc(parent, mark, dom, contentDOM) { + ViewDesc.call(this, parent, [], dom, contentDOM); + this.mark = mark; + } + + if ( ViewDesc ) MarkViewDesc.__proto__ = ViewDesc; + MarkViewDesc.prototype = Object.create( ViewDesc && ViewDesc.prototype ); + MarkViewDesc.prototype.constructor = MarkViewDesc; + + MarkViewDesc.create = function create (parent, mark, inline, view) { + var custom = view.nodeViews[mark.type.name]; + var spec = custom && custom(mark, view, inline); + if (!spec || !spec.dom) + { spec = prosemirrorModel.DOMSerializer.renderSpec(document, mark.type.spec.toDOM(mark, inline)); } + return new MarkViewDesc(parent, mark, spec.dom, spec.contentDOM || spec.dom) + }; + + MarkViewDesc.prototype.parseRule = function parseRule () { return {mark: this.mark.type.name, attrs: this.mark.attrs, contentElement: this.contentDOM} }; + + MarkViewDesc.prototype.matchesMark = function matchesMark (mark) { return this.dirty != NODE_DIRTY && this.mark.eq(mark) }; + + MarkViewDesc.prototype.markDirty = function markDirty (from, to) { + ViewDesc.prototype.markDirty.call(this, from, to); + // Move dirty info to nearest node view + if (this.dirty != NOT_DIRTY) { + var parent = this.parent; + while (!parent.node) { parent = parent.parent; } + if (parent.dirty < this.dirty) { parent.dirty = this.dirty; } + this.dirty = NOT_DIRTY; + } + }; + + MarkViewDesc.prototype.slice = function slice (from, to, view) { + var copy = MarkViewDesc.create(this.parent, this.mark, true, view); + var nodes = this.children, size = this.size; + if (to < size) { nodes = replaceNodes(nodes, to, size, view); } + if (from > 0) { nodes = replaceNodes(nodes, 0, from, view); } + for (var i = 0; i < nodes.length; i++) { nodes[i].parent = copy; } + copy.children = nodes; + return copy + }; + + return MarkViewDesc; +}(ViewDesc)); + +// Node view descs are the main, most common type of view desc, and +// correspond to an actual node in the document. Unlike mark descs, +// they populate their child array themselves. +var NodeViewDesc = /*@__PURE__*/(function (ViewDesc) { + function NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos) { + ViewDesc.call(this, parent, node.isLeaf ? nothing : [], dom, contentDOM); + this.nodeDOM = nodeDOM; + this.node = node; + this.outerDeco = outerDeco; + this.innerDeco = innerDeco; + if (contentDOM) { this.updateChildren(view, pos); } + } + + if ( ViewDesc ) NodeViewDesc.__proto__ = ViewDesc; + NodeViewDesc.prototype = Object.create( ViewDesc && ViewDesc.prototype ); + NodeViewDesc.prototype.constructor = NodeViewDesc; + + var prototypeAccessors$3 = { size: { configurable: true },border: { configurable: true } }; + + // By default, a node is rendered using the `toDOM` method from the + // node type spec. But client code can use the `nodeViews` spec to + // supply a custom node view, which can influence various aspects of + // the way the node works. + // + // (Using subclassing for this was intentionally decided against, + // since it'd require exposing a whole slew of finnicky + // implementation details to the user code that they probably will + // never need.) + NodeViewDesc.create = function create (parent, node, outerDeco, innerDeco, view, pos) { + var assign; + + var custom = view.nodeViews[node.type.name], descObj; + var spec = custom && custom(node, view, function () { + // (This is a function that allows the custom view to find its + // own position) + if (!descObj) { return pos } + if (descObj.parent) { return descObj.parent.posBeforeChild(descObj) } + }, outerDeco); + + var dom = spec && spec.dom, contentDOM = spec && spec.contentDOM; + if (node.isText) { + if (!dom) { dom = document.createTextNode(node.text); } + else if (dom.nodeType != 3) { throw new RangeError("Text must be rendered as a DOM text node") } + } else if (!dom) { +((assign = prosemirrorModel.DOMSerializer.renderSpec(document, node.type.spec.toDOM(node)), dom = assign.dom, contentDOM = assign.contentDOM)); + } + if (!contentDOM && !node.isText && dom.nodeName != "BR") { // Chrome gets confused by
    + if (!dom.hasAttribute("contenteditable")) { dom.contentEditable = false; } + if (node.type.spec.draggable) { dom.draggable = true; } + } + + var nodeDOM = dom; + dom = applyOuterDeco(dom, outerDeco, node); + + if (spec) + { return descObj = new CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, + spec, view, pos + 1) } + else if (node.isText) + { return new TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM, view) } + else + { return new NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos + 1) } + }; + + NodeViewDesc.prototype.parseRule = function parseRule () { + var this$1 = this; + + // Experimental kludge to allow opt-in re-parsing of nodes + if (this.node.type.spec.reparseInView) { return null } + // FIXME the assumption that this can always return the current + // attrs means that if the user somehow manages to change the + // attrs in the dom, that won't be picked up. Not entirely sure + // whether this is a problem + var rule = {node: this.node.type.name, attrs: this.node.attrs}; + if (this.node.type.spec.code) { rule.preserveWhitespace = "full"; } + if (this.contentDOM && !this.contentLost) { rule.contentElement = this.contentDOM; } + else { rule.getContent = function () { return this$1.contentDOM ? prosemirrorModel.Fragment.empty : this$1.node.content; }; } + return rule + }; + + NodeViewDesc.prototype.matchesNode = function matchesNode (node, outerDeco, innerDeco) { + return this.dirty == NOT_DIRTY && node.eq(this.node) && + sameOuterDeco(outerDeco, this.outerDeco) && innerDeco.eq(this.innerDeco) + }; + + prototypeAccessors$3.size.get = function () { return this.node.nodeSize }; + + prototypeAccessors$3.border.get = function () { return this.node.isLeaf ? 0 : 1 }; + + // Syncs `this.children` to match `this.node.content` and the local + // decorations, possibly introducing nesting for marks. Then, in a + // separate step, syncs the DOM inside `this.contentDOM` to + // `this.children`. + NodeViewDesc.prototype.updateChildren = function updateChildren (view, pos) { + var this$1 = this; + + var inline = this.node.inlineContent, off = pos; + var composition = inline && view.composing && this.localCompositionNode(view, pos); + var updater = new ViewTreeUpdater(this, composition && composition.node); + iterDeco(this.node, this.innerDeco, function (widget, i) { + if (widget.spec.marks) + { updater.syncToMarks(widget.spec.marks, inline, view); } + else if (widget.type.side >= 0) + { updater.syncToMarks(i == this$1.node.childCount ? prosemirrorModel.Mark.none : this$1.node.child(i).marks, inline, view); } + // If the next node is a desc matching this widget, reuse it, + // otherwise insert the widget as a new view desc. + updater.placeWidget(widget, view, off); + }, function (child, outerDeco, innerDeco, i) { + // Make sure the wrapping mark descs match the node's marks. + updater.syncToMarks(child.marks, inline, view); + // Either find an existing desc that exactly matches this node, + // and drop the descs before it. + updater.findNodeMatch(child, outerDeco, innerDeco, i) || + // Or try updating the next desc to reflect this node. + updater.updateNextNode(child, outerDeco, innerDeco, view, i) || + // Or just add it as a new desc. + updater.addNode(child, outerDeco, innerDeco, view, off); + off += child.nodeSize; + }); + // Drop all remaining descs after the current position. + updater.syncToMarks(nothing, inline, view); + if (this.node.isTextblock) { updater.addTextblockHacks(); } + updater.destroyRest(); + + // Sync the DOM if anything changed + if (updater.changed || this.dirty == CONTENT_DIRTY) { + // May have to protect focused DOM from being changed if a composition is active + if (composition) { this.protectLocalComposition(view, composition); } + this.renderChildren(); + } + }; + + NodeViewDesc.prototype.renderChildren = function renderChildren () { + renderDescs(this.contentDOM, this.children); + if (result.ios) { iosHacks(this.dom); } + }; + + NodeViewDesc.prototype.localCompositionNode = function localCompositionNode (view, pos) { + // Only do something if both the selection and a focused text node + // are inside of this node, and the node isn't already part of a + // view that's a child of this view + var ref = view.state.selection; + var from = ref.from; + var to = ref.to; + if (!(view.state.selection instanceof prosemirrorState.TextSelection) || from < pos || to > pos + this.node.content.size) { return } + var sel = view.root.getSelection(); + var textNode = nearbyTextNode(sel.focusNode, sel.focusOffset); + if (!textNode || !this.dom.contains(textNode.parentNode)) { return } + + // Find the text in the focused node in the node, stop if it's not + // there (may have been modified through other means, in which + // case it should overwritten) + var text = textNode.nodeValue; + var textPos = findTextInFragment(this.node.content, text, from - pos, to - pos); + + return textPos < 0 ? null : {node: textNode, pos: textPos, text: text} + }; + + NodeViewDesc.prototype.protectLocalComposition = function protectLocalComposition (view, ref) { + var node = ref.node; + var pos = ref.pos; + var text = ref.text; + + // The node is already part of a local view desc, leave it there + if (this.getDesc(node)) { return } + + // Create a composition view for the orphaned nodes + var topNode = node; + for (;; topNode = topNode.parentNode) { + if (topNode.parentNode == this.contentDOM) { break } + while (topNode.previousSibling) { topNode.parentNode.removeChild(topNode.previousSibling); } + while (topNode.nextSibling) { topNode.parentNode.removeChild(topNode.nextSibling); } + if (topNode.pmViewDesc) { topNode.pmViewDesc = null; } + } + var desc = new CompositionViewDesc(this, topNode, node, text); + view.compositionNodes.push(desc); + + // Patch up this.children to contain the composition view + this.children = replaceNodes(this.children, pos, pos + text.length, view, desc); + }; + + // : (Node, [Decoration], DecorationSet, EditorView) → bool + // If this desc be updated to match the given node decoration, + // do so and return true. + NodeViewDesc.prototype.update = function update (node, outerDeco, innerDeco, view) { + if (this.dirty == NODE_DIRTY || + !node.sameMarkup(this.node)) { return false } + this.updateInner(node, outerDeco, innerDeco, view); + return true + }; + + NodeViewDesc.prototype.updateInner = function updateInner (node, outerDeco, innerDeco, view) { + this.updateOuterDeco(outerDeco); + this.node = node; + this.innerDeco = innerDeco; + if (this.contentDOM) { this.updateChildren(view, this.posAtStart); } + this.dirty = NOT_DIRTY; + }; + + NodeViewDesc.prototype.updateOuterDeco = function updateOuterDeco (outerDeco) { + if (sameOuterDeco(outerDeco, this.outerDeco)) { return } + var needsWrap = this.nodeDOM.nodeType != 1; + var oldDOM = this.dom; + this.dom = patchOuterDeco(this.dom, this.nodeDOM, + computeOuterDeco(this.outerDeco, this.node, needsWrap), + computeOuterDeco(outerDeco, this.node, needsWrap)); + if (this.dom != oldDOM) { + oldDOM.pmViewDesc = null; + this.dom.pmViewDesc = this; + } + this.outerDeco = outerDeco; + }; + + // Mark this node as being the selected node. + NodeViewDesc.prototype.selectNode = function selectNode () { + this.nodeDOM.classList.add("ProseMirror-selectednode"); + if (this.contentDOM || !this.node.type.spec.draggable) { this.dom.draggable = true; } + }; + + // Remove selected node marking from this node. + NodeViewDesc.prototype.deselectNode = function deselectNode () { + this.nodeDOM.classList.remove("ProseMirror-selectednode"); + if (this.contentDOM || !this.node.type.spec.draggable) { this.dom.draggable = false; } + }; + + Object.defineProperties( NodeViewDesc.prototype, prototypeAccessors$3 ); + + return NodeViewDesc; +}(ViewDesc)); + +// Create a view desc for the top-level document node, to be exported +// and used by the view class. +function docViewDesc(doc, outerDeco, innerDeco, dom, view) { + applyOuterDeco(dom, outerDeco, doc); + return new NodeViewDesc(null, doc, outerDeco, innerDeco, dom, dom, dom, view, 0) +} + +var TextViewDesc = /*@__PURE__*/(function (NodeViewDesc) { + function TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM, view) { + NodeViewDesc.call(this, parent, node, outerDeco, innerDeco, dom, null, nodeDOM, view); + } + + if ( NodeViewDesc ) TextViewDesc.__proto__ = NodeViewDesc; + TextViewDesc.prototype = Object.create( NodeViewDesc && NodeViewDesc.prototype ); + TextViewDesc.prototype.constructor = TextViewDesc; + + TextViewDesc.prototype.parseRule = function parseRule () { + return {skip: this.nodeDOM.parentNode || true} + }; + + TextViewDesc.prototype.update = function update (node, outerDeco) { + if (this.dirty == NODE_DIRTY || (this.dirty != NOT_DIRTY && !this.inParent()) || + !node.sameMarkup(this.node)) { return false } + this.updateOuterDeco(outerDeco); + if ((this.dirty != NOT_DIRTY || node.text != this.node.text) && node.text != this.nodeDOM.nodeValue) + { this.nodeDOM.nodeValue = node.text; } + this.node = node; + this.dirty = NOT_DIRTY; + return true + }; + + TextViewDesc.prototype.inParent = function inParent () { + var parentDOM = this.parent.contentDOM; + for (var n = this.nodeDOM; n; n = n.parentNode) { if (n == parentDOM) { return true } } + return false + }; + + TextViewDesc.prototype.domFromPos = function domFromPos (pos) { + return {node: this.nodeDOM, offset: pos} + }; + + TextViewDesc.prototype.localPosFromDOM = function localPosFromDOM (dom, offset, bias) { + if (dom == this.nodeDOM) { return this.posAtStart + Math.min(offset, this.node.text.length) } + return NodeViewDesc.prototype.localPosFromDOM.call(this, dom, offset, bias) + }; + + TextViewDesc.prototype.ignoreMutation = function ignoreMutation (mutation) { + return mutation.type != "characterData" && mutation.type != "selection" + }; + + TextViewDesc.prototype.slice = function slice (from, to, view) { + var node = this.node.cut(from, to), dom = document.createTextNode(node.text); + return new TextViewDesc(this.parent, node, this.outerDeco, this.innerDeco, dom, dom, view) + }; + + return TextViewDesc; +}(NodeViewDesc)); + +// A dummy desc used to tag trailing BR or span nodes created to work +// around contentEditable terribleness. +var BRHackViewDesc = /*@__PURE__*/(function (ViewDesc) { + function BRHackViewDesc () { + ViewDesc.apply(this, arguments); + } + + if ( ViewDesc ) BRHackViewDesc.__proto__ = ViewDesc; + BRHackViewDesc.prototype = Object.create( ViewDesc && ViewDesc.prototype ); + BRHackViewDesc.prototype.constructor = BRHackViewDesc; + + BRHackViewDesc.prototype.parseRule = function parseRule () { return {ignore: true} }; + BRHackViewDesc.prototype.matchesHack = function matchesHack () { return this.dirty == NOT_DIRTY }; + + return BRHackViewDesc; +}(ViewDesc)); + +// A separate subclass is used for customized node views, so that the +// extra checks only have to be made for nodes that are actually +// customized. +var CustomNodeViewDesc = /*@__PURE__*/(function (NodeViewDesc) { + function CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, spec, view, pos) { + NodeViewDesc.call(this, parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos); + this.spec = spec; + } + + if ( NodeViewDesc ) CustomNodeViewDesc.__proto__ = NodeViewDesc; + CustomNodeViewDesc.prototype = Object.create( NodeViewDesc && NodeViewDesc.prototype ); + CustomNodeViewDesc.prototype.constructor = CustomNodeViewDesc; + + // A custom `update` method gets to decide whether the update goes + // through. If it does, and there's a `contentDOM` node, our logic + // updates the children. + CustomNodeViewDesc.prototype.update = function update (node, outerDeco, innerDeco, view) { + if (this.dirty == NODE_DIRTY) { return false } + if (this.spec.update) { + var result = this.spec.update(node, outerDeco); + if (result) { this.updateInner(node, outerDeco, innerDeco, view); } + return result + } else if (!this.contentDOM && !node.isLeaf) { + return false + } else { + return NodeViewDesc.prototype.update.call(this, node, outerDeco, innerDeco, view) + } + }; + + CustomNodeViewDesc.prototype.selectNode = function selectNode () { + this.spec.selectNode ? this.spec.selectNode() : NodeViewDesc.prototype.selectNode.call(this); + }; + + CustomNodeViewDesc.prototype.deselectNode = function deselectNode () { + this.spec.deselectNode ? this.spec.deselectNode() : NodeViewDesc.prototype.deselectNode.call(this); + }; + + CustomNodeViewDesc.prototype.setSelection = function setSelection (anchor, head, root, force) { + this.spec.setSelection ? this.spec.setSelection(anchor, head, root) + : NodeViewDesc.prototype.setSelection.call(this, anchor, head, root, force); + }; + + CustomNodeViewDesc.prototype.destroy = function destroy () { + if (this.spec.destroy) { this.spec.destroy(); } + NodeViewDesc.prototype.destroy.call(this); + }; + + CustomNodeViewDesc.prototype.stopEvent = function stopEvent (event) { + return this.spec.stopEvent ? this.spec.stopEvent(event) : false + }; + + CustomNodeViewDesc.prototype.ignoreMutation = function ignoreMutation (mutation) { + return this.spec.ignoreMutation ? this.spec.ignoreMutation(mutation) : NodeViewDesc.prototype.ignoreMutation.call(this, mutation) + }; + + return CustomNodeViewDesc; +}(NodeViewDesc)); + +// : (dom.Node, [ViewDesc]) +// Sync the content of the given DOM node with the nodes associated +// with the given array of view descs, recursing into mark descs +// because this should sync the subtree for a whole node at a time. +function renderDescs(parentDOM, descs) { + var dom = parentDOM.firstChild; + for (var i = 0; i < descs.length; i++) { + var desc = descs[i], childDOM = desc.dom; + if (childDOM.parentNode == parentDOM) { + while (childDOM != dom) { dom = rm(dom); } + dom = dom.nextSibling; + } else { + parentDOM.insertBefore(childDOM, dom); + } + if (desc instanceof MarkViewDesc) { + var pos = dom ? dom.previousSibling : parentDOM.lastChild; + renderDescs(desc.contentDOM, desc.children); + dom = pos ? pos.nextSibling : parentDOM.firstChild; + } + } + while (dom) { dom = rm(dom); } +} + +function OuterDecoLevel(nodeName) { + if (nodeName) { this.nodeName = nodeName; } +} +OuterDecoLevel.prototype = Object.create(null); + +var noDeco = [new OuterDecoLevel]; + +function computeOuterDeco(outerDeco, node, needsWrap) { + if (outerDeco.length == 0) { return noDeco } + + var top = needsWrap ? noDeco[0] : new OuterDecoLevel, result = [top]; + + for (var i = 0; i < outerDeco.length; i++) { + var attrs = outerDeco[i].type.attrs, cur = top; + if (!attrs) { continue } + if (attrs.nodeName) + { result.push(cur = new OuterDecoLevel(attrs.nodeName)); } + + for (var name in attrs) { + var val = attrs[name]; + if (val == null) { continue } + if (needsWrap && result.length == 1) + { result.push(cur = top = new OuterDecoLevel(node.isInline ? "span" : "div")); } + if (name == "class") { cur.class = (cur.class ? cur.class + " " : "") + val; } + else if (name == "style") { cur.style = (cur.style ? cur.style + ";" : "") + val; } + else if (name != "nodeName") { cur[name] = val; } + } + } + + return result +} + +function patchOuterDeco(outerDOM, nodeDOM, prevComputed, curComputed) { + // Shortcut for trivial case + if (prevComputed == noDeco && curComputed == noDeco) { return nodeDOM } + + var curDOM = nodeDOM; + for (var i = 0; i < curComputed.length; i++) { + var deco = curComputed[i], prev = prevComputed[i]; + if (i) { + var parent = (void 0); + if (prev && prev.nodeName == deco.nodeName && curDOM != outerDOM && + (parent = curDOM.parentNode) && parent.tagName.toLowerCase() == deco.nodeName) { + curDOM = parent; + } else { + parent = document.createElement(deco.nodeName); + parent.appendChild(curDOM); + prev = noDeco[0]; + curDOM = parent; + } + } + patchAttributes(curDOM, prev || noDeco[0], deco); + } + return curDOM +} + +function patchAttributes(dom, prev, cur) { + for (var name in prev) + { if (name != "class" && name != "style" && name != "nodeName" && !(name in cur)) + { dom.removeAttribute(name); } } + for (var name$1 in cur) + { if (name$1 != "class" && name$1 != "style" && name$1 != "nodeName" && cur[name$1] != prev[name$1]) + { dom.setAttribute(name$1, cur[name$1]); } } + if (prev.class != cur.class) { + var prevList = prev.class ? prev.class.split(" ") : nothing; + var curList = cur.class ? cur.class.split(" ") : nothing; + for (var i = 0; i < prevList.length; i++) { if (curList.indexOf(prevList[i]) == -1) + { dom.classList.remove(prevList[i]); } } + for (var i$1 = 0; i$1 < curList.length; i$1++) { if (prevList.indexOf(curList[i$1]) == -1) + { dom.classList.add(curList[i$1]); } } + } + if (prev.style != cur.style) { + if (prev.style) { + var prop = /\s*([\w\-\xa1-\uffff]+)\s*:(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*'|\(.*?\)|[^;])*/g, m; + while (m = prop.exec(prev.style)) + { dom.style.removeProperty(m[1]); } + } + if (cur.style) + { dom.style.cssText += cur.style; } + } +} + +function applyOuterDeco(dom, deco, node) { + return patchOuterDeco(dom, dom, noDeco, computeOuterDeco(deco, node, dom.nodeType != 1)) +} + +// : ([Decoration], [Decoration]) → bool +function sameOuterDeco(a, b) { + if (a.length != b.length) { return false } + for (var i = 0; i < a.length; i++) { if (!a[i].type.eq(b[i].type)) { return false } } + return true +} + +// Remove a DOM node and return its next sibling. +function rm(dom) { + var next = dom.nextSibling; + dom.parentNode.removeChild(dom); + return next +} + +// Helper class for incrementally updating a tree of mark descs and +// the widget and node descs inside of them. +var ViewTreeUpdater = function ViewTreeUpdater(top, lockedNode) { + this.top = top; + this.lock = lockedNode; + // Index into `this.top`'s child array, represents the current + // update position. + this.index = 0; + // When entering a mark, the current top and index are pushed + // onto this. + this.stack = []; + // Tracks whether anything was changed + this.changed = false; + + var pre = preMatch(top.node.content, top.children); + this.preMatched = pre.nodes; + this.preMatchOffset = pre.offset; +}; + +ViewTreeUpdater.prototype.getPreMatch = function getPreMatch (index) { + return index >= this.preMatchOffset ? this.preMatched[index - this.preMatchOffset] : null +}; + +// Destroy and remove the children between the given indices in +// `this.top`. +ViewTreeUpdater.prototype.destroyBetween = function destroyBetween (start, end) { + if (start == end) { return } + for (var i = start; i < end; i++) { this.top.children[i].destroy(); } + this.top.children.splice(start, end - start); + this.changed = true; +}; + +// Destroy all remaining children in `this.top`. +ViewTreeUpdater.prototype.destroyRest = function destroyRest () { + this.destroyBetween(this.index, this.top.children.length); +}; + +// : ([Mark], EditorView) +// Sync the current stack of mark descs with the given array of +// marks, reusing existing mark descs when possible. +ViewTreeUpdater.prototype.syncToMarks = function syncToMarks (marks, inline, view) { + var keep = 0, depth = this.stack.length >> 1; + var maxKeep = Math.min(depth, marks.length); + while (keep < maxKeep && + (keep == depth - 1 ? this.top : this.stack[(keep + 1) << 1]).matchesMark(marks[keep]) && marks[keep].type.spec.spanning !== false) + { keep++; } + + while (keep < depth) { + this.destroyRest(); + this.top.dirty = NOT_DIRTY; + this.index = this.stack.pop(); + this.top = this.stack.pop(); + depth--; + } + while (depth < marks.length) { + this.stack.push(this.top, this.index + 1); + var found = -1; + for (var i = this.index; i < Math.min(this.index + 3, this.top.children.length); i++) { + if (this.top.children[i].matchesMark(marks[depth])) { found = i; break } + } + if (found > -1) { + if (found > this.index) { + this.changed = true; + this.destroyBetween(this.index, found); + } + this.top = this.top.children[this.index]; + } else { + var markDesc = MarkViewDesc.create(this.top, marks[depth], inline, view); + this.top.children.splice(this.index, 0, markDesc); + this.top = markDesc; + this.changed = true; + } + this.index = 0; + depth++; + } +}; + +// : (Node, [Decoration], DecorationSet) → bool +// Try to find a node desc matching the given data. Skip over it and +// return true when successful. +ViewTreeUpdater.prototype.findNodeMatch = function findNodeMatch (node, outerDeco, innerDeco, index) { + var found = -1, preMatch = index < 0 ? undefined : this.getPreMatch(index), children = this.top.children; + if (preMatch && preMatch.matchesNode(node, outerDeco, innerDeco)) { + found = children.indexOf(preMatch); + } else { + for (var i = this.index, e = Math.min(children.length, i + 5); i < e; i++) { + var child = children[i]; + if (child.matchesNode(node, outerDeco, innerDeco) && this.preMatched.indexOf(child) < 0) { + found = i; + break + } + } + } + if (found < 0) { return false } + this.destroyBetween(this.index, found); + this.index++; + return true +}; + +// : (Node, [Decoration], DecorationSet, EditorView, Fragment, number) → bool +// Try to update the next node, if any, to the given data. Checks +// pre-matches to avoid overwriting nodes that could still be used. +ViewTreeUpdater.prototype.updateNextNode = function updateNextNode (node, outerDeco, innerDeco, view, index) { + if (this.index == this.top.children.length) { return false } + var next = this.top.children[this.index]; + if (next instanceof NodeViewDesc) { + var preMatch = this.preMatched.indexOf(next); + if (preMatch > -1 && preMatch + this.preMatchOffset != index) { return false } + var nextDOM = next.dom; + + // Can't update if nextDOM is or contains this.lock, except if + // it's a text node whose content already matches the new text + // and whose decorations match the new ones. + var locked = this.lock && (nextDOM == this.lock || nextDOM.nodeType == 1 && nextDOM.contains(this.lock.parentNode)) && + !(node.isText && next.node && next.node.isText && next.nodeDOM.nodeValue == node.text && + next.dirty != NODE_DIRTY && sameOuterDeco(outerDeco, next.outerDeco)); + if (!locked && next.update(node, outerDeco, innerDeco, view)) { + if (next.dom != nextDOM) { this.changed = true; } + this.index++; + return true + } + } + return false +}; + +// : (Node, [Decoration], DecorationSet, EditorView) +// Insert the node as a newly created node desc. +ViewTreeUpdater.prototype.addNode = function addNode (node, outerDeco, innerDeco, view, pos) { + this.top.children.splice(this.index++, 0, NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos)); + this.changed = true; +}; + +ViewTreeUpdater.prototype.placeWidget = function placeWidget (widget, view, pos) { + if (this.index < this.top.children.length && this.top.children[this.index].matchesWidget(widget)) { + this.index++; + } else { + var desc = new WidgetViewDesc(this.top, widget, view, pos); + this.top.children.splice(this.index++, 0, desc); + this.changed = true; + } +}; + +// Make sure a textblock looks and behaves correctly in +// contentEditable. +ViewTreeUpdater.prototype.addTextblockHacks = function addTextblockHacks () { + var lastChild = this.top.children[this.index - 1]; + while (lastChild instanceof MarkViewDesc) { lastChild = lastChild.children[lastChild.children.length - 1]; } + + if (!lastChild || // Empty textblock + !(lastChild instanceof TextViewDesc) || + /\n$/.test(lastChild.node.text)) { + if (this.index < this.top.children.length && this.top.children[this.index].matchesHack()) { + this.index++; + } else { + var dom = document.createElement("br"); + this.top.children.splice(this.index++, 0, new BRHackViewDesc(this.top, nothing, dom, null)); + this.changed = true; + } + } +}; + +// : (Fragment, [ViewDesc]) → [ViewDesc] +// Iterate from the end of the fragment and array of descs to find +// directly matching ones, in order to avoid overeagerly reusing +// those for other nodes. Returns an array whose positions correspond +// to node positions in the fragment, and whose elements are either +// descs matched to the child at that index, or empty. +function preMatch(frag, descs) { + var result = [], end = frag.childCount; + for (var i = descs.length - 1; end > 0 && i >= 0; i--) { + var desc = descs[i], node = desc.node; + if (!node) { continue } + if (node != frag.child(end - 1)) { break } + result.push(desc); + --end; + } + return {nodes: result.reverse(), offset: end} +} + +function compareSide(a, b) { return a.type.side - b.type.side } + +// : (ViewDesc, DecorationSet, (Decoration, number), (Node, [Decoration], DecorationSet, number)) +// This function abstracts iterating over the nodes and decorations in +// a fragment. Calls `onNode` for each node, with its local and child +// decorations. Splits text nodes when there is a decoration starting +// or ending inside of them. Calls `onWidget` for each widget. +function iterDeco(parent, deco, onWidget, onNode) { + var locals = deco.locals(parent), offset = 0; + // Simple, cheap variant for when there are no local decorations + if (locals.length == 0) { + for (var i = 0; i < parent.childCount; i++) { + var child = parent.child(i); + onNode(child, locals, deco.forChild(offset, child), i); + offset += child.nodeSize; + } + return + } + + var decoIndex = 0, active = [], restNode = null; + for (var parentIndex = 0;;) { + if (decoIndex < locals.length && locals[decoIndex].to == offset) { + var widget = locals[decoIndex++], widgets = (void 0); + while (decoIndex < locals.length && locals[decoIndex].to == offset) + { (widgets || (widgets = [widget])).push(locals[decoIndex++]); } + if (widgets) { + widgets.sort(compareSide); + for (var i$1 = 0; i$1 < widgets.length; i$1++) { onWidget(widgets[i$1], parentIndex); } + } else { + onWidget(widget, parentIndex); + } + } + + var child$1 = (void 0), index = (void 0); + if (restNode) { + index = -1; + child$1 = restNode; + restNode = null; + } else if (parentIndex < parent.childCount) { + index = parentIndex; + child$1 = parent.child(parentIndex++); + } else { + break + } + + for (var i$2 = 0; i$2 < active.length; i$2++) { if (active[i$2].to <= offset) { active.splice(i$2--, 1); } } + while (decoIndex < locals.length && locals[decoIndex].from == offset) { active.push(locals[decoIndex++]); } + + var end = offset + child$1.nodeSize; + if (child$1.isText) { + var cutAt = end; + if (decoIndex < locals.length && locals[decoIndex].from < cutAt) { cutAt = locals[decoIndex].from; } + for (var i$3 = 0; i$3 < active.length; i$3++) { if (active[i$3].to < cutAt) { cutAt = active[i$3].to; } } + if (cutAt < end) { + restNode = child$1.cut(cutAt - offset); + child$1 = child$1.cut(0, cutAt - offset); + end = cutAt; + index = -1; + } + } + + onNode(child$1, active.length ? active.slice() : nothing, deco.forChild(offset, child$1), index); + offset = end; + } +} + +// List markers in Mobile Safari will mysteriously disappear +// sometimes. This works around that. +function iosHacks(dom) { + if (dom.nodeName == "UL" || dom.nodeName == "OL") { + var oldCSS = dom.style.cssText; + dom.style.cssText = oldCSS + "; list-style: square !important"; + window.getComputedStyle(dom).listStyle; + dom.style.cssText = oldCSS; + } +} + +function nearbyTextNode(node, offset) { + for (;;) { + if (node.nodeType == 3) { return node } + if (node.nodeType == 1 && offset > 0) { + if (node.childNodes.length > offset && node.childNodes[offset].nodeType == 3) + { return node.childNodes[offset] } + node = node.childNodes[offset - 1]; + offset = nodeSize(node); + } else if (node.nodeType == 1 && offset < node.childNodes.length) { + node = node.childNodes[offset]; + offset = 0; + } else { + return null + } + } +} + +// Find a piece of text in an inline fragment, overlapping from-to +function findTextInFragment(frag, text, from, to) { + for (var str = "", i = 0, childPos = 0; i < frag.childCount; i++) { + var child = frag.child(i), end = childPos + child.nodeSize; + if (child.isText) { + str += child.text; + if (end >= to) { + var strStart = end - str.length, found = str.lastIndexOf(text); + while (found > -1 && strStart + found > from) { found = str.lastIndexOf(text, found - 1); } + if (found > -1 && strStart + found + text.length >= to) { + return strStart + found + } else if (end > to) { + break + } + } + } else { + str = ""; + } + childPos = end; + } + return -1 +} + +// Replace range from-to in an array of view descs with replacement +// (may be null to just delete). This goes very much against the grain +// of the rest of this code, which tends to create nodes with the +// right shape in one go, rather than messing with them after +// creation, but is necessary in the composition hack. +function replaceNodes(nodes, from, to, view, replacement) { + var result = []; + for (var i = 0, off = 0; i < nodes.length; i++) { + var child = nodes[i], start = off, end = off += child.size; + if (start >= to || end <= from) { + result.push(child); + } else { + if (start < from) { result.push(child.slice(0, from - start, view)); } + if (replacement) { + result.push(replacement); + replacement = null; + } + if (end > to) { result.push(child.slice(to - start, child.size, view)); } + } + } + return result +} + +function moveSelectionBlock(state, dir) { + var ref = state.selection; + var $anchor = ref.$anchor; + var $head = ref.$head; + var $side = dir > 0 ? $anchor.max($head) : $anchor.min($head); + var $start = !$side.parent.inlineContent ? $side : $side.depth ? state.doc.resolve(dir > 0 ? $side.after() : $side.before()) : null; + return $start && prosemirrorState.Selection.findFrom($start, dir) +} + +function apply(view, sel) { + view.dispatch(view.state.tr.setSelection(sel).scrollIntoView()); + return true +} + +function selectHorizontally(view, dir, mods) { + var sel = view.state.selection; + if (sel instanceof prosemirrorState.TextSelection) { + if (!sel.empty || mods.indexOf("s") > -1) { + return false + } else if (view.endOfTextblock(dir > 0 ? "right" : "left")) { + var next = moveSelectionBlock(view.state, dir); + if (next && (next instanceof prosemirrorState.NodeSelection)) { return apply(view, next) } + return false + } else { + var $head = sel.$head, node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter, desc; + if (!node || node.isText) { return false } + var nodePos = dir < 0 ? $head.pos - node.nodeSize : $head.pos; + if (!(node.isAtom || (desc = view.docView.descAt(nodePos)) && !desc.contentDOM)) { return false } + if (prosemirrorState.NodeSelection.isSelectable(node)) { + return apply(view, new prosemirrorState.NodeSelection(dir < 0 ? view.state.doc.resolve($head.pos - node.nodeSize) : $head)) + } else if (result.webkit) { + // Chrome and Safari will introduce extra pointless cursor + // positions around inline uneditable nodes, so we have to + // take over and move the cursor past them (#937) + return apply(view, new prosemirrorState.TextSelection(view.state.doc.resolve(dir < 0 ? nodePos : nodePos + node.nodeSize))) + } else { + return false + } + } + } else if (sel instanceof prosemirrorState.NodeSelection && sel.node.isInline) { + return apply(view, new prosemirrorState.TextSelection(dir > 0 ? sel.$to : sel.$from)) + } else { + var next$1 = moveSelectionBlock(view.state, dir); + if (next$1) { return apply(view, next$1) } + return false + } +} + +function nodeLen(node) { + return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length +} + +function isIgnorable(dom) { + var desc = dom.pmViewDesc; + return desc && desc.size == 0 && (dom.nextSibling || dom.nodeName != "BR") +} + +// Make sure the cursor isn't directly after one or more ignored +// nodes, which will confuse the browser's cursor motion logic. +function skipIgnoredNodesLeft(view) { + var sel = view.root.getSelection(); + var node = sel.focusNode, offset = sel.focusOffset; + if (!node) { return } + var moveNode, moveOffset, force = false; + // Gecko will do odd things when the selection is directly in front + // of a non-editable node, so in that case, move it into the next + // node if possible. Issue prosemirror/prosemirror#832. + if (result.gecko && node.nodeType == 1 && offset < nodeLen(node) && isIgnorable(node.childNodes[offset])) { force = true; } + for (;;) { + if (offset > 0) { + if (node.nodeType != 1) { + break + } else { + var before = node.childNodes[offset - 1]; + if (isIgnorable(before)) { + moveNode = node; + moveOffset = --offset; + } else if (before.nodeType == 3) { + node = before; + offset = node.nodeValue.length; + } else { break } + } + } else if (isBlockNode(node)) { + break + } else { + var prev = node.previousSibling; + while (prev && isIgnorable(prev)) { + moveNode = node.parentNode; + moveOffset = domIndex(prev); + prev = prev.previousSibling; + } + if (!prev) { + node = node.parentNode; + if (node == view.dom) { break } + offset = 0; + } else { + node = prev; + offset = nodeLen(node); + } + } + } + if (force) { setSelFocus(view, sel, node, offset); } + else if (moveNode) { setSelFocus(view, sel, moveNode, moveOffset); } +} + +// Make sure the cursor isn't directly before one or more ignored +// nodes. +function skipIgnoredNodesRight(view) { + var sel = view.root.getSelection(); + var node = sel.focusNode, offset = sel.focusOffset; + if (!node) { return } + var len = nodeLen(node); + var moveNode, moveOffset; + for (;;) { + if (offset < len) { + if (node.nodeType != 1) { break } + var after = node.childNodes[offset]; + if (isIgnorable(after)) { + moveNode = node; + moveOffset = ++offset; + } + else { break } + } else if (isBlockNode(node)) { + break + } else { + var next = node.nextSibling; + while (next && isIgnorable(next)) { + moveNode = next.parentNode; + moveOffset = domIndex(next) + 1; + next = next.nextSibling; + } + if (!next) { + node = node.parentNode; + if (node == view.dom) { break } + offset = len = 0; + } else { + node = next; + offset = 0; + len = nodeLen(node); + } + } + } + if (moveNode) { setSelFocus(view, sel, moveNode, moveOffset); } +} + +function isBlockNode(dom) { + var desc = dom.pmViewDesc; + return desc && desc.node && desc.node.isBlock +} + +function setSelFocus(view, sel, node, offset) { + if (selectionCollapsed(sel)) { + var range = document.createRange(); + range.setEnd(node, offset); + range.setStart(node, offset); + sel.removeAllRanges(); + sel.addRange(range); + } else if (sel.extend) { + sel.extend(node, offset); + } + view.domObserver.setCurSelection(); +} + +// : (EditorState, number) +// Check whether vertical selection motion would involve node +// selections. If so, apply it (if not, the result is left to the +// browser) +function selectVertically(view, dir, mods) { + var sel = view.state.selection; + if (sel instanceof prosemirrorState.TextSelection && !sel.empty || mods.indexOf("s") > -1) { return false } + var $from = sel.$from; + var $to = sel.$to; + + if (!$from.parent.inlineContent || view.endOfTextblock(dir < 0 ? "up" : "down")) { + var next = moveSelectionBlock(view.state, dir); + if (next && (next instanceof prosemirrorState.NodeSelection)) + { return apply(view, next) } + } + if (!$from.parent.inlineContent) { + var beyond = prosemirrorState.Selection.findFrom(dir < 0 ? $from : $to, dir); + return beyond ? apply(view, beyond) : true + } + return false +} + +function stopNativeHorizontalDelete(view, dir) { + if (!(view.state.selection instanceof prosemirrorState.TextSelection)) { return true } + var ref = view.state.selection; + var $head = ref.$head; + var $anchor = ref.$anchor; + var empty = ref.empty; + if (!$head.sameParent($anchor)) { return true } + if (!empty) { return false } + if (view.endOfTextblock(dir > 0 ? "forward" : "backward")) { return true } + var nextNode = !$head.textOffset && (dir < 0 ? $head.nodeBefore : $head.nodeAfter); + if (nextNode && !nextNode.isText) { + var tr = view.state.tr; + if (dir < 0) { tr.delete($head.pos - nextNode.nodeSize, $head.pos); } + else { tr.delete($head.pos, $head.pos + nextNode.nodeSize); } + view.dispatch(tr); + return true + } + return false +} + +function switchEditable(view, node, state) { + view.domObserver.stop(); + node.contentEditable = state; + view.domObserver.start(); +} + +// Issue #867 / https://bugs.chromium.org/p/chromium/issues/detail?id=903821 +// In which Chrome does really wrong things when the down arrow is +// pressed when the cursor is directly at the start of a textblock and +// has an uneditable node after it +function chromeDownArrowBug(view) { + if (!result.chrome || view.state.selection.$head.parentOffset > 0) { return } + var ref = view.root.getSelection(); + var focusNode = ref.focusNode; + var focusOffset = ref.focusOffset; + if (focusNode && focusNode.nodeType == 1 && focusOffset == 0 && + focusNode.firstChild && focusNode.firstChild.contentEditable == "false") { + var child = focusNode.firstChild; + switchEditable(view, child, true); + setTimeout(function () { return switchEditable(view, child, false); }, 20); + } +} + +// A backdrop key mapping used to make sure we always suppress keys +// that have a dangerous default effect, even if the commands they are +// bound to return false, and to make sure that cursor-motion keys +// find a cursor (as opposed to a node selection) when pressed. For +// cursor-motion keys, the code in the handlers also takes care of +// block selections. + +function getMods(event) { + var result = ""; + if (event.ctrlKey) { result += "c"; } + if (event.metaKey) { result += "m"; } + if (event.altKey) { result += "a"; } + if (event.shiftKey) { result += "s"; } + return result +} + +function captureKeyDown(view, event) { + var code = event.keyCode, mods = getMods(event); + if (code == 8 || (result.mac && code == 72 && mods == "c")) { // Backspace, Ctrl-h on Mac + return stopNativeHorizontalDelete(view, -1) || skipIgnoredNodesLeft(view) + } else if (code == 46 || (result.mac && code == 68 && mods == "c")) { // Delete, Ctrl-d on Mac + return stopNativeHorizontalDelete(view, 1) || skipIgnoredNodesRight(view) + } else if (code == 13 || code == 27) { // Enter, Esc + return true + } else if (code == 37) { // Left arrow + return selectHorizontally(view, -1, mods) || skipIgnoredNodesLeft(view) + } else if (code == 39) { // Right arrow + return selectHorizontally(view, 1, mods) || skipIgnoredNodesRight(view) + } else if (code == 38) { // Up arrow + return selectVertically(view, -1, mods) || skipIgnoredNodesLeft(view) + } else if (code == 40) { // Down arrow + return chromeDownArrowBug(view) || selectVertically(view, 1, mods) || skipIgnoredNodesRight(view) + } else if (mods == (result.mac ? "m" : "c") && + (code == 66 || code == 73 || code == 89 || code == 90)) { // Mod-[biyz] + return true + } + return false +} + +function selectionFromDOM(view, origin) { + var domSel = view.root.getSelection(), doc = view.state.doc; + var nearestDesc = view.docView.nearestDesc(domSel.focusNode), inWidget = nearestDesc && nearestDesc.size == 0; + var head = view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset); + var $head = doc.resolve(head), $anchor, selection; + if (selectionCollapsed(domSel)) { + $anchor = $head; + while (nearestDesc && !nearestDesc.node) { nearestDesc = nearestDesc.parent; } + if (nearestDesc && nearestDesc.node.isAtom && prosemirrorState.NodeSelection.isSelectable(nearestDesc.node) && nearestDesc.parent) { + var pos = nearestDesc.posBefore; + selection = new prosemirrorState.NodeSelection(head == pos ? $head : doc.resolve(pos)); + } + } else { + $anchor = doc.resolve(view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset)); + } + + if (!selection) { + var bias = origin == "pointer" || (view.state.selection.head < $head.pos && !inWidget) ? 1 : -1; + selection = selectionBetween(view, $anchor, $head, bias); + } + return selection +} + +function selectionToDOM(view, force) { + var sel = view.state.selection; + syncNodeSelection(view, sel); + + if (view.editable ? !view.hasFocus() : !(hasSelection(view) && document.activeElement.contains(view.dom))) { return } + + view.domObserver.disconnectSelection(); + + if (view.cursorWrapper) { + selectCursorWrapper(view); + } else { + var anchor = sel.anchor; + var head = sel.head; + var resetEditableFrom, resetEditableTo; + if (brokenSelectBetweenUneditable && !(sel instanceof prosemirrorState.TextSelection)) { + if (!sel.$from.parent.inlineContent) + { resetEditableFrom = temporarilyEditableNear(view, sel.from); } + if (!sel.empty && !sel.$from.parent.inlineContent) + { resetEditableTo = temporarilyEditableNear(view, sel.to); } + } + view.docView.setSelection(anchor, head, view.root, force); + if (brokenSelectBetweenUneditable) { + if (resetEditableFrom) { resetEditableFrom.contentEditable = "false"; } + if (resetEditableTo) { resetEditableTo.contentEditable = "false"; } + } + if (sel.visible) { + view.dom.classList.remove("ProseMirror-hideselection"); + } else if (anchor != head) { + view.dom.classList.add("ProseMirror-hideselection"); + if ("onselectionchange" in document) { removeClassOnSelectionChange(view); } + } + } + + view.domObserver.setCurSelection(); + view.domObserver.connectSelection(); +} + +// Kludge to work around Webkit not allowing a selection to start/end +// between non-editable block nodes. We briefly make something +// editable, set the selection, then set it uneditable again. + +var brokenSelectBetweenUneditable = result.safari || result.chrome && result.chrome_version < 63; + +function temporarilyEditableNear(view, pos) { + var ref = view.docView.domFromPos(pos); + var node = ref.node; + var offset = ref.offset; + var after = offset < node.childNodes.length ? node.childNodes[offset] : null; + var before = offset ? node.childNodes[offset - 1] : null; + if ((!after || after.contentEditable == "false") && (!before || before.contentEditable == "false")) { + if (after) { + after.contentEditable = "true"; + return after + } else if (before) { + before.contentEditable = "true"; + return before + } + } +} + +function removeClassOnSelectionChange(view) { + var doc = view.dom.ownerDocument; + doc.removeEventListener("selectionchange", view.hideSelectionGuard); + var domSel = view.root.getSelection(); + var node = domSel.anchorNode, offset = domSel.anchorOffset; + doc.addEventListener("selectionchange", view.hideSelectionGuard = function () { + if (domSel.anchorNode != node || domSel.anchorOffset != offset) { + doc.removeEventListener("selectionchange", view.hideSelectionGuard); + view.dom.classList.remove("ProseMirror-hideselection"); + } + }); +} + +function selectCursorWrapper(view) { + var domSel = view.root.getSelection(), range = document.createRange(); + var node = view.cursorWrapper.dom, img = node.nodeName == "IMG"; + if (img) { range.setEnd(node.parentNode, domIndex(node) + 1); } + else { range.setEnd(node, 0); } + range.collapse(false); + domSel.removeAllRanges(); + domSel.addRange(range); + // Kludge to kill 'control selection' in IE11 when selecting an + // invisible cursor wrapper, since that would result in those weird + // resize handles and a selection that considers the absolutely + // positioned wrapper, rather than the root editable node, the + // focused element. + if (!img && !view.state.selection.visible && result.ie && result.ie_version <= 11) { + node.disabled = true; + node.disabled = false; + } +} + +function syncNodeSelection(view, sel) { + if (sel instanceof prosemirrorState.NodeSelection) { + var desc = view.docView.descAt(sel.from); + if (desc != view.lastSelectedViewDesc) { + clearNodeSelection(view); + if (desc) { desc.selectNode(); } + view.lastSelectedViewDesc = desc; + } + } else { + clearNodeSelection(view); + } +} + +// Clear all DOM statefulness of the last node selection. +function clearNodeSelection(view) { + if (view.lastSelectedViewDesc) { + if (view.lastSelectedViewDesc.parent) + { view.lastSelectedViewDesc.deselectNode(); } + view.lastSelectedViewDesc = null; + } +} + +function selectionBetween(view, $anchor, $head, bias) { + return view.someProp("createSelectionBetween", function (f) { return f(view, $anchor, $head); }) + || prosemirrorState.TextSelection.between($anchor, $head, bias) +} + +function hasFocusAndSelection(view) { + if (view.editable && view.root.activeElement != view.dom) { return false } + return hasSelection(view) +} + +function hasSelection(view) { + var sel = view.root.getSelection(); + if (!sel.anchorNode) { return false } + try { + // Firefox will raise 'permission denied' errors when accessing + // properties of `sel.anchorNode` when it's in a generated CSS + // element. + return view.dom.contains(sel.anchorNode.nodeType == 3 ? sel.anchorNode.parentNode : sel.anchorNode) && + (view.editable || view.dom.contains(sel.focusNode.nodeType == 3 ? sel.focusNode.parentNode : sel.focusNode)) + } catch(_) { + return false + } +} + +function anchorInRightPlace(view) { + var anchorDOM = view.docView.domFromPos(view.state.selection.anchor); + var domSel = view.root.getSelection(); + return isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset) +} + +// Note that all referencing and parsing is done with the +// start-of-operation selection and document, since that's the one +// that the DOM represents. If any changes came in in the meantime, +// the modification is mapped over those before it is applied, in +// readDOMChange. + +function parseBetween(view, from_, to_) { + var ref = view.docView.parseRange(from_, to_); + var parent = ref.node; + var fromOffset = ref.fromOffset; + var toOffset = ref.toOffset; + var from = ref.from; + var to = ref.to; + + var domSel = view.root.getSelection(), find = null, anchor = domSel.anchorNode; + if (anchor && view.dom.contains(anchor.nodeType == 1 ? anchor : anchor.parentNode)) { + find = [{node: anchor, offset: domSel.anchorOffset}]; + if (!selectionCollapsed(domSel)) + { find.push({node: domSel.focusNode, offset: domSel.focusOffset}); } + } + // Work around issue in Chrome where backspacing sometimes replaces + // the deleted content with a random BR node (issues #799, #831) + if (result.chrome && view.lastKeyCode === 8) { + for (var off = toOffset; off > fromOffset; off--) { + var node = parent.childNodes[off - 1], desc = node.pmViewDesc; + if (node.nodeType == "BR" && !desc) { toOffset = off; break } + if (!desc || desc.size) { break } + } + } + var startDoc = view.state.doc; + var parser = view.someProp("domParser") || prosemirrorModel.DOMParser.fromSchema(view.state.schema); + var $from = startDoc.resolve(from); + + var sel = null, doc = parser.parse(parent, { + topNode: $from.parent, + topMatch: $from.parent.contentMatchAt($from.index()), + topOpen: true, + from: fromOffset, + to: toOffset, + preserveWhitespace: $from.parent.type.spec.code ? "full" : true, + editableContent: true, + findPositions: find, + ruleFromNode: ruleFromNode, + context: $from + }); + if (find && find[0].pos != null) { + var anchor$1 = find[0].pos, head = find[1] && find[1].pos; + if (head == null) { head = anchor$1; } + sel = {anchor: anchor$1 + from, head: head + from}; + } + return {doc: doc, sel: sel, from: from, to: to} +} + +function ruleFromNode(dom) { + var desc = dom.pmViewDesc; + if (desc) { + return desc.parseRule() + } else if (dom.nodeName == "BR" && dom.parentNode) { + // Safari replaces the list item or table cell with a BR + // directly in the list node (?!) if you delete the last + // character in a list item or table cell (#708, #862) + if (result.safari && /^(ul|ol)$/i.test(dom.parentNode.nodeName)) { + var skip = document.createElement("div"); + skip.appendChild(document.createElement("li")); + return {skip: skip} + } else if (dom.parentNode.lastChild == dom || result.safari && /^(tr|table)$/i.test(dom.parentNode.nodeName)) { + return {ignore: true} + } + } else if (dom.nodeName == "IMG" && dom.getAttribute("mark-placeholder")) { + return {ignore: true} + } +} + +function readDOMChange(view, from, to, typeOver) { + if (from < 0) { + var origin = view.lastSelectionTime > Date.now() - 50 ? view.lastSelectionOrigin : null; + var newSel = selectionFromDOM(view, origin); + if (!view.state.selection.eq(newSel)) { + var tr$1 = view.state.tr.setSelection(newSel); + if (origin == "pointer") { tr$1.setMeta("pointer", true); } + else if (origin == "key") { tr$1.scrollIntoView(); } + view.dispatch(tr$1); + } + return + } + + var $before = view.state.doc.resolve(from); + var shared = $before.sharedDepth(to); + from = $before.before(shared + 1); + to = view.state.doc.resolve(to).after(shared + 1); + + var sel = view.state.selection; + var parse = parseBetween(view, from, to); + + var doc = view.state.doc, compare = doc.slice(parse.from, parse.to); + var preferredPos, preferredSide; + // Prefer anchoring to end when Backspace is pressed + if (view.lastKeyCode === 8 && Date.now() - 100 < view.lastKeyCodeTime) { + preferredPos = view.state.selection.to; + preferredSide = "end"; + } else { + preferredPos = view.state.selection.from; + preferredSide = "start"; + } + view.lastKeyCode = null; + + var change = findDiff(compare.content, parse.doc.content, parse.from, preferredPos, preferredSide); + if (!change) { + if (typeOver && sel instanceof prosemirrorState.TextSelection && !sel.empty && sel.$head.sameParent(sel.$anchor) && + !view.composing && !(parse.sel && parse.sel.anchor != parse.sel.head)) { + change = {start: sel.from, endA: sel.to, endB: sel.to}; + } else { + if (parse.sel) { + var sel$1 = resolveSelection(view, view.state.doc, parse.sel); + if (sel$1 && !sel$1.eq(view.state.selection)) { view.dispatch(view.state.tr.setSelection(sel$1)); } + } + return + } + } + view.domChangeCount++; + // Handle the case where overwriting a selection by typing matches + // the start or end of the selected content, creating a change + // that's smaller than what was actually overwritten. + if (view.state.selection.from < view.state.selection.to && + change.start == change.endB && + view.state.selection instanceof prosemirrorState.TextSelection) { + if (change.start > view.state.selection.from && change.start <= view.state.selection.from + 2) { + change.start = view.state.selection.from; + } else if (change.endA < view.state.selection.to && change.endA >= view.state.selection.to - 2) { + change.endB += (view.state.selection.to - change.endA); + change.endA = view.state.selection.to; + } + } + + // IE11 will insert a non-breaking space _ahead_ of the space after + // the cursor space when adding a space before another space. When + // that happened, adjust the change to cover the space instead. + if (result.ie && result.ie_version <= 11 && change.endB == change.start + 1 && + change.endA == change.start && change.start > parse.from && + parse.doc.textBetween(change.start - parse.from - 1, change.start - parse.from + 1) == " \u00a0") { + change.start--; + change.endA--; + change.endB--; + } + + var $from = parse.doc.resolveNoCache(change.start - parse.from); + var $to = parse.doc.resolveNoCache(change.endB - parse.from); + var nextSel; + // If this looks like the effect of pressing Enter, just dispatch an + // Enter key instead. + if (!$from.sameParent($to) && $from.pos < parse.doc.content.size && + (nextSel = prosemirrorState.Selection.findFrom(parse.doc.resolve($from.pos + 1), 1, true)) && + nextSel.head == $to.pos && + view.someProp("handleKeyDown", function (f) { return f(view, keyEvent(13, "Enter")); })) + { return } + // Same for backspace + if (view.state.selection.anchor > change.start && + looksLikeJoin(doc, change.start, change.endA, $from, $to) && + view.someProp("handleKeyDown", function (f) { return f(view, keyEvent(8, "Backspace")); })) { + if (result.android && result.chrome) { view.domObserver.suppressSelectionUpdates(); } // #820 + return + } + + var chFrom = change.start, chTo = change.endA; + + var tr, storedMarks, markChange, $from1; + if ($from.sameParent($to) && $from.parent.inlineContent) { + if ($from.pos == $to.pos) { // Deletion + // IE11 sometimes weirdly moves the DOM selection around after + // backspacing out the first element in a textblock + if (result.ie && result.ie_version <= 11 && $from.parentOffset == 0) { + view.domObserver.suppressSelectionUpdates(); + setTimeout(function () { return selectionToDOM(view); }, 20); + } + tr = view.state.tr.delete(chFrom, chTo); + storedMarks = doc.resolve(change.start).marksAcross(doc.resolve(change.endA)); + } else if ( // Adding or removing a mark + change.endA == change.endB && ($from1 = doc.resolve(change.start)) && + (markChange = isMarkChange($from.parent.content.cut($from.parentOffset, $to.parentOffset), + $from1.parent.content.cut($from1.parentOffset, change.endA - $from1.start()))) + ) { + tr = view.state.tr; + if (markChange.type == "add") { tr.addMark(chFrom, chTo, markChange.mark); } + else { tr.removeMark(chFrom, chTo, markChange.mark); } + } else if ($from.parent.child($from.index()).isText && $from.index() == $to.index() - ($to.textOffset ? 0 : 1)) { + // Both positions in the same text node -- simply insert text + var text = $from.parent.textBetween($from.parentOffset, $to.parentOffset); + if (view.someProp("handleTextInput", function (f) { return f(view, chFrom, chTo, text); })) { return } + tr = view.state.tr.insertText(text, chFrom, chTo); + } + } + + if (!tr) + { tr = view.state.tr.replace(chFrom, chTo, parse.doc.slice(change.start - parse.from, change.endB - parse.from)); } + if (parse.sel) { + var sel$2 = resolveSelection(view, tr.doc, parse.sel); + // Chrome Android will sometimes, during composition, report the + // selection in the wrong place. If it looks like that is + // happening, don't update the selection. + // Edge just doesn't move the cursor forward when you start typing + // in an empty block or between br nodes. + if (sel$2 && !(result.chrome && result.android && view.composing && sel$2.empty && sel$2.head == chFrom || + result.ie && sel$2.empty && sel$2.head == chFrom)) + { tr.setSelection(sel$2); } + } + if (storedMarks) { tr.ensureMarks(storedMarks); } + view.dispatch(tr.scrollIntoView()); +} + +function resolveSelection(view, doc, parsedSel) { + if (Math.max(parsedSel.anchor, parsedSel.head) > doc.content.size) { return null } + return selectionBetween(view, doc.resolve(parsedSel.anchor), doc.resolve(parsedSel.head)) +} + +// : (Fragment, Fragment) → ?{mark: Mark, type: string} +// Given two same-length, non-empty fragments of inline content, +// determine whether the first could be created from the second by +// removing or adding a single mark type. +function isMarkChange(cur, prev) { + var curMarks = cur.firstChild.marks, prevMarks = prev.firstChild.marks; + var added = curMarks, removed = prevMarks, type, mark, update; + for (var i = 0; i < prevMarks.length; i++) { added = prevMarks[i].removeFromSet(added); } + for (var i$1 = 0; i$1 < curMarks.length; i$1++) { removed = curMarks[i$1].removeFromSet(removed); } + if (added.length == 1 && removed.length == 0) { + mark = added[0]; + type = "add"; + update = function (node) { return node.mark(mark.addToSet(node.marks)); }; + } else if (added.length == 0 && removed.length == 1) { + mark = removed[0]; + type = "remove"; + update = function (node) { return node.mark(mark.removeFromSet(node.marks)); }; + } else { + return null + } + var updated = []; + for (var i$2 = 0; i$2 < prev.childCount; i$2++) { updated.push(update(prev.child(i$2))); } + if (prosemirrorModel.Fragment.from(updated).eq(cur)) { return {mark: mark, type: type} } +} + +function looksLikeJoin(old, start, end, $newStart, $newEnd) { + if (!$newStart.parent.isTextblock || + // The content must have shrunk + end - start <= $newEnd.pos - $newStart.pos || + // newEnd must point directly at or after the end of the block that newStart points into + skipClosingAndOpening($newStart, true, false) < $newEnd.pos) + { return false } + + var $start = old.resolve(start); + // Start must be at the end of a block + if ($start.parentOffset < $start.parent.content.size || !$start.parent.isTextblock) + { return false } + var $next = old.resolve(skipClosingAndOpening($start, true, true)); + // The next textblock must start before end and end near it + if (!$next.parent.isTextblock || $next.pos > end || + skipClosingAndOpening($next, true, false) < end) + { return false } + + // The fragments after the join point must match + return $newStart.parent.content.cut($newStart.parentOffset).eq($next.parent.content) +} + +function skipClosingAndOpening($pos, fromEnd, mayOpen) { + var depth = $pos.depth, end = fromEnd ? $pos.end() : $pos.pos; + while (depth > 0 && (fromEnd || $pos.indexAfter(depth) == $pos.node(depth).childCount)) { + depth--; + end++; + fromEnd = false; + } + if (mayOpen) { + var next = $pos.node(depth).maybeChild($pos.indexAfter(depth)); + while (next && !next.isLeaf) { + next = next.firstChild; + end++; + } + } + return end +} + +function findDiff(a, b, pos, preferredPos, preferredSide) { + var start = a.findDiffStart(b, pos); + if (start == null) { return null } + var ref = a.findDiffEnd(b, pos + a.size, pos + b.size); + var endA = ref.a; + var endB = ref.b; + if (preferredSide == "end") { + var adjust = Math.max(0, start - Math.min(endA, endB)); + preferredPos -= endA + adjust - start; + } + if (endA < start && a.size < b.size) { + var move = preferredPos <= start && preferredPos >= endA ? start - preferredPos : 0; + start -= move; + endB = start + (endB - endA); + endA = start; + } else if (endB < start) { + var move$1 = preferredPos <= start && preferredPos >= endB ? start - preferredPos : 0; + start -= move$1; + endA = start + (endA - endB); + endB = start; + } + return {start: start, endA: endA, endB: endB} +} + +function serializeForClipboard(view, slice) { + var context = []; + var content = slice.content; + var openStart = slice.openStart; + var openEnd = slice.openEnd; + while (openStart > 1 && openEnd > 1 && content.childCount == 1 && content.firstChild.childCount == 1) { + openStart--; + openEnd--; + var node = content.firstChild; + context.push(node.type.name, node.type.hasRequiredAttrs() ? node.attrs : null); + content = node.content; + } + + var serializer = view.someProp("clipboardSerializer") || prosemirrorModel.DOMSerializer.fromSchema(view.state.schema); + var doc = detachedDoc(), wrap = doc.createElement("div"); + wrap.appendChild(serializer.serializeFragment(content, {document: doc})); + + var firstChild = wrap.firstChild, needsWrap; + while (firstChild && firstChild.nodeType == 1 && (needsWrap = wrapMap[firstChild.nodeName.toLowerCase()])) { + for (var i = needsWrap.length - 1; i >= 0; i--) { + var wrapper = doc.createElement(needsWrap[i]); + while (wrap.firstChild) { wrapper.appendChild(wrap.firstChild); } + wrap.appendChild(wrapper); + } + firstChild = wrap.firstChild; + } + + if (firstChild && firstChild.nodeType == 1) + { firstChild.setAttribute("data-pm-slice", (openStart + " " + openEnd + " " + (JSON.stringify(context)))); } + + var text = view.someProp("clipboardTextSerializer", function (f) { return f(slice); }) || + slice.content.textBetween(0, slice.content.size, "\n\n"); + + return {dom: wrap, text: text} +} + +// : (EditorView, string, string, ?bool, ResolvedPos) → ?Slice +// Read a slice of content from the clipboard (or drop data). +function parseFromClipboard(view, text, html, plainText, $context) { + var dom, inCode = $context.parent.type.spec.code, slice; + if (!html && !text) { return null } + var asText = text && (plainText || inCode || !html); + if (asText) { + view.someProp("transformPastedText", function (f) { text = f(text); }); + if (inCode) { return new prosemirrorModel.Slice(prosemirrorModel.Fragment.from(view.state.schema.text(text)), 0, 0) } + var parsed = view.someProp("clipboardTextParser", function (f) { return f(text, $context); }); + if (parsed) { + slice = parsed; + } else { + dom = document.createElement("div"); + text.trim().split(/(?:\r\n?|\n)+/).forEach(function (block) { + dom.appendChild(document.createElement("p")).textContent = block; + }); + } + } else { + view.someProp("transformPastedHTML", function (f) { html = f(html); }); + dom = readHTML(html); + } + + var contextNode = dom && dom.querySelector("[data-pm-slice]"); + var sliceData = contextNode && /^(\d+) (\d+) (.*)/.exec(contextNode.getAttribute("data-pm-slice")); + if (!slice) { + var parser = view.someProp("clipboardParser") || view.someProp("domParser") || prosemirrorModel.DOMParser.fromSchema(view.state.schema); + slice = parser.parseSlice(dom, {preserveWhitespace: !!(asText || sliceData), context: $context}); + } + if (sliceData) + { slice = addContext(closeSlice(slice, +sliceData[1], +sliceData[2]), sliceData[3]); } + else // HTML wasn't created by ProseMirror. Make sure top-level siblings are coherent + { slice = prosemirrorModel.Slice.maxOpen(normalizeSiblings(slice.content, $context), false); } + + view.someProp("transformPasted", function (f) { slice = f(slice); }); + return slice +} + +// Takes a slice parsed with parseSlice, which means there hasn't been +// any content-expression checking done on the top nodes, tries to +// find a parent node in the current context that might fit the nodes, +// and if successful, rebuilds the slice so that it fits into that parent. +// +// This addresses the problem that Transform.replace expects a +// coherent slice, and will fail to place a set of siblings that don't +// fit anywhere in the schema. +function normalizeSiblings(fragment, $context) { + if (fragment.childCount < 2) { return fragment } + var loop = function ( d ) { + var parent = $context.node(d); + var match = parent.contentMatchAt($context.index(d)); + var lastWrap = (void 0), result = []; + fragment.forEach(function (node) { + if (!result) { return } + var wrap = match.findWrapping(node.type), inLast; + if (!wrap) { return result = null } + if (inLast = result.length && lastWrap.length && addToSibling(wrap, lastWrap, node, result[result.length - 1], 0)) { + result[result.length - 1] = inLast; + } else { + if (result.length) { result[result.length - 1] = closeRight(result[result.length - 1], lastWrap.length); } + var wrapped = withWrappers(node, wrap); + result.push(wrapped); + match = match.matchType(wrapped.type, wrapped.attrs); + lastWrap = wrap; + } + }); + if (result) { return { v: prosemirrorModel.Fragment.from(result) } } + }; + + for (var d = $context.depth; d >= 0; d--) { + var returned = loop( d ); + + if ( returned ) return returned.v; + } + return fragment +} + +function withWrappers(node, wrap, from) { + if ( from === void 0 ) from = 0; + + for (var i = wrap.length - 1; i >= from; i--) + { node = wrap[i].create(null, prosemirrorModel.Fragment.from(node)); } + return node +} + +// Used to group adjacent nodes wrapped in similar parents by +// normalizeSiblings into the same parent node +function addToSibling(wrap, lastWrap, node, sibling, depth) { + if (depth < wrap.length && depth < lastWrap.length && wrap[depth] == lastWrap[depth]) { + var inner = addToSibling(wrap, lastWrap, node, sibling.lastChild, depth + 1); + if (inner) { return sibling.copy(sibling.content.replaceChild(sibling.childCount - 1, inner)) } + var match = sibling.contentMatchAt(sibling.childCount); + if (match.matchType(depth == wrap.length - 1 ? node.type : wrap[depth + 1])) + { return sibling.copy(sibling.content.append(prosemirrorModel.Fragment.from(withWrappers(node, wrap, depth + 1)))) } + } +} + +function closeRight(node, depth) { + if (depth == 0) { return node } + var fragment = node.content.replaceChild(node.childCount - 1, closeRight(node.lastChild, depth - 1)); + var fill = node.contentMatchAt(node.childCount).fillBefore(prosemirrorModel.Fragment.empty, true); + return node.copy(fragment.append(fill)) +} + +function closeRange(fragment, side, from, to, depth, openEnd) { + var node = side < 0 ? fragment.firstChild : fragment.lastChild, inner = node.content; + if (depth < to - 1) { inner = closeRange(inner, side, from, to, depth + 1, openEnd); } + if (depth >= from) + { inner = side < 0 ? node.contentMatchAt(0).fillBefore(inner, fragment.childCount > 1 || openEnd <= depth).append(inner) + : inner.append(node.contentMatchAt(node.childCount).fillBefore(prosemirrorModel.Fragment.empty, true)); } + return fragment.replaceChild(side < 0 ? 0 : fragment.childCount - 1, node.copy(inner)) +} + +function closeSlice(slice, openStart, openEnd) { + if (openStart < slice.openStart) + { slice = new prosemirrorModel.Slice(closeRange(slice.content, -1, openStart, slice.openStart, 0, slice.openEnd), openStart, slice.openEnd); } + if (openEnd < slice.openEnd) + { slice = new prosemirrorModel.Slice(closeRange(slice.content, 1, openEnd, slice.openEnd, 0, 0), slice.openStart, openEnd); } + return slice +} + +// Trick from jQuery -- some elements must be wrapped in other +// elements for innerHTML to work. I.e. if you do `div.innerHTML = +// ".."` the table cells are ignored. +var wrapMap = {thead: ["table"], colgroup: ["table"], col: ["table", "colgroup"], + tr: ["table", "tbody"], td: ["table", "tbody", "tr"], th: ["table", "tbody", "tr"]}; + +var _detachedDoc = null; +function detachedDoc() { + return _detachedDoc || (_detachedDoc = document.implementation.createHTMLDocument("title")) +} + +function readHTML(html) { + var metas = /(\s*]*>)*/.exec(html); + if (metas) { html = html.slice(metas[0].length); } + var elt = detachedDoc().createElement("div"); + var firstTag = /(?:]*>)*<([a-z][^>\s]+)/i.exec(html), wrap, depth = 0; + if (wrap = firstTag && wrapMap[firstTag[1].toLowerCase()]) { + html = wrap.map(function (n) { return "<" + n + ">"; }).join("") + html + wrap.map(function (n) { return ""; }).reverse().join(""); + depth = wrap.length; + } + elt.innerHTML = html; + for (var i = 0; i < depth; i++) { elt = elt.firstChild; } + return elt +} + +function addContext(slice, context) { + if (!slice.size) { return slice } + var schema = slice.content.firstChild.type.schema, array; + try { array = JSON.parse(context); } + catch(e) { return slice } + var content = slice.content; + var openStart = slice.openStart; + var openEnd = slice.openEnd; + for (var i = array.length - 2; i >= 0; i -= 2) { + var type = schema.nodes[array[i]]; + if (!type || type.hasRequiredAttrs()) { break } + content = prosemirrorModel.Fragment.from(type.create(array[i + 1], content)); + openStart++; openEnd++; + } + return new prosemirrorModel.Slice(content, openStart, openEnd) +} + +var observeOptions = { + childList: true, + characterData: true, + characterDataOldValue: true, + attributes: true, + attributeOldValue: true, + subtree: true +}; +// IE11 has very broken mutation observers, so we also listen to DOMCharacterDataModified +var useCharData = result.ie && result.ie_version <= 11; + +var SelectionState = function SelectionState() { + this.anchorNode = this.anchorOffset = this.focusNode = this.focusOffset = null; +}; + +SelectionState.prototype.set = function set (sel) { + this.anchorNode = sel.anchorNode; this.anchorOffset = sel.anchorOffset; + this.focusNode = sel.focusNode; this.focusOffset = sel.focusOffset; +}; + +SelectionState.prototype.eq = function eq (sel) { + return sel.anchorNode == this.anchorNode && sel.anchorOffset == this.anchorOffset && + sel.focusNode == this.focusNode && sel.focusOffset == this.focusOffset +}; + +var DOMObserver = function DOMObserver(view, handleDOMChange) { + var this$1 = this; + + this.view = view; + this.handleDOMChange = handleDOMChange; + this.queue = []; + this.flushingSoon = false; + this.observer = window.MutationObserver && + new window.MutationObserver(function (mutations) { + for (var i = 0; i < mutations.length; i++) { this$1.queue.push(mutations[i]); } + // IE11 will sometimes (on backspacing out a single character + // text node after a BR node) call the observer callback + // before actually updating the DOM, which will cause + // ProseMirror to miss the change (see #930) + if (result.ie && result.ie_version <= 11 && mutations.some( + function (m) { return m.type == "childList" && m.removedNodes.length || + m.type == "characterData" && m.oldValue.length > m.target.nodeValue.length; })) + { this$1.flushSoon(); } + else + { this$1.flush(); } + }); + this.currentSelection = new SelectionState; + if (useCharData) { + this.onCharData = function (e) { + this$1.queue.push({target: e.target, type: "characterData", oldValue: e.prevValue}); + this$1.flushSoon(); + }; + } + this.onSelectionChange = this.onSelectionChange.bind(this); + this.suppressingSelectionUpdates = false; +}; + +DOMObserver.prototype.flushSoon = function flushSoon () { + var this$1 = this; + + if (!this.flushingSoon) { + this.flushingSoon = true; + window.setTimeout(function () { this$1.flushingSoon = false; this$1.flush(); }, 20); + } +}; + +DOMObserver.prototype.start = function start () { + if (this.observer) + { this.observer.observe(this.view.dom, observeOptions); } + if (useCharData) + { this.view.dom.addEventListener("DOMCharacterDataModified", this.onCharData); } + this.connectSelection(); +}; + +DOMObserver.prototype.stop = function stop () { + var this$1 = this; + + if (this.observer) { + var take = this.observer.takeRecords(); + if (take.length) { + for (var i = 0; i < take.length; i++) { this.queue.push(take[i]); } + window.setTimeout(function () { return this$1.flush(); }, 20); + } + this.observer.disconnect(); + } + if (useCharData) { this.view.dom.removeEventListener("DOMCharacterDataModified", this.onCharData); } + this.disconnectSelection(); +}; + +DOMObserver.prototype.connectSelection = function connectSelection () { + this.view.dom.ownerDocument.addEventListener("selectionchange", this.onSelectionChange); +}; + +DOMObserver.prototype.disconnectSelection = function disconnectSelection () { + this.view.dom.ownerDocument.removeEventListener("selectionchange", this.onSelectionChange); +}; + +DOMObserver.prototype.suppressSelectionUpdates = function suppressSelectionUpdates () { + var this$1 = this; + + this.suppressingSelectionUpdates = true; + setTimeout(function () { return this$1.suppressingSelectionUpdates = false; }, 50); +}; + +DOMObserver.prototype.onSelectionChange = function onSelectionChange () { + if (!hasFocusAndSelection(this.view)) { return } + if (this.suppressingSelectionUpdates) { return selectionToDOM(this.view) } + // Deletions on IE11 fire their events in the wrong order, giving + // us a selection change event before the DOM changes are + // reported. + if (result.ie && result.ie_version <= 11 && !this.view.state.selection.empty) { + var sel = this.view.root.getSelection(); + // Selection.isCollapsed isn't reliable on IE + if (sel.focusNode && isEquivalentPosition(sel.focusNode, sel.focusOffset, sel.anchorNode, sel.anchorOffset)) + { return this.flushSoon() } + } + this.flush(); +}; + +DOMObserver.prototype.setCurSelection = function setCurSelection () { + this.currentSelection.set(this.view.root.getSelection()); +}; + +DOMObserver.prototype.ignoreSelectionChange = function ignoreSelectionChange (sel) { + if (sel.rangeCount == 0) { return true } + var container = sel.getRangeAt(0).commonAncestorContainer; + var desc = this.view.docView.nearestDesc(container); + return desc && desc.ignoreMutation({type: "selection", target: container.nodeType == 3 ? container.parentNode : container}) +}; + +DOMObserver.prototype.flush = function flush () { + if (!this.view.docView || this.flushingSoon) { return } + var mutations = this.observer ? this.observer.takeRecords() : []; + if (this.queue.length) { + mutations = this.queue.concat(mutations); + this.queue.length = 0; + } + + var sel = this.view.root.getSelection(); + var newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasSelection(this.view) && !this.ignoreSelectionChange(sel); + + var from = -1, to = -1, typeOver = false, added = []; + if (this.view.editable) { + for (var i = 0; i < mutations.length; i++) { + var result$1 = this.registerMutation(mutations[i], added); + if (result$1) { + from = from < 0 ? result$1.from : Math.min(result$1.from, from); + to = to < 0 ? result$1.to : Math.max(result$1.to, to); + if (result$1.typeOver && !this.view.composing) { typeOver = true; } + } + } + } + + if (result.gecko && added.length > 1) { + var brs = added.filter(function (n) { return n.nodeName == "BR"; }); + if (brs.length == 2) { + var a = brs[0]; + var b = brs[1]; + if (a.parentNode && a.parentNode.parentNode == b.parentNode) { b.remove(); } + else { a.remove(); } + } + } + + if (from > -1 || newSel) { + if (from > -1) { + this.view.docView.markDirty(from, to); + checkCSS(this.view); + } + this.handleDOMChange(from, to, typeOver); + if (this.view.docView.dirty) { this.view.updateState(this.view.state); } + else if (!this.currentSelection.eq(sel)) { selectionToDOM(this.view); } + } +}; + +DOMObserver.prototype.registerMutation = function registerMutation (mut, added) { + // Ignore mutations inside nodes that were already noted as inserted + if (added.indexOf(mut.target) > -1) { return null } + var desc = this.view.docView.nearestDesc(mut.target); + if (mut.type == "attributes" && + (desc == this.view.docView || mut.attributeName == "contenteditable" || + // Firefox sometimes fires spurious events for null/empty styles + (mut.attributeName == "style" && !mut.oldValue && !mut.target.getAttribute("style")))) + { return null } + if (!desc || desc.ignoreMutation(mut)) { return null } + + if (mut.type == "childList") { + var prev = mut.previousSibling, next = mut.nextSibling; + if (result.ie && result.ie_version <= 11 && mut.addedNodes.length) { + // IE11 gives us incorrect next/prev siblings for some + // insertions, so if there are added nodes, recompute those + for (var i = 0; i < mut.addedNodes.length; i++) { + var ref = mut.addedNodes[i]; + var previousSibling = ref.previousSibling; + var nextSibling = ref.nextSibling; + if (!previousSibling || Array.prototype.indexOf.call(mut.addedNodes, previousSibling) < 0) { prev = previousSibling; } + if (!nextSibling || Array.prototype.indexOf.call(mut.addedNodes, nextSibling) < 0) { next = nextSibling; } + } + } + var fromOffset = prev && prev.parentNode == mut.target + ? domIndex(prev) + 1 : 0; + var from = desc.localPosFromDOM(mut.target, fromOffset, -1); + var toOffset = next && next.parentNode == mut.target + ? domIndex(next) : mut.target.childNodes.length; + for (var i$1 = 0; i$1 < mut.addedNodes.length; i$1++) { added.push(mut.addedNodes[i$1]); } + var to = desc.localPosFromDOM(mut.target, toOffset, 1); + return {from: from, to: to} + } else if (mut.type == "attributes") { + return {from: desc.posAtStart - desc.border, to: desc.posAtEnd + desc.border} + } else { // "characterData" + return { + from: desc.posAtStart, + to: desc.posAtEnd, + // An event was generated for a text change that didn't change + // any text. Mark the dom change to fall back to assuming the + // selection was typed over with an identical value if it can't + // find another change. + typeOver: mut.target.nodeValue == mut.oldValue + } + } +}; + +var cssChecked = false; + +function checkCSS(view) { + if (cssChecked) { return } + cssChecked = true; + if (getComputedStyle(view.dom).whiteSpace == "normal") + { console["warn"]("ProseMirror expects the CSS white-space property to be set, preferably to 'pre-wrap'. It is recommended to load style/prosemirror.css from the prosemirror-view package."); } +} + +// A collection of DOM events that occur within the editor, and callback functions +// to invoke when the event fires. +var handlers = {}, editHandlers = {}; + +function initInput(view) { + view.shiftKey = false; + view.mouseDown = null; + view.lastKeyCode = null; + view.lastKeyCodeTime = 0; + view.lastClick = {time: 0, x: 0, y: 0, type: ""}; + view.lastSelectionOrigin = null; + view.lastSelectionTime = 0; + + view.composing = false; + view.composingTimeout = null; + view.compositionNodes = []; + view.compositionEndedAt = -2e8; + + view.domObserver = new DOMObserver(view, function (from, to, typeOver) { return readDOMChange(view, from, to, typeOver); }); + view.domObserver.start(); + // Used by hacks like the beforeinput handler to check whether anything happened in the DOM + view.domChangeCount = 0; + + view.eventHandlers = Object.create(null); + var loop = function ( event ) { + var handler = handlers[event]; + view.dom.addEventListener(event, view.eventHandlers[event] = function (event) { + if (eventBelongsToView(view, event) && !runCustomHandler(view, event) && + (view.editable || !(event.type in editHandlers))) + { handler(view, event); } + }); + }; + + for (var event in handlers) loop( event ); + // On Safari, for reasons beyond my understanding, adding an input + // event handler makes an issue where the composition vanishes when + // you press enter go away. + if (result.safari) { view.dom.addEventListener("input", function () { return null; }); } + + ensureListeners(view); +} + +function setSelectionOrigin(view, origin) { + view.lastSelectionOrigin = origin; + view.lastSelectionTime = Date.now(); +} + +function destroyInput(view) { + view.domObserver.stop(); + for (var type in view.eventHandlers) + { view.dom.removeEventListener(type, view.eventHandlers[type]); } + clearTimeout(view.composingTimeout); +} + +function ensureListeners(view) { + view.someProp("handleDOMEvents", function (currentHandlers) { + for (var type in currentHandlers) { if (!view.eventHandlers[type]) + { view.dom.addEventListener(type, view.eventHandlers[type] = function (event) { return runCustomHandler(view, event); }); } } + }); +} + +function runCustomHandler(view, event) { + return view.someProp("handleDOMEvents", function (handlers) { + var handler = handlers[event.type]; + return handler ? handler(view, event) || event.defaultPrevented : false + }) +} + +function eventBelongsToView(view, event) { + if (!event.bubbles) { return true } + if (event.defaultPrevented) { return false } + for (var node = event.target; node != view.dom; node = node.parentNode) + { if (!node || node.nodeType == 11 || + (node.pmViewDesc && node.pmViewDesc.stopEvent(event))) + { return false } } + return true +} + +function dispatchEvent(view, event) { + if (!runCustomHandler(view, event) && handlers[event.type] && + (view.editable || !(event.type in editHandlers))) + { handlers[event.type](view, event); } +} + +editHandlers.keydown = function (view, event) { + view.shiftKey = event.keyCode == 16 || event.shiftKey; + if (inOrNearComposition(view, event)) { return } + view.lastKeyCode = event.keyCode; + view.lastKeyCodeTime = Date.now(); + if (view.someProp("handleKeyDown", function (f) { return f(view, event); }) || captureKeyDown(view, event)) + { event.preventDefault(); } + else + { setSelectionOrigin(view, "key"); } +}; + +editHandlers.keyup = function (view, e) { + if (e.keyCode == 16) { view.shiftKey = false; } +}; + +editHandlers.keypress = function (view, event) { + if (inOrNearComposition(view, event) || !event.charCode || + event.ctrlKey && !event.altKey || result.mac && event.metaKey) { return } + + if (view.someProp("handleKeyPress", function (f) { return f(view, event); })) { + event.preventDefault(); + return + } + + var sel = view.state.selection; + if (!(sel instanceof prosemirrorState.TextSelection) || !sel.$from.sameParent(sel.$to)) { + var text = String.fromCharCode(event.charCode); + if (!view.someProp("handleTextInput", function (f) { return f(view, sel.$from.pos, sel.$to.pos, text); })) + { view.dispatch(view.state.tr.insertText(text).scrollIntoView()); } + event.preventDefault(); + } +}; + +function eventCoords(event) { return {left: event.clientX, top: event.clientY} } + +function isNear(event, click) { + var dx = click.x - event.clientX, dy = click.y - event.clientY; + return dx * dx + dy * dy < 100 +} + +function runHandlerOnContext(view, propName, pos, inside, event) { + if (inside == -1) { return false } + var $pos = view.state.doc.resolve(inside); + var loop = function ( i ) { + if (view.someProp(propName, function (f) { return i > $pos.depth ? f(view, pos, $pos.nodeAfter, $pos.before(i), event, true) + : f(view, pos, $pos.node(i), $pos.before(i), event, false); })) + { return { v: true } } + }; + + for (var i = $pos.depth + 1; i > 0; i--) { + var returned = loop( i ); + + if ( returned ) return returned.v; + } + return false +} + +function updateSelection(view, selection, origin) { + if (!view.focused) { view.focus(); } + var tr = view.state.tr.setSelection(selection); + if (origin == "pointer") { tr.setMeta("pointer", true); } + view.dispatch(tr); +} + +function selectClickedLeaf(view, inside) { + if (inside == -1) { return false } + var $pos = view.state.doc.resolve(inside), node = $pos.nodeAfter; + if (node && node.isAtom && prosemirrorState.NodeSelection.isSelectable(node)) { + updateSelection(view, new prosemirrorState.NodeSelection($pos), "pointer"); + return true + } + return false +} + +function selectClickedNode(view, inside) { + if (inside == -1) { return false } + var sel = view.state.selection, selectedNode, selectAt; + if (sel instanceof prosemirrorState.NodeSelection) { selectedNode = sel.node; } + + var $pos = view.state.doc.resolve(inside); + for (var i = $pos.depth + 1; i > 0; i--) { + var node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i); + if (prosemirrorState.NodeSelection.isSelectable(node)) { + if (selectedNode && sel.$from.depth > 0 && + i >= sel.$from.depth && $pos.before(sel.$from.depth + 1) == sel.$from.pos) + { selectAt = $pos.before(sel.$from.depth); } + else + { selectAt = $pos.before(i); } + break + } + } + + if (selectAt != null) { + updateSelection(view, prosemirrorState.NodeSelection.create(view.state.doc, selectAt), "pointer"); + return true + } else { + return false + } +} + +function handleSingleClick(view, pos, inside, event, selectNode) { + return runHandlerOnContext(view, "handleClickOn", pos, inside, event) || + view.someProp("handleClick", function (f) { return f(view, pos, event); }) || + (selectNode ? selectClickedNode(view, inside) : selectClickedLeaf(view, inside)) +} + +function handleDoubleClick(view, pos, inside, event) { + return runHandlerOnContext(view, "handleDoubleClickOn", pos, inside, event) || + view.someProp("handleDoubleClick", function (f) { return f(view, pos, event); }) +} + +function handleTripleClick(view, pos, inside, event) { + return runHandlerOnContext(view, "handleTripleClickOn", pos, inside, event) || + view.someProp("handleTripleClick", function (f) { return f(view, pos, event); }) || + defaultTripleClick(view, inside) +} + +function defaultTripleClick(view, inside) { + var doc = view.state.doc; + if (inside == -1) { + if (doc.inlineContent) { + updateSelection(view, prosemirrorState.TextSelection.create(doc, 0, doc.content.size), "pointer"); + return true + } + return false + } + + var $pos = doc.resolve(inside); + for (var i = $pos.depth + 1; i > 0; i--) { + var node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i); + var nodePos = $pos.before(i); + if (node.inlineContent) + { updateSelection(view, prosemirrorState.TextSelection.create(doc, nodePos + 1, nodePos + 1 + node.content.size), "pointer"); } + else if (prosemirrorState.NodeSelection.isSelectable(node)) + { updateSelection(view, prosemirrorState.NodeSelection.create(doc, nodePos), "pointer"); } + else + { continue } + return true + } +} + +function forceDOMFlush(view) { + return endComposition(view) +} + +var selectNodeModifier = result.mac ? "metaKey" : "ctrlKey"; + +handlers.mousedown = function (view, event) { + view.shiftKey = event.shiftKey; + var flushed = forceDOMFlush(view); + var now = Date.now(), type = "singleClick"; + if (now - view.lastClick.time < 500 && isNear(event, view.lastClick) && !event[selectNodeModifier]) { + if (view.lastClick.type == "singleClick") { type = "doubleClick"; } + else if (view.lastClick.type == "doubleClick") { type = "tripleClick"; } + } + view.lastClick = {time: now, x: event.clientX, y: event.clientY, type: type}; + + var pos = view.posAtCoords(eventCoords(event)); + if (!pos) { return } + + if (type == "singleClick") + { view.mouseDown = new MouseDown(view, pos, event, flushed); } + else if ((type == "doubleClick" ? handleDoubleClick : handleTripleClick)(view, pos.pos, pos.inside, event)) + { event.preventDefault(); } + else + { setSelectionOrigin(view, "pointer"); } +}; + +var MouseDown = function MouseDown(view, pos, event, flushed) { + var this$1 = this; + + this.view = view; + this.startDoc = view.state.doc; + this.pos = pos; + this.event = event; + this.flushed = flushed; + this.selectNode = event[selectNodeModifier]; + this.allowDefault = event.shiftKey; + + var targetNode, targetPos; + if (pos.inside > -1) { + targetNode = view.state.doc.nodeAt(pos.inside); + targetPos = pos.inside; + } else { + var $pos = view.state.doc.resolve(pos.pos); + targetNode = $pos.parent; + targetPos = $pos.depth ? $pos.before() : 0; + } + + this.mightDrag = null; + + var target = flushed ? null : event.target; + var targetDesc = target ? view.docView.nearestDesc(target, true) : null; + this.target = targetDesc ? targetDesc.dom : null; + + if (targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false || + view.state.selection instanceof prosemirrorState.NodeSelection && targetPos == view.state.selection.from) + { this.mightDrag = {node: targetNode, + pos: targetPos, + addAttr: this.target && !this.target.draggable, + setUneditable: this.target && result.gecko && !this.target.hasAttribute("contentEditable")}; } + + if (this.target && this.mightDrag && (this.mightDrag.addAttr || this.mightDrag.setUneditable)) { + this.view.domObserver.stop(); + if (this.mightDrag.addAttr) { this.target.draggable = true; } + if (this.mightDrag.setUneditable) + { setTimeout(function () { return this$1.target.setAttribute("contentEditable", "false"); }, 20); } + this.view.domObserver.start(); + } + + view.root.addEventListener("mouseup", this.up = this.up.bind(this)); + view.root.addEventListener("mousemove", this.move = this.move.bind(this)); + setSelectionOrigin(view, "pointer"); +}; + +MouseDown.prototype.done = function done () { + this.view.root.removeEventListener("mouseup", this.up); + this.view.root.removeEventListener("mousemove", this.move); + if (this.mightDrag && this.target) { + this.view.domObserver.stop(); + if (this.mightDrag.addAttr) { this.target.draggable = false; } + if (this.mightDrag.setUneditable) { this.target.removeAttribute("contentEditable"); } + this.view.domObserver.start(); + } + this.view.mouseDown = null; +}; + +MouseDown.prototype.up = function up (event) { + this.done(); + + if (!this.view.dom.contains(event.target.nodeType == 3 ? event.target.parentNode : event.target)) + { return } + + var pos = this.pos; + if (this.view.state.doc != this.startDoc) { pos = this.view.posAtCoords(eventCoords(event)); } + + if (this.allowDefault || !pos) { + setSelectionOrigin(this.view, "pointer"); + } else if (handleSingleClick(this.view, pos.pos, pos.inside, event, this.selectNode)) { + event.preventDefault(); + } else if (this.flushed || + // Chrome will sometimes treat a node selection as a + // cursor, but still report that the node is selected + // when asked through getSelection. You'll then get a + // situation where clicking at the point where that + // (hidden) cursor is doesn't change the selection, and + // thus doesn't get a reaction from ProseMirror. This + // works around that. + (result.chrome && !(this.view.state.selection instanceof prosemirrorState.TextSelection) && + (pos.pos == this.view.state.selection.from || pos.pos == this.view.state.selection.to))) { + updateSelection(this.view, prosemirrorState.Selection.near(this.view.state.doc.resolve(pos.pos)), "pointer"); + event.preventDefault(); + } else { + setSelectionOrigin(this.view, "pointer"); + } +}; + +MouseDown.prototype.move = function move (event) { + if (!this.allowDefault && (Math.abs(this.event.x - event.clientX) > 4 || + Math.abs(this.event.y - event.clientY) > 4)) + { this.allowDefault = true; } + setSelectionOrigin(this.view, "pointer"); +}; + +handlers.touchdown = function (view) { + forceDOMFlush(view); + setSelectionOrigin(view, "pointer"); +}; + +handlers.contextmenu = function (view) { return forceDOMFlush(view); }; + +function inOrNearComposition(view, event) { + if (view.composing) { return true } + // See https://www.stum.de/2016/06/24/handling-ime-events-in-javascript/. + // On Japanese input method editors (IMEs), the Enter key is used to confirm character + // selection. On Safari, when Enter is pressed, compositionend and keydown events are + // emitted. The keydown event triggers newline insertion, which we don't want. + // This method returns true if the keydown event should be ignored. + // We only ignore it once, as pressing Enter a second time *should* insert a newline. + // Furthermore, the keydown event timestamp must be close to the compositionEndedAt timestamp. + // This guards against the case where compositionend is triggered without the keyboard + // (e.g. character confirmation may be done with the mouse), and keydown is triggered + // afterwards- we wouldn't want to ignore the keydown event in this case. + if (result.safari && Math.abs(event.timeStamp - view.compositionEndedAt) < 500) { + view.compositionEndedAt = -2e8; + return true + } + return false +} + +// Drop active composition after 5 seconds of inactivity on Android +var timeoutComposition = result.android ? 5000 : -1; + +editHandlers.compositionstart = editHandlers.compositionupdate = function (view) { + if (!view.composing) { + view.domObserver.flush(); + var state = view.state; + var $pos = state.selection.$from; + if (state.selection.empty && + (state.storedMarks || (!$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some(function (m) { return m.type.spec.inclusive === false; })))) { + // Need to wrap the cursor in mark nodes different from the ones in the DOM context + view.markCursor = view.state.storedMarks || $pos.marks(); + endComposition(view, true); + view.markCursor = null; + } else { + endComposition(view); + // In firefox, if the cursor is after but outside a marked node, + // the inserted text won't inherit the marks. So this moves it + // inside if necessary. + if (result.gecko && state.selection.empty && $pos.parentOffset && !$pos.textOffset && $pos.nodeBefore.marks.length) { + var sel = view.root.getSelection(); + for (var node = sel.focusNode, offset = sel.focusOffset; node && node.nodeType == 1 && offset != 0;) { + var before = offset < 0 ? node.lastChild : node.childNodes[offset - 1]; + if (before.nodeType == 3) { + sel.collapse(before, before.nodeValue.length); + break + } else { + node = before; + offset = -1; + } + } + } + } + view.composing = true; + } + scheduleComposeEnd(view, timeoutComposition); +}; + +editHandlers.compositionend = function (view, event) { + if (view.composing) { + view.composing = false; + view.compositionEndedAt = event.timeStamp; + scheduleComposeEnd(view, 20); + } +}; + +function scheduleComposeEnd(view, delay) { + clearTimeout(view.composingTimeout); + if (delay > -1) { view.composingTimeout = setTimeout(function () { return endComposition(view); }, delay); } +} + +function endComposition(view, forceUpdate) { + view.composing = false; + while (view.compositionNodes.length > 0) { view.compositionNodes.pop().markParentsDirty(); } + if (forceUpdate || view.docView.dirty) { + view.updateState(view.state); + return true + } + return false +} + +function captureCopy(view, dom) { + // The extra wrapper is somehow necessary on IE/Edge to prevent the + // content from being mangled when it is put onto the clipboard + var doc = view.dom.ownerDocument; + var wrap = doc.body.appendChild(doc.createElement("div")); + wrap.appendChild(dom); + wrap.style.cssText = "position: fixed; left: -10000px; top: 10px"; + var sel = getSelection(), range = doc.createRange(); + range.selectNodeContents(dom); + // Done because IE will fire a selectionchange moving the selection + // to its start when removeAllRanges is called and the editor still + // has focus (which will mess up the editor's selection state). + view.dom.blur(); + sel.removeAllRanges(); + sel.addRange(range); + setTimeout(function () { + doc.body.removeChild(wrap); + view.focus(); + }, 50); +} + +// This is very crude, but unfortunately both these browsers _pretend_ +// that they have a clipboard API—all the objects and methods are +// there, they just don't work, and they are hard to test. +var brokenClipboardAPI = (result.ie && result.ie_version < 15) || + (result.ios && result.webkit_version < 604); + +handlers.copy = editHandlers.cut = function (view, e) { + var sel = view.state.selection, cut = e.type == "cut"; + if (sel.empty) { return } + + // IE and Edge's clipboard interface is completely broken + var data = brokenClipboardAPI ? null : e.clipboardData; + var slice = sel.content(); + var ref = serializeForClipboard(view, slice); + var dom = ref.dom; + var text = ref.text; + if (data) { + e.preventDefault(); + data.clearData(); + data.setData("text/html", dom.innerHTML); + data.setData("text/plain", text); + } else { + captureCopy(view, dom); + } + if (cut) { view.dispatch(view.state.tr.deleteSelection().scrollIntoView().setMeta("uiEvent", "cut")); } +}; + +function sliceSingleNode(slice) { + return slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1 ? slice.content.firstChild : null +} + +function capturePaste(view, e) { + var doc = view.dom.ownerDocument; + var plainText = view.shiftKey || view.state.selection.$from.parent.type.spec.code; + var target = doc.body.appendChild(doc.createElement(plainText ? "textarea" : "div")); + if (!plainText) { target.contentEditable = "true"; } + target.style.cssText = "position: fixed; left: -10000px; top: 10px"; + target.focus(); + setTimeout(function () { + view.focus(); + doc.body.removeChild(target); + if (plainText) { doPaste(view, target.value, null, e); } + else { doPaste(view, target.textContent, target.innerHTML, e); } + }, 50); +} + +function doPaste(view, text, html, e) { + var slice = parseFromClipboard(view, text, html, view.shiftKey, view.state.selection.$from); + if (view.someProp("handlePaste", function (f) { return f(view, e, slice || prosemirrorModel.Slice.empty); }) || !slice) { return } + + var singleNode = sliceSingleNode(slice); + var tr = singleNode ? view.state.tr.replaceSelectionWith(singleNode, view.shiftKey) : view.state.tr.replaceSelection(slice); + view.dispatch(tr.scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste")); +} + +editHandlers.paste = function (view, e) { + var data = brokenClipboardAPI ? null : e.clipboardData; + var html = data && data.getData("text/html"), text = data && data.getData("text/plain"); + if (data && (html || text || data.files.length)) { + doPaste(view, text, html, e); + e.preventDefault(); + } else { + capturePaste(view, e); + } +}; + +var Dragging = function Dragging(slice, move) { + this.slice = slice; + this.move = move; +}; + +var dragCopyModifier = result.mac ? "altKey" : "ctrlKey"; + +handlers.dragstart = function (view, e) { + var mouseDown = view.mouseDown; + if (mouseDown) { mouseDown.done(); } + if (!e.dataTransfer) { return } + + var sel = view.state.selection; + var pos = sel.empty ? null : view.posAtCoords(eventCoords(e)); + if (pos && pos.pos >= sel.from && pos.pos <= (sel instanceof prosemirrorState.NodeSelection ? sel.to - 1: sel.to)) ; else if (mouseDown && mouseDown.mightDrag) { + view.dispatch(view.state.tr.setSelection(prosemirrorState.NodeSelection.create(view.state.doc, mouseDown.mightDrag.pos))); + } else if (e.target && e.target.nodeType == 1) { + var desc = view.docView.nearestDesc(e.target, true); + if (!desc || !desc.node.type.spec.draggable || desc == view.docView) { return } + view.dispatch(view.state.tr.setSelection(prosemirrorState.NodeSelection.create(view.state.doc, desc.posBefore))); + } + var slice = view.state.selection.content(); + var ref = serializeForClipboard(view, slice); + var dom = ref.dom; + var text = ref.text; + e.dataTransfer.clearData(); + e.dataTransfer.setData(brokenClipboardAPI ? "Text" : "text/html", dom.innerHTML); + if (!brokenClipboardAPI) { e.dataTransfer.setData("text/plain", text); } + view.dragging = new Dragging(slice, !e[dragCopyModifier]); +}; + +handlers.dragend = function (view) { + window.setTimeout(function () { return view.dragging = null; }, 50); +}; + +editHandlers.dragover = editHandlers.dragenter = function (_, e) { return e.preventDefault(); }; + +editHandlers.drop = function (view, e) { + var dragging = view.dragging; + view.dragging = null; + + if (!e.dataTransfer) { return } + + var eventPos = view.posAtCoords(eventCoords(e)); + if (!eventPos) { return } + var $mouse = view.state.doc.resolve(eventPos.pos); + if (!$mouse) { return } + var slice = dragging && dragging.slice || + parseFromClipboard(view, e.dataTransfer.getData(brokenClipboardAPI ? "Text" : "text/plain"), + brokenClipboardAPI ? null : e.dataTransfer.getData("text/html"), false, $mouse); + if (!slice) { return } + + e.preventDefault(); + if (view.someProp("handleDrop", function (f) { return f(view, e, slice, dragging && dragging.move); })) { return } + var insertPos = slice ? prosemirrorTransform.dropPoint(view.state.doc, $mouse.pos, slice) : $mouse.pos; + if (insertPos == null) { insertPos = $mouse.pos; } + + var tr = view.state.tr; + if (dragging && dragging.move) { tr.deleteSelection(); } + + var pos = tr.mapping.map(insertPos); + var isNode = slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1; + var beforeInsert = tr.doc; + if (isNode) + { tr.replaceRangeWith(pos, pos, slice.content.firstChild); } + else + { tr.replaceRange(pos, pos, slice); } + if (tr.doc.eq(beforeInsert)) { return } + + var $pos = tr.doc.resolve(pos); + if (isNode && prosemirrorState.NodeSelection.isSelectable(slice.content.firstChild) && + $pos.nodeAfter && $pos.nodeAfter.sameMarkup(slice.content.firstChild)) + { tr.setSelection(new prosemirrorState.NodeSelection($pos)); } + else + { tr.setSelection(selectionBetween(view, $pos, tr.doc.resolve(tr.mapping.map(insertPos)))); } + view.focus(); + view.dispatch(tr.setMeta("uiEvent", "drop")); +}; + +handlers.focus = function (view) { + if (!view.focused) { + view.domObserver.stop(); + view.dom.classList.add("ProseMirror-focused"); + view.domObserver.start(); + view.focused = true; + } +}; + +handlers.blur = function (view) { + if (view.focused) { + view.domObserver.stop(); + view.dom.classList.remove("ProseMirror-focused"); + view.domObserver.start(); + view.domObserver.currentSelection.set({}); + view.focused = false; + } +}; + +handlers.beforeinput = function (view, event) { + // We should probably do more with beforeinput events, but support + // is so spotty that I'm still waiting to see where they are going. + + // Very specific hack to deal with backspace sometimes failing on + // Chrome Android when after an uneditable node. + if (result.chrome && result.android && event.inputType == "deleteContentBackward") { + var domChangeCount = view.domChangeCount; + setTimeout(function () { + if (view.domChangeCount != domChangeCount) { return } // Event already had some effect + // This bug tends to close the virtual keyboard, so we refocus + view.dom.blur(); + view.focus(); + if (view.someProp("handleKeyDown", function (f) { return f(view, keyEvent(8, "Backspace")); })) { return } + var ref = view.state.selection; + var $cursor = ref.$cursor; + // Crude approximation of backspace behavior when no command handled it + if ($cursor && $cursor.pos > 0) { view.dispatch(view.state.tr.delete($cursor.pos - 1, $cursor.pos).scrollIntoView()); } + }, 50); + } +}; + +// Make sure all handlers get registered +for (var prop in editHandlers) { handlers[prop] = editHandlers[prop]; } + +function compareObjs(a, b) { + if (a == b) { return true } + for (var p in a) { if (a[p] !== b[p]) { return false } } + for (var p$1 in b) { if (!(p$1 in a)) { return false } } + return true +} + +var WidgetType = function WidgetType(toDOM, spec) { + this.spec = spec || noSpec; + this.side = this.spec.side || 0; + this.toDOM = toDOM; +}; + +WidgetType.prototype.map = function map (mapping, span, offset, oldOffset) { + var ref = mapping.mapResult(span.from + oldOffset, this.side < 0 ? -1 : 1); + var pos = ref.pos; + var deleted = ref.deleted; + return deleted ? null : new Decoration(pos - offset, pos - offset, this) +}; + +WidgetType.prototype.valid = function valid () { return true }; + +WidgetType.prototype.eq = function eq (other) { + return this == other || + (other instanceof WidgetType && + (this.spec.key && this.spec.key == other.spec.key || + this.toDOM == other.toDOM && compareObjs(this.spec, other.spec))) +}; + +var InlineType = function InlineType(attrs, spec) { + this.spec = spec || noSpec; + this.attrs = attrs; +}; + +InlineType.prototype.map = function map (mapping, span, offset, oldOffset) { + var from = mapping.map(span.from + oldOffset, this.spec.inclusiveStart ? -1 : 1) - offset; + var to = mapping.map(span.to + oldOffset, this.spec.inclusiveEnd ? 1 : -1) - offset; + return from >= to ? null : new Decoration(from, to, this) +}; + +InlineType.prototype.valid = function valid (_, span) { return span.from < span.to }; + +InlineType.prototype.eq = function eq (other) { + return this == other || + (other instanceof InlineType && compareObjs(this.attrs, other.attrs) && + compareObjs(this.spec, other.spec)) +}; + +InlineType.is = function is (span) { return span.type instanceof InlineType }; + +var NodeType = function NodeType(attrs, spec) { + this.spec = spec || noSpec; + this.attrs = attrs; +}; + +NodeType.prototype.map = function map (mapping, span, offset, oldOffset) { + var from = mapping.mapResult(span.from + oldOffset, 1); + if (from.deleted) { return null } + var to = mapping.mapResult(span.to + oldOffset, -1); + if (to.deleted || to.pos <= from.pos) { return null } + return new Decoration(from.pos - offset, to.pos - offset, this) +}; + +NodeType.prototype.valid = function valid (node, span) { + var ref = node.content.findIndex(span.from); + var index = ref.index; + var offset = ref.offset; + return offset == span.from && offset + node.child(index).nodeSize == span.to +}; + +NodeType.prototype.eq = function eq (other) { + return this == other || + (other instanceof NodeType && compareObjs(this.attrs, other.attrs) && + compareObjs(this.spec, other.spec)) +}; + +// ::- Decoration objects can be provided to the view through the +// [`decorations` prop](#view.EditorProps.decorations). They come in +// several variants—see the static members of this class for details. +var Decoration = function Decoration(from, to, type) { + // :: number + // The start position of the decoration. + this.from = from; + // :: number + // The end position. Will be the same as `from` for [widget + // decorations](#view.Decoration^widget). + this.to = to; + this.type = type; +}; + +var prototypeAccessors$1 = { spec: { configurable: true } }; + +Decoration.prototype.copy = function copy (from, to) { + return new Decoration(from, to, this.type) +}; + +Decoration.prototype.eq = function eq (other) { + return this.type.eq(other.type) && this.from == other.from && this.to == other.to +}; + +Decoration.prototype.map = function map (mapping, offset, oldOffset) { + return this.type.map(mapping, this, offset, oldOffset) +}; + +// :: (number, union<(view: EditorView, getPos: () → number) → dom.Node, dom.Node>, ?Object) → Decoration +// Creates a widget decoration, which is a DOM node that's shown in +// the document at the given position. It is recommended that you +// delay rendering the widget by passing a function that will be +// called when the widget is actually drawn in a view, but you can +// also directly pass a DOM node. `getPos` can be used to find the +// widget's current document position. +// +// spec::- These options are supported: +// +// side:: ?number +// Controls which side of the document position this widget is +// associated with. When negative, it is drawn before a cursor +// at its position, and content inserted at that position ends +// up after the widget. When zero (the default) or positive, the +// widget is drawn after the cursor and content inserted there +// ends up before the widget. +// +// When there are multiple widgets at a given position, their +// `side` values determine the order in which they appear. Those +// with lower values appear first. The ordering of widgets with +// the same `side` value is unspecified. +// +// When `marks` is null, `side` also determines the marks that +// the widget is wrapped in—those of the node before when +// negative, those of the node after when positive. +// +// marks:: ?[Mark] +// The precise set of marks to draw around the widget. +// +// stopEvent:: ?(event: dom.Event) → bool +// Can be used to control which DOM events, when they bubble out +// of this widget, the editor view should ignore. +// +// key:: ?string +// When comparing decorations of this type (in order to decide +// whether it needs to be redrawn), ProseMirror will by default +// compare the widget DOM node by identity. If you pass a key, +// that key will be compared instead, which can be useful when +// you generate decorations on the fly and don't want to store +// and reuse DOM nodes. Make sure that any widgets with the same +// key are interchangeable—if widgets differ in, for example, +// the behavior of some event handler, they should get +// different keys. +Decoration.widget = function widget (pos, toDOM, spec) { + return new Decoration(pos, pos, new WidgetType(toDOM, spec)) +}; + +// :: (number, number, DecorationAttrs, ?Object) → Decoration +// Creates an inline decoration, which adds the given attributes to +// each inline node between `from` and `to`. +// +// spec::- These options are recognized: +// +// inclusiveStart:: ?bool +// Determines how the left side of the decoration is +// [mapped](#transform.Position_Mapping) when content is +// inserted directly at that position. By default, the decoration +// won't include the new content, but you can set this to `true` +// to make it inclusive. +// +// inclusiveEnd:: ?bool +// Determines how the right side of the decoration is mapped. +// See +// [`inclusiveStart`](#view.Decoration^inline^spec.inclusiveStart). +Decoration.inline = function inline (from, to, attrs, spec) { + return new Decoration(from, to, new InlineType(attrs, spec)) +}; + +// :: (number, number, DecorationAttrs, ?Object) → Decoration +// Creates a node decoration. `from` and `to` should point precisely +// before and after a node in the document. That node, and only that +// node, will receive the given attributes. +// +// spec::- +// +// Optional information to store with the decoration. It +// is also used when comparing decorators for equality. +Decoration.node = function node (from, to, attrs, spec) { + return new Decoration(from, to, new NodeType(attrs, spec)) +}; + +// :: Object +// The spec provided when creating this decoration. Can be useful +// if you've stored extra information in that object. +prototypeAccessors$1.spec.get = function () { return this.type.spec }; + +Object.defineProperties( Decoration.prototype, prototypeAccessors$1 ); + +// DecorationAttrs:: interface +// A set of attributes to add to a decorated node. Most properties +// simply directly correspond to DOM attributes of the same name, +// which will be set to the property's value. These are exceptions: +// +// class:: ?string +// A CSS class name or a space-separated set of class names to be +// _added_ to the classes that the node already had. +// +// style:: ?string +// A string of CSS to be _added_ to the node's existing `style` property. +// +// nodeName:: ?string +// When non-null, the target node is wrapped in a DOM element of +// this type (and the other attributes are applied to this element). + +var none = [], noSpec = {}; + +// ::- A collection of [decorations](#view.Decoration), organized in +// such a way that the drawing algorithm can efficiently use and +// compare them. This is a persistent data structure—it is not +// modified, updates create a new value. +var DecorationSet = function DecorationSet(local, children) { + this.local = local && local.length ? local : none; + this.children = children && children.length ? children : none; +}; + +// :: (Node, [Decoration]) → DecorationSet +// Create a set of decorations, using the structure of the given +// document. +DecorationSet.create = function create (doc, decorations) { + return decorations.length ? buildTree(decorations, doc, 0, noSpec) : empty +}; + +// :: (?number, ?number, ?(spec: Object) → bool) → [Decoration] +// Find all decorations in this set which touch the given range +// (including decorations that start or end directly at the +// boundaries) and match the given predicate on their spec. When +// `start` and `end` are omitted, all decorations in the set are +// considered. When `predicate` isn't given, all decorations are +// assumed to match. +DecorationSet.prototype.find = function find (start, end, predicate) { + var result = []; + this.findInner(start == null ? 0 : start, end == null ? 1e9 : end, result, 0, predicate); + return result +}; + +DecorationSet.prototype.findInner = function findInner (start, end, result, offset, predicate) { + for (var i = 0; i < this.local.length; i++) { + var span = this.local[i]; + if (span.from <= end && span.to >= start && (!predicate || predicate(span.spec))) + { result.push(span.copy(span.from + offset, span.to + offset)); } + } + for (var i$1 = 0; i$1 < this.children.length; i$1 += 3) { + if (this.children[i$1] < end && this.children[i$1 + 1] > start) { + var childOff = this.children[i$1] + 1; + this.children[i$1 + 2].findInner(start - childOff, end - childOff, result, offset + childOff, predicate); + } + } +}; + +// :: (Mapping, Node, ?Object) → DecorationSet +// Map the set of decorations in response to a change in the +// document. +// +// options::- An optional set of options. +// +// onRemove:: ?(decorationSpec: Object) +// When given, this function will be called for each decoration +// that gets dropped as a result of the mapping, passing the +// spec of that decoration. +DecorationSet.prototype.map = function map (mapping, doc, options) { + if (this == empty || mapping.maps.length == 0) { return this } + return this.mapInner(mapping, doc, 0, 0, options || noSpec) +}; + +DecorationSet.prototype.mapInner = function mapInner (mapping, node, offset, oldOffset, options) { + var newLocal; + for (var i = 0; i < this.local.length; i++) { + var mapped = this.local[i].map(mapping, offset, oldOffset); + if (mapped && mapped.type.valid(node, mapped)) { (newLocal || (newLocal = [])).push(mapped); } + else if (options.onRemove) { options.onRemove(this.local[i].spec); } + } + + if (this.children.length) + { return mapChildren(this.children, newLocal, mapping, node, offset, oldOffset, options) } + else + { return newLocal ? new DecorationSet(newLocal.sort(byPos)) : empty } +}; + +// :: (Node, [Decoration]) → DecorationSet +// Add the given array of decorations to the ones in the set, +// producing a new set. Needs access to the current document to +// create the appropriate tree structure. +DecorationSet.prototype.add = function add (doc, decorations) { + if (!decorations.length) { return this } + if (this == empty) { return DecorationSet.create(doc, decorations) } + return this.addInner(doc, decorations, 0) +}; + +DecorationSet.prototype.addInner = function addInner (doc, decorations, offset) { + var this$1 = this; + + var children, childIndex = 0; + doc.forEach(function (childNode, childOffset) { + var baseOffset = childOffset + offset, found; + if (!(found = takeSpansForNode(decorations, childNode, baseOffset))) { return } + + if (!children) { children = this$1.children.slice(); } + while (childIndex < children.length && children[childIndex] < childOffset) { childIndex += 3; } + if (children[childIndex] == childOffset) + { children[childIndex + 2] = children[childIndex + 2].addInner(childNode, found, baseOffset + 1); } + else + { children.splice(childIndex, 0, childOffset, childOffset + childNode.nodeSize, buildTree(found, childNode, baseOffset + 1, noSpec)); } + childIndex += 3; + }); + + var local = moveSpans(childIndex ? withoutNulls(decorations) : decorations, -offset); + return new DecorationSet(local.length ? this.local.concat(local).sort(byPos) : this.local, + children || this.children) +}; + +// :: ([Decoration]) → DecorationSet +// Create a new set that contains the decorations in this set, minus +// the ones in the given array. +DecorationSet.prototype.remove = function remove (decorations) { + if (decorations.length == 0 || this == empty) { return this } + return this.removeInner(decorations, 0) +}; + +DecorationSet.prototype.removeInner = function removeInner (decorations, offset) { + var children = this.children, local = this.local; + for (var i = 0; i < children.length; i += 3) { + var found = (void 0), from = children[i] + offset, to = children[i + 1] + offset; + for (var j = 0, span = (void 0); j < decorations.length; j++) { if (span = decorations[j]) { + if (span.from > from && span.to < to) { + decorations[j] = null + ;(found || (found = [])).push(span); + } + } } + if (!found) { continue } + if (children == this.children) { children = this.children.slice(); } + var removed = children[i + 2].removeInner(found, from + 1); + if (removed != empty) { + children[i + 2] = removed; + } else { + children.splice(i, 3); + i -= 3; + } + } + if (local.length) { for (var i$1 = 0, span$1 = (void 0); i$1 < decorations.length; i$1++) { if (span$1 = decorations[i$1]) { + for (var j$1 = 0; j$1 < local.length; j$1++) { if (local[j$1].type.eq(span$1.type)) { + if (local == this.local) { local = this.local.slice(); } + local.splice(j$1--, 1); + } } + } } } + if (children == this.children && local == this.local) { return this } + return local.length || children.length ? new DecorationSet(local, children) : empty +}; + +DecorationSet.prototype.forChild = function forChild (offset, node) { + if (this == empty) { return this } + if (node.isLeaf) { return DecorationSet.empty } + + var child, local; + for (var i = 0; i < this.children.length; i += 3) { if (this.children[i] >= offset) { + if (this.children[i] == offset) { child = this.children[i + 2]; } + break + } } + var start = offset + 1, end = start + node.content.size; + for (var i$1 = 0; i$1 < this.local.length; i$1++) { + var dec = this.local[i$1]; + if (dec.from < end && dec.to > start && (dec.type instanceof InlineType)) { + var from = Math.max(start, dec.from) - start, to = Math.min(end, dec.to) - start; + if (from < to) { (local || (local = [])).push(dec.copy(from, to)); } + } + } + if (local) { + var localSet = new DecorationSet(local.sort(byPos)); + return child ? new DecorationGroup([localSet, child]) : localSet + } + return child || empty +}; + +DecorationSet.prototype.eq = function eq (other) { + if (this == other) { return true } + if (!(other instanceof DecorationSet) || + this.local.length != other.local.length || + this.children.length != other.children.length) { return false } + for (var i = 0; i < this.local.length; i++) + { if (!this.local[i].eq(other.local[i])) { return false } } + for (var i$1 = 0; i$1 < this.children.length; i$1 += 3) + { if (this.children[i$1] != other.children[i$1] || + this.children[i$1 + 1] != other.children[i$1 + 1] || + !this.children[i$1 + 2].eq(other.children[i$1 + 2])) { return false } } + return true +}; + +DecorationSet.prototype.locals = function locals (node) { + return removeOverlap(this.localsInner(node)) +}; + +DecorationSet.prototype.localsInner = function localsInner (node) { + if (this == empty) { return none } + if (node.inlineContent || !this.local.some(InlineType.is)) { return this.local } + var result = []; + for (var i = 0; i < this.local.length; i++) { + if (!(this.local[i].type instanceof InlineType)) + { result.push(this.local[i]); } + } + return result +}; + +var empty = new DecorationSet(); + +// :: DecorationSet +// The empty set of decorations. +DecorationSet.empty = empty; + +DecorationSet.removeOverlap = removeOverlap; + +// :- An abstraction that allows the code dealing with decorations to +// treat multiple DecorationSet objects as if it were a single object +// with (a subset of) the same interface. +var DecorationGroup = function DecorationGroup(members) { + this.members = members; +}; + +DecorationGroup.prototype.forChild = function forChild (offset, child) { + if (child.isLeaf) { return DecorationSet.empty } + var found = []; + for (var i = 0; i < this.members.length; i++) { + var result = this.members[i].forChild(offset, child); + if (result == empty) { continue } + if (result instanceof DecorationGroup) { found = found.concat(result.members); } + else { found.push(result); } + } + return DecorationGroup.from(found) +}; + +DecorationGroup.prototype.eq = function eq (other) { + if (!(other instanceof DecorationGroup) || + other.members.length != this.members.length) { return false } + for (var i = 0; i < this.members.length; i++) + { if (!this.members[i].eq(other.members[i])) { return false } } + return true +}; + +DecorationGroup.prototype.locals = function locals (node) { + var result, sorted = true; + for (var i = 0; i < this.members.length; i++) { + var locals = this.members[i].localsInner(node); + if (!locals.length) { continue } + if (!result) { + result = locals; + } else { + if (sorted) { + result = result.slice(); + sorted = false; + } + for (var j = 0; j < locals.length; j++) { result.push(locals[j]); } + } + } + return result ? removeOverlap(sorted ? result : result.sort(byPos)) : none +}; + +// : ([DecorationSet]) → union +// Create a group for the given array of decoration sets, or return +// a single set when possible. +DecorationGroup.from = function from (members) { + switch (members.length) { + case 0: return empty + case 1: return members[0] + default: return new DecorationGroup(members) + } +}; + +function mapChildren(oldChildren, newLocal, mapping, node, offset, oldOffset, options) { + var children = oldChildren.slice(); + + // Mark the children that are directly touched by changes, and + // move those that are after the changes. + var shift = function (oldStart, oldEnd, newStart, newEnd) { + for (var i = 0; i < children.length; i += 3) { + var end = children[i + 1], dSize = (void 0); + if (end == -1 || oldStart > end + oldOffset) { continue } + if (oldEnd >= children[i] + oldOffset) { + children[i + 1] = -1; + } else if (dSize = (newEnd - newStart) - (oldEnd - oldStart) + (oldOffset - offset)) { + children[i] += dSize; + children[i + 1] += dSize; + } + } + }; + for (var i = 0; i < mapping.maps.length; i++) { mapping.maps[i].forEach(shift); } + + // Find the child nodes that still correspond to a single node, + // recursively call mapInner on them and update their positions. + var mustRebuild = false; + for (var i$1 = 0; i$1 < children.length; i$1 += 3) { if (children[i$1 + 1] == -1) { // Touched nodes + var from = mapping.map(children[i$1] + oldOffset), fromLocal = from - offset; + if (fromLocal < 0 || fromLocal >= node.content.size) { + mustRebuild = true; + continue + } + // Must read oldChildren because children was tagged with -1 + var to = mapping.map(oldChildren[i$1 + 1] + oldOffset, -1), toLocal = to - offset; + var ref = node.content.findIndex(fromLocal); + var index = ref.index; + var childOffset = ref.offset; + var childNode = node.maybeChild(index); + if (childNode && childOffset == fromLocal && childOffset + childNode.nodeSize == toLocal) { + var mapped = children[i$1 + 2].mapInner(mapping, childNode, from + 1, children[i$1] + oldOffset + 1, options); + if (mapped != empty) { + children[i$1] = fromLocal; + children[i$1 + 1] = toLocal; + children[i$1 + 2] = mapped; + } else { + children[i$1 + 1] = -2; + mustRebuild = true; + } + } else { + mustRebuild = true; + } + } } + + // Remaining children must be collected and rebuilt into the appropriate structure + if (mustRebuild) { + var decorations = mapAndGatherRemainingDecorations(children, oldChildren, newLocal || [], mapping, + offset, oldOffset, options); + var built = buildTree(decorations, node, 0, options); + newLocal = built.local; + for (var i$2 = 0; i$2 < children.length; i$2 += 3) { if (children[i$2 + 1] < 0) { + children.splice(i$2, 3); + i$2 -= 3; + } } + for (var i$3 = 0, j = 0; i$3 < built.children.length; i$3 += 3) { + var from$1 = built.children[i$3]; + while (j < children.length && children[j] < from$1) { j += 3; } + children.splice(j, 0, built.children[i$3], built.children[i$3 + 1], built.children[i$3 + 2]); + } + } + + return new DecorationSet(newLocal && newLocal.sort(byPos), children) +} + +function moveSpans(spans, offset) { + if (!offset || !spans.length) { return spans } + var result = []; + for (var i = 0; i < spans.length; i++) { + var span = spans[i]; + result.push(new Decoration(span.from + offset, span.to + offset, span.type)); + } + return result +} + +function mapAndGatherRemainingDecorations(children, oldChildren, decorations, mapping, offset, oldOffset, options) { + // Gather all decorations from the remaining marked children + function gather(set, oldOffset) { + for (var i = 0; i < set.local.length; i++) { + var mapped = set.local[i].map(mapping, offset, oldOffset); + if (mapped) { decorations.push(mapped); } + else if (options.onRemove) { options.onRemove(set.local[i].spec); } + } + for (var i$1 = 0; i$1 < set.children.length; i$1 += 3) + { gather(set.children[i$1 + 2], set.children[i$1] + oldOffset + 1); } + } + for (var i = 0; i < children.length; i += 3) { if (children[i + 1] == -1) + { gather(children[i + 2], oldChildren[i] + oldOffset + 1); } } + + return decorations +} + +function takeSpansForNode(spans, node, offset) { + if (node.isLeaf) { return null } + var end = offset + node.nodeSize, found = null; + for (var i = 0, span = (void 0); i < spans.length; i++) { + if ((span = spans[i]) && span.from > offset && span.to < end) { +(found || (found = [])).push(span); + spans[i] = null; + } + } + return found +} + +function withoutNulls(array) { + var result = []; + for (var i = 0; i < array.length; i++) + { if (array[i] != null) { result.push(array[i]); } } + return result +} + +// : ([Decoration], Node, number) → DecorationSet +// Build up a tree that corresponds to a set of decorations. `offset` +// is a base offset that should be subtractet from the `from` and `to` +// positions in the spans (so that we don't have to allocate new spans +// for recursive calls). +function buildTree(spans, node, offset, options) { + var children = [], hasNulls = false; + node.forEach(function (childNode, localStart) { + var found = takeSpansForNode(spans, childNode, localStart + offset); + if (found) { + hasNulls = true; + var subtree = buildTree(found, childNode, offset + localStart + 1, options); + if (subtree != empty) + { children.push(localStart, localStart + childNode.nodeSize, subtree); } + } + }); + var locals = moveSpans(hasNulls ? withoutNulls(spans) : spans, -offset).sort(byPos); + for (var i = 0; i < locals.length; i++) { if (!locals[i].type.valid(node, locals[i])) { + if (options.onRemove) { options.onRemove(locals[i].spec); } + locals.splice(i--, 1); + } } + return locals.length || children.length ? new DecorationSet(locals, children) : empty +} + +// : (Decoration, Decoration) → number +// Used to sort decorations so that ones with a low start position +// come first, and within a set with the same start position, those +// with an smaller end position come first. +function byPos(a, b) { + return a.from - b.from || a.to - b.to +} + +// : ([Decoration]) → [Decoration] +// Scan a sorted array of decorations for partially overlapping spans, +// and split those so that only fully overlapping spans are left (to +// make subsequent rendering easier). Will return the input array if +// no partially overlapping spans are found (the common case). +function removeOverlap(spans) { + var working = spans; + for (var i = 0; i < working.length - 1; i++) { + var span = working[i]; + if (span.from != span.to) { for (var j = i + 1; j < working.length; j++) { + var next = working[j]; + if (next.from == span.from) { + if (next.to != span.to) { + if (working == spans) { working = spans.slice(); } + // Followed by a partially overlapping larger span. Split that + // span. + working[j] = next.copy(next.from, span.to); + insertAhead(working, j + 1, next.copy(span.to, next.to)); + } + continue + } else { + if (next.from < span.to) { + if (working == spans) { working = spans.slice(); } + // The end of this one overlaps with a subsequent span. Split + // this one. + working[i] = span.copy(span.from, next.from); + insertAhead(working, j, span.copy(next.from, span.to)); + } + break + } + } } + } + return working +} + +function insertAhead(array, i, deco) { + while (i < array.length && byPos(deco, array[i]) > 0) { i++; } + array.splice(i, 0, deco); +} + +// : (EditorView) → union +// Get the decorations associated with the current props of a view. +function viewDecorations(view) { + var found = []; + view.someProp("decorations", function (f) { + var result = f(view.state); + if (result && result != empty) { found.push(result); } + }); + if (view.cursorWrapper) + { found.push(DecorationSet.create(view.state.doc, [view.cursorWrapper.deco])); } + return DecorationGroup.from(found) +} + +// ::- An editor view manages the DOM structure that represents an +// editable document. Its state and behavior are determined by its +// [props](#view.DirectEditorProps). +var EditorView = function EditorView(place, props) { + this._props = props; + // :: EditorState + // The view's current [state](#state.EditorState). + this.state = props.state; + + this.dispatch = this.dispatch.bind(this); + + this._root = null; + this.focused = false; + + // :: dom.Element + // An editable DOM node containing the document. (You probably + // should not directly interfere with its content.) + this.dom = (place && place.mount) || document.createElement("div"); + if (place) { + if (place.appendChild) { place.appendChild(this.dom); } + else if (place.apply) { place(this.dom); } + else if (place.mount) { this.mounted = true; } + } + + // :: bool + // Indicates whether the editor is currently [editable](#view.EditorProps.editable). + this.editable = getEditable(this); + this.markCursor = null; + this.cursorWrapper = null; + updateCursorWrapper(this); + this.nodeViews = buildNodeViews(this); + this.docView = docViewDesc(this.state.doc, computeDocDeco(this), viewDecorations(this), this.dom, this); + + this.lastSelectedViewDesc = null; + // :: ?{slice: Slice, move: bool} + // When editor content is being dragged, this object contains + // information about the dragged slice and whether it is being + // copied or moved. At any other time, it is null. + this.dragging = null; + + initInput(this); + + this.pluginViews = []; + this.updatePluginViews(); +}; + +var prototypeAccessors$2 = { props: { configurable: true },root: { configurable: true } }; + +// composing:: boolean +// Holds `true` when a +// [composition](https://developer.mozilla.org/en-US/docs/Mozilla/IME_handling_guide) +// is active. + +// :: DirectEditorProps +// The view's current [props](#view.EditorProps). +prototypeAccessors$2.props.get = function () { + if (this._props.state != this.state) { + var prev = this._props; + this._props = {}; + for (var name in prev) { this._props[name] = prev[name]; } + this._props.state = this.state; + } + return this._props +}; + +// :: (DirectEditorProps) +// Update the view's props. Will immediately cause an update to +// the DOM. +EditorView.prototype.update = function update (props) { + if (props.handleDOMEvents != this._props.handleDOMEvents) { ensureListeners(this); } + this._props = props; + this.updateStateInner(props.state, true); +}; + +// :: (DirectEditorProps) +// Update the view by updating existing props object with the object +// given as argument. Equivalent to `view.update(Object.assign({}, +// view.props, props))`. +EditorView.prototype.setProps = function setProps (props) { + var updated = {}; + for (var name in this._props) { updated[name] = this._props[name]; } + updated.state = this.state; + for (var name$1 in props) { updated[name$1] = props[name$1]; } + this.update(updated); +}; + +// :: (EditorState) +// Update the editor's `state` prop, without touching any of the +// other props. +EditorView.prototype.updateState = function updateState (state) { + this.updateStateInner(state, this.state.plugins != state.plugins); +}; + +EditorView.prototype.updateStateInner = function updateStateInner (state, reconfigured) { + var this$1 = this; + + var prev = this.state, redraw = false; + this.state = state; + if (reconfigured) { + var nodeViews = buildNodeViews(this); + if (changedNodeViews(nodeViews, this.nodeViews)) { + this.nodeViews = nodeViews; + redraw = true; + } + ensureListeners(this); + } + + this.editable = getEditable(this); + updateCursorWrapper(this); + var innerDeco = viewDecorations(this), outerDeco = computeDocDeco(this); + + var scroll = reconfigured ? "reset" + : state.scrollToSelection > prev.scrollToSelection ? "to selection" : "preserve"; + var updateDoc = redraw || !this.docView.matchesNode(state.doc, outerDeco, innerDeco); + var updateSel = updateDoc || !state.selection.eq(prev.selection); + var oldScrollPos = scroll == "preserve" && updateSel && this.dom.style.overflowAnchor == null && storeScrollPos(this); + + if (updateSel) { + this.domObserver.stop(); + // Work around an issue in Chrome, IE, and Edge where changing + // the DOM around an active selection puts it into a broken + // state where the thing the user sees differs from the + // selection reported by the Selection object (#710, #973, + // #1011, #1013). + var forceSelUpdate = updateDoc && (result.ie || result.chrome) && + !prev.selection.empty && !state.selection.empty && selectionContextChanged(prev.selection, state.selection); + if (updateDoc) { + if (redraw || !this.docView.update(state.doc, outerDeco, innerDeco, this)) { + this.docView.destroy(); + this.docView = docViewDesc(state.doc, outerDeco, innerDeco, this.dom, this); + } + } + // Work around for an issue where an update arriving right between + // a DOM selection change and the "selectionchange" event for it + // can cause a spurious DOM selection update, disrupting mouse + // drag selection. + if (forceSelUpdate || + !(this.mouseDown && this.domObserver.currentSelection.eq(this.root.getSelection()) && anchorInRightPlace(this))) { + selectionToDOM(this, forceSelUpdate); + } else { + syncNodeSelection(this, state.selection); + this.domObserver.setCurSelection(); + } + this.domObserver.start(); + } + + this.updatePluginViews(prev); + + if (scroll == "reset") { + this.dom.scrollTop = 0; + } else if (scroll == "to selection") { + var startDOM = this.root.getSelection().focusNode; + if (this.someProp("handleScrollToSelection", function (f) { return f(this$1); })) + ; // Handled + else if (state.selection instanceof prosemirrorState.NodeSelection) + { scrollRectIntoView(this, this.docView.domAfterPos(state.selection.from).getBoundingClientRect(), startDOM); } + else + { scrollRectIntoView(this, this.coordsAtPos(state.selection.head), startDOM); } + } else if (oldScrollPos) { + resetScrollPos(oldScrollPos); + } +}; + +EditorView.prototype.destroyPluginViews = function destroyPluginViews () { + var view; + while (view = this.pluginViews.pop()) { if (view.destroy) { view.destroy(); } } +}; + +EditorView.prototype.updatePluginViews = function updatePluginViews (prevState) { + if (!prevState || prevState.plugins != this.state.plugins) { + this.destroyPluginViews(); + for (var i = 0; i < this.state.plugins.length; i++) { + var plugin = this.state.plugins[i]; + if (plugin.spec.view) { this.pluginViews.push(plugin.spec.view(this)); } + } + } else { + for (var i$1 = 0; i$1 < this.pluginViews.length; i$1++) { + var pluginView = this.pluginViews[i$1]; + if (pluginView.update) { pluginView.update(this, prevState); } + } + } +}; + +// :: (string, ?(prop: *) → *) → * +// Goes over the values of a prop, first those provided directly, +// then those from plugins (in order), and calls `f` every time a +// non-undefined value is found. When `f` returns a truthy value, +// that is immediately returned. When `f` isn't provided, it is +// treated as the identity function (the prop value is returned +// directly). +EditorView.prototype.someProp = function someProp (propName, f) { + var prop = this._props && this._props[propName], value; + if (prop != null && (value = f ? f(prop) : prop)) { return value } + var plugins = this.state.plugins; + if (plugins) { for (var i = 0; i < plugins.length; i++) { + var prop$1 = plugins[i].props[propName]; + if (prop$1 != null && (value = f ? f(prop$1) : prop$1)) { return value } + } } +}; + +// :: () → bool +// Query whether the view has focus. +EditorView.prototype.hasFocus = function hasFocus () { + return this.root.activeElement == this.dom +}; + +// :: () +// Focus the editor. +EditorView.prototype.focus = function focus () { + this.domObserver.stop(); + if (this.editable) { focusPreventScroll(this.dom); } + selectionToDOM(this); + this.domObserver.start(); +}; + +// :: union +// Get the document root in which the editor exists. This will +// usually be the top-level `document`, but might be a [shadow +// DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Shadow_DOM) +// root if the editor is inside one. +prototypeAccessors$2.root.get = function () { + var cached = this._root; + if (cached == null) { for (var search = this.dom.parentNode; search; search = search.parentNode) { + if (search.nodeType == 9 || (search.nodeType == 11 && search.host)) { + if (!search.getSelection) { Object.getPrototypeOf(search).getSelection = function () { return document.getSelection(); }; } + return this._root = search + } + } } + return cached || document +}; + +// :: ({left: number, top: number}) → ?{pos: number, inside: number} +// Given a pair of viewport coordinates, return the document +// position that corresponds to them. May return null if the given +// coordinates aren't inside of the editor. When an object is +// returned, its `pos` property is the position nearest to the +// coordinates, and its `inside` property holds the position of the +// inner node that the position falls inside of, or -1 if it is at +// the top level, not in any node. +EditorView.prototype.posAtCoords = function posAtCoords$1 (coords) { + return posAtCoords(this, coords) +}; + +// :: (number) → {left: number, right: number, top: number, bottom: number} +// Returns the viewport rectangle at a given document position. `left` +// and `right` will be the same number, as this returns a flat +// cursor-ish rectangle. +EditorView.prototype.coordsAtPos = function coordsAtPos$1 (pos) { + return coordsAtPos(this, pos) +}; + +// :: (number) → {node: dom.Node, offset: number} +// Find the DOM position that corresponds to the given document +// position. Note that you should **not** mutate the editor's +// internal DOM, only inspect it (and even that is usually not +// necessary). +EditorView.prototype.domAtPos = function domAtPos (pos) { + return this.docView.domFromPos(pos) +}; + +// :: (number) → ?dom.Node +// Find the DOM node that represents the document node after the +// given position. May return `null` when the position doesn't point +// in front of a node or if the node is inside an opaque node view. +// +// This is intended to be able to call things like +// `getBoundingClientRect` on that DOM node. Do **not** mutate the +// editor DOM directly, or add styling this way, since that will be +// immediately overriden by the editor as it redraws the node. +EditorView.prototype.nodeDOM = function nodeDOM (pos) { + var desc = this.docView.descAt(pos); + return desc ? desc.nodeDOM : null +}; + +// :: (dom.Node, number, ?number) → number +// Find the document position that corresponds to a given DOM +// position. (Whenever possible, it is preferable to inspect the +// document structure directly, rather than poking around in the +// DOM, but sometimes—for example when interpreting an event +// target—you don't have a choice.) +// +// The `bias` parameter can be used to influence which side of a DOM +// node to use when the position is inside a leaf node. +EditorView.prototype.posAtDOM = function posAtDOM (node, offset, bias) { + if ( bias === void 0 ) bias = -1; + + var pos = this.docView.posFromDOM(node, offset, bias); + if (pos == null) { throw new RangeError("DOM position not inside the editor") } + return pos +}; + +// :: (union<"up", "down", "left", "right", "forward", "backward">, ?EditorState) → bool +// Find out whether the selection is at the end of a textblock when +// moving in a given direction. When, for example, given `"left"`, +// it will return true if moving left from the current cursor +// position would leave that position's parent textblock. Will apply +// to the view's current state by default, but it is possible to +// pass a different state. +EditorView.prototype.endOfTextblock = function endOfTextblock$1 (dir, state) { + return endOfTextblock(this, state || this.state, dir) +}; + +// :: () +// Removes the editor from the DOM and destroys all [node +// views](#view.NodeView). +EditorView.prototype.destroy = function destroy () { + if (!this.docView) { return } + destroyInput(this); + this.destroyPluginViews(); + if (this.mounted) { + this.docView.update(this.state.doc, [], viewDecorations(this), this); + this.dom.textContent = ""; + } else if (this.dom.parentNode) { + this.dom.parentNode.removeChild(this.dom); + } + this.docView.destroy(); + this.docView = null; +}; + +// Used for testing. +EditorView.prototype.dispatchEvent = function dispatchEvent$1 (event) { + return dispatchEvent(this, event) +}; + +// :: (Transaction) +// Dispatch a transaction. Will call +// [`dispatchTransaction`](#view.DirectEditorProps.dispatchTransaction) +// when given, and otherwise defaults to applying the transaction to +// the current state and calling +// [`updateState`](#view.EditorView.updateState) with the result. +// This method is bound to the view instance, so that it can be +// easily passed around. +EditorView.prototype.dispatch = function dispatch (tr) { + var dispatchTransaction = this._props.dispatchTransaction; + if (dispatchTransaction) { dispatchTransaction.call(this, tr); } + else { this.updateState(this.state.apply(tr)); } +}; + +Object.defineProperties( EditorView.prototype, prototypeAccessors$2 ); + +function computeDocDeco(view) { + var attrs = Object.create(null); + attrs.class = "ProseMirror"; + attrs.contenteditable = String(view.editable); + + view.someProp("attributes", function (value) { + if (typeof value == "function") { value = value(view.state); } + if (value) { for (var attr in value) { + if (attr == "class") + { attrs.class += " " + value[attr]; } + else if (!attrs[attr] && attr != "contenteditable" && attr != "nodeName") + { attrs[attr] = String(value[attr]); } + } } + }); + + return [Decoration.node(0, view.state.doc.content.size, attrs)] +} + +function updateCursorWrapper(view) { + var ref = view.state.selection; + var $head = ref.$head; + var $anchor = ref.$anchor; + var visible = ref.visible; + if (view.markCursor) { + var dom = document.createElement("img"); + dom.setAttribute("mark-placeholder", "true"); + view.cursorWrapper = {dom: dom, deco: Decoration.widget($head.pos, dom, {raw: true, marks: view.markCursor})}; + } else if (visible || $head.pos != $anchor.pos) { + view.cursorWrapper = null; + } else { + var dom$1; + if (!view.cursorWrapper || view.cursorWrapper.dom.childNodes.length) { + dom$1 = document.createElement("div"); + dom$1.style.position = "absolute"; + dom$1.style.left = "-100000px"; + } else if (view.cursorWrapper.deco.pos != $head.pos) { + dom$1 = view.cursorWrapper.dom; + } + if (dom$1) + { view.cursorWrapper = {dom: dom$1, deco: Decoration.widget($head.pos, dom$1, {raw: true})}; } + } +} + +function getEditable(view) { + return !view.someProp("editable", function (value) { return value(view.state) === false; }) +} + +function selectionContextChanged(sel1, sel2) { + var depth = Math.min(sel1.$anchor.sharedDepth(sel1.head), sel2.$anchor.sharedDepth(sel2.head)); + return sel1.$anchor.node(depth) != sel2.$anchor.node(depth) +} + +function buildNodeViews(view) { + var result = {}; + view.someProp("nodeViews", function (obj) { + for (var prop in obj) { if (!Object.prototype.hasOwnProperty.call(result, prop)) + { result[prop] = obj[prop]; } } + }); + return result +} + +function changedNodeViews(a, b) { + var nA = 0, nB = 0; + for (var prop in a) { + if (a[prop] != b[prop]) { return true } + nA++; + } + for (var _ in b) { nB++; } + return nA != nB +} + +// EditorProps:: interface +// +// Props are configuration values that can be passed to an editor view +// or included in a plugin. This interface lists the supported props. +// +// The various event-handling functions may all return `true` to +// indicate that they handled the given event. The view will then take +// care to call `preventDefault` on the event, except with +// `handleDOMEvents`, where the handler itself is responsible for that. +// +// How a prop is resolved depends on the prop. Handler functions are +// called one at a time, starting with the base props and then +// searching through the plugins (in order of appearance) until one of +// them returns true. For some props, the first plugin that yields a +// value gets precedence. +// +// handleDOMEvents:: ?Object<(view: EditorView, event: dom.Event) → bool> +// Can be an object mapping DOM event type names to functions that +// handle them. Such functions will be called before any handling +// ProseMirror does of events fired on the editable DOM element. +// Contrary to the other event handling props, when returning true +// from such a function, you are responsible for calling +// `preventDefault` yourself (or not, if you want to allow the +// default behavior). +// +// handleKeyDown:: ?(view: EditorView, event: dom.KeyboardEvent) → bool +// Called when the editor receives a `keydown` event. +// +// handleKeyPress:: ?(view: EditorView, event: dom.KeyboardEvent) → bool +// Handler for `keypress` events. +// +// handleTextInput:: ?(view: EditorView, from: number, to: number, text: string) → bool +// Whenever the user directly input text, this handler is called +// before the input is applied. If it returns `true`, the default +// behavior of actually inserting the text is suppressed. +// +// handleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool +// Called for each node around a click, from the inside out. The +// `direct` flag will be true for the inner node. +// +// handleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool +// Called when the editor is clicked, after `handleClickOn` handlers +// have been called. +// +// handleDoubleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool +// Called for each node around a double click. +// +// handleDoubleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool +// Called when the editor is double-clicked, after `handleDoubleClickOn`. +// +// handleTripleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool +// Called for each node around a triple click. +// +// handleTripleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool +// Called when the editor is triple-clicked, after `handleTripleClickOn`. +// +// handlePaste:: ?(view: EditorView, event: dom.Event, slice: Slice) → bool +// Can be used to override the behavior of pasting. `slice` is the +// pasted content parsed by the editor, but you can directly access +// the event to get at the raw content. +// +// handleDrop:: ?(view: EditorView, event: dom.Event, slice: Slice, moved: bool) → bool +// Called when something is dropped on the editor. `moved` will be +// true if this drop moves from the current selection (which should +// thus be deleted). +// +// handleScrollToSelection:: ?(view: EditorView) → bool +// Called when the view, after updating its state, tries to scroll +// the selection into view. A handler function may return false to +// indicate that it did not handle the scrolling and further +// handlers or the default behavior should be tried. +// +// createSelectionBetween:: ?(view: EditorView, anchor: ResolvedPos, head: ResolvedPos) → ?Selection +// Can be used to override the way a selection is created when +// reading a DOM selection between the given anchor and head. +// +// domParser:: ?DOMParser +// The [parser](#model.DOMParser) to use when reading editor changes +// from the DOM. Defaults to calling +// [`DOMParser.fromSchema`](#model.DOMParser^fromSchema) on the +// editor's schema. +// +// transformPastedHTML:: ?(html: string) → string +// Can be used to transform pasted HTML text, _before_ it is parsed, +// for example to clean it up. +// +// clipboardParser:: ?DOMParser +// The [parser](#model.DOMParser) to use when reading content from +// the clipboard. When not given, the value of the +// [`domParser`](#view.EditorProps.domParser) prop is used. +// +// transformPastedText:: ?(text: string) → string +// Transform pasted plain text. +// +// clipboardTextParser:: ?(text: string, $context: ResolvedPos) → Slice +// A function to parse text from the clipboard into a document +// slice. Called after +// [`transformPastedText`](#view.EditorProps.transformPastedText). +// The default behavior is to split the text into lines, wrap them +// in `

    ` tags, and call +// [`clipboardParser`](#view.EditorProps.clipboardParser) on it. +// +// transformPasted:: ?(Slice) → Slice +// Can be used to transform pasted content before it is applied to +// the document. +// +// nodeViews:: ?Object<(node: Node, view: EditorView, getPos: () → number, decorations: [Decoration]) → NodeView> +// Allows you to pass custom rendering and behavior logic for nodes +// and marks. Should map node and mark names to constructor +// functions that produce a [`NodeView`](#view.NodeView) object +// implementing the node's display behavior. For nodes, the third +// argument `getPos` is a function that can be called to get the +// node's current position, which can be useful when creating +// transactions to update it. For marks, the third argument is a +// boolean that indicates whether the mark's content is inline. +// +// `decorations` is an array of node or inline decorations that are +// active around the node. They are automatically drawn in the +// normal way, and you will usually just want to ignore this, but +// they can also be used as a way to provide context information to +// the node view without adding it to the document itself. +// +// clipboardSerializer:: ?DOMSerializer +// The DOM serializer to use when putting content onto the +// clipboard. If not given, the result of +// [`DOMSerializer.fromSchema`](#model.DOMSerializer^fromSchema) +// will be used. +// +// clipboardTextSerializer:: ?(Slice) → string +// A function that will be called to get the text for the current +// selection when copying text to the clipboard. By default, the +// editor will use [`textBetween`](#model.Node.textBetween) on the +// selected range. +// +// decorations:: ?(state: EditorState) → ?DecorationSet +// A set of [document decorations](#view.Decoration) to show in the +// view. +// +// editable:: ?(state: EditorState) → bool +// When this returns false, the content of the view is not directly +// editable. +// +// attributes:: ?union, (EditorState) → ?Object> +// Control the DOM attributes of the editable element. May be either +// an object or a function going from an editor state to an object. +// By default, the element will get a class `"ProseMirror"`, and +// will have its `contentEditable` attribute determined by the +// [`editable` prop](#view.EditorProps.editable). Additional classes +// provided here will be added to the class. For other attributes, +// the value provided first (as in +// [`someProp`](#view.EditorView.someProp)) will be used. +// +// scrollThreshold:: ?union +// Determines the distance (in pixels) between the cursor and the +// end of the visible viewport at which point, when scrolling the +// cursor into view, scrolling takes place. Defaults to 0. +// +// scrollMargin:: ?union +// Determines the extra space (in pixels) that is left above or +// below the cursor when it is scrolled into view. Defaults to 5. + +// DirectEditorProps:: interface extends EditorProps +// +// The props object given directly to the editor view supports two +// fields that can't be used in plugins: +// +// state:: EditorState +// The current state of the editor. +// +// dispatchTransaction:: ?(tr: Transaction) +// The callback over which to send transactions (state updates) +// produced by the view. If you specify this, you probably want to +// make sure this ends up calling the view's +// [`updateState`](#view.EditorView.updateState) method with a new +// state that has the transaction +// [applied](#state.EditorState.apply). The callback will be bound to have +// the view instance as its `this` binding. + +exports.Decoration = Decoration; +exports.DecorationSet = DecorationSet; +exports.EditorView = EditorView; +exports.__endComposition = endComposition; +exports.__parseFromClipboard = parseFromClipboard; +exports.__serializeForClipboard = serializeForClipboard; +//# sourceMappingURL=index.js.map diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/dist/index.js.map b/packages/tiptap-extensions/node_modules/prosemirror-view/dist/index.js.map new file mode 100644 index 0000000000..4f813e9420 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sources":["../src/browser.js","../src/dom.js","../src/domcoords.js","../src/viewdesc.js","../src/capturekeys.js","../src/selection.js","../src/domchange.js","../src/clipboard.js","../src/domobserver.js","../src/input.js","../src/decoration.js","../src/index.js"],"sourcesContent":["const result = {}\nexport default result\n\nif (typeof navigator != \"undefined\" && typeof document != \"undefined\") {\n const ie_edge = /Edge\\/(\\d+)/.exec(navigator.userAgent)\n const ie_upto10 = /MSIE \\d/.test(navigator.userAgent)\n const ie_11up = /Trident\\/(?:[7-9]|\\d{2,})\\..*rv:(\\d+)/.exec(navigator.userAgent)\n\n result.mac = /Mac/.test(navigator.platform)\n let ie = result.ie = !!(ie_upto10 || ie_11up || ie_edge)\n result.ie_version = ie_upto10 ? document.documentMode || 6 : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : null\n result.gecko = !ie && /gecko\\/(\\d+)/i.test(navigator.userAgent)\n result.gecko_version = result.gecko && +(/Firefox\\/(\\d+)/.exec(navigator.userAgent) || [0, 0])[1]\n let chrome = !ie && /Chrome\\/(\\d+)/.exec(navigator.userAgent)\n result.chrome = !!chrome\n result.chrome_version = chrome && +chrome[1]\n result.ios = !ie && /AppleWebKit/.test(navigator.userAgent) && /Mobile\\/\\w+/.test(navigator.userAgent)\n result.android = /Android \\d/.test(navigator.userAgent)\n result.webkit = !ie && 'WebkitAppearance' in document.documentElement.style\n result.safari = /Apple Computer/.test(navigator.vendor)\n result.webkit_version = result.webkit && +(/\\bAppleWebKit\\/(\\d+)/.exec(navigator.userAgent) || [0, 0])[1]\n}\n","import browser from \"./browser\"\n\nexport const domIndex = function(node) {\n for (var index = 0;; index++) {\n node = node.previousSibling\n if (!node) return index\n }\n}\n\nexport const parentNode = function(node) {\n let parent = node.parentNode\n return parent && parent.nodeType == 11 ? parent.host : parent\n}\n\nexport const textRange = function(node, from, to) {\n let range = document.createRange()\n range.setEnd(node, to == null ? node.nodeValue.length : to)\n range.setStart(node, from || 0)\n return range\n}\n\n// Scans forward and backward through DOM positions equivalent to the\n// given one to see if the two are in the same place (i.e. after a\n// text node vs at the end of that text node)\nexport const isEquivalentPosition = function(node, off, targetNode, targetOff) {\n return targetNode && (scanFor(node, off, targetNode, targetOff, -1) ||\n scanFor(node, off, targetNode, targetOff, 1))\n}\n\nconst atomElements = /^(img|br|input|textarea|hr)$/i\n\nfunction scanFor(node, off, targetNode, targetOff, dir) {\n for (;;) {\n if (node == targetNode && off == targetOff) return true\n if (off == (dir < 0 ? 0 : nodeSize(node))) {\n let parent = node.parentNode\n if (parent.nodeType != 1 || hasBlockDesc(node) || atomElements.test(node.nodeName) || node.contentEditable == \"false\")\n return false\n off = domIndex(node) + (dir < 0 ? 0 : 1)\n node = parent\n } else if (node.nodeType == 1) {\n node = node.childNodes[off + (dir < 0 ? -1 : 0)]\n off = dir < 0 ? nodeSize(node) : 0\n } else {\n return false\n }\n }\n}\n\nexport function nodeSize(node) {\n return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length\n}\n\nfunction hasBlockDesc(dom) {\n let desc\n for (let cur = dom; cur; cur = cur.parentNode) if (desc = cur.pmViewDesc) break\n return desc && desc.node && desc.node.isBlock && (desc.dom == dom || desc.contentDOM == dom)\n}\n\n// Work around Chrome issue https://bugs.chromium.org/p/chromium/issues/detail?id=447523\n// (isCollapsed inappropriately returns true in shadow dom)\nexport const selectionCollapsed = function(domSel) {\n let collapsed = domSel.isCollapsed\n if (collapsed && browser.chrome && domSel.rangeCount && !domSel.getRangeAt(0).collapsed)\n collapsed = false\n return collapsed\n}\n\nexport function keyEvent(keyCode, key) {\n let event = document.createEvent(\"Event\")\n event.initEvent(\"keydown\", true, true)\n event.keyCode = keyCode\n event.key = event.code = key\n return event\n}\n","import {nodeSize, textRange, parentNode} from \"./dom\"\nimport browser from \"./browser\"\n\nfunction windowRect(win) {\n return {left: 0, right: win.innerWidth,\n top: 0, bottom: win.innerHeight}\n}\n\nfunction getSide(value, side) {\n return typeof value == \"number\" ? value : value[side]\n}\n\nexport function scrollRectIntoView(view, rect, startDOM) {\n let scrollThreshold = view.someProp(\"scrollThreshold\") || 0, scrollMargin = view.someProp(\"scrollMargin\") || 5\n let doc = view.dom.ownerDocument, win = doc.defaultView\n for (let parent = startDOM || view.dom;; parent = parentNode(parent)) {\n if (!parent) break\n if (parent.nodeType != 1) continue\n let atTop = parent == doc.body || parent.nodeType != 1\n let bounding = atTop ? windowRect(win) : parent.getBoundingClientRect()\n let moveX = 0, moveY = 0\n if (rect.top < bounding.top + getSide(scrollThreshold, \"top\"))\n moveY = -(bounding.top - rect.top + getSide(scrollMargin, \"top\"))\n else if (rect.bottom > bounding.bottom - getSide(scrollThreshold, \"bottom\"))\n moveY = rect.bottom - bounding.bottom + getSide(scrollMargin, \"bottom\")\n if (rect.left < bounding.left + getSide(scrollThreshold, \"left\"))\n moveX = -(bounding.left - rect.left + getSide(scrollMargin, \"left\"))\n else if (rect.right > bounding.right - getSide(scrollThreshold, \"right\"))\n moveX = rect.right - bounding.right + getSide(scrollMargin, \"right\")\n if (moveX || moveY) {\n if (atTop) {\n win.scrollBy(moveX, moveY)\n } else {\n if (moveY) parent.scrollTop += moveY\n if (moveX) parent.scrollLeft += moveX\n }\n }\n if (atTop) break\n }\n}\n\n// Store the scroll position of the editor's parent nodes, along with\n// the top position of an element near the top of the editor, which\n// will be used to make sure the visible viewport remains stable even\n// when the size of the content above changes.\nexport function storeScrollPos(view) {\n let rect = view.dom.getBoundingClientRect(), startY = Math.max(0, rect.top)\n let refDOM, refTop\n for (let x = (rect.left + rect.right) / 2, y = startY + 1;\n y < Math.min(innerHeight, rect.bottom); y += 5) {\n let dom = view.root.elementFromPoint(x, y)\n if (dom == view.dom || !view.dom.contains(dom)) continue\n let localRect = dom.getBoundingClientRect()\n if (localRect.top >= startY - 20) {\n refDOM = dom\n refTop = localRect.top\n break\n }\n }\n return {refDOM, refTop, stack: scrollStack(view.dom)}\n}\n\nfunction scrollStack(dom) {\n let stack = [], doc = dom.ownerDocument\n for (; dom; dom = parentNode(dom)) {\n stack.push({dom, top: dom.scrollTop, left: dom.scrollLeft})\n if (dom == doc) break\n }\n return stack\n}\n\n// Reset the scroll position of the editor's parent nodes to that what\n// it was before, when storeScrollPos was called.\nexport function resetScrollPos({refDOM, refTop, stack}) {\n let newRefTop = refDOM ? refDOM.getBoundingClientRect().top : 0\n restoreScrollStack(stack, newRefTop == 0 ? 0 : newRefTop - refTop)\n}\n\nfunction restoreScrollStack(stack, dTop) {\n for (let i = 0; i < stack.length; i++) {\n let {dom, top, left} = stack[i]\n if (dom.scrollTop != top + dTop) dom.scrollTop = top + dTop\n if (dom.scrollLeft != left) dom.scrollLeft = left\n }\n}\n\nlet preventScrollSupported = null\n// Feature-detects support for .focus({preventScroll: true}), and uses\n// a fallback kludge when not supported.\nexport function focusPreventScroll(dom) {\n if (dom.setActive) return dom.setActive() // in IE\n if (preventScrollSupported) return dom.focus(preventScrollSupported)\n\n let stored = scrollStack(dom)\n dom.focus(preventScrollSupported == null ? {\n get preventScroll() {\n preventScrollSupported = {preventScroll: true}\n return true\n }\n } : undefined)\n if (!preventScrollSupported) {\n preventScrollSupported = false\n restoreScrollStack(stored, 0)\n }\n}\n\nfunction findOffsetInNode(node, coords) {\n let closest, dxClosest = 2e8, coordsClosest, offset = 0\n let rowBot = coords.top, rowTop = coords.top\n for (let child = node.firstChild, childIndex = 0; child; child = child.nextSibling, childIndex++) {\n let rects\n if (child.nodeType == 1) rects = child.getClientRects()\n else if (child.nodeType == 3) rects = textRange(child).getClientRects()\n else continue\n\n for (let i = 0; i < rects.length; i++) {\n let rect = rects[i]\n if (rect.top <= rowBot && rect.bottom >= rowTop) {\n rowBot = Math.max(rect.bottom, rowBot)\n rowTop = Math.min(rect.top, rowTop)\n let dx = rect.left > coords.left ? rect.left - coords.left\n : rect.right < coords.left ? coords.left - rect.right : 0\n if (dx < dxClosest) {\n closest = child\n dxClosest = dx\n coordsClosest = dx && closest.nodeType == 3 ? {left: rect.right < coords.left ? rect.right : rect.left, top: coords.top} : coords\n if (child.nodeType == 1 && dx)\n offset = childIndex + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0)\n continue\n }\n }\n if (!closest && (coords.left >= rect.right && coords.top >= rect.top ||\n coords.left >= rect.left && coords.top >= rect.bottom))\n offset = childIndex + 1\n }\n }\n if (closest && closest.nodeType == 3) return findOffsetInText(closest, coordsClosest)\n if (!closest || (dxClosest && closest.nodeType == 1)) return {node, offset}\n return findOffsetInNode(closest, coordsClosest)\n}\n\nfunction findOffsetInText(node, coords) {\n let len = node.nodeValue.length\n let range = document.createRange()\n for (let i = 0; i < len; i++) {\n range.setEnd(node, i + 1)\n range.setStart(node, i)\n let rect = singleRect(range, 1)\n if (rect.top == rect.bottom) continue\n if (inRect(coords, rect))\n return {node, offset: i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0)}\n }\n return {node, offset: 0}\n}\n\nfunction inRect(coords, rect) {\n return coords.left >= rect.left - 1 && coords.left <= rect.right + 1&&\n coords.top >= rect.top - 1 && coords.top <= rect.bottom + 1\n}\n\nfunction targetKludge(dom, coords) {\n let parent = dom.parentNode\n if (parent && /^li$/i.test(parent.nodeName) && coords.left < dom.getBoundingClientRect().left)\n return parent\n return dom\n}\n\nfunction posFromElement(view, elt, coords) {\n let {node, offset} = findOffsetInNode(elt, coords), bias = -1\n if (node.nodeType == 1 && !node.firstChild) {\n let rect = node.getBoundingClientRect()\n bias = rect.left != rect.right && coords.left > (rect.left + rect.right) / 2 ? 1 : -1\n }\n return view.docView.posFromDOM(node, offset, bias)\n}\n\nfunction posFromCaret(view, node, offset, coords) {\n // Browser (in caretPosition/RangeFromPoint) will agressively\n // normalize towards nearby inline nodes. Since we are interested in\n // positions between block nodes too, we first walk up the hierarchy\n // of nodes to see if there are block nodes that the coordinates\n // fall outside of. If so, we take the position before/after that\n // block. If not, we call `posFromDOM` on the raw node/offset.\n let outside = -1\n for (let cur = node;;) {\n if (cur == view.dom) break\n let desc = view.docView.nearestDesc(cur, true)\n if (!desc) return null\n if (desc.node.isBlock && desc.parent) {\n let rect = desc.dom.getBoundingClientRect()\n if (rect.left > coords.left || rect.top > coords.top) outside = desc.posBefore\n else if (rect.right < coords.left || rect.bottom < coords.top) outside = desc.posAfter\n else break\n }\n cur = desc.dom.parentNode\n }\n return outside > -1 ? outside : view.docView.posFromDOM(node, offset)\n}\n\nfunction elementFromPoint(element, coords, box) {\n let len = element.childNodes.length\n if (len && box.top < box.bottom) {\n for (let startI = Math.max(0, Math.min(len - 1, Math.floor(len * (coords.top - box.top) / (box.bottom - box.top)) - 2)), i = startI;;) {\n let child = element.childNodes[i]\n if (child.nodeType == 1) {\n let rects = child.getClientRects()\n for (let j = 0; j < rects.length; j++) {\n let rect = rects[j]\n if (inRect(coords, rect)) return elementFromPoint(child, coords, rect)\n }\n }\n if ((i = (i + 1) % len) == startI) break\n }\n }\n return element\n}\n\n// Given an x,y position on the editor, get the position in the document.\nexport function posAtCoords(view, coords) {\n let root = view.root, node, offset\n if (root.caretPositionFromPoint) {\n try { // Firefox throws for this call in hard-to-predict circumstances (#994)\n let pos = root.caretPositionFromPoint(coords.left, coords.top)\n if (pos) ({offsetNode: node, offset} = pos)\n } catch (_) {}\n }\n if (!node && root.caretRangeFromPoint) {\n let range = root.caretRangeFromPoint(coords.left, coords.top)\n if (range) ({startContainer: node, startOffset: offset} = range)\n }\n\n let elt = root.elementFromPoint(coords.left, coords.top + 1), pos\n if (!elt || !view.dom.contains(elt.nodeType != 1 ? elt.parentNode : elt)) {\n let box = view.dom.getBoundingClientRect()\n if (!inRect(coords, box)) return null\n elt = elementFromPoint(view.dom, coords, box)\n if (!elt) return null\n }\n elt = targetKludge(elt, coords)\n if (node) {\n if (browser.gecko && node.nodeType == 1) {\n // Firefox will sometimes return offsets into nodes, which\n // have no actual children, from caretPositionFromPoint (#953)\n offset = Math.min(offset, node.childNodes.length)\n // It'll also move the returned position before image nodes,\n // even if those are behind it.\n if (offset < node.childNodes.length) {\n let next = node.childNodes[offset], box\n if (next.nodeName == \"IMG\" && (box = next.getBoundingClientRect()).right <= coords.left &&\n box.bottom > coords.top)\n offset++\n }\n }\n // Suspiciously specific kludge to work around caret*FromPoint\n // never returning a position at the end of the document\n if (node == view.dom && offset == node.childNodes.length - 1 && node.lastChild.nodeType == 1 &&\n coords.top > node.lastChild.getBoundingClientRect().bottom)\n pos = view.state.doc.content.size\n // Ignore positions directly after a BR, since caret*FromPoint\n // 'round up' positions that would be more accurately placed\n // before the BR node.\n else if (offset == 0 || node.nodeType != 1 || node.childNodes[offset - 1].nodeName != \"BR\")\n pos = posFromCaret(view, node, offset, coords)\n }\n if (pos == null) pos = posFromElement(view, elt, coords)\n\n let desc = view.docView.nearestDesc(elt, true)\n return {pos, inside: desc ? desc.posAtStart - desc.border : -1}\n}\n\nfunction singleRect(object, bias) {\n let rects = object.getClientRects()\n return !rects.length ? object.getBoundingClientRect() : rects[bias < 0 ? 0 : rects.length - 1]\n}\n\n// : (EditorView, number) → {left: number, top: number, right: number, bottom: number}\n// Given a position in the document model, get a bounding box of the\n// character at that position, relative to the window.\nexport function coordsAtPos(view, pos) {\n let {node, offset} = view.docView.domFromPos(pos)\n\n // These browsers support querying empty text ranges\n if (node.nodeType == 3 && (browser.chrome || browser.gecko)) {\n let rect = singleRect(textRange(node, offset, offset), 0)\n // Firefox returns bad results (the position before the space)\n // when querying a position directly after line-broken\n // whitespace. Detect this situation and and kludge around it\n if (browser.gecko && offset && /\\s/.test(node.nodeValue[offset - 1]) && offset < node.nodeValue.length) {\n let rectBefore = singleRect(textRange(node, offset - 1, offset - 1), -1)\n if (Math.abs(rectBefore.left - rect.left) < 1 && rectBefore.top == rect.top) {\n let rectAfter = singleRect(textRange(node, offset, offset + 1), -1)\n return flattenV(rectAfter, rectAfter.left < rectBefore.left)\n }\n }\n return rect\n }\n\n if (node.nodeType == 1 && !view.state.doc.resolve(pos).parent.inlineContent) {\n // Return a horizontal line in block context\n let top = true, rect\n if (offset < node.childNodes.length) {\n let after = node.childNodes[offset]\n if (after.nodeType == 1) rect = after.getBoundingClientRect()\n }\n if (!rect && offset) {\n let before = node.childNodes[offset - 1]\n if (before.nodeType == 1) { rect = before.getBoundingClientRect(); top = false }\n }\n return flattenH(rect || node.getBoundingClientRect(), top)\n }\n\n // Not Firefox/Chrome, or not in a text node, so we have to use\n // actual element/character rectangles to get a solution (this part\n // is not very bidi-safe)\n //\n // Try the left side first, fall back to the right one if that\n // doesn't work.\n for (let dir = -1; dir < 2; dir += 2) {\n if (dir < 0 && offset) {\n let prev, target = node.nodeType == 3 ? textRange(node, offset - 1, offset)\n : (prev = node.childNodes[offset - 1]).nodeType == 3 ? textRange(prev)\n : prev.nodeType == 1 && prev.nodeName != \"BR\" ? prev : null // BR nodes tend to only return the rectangle before them\n if (target) {\n let rect = singleRect(target, 1)\n if (rect.top < rect.bottom) return flattenV(rect, false)\n }\n } else if (dir > 0 && offset < nodeSize(node)) {\n let next, target = node.nodeType == 3 ? textRange(node, offset, offset + 1)\n : (next = node.childNodes[offset]).nodeType == 3 ? textRange(next)\n : next.nodeType == 1 ? next : null\n if (target) {\n let rect = singleRect(target, -1)\n if (rect.top < rect.bottom) return flattenV(rect, true)\n }\n }\n }\n // All else failed, just try to get a rectangle for the target node\n return flattenV(singleRect(node.nodeType == 3 ? textRange(node) : node, 0), false)\n}\n\nfunction flattenV(rect, left) {\n if (rect.width == 0) return rect\n let x = left ? rect.left : rect.right\n return {top: rect.top, bottom: rect.bottom, left: x, right: x}\n}\n\nfunction flattenH(rect, top) {\n if (rect.height == 0) return rect\n let y = top ? rect.top : rect.bottom\n return {top: y, bottom: y, left: rect.left, right: rect.right}\n}\n\nfunction withFlushedState(view, state, f) {\n let viewState = view.state, active = view.root.activeElement\n if (viewState != state) view.updateState(state)\n if (active != view.dom) view.focus()\n try {\n return f()\n } finally {\n if (viewState != state) view.updateState(viewState)\n if (active != view.dom) active.focus()\n }\n}\n\n// : (EditorView, number, number)\n// Whether vertical position motion in a given direction\n// from a position would leave a text block.\nfunction endOfTextblockVertical(view, state, dir) {\n let sel = state.selection\n let $pos = dir == \"up\" ? sel.$anchor.min(sel.$head) : sel.$anchor.max(sel.$head)\n return withFlushedState(view, state, () => {\n let {node: dom} = view.docView.domFromPos($pos.pos)\n for (;;) {\n let nearest = view.docView.nearestDesc(dom, true)\n if (!nearest) break\n if (nearest.node.isBlock) { dom = nearest.dom; break }\n dom = nearest.dom.parentNode\n }\n let coords = coordsAtPos(view, $pos.pos)\n for (let child = dom.firstChild; child; child = child.nextSibling) {\n let boxes\n if (child.nodeType == 1) boxes = child.getClientRects()\n else if (child.nodeType == 3) boxes = textRange(child, 0, child.nodeValue.length).getClientRects()\n else continue\n for (let i = 0; i < boxes.length; i++) {\n let box = boxes[i]\n if (box.bottom > box.top && (dir == \"up\" ? box.bottom < coords.top + 1 : box.top > coords.bottom - 1))\n return false\n }\n }\n return true\n })\n}\n\nconst maybeRTL = /[\\u0590-\\u08ac]/\n\nfunction endOfTextblockHorizontal(view, state, dir) {\n let {$head} = state.selection\n if (!$head.parent.isTextblock) return false\n let offset = $head.parentOffset, atStart = !offset, atEnd = offset == $head.parent.content.size\n let sel = getSelection()\n // If the textblock is all LTR, or the browser doesn't support\n // Selection.modify (Edge), fall back to a primitive approach\n if (!maybeRTL.test($head.parent.textContent) || !sel.modify)\n return dir == \"left\" || dir == \"backward\" ? atStart : atEnd\n\n return withFlushedState(view, state, () => {\n // This is a huge hack, but appears to be the best we can\n // currently do: use `Selection.modify` to move the selection by\n // one character, and see if that moves the cursor out of the\n // textblock (or doesn't move it at all, when at the start/end of\n // the document).\n let oldRange = sel.getRangeAt(0), oldNode = sel.focusNode, oldOff = sel.focusOffset\n let oldBidiLevel = sel.caretBidiLevel // Only for Firefox\n sel.modify(\"move\", dir, \"character\")\n let parentDOM = $head.depth ? view.docView.domAfterPos($head.before()) : view.dom\n let result = !parentDOM.contains(sel.focusNode.nodeType == 1 ? sel.focusNode : sel.focusNode.parentNode) ||\n (oldNode == sel.focusNode && oldOff == sel.focusOffset)\n // Restore the previous selection\n sel.removeAllRanges()\n sel.addRange(oldRange)\n if (oldBidiLevel != null) sel.caretBidiLevel = oldBidiLevel\n return result\n })\n}\n\nlet cachedState = null, cachedDir = null, cachedResult = false\nexport function endOfTextblock(view, state, dir) {\n if (cachedState == state && cachedDir == dir) return cachedResult\n cachedState = state; cachedDir = dir\n return cachedResult = dir == \"up\" || dir == \"down\"\n ? endOfTextblockVertical(view, state, dir)\n : endOfTextblockHorizontal(view, state, dir)\n}\n","import {DOMSerializer, Fragment, Mark} from \"prosemirror-model\"\nimport {TextSelection} from \"prosemirror-state\"\n\nimport {domIndex, isEquivalentPosition, nodeSize} from \"./dom\"\nimport browser from \"./browser\"\n\n// NodeView:: interface\n//\n// By default, document nodes are rendered using the result of the\n// [`toDOM`](#model.NodeSpec.toDOM) method of their spec, and managed\n// entirely by the editor. For some use cases, such as embedded\n// node-specific editing interfaces, you want more control over\n// the behavior of a node's in-editor representation, and need to\n// [define](#view.EditorProps.nodeViews) a custom node view.\n//\n// Objects returned as node views must conform to this interface.\n//\n// dom:: ?dom.Node\n// The outer DOM node that represents the document node. When not\n// given, the default strategy is used to create a DOM node.\n//\n// contentDOM:: ?dom.Node\n// The DOM node that should hold the node's content. Only meaningful\n// if the node view also defines a `dom` property and if its node\n// type is not a leaf node type. When this is present, ProseMirror\n// will take care of rendering the node's children into it. When it\n// is not present, the node view itself is responsible for rendering\n// (or deciding not to render) its child nodes.\n//\n// update:: ?(node: Node, decorations: [Decoration]) → bool\n// When given, this will be called when the view is updating itself.\n// It will be given a node (possibly of a different type), and an\n// array of active decorations (which are automatically drawn, and\n// the node view may ignore if it isn't interested in them), and\n// should return true if it was able to update to that node, and\n// false otherwise. If the node view has a `contentDOM` property (or\n// no `dom` property), updating its child nodes will be handled by\n// ProseMirror.\n//\n// selectNode:: ?()\n// Can be used to override the way the node's selected status (as a\n// node selection) is displayed.\n//\n// deselectNode:: ?()\n// When defining a `selectNode` method, you should also provide a\n// `deselectNode` method to remove the effect again.\n//\n// setSelection:: ?(anchor: number, head: number, root: dom.Document)\n// This will be called to handle setting the selection inside the\n// node. The `anchor` and `head` positions are relative to the start\n// of the node. By default, a DOM selection will be created between\n// the DOM positions corresponding to those positions, but if you\n// override it you can do something else.\n//\n// stopEvent:: ?(event: dom.Event) → bool\n// Can be used to prevent the editor view from trying to handle some\n// or all DOM events that bubble up from the node view. Events for\n// which this returns true are not handled by the editor.\n//\n// ignoreMutation:: ?(dom.MutationRecord) → bool\n// Called when a DOM\n// [mutation](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver)\n// or a selection change happens within the view. When the change is\n// a selection change, the record will have a `type` property of\n// `\"selection\"` (which doesn't occur for native mutation records).\n// Return false if the editor should re-read the selection or\n// re-parse the range around the mutation, true if it can safely be\n// ignored.\n//\n// destroy:: ?()\n// Called when the node view is removed from the editor or the whole\n// editor is destroyed.\n\n// View descriptions are data structures that describe the DOM that is\n// used to represent the editor's content. They are used for:\n//\n// - Incremental redrawing when the document changes\n//\n// - Figuring out what part of the document a given DOM position\n// corresponds to\n//\n// - Wiring in custom implementations of the editing interface for a\n// given node\n//\n// They form a doubly-linked mutable tree, starting at `view.docView`.\n\nconst NOT_DIRTY = 0, CHILD_DIRTY = 1, CONTENT_DIRTY = 2, NODE_DIRTY = 3\n\n// Superclass for the various kinds of descriptions. Defines their\n// basic structure and shared methods.\nclass ViewDesc {\n // : (?ViewDesc, [ViewDesc], dom.Node, ?dom.Node)\n constructor(parent, children, dom, contentDOM) {\n this.parent = parent\n this.children = children\n this.dom = dom\n // An expando property on the DOM node provides a link back to its\n // description.\n dom.pmViewDesc = this\n // This is the node that holds the child views. It may be null for\n // descs that don't have children.\n this.contentDOM = contentDOM\n this.dirty = NOT_DIRTY\n }\n\n // Used to check whether a given description corresponds to a\n // widget/mark/node.\n matchesWidget() { return false }\n matchesMark() { return false }\n matchesNode() { return false }\n matchesHack() { return false }\n\n get beforePosition() { return false }\n\n // : () → ?ParseRule\n // When parsing in-editor content (in domchange.js), we allow\n // descriptions to determine the parse rules that should be used to\n // parse them.\n parseRule() { return null }\n\n // : (dom.Event) → bool\n // Used by the editor's event handler to ignore events that come\n // from certain descs.\n stopEvent() { return false }\n\n // The size of the content represented by this desc.\n get size() {\n let size = 0\n for (let i = 0; i < this.children.length; i++) size += this.children[i].size\n return size\n }\n\n // For block nodes, this represents the space taken up by their\n // start/end tokens.\n get border() { return 0 }\n\n destroy() {\n this.parent = null\n if (this.dom.pmViewDesc == this) this.dom.pmViewDesc = null\n for (let i = 0; i < this.children.length; i++)\n this.children[i].destroy()\n }\n\n posBeforeChild(child) {\n for (let i = 0, pos = this.posAtStart; i < this.children.length; i++) {\n let cur = this.children[i]\n if (cur == child) return pos\n pos += cur.size\n }\n }\n\n get posBefore() {\n return this.parent.posBeforeChild(this)\n }\n\n get posAtStart() {\n return this.parent ? this.parent.posBeforeChild(this) + this.border : 0\n }\n\n get posAfter() {\n return this.posBefore + this.size\n }\n\n get posAtEnd() {\n return this.posAtStart + this.size - 2 * this.border\n }\n\n // : (dom.Node, number, ?number) → number\n localPosFromDOM(dom, offset, bias) {\n // If the DOM position is in the content, use the child desc after\n // it to figure out a position.\n if (this.contentDOM && this.contentDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode)) {\n if (bias < 0) {\n let domBefore, desc\n if (dom == this.contentDOM) {\n domBefore = dom.childNodes[offset - 1]\n } else {\n while (dom.parentNode != this.contentDOM) dom = dom.parentNode\n domBefore = dom.previousSibling\n }\n while (domBefore && !((desc = domBefore.pmViewDesc) && desc.parent == this)) domBefore = domBefore.previousSibling\n return domBefore ? this.posBeforeChild(desc) + desc.size : this.posAtStart\n } else {\n let domAfter, desc\n if (dom == this.contentDOM) {\n domAfter = dom.childNodes[offset]\n } else {\n while (dom.parentNode != this.contentDOM) dom = dom.parentNode\n domAfter = dom.nextSibling\n }\n while (domAfter && !((desc = domAfter.pmViewDesc) && desc.parent == this)) domAfter = domAfter.nextSibling\n return domAfter ? this.posBeforeChild(desc) : this.posAtEnd\n }\n }\n // Otherwise, use various heuristics, falling back on the bias\n // parameter, to determine whether to return the position at the\n // start or at the end of this view desc.\n let atEnd\n if (this.contentDOM && this.contentDOM != this.dom && this.dom.contains(this.contentDOM)) {\n atEnd = dom.compareDocumentPosition(this.contentDOM) & 2\n } else if (this.dom.firstChild) {\n if (offset == 0) for (let search = dom;; search = search.parentNode) {\n if (search == this.dom) { atEnd = false; break }\n if (search.parentNode.firstChild != search) break\n }\n if (atEnd == null && offset == dom.childNodes.length) for (let search = dom;; search = search.parentNode) {\n if (search == this.dom) { atEnd = true; break }\n if (search.parentNode.lastChild != search) break\n }\n }\n return (atEnd == null ? bias > 0 : atEnd) ? this.posAtEnd : this.posAtStart\n }\n\n // Scan up the dom finding the first desc that is a descendant of\n // this one.\n nearestDesc(dom, onlyNodes) {\n for (let first = true, cur = dom; cur; cur = cur.parentNode) {\n let desc = this.getDesc(cur)\n if (desc && (!onlyNodes || desc.node)) {\n // If dom is outside of this desc's nodeDOM, don't count it.\n if (first && desc.nodeDOM && !(desc.nodeDOM.nodeType == 1 ? desc.nodeDOM.contains(dom) : desc.nodeDOM == dom)) first = false\n else return desc\n }\n }\n }\n\n getDesc(dom) {\n let desc = dom.pmViewDesc\n for (let cur = desc; cur; cur = cur.parent) if (cur == this) return desc\n }\n\n posFromDOM(dom, offset, bias) {\n for (let scan = dom;; scan = scan.parentNode) {\n let desc = this.getDesc(scan)\n if (desc) return desc.localPosFromDOM(dom, offset, bias)\n }\n }\n\n // : (number) → ?NodeViewDesc\n // Find the desc for the node after the given pos, if any. (When a\n // parent node overrode rendering, there might not be one.)\n descAt(pos) {\n for (let i = 0, offset = 0; i < this.children.length; i++) {\n let child = this.children[i], end = offset + child.size\n if (offset == pos && end != offset) {\n while (!child.border && child.children.length) child = child.children[0]\n return child\n }\n if (pos < end) return child.descAt(pos - offset - child.border)\n offset = end\n }\n }\n\n // : (number) → {node: dom.Node, offset: number}\n domFromPos(pos) {\n if (!this.contentDOM) return {node: this.dom, offset: 0}\n for (let offset = 0, i = 0;; i++) {\n if (offset == pos) {\n while (i < this.children.length && (this.children[i].beforePosition || this.children[i].dom.parentNode != this.contentDOM)) i++\n return {node: this.contentDOM,\n offset: i == this.children.length ? this.contentDOM.childNodes.length : domIndex(this.children[i].dom)}\n }\n if (i == this.children.length) throw new Error(\"Invalid position \" + pos)\n let child = this.children[i], end = offset + child.size\n if (pos < end) return child.domFromPos(pos - offset - child.border)\n offset = end\n }\n }\n\n // Used to find a DOM range in a single parent for a given changed\n // range.\n parseRange(from, to, base = 0) {\n if (this.children.length == 0)\n return {node: this.contentDOM, from, to, fromOffset: 0, toOffset: this.contentDOM.childNodes.length}\n\n let fromOffset = -1, toOffset = -1\n for (let offset = base, i = 0;; i++) {\n let child = this.children[i], end = offset + child.size\n if (fromOffset == -1 && from <= end) {\n let childBase = offset + child.border\n // FIXME maybe descend mark views to parse a narrower range?\n if (from >= childBase && to <= end - child.border && child.node &&\n child.contentDOM && this.contentDOM.contains(child.contentDOM))\n return child.parseRange(from, to, childBase)\n\n from = offset\n for (let j = i; j > 0; j--) {\n let prev = this.children[j - 1]\n if (prev.size && prev.dom.parentNode == this.contentDOM && !prev.emptyChildAt(1)) {\n fromOffset = domIndex(prev.dom) + 1\n break\n }\n from -= prev.size\n }\n if (fromOffset == -1) fromOffset = 0\n }\n if (fromOffset > -1 && to <= end) {\n to = end\n for (let j = i + 1; j < this.children.length; j++) {\n let next = this.children[j]\n if (next.size && next.dom.parentNode == this.contentDOM && !next.emptyChildAt(-1)) {\n toOffset = domIndex(next.dom)\n break\n }\n to += next.size\n }\n if (toOffset == -1) toOffset = this.contentDOM.childNodes.length\n break\n }\n offset = end\n }\n return {node: this.contentDOM, from, to, fromOffset, toOffset}\n }\n\n emptyChildAt(side) {\n if (this.border || !this.contentDOM || !this.children.length) return false\n let child = this.children[side < 0 ? 0 : this.children.length - 1]\n return child.size == 0 || child.emptyChildAt(side)\n }\n\n // : (number) → dom.Node\n domAfterPos(pos) {\n let {node, offset} = this.domFromPos(pos)\n if (node.nodeType != 1 || offset == node.childNodes.length)\n throw new RangeError(\"No node after pos \" + pos)\n return node.childNodes[offset]\n }\n\n // : (number, number, dom.Document)\n // View descs are responsible for setting any selection that falls\n // entirely inside of them, so that custom implementations can do\n // custom things with the selection. Note that this falls apart when\n // a selection starts in such a node and ends in another, in which\n // case we just use whatever domFromPos produces as a best effort.\n setSelection(anchor, head, root, force) {\n // If the selection falls entirely in a child, give it to that child\n let from = Math.min(anchor, head), to = Math.max(anchor, head)\n for (let i = 0, offset = 0; i < this.children.length; i++) {\n let child = this.children[i], end = offset + child.size\n if (from > offset && to < end)\n return child.setSelection(anchor - offset - child.border, head - offset - child.border, root, force)\n offset = end\n }\n\n let anchorDOM = this.domFromPos(anchor), headDOM = this.domFromPos(head)\n let domSel = root.getSelection(), range = document.createRange()\n if (!force &&\n isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset) &&\n isEquivalentPosition(headDOM.node, headDOM.offset, domSel.focusNode, domSel.focusOffset))\n return\n\n // Selection.extend can be used to create an 'inverted' selection\n // (one where the focus is before the anchor), but not all\n // browsers support it yet.\n if (domSel.extend) {\n range.setEnd(anchorDOM.node, anchorDOM.offset)\n range.collapse(false)\n } else {\n if (anchor > head) { let tmp = anchorDOM; anchorDOM = headDOM; headDOM = tmp }\n range.setEnd(headDOM.node, headDOM.offset)\n range.setStart(anchorDOM.node, anchorDOM.offset)\n }\n domSel.removeAllRanges()\n domSel.addRange(range)\n if (domSel.extend)\n domSel.extend(headDOM.node, headDOM.offset)\n }\n\n // : (dom.MutationRecord) → bool\n ignoreMutation(_mutation) {\n return !this.contentDOM\n }\n\n get contentLost() {\n return this.contentDOM && this.contentDOM != this.dom && !this.dom.contains(this.contentDOM)\n }\n\n // Remove a subtree of the element tree that has been touched\n // by a DOM change, so that the next update will redraw it.\n markDirty(from, to) {\n for (let offset = 0, i = 0; i < this.children.length; i++) {\n let child = this.children[i], end = offset + child.size\n if (offset == end ? from <= end && to >= offset : from < end && to > offset) {\n let startInside = offset + child.border, endInside = end - child.border\n if (from >= startInside && to <= endInside) {\n this.dirty = from == offset || to == end ? CONTENT_DIRTY : CHILD_DIRTY\n if (from == startInside && to == endInside &&\n (child.contentLost || child.dom.parentNode != this.contentDOM)) child.dirty = NODE_DIRTY\n else child.markDirty(from - startInside, to - startInside)\n return\n } else {\n child.dirty = NODE_DIRTY\n }\n }\n offset = end\n }\n this.dirty = CONTENT_DIRTY\n }\n\n markParentsDirty() {\n let level = 1\n for (let node = this.parent; node; node = node.parent) {\n let dirty = level == 1 ? CONTENT_DIRTY : CHILD_DIRTY\n if (node.dirty < dirty) node.dirty = dirty\n }\n }\n}\n\n// Reused array to avoid allocating fresh arrays for things that will\n// stay empty anyway.\nconst nothing = []\n\n// A widget desc represents a widget decoration, which is a DOM node\n// drawn between the document nodes.\nclass WidgetViewDesc extends ViewDesc {\n // : (ViewDesc, Decoration)\n constructor(parent, widget, view, pos) {\n let self, dom = widget.type.toDOM\n if (typeof dom == \"function\") dom = dom(view, () => {\n if (!self) return pos\n if (self.parent) return self.parent.posBeforeChild(self)\n })\n if (!widget.type.spec.raw) {\n if (dom.nodeType != 1) {\n let wrap = document.createElement(\"span\")\n wrap.appendChild(dom)\n dom = wrap\n }\n dom.contentEditable = false\n dom.classList.add(\"ProseMirror-widget\")\n }\n super(parent, nothing, dom, null)\n this.widget = widget\n self = this\n }\n\n get beforePosition() {\n return this.widget.type.side < 0\n }\n\n matchesWidget(widget) {\n return this.dirty == NOT_DIRTY && widget.type.eq(this.widget.type)\n }\n\n parseRule() { return {ignore: true} }\n\n stopEvent(event) {\n let stop = this.widget.spec.stopEvent\n return stop ? stop(event) : false\n }\n}\n\nclass CompositionViewDesc extends ViewDesc {\n constructor(parent, dom, textDOM, text) {\n super(parent, nothing, dom, null)\n this.textDOM = textDOM\n this.text = text\n }\n\n get size() { return this.text.length }\n\n localPosFromDOM(dom, offset) {\n if (dom != this.textDOM) return this.posAtStart + (offset ? this.size : 0)\n return this.posAtStart + offset\n }\n\n domFromPos(pos) {\n return {node: this.textDOM, offset: pos}\n }\n\n ignoreMutation(mut) {\n return mut.type === 'characterData' && mut.target.nodeValue == mut.oldValue\n }\n}\n\n// A mark desc represents a mark. May have multiple children,\n// depending on how the mark is split. Note that marks are drawn using\n// a fixed nesting order, for simplicity and predictability, so in\n// some cases they will be split more often than would appear\n// necessary.\nclass MarkViewDesc extends ViewDesc {\n // : (ViewDesc, Mark, dom.Node)\n constructor(parent, mark, dom, contentDOM) {\n super(parent, [], dom, contentDOM)\n this.mark = mark\n }\n\n static create(parent, mark, inline, view) {\n let custom = view.nodeViews[mark.type.name]\n let spec = custom && custom(mark, view, inline)\n if (!spec || !spec.dom)\n spec = DOMSerializer.renderSpec(document, mark.type.spec.toDOM(mark, inline))\n return new MarkViewDesc(parent, mark, spec.dom, spec.contentDOM || spec.dom)\n }\n\n parseRule() { return {mark: this.mark.type.name, attrs: this.mark.attrs, contentElement: this.contentDOM} }\n\n matchesMark(mark) { return this.dirty != NODE_DIRTY && this.mark.eq(mark) }\n\n markDirty(from, to) {\n super.markDirty(from, to)\n // Move dirty info to nearest node view\n if (this.dirty != NOT_DIRTY) {\n let parent = this.parent\n while (!parent.node) parent = parent.parent\n if (parent.dirty < this.dirty) parent.dirty = this.dirty\n this.dirty = NOT_DIRTY\n }\n }\n\n slice(from, to, view) {\n let copy = MarkViewDesc.create(this.parent, this.mark, true, view)\n let nodes = this.children, size = this.size\n if (to < size) nodes = replaceNodes(nodes, to, size, view)\n if (from > 0) nodes = replaceNodes(nodes, 0, from, view)\n for (let i = 0; i < nodes.length; i++) nodes[i].parent = copy\n copy.children = nodes\n return copy\n }\n}\n\n// Node view descs are the main, most common type of view desc, and\n// correspond to an actual node in the document. Unlike mark descs,\n// they populate their child array themselves.\nclass NodeViewDesc extends ViewDesc {\n // : (?ViewDesc, Node, [Decoration], DecorationSet, dom.Node, ?dom.Node, EditorView)\n constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos) {\n super(parent, node.isLeaf ? nothing : [], dom, contentDOM)\n this.nodeDOM = nodeDOM\n this.node = node\n this.outerDeco = outerDeco\n this.innerDeco = innerDeco\n if (contentDOM) this.updateChildren(view, pos)\n }\n\n // By default, a node is rendered using the `toDOM` method from the\n // node type spec. But client code can use the `nodeViews` spec to\n // supply a custom node view, which can influence various aspects of\n // the way the node works.\n //\n // (Using subclassing for this was intentionally decided against,\n // since it'd require exposing a whole slew of finnicky\n // implementation details to the user code that they probably will\n // never need.)\n static create(parent, node, outerDeco, innerDeco, view, pos) {\n let custom = view.nodeViews[node.type.name], descObj\n let spec = custom && custom(node, view, () => {\n // (This is a function that allows the custom view to find its\n // own position)\n if (!descObj) return pos\n if (descObj.parent) return descObj.parent.posBeforeChild(descObj)\n }, outerDeco)\n\n let dom = spec && spec.dom, contentDOM = spec && spec.contentDOM\n if (node.isText) {\n if (!dom) dom = document.createTextNode(node.text)\n else if (dom.nodeType != 3) throw new RangeError(\"Text must be rendered as a DOM text node\")\n } else if (!dom) {\n ;({dom, contentDOM} = DOMSerializer.renderSpec(document, node.type.spec.toDOM(node)))\n }\n if (!contentDOM && !node.isText && dom.nodeName != \"BR\") { // Chrome gets confused by
    \n if (!dom.hasAttribute(\"contenteditable\")) dom.contentEditable = false\n if (node.type.spec.draggable) dom.draggable = true\n }\n\n let nodeDOM = dom\n dom = applyOuterDeco(dom, outerDeco, node)\n\n if (spec)\n return descObj = new CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM,\n spec, view, pos + 1)\n else if (node.isText)\n return new TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM, view)\n else\n return new NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos + 1)\n }\n\n parseRule() {\n // Experimental kludge to allow opt-in re-parsing of nodes\n if (this.node.type.spec.reparseInView) return null\n // FIXME the assumption that this can always return the current\n // attrs means that if the user somehow manages to change the\n // attrs in the dom, that won't be picked up. Not entirely sure\n // whether this is a problem\n let rule = {node: this.node.type.name, attrs: this.node.attrs}\n if (this.node.type.spec.code) rule.preserveWhitespace = \"full\"\n if (this.contentDOM && !this.contentLost) rule.contentElement = this.contentDOM\n else rule.getContent = () => this.contentDOM ? Fragment.empty : this.node.content\n return rule\n }\n\n matchesNode(node, outerDeco, innerDeco) {\n return this.dirty == NOT_DIRTY && node.eq(this.node) &&\n sameOuterDeco(outerDeco, this.outerDeco) && innerDeco.eq(this.innerDeco)\n }\n\n get size() { return this.node.nodeSize }\n\n get border() { return this.node.isLeaf ? 0 : 1 }\n\n // Syncs `this.children` to match `this.node.content` and the local\n // decorations, possibly introducing nesting for marks. Then, in a\n // separate step, syncs the DOM inside `this.contentDOM` to\n // `this.children`.\n updateChildren(view, pos) {\n let inline = this.node.inlineContent, off = pos\n let composition = inline && view.composing && this.localCompositionNode(view, pos)\n let updater = new ViewTreeUpdater(this, composition && composition.node)\n iterDeco(this.node, this.innerDeco, (widget, i) => {\n if (widget.spec.marks)\n updater.syncToMarks(widget.spec.marks, inline, view)\n else if (widget.type.side >= 0)\n updater.syncToMarks(i == this.node.childCount ? Mark.none : this.node.child(i).marks, inline, view)\n // If the next node is a desc matching this widget, reuse it,\n // otherwise insert the widget as a new view desc.\n updater.placeWidget(widget, view, off)\n }, (child, outerDeco, innerDeco, i) => {\n // Make sure the wrapping mark descs match the node's marks.\n updater.syncToMarks(child.marks, inline, view)\n // Either find an existing desc that exactly matches this node,\n // and drop the descs before it.\n updater.findNodeMatch(child, outerDeco, innerDeco, i) ||\n // Or try updating the next desc to reflect this node.\n updater.updateNextNode(child, outerDeco, innerDeco, view, i) ||\n // Or just add it as a new desc.\n updater.addNode(child, outerDeco, innerDeco, view, off)\n off += child.nodeSize\n })\n // Drop all remaining descs after the current position.\n updater.syncToMarks(nothing, inline, view)\n if (this.node.isTextblock) updater.addTextblockHacks()\n updater.destroyRest()\n\n // Sync the DOM if anything changed\n if (updater.changed || this.dirty == CONTENT_DIRTY) {\n // May have to protect focused DOM from being changed if a composition is active\n if (composition) this.protectLocalComposition(view, composition)\n this.renderChildren()\n }\n }\n\n renderChildren() {\n renderDescs(this.contentDOM, this.children, NodeViewDesc.is)\n if (browser.ios) iosHacks(this.dom)\n }\n\n localCompositionNode(view, pos) {\n // Only do something if both the selection and a focused text node\n // are inside of this node, and the node isn't already part of a\n // view that's a child of this view\n let {from, to} = view.state.selection\n if (!(view.state.selection instanceof TextSelection) || from < pos || to > pos + this.node.content.size) return\n let sel = view.root.getSelection()\n let textNode = nearbyTextNode(sel.focusNode, sel.focusOffset)\n if (!textNode || !this.dom.contains(textNode.parentNode)) return\n\n // Find the text in the focused node in the node, stop if it's not\n // there (may have been modified through other means, in which\n // case it should overwritten)\n let text = textNode.nodeValue\n let textPos = findTextInFragment(this.node.content, text, from - pos, to - pos)\n\n return textPos < 0 ? null : {node: textNode, pos: textPos, text}\n }\n\n protectLocalComposition(view, {node, pos, text}) {\n // The node is already part of a local view desc, leave it there\n if (this.getDesc(node)) return\n\n // Create a composition view for the orphaned nodes\n let topNode = node\n for (;; topNode = topNode.parentNode) {\n if (topNode.parentNode == this.contentDOM) break\n while (topNode.previousSibling) topNode.parentNode.removeChild(topNode.previousSibling)\n while (topNode.nextSibling) topNode.parentNode.removeChild(topNode.nextSibling)\n if (topNode.pmViewDesc) topNode.pmViewDesc = null\n }\n let desc = new CompositionViewDesc(this, topNode, node, text)\n view.compositionNodes.push(desc)\n\n // Patch up this.children to contain the composition view\n this.children = replaceNodes(this.children, pos, pos + text.length, view, desc)\n }\n\n // : (Node, [Decoration], DecorationSet, EditorView) → bool\n // If this desc be updated to match the given node decoration,\n // do so and return true.\n update(node, outerDeco, innerDeco, view) {\n if (this.dirty == NODE_DIRTY ||\n !node.sameMarkup(this.node)) return false\n this.updateInner(node, outerDeco, innerDeco, view)\n return true\n }\n\n updateInner(node, outerDeco, innerDeco, view) {\n this.updateOuterDeco(outerDeco)\n this.node = node\n this.innerDeco = innerDeco\n if (this.contentDOM) this.updateChildren(view, this.posAtStart)\n this.dirty = NOT_DIRTY\n }\n\n updateOuterDeco(outerDeco) {\n if (sameOuterDeco(outerDeco, this.outerDeco)) return\n let needsWrap = this.nodeDOM.nodeType != 1\n let oldDOM = this.dom\n this.dom = patchOuterDeco(this.dom, this.nodeDOM,\n computeOuterDeco(this.outerDeco, this.node, needsWrap),\n computeOuterDeco(outerDeco, this.node, needsWrap))\n if (this.dom != oldDOM) {\n oldDOM.pmViewDesc = null\n this.dom.pmViewDesc = this\n }\n this.outerDeco = outerDeco\n }\n\n // Mark this node as being the selected node.\n selectNode() {\n this.nodeDOM.classList.add(\"ProseMirror-selectednode\")\n if (this.contentDOM || !this.node.type.spec.draggable) this.dom.draggable = true\n }\n\n // Remove selected node marking from this node.\n deselectNode() {\n this.nodeDOM.classList.remove(\"ProseMirror-selectednode\")\n if (this.contentDOM || !this.node.type.spec.draggable) this.dom.draggable = false\n }\n}\n\n// Create a view desc for the top-level document node, to be exported\n// and used by the view class.\nexport function docViewDesc(doc, outerDeco, innerDeco, dom, view) {\n applyOuterDeco(dom, outerDeco, doc)\n return new NodeViewDesc(null, doc, outerDeco, innerDeco, dom, dom, dom, view, 0)\n}\n\nclass TextViewDesc extends NodeViewDesc {\n constructor(parent, node, outerDeco, innerDeco, dom, nodeDOM, view) {\n super(parent, node, outerDeco, innerDeco, dom, null, nodeDOM, view)\n }\n\n parseRule() {\n return {skip: this.nodeDOM.parentNode || true}\n }\n\n update(node, outerDeco) {\n if (this.dirty == NODE_DIRTY || (this.dirty != NOT_DIRTY && !this.inParent()) ||\n !node.sameMarkup(this.node)) return false\n this.updateOuterDeco(outerDeco)\n if ((this.dirty != NOT_DIRTY || node.text != this.node.text) && node.text != this.nodeDOM.nodeValue)\n this.nodeDOM.nodeValue = node.text\n this.node = node\n this.dirty = NOT_DIRTY\n return true\n }\n\n inParent() {\n let parentDOM = this.parent.contentDOM\n for (let n = this.nodeDOM; n; n = n.parentNode) if (n == parentDOM) return true\n return false\n }\n\n domFromPos(pos) {\n return {node: this.nodeDOM, offset: pos}\n }\n\n localPosFromDOM(dom, offset, bias) {\n if (dom == this.nodeDOM) return this.posAtStart + Math.min(offset, this.node.text.length)\n return super.localPosFromDOM(dom, offset, bias)\n }\n\n ignoreMutation(mutation) {\n return mutation.type != \"characterData\" && mutation.type != \"selection\"\n }\n\n slice(from, to, view) {\n let node = this.node.cut(from, to), dom = document.createTextNode(node.text)\n return new TextViewDesc(this.parent, node, this.outerDeco, this.innerDeco, dom, dom, view)\n }\n}\n\n// A dummy desc used to tag trailing BR or span nodes created to work\n// around contentEditable terribleness.\nclass BRHackViewDesc extends ViewDesc {\n parseRule() { return {ignore: true} }\n matchesHack() { return this.dirty == NOT_DIRTY }\n}\n\n// A separate subclass is used for customized node views, so that the\n// extra checks only have to be made for nodes that are actually\n// customized.\nclass CustomNodeViewDesc extends NodeViewDesc {\n // : (?ViewDesc, Node, [Decoration], DecorationSet, dom.Node, ?dom.Node, NodeView, EditorView)\n constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, spec, view, pos) {\n super(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos)\n this.spec = spec\n }\n\n // A custom `update` method gets to decide whether the update goes\n // through. If it does, and there's a `contentDOM` node, our logic\n // updates the children.\n update(node, outerDeco, innerDeco, view) {\n if (this.dirty == NODE_DIRTY) return false\n if (this.spec.update) {\n let result = this.spec.update(node, outerDeco)\n if (result) this.updateInner(node, outerDeco, innerDeco, view)\n return result\n } else if (!this.contentDOM && !node.isLeaf) {\n return false\n } else {\n return super.update(node, outerDeco, innerDeco, view)\n }\n }\n\n selectNode() {\n this.spec.selectNode ? this.spec.selectNode() : super.selectNode()\n }\n\n deselectNode() {\n this.spec.deselectNode ? this.spec.deselectNode() : super.deselectNode()\n }\n\n setSelection(anchor, head, root, force) {\n this.spec.setSelection ? this.spec.setSelection(anchor, head, root)\n : super.setSelection(anchor, head, root, force)\n }\n\n destroy() {\n if (this.spec.destroy) this.spec.destroy()\n super.destroy()\n }\n\n stopEvent(event) {\n return this.spec.stopEvent ? this.spec.stopEvent(event) : false\n }\n\n ignoreMutation(mutation) {\n return this.spec.ignoreMutation ? this.spec.ignoreMutation(mutation) : super.ignoreMutation(mutation)\n }\n}\n\n// : (dom.Node, [ViewDesc])\n// Sync the content of the given DOM node with the nodes associated\n// with the given array of view descs, recursing into mark descs\n// because this should sync the subtree for a whole node at a time.\nfunction renderDescs(parentDOM, descs) {\n let dom = parentDOM.firstChild\n for (let i = 0; i < descs.length; i++) {\n let desc = descs[i], childDOM = desc.dom\n if (childDOM.parentNode == parentDOM) {\n while (childDOM != dom) dom = rm(dom)\n dom = dom.nextSibling\n } else {\n parentDOM.insertBefore(childDOM, dom)\n }\n if (desc instanceof MarkViewDesc) {\n let pos = dom ? dom.previousSibling : parentDOM.lastChild\n renderDescs(desc.contentDOM, desc.children)\n dom = pos ? pos.nextSibling : parentDOM.firstChild\n }\n }\n while (dom) dom = rm(dom)\n}\n\nfunction OuterDecoLevel(nodeName) {\n if (nodeName) this.nodeName = nodeName\n}\nOuterDecoLevel.prototype = Object.create(null)\n\nconst noDeco = [new OuterDecoLevel]\n\nfunction computeOuterDeco(outerDeco, node, needsWrap) {\n if (outerDeco.length == 0) return noDeco\n\n let top = needsWrap ? noDeco[0] : new OuterDecoLevel, result = [top]\n\n for (let i = 0; i < outerDeco.length; i++) {\n let attrs = outerDeco[i].type.attrs, cur = top\n if (!attrs) continue\n if (attrs.nodeName)\n result.push(cur = new OuterDecoLevel(attrs.nodeName))\n\n for (let name in attrs) {\n let val = attrs[name]\n if (val == null) continue\n if (needsWrap && result.length == 1)\n result.push(cur = top = new OuterDecoLevel(node.isInline ? \"span\" : \"div\"))\n if (name == \"class\") cur.class = (cur.class ? cur.class + \" \" : \"\") + val\n else if (name == \"style\") cur.style = (cur.style ? cur.style + \";\" : \"\") + val\n else if (name != \"nodeName\") cur[name] = val\n }\n }\n\n return result\n}\n\nfunction patchOuterDeco(outerDOM, nodeDOM, prevComputed, curComputed) {\n // Shortcut for trivial case\n if (prevComputed == noDeco && curComputed == noDeco) return nodeDOM\n\n let curDOM = nodeDOM\n for (let i = 0; i < curComputed.length; i++) {\n let deco = curComputed[i], prev = prevComputed[i]\n if (i) {\n let parent\n if (prev && prev.nodeName == deco.nodeName && curDOM != outerDOM &&\n (parent = curDOM.parentNode) && parent.tagName.toLowerCase() == deco.nodeName) {\n curDOM = parent\n } else {\n parent = document.createElement(deco.nodeName)\n parent.appendChild(curDOM)\n prev = noDeco[0]\n curDOM = parent\n }\n }\n patchAttributes(curDOM, prev || noDeco[0], deco)\n }\n return curDOM\n}\n\nfunction patchAttributes(dom, prev, cur) {\n for (let name in prev)\n if (name != \"class\" && name != \"style\" && name != \"nodeName\" && !(name in cur))\n dom.removeAttribute(name)\n for (let name in cur)\n if (name != \"class\" && name != \"style\" && name != \"nodeName\" && cur[name] != prev[name])\n dom.setAttribute(name, cur[name])\n if (prev.class != cur.class) {\n let prevList = prev.class ? prev.class.split(\" \") : nothing\n let curList = cur.class ? cur.class.split(\" \") : nothing\n for (let i = 0; i < prevList.length; i++) if (curList.indexOf(prevList[i]) == -1)\n dom.classList.remove(prevList[i])\n for (let i = 0; i < curList.length; i++) if (prevList.indexOf(curList[i]) == -1)\n dom.classList.add(curList[i])\n }\n if (prev.style != cur.style) {\n if (prev.style) {\n let prop = /\\s*([\\w\\-\\xa1-\\uffff]+)\\s*:(?:\"(?:\\\\.|[^\"])*\"|'(?:\\\\.|[^'])*'|\\(.*?\\)|[^;])*/g, m\n while (m = prop.exec(prev.style))\n dom.style.removeProperty(m[1])\n }\n if (cur.style)\n dom.style.cssText += cur.style\n }\n}\n\nfunction applyOuterDeco(dom, deco, node) {\n return patchOuterDeco(dom, dom, noDeco, computeOuterDeco(deco, node, dom.nodeType != 1))\n}\n\n// : ([Decoration], [Decoration]) → bool\nfunction sameOuterDeco(a, b) {\n if (a.length != b.length) return false\n for (let i = 0; i < a.length; i++) if (!a[i].type.eq(b[i].type)) return false\n return true\n}\n\n// Remove a DOM node and return its next sibling.\nfunction rm(dom) {\n let next = dom.nextSibling\n dom.parentNode.removeChild(dom)\n return next\n}\n\n// Helper class for incrementally updating a tree of mark descs and\n// the widget and node descs inside of them.\nclass ViewTreeUpdater {\n // : (NodeViewDesc)\n constructor(top, lockedNode) {\n this.top = top\n this.lock = lockedNode\n // Index into `this.top`'s child array, represents the current\n // update position.\n this.index = 0\n // When entering a mark, the current top and index are pushed\n // onto this.\n this.stack = []\n // Tracks whether anything was changed\n this.changed = false\n\n let pre = preMatch(top.node.content, top.children)\n this.preMatched = pre.nodes\n this.preMatchOffset = pre.offset\n }\n\n getPreMatch(index) {\n return index >= this.preMatchOffset ? this.preMatched[index - this.preMatchOffset] : null\n }\n\n // Destroy and remove the children between the given indices in\n // `this.top`.\n destroyBetween(start, end) {\n if (start == end) return\n for (let i = start; i < end; i++) this.top.children[i].destroy()\n this.top.children.splice(start, end - start)\n this.changed = true\n }\n\n // Destroy all remaining children in `this.top`.\n destroyRest() {\n this.destroyBetween(this.index, this.top.children.length)\n }\n\n // : ([Mark], EditorView)\n // Sync the current stack of mark descs with the given array of\n // marks, reusing existing mark descs when possible.\n syncToMarks(marks, inline, view) {\n let keep = 0, depth = this.stack.length >> 1\n let maxKeep = Math.min(depth, marks.length)\n while (keep < maxKeep &&\n (keep == depth - 1 ? this.top : this.stack[(keep + 1) << 1]).matchesMark(marks[keep]) && marks[keep].type.spec.spanning !== false)\n keep++\n\n while (keep < depth) {\n this.destroyRest()\n this.top.dirty = NOT_DIRTY\n this.index = this.stack.pop()\n this.top = this.stack.pop()\n depth--\n }\n while (depth < marks.length) {\n this.stack.push(this.top, this.index + 1)\n let found = -1\n for (let i = this.index; i < Math.min(this.index + 3, this.top.children.length); i++) {\n if (this.top.children[i].matchesMark(marks[depth])) { found = i; break }\n }\n if (found > -1) {\n if (found > this.index) {\n this.changed = true\n this.destroyBetween(this.index, found)\n }\n this.top = this.top.children[this.index]\n } else {\n let markDesc = MarkViewDesc.create(this.top, marks[depth], inline, view)\n this.top.children.splice(this.index, 0, markDesc)\n this.top = markDesc\n this.changed = true\n }\n this.index = 0\n depth++\n }\n }\n\n // : (Node, [Decoration], DecorationSet) → bool\n // Try to find a node desc matching the given data. Skip over it and\n // return true when successful.\n findNodeMatch(node, outerDeco, innerDeco, index) {\n let found = -1, preMatch = index < 0 ? undefined : this.getPreMatch(index), children = this.top.children\n if (preMatch && preMatch.matchesNode(node, outerDeco, innerDeco)) {\n found = children.indexOf(preMatch)\n } else {\n for (let i = this.index, e = Math.min(children.length, i + 5); i < e; i++) {\n let child = children[i]\n if (child.matchesNode(node, outerDeco, innerDeco) && this.preMatched.indexOf(child) < 0) {\n found = i\n break\n }\n }\n }\n if (found < 0) return false\n this.destroyBetween(this.index, found)\n this.index++\n return true\n }\n\n // : (Node, [Decoration], DecorationSet, EditorView, Fragment, number) → bool\n // Try to update the next node, if any, to the given data. Checks\n // pre-matches to avoid overwriting nodes that could still be used.\n updateNextNode(node, outerDeco, innerDeco, view, index) {\n if (this.index == this.top.children.length) return false\n let next = this.top.children[this.index]\n if (next instanceof NodeViewDesc) {\n let preMatch = this.preMatched.indexOf(next)\n if (preMatch > -1 && preMatch + this.preMatchOffset != index) return false\n let nextDOM = next.dom\n\n // Can't update if nextDOM is or contains this.lock, except if\n // it's a text node whose content already matches the new text\n // and whose decorations match the new ones.\n let locked = this.lock && (nextDOM == this.lock || nextDOM.nodeType == 1 && nextDOM.contains(this.lock.parentNode)) &&\n !(node.isText && next.node && next.node.isText && next.nodeDOM.nodeValue == node.text &&\n next.dirty != NODE_DIRTY && sameOuterDeco(outerDeco, next.outerDeco))\n if (!locked && next.update(node, outerDeco, innerDeco, view)) {\n if (next.dom != nextDOM) this.changed = true\n this.index++\n return true\n }\n }\n return false\n }\n\n // : (Node, [Decoration], DecorationSet, EditorView)\n // Insert the node as a newly created node desc.\n addNode(node, outerDeco, innerDeco, view, pos) {\n this.top.children.splice(this.index++, 0, NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos))\n this.changed = true\n }\n\n placeWidget(widget, view, pos) {\n if (this.index < this.top.children.length && this.top.children[this.index].matchesWidget(widget)) {\n this.index++\n } else {\n let desc = new WidgetViewDesc(this.top, widget, view, pos)\n this.top.children.splice(this.index++, 0, desc)\n this.changed = true\n }\n }\n\n // Make sure a textblock looks and behaves correctly in\n // contentEditable.\n addTextblockHacks() {\n let lastChild = this.top.children[this.index - 1]\n while (lastChild instanceof MarkViewDesc) lastChild = lastChild.children[lastChild.children.length - 1]\n\n if (!lastChild || // Empty textblock\n !(lastChild instanceof TextViewDesc) ||\n /\\n$/.test(lastChild.node.text)) {\n if (this.index < this.top.children.length && this.top.children[this.index].matchesHack()) {\n this.index++\n } else {\n let dom = document.createElement(\"br\")\n this.top.children.splice(this.index++, 0, new BRHackViewDesc(this.top, nothing, dom, null))\n this.changed = true\n }\n }\n }\n}\n\n// : (Fragment, [ViewDesc]) → [ViewDesc]\n// Iterate from the end of the fragment and array of descs to find\n// directly matching ones, in order to avoid overeagerly reusing\n// those for other nodes. Returns an array whose positions correspond\n// to node positions in the fragment, and whose elements are either\n// descs matched to the child at that index, or empty.\nfunction preMatch(frag, descs) {\n let result = [], end = frag.childCount\n for (let i = descs.length - 1; end > 0 && i >= 0; i--) {\n let desc = descs[i], node = desc.node\n if (!node) continue\n if (node != frag.child(end - 1)) break\n result.push(desc)\n --end\n }\n return {nodes: result.reverse(), offset: end}\n}\n\nfunction compareSide(a, b) { return a.type.side - b.type.side }\n\n// : (ViewDesc, DecorationSet, (Decoration, number), (Node, [Decoration], DecorationSet, number))\n// This function abstracts iterating over the nodes and decorations in\n// a fragment. Calls `onNode` for each node, with its local and child\n// decorations. Splits text nodes when there is a decoration starting\n// or ending inside of them. Calls `onWidget` for each widget.\nfunction iterDeco(parent, deco, onWidget, onNode) {\n let locals = deco.locals(parent), offset = 0\n // Simple, cheap variant for when there are no local decorations\n if (locals.length == 0) {\n for (let i = 0; i < parent.childCount; i++) {\n let child = parent.child(i)\n onNode(child, locals, deco.forChild(offset, child), i)\n offset += child.nodeSize\n }\n return\n }\n\n let decoIndex = 0, active = [], restNode = null\n for (let parentIndex = 0;;) {\n if (decoIndex < locals.length && locals[decoIndex].to == offset) {\n let widget = locals[decoIndex++], widgets\n while (decoIndex < locals.length && locals[decoIndex].to == offset)\n (widgets || (widgets = [widget])).push(locals[decoIndex++])\n if (widgets) {\n widgets.sort(compareSide)\n for (let i = 0; i < widgets.length; i++) onWidget(widgets[i], parentIndex)\n } else {\n onWidget(widget, parentIndex)\n }\n }\n\n let child, index\n if (restNode) {\n index = -1\n child = restNode\n restNode = null\n } else if (parentIndex < parent.childCount) {\n index = parentIndex\n child = parent.child(parentIndex++)\n } else {\n break\n }\n\n for (let i = 0; i < active.length; i++) if (active[i].to <= offset) active.splice(i--, 1)\n while (decoIndex < locals.length && locals[decoIndex].from == offset) active.push(locals[decoIndex++])\n\n let end = offset + child.nodeSize\n if (child.isText) {\n let cutAt = end\n if (decoIndex < locals.length && locals[decoIndex].from < cutAt) cutAt = locals[decoIndex].from\n for (let i = 0; i < active.length; i++) if (active[i].to < cutAt) cutAt = active[i].to\n if (cutAt < end) {\n restNode = child.cut(cutAt - offset)\n child = child.cut(0, cutAt - offset)\n end = cutAt\n index = -1\n }\n }\n\n onNode(child, active.length ? active.slice() : nothing, deco.forChild(offset, child), index)\n offset = end\n }\n}\n\n// List markers in Mobile Safari will mysteriously disappear\n// sometimes. This works around that.\nfunction iosHacks(dom) {\n if (dom.nodeName == \"UL\" || dom.nodeName == \"OL\") {\n let oldCSS = dom.style.cssText\n dom.style.cssText = oldCSS + \"; list-style: square !important\"\n window.getComputedStyle(dom).listStyle\n dom.style.cssText = oldCSS\n }\n}\n\nfunction nearbyTextNode(node, offset) {\n for (;;) {\n if (node.nodeType == 3) return node\n if (node.nodeType == 1 && offset > 0) {\n if (node.childNodes.length > offset && node.childNodes[offset].nodeType == 3)\n return node.childNodes[offset]\n node = node.childNodes[offset - 1]\n offset = nodeSize(node)\n } else if (node.nodeType == 1 && offset < node.childNodes.length) {\n node = node.childNodes[offset]\n offset = 0\n } else {\n return null\n }\n }\n}\n\n// Find a piece of text in an inline fragment, overlapping from-to\nfunction findTextInFragment(frag, text, from, to) {\n for (let str = \"\", i = 0, childPos = 0; i < frag.childCount; i++) {\n let child = frag.child(i), end = childPos + child.nodeSize\n if (child.isText) {\n str += child.text\n if (end >= to) {\n let strStart = end - str.length, found = str.lastIndexOf(text)\n while (found > -1 && strStart + found > from) found = str.lastIndexOf(text, found - 1)\n if (found > -1 && strStart + found + text.length >= to) {\n return strStart + found\n } else if (end > to) {\n break\n }\n }\n } else {\n str = \"\"\n }\n childPos = end\n }\n return -1\n}\n\n// Replace range from-to in an array of view descs with replacement\n// (may be null to just delete). This goes very much against the grain\n// of the rest of this code, which tends to create nodes with the\n// right shape in one go, rather than messing with them after\n// creation, but is necessary in the composition hack.\nfunction replaceNodes(nodes, from, to, view, replacement) {\n let result = []\n for (let i = 0, off = 0; i < nodes.length; i++) {\n let child = nodes[i], start = off, end = off += child.size\n if (start >= to || end <= from) {\n result.push(child)\n } else {\n if (start < from) result.push(child.slice(0, from - start, view))\n if (replacement) {\n result.push(replacement)\n replacement = null\n }\n if (end > to) result.push(child.slice(to - start, child.size, view))\n }\n }\n return result\n}\n","import {Selection, NodeSelection, TextSelection} from \"prosemirror-state\"\nimport browser from \"./browser\"\nimport {domIndex, selectionCollapsed} from \"./dom\"\n\nfunction moveSelectionBlock(state, dir) {\n let {$anchor, $head} = state.selection\n let $side = dir > 0 ? $anchor.max($head) : $anchor.min($head)\n let $start = !$side.parent.inlineContent ? $side : $side.depth ? state.doc.resolve(dir > 0 ? $side.after() : $side.before()) : null\n return $start && Selection.findFrom($start, dir)\n}\n\nfunction apply(view, sel) {\n view.dispatch(view.state.tr.setSelection(sel).scrollIntoView())\n return true\n}\n\nfunction selectHorizontally(view, dir, mods) {\n let sel = view.state.selection\n if (sel instanceof TextSelection) {\n if (!sel.empty || mods.indexOf(\"s\") > -1) {\n return false\n } else if (view.endOfTextblock(dir > 0 ? \"right\" : \"left\")) {\n let next = moveSelectionBlock(view.state, dir)\n if (next && (next instanceof NodeSelection)) return apply(view, next)\n return false\n } else {\n let $head = sel.$head, node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter, desc\n if (!node || node.isText) return false\n let nodePos = dir < 0 ? $head.pos - node.nodeSize : $head.pos\n if (!(node.isAtom || (desc = view.docView.descAt(nodePos)) && !desc.contentDOM)) return false\n if (NodeSelection.isSelectable(node)) {\n return apply(view, new NodeSelection(dir < 0 ? view.state.doc.resolve($head.pos - node.nodeSize) : $head))\n } else if (browser.webkit) {\n // Chrome and Safari will introduce extra pointless cursor\n // positions around inline uneditable nodes, so we have to\n // take over and move the cursor past them (#937)\n return apply(view, new TextSelection(view.state.doc.resolve(dir < 0 ? nodePos : nodePos + node.nodeSize)))\n } else {\n return false\n }\n }\n } else if (sel instanceof NodeSelection && sel.node.isInline) {\n return apply(view, new TextSelection(dir > 0 ? sel.$to : sel.$from))\n } else {\n let next = moveSelectionBlock(view.state, dir)\n if (next) return apply(view, next)\n return false\n }\n}\n\nfunction nodeLen(node) {\n return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length\n}\n\nfunction isIgnorable(dom) {\n let desc = dom.pmViewDesc\n return desc && desc.size == 0 && (dom.nextSibling || dom.nodeName != \"BR\")\n}\n\n// Make sure the cursor isn't directly after one or more ignored\n// nodes, which will confuse the browser's cursor motion logic.\nfunction skipIgnoredNodesLeft(view) {\n let sel = view.root.getSelection()\n let node = sel.focusNode, offset = sel.focusOffset\n if (!node) return\n let moveNode, moveOffset, force = false\n // Gecko will do odd things when the selection is directly in front\n // of a non-editable node, so in that case, move it into the next\n // node if possible. Issue prosemirror/prosemirror#832.\n if (browser.gecko && node.nodeType == 1 && offset < nodeLen(node) && isIgnorable(node.childNodes[offset])) force = true\n for (;;) {\n if (offset > 0) {\n if (node.nodeType != 1) {\n break\n } else {\n let before = node.childNodes[offset - 1]\n if (isIgnorable(before)) {\n moveNode = node\n moveOffset = --offset\n } else if (before.nodeType == 3) {\n node = before\n offset = node.nodeValue.length\n } else break\n }\n } else if (isBlockNode(node)) {\n break\n } else {\n let prev = node.previousSibling\n while (prev && isIgnorable(prev)) {\n moveNode = node.parentNode\n moveOffset = domIndex(prev)\n prev = prev.previousSibling\n }\n if (!prev) {\n node = node.parentNode\n if (node == view.dom) break\n offset = 0\n } else {\n node = prev\n offset = nodeLen(node)\n }\n }\n }\n if (force) setSelFocus(view, sel, node, offset)\n else if (moveNode) setSelFocus(view, sel, moveNode, moveOffset)\n}\n\n// Make sure the cursor isn't directly before one or more ignored\n// nodes.\nfunction skipIgnoredNodesRight(view) {\n let sel = view.root.getSelection()\n let node = sel.focusNode, offset = sel.focusOffset\n if (!node) return\n let len = nodeLen(node)\n let moveNode, moveOffset\n for (;;) {\n if (offset < len) {\n if (node.nodeType != 1) break\n let after = node.childNodes[offset]\n if (isIgnorable(after)) {\n moveNode = node\n moveOffset = ++offset\n }\n else break\n } else if (isBlockNode(node)) {\n break\n } else {\n let next = node.nextSibling\n while (next && isIgnorable(next)) {\n moveNode = next.parentNode\n moveOffset = domIndex(next) + 1\n next = next.nextSibling\n }\n if (!next) {\n node = node.parentNode\n if (node == view.dom) break\n offset = len = 0\n } else {\n node = next\n offset = 0\n len = nodeLen(node)\n }\n }\n }\n if (moveNode) setSelFocus(view, sel, moveNode, moveOffset)\n}\n\nfunction isBlockNode(dom) {\n let desc = dom.pmViewDesc\n return desc && desc.node && desc.node.isBlock\n}\n\nfunction setSelFocus(view, sel, node, offset) {\n if (selectionCollapsed(sel)) {\n let range = document.createRange()\n range.setEnd(node, offset)\n range.setStart(node, offset)\n sel.removeAllRanges()\n sel.addRange(range)\n } else if (sel.extend) {\n sel.extend(node, offset)\n }\n view.domObserver.setCurSelection()\n}\n\n// : (EditorState, number)\n// Check whether vertical selection motion would involve node\n// selections. If so, apply it (if not, the result is left to the\n// browser)\nfunction selectVertically(view, dir, mods) {\n let sel = view.state.selection\n if (sel instanceof TextSelection && !sel.empty || mods.indexOf(\"s\") > -1) return false\n let {$from, $to} = sel\n\n if (!$from.parent.inlineContent || view.endOfTextblock(dir < 0 ? \"up\" : \"down\")) {\n let next = moveSelectionBlock(view.state, dir)\n if (next && (next instanceof NodeSelection))\n return apply(view, next)\n }\n if (!$from.parent.inlineContent) {\n let beyond = Selection.findFrom(dir < 0 ? $from : $to, dir)\n return beyond ? apply(view, beyond) : true\n }\n return false\n}\n\nfunction stopNativeHorizontalDelete(view, dir) {\n if (!(view.state.selection instanceof TextSelection)) return true\n let {$head, $anchor, empty} = view.state.selection\n if (!$head.sameParent($anchor)) return true\n if (!empty) return false\n if (view.endOfTextblock(dir > 0 ? \"forward\" : \"backward\")) return true\n let nextNode = !$head.textOffset && (dir < 0 ? $head.nodeBefore : $head.nodeAfter)\n if (nextNode && !nextNode.isText) {\n let tr = view.state.tr\n if (dir < 0) tr.delete($head.pos - nextNode.nodeSize, $head.pos)\n else tr.delete($head.pos, $head.pos + nextNode.nodeSize)\n view.dispatch(tr)\n return true\n }\n return false\n}\n\nfunction switchEditable(view, node, state) {\n view.domObserver.stop()\n node.contentEditable = state\n view.domObserver.start()\n}\n\n// Issue #867 / https://bugs.chromium.org/p/chromium/issues/detail?id=903821\n// In which Chrome does really wrong things when the down arrow is\n// pressed when the cursor is directly at the start of a textblock and\n// has an uneditable node after it\nfunction chromeDownArrowBug(view) {\n if (!browser.chrome || view.state.selection.$head.parentOffset > 0) return\n let {focusNode, focusOffset} = view.root.getSelection()\n if (focusNode && focusNode.nodeType == 1 && focusOffset == 0 &&\n focusNode.firstChild && focusNode.firstChild.contentEditable == \"false\") {\n let child = focusNode.firstChild\n switchEditable(view, child, true)\n setTimeout(() => switchEditable(view, child, false), 20)\n }\n}\n\n// A backdrop key mapping used to make sure we always suppress keys\n// that have a dangerous default effect, even if the commands they are\n// bound to return false, and to make sure that cursor-motion keys\n// find a cursor (as opposed to a node selection) when pressed. For\n// cursor-motion keys, the code in the handlers also takes care of\n// block selections.\n\nfunction getMods(event) {\n let result = \"\"\n if (event.ctrlKey) result += \"c\"\n if (event.metaKey) result += \"m\"\n if (event.altKey) result += \"a\"\n if (event.shiftKey) result += \"s\"\n return result\n}\n\nexport function captureKeyDown(view, event) {\n let code = event.keyCode, mods = getMods(event)\n if (code == 8 || (browser.mac && code == 72 && mods == \"c\")) { // Backspace, Ctrl-h on Mac\n return stopNativeHorizontalDelete(view, -1) || skipIgnoredNodesLeft(view)\n } else if (code == 46 || (browser.mac && code == 68 && mods == \"c\")) { // Delete, Ctrl-d on Mac\n return stopNativeHorizontalDelete(view, 1) || skipIgnoredNodesRight(view)\n } else if (code == 13 || code == 27) { // Enter, Esc\n return true\n } else if (code == 37) { // Left arrow\n return selectHorizontally(view, -1, mods) || skipIgnoredNodesLeft(view)\n } else if (code == 39) { // Right arrow\n return selectHorizontally(view, 1, mods) || skipIgnoredNodesRight(view)\n } else if (code == 38) { // Up arrow\n return selectVertically(view, -1, mods) || skipIgnoredNodesLeft(view)\n } else if (code == 40) { // Down arrow\n return chromeDownArrowBug(view) || selectVertically(view, 1, mods) || skipIgnoredNodesRight(view)\n } else if (mods == (browser.mac ? \"m\" : \"c\") &&\n (code == 66 || code == 73 || code == 89 || code == 90)) { // Mod-[biyz]\n return true\n }\n return false\n}\n","import {TextSelection, NodeSelection} from \"prosemirror-state\"\n\nimport browser from \"./browser\"\nimport {selectionCollapsed, isEquivalentPosition, domIndex} from \"./dom\"\n\nexport function selectionFromDOM(view, origin) {\n let domSel = view.root.getSelection(), doc = view.state.doc\n let nearestDesc = view.docView.nearestDesc(domSel.focusNode), inWidget = nearestDesc && nearestDesc.size == 0\n let head = view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset)\n let $head = doc.resolve(head), $anchor, selection\n if (selectionCollapsed(domSel)) {\n $anchor = $head\n while (nearestDesc && !nearestDesc.node) nearestDesc = nearestDesc.parent\n if (nearestDesc && nearestDesc.node.isAtom && NodeSelection.isSelectable(nearestDesc.node) && nearestDesc.parent) {\n let pos = nearestDesc.posBefore\n selection = new NodeSelection(head == pos ? $head : doc.resolve(pos))\n }\n } else {\n $anchor = doc.resolve(view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset))\n }\n\n if (!selection) {\n let bias = origin == \"pointer\" || (view.state.selection.head < $head.pos && !inWidget) ? 1 : -1\n selection = selectionBetween(view, $anchor, $head, bias)\n }\n return selection\n}\n\nexport function selectionToDOM(view, force) {\n let sel = view.state.selection\n syncNodeSelection(view, sel)\n\n if (view.editable ? !view.hasFocus() : !(hasSelection(view) && document.activeElement.contains(view.dom))) return\n\n view.domObserver.disconnectSelection()\n\n if (view.cursorWrapper) {\n selectCursorWrapper(view)\n } else {\n let {anchor, head} = sel, resetEditableFrom, resetEditableTo\n if (brokenSelectBetweenUneditable && !(sel instanceof TextSelection)) {\n if (!sel.$from.parent.inlineContent)\n resetEditableFrom = temporarilyEditableNear(view, sel.from)\n if (!sel.empty && !sel.$from.parent.inlineContent)\n resetEditableTo = temporarilyEditableNear(view, sel.to)\n }\n view.docView.setSelection(anchor, head, view.root, force)\n if (brokenSelectBetweenUneditable) {\n if (resetEditableFrom) resetEditableFrom.contentEditable = \"false\"\n if (resetEditableTo) resetEditableTo.contentEditable = \"false\"\n }\n if (sel.visible) {\n view.dom.classList.remove(\"ProseMirror-hideselection\")\n } else if (anchor != head) {\n view.dom.classList.add(\"ProseMirror-hideselection\")\n if (\"onselectionchange\" in document) removeClassOnSelectionChange(view)\n }\n }\n\n view.domObserver.setCurSelection()\n view.domObserver.connectSelection()\n}\n\n// Kludge to work around Webkit not allowing a selection to start/end\n// between non-editable block nodes. We briefly make something\n// editable, set the selection, then set it uneditable again.\n\nconst brokenSelectBetweenUneditable = browser.safari || browser.chrome && browser.chrome_version < 63\n\nfunction temporarilyEditableNear(view, pos) {\n let {node, offset} = view.docView.domFromPos(pos)\n let after = offset < node.childNodes.length ? node.childNodes[offset] : null\n let before = offset ? node.childNodes[offset - 1] : null\n if ((!after || after.contentEditable == \"false\") && (!before || before.contentEditable == \"false\")) {\n if (after) {\n after.contentEditable = \"true\"\n return after\n } else if (before) {\n before.contentEditable = \"true\"\n return before\n }\n }\n}\n\nfunction removeClassOnSelectionChange(view) {\n let doc = view.dom.ownerDocument\n doc.removeEventListener(\"selectionchange\", view.hideSelectionGuard)\n let domSel = view.root.getSelection()\n let node = domSel.anchorNode, offset = domSel.anchorOffset\n doc.addEventListener(\"selectionchange\", view.hideSelectionGuard = () => {\n if (domSel.anchorNode != node || domSel.anchorOffset != offset) {\n doc.removeEventListener(\"selectionchange\", view.hideSelectionGuard)\n view.dom.classList.remove(\"ProseMirror-hideselection\")\n }\n })\n}\n\nfunction selectCursorWrapper(view) {\n let domSel = view.root.getSelection(), range = document.createRange()\n let node = view.cursorWrapper.dom, img = node.nodeName == \"IMG\"\n if (img) range.setEnd(node.parentNode, domIndex(node) + 1)\n else range.setEnd(node, 0)\n range.collapse(false)\n domSel.removeAllRanges()\n domSel.addRange(range)\n // Kludge to kill 'control selection' in IE11 when selecting an\n // invisible cursor wrapper, since that would result in those weird\n // resize handles and a selection that considers the absolutely\n // positioned wrapper, rather than the root editable node, the\n // focused element.\n if (!img && !view.state.selection.visible && browser.ie && browser.ie_version <= 11) {\n node.disabled = true\n node.disabled = false\n }\n}\n\nexport function syncNodeSelection(view, sel) {\n if (sel instanceof NodeSelection) {\n let desc = view.docView.descAt(sel.from)\n if (desc != view.lastSelectedViewDesc) {\n clearNodeSelection(view)\n if (desc) desc.selectNode()\n view.lastSelectedViewDesc = desc\n }\n } else {\n clearNodeSelection(view)\n }\n}\n\n// Clear all DOM statefulness of the last node selection.\nfunction clearNodeSelection(view) {\n if (view.lastSelectedViewDesc) {\n if (view.lastSelectedViewDesc.parent)\n view.lastSelectedViewDesc.deselectNode()\n view.lastSelectedViewDesc = null\n }\n}\n\nexport function selectionBetween(view, $anchor, $head, bias) {\n return view.someProp(\"createSelectionBetween\", f => f(view, $anchor, $head))\n || TextSelection.between($anchor, $head, bias)\n}\n\nexport function hasFocusAndSelection(view) {\n if (view.editable && view.root.activeElement != view.dom) return false\n return hasSelection(view)\n}\n\nexport function hasSelection(view) {\n let sel = view.root.getSelection()\n if (!sel.anchorNode) return false\n try {\n // Firefox will raise 'permission denied' errors when accessing\n // properties of `sel.anchorNode` when it's in a generated CSS\n // element.\n return view.dom.contains(sel.anchorNode.nodeType == 3 ? sel.anchorNode.parentNode : sel.anchorNode) &&\n (view.editable || view.dom.contains(sel.focusNode.nodeType == 3 ? sel.focusNode.parentNode : sel.focusNode))\n } catch(_) {\n return false\n }\n}\n\nexport function anchorInRightPlace(view) {\n let anchorDOM = view.docView.domFromPos(view.state.selection.anchor)\n let domSel = view.root.getSelection()\n return isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset)\n}\n","import {Fragment, DOMParser} from \"prosemirror-model\"\nimport {Selection, TextSelection} from \"prosemirror-state\"\n\nimport {selectionBetween, selectionFromDOM, selectionToDOM} from \"./selection\"\nimport {selectionCollapsed, keyEvent} from \"./dom\"\nimport browser from \"./browser\"\n\n// Note that all referencing and parsing is done with the\n// start-of-operation selection and document, since that's the one\n// that the DOM represents. If any changes came in in the meantime,\n// the modification is mapped over those before it is applied, in\n// readDOMChange.\n\nfunction parseBetween(view, from_, to_) {\n let {node: parent, fromOffset, toOffset, from, to} = view.docView.parseRange(from_, to_)\n\n let domSel = view.root.getSelection(), find = null, anchor = domSel.anchorNode\n if (anchor && view.dom.contains(anchor.nodeType == 1 ? anchor : anchor.parentNode)) {\n find = [{node: anchor, offset: domSel.anchorOffset}]\n if (!selectionCollapsed(domSel))\n find.push({node: domSel.focusNode, offset: domSel.focusOffset})\n }\n // Work around issue in Chrome where backspacing sometimes replaces\n // the deleted content with a random BR node (issues #799, #831)\n if (browser.chrome && view.lastKeyCode === 8) {\n for (let off = toOffset; off > fromOffset; off--) {\n let node = parent.childNodes[off - 1], desc = node.pmViewDesc\n if (node.nodeType == \"BR\" && !desc) { toOffset = off; break }\n if (!desc || desc.size) break\n }\n }\n let startDoc = view.state.doc\n let parser = view.someProp(\"domParser\") || DOMParser.fromSchema(view.state.schema)\n let $from = startDoc.resolve(from)\n\n let sel = null, doc = parser.parse(parent, {\n topNode: $from.parent,\n topMatch: $from.parent.contentMatchAt($from.index()),\n topOpen: true,\n from: fromOffset,\n to: toOffset,\n preserveWhitespace: $from.parent.type.spec.code ? \"full\" : true,\n editableContent: true,\n findPositions: find,\n ruleFromNode,\n context: $from\n })\n if (find && find[0].pos != null) {\n let anchor = find[0].pos, head = find[1] && find[1].pos\n if (head == null) head = anchor\n sel = {anchor: anchor + from, head: head + from}\n }\n return {doc, sel, from, to}\n}\n\nfunction ruleFromNode(dom) {\n let desc = dom.pmViewDesc\n if (desc) {\n return desc.parseRule()\n } else if (dom.nodeName == \"BR\" && dom.parentNode) {\n // Safari replaces the list item or table cell with a BR\n // directly in the list node (?!) if you delete the last\n // character in a list item or table cell (#708, #862)\n if (browser.safari && /^(ul|ol)$/i.test(dom.parentNode.nodeName)) {\n let skip = document.createElement(\"div\")\n skip.appendChild(document.createElement(\"li\"))\n return {skip}\n } else if (dom.parentNode.lastChild == dom || browser.safari && /^(tr|table)$/i.test(dom.parentNode.nodeName)) {\n return {ignore: true}\n }\n } else if (dom.nodeName == \"IMG\" && dom.getAttribute(\"mark-placeholder\")) {\n return {ignore: true}\n }\n}\n\nexport function readDOMChange(view, from, to, typeOver) {\n if (from < 0) {\n let origin = view.lastSelectionTime > Date.now() - 50 ? view.lastSelectionOrigin : null\n let newSel = selectionFromDOM(view, origin)\n if (!view.state.selection.eq(newSel)) {\n let tr = view.state.tr.setSelection(newSel)\n if (origin == \"pointer\") tr.setMeta(\"pointer\", true)\n else if (origin == \"key\") tr.scrollIntoView()\n view.dispatch(tr)\n }\n return\n }\n\n let $before = view.state.doc.resolve(from)\n let shared = $before.sharedDepth(to)\n from = $before.before(shared + 1)\n to = view.state.doc.resolve(to).after(shared + 1)\n\n let sel = view.state.selection\n let parse = parseBetween(view, from, to)\n\n let doc = view.state.doc, compare = doc.slice(parse.from, parse.to)\n let preferredPos, preferredSide\n // Prefer anchoring to end when Backspace is pressed\n if (view.lastKeyCode === 8 && Date.now() - 100 < view.lastKeyCodeTime) {\n preferredPos = view.state.selection.to\n preferredSide = \"end\"\n } else {\n preferredPos = view.state.selection.from\n preferredSide = \"start\"\n }\n view.lastKeyCode = null\n\n let change = findDiff(compare.content, parse.doc.content, parse.from, preferredPos, preferredSide)\n if (!change) {\n if (typeOver && sel instanceof TextSelection && !sel.empty && sel.$head.sameParent(sel.$anchor) &&\n !view.composing && !(parse.sel && parse.sel.anchor != parse.sel.head)) {\n change = {start: sel.from, endA: sel.to, endB: sel.to}\n } else {\n if (parse.sel) {\n let sel = resolveSelection(view, view.state.doc, parse.sel)\n if (sel && !sel.eq(view.state.selection)) view.dispatch(view.state.tr.setSelection(sel))\n }\n return\n }\n }\n view.domChangeCount++\n // Handle the case where overwriting a selection by typing matches\n // the start or end of the selected content, creating a change\n // that's smaller than what was actually overwritten.\n if (view.state.selection.from < view.state.selection.to &&\n change.start == change.endB &&\n view.state.selection instanceof TextSelection) {\n if (change.start > view.state.selection.from && change.start <= view.state.selection.from + 2) {\n change.start = view.state.selection.from\n } else if (change.endA < view.state.selection.to && change.endA >= view.state.selection.to - 2) {\n change.endB += (view.state.selection.to - change.endA)\n change.endA = view.state.selection.to\n }\n }\n\n // IE11 will insert a non-breaking space _ahead_ of the space after\n // the cursor space when adding a space before another space. When\n // that happened, adjust the change to cover the space instead.\n if (browser.ie && browser.ie_version <= 11 && change.endB == change.start + 1 &&\n change.endA == change.start && change.start > parse.from &&\n parse.doc.textBetween(change.start - parse.from - 1, change.start - parse.from + 1) == \" \\u00a0\") {\n change.start--\n change.endA--\n change.endB--\n }\n\n let $from = parse.doc.resolveNoCache(change.start - parse.from)\n let $to = parse.doc.resolveNoCache(change.endB - parse.from)\n let nextSel\n // If this looks like the effect of pressing Enter, just dispatch an\n // Enter key instead.\n if (!$from.sameParent($to) && $from.pos < parse.doc.content.size &&\n (nextSel = Selection.findFrom(parse.doc.resolve($from.pos + 1), 1, true)) &&\n nextSel.head == $to.pos &&\n view.someProp(\"handleKeyDown\", f => f(view, keyEvent(13, \"Enter\"))))\n return\n // Same for backspace\n if (view.state.selection.anchor > change.start &&\n looksLikeJoin(doc, change.start, change.endA, $from, $to) &&\n view.someProp(\"handleKeyDown\", f => f(view, keyEvent(8, \"Backspace\")))) {\n if (browser.android && browser.chrome) view.domObserver.suppressSelectionUpdates() // #820\n return\n }\n\n let chFrom = change.start, chTo = change.endA\n\n let tr, storedMarks, markChange, $from1\n if ($from.sameParent($to) && $from.parent.inlineContent) {\n if ($from.pos == $to.pos) { // Deletion\n // IE11 sometimes weirdly moves the DOM selection around after\n // backspacing out the first element in a textblock\n if (browser.ie && browser.ie_version <= 11 && $from.parentOffset == 0) {\n view.domObserver.suppressSelectionUpdates()\n setTimeout(() => selectionToDOM(view), 20)\n }\n tr = view.state.tr.delete(chFrom, chTo)\n storedMarks = doc.resolve(change.start).marksAcross(doc.resolve(change.endA))\n } else if ( // Adding or removing a mark\n change.endA == change.endB && ($from1 = doc.resolve(change.start)) &&\n (markChange = isMarkChange($from.parent.content.cut($from.parentOffset, $to.parentOffset),\n $from1.parent.content.cut($from1.parentOffset, change.endA - $from1.start())))\n ) {\n tr = view.state.tr\n if (markChange.type == \"add\") tr.addMark(chFrom, chTo, markChange.mark)\n else tr.removeMark(chFrom, chTo, markChange.mark)\n } else if ($from.parent.child($from.index()).isText && $from.index() == $to.index() - ($to.textOffset ? 0 : 1)) {\n // Both positions in the same text node -- simply insert text\n let text = $from.parent.textBetween($from.parentOffset, $to.parentOffset)\n if (view.someProp(\"handleTextInput\", f => f(view, chFrom, chTo, text))) return\n tr = view.state.tr.insertText(text, chFrom, chTo)\n }\n }\n\n if (!tr)\n tr = view.state.tr.replace(chFrom, chTo, parse.doc.slice(change.start - parse.from, change.endB - parse.from))\n if (parse.sel) {\n let sel = resolveSelection(view, tr.doc, parse.sel)\n // Chrome Android will sometimes, during composition, report the\n // selection in the wrong place. If it looks like that is\n // happening, don't update the selection.\n // Edge just doesn't move the cursor forward when you start typing\n // in an empty block or between br nodes.\n if (sel && !(browser.chrome && browser.android && view.composing && sel.empty && sel.head == chFrom ||\n browser.ie && sel.empty && sel.head == chFrom))\n tr.setSelection(sel)\n }\n if (storedMarks) tr.ensureMarks(storedMarks)\n view.dispatch(tr.scrollIntoView())\n}\n\nfunction resolveSelection(view, doc, parsedSel) {\n if (Math.max(parsedSel.anchor, parsedSel.head) > doc.content.size) return null\n return selectionBetween(view, doc.resolve(parsedSel.anchor), doc.resolve(parsedSel.head))\n}\n\n// : (Fragment, Fragment) → ?{mark: Mark, type: string}\n// Given two same-length, non-empty fragments of inline content,\n// determine whether the first could be created from the second by\n// removing or adding a single mark type.\nfunction isMarkChange(cur, prev) {\n let curMarks = cur.firstChild.marks, prevMarks = prev.firstChild.marks\n let added = curMarks, removed = prevMarks, type, mark, update\n for (let i = 0; i < prevMarks.length; i++) added = prevMarks[i].removeFromSet(added)\n for (let i = 0; i < curMarks.length; i++) removed = curMarks[i].removeFromSet(removed)\n if (added.length == 1 && removed.length == 0) {\n mark = added[0]\n type = \"add\"\n update = node => node.mark(mark.addToSet(node.marks))\n } else if (added.length == 0 && removed.length == 1) {\n mark = removed[0]\n type = \"remove\"\n update = node => node.mark(mark.removeFromSet(node.marks))\n } else {\n return null\n }\n let updated = []\n for (let i = 0; i < prev.childCount; i++) updated.push(update(prev.child(i)))\n if (Fragment.from(updated).eq(cur)) return {mark, type}\n}\n\nfunction looksLikeJoin(old, start, end, $newStart, $newEnd) {\n if (!$newStart.parent.isTextblock ||\n // The content must have shrunk\n end - start <= $newEnd.pos - $newStart.pos ||\n // newEnd must point directly at or after the end of the block that newStart points into\n skipClosingAndOpening($newStart, true, false) < $newEnd.pos)\n return false\n\n let $start = old.resolve(start)\n // Start must be at the end of a block\n if ($start.parentOffset < $start.parent.content.size || !$start.parent.isTextblock)\n return false\n let $next = old.resolve(skipClosingAndOpening($start, true, true))\n // The next textblock must start before end and end near it\n if (!$next.parent.isTextblock || $next.pos > end ||\n skipClosingAndOpening($next, true, false) < end)\n return false\n\n // The fragments after the join point must match\n return $newStart.parent.content.cut($newStart.parentOffset).eq($next.parent.content)\n}\n\nfunction skipClosingAndOpening($pos, fromEnd, mayOpen) {\n let depth = $pos.depth, end = fromEnd ? $pos.end() : $pos.pos\n while (depth > 0 && (fromEnd || $pos.indexAfter(depth) == $pos.node(depth).childCount)) {\n depth--\n end++\n fromEnd = false\n }\n if (mayOpen) {\n let next = $pos.node(depth).maybeChild($pos.indexAfter(depth))\n while (next && !next.isLeaf) {\n next = next.firstChild\n end++\n }\n }\n return end\n}\n\nfunction findDiff(a, b, pos, preferredPos, preferredSide) {\n let start = a.findDiffStart(b, pos)\n if (start == null) return null\n let {a: endA, b: endB} = a.findDiffEnd(b, pos + a.size, pos + b.size)\n if (preferredSide == \"end\") {\n let adjust = Math.max(0, start - Math.min(endA, endB))\n preferredPos -= endA + adjust - start\n }\n if (endA < start && a.size < b.size) {\n let move = preferredPos <= start && preferredPos >= endA ? start - preferredPos : 0\n start -= move\n endB = start + (endB - endA)\n endA = start\n } else if (endB < start) {\n let move = preferredPos <= start && preferredPos >= endB ? start - preferredPos : 0\n start -= move\n endA = start + (endA - endB)\n endB = start\n }\n return {start, endA, endB}\n}\n","import {Slice, Fragment, DOMParser, DOMSerializer} from \"prosemirror-model\"\n\nexport function serializeForClipboard(view, slice) {\n let context = [], {content, openStart, openEnd} = slice\n while (openStart > 1 && openEnd > 1 && content.childCount == 1 && content.firstChild.childCount == 1) {\n openStart--\n openEnd--\n let node = content.firstChild\n context.push(node.type.name, node.type.hasRequiredAttrs() ? node.attrs : null)\n content = node.content\n }\n\n let serializer = view.someProp(\"clipboardSerializer\") || DOMSerializer.fromSchema(view.state.schema)\n let doc = detachedDoc(), wrap = doc.createElement(\"div\")\n wrap.appendChild(serializer.serializeFragment(content, {document: doc}))\n\n let firstChild = wrap.firstChild, needsWrap\n while (firstChild && firstChild.nodeType == 1 && (needsWrap = wrapMap[firstChild.nodeName.toLowerCase()])) {\n for (let i = needsWrap.length - 1; i >= 0; i--) {\n let wrapper = doc.createElement(needsWrap[i])\n while (wrap.firstChild) wrapper.appendChild(wrap.firstChild)\n wrap.appendChild(wrapper)\n }\n firstChild = wrap.firstChild\n }\n\n if (firstChild && firstChild.nodeType == 1)\n firstChild.setAttribute(\"data-pm-slice\", `${openStart} ${openEnd} ${JSON.stringify(context)}`)\n\n let text = view.someProp(\"clipboardTextSerializer\", f => f(slice)) ||\n slice.content.textBetween(0, slice.content.size, \"\\n\\n\")\n\n return {dom: wrap, text}\n}\n\n// : (EditorView, string, string, ?bool, ResolvedPos) → ?Slice\n// Read a slice of content from the clipboard (or drop data).\nexport function parseFromClipboard(view, text, html, plainText, $context) {\n let dom, inCode = $context.parent.type.spec.code, slice\n if (!html && !text) return null\n let asText = text && (plainText || inCode || !html)\n if (asText) {\n view.someProp(\"transformPastedText\", f => { text = f(text) })\n if (inCode) return new Slice(Fragment.from(view.state.schema.text(text)), 0, 0)\n let parsed = view.someProp(\"clipboardTextParser\", f => f(text, $context))\n if (parsed) {\n slice = parsed\n } else {\n dom = document.createElement(\"div\")\n text.trim().split(/(?:\\r\\n?|\\n)+/).forEach(block => {\n dom.appendChild(document.createElement(\"p\")).textContent = block\n })\n }\n } else {\n view.someProp(\"transformPastedHTML\", f => { html = f(html) })\n dom = readHTML(html)\n }\n\n let contextNode = dom && dom.querySelector(\"[data-pm-slice]\")\n let sliceData = contextNode && /^(\\d+) (\\d+) (.*)/.exec(contextNode.getAttribute(\"data-pm-slice\"))\n if (!slice) {\n let parser = view.someProp(\"clipboardParser\") || view.someProp(\"domParser\") || DOMParser.fromSchema(view.state.schema)\n slice = parser.parseSlice(dom, {preserveWhitespace: !!(asText || sliceData), context: $context})\n }\n if (sliceData)\n slice = addContext(closeSlice(slice, +sliceData[1], +sliceData[2]), sliceData[3])\n else // HTML wasn't created by ProseMirror. Make sure top-level siblings are coherent\n slice = Slice.maxOpen(normalizeSiblings(slice.content, $context), false)\n\n view.someProp(\"transformPasted\", f => { slice = f(slice) })\n return slice\n}\n\n// Takes a slice parsed with parseSlice, which means there hasn't been\n// any content-expression checking done on the top nodes, tries to\n// find a parent node in the current context that might fit the nodes,\n// and if successful, rebuilds the slice so that it fits into that parent.\n//\n// This addresses the problem that Transform.replace expects a\n// coherent slice, and will fail to place a set of siblings that don't\n// fit anywhere in the schema.\nfunction normalizeSiblings(fragment, $context) {\n if (fragment.childCount < 2) return fragment\n for (let d = $context.depth; d >= 0; d--) {\n let parent = $context.node(d)\n let match = parent.contentMatchAt($context.index(d))\n let lastWrap, result = []\n fragment.forEach(node => {\n if (!result) return\n let wrap = match.findWrapping(node.type), inLast\n if (!wrap) return result = null\n if (inLast = result.length && lastWrap.length && addToSibling(wrap, lastWrap, node, result[result.length - 1], 0)) {\n result[result.length - 1] = inLast\n } else {\n if (result.length) result[result.length - 1] = closeRight(result[result.length - 1], lastWrap.length)\n let wrapped = withWrappers(node, wrap)\n result.push(wrapped)\n match = match.matchType(wrapped.type, wrapped.attrs)\n lastWrap = wrap\n }\n })\n if (result) return Fragment.from(result)\n }\n return fragment\n}\n\nfunction withWrappers(node, wrap, from = 0) {\n for (let i = wrap.length - 1; i >= from; i--)\n node = wrap[i].create(null, Fragment.from(node))\n return node\n}\n\n// Used to group adjacent nodes wrapped in similar parents by\n// normalizeSiblings into the same parent node\nfunction addToSibling(wrap, lastWrap, node, sibling, depth) {\n if (depth < wrap.length && depth < lastWrap.length && wrap[depth] == lastWrap[depth]) {\n let inner = addToSibling(wrap, lastWrap, node, sibling.lastChild, depth + 1)\n if (inner) return sibling.copy(sibling.content.replaceChild(sibling.childCount - 1, inner))\n let match = sibling.contentMatchAt(sibling.childCount)\n if (match.matchType(depth == wrap.length - 1 ? node.type : wrap[depth + 1]))\n return sibling.copy(sibling.content.append(Fragment.from(withWrappers(node, wrap, depth + 1))))\n }\n}\n\nfunction closeRight(node, depth) {\n if (depth == 0) return node\n let fragment = node.content.replaceChild(node.childCount - 1, closeRight(node.lastChild, depth - 1))\n let fill = node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true)\n return node.copy(fragment.append(fill))\n}\n\nfunction closeRange(fragment, side, from, to, depth, openEnd) {\n let node = side < 0 ? fragment.firstChild : fragment.lastChild, inner = node.content\n if (depth < to - 1) inner = closeRange(inner, side, from, to, depth + 1, openEnd)\n if (depth >= from)\n inner = side < 0 ? node.contentMatchAt(0).fillBefore(inner, fragment.childCount > 1 || openEnd <= depth).append(inner)\n : inner.append(node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true))\n return fragment.replaceChild(side < 0 ? 0 : fragment.childCount - 1, node.copy(inner))\n}\n\nfunction closeSlice(slice, openStart, openEnd) {\n if (openStart < slice.openStart)\n slice = new Slice(closeRange(slice.content, -1, openStart, slice.openStart, 0, slice.openEnd), openStart, slice.openEnd)\n if (openEnd < slice.openEnd)\n slice = new Slice(closeRange(slice.content, 1, openEnd, slice.openEnd, 0, 0), slice.openStart, openEnd)\n return slice\n}\n\n// Trick from jQuery -- some elements must be wrapped in other\n// elements for innerHTML to work. I.e. if you do `div.innerHTML =\n// \"..\"` the table cells are ignored.\nconst wrapMap = {thead: [\"table\"], colgroup: [\"table\"], col: [\"table\", \"colgroup\"],\n tr: [\"table\", \"tbody\"], td: [\"table\", \"tbody\", \"tr\"], th: [\"table\", \"tbody\", \"tr\"]}\n\nlet _detachedDoc = null\nfunction detachedDoc() {\n return _detachedDoc || (_detachedDoc = document.implementation.createHTMLDocument(\"title\"))\n}\n\nfunction readHTML(html) {\n let metas = /(\\s*]*>)*/.exec(html)\n if (metas) html = html.slice(metas[0].length)\n let elt = detachedDoc().createElement(\"div\")\n let firstTag = /(?:]*>)*<([a-z][^>\\s]+)/i.exec(html), wrap, depth = 0\n if (wrap = firstTag && wrapMap[firstTag[1].toLowerCase()]) {\n html = wrap.map(n => \"<\" + n + \">\").join(\"\") + html + wrap.map(n => \"\").reverse().join(\"\")\n depth = wrap.length\n }\n elt.innerHTML = html\n for (let i = 0; i < depth; i++) elt = elt.firstChild\n return elt\n}\n\nfunction addContext(slice, context) {\n if (!slice.size) return slice\n let schema = slice.content.firstChild.type.schema, array\n try { array = JSON.parse(context) }\n catch(e) { return slice }\n let {content, openStart, openEnd} = slice\n for (let i = array.length - 2; i >= 0; i -= 2) {\n let type = schema.nodes[array[i]]\n if (!type || type.hasRequiredAttrs()) break\n content = Fragment.from(type.create(array[i + 1], content))\n openStart++; openEnd++\n }\n return new Slice(content, openStart, openEnd)\n}\n","import browser from \"./browser\"\nimport {domIndex, isEquivalentPosition} from \"./dom\"\nimport {hasFocusAndSelection, hasSelection, selectionToDOM} from \"./selection\"\n\nconst observeOptions = {\n childList: true,\n characterData: true,\n characterDataOldValue: true,\n attributes: true,\n attributeOldValue: true,\n subtree: true\n}\n// IE11 has very broken mutation observers, so we also listen to DOMCharacterDataModified\nconst useCharData = browser.ie && browser.ie_version <= 11\n\nclass SelectionState {\n constructor() {\n this.anchorNode = this.anchorOffset = this.focusNode = this.focusOffset = null\n }\n\n set(sel) {\n this.anchorNode = sel.anchorNode; this.anchorOffset = sel.anchorOffset\n this.focusNode = sel.focusNode; this.focusOffset = sel.focusOffset\n }\n\n eq(sel) {\n return sel.anchorNode == this.anchorNode && sel.anchorOffset == this.anchorOffset &&\n sel.focusNode == this.focusNode && sel.focusOffset == this.focusOffset\n }\n}\n\nexport class DOMObserver {\n constructor(view, handleDOMChange) {\n this.view = view\n this.handleDOMChange = handleDOMChange\n this.queue = []\n this.flushingSoon = false\n this.observer = window.MutationObserver &&\n new window.MutationObserver(mutations => {\n for (let i = 0; i < mutations.length; i++) this.queue.push(mutations[i])\n // IE11 will sometimes (on backspacing out a single character\n // text node after a BR node) call the observer callback\n // before actually updating the DOM, which will cause\n // ProseMirror to miss the change (see #930)\n if (browser.ie && browser.ie_version <= 11 && mutations.some(\n m => m.type == \"childList\" && m.removedNodes.length ||\n m.type == \"characterData\" && m.oldValue.length > m.target.nodeValue.length))\n this.flushSoon()\n else\n this.flush()\n })\n this.currentSelection = new SelectionState\n if (useCharData) {\n this.onCharData = e => {\n this.queue.push({target: e.target, type: \"characterData\", oldValue: e.prevValue})\n this.flushSoon()\n }\n }\n this.onSelectionChange = this.onSelectionChange.bind(this)\n this.suppressingSelectionUpdates = false\n }\n\n flushSoon() {\n if (!this.flushingSoon) {\n this.flushingSoon = true\n window.setTimeout(() => { this.flushingSoon = false; this.flush() }, 20)\n }\n }\n\n start() {\n if (this.observer)\n this.observer.observe(this.view.dom, observeOptions)\n if (useCharData)\n this.view.dom.addEventListener(\"DOMCharacterDataModified\", this.onCharData)\n this.connectSelection()\n }\n\n stop() {\n if (this.observer) {\n let take = this.observer.takeRecords()\n if (take.length) {\n for (let i = 0; i < take.length; i++) this.queue.push(take[i])\n window.setTimeout(() => this.flush(), 20)\n }\n this.observer.disconnect()\n }\n if (useCharData) this.view.dom.removeEventListener(\"DOMCharacterDataModified\", this.onCharData)\n this.disconnectSelection()\n }\n\n connectSelection() {\n this.view.dom.ownerDocument.addEventListener(\"selectionchange\", this.onSelectionChange)\n }\n\n disconnectSelection() {\n this.view.dom.ownerDocument.removeEventListener(\"selectionchange\", this.onSelectionChange)\n }\n\n suppressSelectionUpdates() {\n this.suppressingSelectionUpdates = true\n setTimeout(() => this.suppressingSelectionUpdates = false, 50)\n }\n\n onSelectionChange() {\n if (!hasFocusAndSelection(this.view)) return\n if (this.suppressingSelectionUpdates) return selectionToDOM(this.view)\n // Deletions on IE11 fire their events in the wrong order, giving\n // us a selection change event before the DOM changes are\n // reported.\n if (browser.ie && browser.ie_version <= 11 && !this.view.state.selection.empty) {\n let sel = this.view.root.getSelection()\n // Selection.isCollapsed isn't reliable on IE\n if (sel.focusNode && isEquivalentPosition(sel.focusNode, sel.focusOffset, sel.anchorNode, sel.anchorOffset))\n return this.flushSoon()\n }\n this.flush()\n }\n\n setCurSelection() {\n this.currentSelection.set(this.view.root.getSelection())\n }\n\n ignoreSelectionChange(sel) {\n if (sel.rangeCount == 0) return true\n let container = sel.getRangeAt(0).commonAncestorContainer\n let desc = this.view.docView.nearestDesc(container)\n return desc && desc.ignoreMutation({type: \"selection\", target: container.nodeType == 3 ? container.parentNode : container})\n }\n\n flush() {\n if (!this.view.docView || this.flushingSoon) return\n let mutations = this.observer ? this.observer.takeRecords() : []\n if (this.queue.length) {\n mutations = this.queue.concat(mutations)\n this.queue.length = 0\n }\n\n let sel = this.view.root.getSelection()\n let newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasSelection(this.view) && !this.ignoreSelectionChange(sel)\n\n let from = -1, to = -1, typeOver = false, added = []\n if (this.view.editable) {\n for (let i = 0; i < mutations.length; i++) {\n let result = this.registerMutation(mutations[i], added)\n if (result) {\n from = from < 0 ? result.from : Math.min(result.from, from)\n to = to < 0 ? result.to : Math.max(result.to, to)\n if (result.typeOver && !this.view.composing) typeOver = true\n }\n }\n }\n\n if (browser.gecko && added.length > 1) {\n let brs = added.filter(n => n.nodeName == \"BR\")\n if (brs.length == 2) {\n let [a, b] = brs\n if (a.parentNode && a.parentNode.parentNode == b.parentNode) b.remove()\n else a.remove()\n }\n }\n\n if (from > -1 || newSel) {\n if (from > -1) {\n this.view.docView.markDirty(from, to)\n checkCSS(this.view)\n }\n this.handleDOMChange(from, to, typeOver)\n if (this.view.docView.dirty) this.view.updateState(this.view.state)\n else if (!this.currentSelection.eq(sel)) selectionToDOM(this.view)\n }\n }\n\n registerMutation(mut, added) {\n // Ignore mutations inside nodes that were already noted as inserted\n if (added.indexOf(mut.target) > -1) return null\n let desc = this.view.docView.nearestDesc(mut.target)\n if (mut.type == \"attributes\" &&\n (desc == this.view.docView || mut.attributeName == \"contenteditable\" ||\n // Firefox sometimes fires spurious events for null/empty styles\n (mut.attributeName == \"style\" && !mut.oldValue && !mut.target.getAttribute(\"style\"))))\n return null\n if (!desc || desc.ignoreMutation(mut)) return null\n\n if (mut.type == \"childList\") {\n let prev = mut.previousSibling, next = mut.nextSibling\n if (browser.ie && browser.ie_version <= 11 && mut.addedNodes.length) {\n // IE11 gives us incorrect next/prev siblings for some\n // insertions, so if there are added nodes, recompute those\n for (let i = 0; i < mut.addedNodes.length; i++) {\n let {previousSibling, nextSibling} = mut.addedNodes[i]\n if (!previousSibling || Array.prototype.indexOf.call(mut.addedNodes, previousSibling) < 0) prev = previousSibling\n if (!nextSibling || Array.prototype.indexOf.call(mut.addedNodes, nextSibling) < 0) next = nextSibling\n }\n }\n let fromOffset = prev && prev.parentNode == mut.target\n ? domIndex(prev) + 1 : 0\n let from = desc.localPosFromDOM(mut.target, fromOffset, -1)\n let toOffset = next && next.parentNode == mut.target\n ? domIndex(next) : mut.target.childNodes.length\n for (let i = 0; i < mut.addedNodes.length; i++) added.push(mut.addedNodes[i])\n let to = desc.localPosFromDOM(mut.target, toOffset, 1)\n return {from, to}\n } else if (mut.type == \"attributes\") {\n return {from: desc.posAtStart - desc.border, to: desc.posAtEnd + desc.border}\n } else { // \"characterData\"\n return {\n from: desc.posAtStart,\n to: desc.posAtEnd,\n // An event was generated for a text change that didn't change\n // any text. Mark the dom change to fall back to assuming the\n // selection was typed over with an identical value if it can't\n // find another change.\n typeOver: mut.target.nodeValue == mut.oldValue\n }\n }\n }\n}\n\nlet cssChecked = false\n\nfunction checkCSS(view) {\n if (cssChecked) return\n cssChecked = true\n if (getComputedStyle(view.dom).whiteSpace == \"normal\")\n console[\"warn\"](\"ProseMirror expects the CSS white-space property to be set, preferably to 'pre-wrap'. It is recommended to load style/prosemirror.css from the prosemirror-view package.\")\n}\n","import {Selection, NodeSelection, TextSelection} from \"prosemirror-state\"\nimport {dropPoint} from \"prosemirror-transform\"\nimport {Slice} from \"prosemirror-model\"\n\nimport browser from \"./browser\"\nimport {captureKeyDown} from \"./capturekeys\"\nimport {readDOMChange} from \"./domchange\"\nimport {parseFromClipboard, serializeForClipboard} from \"./clipboard\"\nimport {DOMObserver} from \"./domobserver\"\nimport {selectionBetween} from \"./selection\"\nimport {keyEvent} from \"./dom\"\n\n// A collection of DOM events that occur within the editor, and callback functions\n// to invoke when the event fires.\nconst handlers = {}, editHandlers = {}\n\nexport function initInput(view) {\n view.shiftKey = false\n view.mouseDown = null\n view.lastKeyCode = null\n view.lastKeyCodeTime = 0\n view.lastClick = {time: 0, x: 0, y: 0, type: \"\"}\n view.lastSelectionOrigin = null\n view.lastSelectionTime = 0\n\n view.composing = false\n view.composingTimeout = null\n view.compositionNodes = []\n view.compositionEndedAt = -2e8\n\n view.domObserver = new DOMObserver(view, (from, to, typeOver) => readDOMChange(view, from, to, typeOver))\n view.domObserver.start()\n // Used by hacks like the beforeinput handler to check whether anything happened in the DOM\n view.domChangeCount = 0\n\n view.eventHandlers = Object.create(null)\n for (let event in handlers) {\n let handler = handlers[event]\n view.dom.addEventListener(event, view.eventHandlers[event] = event => {\n if (eventBelongsToView(view, event) && !runCustomHandler(view, event) &&\n (view.editable || !(event.type in editHandlers)))\n handler(view, event)\n })\n }\n // On Safari, for reasons beyond my understanding, adding an input\n // event handler makes an issue where the composition vanishes when\n // you press enter go away.\n if (browser.safari) view.dom.addEventListener(\"input\", () => null)\n\n ensureListeners(view)\n}\n\nfunction setSelectionOrigin(view, origin) {\n view.lastSelectionOrigin = origin\n view.lastSelectionTime = Date.now()\n}\n\nexport function destroyInput(view) {\n view.domObserver.stop()\n for (let type in view.eventHandlers)\n view.dom.removeEventListener(type, view.eventHandlers[type])\n clearTimeout(view.composingTimeout)\n}\n\nexport function ensureListeners(view) {\n view.someProp(\"handleDOMEvents\", currentHandlers => {\n for (let type in currentHandlers) if (!view.eventHandlers[type])\n view.dom.addEventListener(type, view.eventHandlers[type] = event => runCustomHandler(view, event))\n })\n}\n\nfunction runCustomHandler(view, event) {\n return view.someProp(\"handleDOMEvents\", handlers => {\n let handler = handlers[event.type]\n return handler ? handler(view, event) || event.defaultPrevented : false\n })\n}\n\nfunction eventBelongsToView(view, event) {\n if (!event.bubbles) return true\n if (event.defaultPrevented) return false\n for (let node = event.target; node != view.dom; node = node.parentNode)\n if (!node || node.nodeType == 11 ||\n (node.pmViewDesc && node.pmViewDesc.stopEvent(event)))\n return false\n return true\n}\n\nexport function dispatchEvent(view, event) {\n if (!runCustomHandler(view, event) && handlers[event.type] &&\n (view.editable || !(event.type in editHandlers)))\n handlers[event.type](view, event)\n}\n\neditHandlers.keydown = (view, event) => {\n view.shiftKey = event.keyCode == 16 || event.shiftKey\n if (inOrNearComposition(view, event)) return\n view.lastKeyCode = event.keyCode\n view.lastKeyCodeTime = Date.now()\n if (view.someProp(\"handleKeyDown\", f => f(view, event)) || captureKeyDown(view, event))\n event.preventDefault()\n else\n setSelectionOrigin(view, \"key\")\n}\n\neditHandlers.keyup = (view, e) => {\n if (e.keyCode == 16) view.shiftKey = false\n}\n\neditHandlers.keypress = (view, event) => {\n if (inOrNearComposition(view, event) || !event.charCode ||\n event.ctrlKey && !event.altKey || browser.mac && event.metaKey) return\n\n if (view.someProp(\"handleKeyPress\", f => f(view, event))) {\n event.preventDefault()\n return\n }\n\n let sel = view.state.selection\n if (!(sel instanceof TextSelection) || !sel.$from.sameParent(sel.$to)) {\n let text = String.fromCharCode(event.charCode)\n if (!view.someProp(\"handleTextInput\", f => f(view, sel.$from.pos, sel.$to.pos, text)))\n view.dispatch(view.state.tr.insertText(text).scrollIntoView())\n event.preventDefault()\n }\n}\n\nfunction eventCoords(event) { return {left: event.clientX, top: event.clientY} }\n\nfunction isNear(event, click) {\n let dx = click.x - event.clientX, dy = click.y - event.clientY\n return dx * dx + dy * dy < 100\n}\n\nfunction runHandlerOnContext(view, propName, pos, inside, event) {\n if (inside == -1) return false\n let $pos = view.state.doc.resolve(inside)\n for (let i = $pos.depth + 1; i > 0; i--) {\n if (view.someProp(propName, f => i > $pos.depth ? f(view, pos, $pos.nodeAfter, $pos.before(i), event, true)\n : f(view, pos, $pos.node(i), $pos.before(i), event, false)))\n return true\n }\n return false\n}\n\nfunction updateSelection(view, selection, origin) {\n if (!view.focused) view.focus()\n let tr = view.state.tr.setSelection(selection)\n if (origin == \"pointer\") tr.setMeta(\"pointer\", true)\n view.dispatch(tr)\n}\n\nfunction selectClickedLeaf(view, inside) {\n if (inside == -1) return false\n let $pos = view.state.doc.resolve(inside), node = $pos.nodeAfter\n if (node && node.isAtom && NodeSelection.isSelectable(node)) {\n updateSelection(view, new NodeSelection($pos), \"pointer\")\n return true\n }\n return false\n}\n\nfunction selectClickedNode(view, inside) {\n if (inside == -1) return false\n let sel = view.state.selection, selectedNode, selectAt\n if (sel instanceof NodeSelection) selectedNode = sel.node\n\n let $pos = view.state.doc.resolve(inside)\n for (let i = $pos.depth + 1; i > 0; i--) {\n let node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i)\n if (NodeSelection.isSelectable(node)) {\n if (selectedNode && sel.$from.depth > 0 &&\n i >= sel.$from.depth && $pos.before(sel.$from.depth + 1) == sel.$from.pos)\n selectAt = $pos.before(sel.$from.depth)\n else\n selectAt = $pos.before(i)\n break\n }\n }\n\n if (selectAt != null) {\n updateSelection(view, NodeSelection.create(view.state.doc, selectAt), \"pointer\")\n return true\n } else {\n return false\n }\n}\n\nfunction handleSingleClick(view, pos, inside, event, selectNode) {\n return runHandlerOnContext(view, \"handleClickOn\", pos, inside, event) ||\n view.someProp(\"handleClick\", f => f(view, pos, event)) ||\n (selectNode ? selectClickedNode(view, inside) : selectClickedLeaf(view, inside))\n}\n\nfunction handleDoubleClick(view, pos, inside, event) {\n return runHandlerOnContext(view, \"handleDoubleClickOn\", pos, inside, event) ||\n view.someProp(\"handleDoubleClick\", f => f(view, pos, event))\n}\n\nfunction handleTripleClick(view, pos, inside, event) {\n return runHandlerOnContext(view, \"handleTripleClickOn\", pos, inside, event) ||\n view.someProp(\"handleTripleClick\", f => f(view, pos, event)) ||\n defaultTripleClick(view, inside)\n}\n\nfunction defaultTripleClick(view, inside) {\n let doc = view.state.doc\n if (inside == -1) {\n if (doc.inlineContent) {\n updateSelection(view, TextSelection.create(doc, 0, doc.content.size), \"pointer\")\n return true\n }\n return false\n }\n\n let $pos = doc.resolve(inside)\n for (let i = $pos.depth + 1; i > 0; i--) {\n let node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i)\n let nodePos = $pos.before(i)\n if (node.inlineContent)\n updateSelection(view, TextSelection.create(doc, nodePos + 1, nodePos + 1 + node.content.size), \"pointer\")\n else if (NodeSelection.isSelectable(node))\n updateSelection(view, NodeSelection.create(doc, nodePos), \"pointer\")\n else\n continue\n return true\n }\n}\n\nfunction forceDOMFlush(view) {\n return endComposition(view)\n}\n\nconst selectNodeModifier = browser.mac ? \"metaKey\" : \"ctrlKey\"\n\nhandlers.mousedown = (view, event) => {\n view.shiftKey = event.shiftKey\n let flushed = forceDOMFlush(view)\n let now = Date.now(), type = \"singleClick\"\n if (now - view.lastClick.time < 500 && isNear(event, view.lastClick) && !event[selectNodeModifier]) {\n if (view.lastClick.type == \"singleClick\") type = \"doubleClick\"\n else if (view.lastClick.type == \"doubleClick\") type = \"tripleClick\"\n }\n view.lastClick = {time: now, x: event.clientX, y: event.clientY, type}\n\n let pos = view.posAtCoords(eventCoords(event))\n if (!pos) return\n\n if (type == \"singleClick\")\n view.mouseDown = new MouseDown(view, pos, event, flushed)\n else if ((type == \"doubleClick\" ? handleDoubleClick : handleTripleClick)(view, pos.pos, pos.inside, event))\n event.preventDefault()\n else\n setSelectionOrigin(view, \"pointer\")\n}\n\nclass MouseDown {\n constructor(view, pos, event, flushed) {\n this.view = view\n this.startDoc = view.state.doc\n this.pos = pos\n this.event = event\n this.flushed = flushed\n this.selectNode = event[selectNodeModifier]\n this.allowDefault = event.shiftKey\n\n let targetNode, targetPos\n if (pos.inside > -1) {\n targetNode = view.state.doc.nodeAt(pos.inside)\n targetPos = pos.inside\n } else {\n let $pos = view.state.doc.resolve(pos.pos)\n targetNode = $pos.parent\n targetPos = $pos.depth ? $pos.before() : 0\n }\n\n this.mightDrag = null\n\n const target = flushed ? null : event.target\n const targetDesc = target ? view.docView.nearestDesc(target, true) : null\n this.target = targetDesc ? targetDesc.dom : null\n\n if (targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false ||\n view.state.selection instanceof NodeSelection && targetPos == view.state.selection.from)\n this.mightDrag = {node: targetNode,\n pos: targetPos,\n addAttr: this.target && !this.target.draggable,\n setUneditable: this.target && browser.gecko && !this.target.hasAttribute(\"contentEditable\")}\n\n if (this.target && this.mightDrag && (this.mightDrag.addAttr || this.mightDrag.setUneditable)) {\n this.view.domObserver.stop()\n if (this.mightDrag.addAttr) this.target.draggable = true\n if (this.mightDrag.setUneditable)\n setTimeout(() => this.target.setAttribute(\"contentEditable\", \"false\"), 20)\n this.view.domObserver.start()\n }\n\n view.root.addEventListener(\"mouseup\", this.up = this.up.bind(this))\n view.root.addEventListener(\"mousemove\", this.move = this.move.bind(this))\n setSelectionOrigin(view, \"pointer\")\n }\n\n done() {\n this.view.root.removeEventListener(\"mouseup\", this.up)\n this.view.root.removeEventListener(\"mousemove\", this.move)\n if (this.mightDrag && this.target) {\n this.view.domObserver.stop()\n if (this.mightDrag.addAttr) this.target.draggable = false\n if (this.mightDrag.setUneditable) this.target.removeAttribute(\"contentEditable\")\n this.view.domObserver.start()\n }\n this.view.mouseDown = null\n }\n\n up(event) {\n this.done()\n\n if (!this.view.dom.contains(event.target.nodeType == 3 ? event.target.parentNode : event.target))\n return\n\n let pos = this.pos\n if (this.view.state.doc != this.startDoc) pos = this.view.posAtCoords(eventCoords(event))\n\n if (this.allowDefault || !pos) {\n setSelectionOrigin(this.view, \"pointer\")\n } else if (handleSingleClick(this.view, pos.pos, pos.inside, event, this.selectNode)) {\n event.preventDefault()\n } else if (this.flushed ||\n // Chrome will sometimes treat a node selection as a\n // cursor, but still report that the node is selected\n // when asked through getSelection. You'll then get a\n // situation where clicking at the point where that\n // (hidden) cursor is doesn't change the selection, and\n // thus doesn't get a reaction from ProseMirror. This\n // works around that.\n (browser.chrome && !(this.view.state.selection instanceof TextSelection) &&\n (pos.pos == this.view.state.selection.from || pos.pos == this.view.state.selection.to))) {\n updateSelection(this.view, Selection.near(this.view.state.doc.resolve(pos.pos)), \"pointer\")\n event.preventDefault()\n } else {\n setSelectionOrigin(this.view, \"pointer\")\n }\n }\n\n move(event) {\n if (!this.allowDefault && (Math.abs(this.event.x - event.clientX) > 4 ||\n Math.abs(this.event.y - event.clientY) > 4))\n this.allowDefault = true\n setSelectionOrigin(this.view, \"pointer\")\n }\n}\n\nhandlers.touchdown = view => {\n forceDOMFlush(view)\n setSelectionOrigin(view, \"pointer\")\n}\n\nhandlers.contextmenu = view => forceDOMFlush(view)\n\nfunction inOrNearComposition(view, event) {\n if (view.composing) return true\n // See https://www.stum.de/2016/06/24/handling-ime-events-in-javascript/.\n // On Japanese input method editors (IMEs), the Enter key is used to confirm character\n // selection. On Safari, when Enter is pressed, compositionend and keydown events are\n // emitted. The keydown event triggers newline insertion, which we don't want.\n // This method returns true if the keydown event should be ignored.\n // We only ignore it once, as pressing Enter a second time *should* insert a newline.\n // Furthermore, the keydown event timestamp must be close to the compositionEndedAt timestamp.\n // This guards against the case where compositionend is triggered without the keyboard\n // (e.g. character confirmation may be done with the mouse), and keydown is triggered\n // afterwards- we wouldn't want to ignore the keydown event in this case.\n if (browser.safari && Math.abs(event.timeStamp - view.compositionEndedAt) < 500) {\n view.compositionEndedAt = -2e8\n return true\n }\n return false\n}\n\n// Drop active composition after 5 seconds of inactivity on Android\nconst timeoutComposition = browser.android ? 5000 : -1\n\neditHandlers.compositionstart = editHandlers.compositionupdate = view => {\n if (!view.composing) {\n view.domObserver.flush()\n let {state} = view, $pos = state.selection.$from\n if (state.selection.empty &&\n (state.storedMarks || (!$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some(m => m.type.spec.inclusive === false)))) {\n // Need to wrap the cursor in mark nodes different from the ones in the DOM context\n view.markCursor = view.state.storedMarks || $pos.marks()\n endComposition(view, true)\n view.markCursor = null\n } else {\n endComposition(view)\n // In firefox, if the cursor is after but outside a marked node,\n // the inserted text won't inherit the marks. So this moves it\n // inside if necessary.\n if (browser.gecko && state.selection.empty && $pos.parentOffset && !$pos.textOffset && $pos.nodeBefore.marks.length) {\n let sel = view.root.getSelection()\n for (let node = sel.focusNode, offset = sel.focusOffset; node && node.nodeType == 1 && offset != 0;) {\n let before = offset < 0 ? node.lastChild : node.childNodes[offset - 1]\n if (before.nodeType == 3) {\n sel.collapse(before, before.nodeValue.length)\n break\n } else {\n node = before\n offset = -1\n }\n }\n }\n }\n view.composing = true\n }\n scheduleComposeEnd(view, timeoutComposition)\n}\n\neditHandlers.compositionend = (view, event) => {\n if (view.composing) {\n view.composing = false\n view.compositionEndedAt = event.timeStamp\n scheduleComposeEnd(view, 20)\n }\n}\n\nfunction scheduleComposeEnd(view, delay) {\n clearTimeout(view.composingTimeout)\n if (delay > -1) view.composingTimeout = setTimeout(() => endComposition(view), delay)\n}\n\nexport function endComposition(view, forceUpdate) {\n view.composing = false\n while (view.compositionNodes.length > 0) view.compositionNodes.pop().markParentsDirty()\n if (forceUpdate || view.docView.dirty) {\n view.updateState(view.state)\n return true\n }\n return false\n}\n\nfunction captureCopy(view, dom) {\n // The extra wrapper is somehow necessary on IE/Edge to prevent the\n // content from being mangled when it is put onto the clipboard\n let doc = view.dom.ownerDocument\n let wrap = doc.body.appendChild(doc.createElement(\"div\"))\n wrap.appendChild(dom)\n wrap.style.cssText = \"position: fixed; left: -10000px; top: 10px\"\n let sel = getSelection(), range = doc.createRange()\n range.selectNodeContents(dom)\n // Done because IE will fire a selectionchange moving the selection\n // to its start when removeAllRanges is called and the editor still\n // has focus (which will mess up the editor's selection state).\n view.dom.blur()\n sel.removeAllRanges()\n sel.addRange(range)\n setTimeout(() => {\n doc.body.removeChild(wrap)\n view.focus()\n }, 50)\n}\n\n// This is very crude, but unfortunately both these browsers _pretend_\n// that they have a clipboard API—all the objects and methods are\n// there, they just don't work, and they are hard to test.\nconst brokenClipboardAPI = (browser.ie && browser.ie_version < 15) ||\n (browser.ios && browser.webkit_version < 604)\n\nhandlers.copy = editHandlers.cut = (view, e) => {\n let sel = view.state.selection, cut = e.type == \"cut\"\n if (sel.empty) return\n\n // IE and Edge's clipboard interface is completely broken\n let data = brokenClipboardAPI ? null : e.clipboardData\n let slice = sel.content(), {dom, text} = serializeForClipboard(view, slice)\n if (data) {\n e.preventDefault()\n data.clearData()\n data.setData(\"text/html\", dom.innerHTML)\n data.setData(\"text/plain\", text)\n } else {\n captureCopy(view, dom)\n }\n if (cut) view.dispatch(view.state.tr.deleteSelection().scrollIntoView().setMeta(\"uiEvent\", \"cut\"))\n}\n\nfunction sliceSingleNode(slice) {\n return slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1 ? slice.content.firstChild : null\n}\n\nfunction capturePaste(view, e) {\n let doc = view.dom.ownerDocument\n let plainText = view.shiftKey || view.state.selection.$from.parent.type.spec.code\n let target = doc.body.appendChild(doc.createElement(plainText ? \"textarea\" : \"div\"))\n if (!plainText) target.contentEditable = \"true\"\n target.style.cssText = \"position: fixed; left: -10000px; top: 10px\"\n target.focus()\n setTimeout(() => {\n view.focus()\n doc.body.removeChild(target)\n if (plainText) doPaste(view, target.value, null, e)\n else doPaste(view, target.textContent, target.innerHTML, e)\n }, 50)\n}\n\nfunction doPaste(view, text, html, e) {\n let slice = parseFromClipboard(view, text, html, view.shiftKey, view.state.selection.$from)\n if (view.someProp(\"handlePaste\", f => f(view, e, slice || Slice.empty)) || !slice) return\n\n let singleNode = sliceSingleNode(slice)\n let tr = singleNode ? view.state.tr.replaceSelectionWith(singleNode, view.shiftKey) : view.state.tr.replaceSelection(slice)\n view.dispatch(tr.scrollIntoView().setMeta(\"paste\", true).setMeta(\"uiEvent\", \"paste\"))\n}\n\neditHandlers.paste = (view, e) => {\n let data = brokenClipboardAPI ? null : e.clipboardData\n let html = data && data.getData(\"text/html\"), text = data && data.getData(\"text/plain\")\n if (data && (html || text || data.files.length)) {\n doPaste(view, text, html, e)\n e.preventDefault()\n } else {\n capturePaste(view, e)\n }\n}\n\nclass Dragging {\n constructor(slice, move) {\n this.slice = slice\n this.move = move\n }\n}\n\nconst dragCopyModifier = browser.mac ? \"altKey\" : \"ctrlKey\"\n\nhandlers.dragstart = (view, e) => {\n let mouseDown = view.mouseDown\n if (mouseDown) mouseDown.done()\n if (!e.dataTransfer) return\n\n let sel = view.state.selection\n let pos = sel.empty ? null : view.posAtCoords(eventCoords(e))\n if (pos && pos.pos >= sel.from && pos.pos <= (sel instanceof NodeSelection ? sel.to - 1: sel.to)) {\n // In selection\n } else if (mouseDown && mouseDown.mightDrag) {\n view.dispatch(view.state.tr.setSelection(NodeSelection.create(view.state.doc, mouseDown.mightDrag.pos)))\n } else if (e.target && e.target.nodeType == 1) {\n let desc = view.docView.nearestDesc(e.target, true)\n if (!desc || !desc.node.type.spec.draggable || desc == view.docView) return\n view.dispatch(view.state.tr.setSelection(NodeSelection.create(view.state.doc, desc.posBefore)))\n }\n let slice = view.state.selection.content(), {dom, text} = serializeForClipboard(view, slice)\n e.dataTransfer.clearData()\n e.dataTransfer.setData(brokenClipboardAPI ? \"Text\" : \"text/html\", dom.innerHTML)\n if (!brokenClipboardAPI) e.dataTransfer.setData(\"text/plain\", text)\n view.dragging = new Dragging(slice, !e[dragCopyModifier])\n}\n\nhandlers.dragend = view => {\n window.setTimeout(() => view.dragging = null, 50)\n}\n\neditHandlers.dragover = editHandlers.dragenter = (_, e) => e.preventDefault()\n\neditHandlers.drop = (view, e) => {\n let dragging = view.dragging\n view.dragging = null\n\n if (!e.dataTransfer) return\n\n let eventPos = view.posAtCoords(eventCoords(e))\n if (!eventPos) return\n let $mouse = view.state.doc.resolve(eventPos.pos)\n if (!$mouse) return\n let slice = dragging && dragging.slice ||\n parseFromClipboard(view, e.dataTransfer.getData(brokenClipboardAPI ? \"Text\" : \"text/plain\"),\n brokenClipboardAPI ? null : e.dataTransfer.getData(\"text/html\"), false, $mouse)\n if (!slice) return\n\n e.preventDefault()\n if (view.someProp(\"handleDrop\", f => f(view, e, slice, dragging && dragging.move))) return\n let insertPos = slice ? dropPoint(view.state.doc, $mouse.pos, slice) : $mouse.pos\n if (insertPos == null) insertPos = $mouse.pos\n\n let tr = view.state.tr\n if (dragging && dragging.move) tr.deleteSelection()\n\n let pos = tr.mapping.map(insertPos)\n let isNode = slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1\n let beforeInsert = tr.doc\n if (isNode)\n tr.replaceRangeWith(pos, pos, slice.content.firstChild)\n else\n tr.replaceRange(pos, pos, slice)\n if (tr.doc.eq(beforeInsert)) return\n\n let $pos = tr.doc.resolve(pos)\n if (isNode && NodeSelection.isSelectable(slice.content.firstChild) &&\n $pos.nodeAfter && $pos.nodeAfter.sameMarkup(slice.content.firstChild))\n tr.setSelection(new NodeSelection($pos))\n else\n tr.setSelection(selectionBetween(view, $pos, tr.doc.resolve(tr.mapping.map(insertPos))))\n view.focus()\n view.dispatch(tr.setMeta(\"uiEvent\", \"drop\"))\n}\n\nhandlers.focus = view => {\n if (!view.focused) {\n view.domObserver.stop()\n view.dom.classList.add(\"ProseMirror-focused\")\n view.domObserver.start()\n view.focused = true\n }\n}\n\nhandlers.blur = view => {\n if (view.focused) {\n view.domObserver.stop()\n view.dom.classList.remove(\"ProseMirror-focused\")\n view.domObserver.start()\n view.domObserver.currentSelection.set({})\n view.focused = false\n }\n}\n\nhandlers.beforeinput = (view, event) => {\n // We should probably do more with beforeinput events, but support\n // is so spotty that I'm still waiting to see where they are going.\n\n // Very specific hack to deal with backspace sometimes failing on\n // Chrome Android when after an uneditable node.\n if (browser.chrome && browser.android && event.inputType == \"deleteContentBackward\") {\n let {domChangeCount} = view\n setTimeout(() => {\n if (view.domChangeCount != domChangeCount) return // Event already had some effect\n // This bug tends to close the virtual keyboard, so we refocus\n view.dom.blur()\n view.focus()\n if (view.someProp(\"handleKeyDown\", f => f(view, keyEvent(8, \"Backspace\")))) return\n let {$cursor} = view.state.selection\n // Crude approximation of backspace behavior when no command handled it\n if ($cursor && $cursor.pos > 0) view.dispatch(view.state.tr.delete($cursor.pos - 1, $cursor.pos).scrollIntoView())\n }, 50)\n }\n}\n\n// Make sure all handlers get registered\nfor (let prop in editHandlers) handlers[prop] = editHandlers[prop]\n","function compareObjs(a, b) {\n if (a == b) return true\n for (let p in a) if (a[p] !== b[p]) return false\n for (let p in b) if (!(p in a)) return false\n return true\n}\n\nclass WidgetType {\n constructor(toDOM, spec) {\n this.spec = spec || noSpec\n this.side = this.spec.side || 0\n this.toDOM = toDOM\n }\n\n map(mapping, span, offset, oldOffset) {\n let {pos, deleted} = mapping.mapResult(span.from + oldOffset, this.side < 0 ? -1 : 1)\n return deleted ? null : new Decoration(pos - offset, pos - offset, this)\n }\n\n valid() { return true }\n\n eq(other) {\n return this == other ||\n (other instanceof WidgetType &&\n (this.spec.key && this.spec.key == other.spec.key ||\n this.toDOM == other.toDOM && compareObjs(this.spec, other.spec)))\n }\n}\n\nclass InlineType {\n constructor(attrs, spec) {\n this.spec = spec || noSpec\n this.attrs = attrs\n }\n\n map(mapping, span, offset, oldOffset) {\n let from = mapping.map(span.from + oldOffset, this.spec.inclusiveStart ? -1 : 1) - offset\n let to = mapping.map(span.to + oldOffset, this.spec.inclusiveEnd ? 1 : -1) - offset\n return from >= to ? null : new Decoration(from, to, this)\n }\n\n valid(_, span) { return span.from < span.to }\n\n eq(other) {\n return this == other ||\n (other instanceof InlineType && compareObjs(this.attrs, other.attrs) &&\n compareObjs(this.spec, other.spec))\n }\n\n static is(span) { return span.type instanceof InlineType }\n}\n\nclass NodeType {\n constructor(attrs, spec) {\n this.spec = spec || noSpec\n this.attrs = attrs\n }\n\n map(mapping, span, offset, oldOffset) {\n let from = mapping.mapResult(span.from + oldOffset, 1)\n if (from.deleted) return null\n let to = mapping.mapResult(span.to + oldOffset, -1)\n if (to.deleted || to.pos <= from.pos) return null\n return new Decoration(from.pos - offset, to.pos - offset, this)\n }\n\n valid(node, span) {\n let {index, offset} = node.content.findIndex(span.from)\n return offset == span.from && offset + node.child(index).nodeSize == span.to\n }\n\n eq(other) {\n return this == other ||\n (other instanceof NodeType && compareObjs(this.attrs, other.attrs) &&\n compareObjs(this.spec, other.spec))\n }\n}\n\n// ::- Decoration objects can be provided to the view through the\n// [`decorations` prop](#view.EditorProps.decorations). They come in\n// several variants—see the static members of this class for details.\nexport class Decoration {\n constructor(from, to, type) {\n // :: number\n // The start position of the decoration.\n this.from = from\n // :: number\n // The end position. Will be the same as `from` for [widget\n // decorations](#view.Decoration^widget).\n this.to = to\n this.type = type\n }\n\n copy(from, to) {\n return new Decoration(from, to, this.type)\n }\n\n eq(other) {\n return this.type.eq(other.type) && this.from == other.from && this.to == other.to\n }\n\n map(mapping, offset, oldOffset) {\n return this.type.map(mapping, this, offset, oldOffset)\n }\n\n // :: (number, union<(view: EditorView, getPos: () → number) → dom.Node, dom.Node>, ?Object) → Decoration\n // Creates a widget decoration, which is a DOM node that's shown in\n // the document at the given position. It is recommended that you\n // delay rendering the widget by passing a function that will be\n // called when the widget is actually drawn in a view, but you can\n // also directly pass a DOM node. `getPos` can be used to find the\n // widget's current document position.\n //\n // spec::- These options are supported:\n //\n // side:: ?number\n // Controls which side of the document position this widget is\n // associated with. When negative, it is drawn before a cursor\n // at its position, and content inserted at that position ends\n // up after the widget. When zero (the default) or positive, the\n // widget is drawn after the cursor and content inserted there\n // ends up before the widget.\n //\n // When there are multiple widgets at a given position, their\n // `side` values determine the order in which they appear. Those\n // with lower values appear first. The ordering of widgets with\n // the same `side` value is unspecified.\n //\n // When `marks` is null, `side` also determines the marks that\n // the widget is wrapped in—those of the node before when\n // negative, those of the node after when positive.\n //\n // marks:: ?[Mark]\n // The precise set of marks to draw around the widget.\n //\n // stopEvent:: ?(event: dom.Event) → bool\n // Can be used to control which DOM events, when they bubble out\n // of this widget, the editor view should ignore.\n //\n // key:: ?string\n // When comparing decorations of this type (in order to decide\n // whether it needs to be redrawn), ProseMirror will by default\n // compare the widget DOM node by identity. If you pass a key,\n // that key will be compared instead, which can be useful when\n // you generate decorations on the fly and don't want to store\n // and reuse DOM nodes. Make sure that any widgets with the same\n // key are interchangeable—if widgets differ in, for example,\n // the behavior of some event handler, they should get\n // different keys.\n static widget(pos, toDOM, spec) {\n return new Decoration(pos, pos, new WidgetType(toDOM, spec))\n }\n\n // :: (number, number, DecorationAttrs, ?Object) → Decoration\n // Creates an inline decoration, which adds the given attributes to\n // each inline node between `from` and `to`.\n //\n // spec::- These options are recognized:\n //\n // inclusiveStart:: ?bool\n // Determines how the left side of the decoration is\n // [mapped](#transform.Position_Mapping) when content is\n // inserted directly at that position. By default, the decoration\n // won't include the new content, but you can set this to `true`\n // to make it inclusive.\n //\n // inclusiveEnd:: ?bool\n // Determines how the right side of the decoration is mapped.\n // See\n // [`inclusiveStart`](#view.Decoration^inline^spec.inclusiveStart).\n static inline(from, to, attrs, spec) {\n return new Decoration(from, to, new InlineType(attrs, spec))\n }\n\n // :: (number, number, DecorationAttrs, ?Object) → Decoration\n // Creates a node decoration. `from` and `to` should point precisely\n // before and after a node in the document. That node, and only that\n // node, will receive the given attributes.\n //\n // spec::-\n //\n // Optional information to store with the decoration. It\n // is also used when comparing decorators for equality.\n static node(from, to, attrs, spec) {\n return new Decoration(from, to, new NodeType(attrs, spec))\n }\n\n // :: Object\n // The spec provided when creating this decoration. Can be useful\n // if you've stored extra information in that object.\n get spec() { return this.type.spec }\n}\n\n// DecorationAttrs:: interface\n// A set of attributes to add to a decorated node. Most properties\n// simply directly correspond to DOM attributes of the same name,\n// which will be set to the property's value. These are exceptions:\n//\n// class:: ?string\n// A CSS class name or a space-separated set of class names to be\n// _added_ to the classes that the node already had.\n//\n// style:: ?string\n// A string of CSS to be _added_ to the node's existing `style` property.\n//\n// nodeName:: ?string\n// When non-null, the target node is wrapped in a DOM element of\n// this type (and the other attributes are applied to this element).\n\nconst none = [], noSpec = {}\n\n// ::- A collection of [decorations](#view.Decoration), organized in\n// such a way that the drawing algorithm can efficiently use and\n// compare them. This is a persistent data structure—it is not\n// modified, updates create a new value.\nexport class DecorationSet {\n constructor(local, children) {\n this.local = local && local.length ? local : none\n this.children = children && children.length ? children : none\n }\n\n // :: (Node, [Decoration]) → DecorationSet\n // Create a set of decorations, using the structure of the given\n // document.\n static create(doc, decorations) {\n return decorations.length ? buildTree(decorations, doc, 0, noSpec) : empty\n }\n\n // :: (?number, ?number, ?(spec: Object) → bool) → [Decoration]\n // Find all decorations in this set which touch the given range\n // (including decorations that start or end directly at the\n // boundaries) and match the given predicate on their spec. When\n // `start` and `end` are omitted, all decorations in the set are\n // considered. When `predicate` isn't given, all decorations are\n // assumed to match.\n find(start, end, predicate) {\n let result = []\n this.findInner(start == null ? 0 : start, end == null ? 1e9 : end, result, 0, predicate)\n return result\n }\n\n findInner(start, end, result, offset, predicate) {\n for (let i = 0; i < this.local.length; i++) {\n let span = this.local[i]\n if (span.from <= end && span.to >= start && (!predicate || predicate(span.spec)))\n result.push(span.copy(span.from + offset, span.to + offset))\n }\n for (let i = 0; i < this.children.length; i += 3) {\n if (this.children[i] < end && this.children[i + 1] > start) {\n let childOff = this.children[i] + 1\n this.children[i + 2].findInner(start - childOff, end - childOff, result, offset + childOff, predicate)\n }\n }\n }\n\n // :: (Mapping, Node, ?Object) → DecorationSet\n // Map the set of decorations in response to a change in the\n // document.\n //\n // options::- An optional set of options.\n //\n // onRemove:: ?(decorationSpec: Object)\n // When given, this function will be called for each decoration\n // that gets dropped as a result of the mapping, passing the\n // spec of that decoration.\n map(mapping, doc, options) {\n if (this == empty || mapping.maps.length == 0) return this\n return this.mapInner(mapping, doc, 0, 0, options || noSpec)\n }\n\n mapInner(mapping, node, offset, oldOffset, options) {\n let newLocal\n for (let i = 0; i < this.local.length; i++) {\n let mapped = this.local[i].map(mapping, offset, oldOffset)\n if (mapped && mapped.type.valid(node, mapped)) (newLocal || (newLocal = [])).push(mapped)\n else if (options.onRemove) options.onRemove(this.local[i].spec)\n }\n\n if (this.children.length)\n return mapChildren(this.children, newLocal, mapping, node, offset, oldOffset, options)\n else\n return newLocal ? new DecorationSet(newLocal.sort(byPos)) : empty\n }\n\n // :: (Node, [Decoration]) → DecorationSet\n // Add the given array of decorations to the ones in the set,\n // producing a new set. Needs access to the current document to\n // create the appropriate tree structure.\n add(doc, decorations) {\n if (!decorations.length) return this\n if (this == empty) return DecorationSet.create(doc, decorations)\n return this.addInner(doc, decorations, 0)\n }\n\n addInner(doc, decorations, offset) {\n let children, childIndex = 0\n doc.forEach((childNode, childOffset) => {\n let baseOffset = childOffset + offset, found\n if (!(found = takeSpansForNode(decorations, childNode, baseOffset))) return\n\n if (!children) children = this.children.slice()\n while (childIndex < children.length && children[childIndex] < childOffset) childIndex += 3\n if (children[childIndex] == childOffset)\n children[childIndex + 2] = children[childIndex + 2].addInner(childNode, found, baseOffset + 1)\n else\n children.splice(childIndex, 0, childOffset, childOffset + childNode.nodeSize, buildTree(found, childNode, baseOffset + 1, noSpec))\n childIndex += 3\n })\n\n let local = moveSpans(childIndex ? withoutNulls(decorations) : decorations, -offset)\n return new DecorationSet(local.length ? this.local.concat(local).sort(byPos) : this.local,\n children || this.children)\n }\n\n // :: ([Decoration]) → DecorationSet\n // Create a new set that contains the decorations in this set, minus\n // the ones in the given array.\n remove(decorations) {\n if (decorations.length == 0 || this == empty) return this\n return this.removeInner(decorations, 0)\n }\n\n removeInner(decorations, offset) {\n let children = this.children, local = this.local\n for (let i = 0; i < children.length; i += 3) {\n let found, from = children[i] + offset, to = children[i + 1] + offset\n for (let j = 0, span; j < decorations.length; j++) if (span = decorations[j]) {\n if (span.from > from && span.to < to) {\n decorations[j] = null\n ;(found || (found = [])).push(span)\n }\n }\n if (!found) continue\n if (children == this.children) children = this.children.slice()\n let removed = children[i + 2].removeInner(found, from + 1)\n if (removed != empty) {\n children[i + 2] = removed\n } else {\n children.splice(i, 3)\n i -= 3\n }\n }\n if (local.length) for (let i = 0, span; i < decorations.length; i++) if (span = decorations[i]) {\n for (let j = 0; j < local.length; j++) if (local[j].type.eq(span.type)) {\n if (local == this.local) local = this.local.slice()\n local.splice(j--, 1)\n }\n }\n if (children == this.children && local == this.local) return this\n return local.length || children.length ? new DecorationSet(local, children) : empty\n }\n\n forChild(offset, node) {\n if (this == empty) return this\n if (node.isLeaf) return DecorationSet.empty\n\n let child, local\n for (let i = 0; i < this.children.length; i += 3) if (this.children[i] >= offset) {\n if (this.children[i] == offset) child = this.children[i + 2]\n break\n }\n let start = offset + 1, end = start + node.content.size\n for (let i = 0; i < this.local.length; i++) {\n let dec = this.local[i]\n if (dec.from < end && dec.to > start && (dec.type instanceof InlineType)) {\n let from = Math.max(start, dec.from) - start, to = Math.min(end, dec.to) - start\n if (from < to) (local || (local = [])).push(dec.copy(from, to))\n }\n }\n if (local) {\n let localSet = new DecorationSet(local.sort(byPos))\n return child ? new DecorationGroup([localSet, child]) : localSet\n }\n return child || empty\n }\n\n eq(other) {\n if (this == other) return true\n if (!(other instanceof DecorationSet) ||\n this.local.length != other.local.length ||\n this.children.length != other.children.length) return false\n for (let i = 0; i < this.local.length; i++)\n if (!this.local[i].eq(other.local[i])) return false\n for (let i = 0; i < this.children.length; i += 3)\n if (this.children[i] != other.children[i] ||\n this.children[i + 1] != other.children[i + 1] ||\n !this.children[i + 2].eq(other.children[i + 2])) return false\n return true\n }\n\n locals(node) {\n return removeOverlap(this.localsInner(node))\n }\n\n localsInner(node) {\n if (this == empty) return none\n if (node.inlineContent || !this.local.some(InlineType.is)) return this.local\n let result = []\n for (let i = 0; i < this.local.length; i++) {\n if (!(this.local[i].type instanceof InlineType))\n result.push(this.local[i])\n }\n return result\n }\n}\n\nconst empty = new DecorationSet()\n\n// :: DecorationSet\n// The empty set of decorations.\nDecorationSet.empty = empty\n\nDecorationSet.removeOverlap = removeOverlap\n\n// :- An abstraction that allows the code dealing with decorations to\n// treat multiple DecorationSet objects as if it were a single object\n// with (a subset of) the same interface.\nclass DecorationGroup {\n constructor(members) {\n this.members = members\n }\n\n forChild(offset, child) {\n if (child.isLeaf) return DecorationSet.empty\n let found = []\n for (let i = 0; i < this.members.length; i++) {\n let result = this.members[i].forChild(offset, child)\n if (result == empty) continue\n if (result instanceof DecorationGroup) found = found.concat(result.members)\n else found.push(result)\n }\n return DecorationGroup.from(found)\n }\n\n eq(other) {\n if (!(other instanceof DecorationGroup) ||\n other.members.length != this.members.length) return false\n for (let i = 0; i < this.members.length; i++)\n if (!this.members[i].eq(other.members[i])) return false\n return true\n }\n\n locals(node) {\n let result, sorted = true\n for (let i = 0; i < this.members.length; i++) {\n let locals = this.members[i].localsInner(node)\n if (!locals.length) continue\n if (!result) {\n result = locals\n } else {\n if (sorted) {\n result = result.slice()\n sorted = false\n }\n for (let j = 0; j < locals.length; j++) result.push(locals[j])\n }\n }\n return result ? removeOverlap(sorted ? result : result.sort(byPos)) : none\n }\n\n // : ([DecorationSet]) → union\n // Create a group for the given array of decoration sets, or return\n // a single set when possible.\n static from(members) {\n switch (members.length) {\n case 0: return empty\n case 1: return members[0]\n default: return new DecorationGroup(members)\n }\n }\n}\n\nfunction mapChildren(oldChildren, newLocal, mapping, node, offset, oldOffset, options) {\n let children = oldChildren.slice()\n\n // Mark the children that are directly touched by changes, and\n // move those that are after the changes.\n let shift = (oldStart, oldEnd, newStart, newEnd) => {\n for (let i = 0; i < children.length; i += 3) {\n let end = children[i + 1], dSize\n if (end == -1 || oldStart > end + oldOffset) continue\n if (oldEnd >= children[i] + oldOffset) {\n children[i + 1] = -1\n } else if (dSize = (newEnd - newStart) - (oldEnd - oldStart) + (oldOffset - offset)) {\n children[i] += dSize\n children[i + 1] += dSize\n }\n }\n }\n for (let i = 0; i < mapping.maps.length; i++) mapping.maps[i].forEach(shift)\n\n // Find the child nodes that still correspond to a single node,\n // recursively call mapInner on them and update their positions.\n let mustRebuild = false\n for (let i = 0; i < children.length; i += 3) if (children[i + 1] == -1) { // Touched nodes\n let from = mapping.map(children[i] + oldOffset), fromLocal = from - offset\n if (fromLocal < 0 || fromLocal >= node.content.size) {\n mustRebuild = true\n continue\n }\n // Must read oldChildren because children was tagged with -1\n let to = mapping.map(oldChildren[i + 1] + oldOffset, -1), toLocal = to - offset\n let {index, offset: childOffset} = node.content.findIndex(fromLocal)\n let childNode = node.maybeChild(index)\n if (childNode && childOffset == fromLocal && childOffset + childNode.nodeSize == toLocal) {\n let mapped = children[i + 2].mapInner(mapping, childNode, from + 1, children[i] + oldOffset + 1, options)\n if (mapped != empty) {\n children[i] = fromLocal\n children[i + 1] = toLocal\n children[i + 2] = mapped\n } else {\n children[i + 1] = -2\n mustRebuild = true\n }\n } else {\n mustRebuild = true\n }\n }\n\n // Remaining children must be collected and rebuilt into the appropriate structure\n if (mustRebuild) {\n let decorations = mapAndGatherRemainingDecorations(children, oldChildren, newLocal || [], mapping,\n offset, oldOffset, options)\n let built = buildTree(decorations, node, 0, options)\n newLocal = built.local\n for (let i = 0; i < children.length; i += 3) if (children[i + 1] < 0) {\n children.splice(i, 3)\n i -= 3\n }\n for (let i = 0, j = 0; i < built.children.length; i += 3) {\n let from = built.children[i]\n while (j < children.length && children[j] < from) j += 3\n children.splice(j, 0, built.children[i], built.children[i + 1], built.children[i + 2])\n }\n }\n\n return new DecorationSet(newLocal && newLocal.sort(byPos), children)\n}\n\nfunction moveSpans(spans, offset) {\n if (!offset || !spans.length) return spans\n let result = []\n for (let i = 0; i < spans.length; i++) {\n let span = spans[i]\n result.push(new Decoration(span.from + offset, span.to + offset, span.type))\n }\n return result\n}\n\nfunction mapAndGatherRemainingDecorations(children, oldChildren, decorations, mapping, offset, oldOffset, options) {\n // Gather all decorations from the remaining marked children\n function gather(set, oldOffset) {\n for (let i = 0; i < set.local.length; i++) {\n let mapped = set.local[i].map(mapping, offset, oldOffset)\n if (mapped) decorations.push(mapped)\n else if (options.onRemove) options.onRemove(set.local[i].spec)\n }\n for (let i = 0; i < set.children.length; i += 3)\n gather(set.children[i + 2], set.children[i] + oldOffset + 1)\n }\n for (let i = 0; i < children.length; i += 3) if (children[i + 1] == -1)\n gather(children[i + 2], oldChildren[i] + oldOffset + 1)\n\n return decorations\n}\n\nfunction takeSpansForNode(spans, node, offset) {\n if (node.isLeaf) return null\n let end = offset + node.nodeSize, found = null\n for (let i = 0, span; i < spans.length; i++) {\n if ((span = spans[i]) && span.from > offset && span.to < end) {\n ;(found || (found = [])).push(span)\n spans[i] = null\n }\n }\n return found\n}\n\nfunction withoutNulls(array) {\n let result = []\n for (let i = 0; i < array.length; i++)\n if (array[i] != null) result.push(array[i])\n return result\n}\n\n// : ([Decoration], Node, number) → DecorationSet\n// Build up a tree that corresponds to a set of decorations. `offset`\n// is a base offset that should be subtractet from the `from` and `to`\n// positions in the spans (so that we don't have to allocate new spans\n// for recursive calls).\nfunction buildTree(spans, node, offset, options) {\n let children = [], hasNulls = false\n node.forEach((childNode, localStart) => {\n let found = takeSpansForNode(spans, childNode, localStart + offset)\n if (found) {\n hasNulls = true\n let subtree = buildTree(found, childNode, offset + localStart + 1, options)\n if (subtree != empty)\n children.push(localStart, localStart + childNode.nodeSize, subtree)\n }\n })\n let locals = moveSpans(hasNulls ? withoutNulls(spans) : spans, -offset).sort(byPos)\n for (let i = 0; i < locals.length; i++) if (!locals[i].type.valid(node, locals[i])) {\n if (options.onRemove) options.onRemove(locals[i].spec)\n locals.splice(i--, 1)\n }\n return locals.length || children.length ? new DecorationSet(locals, children) : empty\n}\n\n// : (Decoration, Decoration) → number\n// Used to sort decorations so that ones with a low start position\n// come first, and within a set with the same start position, those\n// with an smaller end position come first.\nfunction byPos(a, b) {\n return a.from - b.from || a.to - b.to\n}\n\n// : ([Decoration]) → [Decoration]\n// Scan a sorted array of decorations for partially overlapping spans,\n// and split those so that only fully overlapping spans are left (to\n// make subsequent rendering easier). Will return the input array if\n// no partially overlapping spans are found (the common case).\nfunction removeOverlap(spans) {\n let working = spans\n for (let i = 0; i < working.length - 1; i++) {\n let span = working[i]\n if (span.from != span.to) for (let j = i + 1; j < working.length; j++) {\n let next = working[j]\n if (next.from == span.from) {\n if (next.to != span.to) {\n if (working == spans) working = spans.slice()\n // Followed by a partially overlapping larger span. Split that\n // span.\n working[j] = next.copy(next.from, span.to)\n insertAhead(working, j + 1, next.copy(span.to, next.to))\n }\n continue\n } else {\n if (next.from < span.to) {\n if (working == spans) working = spans.slice()\n // The end of this one overlaps with a subsequent span. Split\n // this one.\n working[i] = span.copy(span.from, next.from)\n insertAhead(working, j, span.copy(next.from, span.to))\n }\n break\n }\n }\n }\n return working\n}\n\nfunction insertAhead(array, i, deco) {\n while (i < array.length && byPos(deco, array[i]) > 0) i++\n array.splice(i, 0, deco)\n}\n\n// : (EditorView) → union\n// Get the decorations associated with the current props of a view.\nexport function viewDecorations(view) {\n let found = []\n view.someProp(\"decorations\", f => {\n let result = f(view.state)\n if (result && result != empty) found.push(result)\n })\n if (view.cursorWrapper)\n found.push(DecorationSet.create(view.state.doc, [view.cursorWrapper.deco]))\n return DecorationGroup.from(found)\n}\n","import {NodeSelection} from \"prosemirror-state\"\n\nimport {scrollRectIntoView, posAtCoords, coordsAtPos, endOfTextblock, storeScrollPos,\n resetScrollPos, focusPreventScroll} from \"./domcoords\"\nimport {docViewDesc} from \"./viewdesc\"\nimport {initInput, destroyInput, dispatchEvent, ensureListeners} from \"./input\"\nimport {selectionToDOM, anchorInRightPlace, syncNodeSelection} from \"./selection\"\nimport {Decoration, viewDecorations} from \"./decoration\"\nimport browser from \"./browser\"\n\nexport {Decoration, DecorationSet} from \"./decoration\"\n\n// Exported for testing\nexport {serializeForClipboard as __serializeForClipboard, parseFromClipboard as __parseFromClipboard} from \"./clipboard\"\nexport {endComposition as __endComposition} from \"./input\"\n\n// ::- An editor view manages the DOM structure that represents an\n// editable document. Its state and behavior are determined by its\n// [props](#view.DirectEditorProps).\nexport class EditorView {\n // :: (?union, DirectEditorProps)\n // Create a view. `place` may be a DOM node that the editor should\n // be appended to, a function that will place it into the document,\n // or an object whose `mount` property holds the node to use as the\n // document container. If it is `null`, the editor will not be added\n // to the document.\n constructor(place, props) {\n this._props = props\n // :: EditorState\n // The view's current [state](#state.EditorState).\n this.state = props.state\n\n this.dispatch = this.dispatch.bind(this)\n\n this._root = null\n this.focused = false\n\n // :: dom.Element\n // An editable DOM node containing the document. (You probably\n // should not directly interfere with its content.)\n this.dom = (place && place.mount) || document.createElement(\"div\")\n if (place) {\n if (place.appendChild) place.appendChild(this.dom)\n else if (place.apply) place(this.dom)\n else if (place.mount) this.mounted = true\n }\n\n // :: bool\n // Indicates whether the editor is currently [editable](#view.EditorProps.editable).\n this.editable = getEditable(this)\n this.markCursor = null\n this.cursorWrapper = null\n updateCursorWrapper(this)\n this.nodeViews = buildNodeViews(this)\n this.docView = docViewDesc(this.state.doc, computeDocDeco(this), viewDecorations(this), this.dom, this)\n\n this.lastSelectedViewDesc = null\n // :: ?{slice: Slice, move: bool}\n // When editor content is being dragged, this object contains\n // information about the dragged slice and whether it is being\n // copied or moved. At any other time, it is null.\n this.dragging = null\n\n initInput(this)\n\n this.pluginViews = []\n this.updatePluginViews()\n }\n\n // composing:: boolean\n // Holds `true` when a\n // [composition](https://developer.mozilla.org/en-US/docs/Mozilla/IME_handling_guide)\n // is active.\n\n // :: DirectEditorProps\n // The view's current [props](#view.EditorProps).\n get props() {\n if (this._props.state != this.state) {\n let prev = this._props\n this._props = {}\n for (let name in prev) this._props[name] = prev[name]\n this._props.state = this.state\n }\n return this._props\n }\n\n // :: (DirectEditorProps)\n // Update the view's props. Will immediately cause an update to\n // the DOM.\n update(props) {\n if (props.handleDOMEvents != this._props.handleDOMEvents) ensureListeners(this)\n this._props = props\n this.updateStateInner(props.state, true)\n }\n\n // :: (DirectEditorProps)\n // Update the view by updating existing props object with the object\n // given as argument. Equivalent to `view.update(Object.assign({},\n // view.props, props))`.\n setProps(props) {\n let updated = {}\n for (let name in this._props) updated[name] = this._props[name]\n updated.state = this.state\n for (let name in props) updated[name] = props[name]\n this.update(updated)\n }\n\n // :: (EditorState)\n // Update the editor's `state` prop, without touching any of the\n // other props.\n updateState(state) {\n this.updateStateInner(state, this.state.plugins != state.plugins)\n }\n\n updateStateInner(state, reconfigured) {\n let prev = this.state, redraw = false\n this.state = state\n if (reconfigured) {\n let nodeViews = buildNodeViews(this)\n if (changedNodeViews(nodeViews, this.nodeViews)) {\n this.nodeViews = nodeViews\n redraw = true\n }\n ensureListeners(this)\n }\n\n this.editable = getEditable(this)\n updateCursorWrapper(this)\n let innerDeco = viewDecorations(this), outerDeco = computeDocDeco(this)\n\n let scroll = reconfigured ? \"reset\"\n : state.scrollToSelection > prev.scrollToSelection ? \"to selection\" : \"preserve\"\n let updateDoc = redraw || !this.docView.matchesNode(state.doc, outerDeco, innerDeco)\n let updateSel = updateDoc || !state.selection.eq(prev.selection)\n let oldScrollPos = scroll == \"preserve\" && updateSel && this.dom.style.overflowAnchor == null && storeScrollPos(this)\n\n if (updateSel) {\n this.domObserver.stop()\n // Work around an issue in Chrome, IE, and Edge where changing\n // the DOM around an active selection puts it into a broken\n // state where the thing the user sees differs from the\n // selection reported by the Selection object (#710, #973,\n // #1011, #1013).\n let forceSelUpdate = updateDoc && (browser.ie || browser.chrome) &&\n !prev.selection.empty && !state.selection.empty && selectionContextChanged(prev.selection, state.selection)\n if (updateDoc) {\n if (redraw || !this.docView.update(state.doc, outerDeco, innerDeco, this)) {\n this.docView.destroy()\n this.docView = docViewDesc(state.doc, outerDeco, innerDeco, this.dom, this)\n }\n }\n // Work around for an issue where an update arriving right between\n // a DOM selection change and the \"selectionchange\" event for it\n // can cause a spurious DOM selection update, disrupting mouse\n // drag selection.\n if (forceSelUpdate ||\n !(this.mouseDown && this.domObserver.currentSelection.eq(this.root.getSelection()) && anchorInRightPlace(this))) {\n selectionToDOM(this, forceSelUpdate)\n } else {\n syncNodeSelection(this, state.selection)\n this.domObserver.setCurSelection()\n }\n this.domObserver.start()\n }\n\n this.updatePluginViews(prev)\n\n if (scroll == \"reset\") {\n this.dom.scrollTop = 0\n } else if (scroll == \"to selection\") {\n let startDOM = this.root.getSelection().focusNode\n if (this.someProp(\"handleScrollToSelection\", f => f(this)))\n {} // Handled\n else if (state.selection instanceof NodeSelection)\n scrollRectIntoView(this, this.docView.domAfterPos(state.selection.from).getBoundingClientRect(), startDOM)\n else\n scrollRectIntoView(this, this.coordsAtPos(state.selection.head), startDOM)\n } else if (oldScrollPos) {\n resetScrollPos(oldScrollPos)\n }\n }\n\n destroyPluginViews() {\n let view\n while (view = this.pluginViews.pop()) if (view.destroy) view.destroy()\n }\n\n updatePluginViews(prevState) {\n if (!prevState || prevState.plugins != this.state.plugins) {\n this.destroyPluginViews()\n for (let i = 0; i < this.state.plugins.length; i++) {\n let plugin = this.state.plugins[i]\n if (plugin.spec.view) this.pluginViews.push(plugin.spec.view(this))\n }\n } else {\n for (let i = 0; i < this.pluginViews.length; i++) {\n let pluginView = this.pluginViews[i]\n if (pluginView.update) pluginView.update(this, prevState)\n }\n }\n }\n\n // :: (string, ?(prop: *) → *) → *\n // Goes over the values of a prop, first those provided directly,\n // then those from plugins (in order), and calls `f` every time a\n // non-undefined value is found. When `f` returns a truthy value,\n // that is immediately returned. When `f` isn't provided, it is\n // treated as the identity function (the prop value is returned\n // directly).\n someProp(propName, f) {\n let prop = this._props && this._props[propName], value\n if (prop != null && (value = f ? f(prop) : prop)) return value\n let plugins = this.state.plugins\n if (plugins) for (let i = 0; i < plugins.length; i++) {\n let prop = plugins[i].props[propName]\n if (prop != null && (value = f ? f(prop) : prop)) return value\n }\n }\n\n // :: () → bool\n // Query whether the view has focus.\n hasFocus() {\n return this.root.activeElement == this.dom\n }\n\n // :: ()\n // Focus the editor.\n focus() {\n this.domObserver.stop()\n if (this.editable) focusPreventScroll(this.dom)\n selectionToDOM(this)\n this.domObserver.start()\n }\n\n // :: union\n // Get the document root in which the editor exists. This will\n // usually be the top-level `document`, but might be a [shadow\n // DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Shadow_DOM)\n // root if the editor is inside one.\n get root() {\n let cached = this._root\n if (cached == null) for (let search = this.dom.parentNode; search; search = search.parentNode) {\n if (search.nodeType == 9 || (search.nodeType == 11 && search.host)) {\n if (!search.getSelection) Object.getPrototypeOf(search).getSelection = () => document.getSelection()\n return this._root = search\n }\n }\n return cached || document\n }\n\n // :: ({left: number, top: number}) → ?{pos: number, inside: number}\n // Given a pair of viewport coordinates, return the document\n // position that corresponds to them. May return null if the given\n // coordinates aren't inside of the editor. When an object is\n // returned, its `pos` property is the position nearest to the\n // coordinates, and its `inside` property holds the position of the\n // inner node that the position falls inside of, or -1 if it is at\n // the top level, not in any node.\n posAtCoords(coords) {\n return posAtCoords(this, coords)\n }\n\n // :: (number) → {left: number, right: number, top: number, bottom: number}\n // Returns the viewport rectangle at a given document position. `left`\n // and `right` will be the same number, as this returns a flat\n // cursor-ish rectangle.\n coordsAtPos(pos) {\n return coordsAtPos(this, pos)\n }\n\n // :: (number) → {node: dom.Node, offset: number}\n // Find the DOM position that corresponds to the given document\n // position. Note that you should **not** mutate the editor's\n // internal DOM, only inspect it (and even that is usually not\n // necessary).\n domAtPos(pos) {\n return this.docView.domFromPos(pos)\n }\n\n // :: (number) → ?dom.Node\n // Find the DOM node that represents the document node after the\n // given position. May return `null` when the position doesn't point\n // in front of a node or if the node is inside an opaque node view.\n //\n // This is intended to be able to call things like\n // `getBoundingClientRect` on that DOM node. Do **not** mutate the\n // editor DOM directly, or add styling this way, since that will be\n // immediately overriden by the editor as it redraws the node.\n nodeDOM(pos) {\n let desc = this.docView.descAt(pos)\n return desc ? desc.nodeDOM : null\n }\n\n // :: (dom.Node, number, ?number) → number\n // Find the document position that corresponds to a given DOM\n // position. (Whenever possible, it is preferable to inspect the\n // document structure directly, rather than poking around in the\n // DOM, but sometimes—for example when interpreting an event\n // target—you don't have a choice.)\n //\n // The `bias` parameter can be used to influence which side of a DOM\n // node to use when the position is inside a leaf node.\n posAtDOM(node, offset, bias = -1) {\n let pos = this.docView.posFromDOM(node, offset, bias)\n if (pos == null) throw new RangeError(\"DOM position not inside the editor\")\n return pos\n }\n\n // :: (union<\"up\", \"down\", \"left\", \"right\", \"forward\", \"backward\">, ?EditorState) → bool\n // Find out whether the selection is at the end of a textblock when\n // moving in a given direction. When, for example, given `\"left\"`,\n // it will return true if moving left from the current cursor\n // position would leave that position's parent textblock. Will apply\n // to the view's current state by default, but it is possible to\n // pass a different state.\n endOfTextblock(dir, state) {\n return endOfTextblock(this, state || this.state, dir)\n }\n\n // :: ()\n // Removes the editor from the DOM and destroys all [node\n // views](#view.NodeView).\n destroy() {\n if (!this.docView) return\n destroyInput(this)\n this.destroyPluginViews()\n if (this.mounted) {\n this.docView.update(this.state.doc, [], viewDecorations(this), this)\n this.dom.textContent = \"\"\n } else if (this.dom.parentNode) {\n this.dom.parentNode.removeChild(this.dom)\n }\n this.docView.destroy()\n this.docView = null\n }\n\n // Used for testing.\n dispatchEvent(event) {\n return dispatchEvent(this, event)\n }\n\n // :: (Transaction)\n // Dispatch a transaction. Will call\n // [`dispatchTransaction`](#view.DirectEditorProps.dispatchTransaction)\n // when given, and otherwise defaults to applying the transaction to\n // the current state and calling\n // [`updateState`](#view.EditorView.updateState) with the result.\n // This method is bound to the view instance, so that it can be\n // easily passed around.\n dispatch(tr) {\n let dispatchTransaction = this._props.dispatchTransaction\n if (dispatchTransaction) dispatchTransaction.call(this, tr)\n else this.updateState(this.state.apply(tr))\n }\n}\n\nfunction computeDocDeco(view) {\n let attrs = Object.create(null)\n attrs.class = \"ProseMirror\"\n attrs.contenteditable = String(view.editable)\n\n view.someProp(\"attributes\", value => {\n if (typeof value == \"function\") value = value(view.state)\n if (value) for (let attr in value) {\n if (attr == \"class\")\n attrs.class += \" \" + value[attr]\n else if (!attrs[attr] && attr != \"contenteditable\" && attr != \"nodeName\")\n attrs[attr] = String(value[attr])\n }\n })\n\n return [Decoration.node(0, view.state.doc.content.size, attrs)]\n}\n\nfunction updateCursorWrapper(view) {\n let {$head, $anchor, visible} = view.state.selection\n if (view.markCursor) {\n let dom = document.createElement(\"img\")\n dom.setAttribute(\"mark-placeholder\", \"true\")\n view.cursorWrapper = {dom, deco: Decoration.widget($head.pos, dom, {raw: true, marks: view.markCursor})}\n } else if (visible || $head.pos != $anchor.pos) {\n view.cursorWrapper = null\n } else {\n let dom\n if (!view.cursorWrapper || view.cursorWrapper.dom.childNodes.length) {\n dom = document.createElement(\"div\")\n dom.style.position = \"absolute\"\n dom.style.left = \"-100000px\"\n } else if (view.cursorWrapper.deco.pos != $head.pos) {\n dom = view.cursorWrapper.dom\n }\n if (dom)\n view.cursorWrapper = {dom, deco: Decoration.widget($head.pos, dom, {raw: true})}\n }\n}\n\nfunction getEditable(view) {\n return !view.someProp(\"editable\", value => value(view.state) === false)\n}\n\nfunction selectionContextChanged(sel1, sel2) {\n let depth = Math.min(sel1.$anchor.sharedDepth(sel1.head), sel2.$anchor.sharedDepth(sel2.head))\n return sel1.$anchor.node(depth) != sel2.$anchor.node(depth)\n}\n\nfunction buildNodeViews(view) {\n let result = {}\n view.someProp(\"nodeViews\", obj => {\n for (let prop in obj) if (!Object.prototype.hasOwnProperty.call(result, prop))\n result[prop] = obj[prop]\n })\n return result\n}\n\nfunction changedNodeViews(a, b) {\n let nA = 0, nB = 0\n for (let prop in a) {\n if (a[prop] != b[prop]) return true\n nA++\n }\n for (let _ in b) nB++\n return nA != nB\n}\n\n// EditorProps:: interface\n//\n// Props are configuration values that can be passed to an editor view\n// or included in a plugin. This interface lists the supported props.\n//\n// The various event-handling functions may all return `true` to\n// indicate that they handled the given event. The view will then take\n// care to call `preventDefault` on the event, except with\n// `handleDOMEvents`, where the handler itself is responsible for that.\n//\n// How a prop is resolved depends on the prop. Handler functions are\n// called one at a time, starting with the base props and then\n// searching through the plugins (in order of appearance) until one of\n// them returns true. For some props, the first plugin that yields a\n// value gets precedence.\n//\n// handleDOMEvents:: ?Object<(view: EditorView, event: dom.Event) → bool>\n// Can be an object mapping DOM event type names to functions that\n// handle them. Such functions will be called before any handling\n// ProseMirror does of events fired on the editable DOM element.\n// Contrary to the other event handling props, when returning true\n// from such a function, you are responsible for calling\n// `preventDefault` yourself (or not, if you want to allow the\n// default behavior).\n//\n// handleKeyDown:: ?(view: EditorView, event: dom.KeyboardEvent) → bool\n// Called when the editor receives a `keydown` event.\n//\n// handleKeyPress:: ?(view: EditorView, event: dom.KeyboardEvent) → bool\n// Handler for `keypress` events.\n//\n// handleTextInput:: ?(view: EditorView, from: number, to: number, text: string) → bool\n// Whenever the user directly input text, this handler is called\n// before the input is applied. If it returns `true`, the default\n// behavior of actually inserting the text is suppressed.\n//\n// handleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool\n// Called for each node around a click, from the inside out. The\n// `direct` flag will be true for the inner node.\n//\n// handleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool\n// Called when the editor is clicked, after `handleClickOn` handlers\n// have been called.\n//\n// handleDoubleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool\n// Called for each node around a double click.\n//\n// handleDoubleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool\n// Called when the editor is double-clicked, after `handleDoubleClickOn`.\n//\n// handleTripleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool\n// Called for each node around a triple click.\n//\n// handleTripleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool\n// Called when the editor is triple-clicked, after `handleTripleClickOn`.\n//\n// handlePaste:: ?(view: EditorView, event: dom.Event, slice: Slice) → bool\n// Can be used to override the behavior of pasting. `slice` is the\n// pasted content parsed by the editor, but you can directly access\n// the event to get at the raw content.\n//\n// handleDrop:: ?(view: EditorView, event: dom.Event, slice: Slice, moved: bool) → bool\n// Called when something is dropped on the editor. `moved` will be\n// true if this drop moves from the current selection (which should\n// thus be deleted).\n//\n// handleScrollToSelection:: ?(view: EditorView) → bool\n// Called when the view, after updating its state, tries to scroll\n// the selection into view. A handler function may return false to\n// indicate that it did not handle the scrolling and further\n// handlers or the default behavior should be tried.\n//\n// createSelectionBetween:: ?(view: EditorView, anchor: ResolvedPos, head: ResolvedPos) → ?Selection\n// Can be used to override the way a selection is created when\n// reading a DOM selection between the given anchor and head.\n//\n// domParser:: ?DOMParser\n// The [parser](#model.DOMParser) to use when reading editor changes\n// from the DOM. Defaults to calling\n// [`DOMParser.fromSchema`](#model.DOMParser^fromSchema) on the\n// editor's schema.\n//\n// transformPastedHTML:: ?(html: string) → string\n// Can be used to transform pasted HTML text, _before_ it is parsed,\n// for example to clean it up.\n//\n// clipboardParser:: ?DOMParser\n// The [parser](#model.DOMParser) to use when reading content from\n// the clipboard. When not given, the value of the\n// [`domParser`](#view.EditorProps.domParser) prop is used.\n//\n// transformPastedText:: ?(text: string) → string\n// Transform pasted plain text.\n//\n// clipboardTextParser:: ?(text: string, $context: ResolvedPos) → Slice\n// A function to parse text from the clipboard into a document\n// slice. Called after\n// [`transformPastedText`](#view.EditorProps.transformPastedText).\n// The default behavior is to split the text into lines, wrap them\n// in `

    ` tags, and call\n// [`clipboardParser`](#view.EditorProps.clipboardParser) on it.\n//\n// transformPasted:: ?(Slice) → Slice\n// Can be used to transform pasted content before it is applied to\n// the document.\n//\n// nodeViews:: ?Object<(node: Node, view: EditorView, getPos: () → number, decorations: [Decoration]) → NodeView>\n// Allows you to pass custom rendering and behavior logic for nodes\n// and marks. Should map node and mark names to constructor\n// functions that produce a [`NodeView`](#view.NodeView) object\n// implementing the node's display behavior. For nodes, the third\n// argument `getPos` is a function that can be called to get the\n// node's current position, which can be useful when creating\n// transactions to update it. For marks, the third argument is a\n// boolean that indicates whether the mark's content is inline.\n//\n// `decorations` is an array of node or inline decorations that are\n// active around the node. They are automatically drawn in the\n// normal way, and you will usually just want to ignore this, but\n// they can also be used as a way to provide context information to\n// the node view without adding it to the document itself.\n//\n// clipboardSerializer:: ?DOMSerializer\n// The DOM serializer to use when putting content onto the\n// clipboard. If not given, the result of\n// [`DOMSerializer.fromSchema`](#model.DOMSerializer^fromSchema)\n// will be used.\n//\n// clipboardTextSerializer:: ?(Slice) → string\n// A function that will be called to get the text for the current\n// selection when copying text to the clipboard. By default, the\n// editor will use [`textBetween`](#model.Node.textBetween) on the\n// selected range.\n//\n// decorations:: ?(state: EditorState) → ?DecorationSet\n// A set of [document decorations](#view.Decoration) to show in the\n// view.\n//\n// editable:: ?(state: EditorState) → bool\n// When this returns false, the content of the view is not directly\n// editable.\n//\n// attributes:: ?union, (EditorState) → ?Object>\n// Control the DOM attributes of the editable element. May be either\n// an object or a function going from an editor state to an object.\n// By default, the element will get a class `\"ProseMirror\"`, and\n// will have its `contentEditable` attribute determined by the\n// [`editable` prop](#view.EditorProps.editable). Additional classes\n// provided here will be added to the class. For other attributes,\n// the value provided first (as in\n// [`someProp`](#view.EditorView.someProp)) will be used.\n//\n// scrollThreshold:: ?union\n// Determines the distance (in pixels) between the cursor and the\n// end of the visible viewport at which point, when scrolling the\n// cursor into view, scrolling takes place. Defaults to 0.\n//\n// scrollMargin:: ?union\n// Determines the extra space (in pixels) that is left above or\n// below the cursor when it is scrolled into view. Defaults to 5.\n\n// DirectEditorProps:: interface extends EditorProps\n//\n// The props object given directly to the editor view supports two\n// fields that can't be used in plugins:\n//\n// state:: EditorState\n// The current state of the editor.\n//\n// dispatchTransaction:: ?(tr: Transaction)\n// The callback over which to send transactions (state updates)\n// produced by the view. If you specify this, you probably want to\n// make sure this ends up calling the view's\n// [`updateState`](#view.EditorView.updateState) method with a new\n// state that has the transaction\n// [applied](#state.EditorState.apply). The callback will be bound to have\n// the view instance as its `this` binding.\n"],"names":["const","let","browser","pos","box","rect","target","desc","search","j","super","DOMSerializer","this","Fragment","Mark","TextSelection","name","i","child","Selection","NodeSelection","next","DOMParser","anchor","tr","sel","move","Slice","d","result","dropPoint","p","prototypeAccessors","span","from","prop","dom"],"mappings":"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"} \ No newline at end of file diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/.tern-project b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/.tern-project new file mode 100644 index 0000000000..dde39765e5 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/.tern-project @@ -0,0 +1,8 @@ +{ + "libs": ["browser"], + "plugins": { + "node": {}, + "complete_strings": {}, + "es_modules": {} + } +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/CHANGELOG.md b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/CHANGELOG.md new file mode 100644 index 0000000000..fa7ae8a8f1 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/CHANGELOG.md @@ -0,0 +1,272 @@ +## 1.2.2 (2019-11-20) + +### Bug fixes + +Rename ES module files to use a .js extension, since Webpack gets confused by .mjs + +## 1.2.1 (2019-11-19) + +### Bug fixes + +The file referred to in the package's `module` field now is compiled down to ES5. + +## 1.2.0 (2019-11-08) + +### New features + +Add a `module` field to package json file. + +## 1.1.6 (2019-11-01) + +### Bug fixes + +Fixes an issue where deleting a range from the start of block A to the end of block B would leave you with an empty block of type B. + +## 1.1.5 (2019-10-02) + +### Bug fixes + +Fix crash in building replace steps for open-ended slices with complicated node content expressions. + +## 1.1.4 (2019-08-26) + +### Bug fixes + +[`Mapping.invert`](https://prosemirror.net/docs/ref/#transform.Mapping.invert) is now part of the documented API (it was intented to be public from the start, but a typo prevented it from showing up in the docs). + +Fix an issue where a replace could needlessly drop content when the first node of the slice didn't fit the target context. + +`replaceRange` now more aggressively expands the replaced region if `replace` fails to place the slice. + +## 1.1.3 (2018-07-03) + +### Bug fixes + +Replacing from a code block into a paragraph that has marks, or similar scenarios that would join content with the wrong marks into a node, no longer crashes. + +## 1.1.2 (2018-06-29) + +### Bug fixes + +Fix issue where [`replaceRange`](https://prosemirror.net/docs/ref/#transform.Transform.replaceRange) might create invalid nodes. + +## 1.1.1 (2018-06-26) + +### Bug fixes + +Fix issues in the new [`dropPoint`](https://prosemirror.net/docs/ref/#transform.dropPoint) function. + +## 1.1.0 (2018-06-20) + +### New features + +[`Transform.getMirror`](https://prosemirror.net/docs/ref/#transform.Transform.getMirror), usable in obscure circumstances for inspecting the mirroring structure or a transform, is now a public method. + +New utility function [`dropPoint`](https://prosemirror.net/docs/ref/#transform.dropPoint), which tries to find a valid position for dropping a slice near a given document position. + +## 1.0.10 (2018-04-15) + +### Bug fixes + +[`Transform.setBlockType`](https://prosemirror.net/docs/ref/#transform.Transform.setBlockType) no longer drops marks on the nodes it updates. + +## 1.0.9 (2018-04-05) + +### Bug fixes + +Fix a bug that made [`replaceStep`](https://prosemirror.net/docs/ref/#transform.replaceStep) unable to generate wrapper nodes in some circumstances. + +## 1.0.8 (2018-04-04) + +### Bug fixes + +Fixes an issue where [`replaceStep`](https://prosemirror.net/docs/ref/#transform.replaceStep) could generate slices that internally violated the schema. + +## 1.0.7 (2018-03-21) + +### Bug fixes + +[`Transform.deleteRange`](https://prosemirror.net/docs/ref/#transform.Transform.deleteRange) will cover unmatched opening at the start of the deleted range. + +## 1.0.6 (2018-03-15) + +### Bug fixes + +Throw errors, rather than constructing invalid objects, when deserializing from invalid JSON data. + +## 1.0.5 (2018-03-14) + +### Bug fixes + +[`replaceStep`](https://prosemirror.net/docs/ref/#transform.replaceStep) will now return null rather than an empty step when it fails to place the slice. + +Avoid duplicating defining parent nodes in [`replaceRange`](https://prosemirror.net/docs/ref/#tranform.Transform.replaceRange). + +## 1.0.4 (2018-02-23) + +### Bug fixes + +Fix overeager closing of destination nodes when fitting a slice during replacing. + +## 1.0.3 (2018-02-23) + +### Bug fixes + +Fix a problem where slice-placing didn't handle content matches correctly and might generate invalid steps or fail to generate steps though a valid one exists. + +Allows adjacent nodes from an inserted slice to be placed in different parent nodes, allowing `Transform.replace` to create fits that weren't previously found. + +## 1.0.2 (2018-01-24) + +### Bug fixes + +Fixes a crash in [`replace`](http://prosemirror.net/docs/ref/#transform.Transform.replace). + +## 1.0.1 (2017-11-10) + +### Bug fixes + +The errors raised by [`Transform.step`](http://prosemirror.net/docs/ref/#transform.Transform.step) now properly inherit from Error. + +## 1.0.0 (2017-10-13) + +### Bug fixes + +When [`setBlockType`](http://prosemirror.net/docs/ref/#transform.Transform.setBlockType) comes across a textblock that can't be changed due to schema constraints, it skips it instead of failing. + +[`canSplit`](http://prosemirror.net/docs/ref/#transform.canSplit) now returns false when the requested split goes through isolating nodes. + +## 0.24.0 (2017-09-25) + +### Breaking changes + +The `setNodeType` method on transforms is now more descriptively called [`setNodeMarkup`](http://prosemirror.net/docs/ref/version/0.24.0.html#transform.Transform.setNodeMarkup). The old name will continue to work with a warning until the next release. + +## 0.23.0 (2017-09-13) + +### Breaking changes + +[`Step.toJSON`](http://prosemirror.net/docs/ref/version/0.23.0.html#transform.Step.toJSON) no longer has a default implementation. + +Steps no longer have an `offset` method. Map them through a map created with [`StepMap.offset`](http://prosemirror.net/docs/ref/version/0.23.0.html#transform.StepMap^offset) instead. + +The `clearMarkup` method on [`Transform`](http://prosemirror.net/docs/ref/version/0.23.0.html#transform.Transform) is no longer supported (you probably needed [`clearIncompatible`](http://prosemirror.net/docs/ref/version/0.23.0.html#transform.Transform.clearIncompatible) anyway). + +### Bug fixes + +Pasting a list item at the start of a non-empty textblock now wraps the textblock in a list. + +Marks on open nodes at the left of a slice are no longer dropped by [`Transform.replace`](http://prosemirror.net/docs/ref/version/0.23.0.html#transform.Transform.replace). + +### New features + +`StepMap` now has a static method [`offset`](http://prosemirror.net/docs/ref/version/0.23.0.html#transform.StepMap^offset), which can be used to create a map that offsets all positions by a given distance. + +Transform objects now have a [`clearIncompatible`](http://prosemirror.net/docs/ref/version/0.23.0.html#transform.Transform.clearIncompatible) method that can help make sure a node's content matches another node type. + +## 0.22.2 (2017-07-06) + +### Bug fixes + +Fix another bug in the way `canSplit` interpreted its `typesAfter` argument. + +## 0.22.1 (2017-07-03) + +### Bug fixes + +Fix crash in [`canSplit`](http://prosemirror.net/docs/ref/version/0.22.0.html#transform.canSplit) when an array containing null fields is passed as fourth argument. + +## 0.22.0 (2017-06-29) + +### Bug fixes + +[`canSplit`](http://prosemirror.net/docs/ref/version/0.22.0.html#transform.canSplit) now returns false when given custom after-split node types that don't match the content at that point. + +Fixes [`canLift`](http://prosemirror.net/docs/ref/version/0.22.0.html#transform.canLift) incorrectly returning null when lifting into an isolating node. + +## 0.21.1 (2017-05-16) + +### Bug fixes + +[`addMark`](http://prosemirror.net/docs/ref/version/0.21.0.html#transform.Transform.addMark) no longer assumes marks always [exclude](http://prosemirror.net/docs/ref/version/0.21.0.html#model.MarkSpec.excludes) only themselves. + +`replaceRange`](http://prosemirror.net/docs/ref/version/0.21.0.html#transform.Transform.replaceRange) and [`deleteRange`](http://prosemirror.net/docs/ref/version/0.21.0.html#transform.Transform.deleteRange) will no longer expand the range across isolating node boundaries. + +## 0.20.0 (2017-04-03) + +### Bug fixes + +Fixes issue where replacing would sometimes unexpectedly split nodes. + +## 0.18.0 (2017-02-24) + +### New features + +[`Transform.setNodeType`](http://prosemirror.net/docs/ref/version/0.18.0.html#transform.Transform.setNodeType) now takes an optional argument to set the new node's attributes. + +Steps now provide an [`offset`](http://prosemirror.net/docs/ref/version/0.18.0.html#transform.Step.offset) method, which makes it possible to create a copy the step with its position offset by a given amount. + +[`docChanged`](http://prosemirror.net/docs/ref/version/0.18.0.html#transform.Transform.docChanged) is now a property on the `Transform` class, rather than its `Transaction` subclass. + +`Mapping` instances now have [`invert`](http://prosemirror.net/docs/ref/version/0.18.0.html#transform.Mapping.invert) and [`appendMappingInverted`](http://prosemirror.net/docs/ref/version/0.18.0.html#transform.Mapping.appendMappingInverted) methods to make mapping through them in reverse easier. + +## 0.15.0 (2016-12-10) + +### Bug fixes + +Fix bug where pasted/inserted content would sometimes get incorrectly closed at the right side. + +## 0.13.0 (2016-11-11) + +### Bug fixes + +Fix issue where [`Transform.replace`](http://prosemirror.net/docs/ref/version/0.13.0.html#transform.Transform.replace) would, in specific circumstances, unneccessarily drop content. + +### New features + +The new [`Transform`](http://prosemirror.net/docs/ref/version/0.13.0.html#transform.Transform) method [`replaceRange`](http://prosemirror.net/docs/ref/version/0.13.0.html#transform.Transform.replaceRange), [`replaceRangeWith`](http://prosemirror.net/docs/ref/version/0.13.0.html#transform.Transform.replaceRangeWith), and [`deleteRange`](http://prosemirror.net/docs/ref/version/0.13.0.html#transform.Transform.deleteRange) provide a way to replace and delete content in a 'do what I mean' way, automatically expanding the replaced region over empty parent nodes and including the parent nodes in the inserted content when appropriate. + +## 0.12.1 (2016-11-01) + +### Bug fixes + +Fix bug in `Transform.setBlockType` when used in a transform that already has steps. + +## 0.12.0 (2016-10-21) + +### Breaking changes + +Mapped positions now count as deleted when the token to the +side specified by the `assoc` parameter is deleted, rather than when +both tokens around them are deleted. (This is usually what you already +wanted anyway.) + +## 0.11.0 (2016-09-21) + +### Breaking changes + +Moved into a separate module. + +The `Remapping` class was renamed to `Mapping` and works differently +(simpler, grows in only one direction, and has provision for mapping +through only a part of it). + +[`Transform`](http://prosemirror.net/docs/ref/version/0.11.0.html#transform.Transform) objects now build up a `Mapping` +instead of an array of maps. + +`PosMap` was renamed to [`StepMap`](http://prosemirror.net/docs/ref/version/0.11.0.html#transform.StepMap) to make it +clearer that this applies only to a single step (as opposed to +[`Mapping`](http://prosemirror.net/docs/ref/version/0.11.0.html#transform.Mapping). + +The arguments to [`canSplit`](http://prosemirror.net/docs/ref/version/0.11.0.html#transform.canSplit) and +[`split`](http://prosemirror.net/docs/ref/version/0.11.0.html#transform.Transform.split) were changed to make it +possible to specify multiple split-off node types for splits with a +depth greater than 1. + +Rename `joinable` to [`canJoin`](http://prosemirror.net/docs/ref/version/0.11.0.html#transform.canJoin). + +### New features + +Steps can now be [merged](http://prosemirror.net/docs/ref/version/0.11.0.html#transform.Step.merge) in some +circumstances, which can be useful when storing a lot of them. + diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/CONTRIBUTING.md b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/CONTRIBUTING.md new file mode 100644 index 0000000000..f2a345d830 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/CONTRIBUTING.md @@ -0,0 +1,104 @@ +# How to contribute + +- [Getting help](#getting-help) +- [Submitting bug reports](#submitting-bug-reports) +- [Contributing code](#contributing-code) + +## Getting help + +Community discussion, questions, and informal bug reporting is done on the +[discuss.ProseMirror forum](http://discuss.prosemirror.net). + +## Submitting bug reports + +Report bugs on the +[GitHub issue tracker](http://github.com/prosemirror/prosemirror/issues). +Before reporting a bug, please read these pointers. + +- The issue tracker is for *bugs*, not requests for help. Questions + should be asked on the [forum](http://discuss.prosemirror.net). + +- Include information about the version of the code that exhibits the + problem. For browser-related issues, include the browser and browser + version on which the problem occurred. + +- Mention very precisely what went wrong. "X is broken" is not a good + bug report. What did you expect to happen? What happened instead? + Describe the exact steps a maintainer has to take to make the + problem occur. A screencast can be useful, but is no substitute for + a textual description. + +- A great way to make it easy to reproduce your problem, if it can not + be trivially reproduced on the website demos, is to submit a script + that triggers the issue. + +## Contributing code + +If you want to make a change that involves a significant overhaul of +the code or introduces a user-visible new feature, create an +[RFC](https://github.com/ProseMirror/rfcs/) first with your proposal. + +- Make sure you have a [GitHub Account](https://github.com/signup/free) + +- Fork the relevant repository + ([how to fork a repo](https://help.github.com/articles/fork-a-repo)) + +- Create a local checkout of the code. You can use the + [main repository](https://github.com/prosemirror/prosemirror) to + easily check out all core modules. + +- Make your changes, and commit them + +- Follow the code style of the rest of the project (see below). Run + `npm run lint` (in the main repository checkout) to make sure that + the linter is happy. + +- If your changes are easy to test or likely to regress, add tests in + the relevant `test/` directory. Either put them in an existing + `test-*.js` file, if they fit there, or add a new file. + +- Make sure all tests pass. Run `npm run test` to verify tests pass + (you will need Node.js v6+). + +- Submit a pull request ([how to create a pull request](https://help.github.com/articles/fork-a-repo)). + Don't put more than one feature/fix in a single pull request. + +By contributing code to ProseMirror you + + - Agree to license the contributed code under the project's [MIT + license](https://github.com/ProseMirror/prosemirror/blob/master/LICENSE). + + - Confirm that you have the right to contribute and license the code + in question. (Either you hold all rights on the code, or the rights + holder has explicitly granted the right to use it like this, + through a compatible open source license or through a direct + agreement with you.) + +### Coding standards + +- ES6 syntax, targeting an ES5 runtime (i.e. don't use library + elements added by ES6, don't use ES7/ES.next syntax). + +- 2 spaces per indentation level, no tabs. + +- No semicolons except when necessary. + +- Follow the surrounding code when it comes to spacing, brace + placement, etc. + +- Brace-less single-statement bodies are encouraged (whenever they + don't impact readability). + +- [getdocs](https://github.com/marijnh/getdocs)-style doc comments + above items that are part of the public API. + +- When documenting non-public items, you can put the type after a + single colon, so that getdocs doesn't pick it up and add it to the + API reference. + +- The linter (`npm run lint`) complains about unused variables and + functions. Prefix their names with an underscore to muffle it. + +- ProseMirror does *not* follow JSHint or JSLint prescribed style. + Patches that try to 'fix' code to pass one of these linters will not + be accepted. diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/LICENSE b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/LICENSE new file mode 100644 index 0000000000..ef9326c512 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2015-2017 by Marijn Haverbeke and others + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/README.md b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/README.md new file mode 100644 index 0000000000..e19d944ea9 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/README.md @@ -0,0 +1,29 @@ +# prosemirror-transform + +[ [**WEBSITE**](http://prosemirror.net) | [**ISSUES**](https://github.com/prosemirror/prosemirror/issues) | [**FORUM**](https://discuss.prosemirror.net) | [**GITTER**](https://gitter.im/ProseMirror/prosemirror) | [**CHANGELOG**](https://github.com/ProseMirror/prosemirror-transform/blob/master/CHANGELOG.md) ] + +This is a [core module](http://prosemirror.net/docs/ref/#transform) of [ProseMirror](http://prosemirror.net). +ProseMirror is a well-behaved rich semantic content editor based on +contentEditable, with support for collaborative editing and custom +document schemas. + +This [module](http://prosemirror.net/docs/ref/#transform) implements +document [transforms](http://prosemirror\.net/docs/guide/#transform), +which are used by the editor to treat changes as first-class values, +which can be saved, shared, and reasoned about. + +The [project page](http://prosemirror.net) has more information, a +number of [examples](http://prosemirror.net/examples/) and the +[documentation](http://prosemirror.net/docs/). + +This code is released under an +[MIT license](https://github.com/prosemirror/prosemirror/tree/master/LICENSE). +There's a [forum](http://discuss.prosemirror.net) for general +discussion and support requests, and the +[Github bug tracker](https://github.com/prosemirror/prosemirror/issues) +is the place to report issues. + +We aim to be an inclusive, welcoming community. To make that explicit, +we have a [code of +conduct](http://contributor-covenant.org/version/1/1/0/) that applies +to communication around the project. diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/dist/index.es.js b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/dist/index.es.js new file mode 100644 index 0000000000..abb467c635 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/dist/index.es.js @@ -0,0 +1,1689 @@ +import { ReplaceError, Slice, Fragment, MarkType } from 'prosemirror-model'; + +// Mappable:: interface +// There are several things that positions can be mapped through. +// Such objects conform to this interface. +// +// map:: (pos: number, assoc: ?number) → number +// Map a position through this object. When given, `assoc` (should +// be -1 or 1, defaults to 1) determines with which side the +// position is associated, which determines in which direction to +// move when a chunk of content is inserted at the mapped position. +// +// mapResult:: (pos: number, assoc: ?number) → MapResult +// Map a position, and return an object containing additional +// information about the mapping. The result's `deleted` field tells +// you whether the position was deleted (completely enclosed in a +// replaced range) during the mapping. When content on only one side +// is deleted, the position itself is only considered deleted when +// `assoc` points in the direction of the deleted content. + +// Recovery values encode a range index and an offset. They are +// represented as numbers, because tons of them will be created when +// mapping, for example, a large number of decorations. The number's +// lower 16 bits provide the index, the remaining bits the offset. +// +// Note: We intentionally don't use bit shift operators to en- and +// decode these, since those clip to 32 bits, which we might in rare +// cases want to overflow. A 64-bit float can represent 48-bit +// integers precisely. + +var lower16 = 0xffff; +var factor16 = Math.pow(2, 16); + +function makeRecover(index, offset) { return index + offset * factor16 } +function recoverIndex(value) { return value & lower16 } +function recoverOffset(value) { return (value - (value & lower16)) / factor16 } + +// ::- An object representing a mapped position with extra +// information. +var MapResult = function MapResult(pos, deleted, recover) { + if ( deleted === void 0 ) deleted = false; + if ( recover === void 0 ) recover = null; + + // :: number The mapped version of the position. + this.pos = pos; + // :: bool Tells you whether the position was deleted, that is, + // whether the step removed its surroundings from the document. + this.deleted = deleted; + this.recover = recover; +}; + +// :: class extends Mappable +// A map describing the deletions and insertions made by a step, which +// can be used to find the correspondence between positions in the +// pre-step version of a document and the same position in the +// post-step version. +var StepMap = function StepMap(ranges, inverted) { + if ( inverted === void 0 ) inverted = false; + + this.ranges = ranges; + this.inverted = inverted; +}; + +StepMap.prototype.recover = function recover (value) { + var diff = 0, index = recoverIndex(value); + if (!this.inverted) { for (var i = 0; i < index; i++) + { diff += this.ranges[i * 3 + 2] - this.ranges[i * 3 + 1]; } } + return this.ranges[index * 3] + diff + recoverOffset(value) +}; + +// : (number, ?number) → MapResult +StepMap.prototype.mapResult = function mapResult (pos, assoc) { + if ( assoc === void 0 ) assoc = 1; + return this._map(pos, assoc, false) }; + +// : (number, ?number) → number +StepMap.prototype.map = function map (pos, assoc) { + if ( assoc === void 0 ) assoc = 1; + return this._map(pos, assoc, true) }; + +StepMap.prototype._map = function _map (pos, assoc, simple) { + var diff = 0, oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; + for (var i = 0; i < this.ranges.length; i += 3) { + var start = this.ranges[i] - (this.inverted ? diff : 0); + if (start > pos) { break } + var oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex], end = start + oldSize; + if (pos <= end) { + var side = !oldSize ? assoc : pos == start ? -1 : pos == end ? 1 : assoc; + var result = start + diff + (side < 0 ? 0 : newSize); + if (simple) { return result } + var recover = makeRecover(i / 3, pos - start); + return new MapResult(result, assoc < 0 ? pos != start : pos != end, recover) + } + diff += newSize - oldSize; + } + return simple ? pos + diff : new MapResult(pos + diff) +}; + +StepMap.prototype.touches = function touches (pos, recover) { + var diff = 0, index = recoverIndex(recover); + var oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; + for (var i = 0; i < this.ranges.length; i += 3) { + var start = this.ranges[i] - (this.inverted ? diff : 0); + if (start > pos) { break } + var oldSize = this.ranges[i + oldIndex], end = start + oldSize; + if (pos <= end && i == index * 3) { return true } + diff += this.ranges[i + newIndex] - oldSize; + } + return false +}; + +// :: ((oldStart: number, oldEnd: number, newStart: number, newEnd: number)) +// Calls the given function on each of the changed ranges included in +// this map. +StepMap.prototype.forEach = function forEach (f) { + var oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; + for (var i = 0, diff = 0; i < this.ranges.length; i += 3) { + var start = this.ranges[i], oldStart = start - (this.inverted ? diff : 0), newStart = start + (this.inverted ? 0 : diff); + var oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex]; + f(oldStart, oldStart + oldSize, newStart, newStart + newSize); + diff += newSize - oldSize; + } +}; + +// :: () → StepMap +// Create an inverted version of this map. The result can be used to +// map positions in the post-step document to the pre-step document. +StepMap.prototype.invert = function invert () { + return new StepMap(this.ranges, !this.inverted) +}; + +StepMap.prototype.toString = function toString () { + return (this.inverted ? "-" : "") + JSON.stringify(this.ranges) +}; + +// :: (n: number) → StepMap +// Create a map that moves all positions by offset `n` (which may be +// negative). This can be useful when applying steps meant for a +// sub-document to a larger document, or vice-versa. +StepMap.offset = function offset (n) { + return n == 0 ? StepMap.empty : new StepMap(n < 0 ? [0, -n, 0] : [0, 0, n]) +}; + +StepMap.empty = new StepMap([]); + +// :: class extends Mappable +// A mapping represents a pipeline of zero or more [step +// maps](#transform.StepMap). It has special provisions for losslessly +// handling mapping positions through a series of steps in which some +// steps are inverted versions of earlier steps. (This comes up when +// ‘[rebasing](/docs/guide/#transform.rebasing)’ steps for +// collaboration or history management.) +var Mapping = function Mapping(maps, mirror, from, to) { + // :: [StepMap] + // The step maps in this mapping. + this.maps = maps || []; + // :: number + // The starting position in the `maps` array, used when `map` or + // `mapResult` is called. + this.from = from || 0; + // :: number + // The end position in the `maps` array. + this.to = to == null ? this.maps.length : to; + this.mirror = mirror; +}; + +// :: (?number, ?number) → Mapping +// Create a mapping that maps only through a part of this one. +Mapping.prototype.slice = function slice (from, to) { + if ( from === void 0 ) from = 0; + if ( to === void 0 ) to = this.maps.length; + + return new Mapping(this.maps, this.mirror, from, to) +}; + +Mapping.prototype.copy = function copy () { + return new Mapping(this.maps.slice(), this.mirror && this.mirror.slice(), this.from, this.to) +}; + +// :: (StepMap, ?number) +// Add a step map to the end of this mapping. If `mirrors` is +// given, it should be the index of the step map that is the mirror +// image of this one. +Mapping.prototype.appendMap = function appendMap (map, mirrors) { + this.to = this.maps.push(map); + if (mirrors != null) { this.setMirror(this.maps.length - 1, mirrors); } +}; + +// :: (Mapping) +// Add all the step maps in a given mapping to this one (preserving +// mirroring information). +Mapping.prototype.appendMapping = function appendMapping (mapping) { + for (var i = 0, startSize = this.maps.length; i < mapping.maps.length; i++) { + var mirr = mapping.getMirror(i); + this.appendMap(mapping.maps[i], mirr != null && mirr < i ? startSize + mirr : null); + } +}; + +// :: (number) → ?number +// Finds the offset of the step map that mirrors the map at the +// given offset, in this mapping (as per the second argument to +// `appendMap`). +Mapping.prototype.getMirror = function getMirror (n) { + if (this.mirror) { for (var i = 0; i < this.mirror.length; i++) + { if (this.mirror[i] == n) { return this.mirror[i + (i % 2 ? -1 : 1)] } } } +}; + +Mapping.prototype.setMirror = function setMirror (n, m) { + if (!this.mirror) { this.mirror = []; } + this.mirror.push(n, m); +}; + +// :: (Mapping) +// Append the inverse of the given mapping to this one. +Mapping.prototype.appendMappingInverted = function appendMappingInverted (mapping) { + for (var i = mapping.maps.length - 1, totalSize = this.maps.length + mapping.maps.length; i >= 0; i--) { + var mirr = mapping.getMirror(i); + this.appendMap(mapping.maps[i].invert(), mirr != null && mirr > i ? totalSize - mirr - 1 : null); + } +}; + +// :: () → Mapping +// Create an inverted version of this mapping. +Mapping.prototype.invert = function invert () { + var inverse = new Mapping; + inverse.appendMappingInverted(this); + return inverse +}; + +// : (number, ?number) → number +// Map a position through this mapping. +Mapping.prototype.map = function map (pos, assoc) { + if ( assoc === void 0 ) assoc = 1; + + if (this.mirror) { return this._map(pos, assoc, true) } + for (var i = this.from; i < this.to; i++) + { pos = this.maps[i].map(pos, assoc); } + return pos +}; + +// : (number, ?number) → MapResult +// Map a position through this mapping, returning a mapping +// result. +Mapping.prototype.mapResult = function mapResult (pos, assoc) { + if ( assoc === void 0 ) assoc = 1; + return this._map(pos, assoc, false) }; + +Mapping.prototype._map = function _map (pos, assoc, simple) { + var deleted = false, recoverables = null; + + for (var i = this.from; i < this.to; i++) { + var map = this.maps[i], rec = recoverables && recoverables[i]; + if (rec != null && map.touches(pos, rec)) { + pos = map.recover(rec); + continue + } + + var result = map.mapResult(pos, assoc); + if (result.recover != null) { + var corr = this.getMirror(i); + if (corr != null && corr > i && corr < this.to) { + if (result.deleted) { + i = corr; + pos = this.maps[corr].recover(result.recover); + continue + } else { +(recoverables || (recoverables = Object.create(null)))[corr] = result.recover; + } + } + } + + if (result.deleted) { deleted = true; } + pos = result.pos; + } + + return simple ? pos : new MapResult(pos, deleted) +}; + +function TransformError(message) { + var err = Error.call(this, message); + err.__proto__ = TransformError.prototype; + return err +} + +TransformError.prototype = Object.create(Error.prototype); +TransformError.prototype.constructor = TransformError; +TransformError.prototype.name = "TransformError"; + +// ::- Abstraction to build up and track an array of +// [steps](#transform.Step) representing a document transformation. +// +// Most transforming methods return the `Transform` object itself, so +// that they can be chained. +var Transform = function Transform(doc) { + // :: Node + // The current document (the result of applying the steps in the + // transform). + this.doc = doc; + // :: [Step] + // The steps in this transform. + this.steps = []; + // :: [Node] + // The documents before each of the steps. + this.docs = []; + // :: Mapping + // A mapping with the maps for each of the steps in this transform. + this.mapping = new Mapping; +}; + +var prototypeAccessors = { before: { configurable: true },docChanged: { configurable: true } }; + +// :: Node The starting document. +prototypeAccessors.before.get = function () { return this.docs.length ? this.docs[0] : this.doc }; + +// :: (step: Step) → this +// Apply a new step in this transform, saving the result. Throws an +// error when the step fails. +Transform.prototype.step = function step (object) { + var result = this.maybeStep(object); + if (result.failed) { throw new TransformError(result.failed) } + return this +}; + +// :: (Step) → StepResult +// Try to apply a step in this transformation, ignoring it if it +// fails. Returns the step result. +Transform.prototype.maybeStep = function maybeStep (step) { + var result = step.apply(this.doc); + if (!result.failed) { this.addStep(step, result.doc); } + return result +}; + +// :: bool +// True when the document has been changed (when there are any +// steps). +prototypeAccessors.docChanged.get = function () { + return this.steps.length > 0 +}; + +Transform.prototype.addStep = function addStep (step, doc) { + this.docs.push(this.doc); + this.steps.push(step); + this.mapping.appendMap(step.getMap()); + this.doc = doc; +}; + +Object.defineProperties( Transform.prototype, prototypeAccessors ); + +function mustOverride() { throw new Error("Override me") } + +var stepsByID = Object.create(null); + +// ::- A step object represents an atomic change. It generally applies +// only to the document it was created for, since the positions +// stored in it will only make sense for that document. +// +// New steps are defined by creating classes that extend `Step`, +// overriding the `apply`, `invert`, `map`, `getMap` and `fromJSON` +// methods, and registering your class with a unique +// JSON-serialization identifier using +// [`Step.jsonID`](#transform.Step^jsonID). +var Step = function Step () {}; + +Step.prototype.apply = function apply (_doc) { return mustOverride() }; + +// :: () → StepMap +// Get the step map that represents the changes made by this step, +// and which can be used to transform between positions in the old +// and the new document. +Step.prototype.getMap = function getMap () { return StepMap.empty }; + +// :: (doc: Node) → Step +// Create an inverted version of this step. Needs the document as it +// was before the step as argument. +Step.prototype.invert = function invert (_doc) { return mustOverride() }; + +// :: (mapping: Mappable) → ?Step +// Map this step through a mappable thing, returning either a +// version of that step with its positions adjusted, or `null` if +// the step was entirely deleted by the mapping. +Step.prototype.map = function map (_mapping) { return mustOverride() }; + +// :: (other: Step) → ?Step +// Try to merge this step with another one, to be applied directly +// after it. Returns the merged step when possible, null if the +// steps can't be merged. +Step.prototype.merge = function merge (_other) { return null }; + +// :: () → Object +// Create a JSON-serializeable representation of this step. When +// defining this for a custom subclass, make sure the result object +// includes the step type's [JSON id](#transform.Step^jsonID) under +// the `stepType` property. +Step.prototype.toJSON = function toJSON () { return mustOverride() }; + +// :: (Schema, Object) → Step +// Deserialize a step from its JSON representation. Will call +// through to the step class' own implementation of this method. +Step.fromJSON = function fromJSON (schema, json) { + if (!json || !json.stepType) { throw new RangeError("Invalid input for Step.fromJSON") } + var type = stepsByID[json.stepType]; + if (!type) { throw new RangeError(("No step type " + (json.stepType) + " defined")) } + return type.fromJSON(schema, json) +}; + +// :: (string, constructor) +// To be able to serialize steps to JSON, each step needs a string +// ID to attach to its JSON representation. Use this method to +// register an ID for your step classes. Try to pick something +// that's unlikely to clash with steps from other modules. +Step.jsonID = function jsonID (id, stepClass) { + if (id in stepsByID) { throw new RangeError("Duplicate use of step JSON ID " + id) } + stepsByID[id] = stepClass; + stepClass.prototype.jsonID = id; + return stepClass +}; + +// ::- The result of [applying](#transform.Step.apply) a step. Contains either a +// new document or a failure value. +var StepResult = function StepResult(doc, failed) { + // :: ?Node The transformed document. + this.doc = doc; + // :: ?string Text providing information about a failed step. + this.failed = failed; +}; + +// :: (Node) → StepResult +// Create a successful step result. +StepResult.ok = function ok (doc) { return new StepResult(doc, null) }; + +// :: (string) → StepResult +// Create a failed step result. +StepResult.fail = function fail (message) { return new StepResult(null, message) }; + +// :: (Node, number, number, Slice) → StepResult +// Call [`Node.replace`](#model.Node.replace) with the given +// arguments. Create a successful result if it succeeds, and a +// failed one if it throws a `ReplaceError`. +StepResult.fromReplace = function fromReplace (doc, from, to, slice) { + try { + return StepResult.ok(doc.replace(from, to, slice)) + } catch (e) { + if (e instanceof ReplaceError) { return StepResult.fail(e.message) } + throw e + } +}; + +// ::- Replace a part of the document with a slice of new content. +var ReplaceStep = /*@__PURE__*/(function (Step) { + function ReplaceStep(from, to, slice, structure) { + Step.call(this); + this.from = from; + this.to = to; + this.slice = slice; + this.structure = !!structure; + } + + if ( Step ) ReplaceStep.__proto__ = Step; + ReplaceStep.prototype = Object.create( Step && Step.prototype ); + ReplaceStep.prototype.constructor = ReplaceStep; + + ReplaceStep.prototype.apply = function apply (doc) { + if (this.structure && contentBetween(doc, this.from, this.to)) + { return StepResult.fail("Structure replace would overwrite content") } + return StepResult.fromReplace(doc, this.from, this.to, this.slice) + }; + + ReplaceStep.prototype.getMap = function getMap () { + return new StepMap([this.from, this.to - this.from, this.slice.size]) + }; + + ReplaceStep.prototype.invert = function invert (doc) { + return new ReplaceStep(this.from, this.from + this.slice.size, doc.slice(this.from, this.to)) + }; + + ReplaceStep.prototype.map = function map (mapping) { + var from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); + if (from.deleted && to.deleted) { return null } + return new ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice) + }; + + ReplaceStep.prototype.merge = function merge (other) { + if (!(other instanceof ReplaceStep) || other.structure != this.structure) { return null } + + if (this.from + this.slice.size == other.from && !this.slice.openEnd && !other.slice.openStart) { + var slice = this.slice.size + other.slice.size == 0 ? Slice.empty + : new Slice(this.slice.content.append(other.slice.content), this.slice.openStart, other.slice.openEnd); + return new ReplaceStep(this.from, this.to + (other.to - other.from), slice, this.structure) + } else if (other.to == this.from && !this.slice.openStart && !other.slice.openEnd) { + var slice$1 = this.slice.size + other.slice.size == 0 ? Slice.empty + : new Slice(other.slice.content.append(this.slice.content), other.slice.openStart, this.slice.openEnd); + return new ReplaceStep(other.from, this.to, slice$1, this.structure) + } else { + return null + } + }; + + ReplaceStep.prototype.toJSON = function toJSON () { + var json = {stepType: "replace", from: this.from, to: this.to}; + if (this.slice.size) { json.slice = this.slice.toJSON(); } + if (this.structure) { json.structure = true; } + return json + }; + + ReplaceStep.fromJSON = function fromJSON (schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + { throw new RangeError("Invalid input for ReplaceStep.fromJSON") } + return new ReplaceStep(json.from, json.to, Slice.fromJSON(schema, json.slice), !!json.structure) + }; + + return ReplaceStep; +}(Step)); + +Step.jsonID("replace", ReplaceStep); + +// ::- Replace a part of the document with a slice of content, but +// preserve a range of the replaced content by moving it into the +// slice. +var ReplaceAroundStep = /*@__PURE__*/(function (Step) { + function ReplaceAroundStep(from, to, gapFrom, gapTo, slice, insert, structure) { + Step.call(this); + this.from = from; + this.to = to; + this.gapFrom = gapFrom; + this.gapTo = gapTo; + this.slice = slice; + this.insert = insert; + this.structure = !!structure; + } + + if ( Step ) ReplaceAroundStep.__proto__ = Step; + ReplaceAroundStep.prototype = Object.create( Step && Step.prototype ); + ReplaceAroundStep.prototype.constructor = ReplaceAroundStep; + + ReplaceAroundStep.prototype.apply = function apply (doc) { + if (this.structure && (contentBetween(doc, this.from, this.gapFrom) || + contentBetween(doc, this.gapTo, this.to))) + { return StepResult.fail("Structure gap-replace would overwrite content") } + + var gap = doc.slice(this.gapFrom, this.gapTo); + if (gap.openStart || gap.openEnd) + { return StepResult.fail("Gap is not a flat range") } + var inserted = this.slice.insertAt(this.insert, gap.content); + if (!inserted) { return StepResult.fail("Content does not fit in gap") } + return StepResult.fromReplace(doc, this.from, this.to, inserted) + }; + + ReplaceAroundStep.prototype.getMap = function getMap () { + return new StepMap([this.from, this.gapFrom - this.from, this.insert, + this.gapTo, this.to - this.gapTo, this.slice.size - this.insert]) + }; + + ReplaceAroundStep.prototype.invert = function invert (doc) { + var gap = this.gapTo - this.gapFrom; + return new ReplaceAroundStep(this.from, this.from + this.slice.size + gap, + this.from + this.insert, this.from + this.insert + gap, + doc.slice(this.from, this.to).removeBetween(this.gapFrom - this.from, this.gapTo - this.from), + this.gapFrom - this.from, this.structure) + }; + + ReplaceAroundStep.prototype.map = function map (mapping) { + var from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); + var gapFrom = mapping.map(this.gapFrom, -1), gapTo = mapping.map(this.gapTo, 1); + if ((from.deleted && to.deleted) || gapFrom < from.pos || gapTo > to.pos) { return null } + return new ReplaceAroundStep(from.pos, to.pos, gapFrom, gapTo, this.slice, this.insert, this.structure) + }; + + ReplaceAroundStep.prototype.toJSON = function toJSON () { + var json = {stepType: "replaceAround", from: this.from, to: this.to, + gapFrom: this.gapFrom, gapTo: this.gapTo, insert: this.insert}; + if (this.slice.size) { json.slice = this.slice.toJSON(); } + if (this.structure) { json.structure = true; } + return json + }; + + ReplaceAroundStep.fromJSON = function fromJSON (schema, json) { + if (typeof json.from != "number" || typeof json.to != "number" || + typeof json.gapFrom != "number" || typeof json.gapTo != "number" || typeof json.insert != "number") + { throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON") } + return new ReplaceAroundStep(json.from, json.to, json.gapFrom, json.gapTo, + Slice.fromJSON(schema, json.slice), json.insert, !!json.structure) + }; + + return ReplaceAroundStep; +}(Step)); + +Step.jsonID("replaceAround", ReplaceAroundStep); + +function contentBetween(doc, from, to) { + var $from = doc.resolve(from), dist = to - from, depth = $from.depth; + while (dist > 0 && depth > 0 && $from.indexAfter(depth) == $from.node(depth).childCount) { + depth--; + dist--; + } + if (dist > 0) { + var next = $from.node(depth).maybeChild($from.indexAfter(depth)); + while (dist > 0) { + if (!next || next.isLeaf) { return true } + next = next.firstChild; + dist--; + } + } + return false +} + +function canCut(node, start, end) { + return (start == 0 || node.canReplace(start, node.childCount)) && + (end == node.childCount || node.canReplace(0, end)) +} + +// :: (NodeRange) → ?number +// Try to find a target depth to which the content in the given range +// can be lifted. Will not go across +// [isolating](#model.NodeSpec.isolating) parent nodes. +function liftTarget(range) { + var parent = range.parent; + var content = parent.content.cutByIndex(range.startIndex, range.endIndex); + for (var depth = range.depth;; --depth) { + var node = range.$from.node(depth); + var index = range.$from.index(depth), endIndex = range.$to.indexAfter(depth); + if (depth < range.depth && node.canReplace(index, endIndex, content)) + { return depth } + if (depth == 0 || node.type.spec.isolating || !canCut(node, index, endIndex)) { break } + } +} + +// :: (NodeRange, number) → this +// Split the content in the given range off from its parent, if there +// is sibling content before or after it, and move it up the tree to +// the depth specified by `target`. You'll probably want to use +// [`liftTarget`](#transform.liftTarget) to compute `target`, to make +// sure the lift is valid. +Transform.prototype.lift = function(range, target) { + var $from = range.$from; + var $to = range.$to; + var depth = range.depth; + + var gapStart = $from.before(depth + 1), gapEnd = $to.after(depth + 1); + var start = gapStart, end = gapEnd; + + var before = Fragment.empty, openStart = 0; + for (var d = depth, splitting = false; d > target; d--) + { if (splitting || $from.index(d) > 0) { + splitting = true; + before = Fragment.from($from.node(d).copy(before)); + openStart++; + } else { + start--; + } } + var after = Fragment.empty, openEnd = 0; + for (var d$1 = depth, splitting$1 = false; d$1 > target; d$1--) + { if (splitting$1 || $to.after(d$1 + 1) < $to.end(d$1)) { + splitting$1 = true; + after = Fragment.from($to.node(d$1).copy(after)); + openEnd++; + } else { + end++; + } } + + return this.step(new ReplaceAroundStep(start, end, gapStart, gapEnd, + new Slice(before.append(after), openStart, openEnd), + before.size - openStart, true)) +}; + +// :: (NodeRange, NodeType, ?Object, ?NodeRange) → ?[{type: NodeType, attrs: ?Object}] +// Try to find a valid way to wrap the content in the given range in a +// node of the given type. May introduce extra nodes around and inside +// the wrapper node, if necessary. Returns null if no valid wrapping +// could be found. When `innerRange` is given, that range's content is +// used as the content to fit into the wrapping, instead of the +// content of `range`. +function findWrapping(range, nodeType, attrs, innerRange) { + if ( innerRange === void 0 ) innerRange = range; + + var around = findWrappingOutside(range, nodeType); + var inner = around && findWrappingInside(innerRange, nodeType); + if (!inner) { return null } + return around.map(withAttrs).concat({type: nodeType, attrs: attrs}).concat(inner.map(withAttrs)) +} + +function withAttrs(type) { return {type: type, attrs: null} } + +function findWrappingOutside(range, type) { + var parent = range.parent; + var startIndex = range.startIndex; + var endIndex = range.endIndex; + var around = parent.contentMatchAt(startIndex).findWrapping(type); + if (!around) { return null } + var outer = around.length ? around[0] : type; + return parent.canReplaceWith(startIndex, endIndex, outer) ? around : null +} + +function findWrappingInside(range, type) { + var parent = range.parent; + var startIndex = range.startIndex; + var endIndex = range.endIndex; + var inner = parent.child(startIndex); + var inside = type.contentMatch.findWrapping(inner.type); + if (!inside) { return null } + var lastType = inside.length ? inside[inside.length - 1] : type; + var innerMatch = lastType.contentMatch; + for (var i = startIndex; innerMatch && i < endIndex; i++) + { innerMatch = innerMatch.matchType(parent.child(i).type); } + if (!innerMatch || !innerMatch.validEnd) { return null } + return inside +} + +// :: (NodeRange, [{type: NodeType, attrs: ?Object}]) → this +// Wrap the given [range](#model.NodeRange) in the given set of wrappers. +// The wrappers are assumed to be valid in this position, and should +// probably be computed with [`findWrapping`](#transform.findWrapping). +Transform.prototype.wrap = function(range, wrappers) { + var content = Fragment.empty; + for (var i = wrappers.length - 1; i >= 0; i--) + { content = Fragment.from(wrappers[i].type.create(wrappers[i].attrs, content)); } + + var start = range.start, end = range.end; + return this.step(new ReplaceAroundStep(start, end, start, end, new Slice(content, 0, 0), wrappers.length, true)) +}; + +// :: (number, ?number, NodeType, ?Object) → this +// Set the type of all textblocks (partly) between `from` and `to` to +// the given node type with the given attributes. +Transform.prototype.setBlockType = function(from, to, type, attrs) { + var this$1 = this; + if ( to === void 0 ) to = from; + + if (!type.isTextblock) { throw new RangeError("Type given to setBlockType should be a textblock") } + var mapFrom = this.steps.length; + this.doc.nodesBetween(from, to, function (node, pos) { + if (node.isTextblock && !node.hasMarkup(type, attrs) && canChangeType(this$1.doc, this$1.mapping.slice(mapFrom).map(pos), type)) { + // Ensure all markup that isn't allowed in the new node type is cleared + this$1.clearIncompatible(this$1.mapping.slice(mapFrom).map(pos, 1), type); + var mapping = this$1.mapping.slice(mapFrom); + var startM = mapping.map(pos, 1), endM = mapping.map(pos + node.nodeSize, 1); + this$1.step(new ReplaceAroundStep(startM, endM, startM + 1, endM - 1, + new Slice(Fragment.from(type.create(attrs, null, node.marks)), 0, 0), 1, true)); + return false + } + }); + return this +}; + +function canChangeType(doc, pos, type) { + var $pos = doc.resolve(pos), index = $pos.index(); + return $pos.parent.canReplaceWith(index, index + 1, type) +} + +// :: (number, ?NodeType, ?Object, ?[Mark]) → this +// Change the type, attributes, and/or marks of the node at `pos`. +// When `type` isn't given, the existing node type is preserved, +Transform.prototype.setNodeMarkup = function(pos, type, attrs, marks) { + var node = this.doc.nodeAt(pos); + if (!node) { throw new RangeError("No node at given position") } + if (!type) { type = node.type; } + var newNode = type.create(attrs, null, marks || node.marks); + if (node.isLeaf) + { return this.replaceWith(pos, pos + node.nodeSize, newNode) } + + if (!type.validContent(node.content)) + { throw new RangeError("Invalid content for node type " + type.name) } + + return this.step(new ReplaceAroundStep(pos, pos + node.nodeSize, pos + 1, pos + node.nodeSize - 1, + new Slice(Fragment.from(newNode), 0, 0), 1, true)) +}; + +// :: (Node, number, number, ?[?{type: NodeType, attrs: ?Object}]) → bool +// Check whether splitting at the given position is allowed. +function canSplit(doc, pos, depth, typesAfter) { + if ( depth === void 0 ) depth = 1; + + var $pos = doc.resolve(pos), base = $pos.depth - depth; + var innerType = (typesAfter && typesAfter[typesAfter.length - 1]) || $pos.parent; + if (base < 0 || $pos.parent.type.spec.isolating || + !$pos.parent.canReplace($pos.index(), $pos.parent.childCount) || + !innerType.type.validContent($pos.parent.content.cutByIndex($pos.index(), $pos.parent.childCount))) + { return false } + for (var d = $pos.depth - 1, i = depth - 2; d > base; d--, i--) { + var node = $pos.node(d), index$1 = $pos.index(d); + if (node.type.spec.isolating) { return false } + var rest = node.content.cutByIndex(index$1, node.childCount); + var after = (typesAfter && typesAfter[i]) || node; + if (after != node) { rest = rest.replaceChild(0, after.type.create(after.attrs)); } + if (!node.canReplace(index$1 + 1, node.childCount) || !after.type.validContent(rest)) + { return false } + } + var index = $pos.indexAfter(base); + var baseType = typesAfter && typesAfter[0]; + return $pos.node(base).canReplaceWith(index, index, baseType ? baseType.type : $pos.node(base + 1).type) +} + +// :: (number, ?number, ?[?{type: NodeType, attrs: ?Object}]) → this +// Split the node at the given position, and optionally, if `depth` is +// greater than one, any number of nodes above that. By default, the +// parts split off will inherit the node type of the original node. +// This can be changed by passing an array of types and attributes to +// use after the split. +Transform.prototype.split = function(pos, depth, typesAfter) { + if ( depth === void 0 ) depth = 1; + + var $pos = this.doc.resolve(pos), before = Fragment.empty, after = Fragment.empty; + for (var d = $pos.depth, e = $pos.depth - depth, i = depth - 1; d > e; d--, i--) { + before = Fragment.from($pos.node(d).copy(before)); + var typeAfter = typesAfter && typesAfter[i]; + after = Fragment.from(typeAfter ? typeAfter.type.create(typeAfter.attrs, after) : $pos.node(d).copy(after)); + } + return this.step(new ReplaceStep(pos, pos, new Slice(before.append(after), depth, depth), true)) +}; + +// :: (Node, number) → bool +// Test whether the blocks before and after a given position can be +// joined. +function canJoin(doc, pos) { + var $pos = doc.resolve(pos), index = $pos.index(); + return joinable($pos.nodeBefore, $pos.nodeAfter) && + $pos.parent.canReplace(index, index + 1) +} + +function joinable(a, b) { + return a && b && !a.isLeaf && a.canAppend(b) +} + +// :: (Node, number, ?number) → ?number +// Find an ancestor of the given position that can be joined to the +// block before (or after if `dir` is positive). Returns the joinable +// point, if any. +function joinPoint(doc, pos, dir) { + if ( dir === void 0 ) dir = -1; + + var $pos = doc.resolve(pos); + for (var d = $pos.depth;; d--) { + var before = (void 0), after = (void 0); + if (d == $pos.depth) { + before = $pos.nodeBefore; + after = $pos.nodeAfter; + } else if (dir > 0) { + before = $pos.node(d + 1); + after = $pos.node(d).maybeChild($pos.index(d) + 1); + } else { + before = $pos.node(d).maybeChild($pos.index(d) - 1); + after = $pos.node(d + 1); + } + if (before && !before.isTextblock && joinable(before, after)) { return pos } + if (d == 0) { break } + pos = dir < 0 ? $pos.before(d) : $pos.after(d); + } +} + +// :: (number, ?number) → this +// Join the blocks around the given position. If depth is 2, their +// last and first siblings are also joined, and so on. +Transform.prototype.join = function(pos, depth) { + if ( depth === void 0 ) depth = 1; + + var step = new ReplaceStep(pos - depth, pos + depth, Slice.empty, true); + return this.step(step) +}; + +// :: (Node, number, NodeType) → ?number +// Try to find a point where a node of the given type can be inserted +// near `pos`, by searching up the node hierarchy when `pos` itself +// isn't a valid place but is at the start or end of a node. Return +// null if no position was found. +function insertPoint(doc, pos, nodeType) { + var $pos = doc.resolve(pos); + if ($pos.parent.canReplaceWith($pos.index(), $pos.index(), nodeType)) { return pos } + + if ($pos.parentOffset == 0) + { for (var d = $pos.depth - 1; d >= 0; d--) { + var index = $pos.index(d); + if ($pos.node(d).canReplaceWith(index, index, nodeType)) { return $pos.before(d + 1) } + if (index > 0) { return null } + } } + if ($pos.parentOffset == $pos.parent.content.size) + { for (var d$1 = $pos.depth - 1; d$1 >= 0; d$1--) { + var index$1 = $pos.indexAfter(d$1); + if ($pos.node(d$1).canReplaceWith(index$1, index$1, nodeType)) { return $pos.after(d$1 + 1) } + if (index$1 < $pos.node(d$1).childCount) { return null } + } } +} + +// :: (Node, number, Slice) → ?number +// Finds a position at or around the given position where the given +// slice can be inserted. Will look at parent nodes' nearest boundary +// and try there, even if the original position wasn't directly at the +// start or end of that node. Returns null when no position was found. +function dropPoint(doc, pos, slice) { + var $pos = doc.resolve(pos); + if (!slice.content.size) { return pos } + var content = slice.content; + for (var i = 0; i < slice.openStart; i++) { content = content.firstChild.content; } + for (var pass = 1; pass <= (slice.openStart == 0 && slice.size ? 2 : 1); pass++) { + for (var d = $pos.depth; d >= 0; d--) { + var bias = d == $pos.depth ? 0 : $pos.pos <= ($pos.start(d + 1) + $pos.end(d + 1)) / 2 ? -1 : 1; + var insertPos = $pos.index(d) + (bias > 0 ? 1 : 0); + if (pass == 1 + ? $pos.node(d).canReplace(insertPos, insertPos, content) + : $pos.node(d).contentMatchAt(insertPos).findWrapping(content.firstChild.type)) + { return bias == 0 ? $pos.pos : bias < 0 ? $pos.before(d + 1) : $pos.after(d + 1) } + } + } + return null +} + +function mapFragment(fragment, f, parent) { + var mapped = []; + for (var i = 0; i < fragment.childCount; i++) { + var child = fragment.child(i); + if (child.content.size) { child = child.copy(mapFragment(child.content, f, child)); } + if (child.isInline) { child = f(child, parent, i); } + mapped.push(child); + } + return Fragment.fromArray(mapped) +} + +// ::- Add a mark to all inline content between two positions. +var AddMarkStep = /*@__PURE__*/(function (Step) { + function AddMarkStep(from, to, mark) { + Step.call(this); + this.from = from; + this.to = to; + this.mark = mark; + } + + if ( Step ) AddMarkStep.__proto__ = Step; + AddMarkStep.prototype = Object.create( Step && Step.prototype ); + AddMarkStep.prototype.constructor = AddMarkStep; + + AddMarkStep.prototype.apply = function apply (doc) { + var this$1 = this; + + var oldSlice = doc.slice(this.from, this.to), $from = doc.resolve(this.from); + var parent = $from.node($from.sharedDepth(this.to)); + var slice = new Slice(mapFragment(oldSlice.content, function (node, parent) { + if (!parent.type.allowsMarkType(this$1.mark.type)) { return node } + return node.mark(this$1.mark.addToSet(node.marks)) + }, parent), oldSlice.openStart, oldSlice.openEnd); + return StepResult.fromReplace(doc, this.from, this.to, slice) + }; + + AddMarkStep.prototype.invert = function invert () { + return new RemoveMarkStep(this.from, this.to, this.mark) + }; + + AddMarkStep.prototype.map = function map (mapping) { + var from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); + if (from.deleted && to.deleted || from.pos >= to.pos) { return null } + return new AddMarkStep(from.pos, to.pos, this.mark) + }; + + AddMarkStep.prototype.merge = function merge (other) { + if (other instanceof AddMarkStep && + other.mark.eq(this.mark) && + this.from <= other.to && this.to >= other.from) + { return new AddMarkStep(Math.min(this.from, other.from), + Math.max(this.to, other.to), this.mark) } + }; + + AddMarkStep.prototype.toJSON = function toJSON () { + return {stepType: "addMark", mark: this.mark.toJSON(), + from: this.from, to: this.to} + }; + + AddMarkStep.fromJSON = function fromJSON (schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + { throw new RangeError("Invalid input for AddMarkStep.fromJSON") } + return new AddMarkStep(json.from, json.to, schema.markFromJSON(json.mark)) + }; + + return AddMarkStep; +}(Step)); + +Step.jsonID("addMark", AddMarkStep); + +// ::- Remove a mark from all inline content between two positions. +var RemoveMarkStep = /*@__PURE__*/(function (Step) { + function RemoveMarkStep(from, to, mark) { + Step.call(this); + this.from = from; + this.to = to; + this.mark = mark; + } + + if ( Step ) RemoveMarkStep.__proto__ = Step; + RemoveMarkStep.prototype = Object.create( Step && Step.prototype ); + RemoveMarkStep.prototype.constructor = RemoveMarkStep; + + RemoveMarkStep.prototype.apply = function apply (doc) { + var this$1 = this; + + var oldSlice = doc.slice(this.from, this.to); + var slice = new Slice(mapFragment(oldSlice.content, function (node) { + return node.mark(this$1.mark.removeFromSet(node.marks)) + }), oldSlice.openStart, oldSlice.openEnd); + return StepResult.fromReplace(doc, this.from, this.to, slice) + }; + + RemoveMarkStep.prototype.invert = function invert () { + return new AddMarkStep(this.from, this.to, this.mark) + }; + + RemoveMarkStep.prototype.map = function map (mapping) { + var from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); + if (from.deleted && to.deleted || from.pos >= to.pos) { return null } + return new RemoveMarkStep(from.pos, to.pos, this.mark) + }; + + RemoveMarkStep.prototype.merge = function merge (other) { + if (other instanceof RemoveMarkStep && + other.mark.eq(this.mark) && + this.from <= other.to && this.to >= other.from) + { return new RemoveMarkStep(Math.min(this.from, other.from), + Math.max(this.to, other.to), this.mark) } + }; + + RemoveMarkStep.prototype.toJSON = function toJSON () { + return {stepType: "removeMark", mark: this.mark.toJSON(), + from: this.from, to: this.to} + }; + + RemoveMarkStep.fromJSON = function fromJSON (schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + { throw new RangeError("Invalid input for RemoveMarkStep.fromJSON") } + return new RemoveMarkStep(json.from, json.to, schema.markFromJSON(json.mark)) + }; + + return RemoveMarkStep; +}(Step)); + +Step.jsonID("removeMark", RemoveMarkStep); + +// :: (number, number, Mark) → this +// Add the given mark to the inline content between `from` and `to`. +Transform.prototype.addMark = function(from, to, mark) { + var this$1 = this; + + var removed = [], added = [], removing = null, adding = null; + this.doc.nodesBetween(from, to, function (node, pos, parent) { + if (!node.isInline) { return } + var marks = node.marks; + if (!mark.isInSet(marks) && parent.type.allowsMarkType(mark.type)) { + var start = Math.max(pos, from), end = Math.min(pos + node.nodeSize, to); + var newSet = mark.addToSet(marks); + + for (var i = 0; i < marks.length; i++) { + if (!marks[i].isInSet(newSet)) { + if (removing && removing.to == start && removing.mark.eq(marks[i])) + { removing.to = end; } + else + { removed.push(removing = new RemoveMarkStep(start, end, marks[i])); } + } + } + + if (adding && adding.to == start) + { adding.to = end; } + else + { added.push(adding = new AddMarkStep(start, end, mark)); } + } + }); + + removed.forEach(function (s) { return this$1.step(s); }); + added.forEach(function (s) { return this$1.step(s); }); + return this +}; + +// :: (number, number, ?union) → this +// Remove marks from inline nodes between `from` and `to`. When `mark` +// is a single mark, remove precisely that mark. When it is a mark type, +// remove all marks of that type. When it is null, remove all marks of +// any type. +Transform.prototype.removeMark = function(from, to, mark) { + var this$1 = this; + if ( mark === void 0 ) mark = null; + + var matched = [], step = 0; + this.doc.nodesBetween(from, to, function (node, pos) { + if (!node.isInline) { return } + step++; + var toRemove = null; + if (mark instanceof MarkType) { + var found = mark.isInSet(node.marks); + if (found) { toRemove = [found]; } + } else if (mark) { + if (mark.isInSet(node.marks)) { toRemove = [mark]; } + } else { + toRemove = node.marks; + } + if (toRemove && toRemove.length) { + var end = Math.min(pos + node.nodeSize, to); + for (var i = 0; i < toRemove.length; i++) { + var style = toRemove[i], found$1 = (void 0); + for (var j = 0; j < matched.length; j++) { + var m = matched[j]; + if (m.step == step - 1 && style.eq(matched[j].style)) { found$1 = m; } + } + if (found$1) { + found$1.to = end; + found$1.step = step; + } else { + matched.push({style: style, from: Math.max(pos, from), to: end, step: step}); + } + } + } + }); + matched.forEach(function (m) { return this$1.step(new RemoveMarkStep(m.from, m.to, m.style)); }); + return this +}; + +// :: (number, NodeType, ?ContentMatch) → this +// Removes all marks and nodes from the content of the node at `pos` +// that don't match the given new parent node type. Accepts an +// optional starting [content match](#model.ContentMatch) as third +// argument. +Transform.prototype.clearIncompatible = function(pos, parentType, match) { + if ( match === void 0 ) match = parentType.contentMatch; + + var node = this.doc.nodeAt(pos); + var delSteps = [], cur = pos + 1; + for (var i = 0; i < node.childCount; i++) { + var child = node.child(i), end = cur + child.nodeSize; + var allowed = match.matchType(child.type, child.attrs); + if (!allowed) { + delSteps.push(new ReplaceStep(cur, end, Slice.empty)); + } else { + match = allowed; + for (var j = 0; j < child.marks.length; j++) { if (!parentType.allowsMarkType(child.marks[j].type)) + { this.step(new RemoveMarkStep(cur, end, child.marks[j])); } } + } + cur = end; + } + if (!match.validEnd) { + var fill = match.fillBefore(Fragment.empty, true); + this.replace(cur, cur, new Slice(fill, 0, 0)); + } + for (var i$1 = delSteps.length - 1; i$1 >= 0; i$1--) { this.step(delSteps[i$1]); } + return this +}; + +// :: (Node, number, ?number, ?Slice) → ?Step +// ‘Fit’ a slice into a given position in the document, producing a +// [step](#transform.Step) that inserts it. Will return null if +// there's no meaningful way to insert the slice here, or inserting it +// would be a no-op (an empty slice over an empty range). +function replaceStep(doc, from, to, slice) { + if ( to === void 0 ) to = from; + if ( slice === void 0 ) slice = Slice.empty; + + if (from == to && !slice.size) { return null } + + var $from = doc.resolve(from), $to = doc.resolve(to); + // Optimization -- avoid work if it's obvious that it's not needed. + if (fitsTrivially($from, $to, slice)) { return new ReplaceStep(from, to, slice) } + var placed = placeSlice($from, slice); + + var fittedLeft = fitLeft($from, placed); + var fitted = fitRight($from, $to, fittedLeft); + if (!fitted) { return null } + if (fittedLeft.size != fitted.size && canMoveText($from, $to, fittedLeft)) { + var d = $to.depth, after = $to.after(d); + while (d > 1 && after == $to.end(--d)) { ++after; } + var fittedAfter = fitRight($from, doc.resolve(after), fittedLeft); + if (fittedAfter) + { return new ReplaceAroundStep(from, after, to, $to.end(), fittedAfter, fittedLeft.size) } + } + return fitted.size || from != to ? new ReplaceStep(from, to, fitted) : null +} + +// :: (number, ?number, ?Slice) → this +// Replace the part of the document between `from` and `to` with the +// given `slice`. +Transform.prototype.replace = function(from, to, slice) { + if ( to === void 0 ) to = from; + if ( slice === void 0 ) slice = Slice.empty; + + var step = replaceStep(this.doc, from, to, slice); + if (step) { this.step(step); } + return this +}; + +// :: (number, number, union) → this +// Replace the given range with the given content, which may be a +// fragment, node, or array of nodes. +Transform.prototype.replaceWith = function(from, to, content) { + return this.replace(from, to, new Slice(Fragment.from(content), 0, 0)) +}; + +// :: (number, number) → this +// Delete the content between the given positions. +Transform.prototype.delete = function(from, to) { + return this.replace(from, to, Slice.empty) +}; + +// :: (number, union) → this +// Insert the given content at the given position. +Transform.prototype.insert = function(pos, content) { + return this.replaceWith(pos, pos, content) +}; + + + +function fitLeftInner($from, depth, placed, placedBelow) { + var content = Fragment.empty, openEnd = 0, placedHere = placed[depth]; + if ($from.depth > depth) { + var inner = fitLeftInner($from, depth + 1, placed, placedBelow || placedHere); + openEnd = inner.openEnd + 1; + content = Fragment.from($from.node(depth + 1).copy(inner.content)); + } + + if (placedHere) { + content = content.append(placedHere.content); + openEnd = placedHere.openEnd; + } + if (placedBelow) { + content = content.append($from.node(depth).contentMatchAt($from.indexAfter(depth)).fillBefore(Fragment.empty, true)); + openEnd = 0; + } + + return {content: content, openEnd: openEnd} +} + +function fitLeft($from, placed) { + var ref = fitLeftInner($from, 0, placed, false); + var content = ref.content; + var openEnd = ref.openEnd; + return new Slice(content, $from.depth, openEnd || 0) +} + +function fitRightJoin(content, parent, $from, $to, depth, openStart, openEnd) { + var match, count = content.childCount, matchCount = count - (openEnd > 0 ? 1 : 0); + var parentNode = openStart < 0 ? parent : $from.node(depth); + if (openStart < 0) + { match = parentNode.contentMatchAt(matchCount); } + else if (count == 1 && openEnd > 0) + { match = parentNode.contentMatchAt(openStart ? $from.index(depth) : $from.indexAfter(depth)); } + else + { match = parentNode.contentMatchAt($from.indexAfter(depth)) + .matchFragment(content, count > 0 && openStart ? 1 : 0, matchCount); } + + var toNode = $to.node(depth); + if (openEnd > 0 && depth < $to.depth) { + var after = toNode.content.cutByIndex($to.indexAfter(depth)).addToStart(content.lastChild); + var joinable$1 = match.fillBefore(after, true); + // Can't insert content if there's a single node stretched across this gap + if (joinable$1 && joinable$1.size && openStart > 0 && count == 1) { joinable$1 = null; } + + if (joinable$1) { + var inner = fitRightJoin(content.lastChild.content, content.lastChild, $from, $to, + depth + 1, count == 1 ? openStart - 1 : -1, openEnd - 1); + if (inner) { + var last = content.lastChild.copy(inner); + if (joinable$1.size) + { return content.cutByIndex(0, count - 1).append(joinable$1).addToEnd(last) } + else + { return content.replaceChild(count - 1, last) } + } + } + } + if (openEnd > 0) + { match = match.matchType((count == 1 && openStart > 0 ? $from.node(depth + 1) : content.lastChild).type); } + + // If we're here, the next level can't be joined, so we see what + // happens if we leave it open. + var toIndex = $to.index(depth); + if (toIndex == toNode.childCount && !toNode.type.compatibleContent(parent.type)) { return null } + var joinable = match.fillBefore(toNode.content, true, toIndex); + for (var i = toIndex; joinable && i < toNode.content.childCount; i++) + { if (!parentNode.type.allowsMarks(toNode.content.child(i).marks)) { joinable = null; } } + if (!joinable) { return null } + + if (openEnd > 0) { + var closed = fitRightClosed(content.lastChild, openEnd - 1, $from, depth + 1, + count == 1 ? openStart - 1 : -1); + content = content.replaceChild(count - 1, closed); + } + content = content.append(joinable); + if ($to.depth > depth) + { content = content.addToEnd(fitRightSeparate($to, depth + 1)); } + return content +} + +function fitRightClosed(node, openEnd, $from, depth, openStart) { + var match, content = node.content, count = content.childCount; + if (openStart >= 0) + { match = $from.node(depth).contentMatchAt($from.indexAfter(depth)) + .matchFragment(content, openStart > 0 ? 1 : 0, count); } + else + { match = node.contentMatchAt(count); } + + if (openEnd > 0) { + var closed = fitRightClosed(content.lastChild, openEnd - 1, $from, depth + 1, + count == 1 ? openStart - 1 : -1); + content = content.replaceChild(count - 1, closed); + } + + return node.copy(content.append(match.fillBefore(Fragment.empty, true))) +} + +function fitRightSeparate($to, depth) { + var node = $to.node(depth); + var fill = node.contentMatchAt(0).fillBefore(node.content, true, $to.index(depth)); + if ($to.depth > depth) { fill = fill.addToEnd(fitRightSeparate($to, depth + 1)); } + return node.copy(fill) +} + +function normalizeSlice(content, openStart, openEnd) { + while (openStart > 0 && openEnd > 0 && content.childCount == 1) { + content = content.firstChild.content; + openStart--; + openEnd--; + } + return new Slice(content, openStart, openEnd) +} + +// : (ResolvedPos, ResolvedPos, number, Slice) → Slice +function fitRight($from, $to, slice) { + var fitted = fitRightJoin(slice.content, $from.node(0), $from, $to, 0, slice.openStart, slice.openEnd); + if (!fitted) { return null } + return normalizeSlice(fitted, slice.openStart, $to.depth) +} + +function fitsTrivially($from, $to, slice) { + return !slice.openStart && !slice.openEnd && $from.start() == $to.start() && + $from.parent.canReplace($from.index(), $to.index(), slice.content) +} + +function canMoveText($from, $to, slice) { + if (!$to.parent.isTextblock) { return false } + + var parent = slice.openEnd ? nodeRight(slice.content, slice.openEnd) + : $from.node($from.depth - (slice.openStart - slice.openEnd)); + if (!parent.isTextblock) { return false } + for (var i = $to.index(); i < $to.parent.childCount; i++) + { if (!parent.type.allowsMarks($to.parent.child(i).marks)) { return false } } + var match; + if (slice.openEnd) { + match = parent.contentMatchAt(parent.childCount); + } else { + match = parent.contentMatchAt(parent.childCount); + if (slice.size) { match = match.matchFragment(slice.content, slice.openStart ? 1 : 0); } + } + match = match.matchFragment($to.parent.content, $to.index()); + return match && match.validEnd +} + +function nodeRight(content, depth) { + for (var i = 1; i < depth; i++) { content = content.lastChild.content; } + return content.lastChild +} + +// Algorithm for 'placing' the elements of a slice into a gap: +// +// We consider the content of each node that is open to the left to be +// independently placeable. I.e. in , when the +// paragraph on the left is open, "foo" can be placed (somewhere on +// the left side of the replacement gap) independently from p("bar"). +// +// So placeSlice splits up a slice into a number of sub-slices, +// along with information on where they can be placed on the given +// left-side edge. It works by walking the open side of the slice, +// from the inside out, and trying to find a landing spot for each +// element, by simultaneously scanning over the gap side. When no +// place is found for an open node's content, it is left in that node. + +// : (ResolvedPos, Slice) → [{content: Fragment, openEnd: number, depth: number}] +function placeSlice($from, slice) { + var frontier = new Frontier($from); + for (var pass = 1; slice.size && pass <= 3; pass++) { + var value = frontier.placeSlice(slice.content, slice.openStart, slice.openEnd, pass); + if (pass == 3 && value != slice && value.size) { pass = 0; } // Restart if the 3rd pass made progress but left content + slice = value; + } + while (frontier.open.length) { frontier.closeNode(); } + return frontier.placed +} + +// Helper class that models the open side of the insert position, +// keeping track of the content match and already inserted content +// at each depth. +var Frontier = function Frontier($pos) { + // : [{parent: Node, match: ContentMatch, content: Fragment, wrapper: bool, openEnd: number, depth: number}] + this.open = []; + for (var d = 0; d <= $pos.depth; d++) { + var parent = $pos.node(d), match = parent.contentMatchAt($pos.indexAfter(d)); + this.open.push({parent: parent, match: match, content: Fragment.empty, wrapper: false, openEnd: 0, depth: d}); + } + this.placed = []; +}; + +// : (Fragment, number, number, number, ?Node) → Slice +// Tries to place the content of the given slice, and returns a +// slice containing unplaced content. +// +// pass 1: try to fit directly +// pass 2: allow wrapper nodes to be introduced +// pass 3: allow unwrapping of nodes that aren't open +Frontier.prototype.placeSlice = function placeSlice (fragment, openStart, openEnd, pass, parent) { + if (openStart > 0) { + var first = fragment.firstChild; + var inner = this.placeSlice(first.content, Math.max(0, openStart - 1), + openEnd && fragment.childCount == 1 ? openEnd - 1 : 0, + pass, first); + if (inner.content != first.content) { + if (inner.content.size) { + fragment = fragment.replaceChild(0, first.copy(inner.content)); + openStart = inner.openStart + 1; + } else { + if (fragment.childCount == 1) { openEnd = 0; } + fragment = fragment.cutByIndex(1); + openStart = 0; + } + } + } + var result = this.placeContent(fragment, openStart, openEnd, pass, parent); + if (pass > 2 && result.size && openStart == 0) { + var child = result.content.firstChild, single = result.content.childCount == 1; + this.placeContent(child.content, 0, openEnd && single ? openEnd - 1 : 0, pass, child); + result = single ? Fragment.empty : new Slice(result.content.cutByIndex(1), 0, openEnd); + } + return result +}; + +Frontier.prototype.placeContent = function placeContent (fragment, openStart, openEnd, pass, parent) { + var i = 0; + // Go over the fragment's children + for (; i < fragment.childCount; i++) { + var child = fragment.child(i), placed = false, last = i == fragment.childCount - 1; + // Try each open node in turn, starting from the innermost + for (var d = this.open.length - 1; d >= 0; d--) { + var open = this.open[d], wrap = (void 0); + + // If pass > 1, it is allowed to wrap the node to help find a + // fit, so if findWrapping returns something, we add open + // nodes to the frontier for that wrapping. + if (pass > 1 && (wrap = open.match.findWrapping(child.type)) && + !(parent && wrap.length && wrap[wrap.length - 1] == parent.type)) { + while (this.open.length - 1 > d) { this.closeNode(); } + for (var w = 0; w < wrap.length; w++) { + open.match = open.match.matchType(wrap[w]); + d++; + open = {parent: wrap[w].create(), + match: wrap[w].contentMatch, + content: Fragment.empty, wrapper: true, openEnd: 0, depth: d + w}; + this.open.push(open); + } + } + + // See if the child fits here + var match = open.match.matchType(child.type); + if (!match) { + var fill = open.match.fillBefore(Fragment.from(child)); + if (fill) { + for (var j = 0; j < fill.childCount; j++) { + var ch = fill.child(j); + this.addNode(open, ch, 0); + match = open.match.matchFragment(ch); + } + } else if (parent && open.match.matchType(parent.type)) { + // Don't continue looking further up if the parent node + // would fit here. + break + } else { + continue + } + } + + // Close open nodes above this one, since we're starting to + // add to this. + while (this.open.length - 1 > d) { this.closeNode(); } + // Strip marks from the child or close its start when necessary + child = child.mark(open.parent.type.allowedMarks(child.marks)); + if (openStart) { + child = closeNodeStart(child, openStart, last ? openEnd : 0); + openStart = 0; + } + // Add the child to this open node and adjust its metadata + this.addNode(open, child, last ? openEnd : 0); + open.match = match; + if (last) { openEnd = 0; } + placed = true; + break + } + // As soon as we've failed to place a node we stop looking at + // later nodes + if (!placed) { break } + } + // Close the current open node if it's not the the root and we + // either placed up to the end of the node or the the current + // slice depth's node type matches the open node's type + if (this.open.length > 1 && + (i > 0 && i == fragment.childCount || + parent && this.open[this.open.length - 1].parent.type == parent.type)) + { this.closeNode(); } + + return new Slice(fragment.cutByIndex(i), openStart, openEnd) +}; + +Frontier.prototype.addNode = function addNode (open, node, openEnd) { + open.content = closeFragmentEnd(open.content, open.openEnd).addToEnd(node); + open.openEnd = openEnd; +}; + +Frontier.prototype.closeNode = function closeNode () { + var open = this.open.pop(); + if (open.content.size == 0) ; else if (open.wrapper) { + this.addNode(this.open[this.open.length - 1], open.parent.copy(open.content), open.openEnd + 1); + } else { + this.placed[open.depth] = {depth: open.depth, content: open.content, openEnd: open.openEnd}; + } +}; + +function closeNodeStart(node, openStart, openEnd) { + var content = node.content; + if (openStart > 1) { + var first = closeNodeStart(node.firstChild, openStart - 1, node.childCount == 1 ? openEnd - 1 : 0); + content = node.content.replaceChild(0, first); + } + var fill = node.type.contentMatch.fillBefore(content, openEnd == 0); + return node.copy(fill.append(content)) +} + +function closeNodeEnd(node, depth) { + var content = node.content; + if (depth > 1) { + var last = closeNodeEnd(node.lastChild, depth - 1); + content = node.content.replaceChild(node.childCount - 1, last); + } + var fill = node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true); + return node.copy(content.append(fill)) +} + +function closeFragmentEnd(fragment, depth) { + return depth ? fragment.replaceChild(fragment.childCount - 1, closeNodeEnd(fragment.lastChild, depth)) : fragment +} + +// :: (number, number, Slice) → this +// Replace a range of the document with a given slice, using `from`, +// `to`, and the slice's [`openStart`](#model.Slice.openStart) property +// as hints, rather than fixed start and end points. This method may +// grow the replaced area or close open nodes in the slice in order to +// get a fit that is more in line with WYSIWYG expectations, by +// dropping fully covered parent nodes of the replaced region when +// they are marked [non-defining](#model.NodeSpec.defining), or +// including an open parent node from the slice that _is_ marked as +// [defining](#model.NodeSpec.defining). +// +// This is the method, for example, to handle paste. The similar +// [`replace`](#transform.Transform.replace) method is a more +// primitive tool which will _not_ move the start and end of its given +// range, and is useful in situations where you need more precise +// control over what happens. +Transform.prototype.replaceRange = function(from, to, slice) { + if (!slice.size) { return this.deleteRange(from, to) } + + var $from = this.doc.resolve(from), $to = this.doc.resolve(to); + if (fitsTrivially($from, $to, slice)) + { return this.step(new ReplaceStep(from, to, slice)) } + + var targetDepths = coveredDepths($from, this.doc.resolve(to)); + // Can't replace the whole document, so remove 0 if it's present + if (targetDepths[targetDepths.length - 1] == 0) { targetDepths.pop(); } + // Negative numbers represent not expansion over the whole node at + // that depth, but replacing from $from.before(-D) to $to.pos. + var preferredTarget = -($from.depth + 1); + targetDepths.unshift(preferredTarget); + // This loop picks a preferred target depth, if one of the covering + // depths is not outside of a defining node, and adds negative + // depths for any depth that has $from at its start and does not + // cross a defining node. + for (var d = $from.depth, pos = $from.pos - 1; d > 0; d--, pos--) { + var spec = $from.node(d).type.spec; + if (spec.defining || spec.isolating) { break } + if (targetDepths.indexOf(d) > -1) { preferredTarget = d; } + else if ($from.before(d) == pos) { targetDepths.splice(1, 0, -d); } + } + // Try to fit each possible depth of the slice into each possible + // target depth, starting with the preferred depths. + var preferredTargetIndex = targetDepths.indexOf(preferredTarget); + + var leftNodes = [], preferredDepth = slice.openStart; + for (var content = slice.content, i = 0;; i++) { + var node = content.firstChild; + leftNodes.push(node); + if (i == slice.openStart) { break } + content = node.content; + } + // Back up if the node directly above openStart, or the node above + // that separated only by a non-defining textblock node, is defining. + if (preferredDepth > 0 && leftNodes[preferredDepth - 1].type.spec.defining && + $from.node(preferredTargetIndex).type != leftNodes[preferredDepth - 1].type) + { preferredDepth -= 1; } + else if (preferredDepth >= 2 && leftNodes[preferredDepth - 1].isTextblock && leftNodes[preferredDepth - 2].type.spec.defining && + $from.node(preferredTargetIndex).type != leftNodes[preferredDepth - 2].type) + { preferredDepth -= 2; } + + for (var j = slice.openStart; j >= 0; j--) { + var openDepth = (j + preferredDepth + 1) % (slice.openStart + 1); + var insert = leftNodes[openDepth]; + if (!insert) { continue } + for (var i$1 = 0; i$1 < targetDepths.length; i$1++) { + // Loop over possible expansion levels, starting with the + // preferred one + var targetDepth = targetDepths[(i$1 + preferredTargetIndex) % targetDepths.length], expand = true; + if (targetDepth < 0) { expand = false; targetDepth = -targetDepth; } + var parent = $from.node(targetDepth - 1), index = $from.index(targetDepth - 1); + if (parent.canReplaceWith(index, index, insert.type, insert.marks)) + { return this.replace($from.before(targetDepth), expand ? $to.after(targetDepth) : to, + new Slice(closeFragment(slice.content, 0, slice.openStart, openDepth), + openDepth, slice.openEnd)) } + } + } + + var startSteps = this.steps.length; + for (var i$2 = targetDepths.length - 1; i$2 >= 0; i$2--) { + this.replace(from, to, slice); + if (this.steps.length > startSteps) { break } + var depth = targetDepths[i$2]; + if (i$2 < 0) { continue } + from = $from.before(depth); to = $to.after(depth); + } + return this +}; + +function closeFragment(fragment, depth, oldOpen, newOpen, parent) { + if (depth < oldOpen) { + var first = fragment.firstChild; + fragment = fragment.replaceChild(0, first.copy(closeFragment(first.content, depth + 1, oldOpen, newOpen, first))); + } + if (depth > newOpen) { + var match = parent.contentMatchAt(0); + var start = match.fillBefore(fragment).append(fragment); + fragment = start.append(match.matchFragment(start).fillBefore(Fragment.empty, true)); + } + return fragment +} + +// :: (number, number, Node) → this +// Replace the given range with a node, but use `from` and `to` as +// hints, rather than precise positions. When from and to are the same +// and are at the start or end of a parent node in which the given +// node doesn't fit, this method may _move_ them out towards a parent +// that does allow the given node to be placed. When the given range +// completely covers a parent node, this method may completely replace +// that parent node. +Transform.prototype.replaceRangeWith = function(from, to, node) { + if (!node.isInline && from == to && this.doc.resolve(from).parent.content.size) { + var point = insertPoint(this.doc, from, node.type); + if (point != null) { from = to = point; } + } + return this.replaceRange(from, to, new Slice(Fragment.from(node), 0, 0)) +}; + +// :: (number, number) → this +// Delete the given range, expanding it to cover fully covered +// parent nodes until a valid replace is found. +Transform.prototype.deleteRange = function(from, to) { + var $from = this.doc.resolve(from), $to = this.doc.resolve(to); + var covered = coveredDepths($from, $to); + for (var i = 0; i < covered.length; i++) { + var depth = covered[i], last = i == covered.length - 1; + if ((last && depth == 0) || $from.node(depth).type.contentMatch.validEnd) + { return this.delete($from.start(depth), $to.end(depth)) } + if (depth > 0 && (last || $from.node(depth - 1).canReplace($from.index(depth - 1), $to.indexAfter(depth - 1)))) + { return this.delete($from.before(depth), $to.after(depth)) } + } + for (var d = 1; d <= $from.depth; d++) { + if (from - $from.start(d) == $from.depth - d && to > $from.end(d) && $to.end(d) - to != $to.depth - d) + { return this.delete($from.before(d), to) } + } + return this.delete(from, to) +}; + +// : (ResolvedPos, ResolvedPos) → [number] +// Returns an array of all depths for which $from - $to spans the +// whole content of the nodes at that depth. +function coveredDepths($from, $to) { + var result = [], minDepth = Math.min($from.depth, $to.depth); + for (var d = minDepth; d >= 0; d--) { + var start = $from.start(d); + if (start < $from.pos - ($from.depth - d) || + $to.end(d) > $to.pos + ($to.depth - d) || + $from.node(d).type.spec.isolating || + $to.node(d).type.spec.isolating) { break } + if (start == $to.start(d)) { result.push(d); } + } + return result +} + +export { AddMarkStep, MapResult, Mapping, RemoveMarkStep, ReplaceAroundStep, ReplaceStep, Step, StepMap, StepResult, Transform, TransformError, canJoin, canSplit, dropPoint, findWrapping, insertPoint, joinPoint, liftTarget, replaceStep }; +//# sourceMappingURL=index.es.js.map diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/dist/index.es.js.map b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/dist/index.es.js.map new file mode 100644 index 0000000000..6980959035 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/dist/index.es.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.es.js","sources":["../src/map.js","../src/transform.js","../src/step.js","../src/replace_step.js","../src/structure.js","../src/mark_step.js","../src/mark.js","../src/replace.js"],"sourcesContent":["// Mappable:: interface\n// There are several things that positions can be mapped through.\n// Such objects conform to this interface.\n//\n// map:: (pos: number, assoc: ?number) → number\n// Map a position through this object. When given, `assoc` (should\n// be -1 or 1, defaults to 1) determines with which side the\n// position is associated, which determines in which direction to\n// move when a chunk of content is inserted at the mapped position.\n//\n// mapResult:: (pos: number, assoc: ?number) → MapResult\n// Map a position, and return an object containing additional\n// information about the mapping. The result's `deleted` field tells\n// you whether the position was deleted (completely enclosed in a\n// replaced range) during the mapping. When content on only one side\n// is deleted, the position itself is only considered deleted when\n// `assoc` points in the direction of the deleted content.\n\n// Recovery values encode a range index and an offset. They are\n// represented as numbers, because tons of them will be created when\n// mapping, for example, a large number of decorations. The number's\n// lower 16 bits provide the index, the remaining bits the offset.\n//\n// Note: We intentionally don't use bit shift operators to en- and\n// decode these, since those clip to 32 bits, which we might in rare\n// cases want to overflow. A 64-bit float can represent 48-bit\n// integers precisely.\n\nconst lower16 = 0xffff\nconst factor16 = Math.pow(2, 16)\n\nfunction makeRecover(index, offset) { return index + offset * factor16 }\nfunction recoverIndex(value) { return value & lower16 }\nfunction recoverOffset(value) { return (value - (value & lower16)) / factor16 }\n\n// ::- An object representing a mapped position with extra\n// information.\nexport class MapResult {\n constructor(pos, deleted = false, recover = null) {\n // :: number The mapped version of the position.\n this.pos = pos\n // :: bool Tells you whether the position was deleted, that is,\n // whether the step removed its surroundings from the document.\n this.deleted = deleted\n this.recover = recover\n }\n}\n\n// :: class extends Mappable\n// A map describing the deletions and insertions made by a step, which\n// can be used to find the correspondence between positions in the\n// pre-step version of a document and the same position in the\n// post-step version.\nexport class StepMap {\n // :: ([number])\n // Create a position map. The modifications to the document are\n // represented as an array of numbers, in which each group of three\n // represents a modified chunk as `[start, oldSize, newSize]`.\n constructor(ranges, inverted = false) {\n this.ranges = ranges\n this.inverted = inverted\n }\n\n recover(value) {\n let diff = 0, index = recoverIndex(value)\n if (!this.inverted) for (let i = 0; i < index; i++)\n diff += this.ranges[i * 3 + 2] - this.ranges[i * 3 + 1]\n return this.ranges[index * 3] + diff + recoverOffset(value)\n }\n\n // : (number, ?number) → MapResult\n mapResult(pos, assoc = 1) { return this._map(pos, assoc, false) }\n\n // : (number, ?number) → number\n map(pos, assoc = 1) { return this._map(pos, assoc, true) }\n\n _map(pos, assoc, simple) {\n let diff = 0, oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2\n for (let i = 0; i < this.ranges.length; i += 3) {\n let start = this.ranges[i] - (this.inverted ? diff : 0)\n if (start > pos) break\n let oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex], end = start + oldSize\n if (pos <= end) {\n let side = !oldSize ? assoc : pos == start ? -1 : pos == end ? 1 : assoc\n let result = start + diff + (side < 0 ? 0 : newSize)\n if (simple) return result\n let recover = makeRecover(i / 3, pos - start)\n return new MapResult(result, assoc < 0 ? pos != start : pos != end, recover)\n }\n diff += newSize - oldSize\n }\n return simple ? pos + diff : new MapResult(pos + diff)\n }\n\n touches(pos, recover) {\n let diff = 0, index = recoverIndex(recover)\n let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2\n for (let i = 0; i < this.ranges.length; i += 3) {\n let start = this.ranges[i] - (this.inverted ? diff : 0)\n if (start > pos) break\n let oldSize = this.ranges[i + oldIndex], end = start + oldSize\n if (pos <= end && i == index * 3) return true\n diff += this.ranges[i + newIndex] - oldSize\n }\n return false\n }\n\n // :: ((oldStart: number, oldEnd: number, newStart: number, newEnd: number))\n // Calls the given function on each of the changed ranges included in\n // this map.\n forEach(f) {\n let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2\n for (let i = 0, diff = 0; i < this.ranges.length; i += 3) {\n let start = this.ranges[i], oldStart = start - (this.inverted ? diff : 0), newStart = start + (this.inverted ? 0 : diff)\n let oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex]\n f(oldStart, oldStart + oldSize, newStart, newStart + newSize)\n diff += newSize - oldSize\n }\n }\n\n // :: () → StepMap\n // Create an inverted version of this map. The result can be used to\n // map positions in the post-step document to the pre-step document.\n invert() {\n return new StepMap(this.ranges, !this.inverted)\n }\n\n toString() {\n return (this.inverted ? \"-\" : \"\") + JSON.stringify(this.ranges)\n }\n\n // :: (n: number) → StepMap\n // Create a map that moves all positions by offset `n` (which may be\n // negative). This can be useful when applying steps meant for a\n // sub-document to a larger document, or vice-versa.\n static offset(n) {\n return n == 0 ? StepMap.empty : new StepMap(n < 0 ? [0, -n, 0] : [0, 0, n])\n }\n}\n\nStepMap.empty = new StepMap([])\n\n// :: class extends Mappable\n// A mapping represents a pipeline of zero or more [step\n// maps](#transform.StepMap). It has special provisions for losslessly\n// handling mapping positions through a series of steps in which some\n// steps are inverted versions of earlier steps. (This comes up when\n// ‘[rebasing](/docs/guide/#transform.rebasing)’ steps for\n// collaboration or history management.)\nexport class Mapping {\n // :: (?[StepMap])\n // Create a new mapping with the given position maps.\n constructor(maps, mirror, from, to) {\n // :: [StepMap]\n // The step maps in this mapping.\n this.maps = maps || []\n // :: number\n // The starting position in the `maps` array, used when `map` or\n // `mapResult` is called.\n this.from = from || 0\n // :: number\n // The end position in the `maps` array.\n this.to = to == null ? this.maps.length : to\n this.mirror = mirror\n }\n\n // :: (?number, ?number) → Mapping\n // Create a mapping that maps only through a part of this one.\n slice(from = 0, to = this.maps.length) {\n return new Mapping(this.maps, this.mirror, from, to)\n }\n\n copy() {\n return new Mapping(this.maps.slice(), this.mirror && this.mirror.slice(), this.from, this.to)\n }\n\n // :: (StepMap, ?number)\n // Add a step map to the end of this mapping. If `mirrors` is\n // given, it should be the index of the step map that is the mirror\n // image of this one.\n appendMap(map, mirrors) {\n this.to = this.maps.push(map)\n if (mirrors != null) this.setMirror(this.maps.length - 1, mirrors)\n }\n\n // :: (Mapping)\n // Add all the step maps in a given mapping to this one (preserving\n // mirroring information).\n appendMapping(mapping) {\n for (let i = 0, startSize = this.maps.length; i < mapping.maps.length; i++) {\n let mirr = mapping.getMirror(i)\n this.appendMap(mapping.maps[i], mirr != null && mirr < i ? startSize + mirr : null)\n }\n }\n\n // :: (number) → ?number\n // Finds the offset of the step map that mirrors the map at the\n // given offset, in this mapping (as per the second argument to\n // `appendMap`).\n getMirror(n) {\n if (this.mirror) for (let i = 0; i < this.mirror.length; i++)\n if (this.mirror[i] == n) return this.mirror[i + (i % 2 ? -1 : 1)]\n }\n\n setMirror(n, m) {\n if (!this.mirror) this.mirror = []\n this.mirror.push(n, m)\n }\n\n // :: (Mapping)\n // Append the inverse of the given mapping to this one.\n appendMappingInverted(mapping) {\n for (let i = mapping.maps.length - 1, totalSize = this.maps.length + mapping.maps.length; i >= 0; i--) {\n let mirr = mapping.getMirror(i)\n this.appendMap(mapping.maps[i].invert(), mirr != null && mirr > i ? totalSize - mirr - 1 : null)\n }\n }\n\n // :: () → Mapping\n // Create an inverted version of this mapping.\n invert() {\n let inverse = new Mapping\n inverse.appendMappingInverted(this)\n return inverse\n }\n\n // : (number, ?number) → number\n // Map a position through this mapping.\n map(pos, assoc = 1) {\n if (this.mirror) return this._map(pos, assoc, true)\n for (let i = this.from; i < this.to; i++)\n pos = this.maps[i].map(pos, assoc)\n return pos\n }\n\n // : (number, ?number) → MapResult\n // Map a position through this mapping, returning a mapping\n // result.\n mapResult(pos, assoc = 1) { return this._map(pos, assoc, false) }\n\n _map(pos, assoc, simple) {\n let deleted = false, recoverables = null\n\n for (let i = this.from; i < this.to; i++) {\n let map = this.maps[i], rec = recoverables && recoverables[i]\n if (rec != null && map.touches(pos, rec)) {\n pos = map.recover(rec)\n continue\n }\n\n let result = map.mapResult(pos, assoc)\n if (result.recover != null) {\n let corr = this.getMirror(i)\n if (corr != null && corr > i && corr < this.to) {\n if (result.deleted) {\n i = corr\n pos = this.maps[corr].recover(result.recover)\n continue\n } else {\n ;(recoverables || (recoverables = Object.create(null)))[corr] = result.recover\n }\n }\n }\n\n if (result.deleted) deleted = true\n pos = result.pos\n }\n\n return simple ? pos : new MapResult(pos, deleted)\n }\n}\n","import {Mapping} from \"./map\"\n\nexport function TransformError(message) {\n let err = Error.call(this, message)\n err.__proto__ = TransformError.prototype\n return err\n}\n\nTransformError.prototype = Object.create(Error.prototype)\nTransformError.prototype.constructor = TransformError\nTransformError.prototype.name = \"TransformError\"\n\n// ::- Abstraction to build up and track an array of\n// [steps](#transform.Step) representing a document transformation.\n//\n// Most transforming methods return the `Transform` object itself, so\n// that they can be chained.\nexport class Transform {\n // :: (Node)\n // Create a transform that starts with the given document.\n constructor(doc) {\n // :: Node\n // The current document (the result of applying the steps in the\n // transform).\n this.doc = doc\n // :: [Step]\n // The steps in this transform.\n this.steps = []\n // :: [Node]\n // The documents before each of the steps.\n this.docs = []\n // :: Mapping\n // A mapping with the maps for each of the steps in this transform.\n this.mapping = new Mapping\n }\n\n // :: Node The starting document.\n get before() { return this.docs.length ? this.docs[0] : this.doc }\n\n // :: (step: Step) → this\n // Apply a new step in this transform, saving the result. Throws an\n // error when the step fails.\n step(object) {\n let result = this.maybeStep(object)\n if (result.failed) throw new TransformError(result.failed)\n return this\n }\n\n // :: (Step) → StepResult\n // Try to apply a step in this transformation, ignoring it if it\n // fails. Returns the step result.\n maybeStep(step) {\n let result = step.apply(this.doc)\n if (!result.failed) this.addStep(step, result.doc)\n return result\n }\n\n // :: bool\n // True when the document has been changed (when there are any\n // steps).\n get docChanged() {\n return this.steps.length > 0\n }\n\n addStep(step, doc) {\n this.docs.push(this.doc)\n this.steps.push(step)\n this.mapping.appendMap(step.getMap())\n this.doc = doc\n }\n}\n","import {ReplaceError} from \"prosemirror-model\"\n\nimport {StepMap} from \"./map\"\n\nfunction mustOverride() { throw new Error(\"Override me\") }\n\nconst stepsByID = Object.create(null)\n\n// ::- A step object represents an atomic change. It generally applies\n// only to the document it was created for, since the positions\n// stored in it will only make sense for that document.\n//\n// New steps are defined by creating classes that extend `Step`,\n// overriding the `apply`, `invert`, `map`, `getMap` and `fromJSON`\n// methods, and registering your class with a unique\n// JSON-serialization identifier using\n// [`Step.jsonID`](#transform.Step^jsonID).\nexport class Step {\n // :: (doc: Node) → StepResult\n // Applies this step to the given document, returning a result\n // object that either indicates failure, if the step can not be\n // applied to this document, or indicates success by containing a\n // transformed document.\n apply(_doc) { return mustOverride() }\n\n // :: () → StepMap\n // Get the step map that represents the changes made by this step,\n // and which can be used to transform between positions in the old\n // and the new document.\n getMap() { return StepMap.empty }\n\n // :: (doc: Node) → Step\n // Create an inverted version of this step. Needs the document as it\n // was before the step as argument.\n invert(_doc) { return mustOverride() }\n\n // :: (mapping: Mappable) → ?Step\n // Map this step through a mappable thing, returning either a\n // version of that step with its positions adjusted, or `null` if\n // the step was entirely deleted by the mapping.\n map(_mapping) { return mustOverride() }\n\n // :: (other: Step) → ?Step\n // Try to merge this step with another one, to be applied directly\n // after it. Returns the merged step when possible, null if the\n // steps can't be merged.\n merge(_other) { return null }\n\n // :: () → Object\n // Create a JSON-serializeable representation of this step. When\n // defining this for a custom subclass, make sure the result object\n // includes the step type's [JSON id](#transform.Step^jsonID) under\n // the `stepType` property.\n toJSON() { return mustOverride() }\n\n // :: (Schema, Object) → Step\n // Deserialize a step from its JSON representation. Will call\n // through to the step class' own implementation of this method.\n static fromJSON(schema, json) {\n if (!json || !json.stepType) throw new RangeError(\"Invalid input for Step.fromJSON\")\n let type = stepsByID[json.stepType]\n if (!type) throw new RangeError(`No step type ${json.stepType} defined`)\n return type.fromJSON(schema, json)\n }\n\n // :: (string, constructor)\n // To be able to serialize steps to JSON, each step needs a string\n // ID to attach to its JSON representation. Use this method to\n // register an ID for your step classes. Try to pick something\n // that's unlikely to clash with steps from other modules.\n static jsonID(id, stepClass) {\n if (id in stepsByID) throw new RangeError(\"Duplicate use of step JSON ID \" + id)\n stepsByID[id] = stepClass\n stepClass.prototype.jsonID = id\n return stepClass\n }\n}\n\n// ::- The result of [applying](#transform.Step.apply) a step. Contains either a\n// new document or a failure value.\nexport class StepResult {\n // : (?Node, ?string)\n constructor(doc, failed) {\n // :: ?Node The transformed document.\n this.doc = doc\n // :: ?string Text providing information about a failed step.\n this.failed = failed\n }\n\n // :: (Node) → StepResult\n // Create a successful step result.\n static ok(doc) { return new StepResult(doc, null) }\n\n // :: (string) → StepResult\n // Create a failed step result.\n static fail(message) { return new StepResult(null, message) }\n\n // :: (Node, number, number, Slice) → StepResult\n // Call [`Node.replace`](#model.Node.replace) with the given\n // arguments. Create a successful result if it succeeds, and a\n // failed one if it throws a `ReplaceError`.\n static fromReplace(doc, from, to, slice) {\n try {\n return StepResult.ok(doc.replace(from, to, slice))\n } catch (e) {\n if (e instanceof ReplaceError) return StepResult.fail(e.message)\n throw e\n }\n }\n}\n","import {Slice} from \"prosemirror-model\"\n\nimport {Step, StepResult} from \"./step\"\nimport {StepMap} from \"./map\"\n\n// ::- Replace a part of the document with a slice of new content.\nexport class ReplaceStep extends Step {\n // :: (number, number, Slice, ?bool)\n // The given `slice` should fit the 'gap' between `from` and\n // `to`—the depths must line up, and the surrounding nodes must be\n // able to be joined with the open sides of the slice. When\n // `structure` is true, the step will fail if the content between\n // from and to is not just a sequence of closing and then opening\n // tokens (this is to guard against rebased replace steps\n // overwriting something they weren't supposed to).\n constructor(from, to, slice, structure) {\n super()\n this.from = from\n this.to = to\n this.slice = slice\n this.structure = !!structure\n }\n\n apply(doc) {\n if (this.structure && contentBetween(doc, this.from, this.to))\n return StepResult.fail(\"Structure replace would overwrite content\")\n return StepResult.fromReplace(doc, this.from, this.to, this.slice)\n }\n\n getMap() {\n return new StepMap([this.from, this.to - this.from, this.slice.size])\n }\n\n invert(doc) {\n return new ReplaceStep(this.from, this.from + this.slice.size, doc.slice(this.from, this.to))\n }\n\n map(mapping) {\n let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1)\n if (from.deleted && to.deleted) return null\n return new ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice)\n }\n\n merge(other) {\n if (!(other instanceof ReplaceStep) || other.structure != this.structure) return null\n\n if (this.from + this.slice.size == other.from && !this.slice.openEnd && !other.slice.openStart) {\n let slice = this.slice.size + other.slice.size == 0 ? Slice.empty\n : new Slice(this.slice.content.append(other.slice.content), this.slice.openStart, other.slice.openEnd)\n return new ReplaceStep(this.from, this.to + (other.to - other.from), slice, this.structure)\n } else if (other.to == this.from && !this.slice.openStart && !other.slice.openEnd) {\n let slice = this.slice.size + other.slice.size == 0 ? Slice.empty\n : new Slice(other.slice.content.append(this.slice.content), other.slice.openStart, this.slice.openEnd)\n return new ReplaceStep(other.from, this.to, slice, this.structure)\n } else {\n return null\n }\n }\n\n toJSON() {\n let json = {stepType: \"replace\", from: this.from, to: this.to}\n if (this.slice.size) json.slice = this.slice.toJSON()\n if (this.structure) json.structure = true\n return json\n }\n\n static fromJSON(schema, json) {\n if (typeof json.from != \"number\" || typeof json.to != \"number\")\n throw new RangeError(\"Invalid input for ReplaceStep.fromJSON\")\n return new ReplaceStep(json.from, json.to, Slice.fromJSON(schema, json.slice), !!json.structure)\n }\n}\n\nStep.jsonID(\"replace\", ReplaceStep)\n\n// ::- Replace a part of the document with a slice of content, but\n// preserve a range of the replaced content by moving it into the\n// slice.\nexport class ReplaceAroundStep extends Step {\n // :: (number, number, number, number, Slice, number, ?bool)\n // Create a replace-around step with the given range and gap.\n // `insert` should be the point in the slice into which the content\n // of the gap should be moved. `structure` has the same meaning as\n // it has in the [`ReplaceStep`](#transform.ReplaceStep) class.\n constructor(from, to, gapFrom, gapTo, slice, insert, structure) {\n super()\n this.from = from\n this.to = to\n this.gapFrom = gapFrom\n this.gapTo = gapTo\n this.slice = slice\n this.insert = insert\n this.structure = !!structure\n }\n\n apply(doc) {\n if (this.structure && (contentBetween(doc, this.from, this.gapFrom) ||\n contentBetween(doc, this.gapTo, this.to)))\n return StepResult.fail(\"Structure gap-replace would overwrite content\")\n\n let gap = doc.slice(this.gapFrom, this.gapTo)\n if (gap.openStart || gap.openEnd)\n return StepResult.fail(\"Gap is not a flat range\")\n let inserted = this.slice.insertAt(this.insert, gap.content)\n if (!inserted) return StepResult.fail(\"Content does not fit in gap\")\n return StepResult.fromReplace(doc, this.from, this.to, inserted)\n }\n\n getMap() {\n return new StepMap([this.from, this.gapFrom - this.from, this.insert,\n this.gapTo, this.to - this.gapTo, this.slice.size - this.insert])\n }\n\n invert(doc) {\n let gap = this.gapTo - this.gapFrom\n return new ReplaceAroundStep(this.from, this.from + this.slice.size + gap,\n this.from + this.insert, this.from + this.insert + gap,\n doc.slice(this.from, this.to).removeBetween(this.gapFrom - this.from, this.gapTo - this.from),\n this.gapFrom - this.from, this.structure)\n }\n\n map(mapping) {\n let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1)\n let gapFrom = mapping.map(this.gapFrom, -1), gapTo = mapping.map(this.gapTo, 1)\n if ((from.deleted && to.deleted) || gapFrom < from.pos || gapTo > to.pos) return null\n return new ReplaceAroundStep(from.pos, to.pos, gapFrom, gapTo, this.slice, this.insert, this.structure)\n }\n\n toJSON() {\n let json = {stepType: \"replaceAround\", from: this.from, to: this.to,\n gapFrom: this.gapFrom, gapTo: this.gapTo, insert: this.insert}\n if (this.slice.size) json.slice = this.slice.toJSON()\n if (this.structure) json.structure = true\n return json\n }\n\n static fromJSON(schema, json) {\n if (typeof json.from != \"number\" || typeof json.to != \"number\" ||\n typeof json.gapFrom != \"number\" || typeof json.gapTo != \"number\" || typeof json.insert != \"number\")\n throw new RangeError(\"Invalid input for ReplaceAroundStep.fromJSON\")\n return new ReplaceAroundStep(json.from, json.to, json.gapFrom, json.gapTo,\n Slice.fromJSON(schema, json.slice), json.insert, !!json.structure)\n }\n}\n\nStep.jsonID(\"replaceAround\", ReplaceAroundStep)\n\nfunction contentBetween(doc, from, to) {\n let $from = doc.resolve(from), dist = to - from, depth = $from.depth\n while (dist > 0 && depth > 0 && $from.indexAfter(depth) == $from.node(depth).childCount) {\n depth--\n dist--\n }\n if (dist > 0) {\n let next = $from.node(depth).maybeChild($from.indexAfter(depth))\n while (dist > 0) {\n if (!next || next.isLeaf) return true\n next = next.firstChild\n dist--\n }\n }\n return false\n}\n","import {Slice, Fragment} from \"prosemirror-model\"\n\nimport {Transform} from \"./transform\"\nimport {ReplaceStep, ReplaceAroundStep} from \"./replace_step\"\n\nfunction canCut(node, start, end) {\n return (start == 0 || node.canReplace(start, node.childCount)) &&\n (end == node.childCount || node.canReplace(0, end))\n}\n\n// :: (NodeRange) → ?number\n// Try to find a target depth to which the content in the given range\n// can be lifted. Will not go across\n// [isolating](#model.NodeSpec.isolating) parent nodes.\nexport function liftTarget(range) {\n let parent = range.parent\n let content = parent.content.cutByIndex(range.startIndex, range.endIndex)\n for (let depth = range.depth;; --depth) {\n let node = range.$from.node(depth)\n let index = range.$from.index(depth), endIndex = range.$to.indexAfter(depth)\n if (depth < range.depth && node.canReplace(index, endIndex, content))\n return depth\n if (depth == 0 || node.type.spec.isolating || !canCut(node, index, endIndex)) break\n }\n}\n\n// :: (NodeRange, number) → this\n// Split the content in the given range off from its parent, if there\n// is sibling content before or after it, and move it up the tree to\n// the depth specified by `target`. You'll probably want to use\n// [`liftTarget`](#transform.liftTarget) to compute `target`, to make\n// sure the lift is valid.\nTransform.prototype.lift = function(range, target) {\n let {$from, $to, depth} = range\n\n let gapStart = $from.before(depth + 1), gapEnd = $to.after(depth + 1)\n let start = gapStart, end = gapEnd\n\n let before = Fragment.empty, openStart = 0\n for (let d = depth, splitting = false; d > target; d--)\n if (splitting || $from.index(d) > 0) {\n splitting = true\n before = Fragment.from($from.node(d).copy(before))\n openStart++\n } else {\n start--\n }\n let after = Fragment.empty, openEnd = 0\n for (let d = depth, splitting = false; d > target; d--)\n if (splitting || $to.after(d + 1) < $to.end(d)) {\n splitting = true\n after = Fragment.from($to.node(d).copy(after))\n openEnd++\n } else {\n end++\n }\n\n return this.step(new ReplaceAroundStep(start, end, gapStart, gapEnd,\n new Slice(before.append(after), openStart, openEnd),\n before.size - openStart, true))\n}\n\n// :: (NodeRange, NodeType, ?Object, ?NodeRange) → ?[{type: NodeType, attrs: ?Object}]\n// Try to find a valid way to wrap the content in the given range in a\n// node of the given type. May introduce extra nodes around and inside\n// the wrapper node, if necessary. Returns null if no valid wrapping\n// could be found. When `innerRange` is given, that range's content is\n// used as the content to fit into the wrapping, instead of the\n// content of `range`.\nexport function findWrapping(range, nodeType, attrs, innerRange = range) {\n let around = findWrappingOutside(range, nodeType)\n let inner = around && findWrappingInside(innerRange, nodeType)\n if (!inner) return null\n return around.map(withAttrs).concat({type: nodeType, attrs}).concat(inner.map(withAttrs))\n}\n\nfunction withAttrs(type) { return {type, attrs: null} }\n\nfunction findWrappingOutside(range, type) {\n let {parent, startIndex, endIndex} = range\n let around = parent.contentMatchAt(startIndex).findWrapping(type)\n if (!around) return null\n let outer = around.length ? around[0] : type\n return parent.canReplaceWith(startIndex, endIndex, outer) ? around : null\n}\n\nfunction findWrappingInside(range, type) {\n let {parent, startIndex, endIndex} = range\n let inner = parent.child(startIndex)\n let inside = type.contentMatch.findWrapping(inner.type)\n if (!inside) return null\n let lastType = inside.length ? inside[inside.length - 1] : type\n let innerMatch = lastType.contentMatch\n for (let i = startIndex; innerMatch && i < endIndex; i++)\n innerMatch = innerMatch.matchType(parent.child(i).type)\n if (!innerMatch || !innerMatch.validEnd) return null\n return inside\n}\n\n// :: (NodeRange, [{type: NodeType, attrs: ?Object}]) → this\n// Wrap the given [range](#model.NodeRange) in the given set of wrappers.\n// The wrappers are assumed to be valid in this position, and should\n// probably be computed with [`findWrapping`](#transform.findWrapping).\nTransform.prototype.wrap = function(range, wrappers) {\n let content = Fragment.empty\n for (let i = wrappers.length - 1; i >= 0; i--)\n content = Fragment.from(wrappers[i].type.create(wrappers[i].attrs, content))\n\n let start = range.start, end = range.end\n return this.step(new ReplaceAroundStep(start, end, start, end, new Slice(content, 0, 0), wrappers.length, true))\n}\n\n// :: (number, ?number, NodeType, ?Object) → this\n// Set the type of all textblocks (partly) between `from` and `to` to\n// the given node type with the given attributes.\nTransform.prototype.setBlockType = function(from, to = from, type, attrs) {\n if (!type.isTextblock) throw new RangeError(\"Type given to setBlockType should be a textblock\")\n let mapFrom = this.steps.length\n this.doc.nodesBetween(from, to, (node, pos) => {\n if (node.isTextblock && !node.hasMarkup(type, attrs) && canChangeType(this.doc, this.mapping.slice(mapFrom).map(pos), type)) {\n // Ensure all markup that isn't allowed in the new node type is cleared\n this.clearIncompatible(this.mapping.slice(mapFrom).map(pos, 1), type)\n let mapping = this.mapping.slice(mapFrom)\n let startM = mapping.map(pos, 1), endM = mapping.map(pos + node.nodeSize, 1)\n this.step(new ReplaceAroundStep(startM, endM, startM + 1, endM - 1,\n new Slice(Fragment.from(type.create(attrs, null, node.marks)), 0, 0), 1, true))\n return false\n }\n })\n return this\n}\n\nfunction canChangeType(doc, pos, type) {\n let $pos = doc.resolve(pos), index = $pos.index()\n return $pos.parent.canReplaceWith(index, index + 1, type)\n}\n\n// :: (number, ?NodeType, ?Object, ?[Mark]) → this\n// Change the type, attributes, and/or marks of the node at `pos`.\n// When `type` isn't given, the existing node type is preserved,\nTransform.prototype.setNodeMarkup = function(pos, type, attrs, marks) {\n let node = this.doc.nodeAt(pos)\n if (!node) throw new RangeError(\"No node at given position\")\n if (!type) type = node.type\n let newNode = type.create(attrs, null, marks || node.marks)\n if (node.isLeaf)\n return this.replaceWith(pos, pos + node.nodeSize, newNode)\n\n if (!type.validContent(node.content))\n throw new RangeError(\"Invalid content for node type \" + type.name)\n\n return this.step(new ReplaceAroundStep(pos, pos + node.nodeSize, pos + 1, pos + node.nodeSize - 1,\n new Slice(Fragment.from(newNode), 0, 0), 1, true))\n}\n\n// :: (Node, number, number, ?[?{type: NodeType, attrs: ?Object}]) → bool\n// Check whether splitting at the given position is allowed.\nexport function canSplit(doc, pos, depth = 1, typesAfter) {\n let $pos = doc.resolve(pos), base = $pos.depth - depth\n let innerType = (typesAfter && typesAfter[typesAfter.length - 1]) || $pos.parent\n if (base < 0 || $pos.parent.type.spec.isolating ||\n !$pos.parent.canReplace($pos.index(), $pos.parent.childCount) ||\n !innerType.type.validContent($pos.parent.content.cutByIndex($pos.index(), $pos.parent.childCount)))\n return false\n for (let d = $pos.depth - 1, i = depth - 2; d > base; d--, i--) {\n let node = $pos.node(d), index = $pos.index(d)\n if (node.type.spec.isolating) return false\n let rest = node.content.cutByIndex(index, node.childCount)\n let after = (typesAfter && typesAfter[i]) || node\n if (after != node) rest = rest.replaceChild(0, after.type.create(after.attrs))\n if (!node.canReplace(index + 1, node.childCount) || !after.type.validContent(rest))\n return false\n }\n let index = $pos.indexAfter(base)\n let baseType = typesAfter && typesAfter[0]\n return $pos.node(base).canReplaceWith(index, index, baseType ? baseType.type : $pos.node(base + 1).type)\n}\n\n// :: (number, ?number, ?[?{type: NodeType, attrs: ?Object}]) → this\n// Split the node at the given position, and optionally, if `depth` is\n// greater than one, any number of nodes above that. By default, the\n// parts split off will inherit the node type of the original node.\n// This can be changed by passing an array of types and attributes to\n// use after the split.\nTransform.prototype.split = function(pos, depth = 1, typesAfter) {\n let $pos = this.doc.resolve(pos), before = Fragment.empty, after = Fragment.empty\n for (let d = $pos.depth, e = $pos.depth - depth, i = depth - 1; d > e; d--, i--) {\n before = Fragment.from($pos.node(d).copy(before))\n let typeAfter = typesAfter && typesAfter[i]\n after = Fragment.from(typeAfter ? typeAfter.type.create(typeAfter.attrs, after) : $pos.node(d).copy(after))\n }\n return this.step(new ReplaceStep(pos, pos, new Slice(before.append(after), depth, depth), true))\n}\n\n// :: (Node, number) → bool\n// Test whether the blocks before and after a given position can be\n// joined.\nexport function canJoin(doc, pos) {\n let $pos = doc.resolve(pos), index = $pos.index()\n return joinable($pos.nodeBefore, $pos.nodeAfter) &&\n $pos.parent.canReplace(index, index + 1)\n}\n\nfunction joinable(a, b) {\n return a && b && !a.isLeaf && a.canAppend(b)\n}\n\n// :: (Node, number, ?number) → ?number\n// Find an ancestor of the given position that can be joined to the\n// block before (or after if `dir` is positive). Returns the joinable\n// point, if any.\nexport function joinPoint(doc, pos, dir = -1) {\n let $pos = doc.resolve(pos)\n for (let d = $pos.depth;; d--) {\n let before, after\n if (d == $pos.depth) {\n before = $pos.nodeBefore\n after = $pos.nodeAfter\n } else if (dir > 0) {\n before = $pos.node(d + 1)\n after = $pos.node(d).maybeChild($pos.index(d) + 1)\n } else {\n before = $pos.node(d).maybeChild($pos.index(d) - 1)\n after = $pos.node(d + 1)\n }\n if (before && !before.isTextblock && joinable(before, after)) return pos\n if (d == 0) break\n pos = dir < 0 ? $pos.before(d) : $pos.after(d)\n }\n}\n\n// :: (number, ?number) → this\n// Join the blocks around the given position. If depth is 2, their\n// last and first siblings are also joined, and so on.\nTransform.prototype.join = function(pos, depth = 1) {\n let step = new ReplaceStep(pos - depth, pos + depth, Slice.empty, true)\n return this.step(step)\n}\n\n// :: (Node, number, NodeType) → ?number\n// Try to find a point where a node of the given type can be inserted\n// near `pos`, by searching up the node hierarchy when `pos` itself\n// isn't a valid place but is at the start or end of a node. Return\n// null if no position was found.\nexport function insertPoint(doc, pos, nodeType) {\n let $pos = doc.resolve(pos)\n if ($pos.parent.canReplaceWith($pos.index(), $pos.index(), nodeType)) return pos\n\n if ($pos.parentOffset == 0)\n for (let d = $pos.depth - 1; d >= 0; d--) {\n let index = $pos.index(d)\n if ($pos.node(d).canReplaceWith(index, index, nodeType)) return $pos.before(d + 1)\n if (index > 0) return null\n }\n if ($pos.parentOffset == $pos.parent.content.size)\n for (let d = $pos.depth - 1; d >= 0; d--) {\n let index = $pos.indexAfter(d)\n if ($pos.node(d).canReplaceWith(index, index, nodeType)) return $pos.after(d + 1)\n if (index < $pos.node(d).childCount) return null\n }\n}\n\n// :: (Node, number, Slice) → ?number\n// Finds a position at or around the given position where the given\n// slice can be inserted. Will look at parent nodes' nearest boundary\n// and try there, even if the original position wasn't directly at the\n// start or end of that node. Returns null when no position was found.\nexport function dropPoint(doc, pos, slice) {\n let $pos = doc.resolve(pos)\n if (!slice.content.size) return pos\n let content = slice.content\n for (let i = 0; i < slice.openStart; i++) content = content.firstChild.content\n for (let pass = 1; pass <= (slice.openStart == 0 && slice.size ? 2 : 1); pass++) {\n for (let d = $pos.depth; d >= 0; d--) {\n let bias = d == $pos.depth ? 0 : $pos.pos <= ($pos.start(d + 1) + $pos.end(d + 1)) / 2 ? -1 : 1\n let insertPos = $pos.index(d) + (bias > 0 ? 1 : 0)\n if (pass == 1\n ? $pos.node(d).canReplace(insertPos, insertPos, content)\n : $pos.node(d).contentMatchAt(insertPos).findWrapping(content.firstChild.type))\n return bias == 0 ? $pos.pos : bias < 0 ? $pos.before(d + 1) : $pos.after(d + 1)\n }\n }\n return null\n}\n","import {Fragment, Slice} from \"prosemirror-model\"\nimport {Step, StepResult} from \"./step\"\n\nfunction mapFragment(fragment, f, parent) {\n let mapped = []\n for (let i = 0; i < fragment.childCount; i++) {\n let child = fragment.child(i)\n if (child.content.size) child = child.copy(mapFragment(child.content, f, child))\n if (child.isInline) child = f(child, parent, i)\n mapped.push(child)\n }\n return Fragment.fromArray(mapped)\n}\n\n// ::- Add a mark to all inline content between two positions.\nexport class AddMarkStep extends Step {\n // :: (number, number, Mark)\n constructor(from, to, mark) {\n super()\n this.from = from\n this.to = to\n this.mark = mark\n }\n\n apply(doc) {\n let oldSlice = doc.slice(this.from, this.to), $from = doc.resolve(this.from)\n let parent = $from.node($from.sharedDepth(this.to))\n let slice = new Slice(mapFragment(oldSlice.content, (node, parent) => {\n if (!parent.type.allowsMarkType(this.mark.type)) return node\n return node.mark(this.mark.addToSet(node.marks))\n }, parent), oldSlice.openStart, oldSlice.openEnd)\n return StepResult.fromReplace(doc, this.from, this.to, slice)\n }\n\n invert() {\n return new RemoveMarkStep(this.from, this.to, this.mark)\n }\n\n map(mapping) {\n let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1)\n if (from.deleted && to.deleted || from.pos >= to.pos) return null\n return new AddMarkStep(from.pos, to.pos, this.mark)\n }\n\n merge(other) {\n if (other instanceof AddMarkStep &&\n other.mark.eq(this.mark) &&\n this.from <= other.to && this.to >= other.from)\n return new AddMarkStep(Math.min(this.from, other.from),\n Math.max(this.to, other.to), this.mark)\n }\n\n toJSON() {\n return {stepType: \"addMark\", mark: this.mark.toJSON(),\n from: this.from, to: this.to}\n }\n\n static fromJSON(schema, json) {\n if (typeof json.from != \"number\" || typeof json.to != \"number\")\n throw new RangeError(\"Invalid input for AddMarkStep.fromJSON\")\n return new AddMarkStep(json.from, json.to, schema.markFromJSON(json.mark))\n }\n}\n\nStep.jsonID(\"addMark\", AddMarkStep)\n\n// ::- Remove a mark from all inline content between two positions.\nexport class RemoveMarkStep extends Step {\n // :: (number, number, Mark)\n constructor(from, to, mark) {\n super()\n this.from = from\n this.to = to\n this.mark = mark\n }\n\n apply(doc) {\n let oldSlice = doc.slice(this.from, this.to)\n let slice = new Slice(mapFragment(oldSlice.content, node => {\n return node.mark(this.mark.removeFromSet(node.marks))\n }), oldSlice.openStart, oldSlice.openEnd)\n return StepResult.fromReplace(doc, this.from, this.to, slice)\n }\n\n invert() {\n return new AddMarkStep(this.from, this.to, this.mark)\n }\n\n map(mapping) {\n let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1)\n if (from.deleted && to.deleted || from.pos >= to.pos) return null\n return new RemoveMarkStep(from.pos, to.pos, this.mark)\n }\n\n merge(other) {\n if (other instanceof RemoveMarkStep &&\n other.mark.eq(this.mark) &&\n this.from <= other.to && this.to >= other.from)\n return new RemoveMarkStep(Math.min(this.from, other.from),\n Math.max(this.to, other.to), this.mark)\n }\n\n toJSON() {\n return {stepType: \"removeMark\", mark: this.mark.toJSON(),\n from: this.from, to: this.to}\n }\n\n static fromJSON(schema, json) {\n if (typeof json.from != \"number\" || typeof json.to != \"number\")\n throw new RangeError(\"Invalid input for RemoveMarkStep.fromJSON\")\n return new RemoveMarkStep(json.from, json.to, schema.markFromJSON(json.mark))\n }\n}\n\nStep.jsonID(\"removeMark\", RemoveMarkStep)\n","import {MarkType, Slice, Fragment} from \"prosemirror-model\"\n\nimport {Transform} from \"./transform\"\nimport {AddMarkStep, RemoveMarkStep} from \"./mark_step\"\nimport {ReplaceStep} from \"./replace_step\"\n\n// :: (number, number, Mark) → this\n// Add the given mark to the inline content between `from` and `to`.\nTransform.prototype.addMark = function(from, to, mark) {\n let removed = [], added = [], removing = null, adding = null\n this.doc.nodesBetween(from, to, (node, pos, parent) => {\n if (!node.isInline) return\n let marks = node.marks\n if (!mark.isInSet(marks) && parent.type.allowsMarkType(mark.type)) {\n let start = Math.max(pos, from), end = Math.min(pos + node.nodeSize, to)\n let newSet = mark.addToSet(marks)\n\n for (let i = 0; i < marks.length; i++) {\n if (!marks[i].isInSet(newSet)) {\n if (removing && removing.to == start && removing.mark.eq(marks[i]))\n removing.to = end\n else\n removed.push(removing = new RemoveMarkStep(start, end, marks[i]))\n }\n }\n\n if (adding && adding.to == start)\n adding.to = end\n else\n added.push(adding = new AddMarkStep(start, end, mark))\n }\n })\n\n removed.forEach(s => this.step(s))\n added.forEach(s => this.step(s))\n return this\n}\n\n// :: (number, number, ?union) → this\n// Remove marks from inline nodes between `from` and `to`. When `mark`\n// is a single mark, remove precisely that mark. When it is a mark type,\n// remove all marks of that type. When it is null, remove all marks of\n// any type.\nTransform.prototype.removeMark = function(from, to, mark = null) {\n let matched = [], step = 0\n this.doc.nodesBetween(from, to, (node, pos) => {\n if (!node.isInline) return\n step++\n let toRemove = null\n if (mark instanceof MarkType) {\n let found = mark.isInSet(node.marks)\n if (found) toRemove = [found]\n } else if (mark) {\n if (mark.isInSet(node.marks)) toRemove = [mark]\n } else {\n toRemove = node.marks\n }\n if (toRemove && toRemove.length) {\n let end = Math.min(pos + node.nodeSize, to)\n for (let i = 0; i < toRemove.length; i++) {\n let style = toRemove[i], found\n for (let j = 0; j < matched.length; j++) {\n let m = matched[j]\n if (m.step == step - 1 && style.eq(matched[j].style)) found = m\n }\n if (found) {\n found.to = end\n found.step = step\n } else {\n matched.push({style, from: Math.max(pos, from), to: end, step})\n }\n }\n }\n })\n matched.forEach(m => this.step(new RemoveMarkStep(m.from, m.to, m.style)))\n return this\n}\n\n// :: (number, NodeType, ?ContentMatch) → this\n// Removes all marks and nodes from the content of the node at `pos`\n// that don't match the given new parent node type. Accepts an\n// optional starting [content match](#model.ContentMatch) as third\n// argument.\nTransform.prototype.clearIncompatible = function(pos, parentType, match = parentType.contentMatch) {\n let node = this.doc.nodeAt(pos)\n let delSteps = [], cur = pos + 1\n for (let i = 0; i < node.childCount; i++) {\n let child = node.child(i), end = cur + child.nodeSize\n let allowed = match.matchType(child.type, child.attrs)\n if (!allowed) {\n delSteps.push(new ReplaceStep(cur, end, Slice.empty))\n } else {\n match = allowed\n for (let j = 0; j < child.marks.length; j++) if (!parentType.allowsMarkType(child.marks[j].type))\n this.step(new RemoveMarkStep(cur, end, child.marks[j]))\n }\n cur = end\n }\n if (!match.validEnd) {\n let fill = match.fillBefore(Fragment.empty, true)\n this.replace(cur, cur, new Slice(fill, 0, 0))\n }\n for (let i = delSteps.length - 1; i >= 0; i--) this.step(delSteps[i])\n return this\n}\n","import {Fragment, Slice} from \"prosemirror-model\"\n\nimport {ReplaceStep, ReplaceAroundStep} from \"./replace_step\"\nimport {Transform} from \"./transform\"\nimport {insertPoint} from \"./structure\"\n\n// :: (Node, number, ?number, ?Slice) → ?Step\n// ‘Fit’ a slice into a given position in the document, producing a\n// [step](#transform.Step) that inserts it. Will return null if\n// there's no meaningful way to insert the slice here, or inserting it\n// would be a no-op (an empty slice over an empty range).\nexport function replaceStep(doc, from, to = from, slice = Slice.empty) {\n if (from == to && !slice.size) return null\n\n let $from = doc.resolve(from), $to = doc.resolve(to)\n // Optimization -- avoid work if it's obvious that it's not needed.\n if (fitsTrivially($from, $to, slice)) return new ReplaceStep(from, to, slice)\n let placed = placeSlice($from, slice)\n\n let fittedLeft = fitLeft($from, placed)\n let fitted = fitRight($from, $to, fittedLeft)\n if (!fitted) return null\n if (fittedLeft.size != fitted.size && canMoveText($from, $to, fittedLeft)) {\n let d = $to.depth, after = $to.after(d)\n while (d > 1 && after == $to.end(--d)) ++after\n let fittedAfter = fitRight($from, doc.resolve(after), fittedLeft)\n if (fittedAfter)\n return new ReplaceAroundStep(from, after, to, $to.end(), fittedAfter, fittedLeft.size)\n }\n return fitted.size || from != to ? new ReplaceStep(from, to, fitted) : null\n}\n\n// :: (number, ?number, ?Slice) → this\n// Replace the part of the document between `from` and `to` with the\n// given `slice`.\nTransform.prototype.replace = function(from, to = from, slice = Slice.empty) {\n let step = replaceStep(this.doc, from, to, slice)\n if (step) this.step(step)\n return this\n}\n\n// :: (number, number, union) → this\n// Replace the given range with the given content, which may be a\n// fragment, node, or array of nodes.\nTransform.prototype.replaceWith = function(from, to, content) {\n return this.replace(from, to, new Slice(Fragment.from(content), 0, 0))\n}\n\n// :: (number, number) → this\n// Delete the content between the given positions.\nTransform.prototype.delete = function(from, to) {\n return this.replace(from, to, Slice.empty)\n}\n\n// :: (number, union) → this\n// Insert the given content at the given position.\nTransform.prototype.insert = function(pos, content) {\n return this.replaceWith(pos, pos, content)\n}\n\n\n\nfunction fitLeftInner($from, depth, placed, placedBelow) {\n let content = Fragment.empty, openEnd = 0, placedHere = placed[depth]\n if ($from.depth > depth) {\n let inner = fitLeftInner($from, depth + 1, placed, placedBelow || placedHere)\n openEnd = inner.openEnd + 1\n content = Fragment.from($from.node(depth + 1).copy(inner.content))\n }\n\n if (placedHere) {\n content = content.append(placedHere.content)\n openEnd = placedHere.openEnd\n }\n if (placedBelow) {\n content = content.append($from.node(depth).contentMatchAt($from.indexAfter(depth)).fillBefore(Fragment.empty, true))\n openEnd = 0\n }\n\n return {content, openEnd}\n}\n\nfunction fitLeft($from, placed) {\n let {content, openEnd} = fitLeftInner($from, 0, placed, false)\n return new Slice(content, $from.depth, openEnd || 0)\n}\n\nfunction fitRightJoin(content, parent, $from, $to, depth, openStart, openEnd) {\n let match, count = content.childCount, matchCount = count - (openEnd > 0 ? 1 : 0)\n let parentNode = openStart < 0 ? parent : $from.node(depth)\n if (openStart < 0)\n match = parentNode.contentMatchAt(matchCount)\n else if (count == 1 && openEnd > 0)\n match = parentNode.contentMatchAt(openStart ? $from.index(depth) : $from.indexAfter(depth))\n else\n match = parentNode.contentMatchAt($from.indexAfter(depth))\n .matchFragment(content, count > 0 && openStart ? 1 : 0, matchCount)\n\n let toNode = $to.node(depth)\n if (openEnd > 0 && depth < $to.depth) {\n let after = toNode.content.cutByIndex($to.indexAfter(depth)).addToStart(content.lastChild)\n let joinable = match.fillBefore(after, true)\n // Can't insert content if there's a single node stretched across this gap\n if (joinable && joinable.size && openStart > 0 && count == 1) joinable = null\n\n if (joinable) {\n let inner = fitRightJoin(content.lastChild.content, content.lastChild, $from, $to,\n depth + 1, count == 1 ? openStart - 1 : -1, openEnd - 1)\n if (inner) {\n let last = content.lastChild.copy(inner)\n if (joinable.size)\n return content.cutByIndex(0, count - 1).append(joinable).addToEnd(last)\n else\n return content.replaceChild(count - 1, last)\n }\n }\n }\n if (openEnd > 0)\n match = match.matchType((count == 1 && openStart > 0 ? $from.node(depth + 1) : content.lastChild).type)\n\n // If we're here, the next level can't be joined, so we see what\n // happens if we leave it open.\n let toIndex = $to.index(depth)\n if (toIndex == toNode.childCount && !toNode.type.compatibleContent(parent.type)) return null\n let joinable = match.fillBefore(toNode.content, true, toIndex)\n for (let i = toIndex; joinable && i < toNode.content.childCount; i++)\n if (!parentNode.type.allowsMarks(toNode.content.child(i).marks)) joinable = null\n if (!joinable) return null\n\n if (openEnd > 0) {\n let closed = fitRightClosed(content.lastChild, openEnd - 1, $from, depth + 1,\n count == 1 ? openStart - 1 : -1)\n content = content.replaceChild(count - 1, closed)\n }\n content = content.append(joinable)\n if ($to.depth > depth)\n content = content.addToEnd(fitRightSeparate($to, depth + 1))\n return content\n}\n\nfunction fitRightClosed(node, openEnd, $from, depth, openStart) {\n let match, content = node.content, count = content.childCount\n if (openStart >= 0)\n match = $from.node(depth).contentMatchAt($from.indexAfter(depth))\n .matchFragment(content, openStart > 0 ? 1 : 0, count)\n else\n match = node.contentMatchAt(count)\n\n if (openEnd > 0) {\n let closed = fitRightClosed(content.lastChild, openEnd - 1, $from, depth + 1,\n count == 1 ? openStart - 1 : -1)\n content = content.replaceChild(count - 1, closed)\n }\n\n return node.copy(content.append(match.fillBefore(Fragment.empty, true)))\n}\n\nfunction fitRightSeparate($to, depth) {\n let node = $to.node(depth)\n let fill = node.contentMatchAt(0).fillBefore(node.content, true, $to.index(depth))\n if ($to.depth > depth) fill = fill.addToEnd(fitRightSeparate($to, depth + 1))\n return node.copy(fill)\n}\n\nfunction normalizeSlice(content, openStart, openEnd) {\n while (openStart > 0 && openEnd > 0 && content.childCount == 1) {\n content = content.firstChild.content\n openStart--\n openEnd--\n }\n return new Slice(content, openStart, openEnd)\n}\n\n// : (ResolvedPos, ResolvedPos, number, Slice) → Slice\nfunction fitRight($from, $to, slice) {\n let fitted = fitRightJoin(slice.content, $from.node(0), $from, $to, 0, slice.openStart, slice.openEnd)\n if (!fitted) return null\n return normalizeSlice(fitted, slice.openStart, $to.depth)\n}\n\nfunction fitsTrivially($from, $to, slice) {\n return !slice.openStart && !slice.openEnd && $from.start() == $to.start() &&\n $from.parent.canReplace($from.index(), $to.index(), slice.content)\n}\n\nfunction canMoveText($from, $to, slice) {\n if (!$to.parent.isTextblock) return false\n\n let parent = slice.openEnd ? nodeRight(slice.content, slice.openEnd)\n : $from.node($from.depth - (slice.openStart - slice.openEnd))\n if (!parent.isTextblock) return false\n for (let i = $to.index(); i < $to.parent.childCount; i++)\n if (!parent.type.allowsMarks($to.parent.child(i).marks)) return false\n let match\n if (slice.openEnd) {\n match = parent.contentMatchAt(parent.childCount)\n } else {\n match = parent.contentMatchAt(parent.childCount)\n if (slice.size) match = match.matchFragment(slice.content, slice.openStart ? 1 : 0)\n }\n match = match.matchFragment($to.parent.content, $to.index())\n return match && match.validEnd\n}\n\nfunction nodeRight(content, depth) {\n for (let i = 1; i < depth; i++) content = content.lastChild.content\n return content.lastChild\n}\n\n// Algorithm for 'placing' the elements of a slice into a gap:\n//\n// We consider the content of each node that is open to the left to be\n// independently placeable. I.e. in , when the\n// paragraph on the left is open, \"foo\" can be placed (somewhere on\n// the left side of the replacement gap) independently from p(\"bar\").\n//\n// So placeSlice splits up a slice into a number of sub-slices,\n// along with information on where they can be placed on the given\n// left-side edge. It works by walking the open side of the slice,\n// from the inside out, and trying to find a landing spot for each\n// element, by simultaneously scanning over the gap side. When no\n// place is found for an open node's content, it is left in that node.\n\n// : (ResolvedPos, Slice) → [{content: Fragment, openEnd: number, depth: number}]\nfunction placeSlice($from, slice) {\n let frontier = new Frontier($from)\n for (let pass = 1; slice.size && pass <= 3; pass++) {\n let value = frontier.placeSlice(slice.content, slice.openStart, slice.openEnd, pass)\n if (pass == 3 && value != slice && value.size) pass = 0 // Restart if the 3rd pass made progress but left content\n slice = value\n }\n while (frontier.open.length) frontier.closeNode()\n return frontier.placed\n}\n\n// Helper class that models the open side of the insert position,\n// keeping track of the content match and already inserted content\n// at each depth.\nclass Frontier {\n constructor($pos) {\n // : [{parent: Node, match: ContentMatch, content: Fragment, wrapper: bool, openEnd: number, depth: number}]\n this.open = []\n for (let d = 0; d <= $pos.depth; d++) {\n let parent = $pos.node(d), match = parent.contentMatchAt($pos.indexAfter(d))\n this.open.push({parent, match, content: Fragment.empty, wrapper: false, openEnd: 0, depth: d})\n }\n this.placed = []\n }\n\n // : (Fragment, number, number, number, ?Node) → Slice\n // Tries to place the content of the given slice, and returns a\n // slice containing unplaced content.\n //\n // pass 1: try to fit directly\n // pass 2: allow wrapper nodes to be introduced\n // pass 3: allow unwrapping of nodes that aren't open\n placeSlice(fragment, openStart, openEnd, pass, parent) {\n if (openStart > 0) {\n let first = fragment.firstChild\n let inner = this.placeSlice(first.content, Math.max(0, openStart - 1),\n openEnd && fragment.childCount == 1 ? openEnd - 1 : 0,\n pass, first)\n if (inner.content != first.content) {\n if (inner.content.size) {\n fragment = fragment.replaceChild(0, first.copy(inner.content))\n openStart = inner.openStart + 1\n } else {\n if (fragment.childCount == 1) openEnd = 0\n fragment = fragment.cutByIndex(1)\n openStart = 0\n }\n }\n }\n let result = this.placeContent(fragment, openStart, openEnd, pass, parent)\n if (pass > 2 && result.size && openStart == 0) {\n let child = result.content.firstChild, single = result.content.childCount == 1\n this.placeContent(child.content, 0, openEnd && single ? openEnd - 1 : 0, pass, child)\n result = single ? Fragment.empty : new Slice(result.content.cutByIndex(1), 0, openEnd)\n }\n return result\n }\n\n placeContent(fragment, openStart, openEnd, pass, parent) {\n let i = 0\n // Go over the fragment's children\n for (; i < fragment.childCount; i++) {\n let child = fragment.child(i), placed = false, last = i == fragment.childCount - 1\n // Try each open node in turn, starting from the innermost\n for (let d = this.open.length - 1; d >= 0; d--) {\n let open = this.open[d], wrap\n\n // If pass > 1, it is allowed to wrap the node to help find a\n // fit, so if findWrapping returns something, we add open\n // nodes to the frontier for that wrapping.\n if (pass > 1 && (wrap = open.match.findWrapping(child.type)) &&\n !(parent && wrap.length && wrap[wrap.length - 1] == parent.type)) {\n while (this.open.length - 1 > d) this.closeNode()\n for (let w = 0; w < wrap.length; w++) {\n open.match = open.match.matchType(wrap[w])\n d++\n open = {parent: wrap[w].create(),\n match: wrap[w].contentMatch,\n content: Fragment.empty, wrapper: true, openEnd: 0, depth: d + w}\n this.open.push(open)\n }\n }\n\n // See if the child fits here\n let match = open.match.matchType(child.type)\n if (!match) {\n let fill = open.match.fillBefore(Fragment.from(child))\n if (fill) {\n for (let j = 0; j < fill.childCount; j++) {\n let ch = fill.child(j)\n this.addNode(open, ch, 0)\n match = open.match.matchFragment(ch)\n }\n } else if (parent && open.match.matchType(parent.type)) {\n // Don't continue looking further up if the parent node\n // would fit here.\n break\n } else {\n continue\n }\n }\n\n // Close open nodes above this one, since we're starting to\n // add to this.\n while (this.open.length - 1 > d) this.closeNode()\n // Strip marks from the child or close its start when necessary\n child = child.mark(open.parent.type.allowedMarks(child.marks))\n if (openStart) {\n child = closeNodeStart(child, openStart, last ? openEnd : 0)\n openStart = 0\n }\n // Add the child to this open node and adjust its metadata\n this.addNode(open, child, last ? openEnd : 0)\n open.match = match\n if (last) openEnd = 0\n placed = true\n break\n }\n // As soon as we've failed to place a node we stop looking at\n // later nodes\n if (!placed) break\n }\n // Close the current open node if it's not the the root and we\n // either placed up to the end of the node or the the current\n // slice depth's node type matches the open node's type\n if (this.open.length > 1 &&\n (i > 0 && i == fragment.childCount ||\n parent && this.open[this.open.length - 1].parent.type == parent.type))\n this.closeNode()\n\n return new Slice(fragment.cutByIndex(i), openStart, openEnd)\n }\n\n addNode(open, node, openEnd) {\n open.content = closeFragmentEnd(open.content, open.openEnd).addToEnd(node)\n open.openEnd = openEnd\n }\n\n closeNode() {\n let open = this.open.pop()\n if (open.content.size == 0) {\n // Nothing here\n } else if (open.wrapper) {\n this.addNode(this.open[this.open.length - 1], open.parent.copy(open.content), open.openEnd + 1)\n } else {\n this.placed[open.depth] = {depth: open.depth, content: open.content, openEnd: open.openEnd}\n }\n }\n}\n\nfunction closeNodeStart(node, openStart, openEnd) {\n let content = node.content\n if (openStart > 1) {\n let first = closeNodeStart(node.firstChild, openStart - 1, node.childCount == 1 ? openEnd - 1 : 0)\n content = node.content.replaceChild(0, first)\n }\n let fill = node.type.contentMatch.fillBefore(content, openEnd == 0)\n return node.copy(fill.append(content))\n}\n\nfunction closeNodeEnd(node, depth) {\n let content = node.content\n if (depth > 1) {\n let last = closeNodeEnd(node.lastChild, depth - 1)\n content = node.content.replaceChild(node.childCount - 1, last)\n }\n let fill = node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true)\n return node.copy(content.append(fill))\n}\n\nfunction closeFragmentEnd(fragment, depth) {\n return depth ? fragment.replaceChild(fragment.childCount - 1, closeNodeEnd(fragment.lastChild, depth)) : fragment\n}\n\n// :: (number, number, Slice) → this\n// Replace a range of the document with a given slice, using `from`,\n// `to`, and the slice's [`openStart`](#model.Slice.openStart) property\n// as hints, rather than fixed start and end points. This method may\n// grow the replaced area or close open nodes in the slice in order to\n// get a fit that is more in line with WYSIWYG expectations, by\n// dropping fully covered parent nodes of the replaced region when\n// they are marked [non-defining](#model.NodeSpec.defining), or\n// including an open parent node from the slice that _is_ marked as\n// [defining](#model.NodeSpec.defining).\n//\n// This is the method, for example, to handle paste. The similar\n// [`replace`](#transform.Transform.replace) method is a more\n// primitive tool which will _not_ move the start and end of its given\n// range, and is useful in situations where you need more precise\n// control over what happens.\nTransform.prototype.replaceRange = function(from, to, slice) {\n if (!slice.size) return this.deleteRange(from, to)\n\n let $from = this.doc.resolve(from), $to = this.doc.resolve(to)\n if (fitsTrivially($from, $to, slice))\n return this.step(new ReplaceStep(from, to, slice))\n\n let targetDepths = coveredDepths($from, this.doc.resolve(to))\n // Can't replace the whole document, so remove 0 if it's present\n if (targetDepths[targetDepths.length - 1] == 0) targetDepths.pop()\n // Negative numbers represent not expansion over the whole node at\n // that depth, but replacing from $from.before(-D) to $to.pos.\n let preferredTarget = -($from.depth + 1)\n targetDepths.unshift(preferredTarget)\n // This loop picks a preferred target depth, if one of the covering\n // depths is not outside of a defining node, and adds negative\n // depths for any depth that has $from at its start and does not\n // cross a defining node.\n for (let d = $from.depth, pos = $from.pos - 1; d > 0; d--, pos--) {\n let spec = $from.node(d).type.spec\n if (spec.defining || spec.isolating) break\n if (targetDepths.indexOf(d) > -1) preferredTarget = d\n else if ($from.before(d) == pos) targetDepths.splice(1, 0, -d)\n }\n // Try to fit each possible depth of the slice into each possible\n // target depth, starting with the preferred depths.\n let preferredTargetIndex = targetDepths.indexOf(preferredTarget)\n\n let leftNodes = [], preferredDepth = slice.openStart\n for (let content = slice.content, i = 0;; i++) {\n let node = content.firstChild\n leftNodes.push(node)\n if (i == slice.openStart) break\n content = node.content\n }\n // Back up if the node directly above openStart, or the node above\n // that separated only by a non-defining textblock node, is defining.\n if (preferredDepth > 0 && leftNodes[preferredDepth - 1].type.spec.defining &&\n $from.node(preferredTargetIndex).type != leftNodes[preferredDepth - 1].type)\n preferredDepth -= 1\n else if (preferredDepth >= 2 && leftNodes[preferredDepth - 1].isTextblock && leftNodes[preferredDepth - 2].type.spec.defining &&\n $from.node(preferredTargetIndex).type != leftNodes[preferredDepth - 2].type)\n preferredDepth -= 2\n\n for (let j = slice.openStart; j >= 0; j--) {\n let openDepth = (j + preferredDepth + 1) % (slice.openStart + 1)\n let insert = leftNodes[openDepth]\n if (!insert) continue\n for (let i = 0; i < targetDepths.length; i++) {\n // Loop over possible expansion levels, starting with the\n // preferred one\n let targetDepth = targetDepths[(i + preferredTargetIndex) % targetDepths.length], expand = true\n if (targetDepth < 0) { expand = false; targetDepth = -targetDepth }\n let parent = $from.node(targetDepth - 1), index = $from.index(targetDepth - 1)\n if (parent.canReplaceWith(index, index, insert.type, insert.marks))\n return this.replace($from.before(targetDepth), expand ? $to.after(targetDepth) : to,\n new Slice(closeFragment(slice.content, 0, slice.openStart, openDepth),\n openDepth, slice.openEnd))\n }\n }\n\n let startSteps = this.steps.length\n for (let i = targetDepths.length - 1; i >= 0; i--) {\n this.replace(from, to, slice)\n if (this.steps.length > startSteps) break\n let depth = targetDepths[i]\n if (i < 0) continue\n from = $from.before(depth); to = $to.after(depth)\n }\n return this\n}\n\nfunction closeFragment(fragment, depth, oldOpen, newOpen, parent) {\n if (depth < oldOpen) {\n let first = fragment.firstChild\n fragment = fragment.replaceChild(0, first.copy(closeFragment(first.content, depth + 1, oldOpen, newOpen, first)))\n }\n if (depth > newOpen) {\n let match = parent.contentMatchAt(0)\n let start = match.fillBefore(fragment).append(fragment)\n fragment = start.append(match.matchFragment(start).fillBefore(Fragment.empty, true))\n }\n return fragment\n}\n\n// :: (number, number, Node) → this\n// Replace the given range with a node, but use `from` and `to` as\n// hints, rather than precise positions. When from and to are the same\n// and are at the start or end of a parent node in which the given\n// node doesn't fit, this method may _move_ them out towards a parent\n// that does allow the given node to be placed. When the given range\n// completely covers a parent node, this method may completely replace\n// that parent node.\nTransform.prototype.replaceRangeWith = function(from, to, node) {\n if (!node.isInline && from == to && this.doc.resolve(from).parent.content.size) {\n let point = insertPoint(this.doc, from, node.type)\n if (point != null) from = to = point\n }\n return this.replaceRange(from, to, new Slice(Fragment.from(node), 0, 0))\n}\n\n// :: (number, number) → this\n// Delete the given range, expanding it to cover fully covered\n// parent nodes until a valid replace is found.\nTransform.prototype.deleteRange = function(from, to) {\n let $from = this.doc.resolve(from), $to = this.doc.resolve(to)\n let covered = coveredDepths($from, $to)\n for (let i = 0; i < covered.length; i++) {\n let depth = covered[i], last = i == covered.length - 1\n if ((last && depth == 0) || $from.node(depth).type.contentMatch.validEnd)\n return this.delete($from.start(depth), $to.end(depth))\n if (depth > 0 && (last || $from.node(depth - 1).canReplace($from.index(depth - 1), $to.indexAfter(depth - 1))))\n return this.delete($from.before(depth), $to.after(depth))\n }\n for (let d = 1; d <= $from.depth; d++) {\n if (from - $from.start(d) == $from.depth - d && to > $from.end(d) && $to.end(d) - to != $to.depth - d)\n return this.delete($from.before(d), to)\n }\n return this.delete(from, to)\n}\n\n// : (ResolvedPos, ResolvedPos) → [number]\n// Returns an array of all depths for which $from - $to spans the\n// whole content of the nodes at that depth.\nfunction coveredDepths($from, $to) {\n let result = [], minDepth = Math.min($from.depth, $to.depth)\n for (let d = minDepth; d >= 0; d--) {\n let start = $from.start(d)\n if (start < $from.pos - ($from.depth - d) ||\n $to.end(d) > $to.pos + ($to.depth - d) ||\n $from.node(d).type.spec.isolating ||\n $to.node(d).type.spec.isolating) break\n if (start == $to.start(d)) result.push(d)\n }\n return result\n}\n"],"names":["const","let","super","slice","d","splitting","this","index","found","i","joinable"],"mappings":"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"} \ No newline at end of file diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/dist/index.js b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/dist/index.js new file mode 100644 index 0000000000..e8496fb82a --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/dist/index.js @@ -0,0 +1,1711 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +var prosemirrorModel = require('prosemirror-model'); + +// Mappable:: interface +// There are several things that positions can be mapped through. +// Such objects conform to this interface. +// +// map:: (pos: number, assoc: ?number) → number +// Map a position through this object. When given, `assoc` (should +// be -1 or 1, defaults to 1) determines with which side the +// position is associated, which determines in which direction to +// move when a chunk of content is inserted at the mapped position. +// +// mapResult:: (pos: number, assoc: ?number) → MapResult +// Map a position, and return an object containing additional +// information about the mapping. The result's `deleted` field tells +// you whether the position was deleted (completely enclosed in a +// replaced range) during the mapping. When content on only one side +// is deleted, the position itself is only considered deleted when +// `assoc` points in the direction of the deleted content. + +// Recovery values encode a range index and an offset. They are +// represented as numbers, because tons of them will be created when +// mapping, for example, a large number of decorations. The number's +// lower 16 bits provide the index, the remaining bits the offset. +// +// Note: We intentionally don't use bit shift operators to en- and +// decode these, since those clip to 32 bits, which we might in rare +// cases want to overflow. A 64-bit float can represent 48-bit +// integers precisely. + +var lower16 = 0xffff; +var factor16 = Math.pow(2, 16); + +function makeRecover(index, offset) { return index + offset * factor16 } +function recoverIndex(value) { return value & lower16 } +function recoverOffset(value) { return (value - (value & lower16)) / factor16 } + +// ::- An object representing a mapped position with extra +// information. +var MapResult = function MapResult(pos, deleted, recover) { + if ( deleted === void 0 ) deleted = false; + if ( recover === void 0 ) recover = null; + + // :: number The mapped version of the position. + this.pos = pos; + // :: bool Tells you whether the position was deleted, that is, + // whether the step removed its surroundings from the document. + this.deleted = deleted; + this.recover = recover; +}; + +// :: class extends Mappable +// A map describing the deletions and insertions made by a step, which +// can be used to find the correspondence between positions in the +// pre-step version of a document and the same position in the +// post-step version. +var StepMap = function StepMap(ranges, inverted) { + if ( inverted === void 0 ) inverted = false; + + this.ranges = ranges; + this.inverted = inverted; +}; + +StepMap.prototype.recover = function recover (value) { + var diff = 0, index = recoverIndex(value); + if (!this.inverted) { for (var i = 0; i < index; i++) + { diff += this.ranges[i * 3 + 2] - this.ranges[i * 3 + 1]; } } + return this.ranges[index * 3] + diff + recoverOffset(value) +}; + +// : (number, ?number) → MapResult +StepMap.prototype.mapResult = function mapResult (pos, assoc) { + if ( assoc === void 0 ) assoc = 1; + return this._map(pos, assoc, false) }; + +// : (number, ?number) → number +StepMap.prototype.map = function map (pos, assoc) { + if ( assoc === void 0 ) assoc = 1; + return this._map(pos, assoc, true) }; + +StepMap.prototype._map = function _map (pos, assoc, simple) { + var diff = 0, oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; + for (var i = 0; i < this.ranges.length; i += 3) { + var start = this.ranges[i] - (this.inverted ? diff : 0); + if (start > pos) { break } + var oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex], end = start + oldSize; + if (pos <= end) { + var side = !oldSize ? assoc : pos == start ? -1 : pos == end ? 1 : assoc; + var result = start + diff + (side < 0 ? 0 : newSize); + if (simple) { return result } + var recover = makeRecover(i / 3, pos - start); + return new MapResult(result, assoc < 0 ? pos != start : pos != end, recover) + } + diff += newSize - oldSize; + } + return simple ? pos + diff : new MapResult(pos + diff) +}; + +StepMap.prototype.touches = function touches (pos, recover) { + var diff = 0, index = recoverIndex(recover); + var oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; + for (var i = 0; i < this.ranges.length; i += 3) { + var start = this.ranges[i] - (this.inverted ? diff : 0); + if (start > pos) { break } + var oldSize = this.ranges[i + oldIndex], end = start + oldSize; + if (pos <= end && i == index * 3) { return true } + diff += this.ranges[i + newIndex] - oldSize; + } + return false +}; + +// :: ((oldStart: number, oldEnd: number, newStart: number, newEnd: number)) +// Calls the given function on each of the changed ranges included in +// this map. +StepMap.prototype.forEach = function forEach (f) { + var oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; + for (var i = 0, diff = 0; i < this.ranges.length; i += 3) { + var start = this.ranges[i], oldStart = start - (this.inverted ? diff : 0), newStart = start + (this.inverted ? 0 : diff); + var oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex]; + f(oldStart, oldStart + oldSize, newStart, newStart + newSize); + diff += newSize - oldSize; + } +}; + +// :: () → StepMap +// Create an inverted version of this map. The result can be used to +// map positions in the post-step document to the pre-step document. +StepMap.prototype.invert = function invert () { + return new StepMap(this.ranges, !this.inverted) +}; + +StepMap.prototype.toString = function toString () { + return (this.inverted ? "-" : "") + JSON.stringify(this.ranges) +}; + +// :: (n: number) → StepMap +// Create a map that moves all positions by offset `n` (which may be +// negative). This can be useful when applying steps meant for a +// sub-document to a larger document, or vice-versa. +StepMap.offset = function offset (n) { + return n == 0 ? StepMap.empty : new StepMap(n < 0 ? [0, -n, 0] : [0, 0, n]) +}; + +StepMap.empty = new StepMap([]); + +// :: class extends Mappable +// A mapping represents a pipeline of zero or more [step +// maps](#transform.StepMap). It has special provisions for losslessly +// handling mapping positions through a series of steps in which some +// steps are inverted versions of earlier steps. (This comes up when +// ‘[rebasing](/docs/guide/#transform.rebasing)’ steps for +// collaboration or history management.) +var Mapping = function Mapping(maps, mirror, from, to) { + // :: [StepMap] + // The step maps in this mapping. + this.maps = maps || []; + // :: number + // The starting position in the `maps` array, used when `map` or + // `mapResult` is called. + this.from = from || 0; + // :: number + // The end position in the `maps` array. + this.to = to == null ? this.maps.length : to; + this.mirror = mirror; +}; + +// :: (?number, ?number) → Mapping +// Create a mapping that maps only through a part of this one. +Mapping.prototype.slice = function slice (from, to) { + if ( from === void 0 ) from = 0; + if ( to === void 0 ) to = this.maps.length; + + return new Mapping(this.maps, this.mirror, from, to) +}; + +Mapping.prototype.copy = function copy () { + return new Mapping(this.maps.slice(), this.mirror && this.mirror.slice(), this.from, this.to) +}; + +// :: (StepMap, ?number) +// Add a step map to the end of this mapping. If `mirrors` is +// given, it should be the index of the step map that is the mirror +// image of this one. +Mapping.prototype.appendMap = function appendMap (map, mirrors) { + this.to = this.maps.push(map); + if (mirrors != null) { this.setMirror(this.maps.length - 1, mirrors); } +}; + +// :: (Mapping) +// Add all the step maps in a given mapping to this one (preserving +// mirroring information). +Mapping.prototype.appendMapping = function appendMapping (mapping) { + for (var i = 0, startSize = this.maps.length; i < mapping.maps.length; i++) { + var mirr = mapping.getMirror(i); + this.appendMap(mapping.maps[i], mirr != null && mirr < i ? startSize + mirr : null); + } +}; + +// :: (number) → ?number +// Finds the offset of the step map that mirrors the map at the +// given offset, in this mapping (as per the second argument to +// `appendMap`). +Mapping.prototype.getMirror = function getMirror (n) { + if (this.mirror) { for (var i = 0; i < this.mirror.length; i++) + { if (this.mirror[i] == n) { return this.mirror[i + (i % 2 ? -1 : 1)] } } } +}; + +Mapping.prototype.setMirror = function setMirror (n, m) { + if (!this.mirror) { this.mirror = []; } + this.mirror.push(n, m); +}; + +// :: (Mapping) +// Append the inverse of the given mapping to this one. +Mapping.prototype.appendMappingInverted = function appendMappingInverted (mapping) { + for (var i = mapping.maps.length - 1, totalSize = this.maps.length + mapping.maps.length; i >= 0; i--) { + var mirr = mapping.getMirror(i); + this.appendMap(mapping.maps[i].invert(), mirr != null && mirr > i ? totalSize - mirr - 1 : null); + } +}; + +// :: () → Mapping +// Create an inverted version of this mapping. +Mapping.prototype.invert = function invert () { + var inverse = new Mapping; + inverse.appendMappingInverted(this); + return inverse +}; + +// : (number, ?number) → number +// Map a position through this mapping. +Mapping.prototype.map = function map (pos, assoc) { + if ( assoc === void 0 ) assoc = 1; + + if (this.mirror) { return this._map(pos, assoc, true) } + for (var i = this.from; i < this.to; i++) + { pos = this.maps[i].map(pos, assoc); } + return pos +}; + +// : (number, ?number) → MapResult +// Map a position through this mapping, returning a mapping +// result. +Mapping.prototype.mapResult = function mapResult (pos, assoc) { + if ( assoc === void 0 ) assoc = 1; + return this._map(pos, assoc, false) }; + +Mapping.prototype._map = function _map (pos, assoc, simple) { + var deleted = false, recoverables = null; + + for (var i = this.from; i < this.to; i++) { + var map = this.maps[i], rec = recoverables && recoverables[i]; + if (rec != null && map.touches(pos, rec)) { + pos = map.recover(rec); + continue + } + + var result = map.mapResult(pos, assoc); + if (result.recover != null) { + var corr = this.getMirror(i); + if (corr != null && corr > i && corr < this.to) { + if (result.deleted) { + i = corr; + pos = this.maps[corr].recover(result.recover); + continue + } else { +(recoverables || (recoverables = Object.create(null)))[corr] = result.recover; + } + } + } + + if (result.deleted) { deleted = true; } + pos = result.pos; + } + + return simple ? pos : new MapResult(pos, deleted) +}; + +function TransformError(message) { + var err = Error.call(this, message); + err.__proto__ = TransformError.prototype; + return err +} + +TransformError.prototype = Object.create(Error.prototype); +TransformError.prototype.constructor = TransformError; +TransformError.prototype.name = "TransformError"; + +// ::- Abstraction to build up and track an array of +// [steps](#transform.Step) representing a document transformation. +// +// Most transforming methods return the `Transform` object itself, so +// that they can be chained. +var Transform = function Transform(doc) { + // :: Node + // The current document (the result of applying the steps in the + // transform). + this.doc = doc; + // :: [Step] + // The steps in this transform. + this.steps = []; + // :: [Node] + // The documents before each of the steps. + this.docs = []; + // :: Mapping + // A mapping with the maps for each of the steps in this transform. + this.mapping = new Mapping; +}; + +var prototypeAccessors = { before: { configurable: true },docChanged: { configurable: true } }; + +// :: Node The starting document. +prototypeAccessors.before.get = function () { return this.docs.length ? this.docs[0] : this.doc }; + +// :: (step: Step) → this +// Apply a new step in this transform, saving the result. Throws an +// error when the step fails. +Transform.prototype.step = function step (object) { + var result = this.maybeStep(object); + if (result.failed) { throw new TransformError(result.failed) } + return this +}; + +// :: (Step) → StepResult +// Try to apply a step in this transformation, ignoring it if it +// fails. Returns the step result. +Transform.prototype.maybeStep = function maybeStep (step) { + var result = step.apply(this.doc); + if (!result.failed) { this.addStep(step, result.doc); } + return result +}; + +// :: bool +// True when the document has been changed (when there are any +// steps). +prototypeAccessors.docChanged.get = function () { + return this.steps.length > 0 +}; + +Transform.prototype.addStep = function addStep (step, doc) { + this.docs.push(this.doc); + this.steps.push(step); + this.mapping.appendMap(step.getMap()); + this.doc = doc; +}; + +Object.defineProperties( Transform.prototype, prototypeAccessors ); + +function mustOverride() { throw new Error("Override me") } + +var stepsByID = Object.create(null); + +// ::- A step object represents an atomic change. It generally applies +// only to the document it was created for, since the positions +// stored in it will only make sense for that document. +// +// New steps are defined by creating classes that extend `Step`, +// overriding the `apply`, `invert`, `map`, `getMap` and `fromJSON` +// methods, and registering your class with a unique +// JSON-serialization identifier using +// [`Step.jsonID`](#transform.Step^jsonID). +var Step = function Step () {}; + +Step.prototype.apply = function apply (_doc) { return mustOverride() }; + +// :: () → StepMap +// Get the step map that represents the changes made by this step, +// and which can be used to transform between positions in the old +// and the new document. +Step.prototype.getMap = function getMap () { return StepMap.empty }; + +// :: (doc: Node) → Step +// Create an inverted version of this step. Needs the document as it +// was before the step as argument. +Step.prototype.invert = function invert (_doc) { return mustOverride() }; + +// :: (mapping: Mappable) → ?Step +// Map this step through a mappable thing, returning either a +// version of that step with its positions adjusted, or `null` if +// the step was entirely deleted by the mapping. +Step.prototype.map = function map (_mapping) { return mustOverride() }; + +// :: (other: Step) → ?Step +// Try to merge this step with another one, to be applied directly +// after it. Returns the merged step when possible, null if the +// steps can't be merged. +Step.prototype.merge = function merge (_other) { return null }; + +// :: () → Object +// Create a JSON-serializeable representation of this step. When +// defining this for a custom subclass, make sure the result object +// includes the step type's [JSON id](#transform.Step^jsonID) under +// the `stepType` property. +Step.prototype.toJSON = function toJSON () { return mustOverride() }; + +// :: (Schema, Object) → Step +// Deserialize a step from its JSON representation. Will call +// through to the step class' own implementation of this method. +Step.fromJSON = function fromJSON (schema, json) { + if (!json || !json.stepType) { throw new RangeError("Invalid input for Step.fromJSON") } + var type = stepsByID[json.stepType]; + if (!type) { throw new RangeError(("No step type " + (json.stepType) + " defined")) } + return type.fromJSON(schema, json) +}; + +// :: (string, constructor) +// To be able to serialize steps to JSON, each step needs a string +// ID to attach to its JSON representation. Use this method to +// register an ID for your step classes. Try to pick something +// that's unlikely to clash with steps from other modules. +Step.jsonID = function jsonID (id, stepClass) { + if (id in stepsByID) { throw new RangeError("Duplicate use of step JSON ID " + id) } + stepsByID[id] = stepClass; + stepClass.prototype.jsonID = id; + return stepClass +}; + +// ::- The result of [applying](#transform.Step.apply) a step. Contains either a +// new document or a failure value. +var StepResult = function StepResult(doc, failed) { + // :: ?Node The transformed document. + this.doc = doc; + // :: ?string Text providing information about a failed step. + this.failed = failed; +}; + +// :: (Node) → StepResult +// Create a successful step result. +StepResult.ok = function ok (doc) { return new StepResult(doc, null) }; + +// :: (string) → StepResult +// Create a failed step result. +StepResult.fail = function fail (message) { return new StepResult(null, message) }; + +// :: (Node, number, number, Slice) → StepResult +// Call [`Node.replace`](#model.Node.replace) with the given +// arguments. Create a successful result if it succeeds, and a +// failed one if it throws a `ReplaceError`. +StepResult.fromReplace = function fromReplace (doc, from, to, slice) { + try { + return StepResult.ok(doc.replace(from, to, slice)) + } catch (e) { + if (e instanceof prosemirrorModel.ReplaceError) { return StepResult.fail(e.message) } + throw e + } +}; + +// ::- Replace a part of the document with a slice of new content. +var ReplaceStep = /*@__PURE__*/(function (Step) { + function ReplaceStep(from, to, slice, structure) { + Step.call(this); + this.from = from; + this.to = to; + this.slice = slice; + this.structure = !!structure; + } + + if ( Step ) ReplaceStep.__proto__ = Step; + ReplaceStep.prototype = Object.create( Step && Step.prototype ); + ReplaceStep.prototype.constructor = ReplaceStep; + + ReplaceStep.prototype.apply = function apply (doc) { + if (this.structure && contentBetween(doc, this.from, this.to)) + { return StepResult.fail("Structure replace would overwrite content") } + return StepResult.fromReplace(doc, this.from, this.to, this.slice) + }; + + ReplaceStep.prototype.getMap = function getMap () { + return new StepMap([this.from, this.to - this.from, this.slice.size]) + }; + + ReplaceStep.prototype.invert = function invert (doc) { + return new ReplaceStep(this.from, this.from + this.slice.size, doc.slice(this.from, this.to)) + }; + + ReplaceStep.prototype.map = function map (mapping) { + var from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); + if (from.deleted && to.deleted) { return null } + return new ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice) + }; + + ReplaceStep.prototype.merge = function merge (other) { + if (!(other instanceof ReplaceStep) || other.structure != this.structure) { return null } + + if (this.from + this.slice.size == other.from && !this.slice.openEnd && !other.slice.openStart) { + var slice = this.slice.size + other.slice.size == 0 ? prosemirrorModel.Slice.empty + : new prosemirrorModel.Slice(this.slice.content.append(other.slice.content), this.slice.openStart, other.slice.openEnd); + return new ReplaceStep(this.from, this.to + (other.to - other.from), slice, this.structure) + } else if (other.to == this.from && !this.slice.openStart && !other.slice.openEnd) { + var slice$1 = this.slice.size + other.slice.size == 0 ? prosemirrorModel.Slice.empty + : new prosemirrorModel.Slice(other.slice.content.append(this.slice.content), other.slice.openStart, this.slice.openEnd); + return new ReplaceStep(other.from, this.to, slice$1, this.structure) + } else { + return null + } + }; + + ReplaceStep.prototype.toJSON = function toJSON () { + var json = {stepType: "replace", from: this.from, to: this.to}; + if (this.slice.size) { json.slice = this.slice.toJSON(); } + if (this.structure) { json.structure = true; } + return json + }; + + ReplaceStep.fromJSON = function fromJSON (schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + { throw new RangeError("Invalid input for ReplaceStep.fromJSON") } + return new ReplaceStep(json.from, json.to, prosemirrorModel.Slice.fromJSON(schema, json.slice), !!json.structure) + }; + + return ReplaceStep; +}(Step)); + +Step.jsonID("replace", ReplaceStep); + +// ::- Replace a part of the document with a slice of content, but +// preserve a range of the replaced content by moving it into the +// slice. +var ReplaceAroundStep = /*@__PURE__*/(function (Step) { + function ReplaceAroundStep(from, to, gapFrom, gapTo, slice, insert, structure) { + Step.call(this); + this.from = from; + this.to = to; + this.gapFrom = gapFrom; + this.gapTo = gapTo; + this.slice = slice; + this.insert = insert; + this.structure = !!structure; + } + + if ( Step ) ReplaceAroundStep.__proto__ = Step; + ReplaceAroundStep.prototype = Object.create( Step && Step.prototype ); + ReplaceAroundStep.prototype.constructor = ReplaceAroundStep; + + ReplaceAroundStep.prototype.apply = function apply (doc) { + if (this.structure && (contentBetween(doc, this.from, this.gapFrom) || + contentBetween(doc, this.gapTo, this.to))) + { return StepResult.fail("Structure gap-replace would overwrite content") } + + var gap = doc.slice(this.gapFrom, this.gapTo); + if (gap.openStart || gap.openEnd) + { return StepResult.fail("Gap is not a flat range") } + var inserted = this.slice.insertAt(this.insert, gap.content); + if (!inserted) { return StepResult.fail("Content does not fit in gap") } + return StepResult.fromReplace(doc, this.from, this.to, inserted) + }; + + ReplaceAroundStep.prototype.getMap = function getMap () { + return new StepMap([this.from, this.gapFrom - this.from, this.insert, + this.gapTo, this.to - this.gapTo, this.slice.size - this.insert]) + }; + + ReplaceAroundStep.prototype.invert = function invert (doc) { + var gap = this.gapTo - this.gapFrom; + return new ReplaceAroundStep(this.from, this.from + this.slice.size + gap, + this.from + this.insert, this.from + this.insert + gap, + doc.slice(this.from, this.to).removeBetween(this.gapFrom - this.from, this.gapTo - this.from), + this.gapFrom - this.from, this.structure) + }; + + ReplaceAroundStep.prototype.map = function map (mapping) { + var from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); + var gapFrom = mapping.map(this.gapFrom, -1), gapTo = mapping.map(this.gapTo, 1); + if ((from.deleted && to.deleted) || gapFrom < from.pos || gapTo > to.pos) { return null } + return new ReplaceAroundStep(from.pos, to.pos, gapFrom, gapTo, this.slice, this.insert, this.structure) + }; + + ReplaceAroundStep.prototype.toJSON = function toJSON () { + var json = {stepType: "replaceAround", from: this.from, to: this.to, + gapFrom: this.gapFrom, gapTo: this.gapTo, insert: this.insert}; + if (this.slice.size) { json.slice = this.slice.toJSON(); } + if (this.structure) { json.structure = true; } + return json + }; + + ReplaceAroundStep.fromJSON = function fromJSON (schema, json) { + if (typeof json.from != "number" || typeof json.to != "number" || + typeof json.gapFrom != "number" || typeof json.gapTo != "number" || typeof json.insert != "number") + { throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON") } + return new ReplaceAroundStep(json.from, json.to, json.gapFrom, json.gapTo, + prosemirrorModel.Slice.fromJSON(schema, json.slice), json.insert, !!json.structure) + }; + + return ReplaceAroundStep; +}(Step)); + +Step.jsonID("replaceAround", ReplaceAroundStep); + +function contentBetween(doc, from, to) { + var $from = doc.resolve(from), dist = to - from, depth = $from.depth; + while (dist > 0 && depth > 0 && $from.indexAfter(depth) == $from.node(depth).childCount) { + depth--; + dist--; + } + if (dist > 0) { + var next = $from.node(depth).maybeChild($from.indexAfter(depth)); + while (dist > 0) { + if (!next || next.isLeaf) { return true } + next = next.firstChild; + dist--; + } + } + return false +} + +function canCut(node, start, end) { + return (start == 0 || node.canReplace(start, node.childCount)) && + (end == node.childCount || node.canReplace(0, end)) +} + +// :: (NodeRange) → ?number +// Try to find a target depth to which the content in the given range +// can be lifted. Will not go across +// [isolating](#model.NodeSpec.isolating) parent nodes. +function liftTarget(range) { + var parent = range.parent; + var content = parent.content.cutByIndex(range.startIndex, range.endIndex); + for (var depth = range.depth;; --depth) { + var node = range.$from.node(depth); + var index = range.$from.index(depth), endIndex = range.$to.indexAfter(depth); + if (depth < range.depth && node.canReplace(index, endIndex, content)) + { return depth } + if (depth == 0 || node.type.spec.isolating || !canCut(node, index, endIndex)) { break } + } +} + +// :: (NodeRange, number) → this +// Split the content in the given range off from its parent, if there +// is sibling content before or after it, and move it up the tree to +// the depth specified by `target`. You'll probably want to use +// [`liftTarget`](#transform.liftTarget) to compute `target`, to make +// sure the lift is valid. +Transform.prototype.lift = function(range, target) { + var $from = range.$from; + var $to = range.$to; + var depth = range.depth; + + var gapStart = $from.before(depth + 1), gapEnd = $to.after(depth + 1); + var start = gapStart, end = gapEnd; + + var before = prosemirrorModel.Fragment.empty, openStart = 0; + for (var d = depth, splitting = false; d > target; d--) + { if (splitting || $from.index(d) > 0) { + splitting = true; + before = prosemirrorModel.Fragment.from($from.node(d).copy(before)); + openStart++; + } else { + start--; + } } + var after = prosemirrorModel.Fragment.empty, openEnd = 0; + for (var d$1 = depth, splitting$1 = false; d$1 > target; d$1--) + { if (splitting$1 || $to.after(d$1 + 1) < $to.end(d$1)) { + splitting$1 = true; + after = prosemirrorModel.Fragment.from($to.node(d$1).copy(after)); + openEnd++; + } else { + end++; + } } + + return this.step(new ReplaceAroundStep(start, end, gapStart, gapEnd, + new prosemirrorModel.Slice(before.append(after), openStart, openEnd), + before.size - openStart, true)) +}; + +// :: (NodeRange, NodeType, ?Object, ?NodeRange) → ?[{type: NodeType, attrs: ?Object}] +// Try to find a valid way to wrap the content in the given range in a +// node of the given type. May introduce extra nodes around and inside +// the wrapper node, if necessary. Returns null if no valid wrapping +// could be found. When `innerRange` is given, that range's content is +// used as the content to fit into the wrapping, instead of the +// content of `range`. +function findWrapping(range, nodeType, attrs, innerRange) { + if ( innerRange === void 0 ) innerRange = range; + + var around = findWrappingOutside(range, nodeType); + var inner = around && findWrappingInside(innerRange, nodeType); + if (!inner) { return null } + return around.map(withAttrs).concat({type: nodeType, attrs: attrs}).concat(inner.map(withAttrs)) +} + +function withAttrs(type) { return {type: type, attrs: null} } + +function findWrappingOutside(range, type) { + var parent = range.parent; + var startIndex = range.startIndex; + var endIndex = range.endIndex; + var around = parent.contentMatchAt(startIndex).findWrapping(type); + if (!around) { return null } + var outer = around.length ? around[0] : type; + return parent.canReplaceWith(startIndex, endIndex, outer) ? around : null +} + +function findWrappingInside(range, type) { + var parent = range.parent; + var startIndex = range.startIndex; + var endIndex = range.endIndex; + var inner = parent.child(startIndex); + var inside = type.contentMatch.findWrapping(inner.type); + if (!inside) { return null } + var lastType = inside.length ? inside[inside.length - 1] : type; + var innerMatch = lastType.contentMatch; + for (var i = startIndex; innerMatch && i < endIndex; i++) + { innerMatch = innerMatch.matchType(parent.child(i).type); } + if (!innerMatch || !innerMatch.validEnd) { return null } + return inside +} + +// :: (NodeRange, [{type: NodeType, attrs: ?Object}]) → this +// Wrap the given [range](#model.NodeRange) in the given set of wrappers. +// The wrappers are assumed to be valid in this position, and should +// probably be computed with [`findWrapping`](#transform.findWrapping). +Transform.prototype.wrap = function(range, wrappers) { + var content = prosemirrorModel.Fragment.empty; + for (var i = wrappers.length - 1; i >= 0; i--) + { content = prosemirrorModel.Fragment.from(wrappers[i].type.create(wrappers[i].attrs, content)); } + + var start = range.start, end = range.end; + return this.step(new ReplaceAroundStep(start, end, start, end, new prosemirrorModel.Slice(content, 0, 0), wrappers.length, true)) +}; + +// :: (number, ?number, NodeType, ?Object) → this +// Set the type of all textblocks (partly) between `from` and `to` to +// the given node type with the given attributes. +Transform.prototype.setBlockType = function(from, to, type, attrs) { + var this$1 = this; + if ( to === void 0 ) to = from; + + if (!type.isTextblock) { throw new RangeError("Type given to setBlockType should be a textblock") } + var mapFrom = this.steps.length; + this.doc.nodesBetween(from, to, function (node, pos) { + if (node.isTextblock && !node.hasMarkup(type, attrs) && canChangeType(this$1.doc, this$1.mapping.slice(mapFrom).map(pos), type)) { + // Ensure all markup that isn't allowed in the new node type is cleared + this$1.clearIncompatible(this$1.mapping.slice(mapFrom).map(pos, 1), type); + var mapping = this$1.mapping.slice(mapFrom); + var startM = mapping.map(pos, 1), endM = mapping.map(pos + node.nodeSize, 1); + this$1.step(new ReplaceAroundStep(startM, endM, startM + 1, endM - 1, + new prosemirrorModel.Slice(prosemirrorModel.Fragment.from(type.create(attrs, null, node.marks)), 0, 0), 1, true)); + return false + } + }); + return this +}; + +function canChangeType(doc, pos, type) { + var $pos = doc.resolve(pos), index = $pos.index(); + return $pos.parent.canReplaceWith(index, index + 1, type) +} + +// :: (number, ?NodeType, ?Object, ?[Mark]) → this +// Change the type, attributes, and/or marks of the node at `pos`. +// When `type` isn't given, the existing node type is preserved, +Transform.prototype.setNodeMarkup = function(pos, type, attrs, marks) { + var node = this.doc.nodeAt(pos); + if (!node) { throw new RangeError("No node at given position") } + if (!type) { type = node.type; } + var newNode = type.create(attrs, null, marks || node.marks); + if (node.isLeaf) + { return this.replaceWith(pos, pos + node.nodeSize, newNode) } + + if (!type.validContent(node.content)) + { throw new RangeError("Invalid content for node type " + type.name) } + + return this.step(new ReplaceAroundStep(pos, pos + node.nodeSize, pos + 1, pos + node.nodeSize - 1, + new prosemirrorModel.Slice(prosemirrorModel.Fragment.from(newNode), 0, 0), 1, true)) +}; + +// :: (Node, number, number, ?[?{type: NodeType, attrs: ?Object}]) → bool +// Check whether splitting at the given position is allowed. +function canSplit(doc, pos, depth, typesAfter) { + if ( depth === void 0 ) depth = 1; + + var $pos = doc.resolve(pos), base = $pos.depth - depth; + var innerType = (typesAfter && typesAfter[typesAfter.length - 1]) || $pos.parent; + if (base < 0 || $pos.parent.type.spec.isolating || + !$pos.parent.canReplace($pos.index(), $pos.parent.childCount) || + !innerType.type.validContent($pos.parent.content.cutByIndex($pos.index(), $pos.parent.childCount))) + { return false } + for (var d = $pos.depth - 1, i = depth - 2; d > base; d--, i--) { + var node = $pos.node(d), index$1 = $pos.index(d); + if (node.type.spec.isolating) { return false } + var rest = node.content.cutByIndex(index$1, node.childCount); + var after = (typesAfter && typesAfter[i]) || node; + if (after != node) { rest = rest.replaceChild(0, after.type.create(after.attrs)); } + if (!node.canReplace(index$1 + 1, node.childCount) || !after.type.validContent(rest)) + { return false } + } + var index = $pos.indexAfter(base); + var baseType = typesAfter && typesAfter[0]; + return $pos.node(base).canReplaceWith(index, index, baseType ? baseType.type : $pos.node(base + 1).type) +} + +// :: (number, ?number, ?[?{type: NodeType, attrs: ?Object}]) → this +// Split the node at the given position, and optionally, if `depth` is +// greater than one, any number of nodes above that. By default, the +// parts split off will inherit the node type of the original node. +// This can be changed by passing an array of types and attributes to +// use after the split. +Transform.prototype.split = function(pos, depth, typesAfter) { + if ( depth === void 0 ) depth = 1; + + var $pos = this.doc.resolve(pos), before = prosemirrorModel.Fragment.empty, after = prosemirrorModel.Fragment.empty; + for (var d = $pos.depth, e = $pos.depth - depth, i = depth - 1; d > e; d--, i--) { + before = prosemirrorModel.Fragment.from($pos.node(d).copy(before)); + var typeAfter = typesAfter && typesAfter[i]; + after = prosemirrorModel.Fragment.from(typeAfter ? typeAfter.type.create(typeAfter.attrs, after) : $pos.node(d).copy(after)); + } + return this.step(new ReplaceStep(pos, pos, new prosemirrorModel.Slice(before.append(after), depth, depth), true)) +}; + +// :: (Node, number) → bool +// Test whether the blocks before and after a given position can be +// joined. +function canJoin(doc, pos) { + var $pos = doc.resolve(pos), index = $pos.index(); + return joinable($pos.nodeBefore, $pos.nodeAfter) && + $pos.parent.canReplace(index, index + 1) +} + +function joinable(a, b) { + return a && b && !a.isLeaf && a.canAppend(b) +} + +// :: (Node, number, ?number) → ?number +// Find an ancestor of the given position that can be joined to the +// block before (or after if `dir` is positive). Returns the joinable +// point, if any. +function joinPoint(doc, pos, dir) { + if ( dir === void 0 ) dir = -1; + + var $pos = doc.resolve(pos); + for (var d = $pos.depth;; d--) { + var before = (void 0), after = (void 0); + if (d == $pos.depth) { + before = $pos.nodeBefore; + after = $pos.nodeAfter; + } else if (dir > 0) { + before = $pos.node(d + 1); + after = $pos.node(d).maybeChild($pos.index(d) + 1); + } else { + before = $pos.node(d).maybeChild($pos.index(d) - 1); + after = $pos.node(d + 1); + } + if (before && !before.isTextblock && joinable(before, after)) { return pos } + if (d == 0) { break } + pos = dir < 0 ? $pos.before(d) : $pos.after(d); + } +} + +// :: (number, ?number) → this +// Join the blocks around the given position. If depth is 2, their +// last and first siblings are also joined, and so on. +Transform.prototype.join = function(pos, depth) { + if ( depth === void 0 ) depth = 1; + + var step = new ReplaceStep(pos - depth, pos + depth, prosemirrorModel.Slice.empty, true); + return this.step(step) +}; + +// :: (Node, number, NodeType) → ?number +// Try to find a point where a node of the given type can be inserted +// near `pos`, by searching up the node hierarchy when `pos` itself +// isn't a valid place but is at the start or end of a node. Return +// null if no position was found. +function insertPoint(doc, pos, nodeType) { + var $pos = doc.resolve(pos); + if ($pos.parent.canReplaceWith($pos.index(), $pos.index(), nodeType)) { return pos } + + if ($pos.parentOffset == 0) + { for (var d = $pos.depth - 1; d >= 0; d--) { + var index = $pos.index(d); + if ($pos.node(d).canReplaceWith(index, index, nodeType)) { return $pos.before(d + 1) } + if (index > 0) { return null } + } } + if ($pos.parentOffset == $pos.parent.content.size) + { for (var d$1 = $pos.depth - 1; d$1 >= 0; d$1--) { + var index$1 = $pos.indexAfter(d$1); + if ($pos.node(d$1).canReplaceWith(index$1, index$1, nodeType)) { return $pos.after(d$1 + 1) } + if (index$1 < $pos.node(d$1).childCount) { return null } + } } +} + +// :: (Node, number, Slice) → ?number +// Finds a position at or around the given position where the given +// slice can be inserted. Will look at parent nodes' nearest boundary +// and try there, even if the original position wasn't directly at the +// start or end of that node. Returns null when no position was found. +function dropPoint(doc, pos, slice) { + var $pos = doc.resolve(pos); + if (!slice.content.size) { return pos } + var content = slice.content; + for (var i = 0; i < slice.openStart; i++) { content = content.firstChild.content; } + for (var pass = 1; pass <= (slice.openStart == 0 && slice.size ? 2 : 1); pass++) { + for (var d = $pos.depth; d >= 0; d--) { + var bias = d == $pos.depth ? 0 : $pos.pos <= ($pos.start(d + 1) + $pos.end(d + 1)) / 2 ? -1 : 1; + var insertPos = $pos.index(d) + (bias > 0 ? 1 : 0); + if (pass == 1 + ? $pos.node(d).canReplace(insertPos, insertPos, content) + : $pos.node(d).contentMatchAt(insertPos).findWrapping(content.firstChild.type)) + { return bias == 0 ? $pos.pos : bias < 0 ? $pos.before(d + 1) : $pos.after(d + 1) } + } + } + return null +} + +function mapFragment(fragment, f, parent) { + var mapped = []; + for (var i = 0; i < fragment.childCount; i++) { + var child = fragment.child(i); + if (child.content.size) { child = child.copy(mapFragment(child.content, f, child)); } + if (child.isInline) { child = f(child, parent, i); } + mapped.push(child); + } + return prosemirrorModel.Fragment.fromArray(mapped) +} + +// ::- Add a mark to all inline content between two positions. +var AddMarkStep = /*@__PURE__*/(function (Step) { + function AddMarkStep(from, to, mark) { + Step.call(this); + this.from = from; + this.to = to; + this.mark = mark; + } + + if ( Step ) AddMarkStep.__proto__ = Step; + AddMarkStep.prototype = Object.create( Step && Step.prototype ); + AddMarkStep.prototype.constructor = AddMarkStep; + + AddMarkStep.prototype.apply = function apply (doc) { + var this$1 = this; + + var oldSlice = doc.slice(this.from, this.to), $from = doc.resolve(this.from); + var parent = $from.node($from.sharedDepth(this.to)); + var slice = new prosemirrorModel.Slice(mapFragment(oldSlice.content, function (node, parent) { + if (!parent.type.allowsMarkType(this$1.mark.type)) { return node } + return node.mark(this$1.mark.addToSet(node.marks)) + }, parent), oldSlice.openStart, oldSlice.openEnd); + return StepResult.fromReplace(doc, this.from, this.to, slice) + }; + + AddMarkStep.prototype.invert = function invert () { + return new RemoveMarkStep(this.from, this.to, this.mark) + }; + + AddMarkStep.prototype.map = function map (mapping) { + var from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); + if (from.deleted && to.deleted || from.pos >= to.pos) { return null } + return new AddMarkStep(from.pos, to.pos, this.mark) + }; + + AddMarkStep.prototype.merge = function merge (other) { + if (other instanceof AddMarkStep && + other.mark.eq(this.mark) && + this.from <= other.to && this.to >= other.from) + { return new AddMarkStep(Math.min(this.from, other.from), + Math.max(this.to, other.to), this.mark) } + }; + + AddMarkStep.prototype.toJSON = function toJSON () { + return {stepType: "addMark", mark: this.mark.toJSON(), + from: this.from, to: this.to} + }; + + AddMarkStep.fromJSON = function fromJSON (schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + { throw new RangeError("Invalid input for AddMarkStep.fromJSON") } + return new AddMarkStep(json.from, json.to, schema.markFromJSON(json.mark)) + }; + + return AddMarkStep; +}(Step)); + +Step.jsonID("addMark", AddMarkStep); + +// ::- Remove a mark from all inline content between two positions. +var RemoveMarkStep = /*@__PURE__*/(function (Step) { + function RemoveMarkStep(from, to, mark) { + Step.call(this); + this.from = from; + this.to = to; + this.mark = mark; + } + + if ( Step ) RemoveMarkStep.__proto__ = Step; + RemoveMarkStep.prototype = Object.create( Step && Step.prototype ); + RemoveMarkStep.prototype.constructor = RemoveMarkStep; + + RemoveMarkStep.prototype.apply = function apply (doc) { + var this$1 = this; + + var oldSlice = doc.slice(this.from, this.to); + var slice = new prosemirrorModel.Slice(mapFragment(oldSlice.content, function (node) { + return node.mark(this$1.mark.removeFromSet(node.marks)) + }), oldSlice.openStart, oldSlice.openEnd); + return StepResult.fromReplace(doc, this.from, this.to, slice) + }; + + RemoveMarkStep.prototype.invert = function invert () { + return new AddMarkStep(this.from, this.to, this.mark) + }; + + RemoveMarkStep.prototype.map = function map (mapping) { + var from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); + if (from.deleted && to.deleted || from.pos >= to.pos) { return null } + return new RemoveMarkStep(from.pos, to.pos, this.mark) + }; + + RemoveMarkStep.prototype.merge = function merge (other) { + if (other instanceof RemoveMarkStep && + other.mark.eq(this.mark) && + this.from <= other.to && this.to >= other.from) + { return new RemoveMarkStep(Math.min(this.from, other.from), + Math.max(this.to, other.to), this.mark) } + }; + + RemoveMarkStep.prototype.toJSON = function toJSON () { + return {stepType: "removeMark", mark: this.mark.toJSON(), + from: this.from, to: this.to} + }; + + RemoveMarkStep.fromJSON = function fromJSON (schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + { throw new RangeError("Invalid input for RemoveMarkStep.fromJSON") } + return new RemoveMarkStep(json.from, json.to, schema.markFromJSON(json.mark)) + }; + + return RemoveMarkStep; +}(Step)); + +Step.jsonID("removeMark", RemoveMarkStep); + +// :: (number, number, Mark) → this +// Add the given mark to the inline content between `from` and `to`. +Transform.prototype.addMark = function(from, to, mark) { + var this$1 = this; + + var removed = [], added = [], removing = null, adding = null; + this.doc.nodesBetween(from, to, function (node, pos, parent) { + if (!node.isInline) { return } + var marks = node.marks; + if (!mark.isInSet(marks) && parent.type.allowsMarkType(mark.type)) { + var start = Math.max(pos, from), end = Math.min(pos + node.nodeSize, to); + var newSet = mark.addToSet(marks); + + for (var i = 0; i < marks.length; i++) { + if (!marks[i].isInSet(newSet)) { + if (removing && removing.to == start && removing.mark.eq(marks[i])) + { removing.to = end; } + else + { removed.push(removing = new RemoveMarkStep(start, end, marks[i])); } + } + } + + if (adding && adding.to == start) + { adding.to = end; } + else + { added.push(adding = new AddMarkStep(start, end, mark)); } + } + }); + + removed.forEach(function (s) { return this$1.step(s); }); + added.forEach(function (s) { return this$1.step(s); }); + return this +}; + +// :: (number, number, ?union) → this +// Remove marks from inline nodes between `from` and `to`. When `mark` +// is a single mark, remove precisely that mark. When it is a mark type, +// remove all marks of that type. When it is null, remove all marks of +// any type. +Transform.prototype.removeMark = function(from, to, mark) { + var this$1 = this; + if ( mark === void 0 ) mark = null; + + var matched = [], step = 0; + this.doc.nodesBetween(from, to, function (node, pos) { + if (!node.isInline) { return } + step++; + var toRemove = null; + if (mark instanceof prosemirrorModel.MarkType) { + var found = mark.isInSet(node.marks); + if (found) { toRemove = [found]; } + } else if (mark) { + if (mark.isInSet(node.marks)) { toRemove = [mark]; } + } else { + toRemove = node.marks; + } + if (toRemove && toRemove.length) { + var end = Math.min(pos + node.nodeSize, to); + for (var i = 0; i < toRemove.length; i++) { + var style = toRemove[i], found$1 = (void 0); + for (var j = 0; j < matched.length; j++) { + var m = matched[j]; + if (m.step == step - 1 && style.eq(matched[j].style)) { found$1 = m; } + } + if (found$1) { + found$1.to = end; + found$1.step = step; + } else { + matched.push({style: style, from: Math.max(pos, from), to: end, step: step}); + } + } + } + }); + matched.forEach(function (m) { return this$1.step(new RemoveMarkStep(m.from, m.to, m.style)); }); + return this +}; + +// :: (number, NodeType, ?ContentMatch) → this +// Removes all marks and nodes from the content of the node at `pos` +// that don't match the given new parent node type. Accepts an +// optional starting [content match](#model.ContentMatch) as third +// argument. +Transform.prototype.clearIncompatible = function(pos, parentType, match) { + if ( match === void 0 ) match = parentType.contentMatch; + + var node = this.doc.nodeAt(pos); + var delSteps = [], cur = pos + 1; + for (var i = 0; i < node.childCount; i++) { + var child = node.child(i), end = cur + child.nodeSize; + var allowed = match.matchType(child.type, child.attrs); + if (!allowed) { + delSteps.push(new ReplaceStep(cur, end, prosemirrorModel.Slice.empty)); + } else { + match = allowed; + for (var j = 0; j < child.marks.length; j++) { if (!parentType.allowsMarkType(child.marks[j].type)) + { this.step(new RemoveMarkStep(cur, end, child.marks[j])); } } + } + cur = end; + } + if (!match.validEnd) { + var fill = match.fillBefore(prosemirrorModel.Fragment.empty, true); + this.replace(cur, cur, new prosemirrorModel.Slice(fill, 0, 0)); + } + for (var i$1 = delSteps.length - 1; i$1 >= 0; i$1--) { this.step(delSteps[i$1]); } + return this +}; + +// :: (Node, number, ?number, ?Slice) → ?Step +// ‘Fit’ a slice into a given position in the document, producing a +// [step](#transform.Step) that inserts it. Will return null if +// there's no meaningful way to insert the slice here, or inserting it +// would be a no-op (an empty slice over an empty range). +function replaceStep(doc, from, to, slice) { + if ( to === void 0 ) to = from; + if ( slice === void 0 ) slice = prosemirrorModel.Slice.empty; + + if (from == to && !slice.size) { return null } + + var $from = doc.resolve(from), $to = doc.resolve(to); + // Optimization -- avoid work if it's obvious that it's not needed. + if (fitsTrivially($from, $to, slice)) { return new ReplaceStep(from, to, slice) } + var placed = placeSlice($from, slice); + + var fittedLeft = fitLeft($from, placed); + var fitted = fitRight($from, $to, fittedLeft); + if (!fitted) { return null } + if (fittedLeft.size != fitted.size && canMoveText($from, $to, fittedLeft)) { + var d = $to.depth, after = $to.after(d); + while (d > 1 && after == $to.end(--d)) { ++after; } + var fittedAfter = fitRight($from, doc.resolve(after), fittedLeft); + if (fittedAfter) + { return new ReplaceAroundStep(from, after, to, $to.end(), fittedAfter, fittedLeft.size) } + } + return fitted.size || from != to ? new ReplaceStep(from, to, fitted) : null +} + +// :: (number, ?number, ?Slice) → this +// Replace the part of the document between `from` and `to` with the +// given `slice`. +Transform.prototype.replace = function(from, to, slice) { + if ( to === void 0 ) to = from; + if ( slice === void 0 ) slice = prosemirrorModel.Slice.empty; + + var step = replaceStep(this.doc, from, to, slice); + if (step) { this.step(step); } + return this +}; + +// :: (number, number, union) → this +// Replace the given range with the given content, which may be a +// fragment, node, or array of nodes. +Transform.prototype.replaceWith = function(from, to, content) { + return this.replace(from, to, new prosemirrorModel.Slice(prosemirrorModel.Fragment.from(content), 0, 0)) +}; + +// :: (number, number) → this +// Delete the content between the given positions. +Transform.prototype.delete = function(from, to) { + return this.replace(from, to, prosemirrorModel.Slice.empty) +}; + +// :: (number, union) → this +// Insert the given content at the given position. +Transform.prototype.insert = function(pos, content) { + return this.replaceWith(pos, pos, content) +}; + + + +function fitLeftInner($from, depth, placed, placedBelow) { + var content = prosemirrorModel.Fragment.empty, openEnd = 0, placedHere = placed[depth]; + if ($from.depth > depth) { + var inner = fitLeftInner($from, depth + 1, placed, placedBelow || placedHere); + openEnd = inner.openEnd + 1; + content = prosemirrorModel.Fragment.from($from.node(depth + 1).copy(inner.content)); + } + + if (placedHere) { + content = content.append(placedHere.content); + openEnd = placedHere.openEnd; + } + if (placedBelow) { + content = content.append($from.node(depth).contentMatchAt($from.indexAfter(depth)).fillBefore(prosemirrorModel.Fragment.empty, true)); + openEnd = 0; + } + + return {content: content, openEnd: openEnd} +} + +function fitLeft($from, placed) { + var ref = fitLeftInner($from, 0, placed, false); + var content = ref.content; + var openEnd = ref.openEnd; + return new prosemirrorModel.Slice(content, $from.depth, openEnd || 0) +} + +function fitRightJoin(content, parent, $from, $to, depth, openStart, openEnd) { + var match, count = content.childCount, matchCount = count - (openEnd > 0 ? 1 : 0); + var parentNode = openStart < 0 ? parent : $from.node(depth); + if (openStart < 0) + { match = parentNode.contentMatchAt(matchCount); } + else if (count == 1 && openEnd > 0) + { match = parentNode.contentMatchAt(openStart ? $from.index(depth) : $from.indexAfter(depth)); } + else + { match = parentNode.contentMatchAt($from.indexAfter(depth)) + .matchFragment(content, count > 0 && openStart ? 1 : 0, matchCount); } + + var toNode = $to.node(depth); + if (openEnd > 0 && depth < $to.depth) { + var after = toNode.content.cutByIndex($to.indexAfter(depth)).addToStart(content.lastChild); + var joinable$1 = match.fillBefore(after, true); + // Can't insert content if there's a single node stretched across this gap + if (joinable$1 && joinable$1.size && openStart > 0 && count == 1) { joinable$1 = null; } + + if (joinable$1) { + var inner = fitRightJoin(content.lastChild.content, content.lastChild, $from, $to, + depth + 1, count == 1 ? openStart - 1 : -1, openEnd - 1); + if (inner) { + var last = content.lastChild.copy(inner); + if (joinable$1.size) + { return content.cutByIndex(0, count - 1).append(joinable$1).addToEnd(last) } + else + { return content.replaceChild(count - 1, last) } + } + } + } + if (openEnd > 0) + { match = match.matchType((count == 1 && openStart > 0 ? $from.node(depth + 1) : content.lastChild).type); } + + // If we're here, the next level can't be joined, so we see what + // happens if we leave it open. + var toIndex = $to.index(depth); + if (toIndex == toNode.childCount && !toNode.type.compatibleContent(parent.type)) { return null } + var joinable = match.fillBefore(toNode.content, true, toIndex); + for (var i = toIndex; joinable && i < toNode.content.childCount; i++) + { if (!parentNode.type.allowsMarks(toNode.content.child(i).marks)) { joinable = null; } } + if (!joinable) { return null } + + if (openEnd > 0) { + var closed = fitRightClosed(content.lastChild, openEnd - 1, $from, depth + 1, + count == 1 ? openStart - 1 : -1); + content = content.replaceChild(count - 1, closed); + } + content = content.append(joinable); + if ($to.depth > depth) + { content = content.addToEnd(fitRightSeparate($to, depth + 1)); } + return content +} + +function fitRightClosed(node, openEnd, $from, depth, openStart) { + var match, content = node.content, count = content.childCount; + if (openStart >= 0) + { match = $from.node(depth).contentMatchAt($from.indexAfter(depth)) + .matchFragment(content, openStart > 0 ? 1 : 0, count); } + else + { match = node.contentMatchAt(count); } + + if (openEnd > 0) { + var closed = fitRightClosed(content.lastChild, openEnd - 1, $from, depth + 1, + count == 1 ? openStart - 1 : -1); + content = content.replaceChild(count - 1, closed); + } + + return node.copy(content.append(match.fillBefore(prosemirrorModel.Fragment.empty, true))) +} + +function fitRightSeparate($to, depth) { + var node = $to.node(depth); + var fill = node.contentMatchAt(0).fillBefore(node.content, true, $to.index(depth)); + if ($to.depth > depth) { fill = fill.addToEnd(fitRightSeparate($to, depth + 1)); } + return node.copy(fill) +} + +function normalizeSlice(content, openStart, openEnd) { + while (openStart > 0 && openEnd > 0 && content.childCount == 1) { + content = content.firstChild.content; + openStart--; + openEnd--; + } + return new prosemirrorModel.Slice(content, openStart, openEnd) +} + +// : (ResolvedPos, ResolvedPos, number, Slice) → Slice +function fitRight($from, $to, slice) { + var fitted = fitRightJoin(slice.content, $from.node(0), $from, $to, 0, slice.openStart, slice.openEnd); + if (!fitted) { return null } + return normalizeSlice(fitted, slice.openStart, $to.depth) +} + +function fitsTrivially($from, $to, slice) { + return !slice.openStart && !slice.openEnd && $from.start() == $to.start() && + $from.parent.canReplace($from.index(), $to.index(), slice.content) +} + +function canMoveText($from, $to, slice) { + if (!$to.parent.isTextblock) { return false } + + var parent = slice.openEnd ? nodeRight(slice.content, slice.openEnd) + : $from.node($from.depth - (slice.openStart - slice.openEnd)); + if (!parent.isTextblock) { return false } + for (var i = $to.index(); i < $to.parent.childCount; i++) + { if (!parent.type.allowsMarks($to.parent.child(i).marks)) { return false } } + var match; + if (slice.openEnd) { + match = parent.contentMatchAt(parent.childCount); + } else { + match = parent.contentMatchAt(parent.childCount); + if (slice.size) { match = match.matchFragment(slice.content, slice.openStart ? 1 : 0); } + } + match = match.matchFragment($to.parent.content, $to.index()); + return match && match.validEnd +} + +function nodeRight(content, depth) { + for (var i = 1; i < depth; i++) { content = content.lastChild.content; } + return content.lastChild +} + +// Algorithm for 'placing' the elements of a slice into a gap: +// +// We consider the content of each node that is open to the left to be +// independently placeable. I.e. in , when the +// paragraph on the left is open, "foo" can be placed (somewhere on +// the left side of the replacement gap) independently from p("bar"). +// +// So placeSlice splits up a slice into a number of sub-slices, +// along with information on where they can be placed on the given +// left-side edge. It works by walking the open side of the slice, +// from the inside out, and trying to find a landing spot for each +// element, by simultaneously scanning over the gap side. When no +// place is found for an open node's content, it is left in that node. + +// : (ResolvedPos, Slice) → [{content: Fragment, openEnd: number, depth: number}] +function placeSlice($from, slice) { + var frontier = new Frontier($from); + for (var pass = 1; slice.size && pass <= 3; pass++) { + var value = frontier.placeSlice(slice.content, slice.openStart, slice.openEnd, pass); + if (pass == 3 && value != slice && value.size) { pass = 0; } // Restart if the 3rd pass made progress but left content + slice = value; + } + while (frontier.open.length) { frontier.closeNode(); } + return frontier.placed +} + +// Helper class that models the open side of the insert position, +// keeping track of the content match and already inserted content +// at each depth. +var Frontier = function Frontier($pos) { + // : [{parent: Node, match: ContentMatch, content: Fragment, wrapper: bool, openEnd: number, depth: number}] + this.open = []; + for (var d = 0; d <= $pos.depth; d++) { + var parent = $pos.node(d), match = parent.contentMatchAt($pos.indexAfter(d)); + this.open.push({parent: parent, match: match, content: prosemirrorModel.Fragment.empty, wrapper: false, openEnd: 0, depth: d}); + } + this.placed = []; +}; + +// : (Fragment, number, number, number, ?Node) → Slice +// Tries to place the content of the given slice, and returns a +// slice containing unplaced content. +// +// pass 1: try to fit directly +// pass 2: allow wrapper nodes to be introduced +// pass 3: allow unwrapping of nodes that aren't open +Frontier.prototype.placeSlice = function placeSlice (fragment, openStart, openEnd, pass, parent) { + if (openStart > 0) { + var first = fragment.firstChild; + var inner = this.placeSlice(first.content, Math.max(0, openStart - 1), + openEnd && fragment.childCount == 1 ? openEnd - 1 : 0, + pass, first); + if (inner.content != first.content) { + if (inner.content.size) { + fragment = fragment.replaceChild(0, first.copy(inner.content)); + openStart = inner.openStart + 1; + } else { + if (fragment.childCount == 1) { openEnd = 0; } + fragment = fragment.cutByIndex(1); + openStart = 0; + } + } + } + var result = this.placeContent(fragment, openStart, openEnd, pass, parent); + if (pass > 2 && result.size && openStart == 0) { + var child = result.content.firstChild, single = result.content.childCount == 1; + this.placeContent(child.content, 0, openEnd && single ? openEnd - 1 : 0, pass, child); + result = single ? prosemirrorModel.Fragment.empty : new prosemirrorModel.Slice(result.content.cutByIndex(1), 0, openEnd); + } + return result +}; + +Frontier.prototype.placeContent = function placeContent (fragment, openStart, openEnd, pass, parent) { + var i = 0; + // Go over the fragment's children + for (; i < fragment.childCount; i++) { + var child = fragment.child(i), placed = false, last = i == fragment.childCount - 1; + // Try each open node in turn, starting from the innermost + for (var d = this.open.length - 1; d >= 0; d--) { + var open = this.open[d], wrap = (void 0); + + // If pass > 1, it is allowed to wrap the node to help find a + // fit, so if findWrapping returns something, we add open + // nodes to the frontier for that wrapping. + if (pass > 1 && (wrap = open.match.findWrapping(child.type)) && + !(parent && wrap.length && wrap[wrap.length - 1] == parent.type)) { + while (this.open.length - 1 > d) { this.closeNode(); } + for (var w = 0; w < wrap.length; w++) { + open.match = open.match.matchType(wrap[w]); + d++; + open = {parent: wrap[w].create(), + match: wrap[w].contentMatch, + content: prosemirrorModel.Fragment.empty, wrapper: true, openEnd: 0, depth: d + w}; + this.open.push(open); + } + } + + // See if the child fits here + var match = open.match.matchType(child.type); + if (!match) { + var fill = open.match.fillBefore(prosemirrorModel.Fragment.from(child)); + if (fill) { + for (var j = 0; j < fill.childCount; j++) { + var ch = fill.child(j); + this.addNode(open, ch, 0); + match = open.match.matchFragment(ch); + } + } else if (parent && open.match.matchType(parent.type)) { + // Don't continue looking further up if the parent node + // would fit here. + break + } else { + continue + } + } + + // Close open nodes above this one, since we're starting to + // add to this. + while (this.open.length - 1 > d) { this.closeNode(); } + // Strip marks from the child or close its start when necessary + child = child.mark(open.parent.type.allowedMarks(child.marks)); + if (openStart) { + child = closeNodeStart(child, openStart, last ? openEnd : 0); + openStart = 0; + } + // Add the child to this open node and adjust its metadata + this.addNode(open, child, last ? openEnd : 0); + open.match = match; + if (last) { openEnd = 0; } + placed = true; + break + } + // As soon as we've failed to place a node we stop looking at + // later nodes + if (!placed) { break } + } + // Close the current open node if it's not the the root and we + // either placed up to the end of the node or the the current + // slice depth's node type matches the open node's type + if (this.open.length > 1 && + (i > 0 && i == fragment.childCount || + parent && this.open[this.open.length - 1].parent.type == parent.type)) + { this.closeNode(); } + + return new prosemirrorModel.Slice(fragment.cutByIndex(i), openStart, openEnd) +}; + +Frontier.prototype.addNode = function addNode (open, node, openEnd) { + open.content = closeFragmentEnd(open.content, open.openEnd).addToEnd(node); + open.openEnd = openEnd; +}; + +Frontier.prototype.closeNode = function closeNode () { + var open = this.open.pop(); + if (open.content.size == 0) ; else if (open.wrapper) { + this.addNode(this.open[this.open.length - 1], open.parent.copy(open.content), open.openEnd + 1); + } else { + this.placed[open.depth] = {depth: open.depth, content: open.content, openEnd: open.openEnd}; + } +}; + +function closeNodeStart(node, openStart, openEnd) { + var content = node.content; + if (openStart > 1) { + var first = closeNodeStart(node.firstChild, openStart - 1, node.childCount == 1 ? openEnd - 1 : 0); + content = node.content.replaceChild(0, first); + } + var fill = node.type.contentMatch.fillBefore(content, openEnd == 0); + return node.copy(fill.append(content)) +} + +function closeNodeEnd(node, depth) { + var content = node.content; + if (depth > 1) { + var last = closeNodeEnd(node.lastChild, depth - 1); + content = node.content.replaceChild(node.childCount - 1, last); + } + var fill = node.contentMatchAt(node.childCount).fillBefore(prosemirrorModel.Fragment.empty, true); + return node.copy(content.append(fill)) +} + +function closeFragmentEnd(fragment, depth) { + return depth ? fragment.replaceChild(fragment.childCount - 1, closeNodeEnd(fragment.lastChild, depth)) : fragment +} + +// :: (number, number, Slice) → this +// Replace a range of the document with a given slice, using `from`, +// `to`, and the slice's [`openStart`](#model.Slice.openStart) property +// as hints, rather than fixed start and end points. This method may +// grow the replaced area or close open nodes in the slice in order to +// get a fit that is more in line with WYSIWYG expectations, by +// dropping fully covered parent nodes of the replaced region when +// they are marked [non-defining](#model.NodeSpec.defining), or +// including an open parent node from the slice that _is_ marked as +// [defining](#model.NodeSpec.defining). +// +// This is the method, for example, to handle paste. The similar +// [`replace`](#transform.Transform.replace) method is a more +// primitive tool which will _not_ move the start and end of its given +// range, and is useful in situations where you need more precise +// control over what happens. +Transform.prototype.replaceRange = function(from, to, slice) { + if (!slice.size) { return this.deleteRange(from, to) } + + var $from = this.doc.resolve(from), $to = this.doc.resolve(to); + if (fitsTrivially($from, $to, slice)) + { return this.step(new ReplaceStep(from, to, slice)) } + + var targetDepths = coveredDepths($from, this.doc.resolve(to)); + // Can't replace the whole document, so remove 0 if it's present + if (targetDepths[targetDepths.length - 1] == 0) { targetDepths.pop(); } + // Negative numbers represent not expansion over the whole node at + // that depth, but replacing from $from.before(-D) to $to.pos. + var preferredTarget = -($from.depth + 1); + targetDepths.unshift(preferredTarget); + // This loop picks a preferred target depth, if one of the covering + // depths is not outside of a defining node, and adds negative + // depths for any depth that has $from at its start and does not + // cross a defining node. + for (var d = $from.depth, pos = $from.pos - 1; d > 0; d--, pos--) { + var spec = $from.node(d).type.spec; + if (spec.defining || spec.isolating) { break } + if (targetDepths.indexOf(d) > -1) { preferredTarget = d; } + else if ($from.before(d) == pos) { targetDepths.splice(1, 0, -d); } + } + // Try to fit each possible depth of the slice into each possible + // target depth, starting with the preferred depths. + var preferredTargetIndex = targetDepths.indexOf(preferredTarget); + + var leftNodes = [], preferredDepth = slice.openStart; + for (var content = slice.content, i = 0;; i++) { + var node = content.firstChild; + leftNodes.push(node); + if (i == slice.openStart) { break } + content = node.content; + } + // Back up if the node directly above openStart, or the node above + // that separated only by a non-defining textblock node, is defining. + if (preferredDepth > 0 && leftNodes[preferredDepth - 1].type.spec.defining && + $from.node(preferredTargetIndex).type != leftNodes[preferredDepth - 1].type) + { preferredDepth -= 1; } + else if (preferredDepth >= 2 && leftNodes[preferredDepth - 1].isTextblock && leftNodes[preferredDepth - 2].type.spec.defining && + $from.node(preferredTargetIndex).type != leftNodes[preferredDepth - 2].type) + { preferredDepth -= 2; } + + for (var j = slice.openStart; j >= 0; j--) { + var openDepth = (j + preferredDepth + 1) % (slice.openStart + 1); + var insert = leftNodes[openDepth]; + if (!insert) { continue } + for (var i$1 = 0; i$1 < targetDepths.length; i$1++) { + // Loop over possible expansion levels, starting with the + // preferred one + var targetDepth = targetDepths[(i$1 + preferredTargetIndex) % targetDepths.length], expand = true; + if (targetDepth < 0) { expand = false; targetDepth = -targetDepth; } + var parent = $from.node(targetDepth - 1), index = $from.index(targetDepth - 1); + if (parent.canReplaceWith(index, index, insert.type, insert.marks)) + { return this.replace($from.before(targetDepth), expand ? $to.after(targetDepth) : to, + new prosemirrorModel.Slice(closeFragment(slice.content, 0, slice.openStart, openDepth), + openDepth, slice.openEnd)) } + } + } + + var startSteps = this.steps.length; + for (var i$2 = targetDepths.length - 1; i$2 >= 0; i$2--) { + this.replace(from, to, slice); + if (this.steps.length > startSteps) { break } + var depth = targetDepths[i$2]; + if (i$2 < 0) { continue } + from = $from.before(depth); to = $to.after(depth); + } + return this +}; + +function closeFragment(fragment, depth, oldOpen, newOpen, parent) { + if (depth < oldOpen) { + var first = fragment.firstChild; + fragment = fragment.replaceChild(0, first.copy(closeFragment(first.content, depth + 1, oldOpen, newOpen, first))); + } + if (depth > newOpen) { + var match = parent.contentMatchAt(0); + var start = match.fillBefore(fragment).append(fragment); + fragment = start.append(match.matchFragment(start).fillBefore(prosemirrorModel.Fragment.empty, true)); + } + return fragment +} + +// :: (number, number, Node) → this +// Replace the given range with a node, but use `from` and `to` as +// hints, rather than precise positions. When from and to are the same +// and are at the start or end of a parent node in which the given +// node doesn't fit, this method may _move_ them out towards a parent +// that does allow the given node to be placed. When the given range +// completely covers a parent node, this method may completely replace +// that parent node. +Transform.prototype.replaceRangeWith = function(from, to, node) { + if (!node.isInline && from == to && this.doc.resolve(from).parent.content.size) { + var point = insertPoint(this.doc, from, node.type); + if (point != null) { from = to = point; } + } + return this.replaceRange(from, to, new prosemirrorModel.Slice(prosemirrorModel.Fragment.from(node), 0, 0)) +}; + +// :: (number, number) → this +// Delete the given range, expanding it to cover fully covered +// parent nodes until a valid replace is found. +Transform.prototype.deleteRange = function(from, to) { + var $from = this.doc.resolve(from), $to = this.doc.resolve(to); + var covered = coveredDepths($from, $to); + for (var i = 0; i < covered.length; i++) { + var depth = covered[i], last = i == covered.length - 1; + if ((last && depth == 0) || $from.node(depth).type.contentMatch.validEnd) + { return this.delete($from.start(depth), $to.end(depth)) } + if (depth > 0 && (last || $from.node(depth - 1).canReplace($from.index(depth - 1), $to.indexAfter(depth - 1)))) + { return this.delete($from.before(depth), $to.after(depth)) } + } + for (var d = 1; d <= $from.depth; d++) { + if (from - $from.start(d) == $from.depth - d && to > $from.end(d) && $to.end(d) - to != $to.depth - d) + { return this.delete($from.before(d), to) } + } + return this.delete(from, to) +}; + +// : (ResolvedPos, ResolvedPos) → [number] +// Returns an array of all depths for which $from - $to spans the +// whole content of the nodes at that depth. +function coveredDepths($from, $to) { + var result = [], minDepth = Math.min($from.depth, $to.depth); + for (var d = minDepth; d >= 0; d--) { + var start = $from.start(d); + if (start < $from.pos - ($from.depth - d) || + $to.end(d) > $to.pos + ($to.depth - d) || + $from.node(d).type.spec.isolating || + $to.node(d).type.spec.isolating) { break } + if (start == $to.start(d)) { result.push(d); } + } + return result +} + +exports.AddMarkStep = AddMarkStep; +exports.MapResult = MapResult; +exports.Mapping = Mapping; +exports.RemoveMarkStep = RemoveMarkStep; +exports.ReplaceAroundStep = ReplaceAroundStep; +exports.ReplaceStep = ReplaceStep; +exports.Step = Step; +exports.StepMap = StepMap; +exports.StepResult = StepResult; +exports.Transform = Transform; +exports.TransformError = TransformError; +exports.canJoin = canJoin; +exports.canSplit = canSplit; +exports.dropPoint = dropPoint; +exports.findWrapping = findWrapping; +exports.insertPoint = insertPoint; +exports.joinPoint = joinPoint; +exports.liftTarget = liftTarget; +exports.replaceStep = replaceStep; +//# sourceMappingURL=index.js.map diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/dist/index.js.map b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/dist/index.js.map new file mode 100644 index 0000000000..ef30dec3d1 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sources":["../src/map.js","../src/transform.js","../src/step.js","../src/replace_step.js","../src/structure.js","../src/mark_step.js","../src/mark.js","../src/replace.js"],"sourcesContent":["// Mappable:: interface\n// There are several things that positions can be mapped through.\n// Such objects conform to this interface.\n//\n// map:: (pos: number, assoc: ?number) → number\n// Map a position through this object. When given, `assoc` (should\n// be -1 or 1, defaults to 1) determines with which side the\n// position is associated, which determines in which direction to\n// move when a chunk of content is inserted at the mapped position.\n//\n// mapResult:: (pos: number, assoc: ?number) → MapResult\n// Map a position, and return an object containing additional\n// information about the mapping. The result's `deleted` field tells\n// you whether the position was deleted (completely enclosed in a\n// replaced range) during the mapping. When content on only one side\n// is deleted, the position itself is only considered deleted when\n// `assoc` points in the direction of the deleted content.\n\n// Recovery values encode a range index and an offset. They are\n// represented as numbers, because tons of them will be created when\n// mapping, for example, a large number of decorations. The number's\n// lower 16 bits provide the index, the remaining bits the offset.\n//\n// Note: We intentionally don't use bit shift operators to en- and\n// decode these, since those clip to 32 bits, which we might in rare\n// cases want to overflow. A 64-bit float can represent 48-bit\n// integers precisely.\n\nconst lower16 = 0xffff\nconst factor16 = Math.pow(2, 16)\n\nfunction makeRecover(index, offset) { return index + offset * factor16 }\nfunction recoverIndex(value) { return value & lower16 }\nfunction recoverOffset(value) { return (value - (value & lower16)) / factor16 }\n\n// ::- An object representing a mapped position with extra\n// information.\nexport class MapResult {\n constructor(pos, deleted = false, recover = null) {\n // :: number The mapped version of the position.\n this.pos = pos\n // :: bool Tells you whether the position was deleted, that is,\n // whether the step removed its surroundings from the document.\n this.deleted = deleted\n this.recover = recover\n }\n}\n\n// :: class extends Mappable\n// A map describing the deletions and insertions made by a step, which\n// can be used to find the correspondence between positions in the\n// pre-step version of a document and the same position in the\n// post-step version.\nexport class StepMap {\n // :: ([number])\n // Create a position map. The modifications to the document are\n // represented as an array of numbers, in which each group of three\n // represents a modified chunk as `[start, oldSize, newSize]`.\n constructor(ranges, inverted = false) {\n this.ranges = ranges\n this.inverted = inverted\n }\n\n recover(value) {\n let diff = 0, index = recoverIndex(value)\n if (!this.inverted) for (let i = 0; i < index; i++)\n diff += this.ranges[i * 3 + 2] - this.ranges[i * 3 + 1]\n return this.ranges[index * 3] + diff + recoverOffset(value)\n }\n\n // : (number, ?number) → MapResult\n mapResult(pos, assoc = 1) { return this._map(pos, assoc, false) }\n\n // : (number, ?number) → number\n map(pos, assoc = 1) { return this._map(pos, assoc, true) }\n\n _map(pos, assoc, simple) {\n let diff = 0, oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2\n for (let i = 0; i < this.ranges.length; i += 3) {\n let start = this.ranges[i] - (this.inverted ? diff : 0)\n if (start > pos) break\n let oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex], end = start + oldSize\n if (pos <= end) {\n let side = !oldSize ? assoc : pos == start ? -1 : pos == end ? 1 : assoc\n let result = start + diff + (side < 0 ? 0 : newSize)\n if (simple) return result\n let recover = makeRecover(i / 3, pos - start)\n return new MapResult(result, assoc < 0 ? pos != start : pos != end, recover)\n }\n diff += newSize - oldSize\n }\n return simple ? pos + diff : new MapResult(pos + diff)\n }\n\n touches(pos, recover) {\n let diff = 0, index = recoverIndex(recover)\n let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2\n for (let i = 0; i < this.ranges.length; i += 3) {\n let start = this.ranges[i] - (this.inverted ? diff : 0)\n if (start > pos) break\n let oldSize = this.ranges[i + oldIndex], end = start + oldSize\n if (pos <= end && i == index * 3) return true\n diff += this.ranges[i + newIndex] - oldSize\n }\n return false\n }\n\n // :: ((oldStart: number, oldEnd: number, newStart: number, newEnd: number))\n // Calls the given function on each of the changed ranges included in\n // this map.\n forEach(f) {\n let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2\n for (let i = 0, diff = 0; i < this.ranges.length; i += 3) {\n let start = this.ranges[i], oldStart = start - (this.inverted ? diff : 0), newStart = start + (this.inverted ? 0 : diff)\n let oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex]\n f(oldStart, oldStart + oldSize, newStart, newStart + newSize)\n diff += newSize - oldSize\n }\n }\n\n // :: () → StepMap\n // Create an inverted version of this map. The result can be used to\n // map positions in the post-step document to the pre-step document.\n invert() {\n return new StepMap(this.ranges, !this.inverted)\n }\n\n toString() {\n return (this.inverted ? \"-\" : \"\") + JSON.stringify(this.ranges)\n }\n\n // :: (n: number) → StepMap\n // Create a map that moves all positions by offset `n` (which may be\n // negative). This can be useful when applying steps meant for a\n // sub-document to a larger document, or vice-versa.\n static offset(n) {\n return n == 0 ? StepMap.empty : new StepMap(n < 0 ? [0, -n, 0] : [0, 0, n])\n }\n}\n\nStepMap.empty = new StepMap([])\n\n// :: class extends Mappable\n// A mapping represents a pipeline of zero or more [step\n// maps](#transform.StepMap). It has special provisions for losslessly\n// handling mapping positions through a series of steps in which some\n// steps are inverted versions of earlier steps. (This comes up when\n// ‘[rebasing](/docs/guide/#transform.rebasing)’ steps for\n// collaboration or history management.)\nexport class Mapping {\n // :: (?[StepMap])\n // Create a new mapping with the given position maps.\n constructor(maps, mirror, from, to) {\n // :: [StepMap]\n // The step maps in this mapping.\n this.maps = maps || []\n // :: number\n // The starting position in the `maps` array, used when `map` or\n // `mapResult` is called.\n this.from = from || 0\n // :: number\n // The end position in the `maps` array.\n this.to = to == null ? this.maps.length : to\n this.mirror = mirror\n }\n\n // :: (?number, ?number) → Mapping\n // Create a mapping that maps only through a part of this one.\n slice(from = 0, to = this.maps.length) {\n return new Mapping(this.maps, this.mirror, from, to)\n }\n\n copy() {\n return new Mapping(this.maps.slice(), this.mirror && this.mirror.slice(), this.from, this.to)\n }\n\n // :: (StepMap, ?number)\n // Add a step map to the end of this mapping. If `mirrors` is\n // given, it should be the index of the step map that is the mirror\n // image of this one.\n appendMap(map, mirrors) {\n this.to = this.maps.push(map)\n if (mirrors != null) this.setMirror(this.maps.length - 1, mirrors)\n }\n\n // :: (Mapping)\n // Add all the step maps in a given mapping to this one (preserving\n // mirroring information).\n appendMapping(mapping) {\n for (let i = 0, startSize = this.maps.length; i < mapping.maps.length; i++) {\n let mirr = mapping.getMirror(i)\n this.appendMap(mapping.maps[i], mirr != null && mirr < i ? startSize + mirr : null)\n }\n }\n\n // :: (number) → ?number\n // Finds the offset of the step map that mirrors the map at the\n // given offset, in this mapping (as per the second argument to\n // `appendMap`).\n getMirror(n) {\n if (this.mirror) for (let i = 0; i < this.mirror.length; i++)\n if (this.mirror[i] == n) return this.mirror[i + (i % 2 ? -1 : 1)]\n }\n\n setMirror(n, m) {\n if (!this.mirror) this.mirror = []\n this.mirror.push(n, m)\n }\n\n // :: (Mapping)\n // Append the inverse of the given mapping to this one.\n appendMappingInverted(mapping) {\n for (let i = mapping.maps.length - 1, totalSize = this.maps.length + mapping.maps.length; i >= 0; i--) {\n let mirr = mapping.getMirror(i)\n this.appendMap(mapping.maps[i].invert(), mirr != null && mirr > i ? totalSize - mirr - 1 : null)\n }\n }\n\n // :: () → Mapping\n // Create an inverted version of this mapping.\n invert() {\n let inverse = new Mapping\n inverse.appendMappingInverted(this)\n return inverse\n }\n\n // : (number, ?number) → number\n // Map a position through this mapping.\n map(pos, assoc = 1) {\n if (this.mirror) return this._map(pos, assoc, true)\n for (let i = this.from; i < this.to; i++)\n pos = this.maps[i].map(pos, assoc)\n return pos\n }\n\n // : (number, ?number) → MapResult\n // Map a position through this mapping, returning a mapping\n // result.\n mapResult(pos, assoc = 1) { return this._map(pos, assoc, false) }\n\n _map(pos, assoc, simple) {\n let deleted = false, recoverables = null\n\n for (let i = this.from; i < this.to; i++) {\n let map = this.maps[i], rec = recoverables && recoverables[i]\n if (rec != null && map.touches(pos, rec)) {\n pos = map.recover(rec)\n continue\n }\n\n let result = map.mapResult(pos, assoc)\n if (result.recover != null) {\n let corr = this.getMirror(i)\n if (corr != null && corr > i && corr < this.to) {\n if (result.deleted) {\n i = corr\n pos = this.maps[corr].recover(result.recover)\n continue\n } else {\n ;(recoverables || (recoverables = Object.create(null)))[corr] = result.recover\n }\n }\n }\n\n if (result.deleted) deleted = true\n pos = result.pos\n }\n\n return simple ? pos : new MapResult(pos, deleted)\n }\n}\n","import {Mapping} from \"./map\"\n\nexport function TransformError(message) {\n let err = Error.call(this, message)\n err.__proto__ = TransformError.prototype\n return err\n}\n\nTransformError.prototype = Object.create(Error.prototype)\nTransformError.prototype.constructor = TransformError\nTransformError.prototype.name = \"TransformError\"\n\n// ::- Abstraction to build up and track an array of\n// [steps](#transform.Step) representing a document transformation.\n//\n// Most transforming methods return the `Transform` object itself, so\n// that they can be chained.\nexport class Transform {\n // :: (Node)\n // Create a transform that starts with the given document.\n constructor(doc) {\n // :: Node\n // The current document (the result of applying the steps in the\n // transform).\n this.doc = doc\n // :: [Step]\n // The steps in this transform.\n this.steps = []\n // :: [Node]\n // The documents before each of the steps.\n this.docs = []\n // :: Mapping\n // A mapping with the maps for each of the steps in this transform.\n this.mapping = new Mapping\n }\n\n // :: Node The starting document.\n get before() { return this.docs.length ? this.docs[0] : this.doc }\n\n // :: (step: Step) → this\n // Apply a new step in this transform, saving the result. Throws an\n // error when the step fails.\n step(object) {\n let result = this.maybeStep(object)\n if (result.failed) throw new TransformError(result.failed)\n return this\n }\n\n // :: (Step) → StepResult\n // Try to apply a step in this transformation, ignoring it if it\n // fails. Returns the step result.\n maybeStep(step) {\n let result = step.apply(this.doc)\n if (!result.failed) this.addStep(step, result.doc)\n return result\n }\n\n // :: bool\n // True when the document has been changed (when there are any\n // steps).\n get docChanged() {\n return this.steps.length > 0\n }\n\n addStep(step, doc) {\n this.docs.push(this.doc)\n this.steps.push(step)\n this.mapping.appendMap(step.getMap())\n this.doc = doc\n }\n}\n","import {ReplaceError} from \"prosemirror-model\"\n\nimport {StepMap} from \"./map\"\n\nfunction mustOverride() { throw new Error(\"Override me\") }\n\nconst stepsByID = Object.create(null)\n\n// ::- A step object represents an atomic change. It generally applies\n// only to the document it was created for, since the positions\n// stored in it will only make sense for that document.\n//\n// New steps are defined by creating classes that extend `Step`,\n// overriding the `apply`, `invert`, `map`, `getMap` and `fromJSON`\n// methods, and registering your class with a unique\n// JSON-serialization identifier using\n// [`Step.jsonID`](#transform.Step^jsonID).\nexport class Step {\n // :: (doc: Node) → StepResult\n // Applies this step to the given document, returning a result\n // object that either indicates failure, if the step can not be\n // applied to this document, or indicates success by containing a\n // transformed document.\n apply(_doc) { return mustOverride() }\n\n // :: () → StepMap\n // Get the step map that represents the changes made by this step,\n // and which can be used to transform between positions in the old\n // and the new document.\n getMap() { return StepMap.empty }\n\n // :: (doc: Node) → Step\n // Create an inverted version of this step. Needs the document as it\n // was before the step as argument.\n invert(_doc) { return mustOverride() }\n\n // :: (mapping: Mappable) → ?Step\n // Map this step through a mappable thing, returning either a\n // version of that step with its positions adjusted, or `null` if\n // the step was entirely deleted by the mapping.\n map(_mapping) { return mustOverride() }\n\n // :: (other: Step) → ?Step\n // Try to merge this step with another one, to be applied directly\n // after it. Returns the merged step when possible, null if the\n // steps can't be merged.\n merge(_other) { return null }\n\n // :: () → Object\n // Create a JSON-serializeable representation of this step. When\n // defining this for a custom subclass, make sure the result object\n // includes the step type's [JSON id](#transform.Step^jsonID) under\n // the `stepType` property.\n toJSON() { return mustOverride() }\n\n // :: (Schema, Object) → Step\n // Deserialize a step from its JSON representation. Will call\n // through to the step class' own implementation of this method.\n static fromJSON(schema, json) {\n if (!json || !json.stepType) throw new RangeError(\"Invalid input for Step.fromJSON\")\n let type = stepsByID[json.stepType]\n if (!type) throw new RangeError(`No step type ${json.stepType} defined`)\n return type.fromJSON(schema, json)\n }\n\n // :: (string, constructor)\n // To be able to serialize steps to JSON, each step needs a string\n // ID to attach to its JSON representation. Use this method to\n // register an ID for your step classes. Try to pick something\n // that's unlikely to clash with steps from other modules.\n static jsonID(id, stepClass) {\n if (id in stepsByID) throw new RangeError(\"Duplicate use of step JSON ID \" + id)\n stepsByID[id] = stepClass\n stepClass.prototype.jsonID = id\n return stepClass\n }\n}\n\n// ::- The result of [applying](#transform.Step.apply) a step. Contains either a\n// new document or a failure value.\nexport class StepResult {\n // : (?Node, ?string)\n constructor(doc, failed) {\n // :: ?Node The transformed document.\n this.doc = doc\n // :: ?string Text providing information about a failed step.\n this.failed = failed\n }\n\n // :: (Node) → StepResult\n // Create a successful step result.\n static ok(doc) { return new StepResult(doc, null) }\n\n // :: (string) → StepResult\n // Create a failed step result.\n static fail(message) { return new StepResult(null, message) }\n\n // :: (Node, number, number, Slice) → StepResult\n // Call [`Node.replace`](#model.Node.replace) with the given\n // arguments. Create a successful result if it succeeds, and a\n // failed one if it throws a `ReplaceError`.\n static fromReplace(doc, from, to, slice) {\n try {\n return StepResult.ok(doc.replace(from, to, slice))\n } catch (e) {\n if (e instanceof ReplaceError) return StepResult.fail(e.message)\n throw e\n }\n }\n}\n","import {Slice} from \"prosemirror-model\"\n\nimport {Step, StepResult} from \"./step\"\nimport {StepMap} from \"./map\"\n\n// ::- Replace a part of the document with a slice of new content.\nexport class ReplaceStep extends Step {\n // :: (number, number, Slice, ?bool)\n // The given `slice` should fit the 'gap' between `from` and\n // `to`—the depths must line up, and the surrounding nodes must be\n // able to be joined with the open sides of the slice. When\n // `structure` is true, the step will fail if the content between\n // from and to is not just a sequence of closing and then opening\n // tokens (this is to guard against rebased replace steps\n // overwriting something they weren't supposed to).\n constructor(from, to, slice, structure) {\n super()\n this.from = from\n this.to = to\n this.slice = slice\n this.structure = !!structure\n }\n\n apply(doc) {\n if (this.structure && contentBetween(doc, this.from, this.to))\n return StepResult.fail(\"Structure replace would overwrite content\")\n return StepResult.fromReplace(doc, this.from, this.to, this.slice)\n }\n\n getMap() {\n return new StepMap([this.from, this.to - this.from, this.slice.size])\n }\n\n invert(doc) {\n return new ReplaceStep(this.from, this.from + this.slice.size, doc.slice(this.from, this.to))\n }\n\n map(mapping) {\n let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1)\n if (from.deleted && to.deleted) return null\n return new ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice)\n }\n\n merge(other) {\n if (!(other instanceof ReplaceStep) || other.structure != this.structure) return null\n\n if (this.from + this.slice.size == other.from && !this.slice.openEnd && !other.slice.openStart) {\n let slice = this.slice.size + other.slice.size == 0 ? Slice.empty\n : new Slice(this.slice.content.append(other.slice.content), this.slice.openStart, other.slice.openEnd)\n return new ReplaceStep(this.from, this.to + (other.to - other.from), slice, this.structure)\n } else if (other.to == this.from && !this.slice.openStart && !other.slice.openEnd) {\n let slice = this.slice.size + other.slice.size == 0 ? Slice.empty\n : new Slice(other.slice.content.append(this.slice.content), other.slice.openStart, this.slice.openEnd)\n return new ReplaceStep(other.from, this.to, slice, this.structure)\n } else {\n return null\n }\n }\n\n toJSON() {\n let json = {stepType: \"replace\", from: this.from, to: this.to}\n if (this.slice.size) json.slice = this.slice.toJSON()\n if (this.structure) json.structure = true\n return json\n }\n\n static fromJSON(schema, json) {\n if (typeof json.from != \"number\" || typeof json.to != \"number\")\n throw new RangeError(\"Invalid input for ReplaceStep.fromJSON\")\n return new ReplaceStep(json.from, json.to, Slice.fromJSON(schema, json.slice), !!json.structure)\n }\n}\n\nStep.jsonID(\"replace\", ReplaceStep)\n\n// ::- Replace a part of the document with a slice of content, but\n// preserve a range of the replaced content by moving it into the\n// slice.\nexport class ReplaceAroundStep extends Step {\n // :: (number, number, number, number, Slice, number, ?bool)\n // Create a replace-around step with the given range and gap.\n // `insert` should be the point in the slice into which the content\n // of the gap should be moved. `structure` has the same meaning as\n // it has in the [`ReplaceStep`](#transform.ReplaceStep) class.\n constructor(from, to, gapFrom, gapTo, slice, insert, structure) {\n super()\n this.from = from\n this.to = to\n this.gapFrom = gapFrom\n this.gapTo = gapTo\n this.slice = slice\n this.insert = insert\n this.structure = !!structure\n }\n\n apply(doc) {\n if (this.structure && (contentBetween(doc, this.from, this.gapFrom) ||\n contentBetween(doc, this.gapTo, this.to)))\n return StepResult.fail(\"Structure gap-replace would overwrite content\")\n\n let gap = doc.slice(this.gapFrom, this.gapTo)\n if (gap.openStart || gap.openEnd)\n return StepResult.fail(\"Gap is not a flat range\")\n let inserted = this.slice.insertAt(this.insert, gap.content)\n if (!inserted) return StepResult.fail(\"Content does not fit in gap\")\n return StepResult.fromReplace(doc, this.from, this.to, inserted)\n }\n\n getMap() {\n return new StepMap([this.from, this.gapFrom - this.from, this.insert,\n this.gapTo, this.to - this.gapTo, this.slice.size - this.insert])\n }\n\n invert(doc) {\n let gap = this.gapTo - this.gapFrom\n return new ReplaceAroundStep(this.from, this.from + this.slice.size + gap,\n this.from + this.insert, this.from + this.insert + gap,\n doc.slice(this.from, this.to).removeBetween(this.gapFrom - this.from, this.gapTo - this.from),\n this.gapFrom - this.from, this.structure)\n }\n\n map(mapping) {\n let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1)\n let gapFrom = mapping.map(this.gapFrom, -1), gapTo = mapping.map(this.gapTo, 1)\n if ((from.deleted && to.deleted) || gapFrom < from.pos || gapTo > to.pos) return null\n return new ReplaceAroundStep(from.pos, to.pos, gapFrom, gapTo, this.slice, this.insert, this.structure)\n }\n\n toJSON() {\n let json = {stepType: \"replaceAround\", from: this.from, to: this.to,\n gapFrom: this.gapFrom, gapTo: this.gapTo, insert: this.insert}\n if (this.slice.size) json.slice = this.slice.toJSON()\n if (this.structure) json.structure = true\n return json\n }\n\n static fromJSON(schema, json) {\n if (typeof json.from != \"number\" || typeof json.to != \"number\" ||\n typeof json.gapFrom != \"number\" || typeof json.gapTo != \"number\" || typeof json.insert != \"number\")\n throw new RangeError(\"Invalid input for ReplaceAroundStep.fromJSON\")\n return new ReplaceAroundStep(json.from, json.to, json.gapFrom, json.gapTo,\n Slice.fromJSON(schema, json.slice), json.insert, !!json.structure)\n }\n}\n\nStep.jsonID(\"replaceAround\", ReplaceAroundStep)\n\nfunction contentBetween(doc, from, to) {\n let $from = doc.resolve(from), dist = to - from, depth = $from.depth\n while (dist > 0 && depth > 0 && $from.indexAfter(depth) == $from.node(depth).childCount) {\n depth--\n dist--\n }\n if (dist > 0) {\n let next = $from.node(depth).maybeChild($from.indexAfter(depth))\n while (dist > 0) {\n if (!next || next.isLeaf) return true\n next = next.firstChild\n dist--\n }\n }\n return false\n}\n","import {Slice, Fragment} from \"prosemirror-model\"\n\nimport {Transform} from \"./transform\"\nimport {ReplaceStep, ReplaceAroundStep} from \"./replace_step\"\n\nfunction canCut(node, start, end) {\n return (start == 0 || node.canReplace(start, node.childCount)) &&\n (end == node.childCount || node.canReplace(0, end))\n}\n\n// :: (NodeRange) → ?number\n// Try to find a target depth to which the content in the given range\n// can be lifted. Will not go across\n// [isolating](#model.NodeSpec.isolating) parent nodes.\nexport function liftTarget(range) {\n let parent = range.parent\n let content = parent.content.cutByIndex(range.startIndex, range.endIndex)\n for (let depth = range.depth;; --depth) {\n let node = range.$from.node(depth)\n let index = range.$from.index(depth), endIndex = range.$to.indexAfter(depth)\n if (depth < range.depth && node.canReplace(index, endIndex, content))\n return depth\n if (depth == 0 || node.type.spec.isolating || !canCut(node, index, endIndex)) break\n }\n}\n\n// :: (NodeRange, number) → this\n// Split the content in the given range off from its parent, if there\n// is sibling content before or after it, and move it up the tree to\n// the depth specified by `target`. You'll probably want to use\n// [`liftTarget`](#transform.liftTarget) to compute `target`, to make\n// sure the lift is valid.\nTransform.prototype.lift = function(range, target) {\n let {$from, $to, depth} = range\n\n let gapStart = $from.before(depth + 1), gapEnd = $to.after(depth + 1)\n let start = gapStart, end = gapEnd\n\n let before = Fragment.empty, openStart = 0\n for (let d = depth, splitting = false; d > target; d--)\n if (splitting || $from.index(d) > 0) {\n splitting = true\n before = Fragment.from($from.node(d).copy(before))\n openStart++\n } else {\n start--\n }\n let after = Fragment.empty, openEnd = 0\n for (let d = depth, splitting = false; d > target; d--)\n if (splitting || $to.after(d + 1) < $to.end(d)) {\n splitting = true\n after = Fragment.from($to.node(d).copy(after))\n openEnd++\n } else {\n end++\n }\n\n return this.step(new ReplaceAroundStep(start, end, gapStart, gapEnd,\n new Slice(before.append(after), openStart, openEnd),\n before.size - openStart, true))\n}\n\n// :: (NodeRange, NodeType, ?Object, ?NodeRange) → ?[{type: NodeType, attrs: ?Object}]\n// Try to find a valid way to wrap the content in the given range in a\n// node of the given type. May introduce extra nodes around and inside\n// the wrapper node, if necessary. Returns null if no valid wrapping\n// could be found. When `innerRange` is given, that range's content is\n// used as the content to fit into the wrapping, instead of the\n// content of `range`.\nexport function findWrapping(range, nodeType, attrs, innerRange = range) {\n let around = findWrappingOutside(range, nodeType)\n let inner = around && findWrappingInside(innerRange, nodeType)\n if (!inner) return null\n return around.map(withAttrs).concat({type: nodeType, attrs}).concat(inner.map(withAttrs))\n}\n\nfunction withAttrs(type) { return {type, attrs: null} }\n\nfunction findWrappingOutside(range, type) {\n let {parent, startIndex, endIndex} = range\n let around = parent.contentMatchAt(startIndex).findWrapping(type)\n if (!around) return null\n let outer = around.length ? around[0] : type\n return parent.canReplaceWith(startIndex, endIndex, outer) ? around : null\n}\n\nfunction findWrappingInside(range, type) {\n let {parent, startIndex, endIndex} = range\n let inner = parent.child(startIndex)\n let inside = type.contentMatch.findWrapping(inner.type)\n if (!inside) return null\n let lastType = inside.length ? inside[inside.length - 1] : type\n let innerMatch = lastType.contentMatch\n for (let i = startIndex; innerMatch && i < endIndex; i++)\n innerMatch = innerMatch.matchType(parent.child(i).type)\n if (!innerMatch || !innerMatch.validEnd) return null\n return inside\n}\n\n// :: (NodeRange, [{type: NodeType, attrs: ?Object}]) → this\n// Wrap the given [range](#model.NodeRange) in the given set of wrappers.\n// The wrappers are assumed to be valid in this position, and should\n// probably be computed with [`findWrapping`](#transform.findWrapping).\nTransform.prototype.wrap = function(range, wrappers) {\n let content = Fragment.empty\n for (let i = wrappers.length - 1; i >= 0; i--)\n content = Fragment.from(wrappers[i].type.create(wrappers[i].attrs, content))\n\n let start = range.start, end = range.end\n return this.step(new ReplaceAroundStep(start, end, start, end, new Slice(content, 0, 0), wrappers.length, true))\n}\n\n// :: (number, ?number, NodeType, ?Object) → this\n// Set the type of all textblocks (partly) between `from` and `to` to\n// the given node type with the given attributes.\nTransform.prototype.setBlockType = function(from, to = from, type, attrs) {\n if (!type.isTextblock) throw new RangeError(\"Type given to setBlockType should be a textblock\")\n let mapFrom = this.steps.length\n this.doc.nodesBetween(from, to, (node, pos) => {\n if (node.isTextblock && !node.hasMarkup(type, attrs) && canChangeType(this.doc, this.mapping.slice(mapFrom).map(pos), type)) {\n // Ensure all markup that isn't allowed in the new node type is cleared\n this.clearIncompatible(this.mapping.slice(mapFrom).map(pos, 1), type)\n let mapping = this.mapping.slice(mapFrom)\n let startM = mapping.map(pos, 1), endM = mapping.map(pos + node.nodeSize, 1)\n this.step(new ReplaceAroundStep(startM, endM, startM + 1, endM - 1,\n new Slice(Fragment.from(type.create(attrs, null, node.marks)), 0, 0), 1, true))\n return false\n }\n })\n return this\n}\n\nfunction canChangeType(doc, pos, type) {\n let $pos = doc.resolve(pos), index = $pos.index()\n return $pos.parent.canReplaceWith(index, index + 1, type)\n}\n\n// :: (number, ?NodeType, ?Object, ?[Mark]) → this\n// Change the type, attributes, and/or marks of the node at `pos`.\n// When `type` isn't given, the existing node type is preserved,\nTransform.prototype.setNodeMarkup = function(pos, type, attrs, marks) {\n let node = this.doc.nodeAt(pos)\n if (!node) throw new RangeError(\"No node at given position\")\n if (!type) type = node.type\n let newNode = type.create(attrs, null, marks || node.marks)\n if (node.isLeaf)\n return this.replaceWith(pos, pos + node.nodeSize, newNode)\n\n if (!type.validContent(node.content))\n throw new RangeError(\"Invalid content for node type \" + type.name)\n\n return this.step(new ReplaceAroundStep(pos, pos + node.nodeSize, pos + 1, pos + node.nodeSize - 1,\n new Slice(Fragment.from(newNode), 0, 0), 1, true))\n}\n\n// :: (Node, number, number, ?[?{type: NodeType, attrs: ?Object}]) → bool\n// Check whether splitting at the given position is allowed.\nexport function canSplit(doc, pos, depth = 1, typesAfter) {\n let $pos = doc.resolve(pos), base = $pos.depth - depth\n let innerType = (typesAfter && typesAfter[typesAfter.length - 1]) || $pos.parent\n if (base < 0 || $pos.parent.type.spec.isolating ||\n !$pos.parent.canReplace($pos.index(), $pos.parent.childCount) ||\n !innerType.type.validContent($pos.parent.content.cutByIndex($pos.index(), $pos.parent.childCount)))\n return false\n for (let d = $pos.depth - 1, i = depth - 2; d > base; d--, i--) {\n let node = $pos.node(d), index = $pos.index(d)\n if (node.type.spec.isolating) return false\n let rest = node.content.cutByIndex(index, node.childCount)\n let after = (typesAfter && typesAfter[i]) || node\n if (after != node) rest = rest.replaceChild(0, after.type.create(after.attrs))\n if (!node.canReplace(index + 1, node.childCount) || !after.type.validContent(rest))\n return false\n }\n let index = $pos.indexAfter(base)\n let baseType = typesAfter && typesAfter[0]\n return $pos.node(base).canReplaceWith(index, index, baseType ? baseType.type : $pos.node(base + 1).type)\n}\n\n// :: (number, ?number, ?[?{type: NodeType, attrs: ?Object}]) → this\n// Split the node at the given position, and optionally, if `depth` is\n// greater than one, any number of nodes above that. By default, the\n// parts split off will inherit the node type of the original node.\n// This can be changed by passing an array of types and attributes to\n// use after the split.\nTransform.prototype.split = function(pos, depth = 1, typesAfter) {\n let $pos = this.doc.resolve(pos), before = Fragment.empty, after = Fragment.empty\n for (let d = $pos.depth, e = $pos.depth - depth, i = depth - 1; d > e; d--, i--) {\n before = Fragment.from($pos.node(d).copy(before))\n let typeAfter = typesAfter && typesAfter[i]\n after = Fragment.from(typeAfter ? typeAfter.type.create(typeAfter.attrs, after) : $pos.node(d).copy(after))\n }\n return this.step(new ReplaceStep(pos, pos, new Slice(before.append(after), depth, depth), true))\n}\n\n// :: (Node, number) → bool\n// Test whether the blocks before and after a given position can be\n// joined.\nexport function canJoin(doc, pos) {\n let $pos = doc.resolve(pos), index = $pos.index()\n return joinable($pos.nodeBefore, $pos.nodeAfter) &&\n $pos.parent.canReplace(index, index + 1)\n}\n\nfunction joinable(a, b) {\n return a && b && !a.isLeaf && a.canAppend(b)\n}\n\n// :: (Node, number, ?number) → ?number\n// Find an ancestor of the given position that can be joined to the\n// block before (or after if `dir` is positive). Returns the joinable\n// point, if any.\nexport function joinPoint(doc, pos, dir = -1) {\n let $pos = doc.resolve(pos)\n for (let d = $pos.depth;; d--) {\n let before, after\n if (d == $pos.depth) {\n before = $pos.nodeBefore\n after = $pos.nodeAfter\n } else if (dir > 0) {\n before = $pos.node(d + 1)\n after = $pos.node(d).maybeChild($pos.index(d) + 1)\n } else {\n before = $pos.node(d).maybeChild($pos.index(d) - 1)\n after = $pos.node(d + 1)\n }\n if (before && !before.isTextblock && joinable(before, after)) return pos\n if (d == 0) break\n pos = dir < 0 ? $pos.before(d) : $pos.after(d)\n }\n}\n\n// :: (number, ?number) → this\n// Join the blocks around the given position. If depth is 2, their\n// last and first siblings are also joined, and so on.\nTransform.prototype.join = function(pos, depth = 1) {\n let step = new ReplaceStep(pos - depth, pos + depth, Slice.empty, true)\n return this.step(step)\n}\n\n// :: (Node, number, NodeType) → ?number\n// Try to find a point where a node of the given type can be inserted\n// near `pos`, by searching up the node hierarchy when `pos` itself\n// isn't a valid place but is at the start or end of a node. Return\n// null if no position was found.\nexport function insertPoint(doc, pos, nodeType) {\n let $pos = doc.resolve(pos)\n if ($pos.parent.canReplaceWith($pos.index(), $pos.index(), nodeType)) return pos\n\n if ($pos.parentOffset == 0)\n for (let d = $pos.depth - 1; d >= 0; d--) {\n let index = $pos.index(d)\n if ($pos.node(d).canReplaceWith(index, index, nodeType)) return $pos.before(d + 1)\n if (index > 0) return null\n }\n if ($pos.parentOffset == $pos.parent.content.size)\n for (let d = $pos.depth - 1; d >= 0; d--) {\n let index = $pos.indexAfter(d)\n if ($pos.node(d).canReplaceWith(index, index, nodeType)) return $pos.after(d + 1)\n if (index < $pos.node(d).childCount) return null\n }\n}\n\n// :: (Node, number, Slice) → ?number\n// Finds a position at or around the given position where the given\n// slice can be inserted. Will look at parent nodes' nearest boundary\n// and try there, even if the original position wasn't directly at the\n// start or end of that node. Returns null when no position was found.\nexport function dropPoint(doc, pos, slice) {\n let $pos = doc.resolve(pos)\n if (!slice.content.size) return pos\n let content = slice.content\n for (let i = 0; i < slice.openStart; i++) content = content.firstChild.content\n for (let pass = 1; pass <= (slice.openStart == 0 && slice.size ? 2 : 1); pass++) {\n for (let d = $pos.depth; d >= 0; d--) {\n let bias = d == $pos.depth ? 0 : $pos.pos <= ($pos.start(d + 1) + $pos.end(d + 1)) / 2 ? -1 : 1\n let insertPos = $pos.index(d) + (bias > 0 ? 1 : 0)\n if (pass == 1\n ? $pos.node(d).canReplace(insertPos, insertPos, content)\n : $pos.node(d).contentMatchAt(insertPos).findWrapping(content.firstChild.type))\n return bias == 0 ? $pos.pos : bias < 0 ? $pos.before(d + 1) : $pos.after(d + 1)\n }\n }\n return null\n}\n","import {Fragment, Slice} from \"prosemirror-model\"\nimport {Step, StepResult} from \"./step\"\n\nfunction mapFragment(fragment, f, parent) {\n let mapped = []\n for (let i = 0; i < fragment.childCount; i++) {\n let child = fragment.child(i)\n if (child.content.size) child = child.copy(mapFragment(child.content, f, child))\n if (child.isInline) child = f(child, parent, i)\n mapped.push(child)\n }\n return Fragment.fromArray(mapped)\n}\n\n// ::- Add a mark to all inline content between two positions.\nexport class AddMarkStep extends Step {\n // :: (number, number, Mark)\n constructor(from, to, mark) {\n super()\n this.from = from\n this.to = to\n this.mark = mark\n }\n\n apply(doc) {\n let oldSlice = doc.slice(this.from, this.to), $from = doc.resolve(this.from)\n let parent = $from.node($from.sharedDepth(this.to))\n let slice = new Slice(mapFragment(oldSlice.content, (node, parent) => {\n if (!parent.type.allowsMarkType(this.mark.type)) return node\n return node.mark(this.mark.addToSet(node.marks))\n }, parent), oldSlice.openStart, oldSlice.openEnd)\n return StepResult.fromReplace(doc, this.from, this.to, slice)\n }\n\n invert() {\n return new RemoveMarkStep(this.from, this.to, this.mark)\n }\n\n map(mapping) {\n let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1)\n if (from.deleted && to.deleted || from.pos >= to.pos) return null\n return new AddMarkStep(from.pos, to.pos, this.mark)\n }\n\n merge(other) {\n if (other instanceof AddMarkStep &&\n other.mark.eq(this.mark) &&\n this.from <= other.to && this.to >= other.from)\n return new AddMarkStep(Math.min(this.from, other.from),\n Math.max(this.to, other.to), this.mark)\n }\n\n toJSON() {\n return {stepType: \"addMark\", mark: this.mark.toJSON(),\n from: this.from, to: this.to}\n }\n\n static fromJSON(schema, json) {\n if (typeof json.from != \"number\" || typeof json.to != \"number\")\n throw new RangeError(\"Invalid input for AddMarkStep.fromJSON\")\n return new AddMarkStep(json.from, json.to, schema.markFromJSON(json.mark))\n }\n}\n\nStep.jsonID(\"addMark\", AddMarkStep)\n\n// ::- Remove a mark from all inline content between two positions.\nexport class RemoveMarkStep extends Step {\n // :: (number, number, Mark)\n constructor(from, to, mark) {\n super()\n this.from = from\n this.to = to\n this.mark = mark\n }\n\n apply(doc) {\n let oldSlice = doc.slice(this.from, this.to)\n let slice = new Slice(mapFragment(oldSlice.content, node => {\n return node.mark(this.mark.removeFromSet(node.marks))\n }), oldSlice.openStart, oldSlice.openEnd)\n return StepResult.fromReplace(doc, this.from, this.to, slice)\n }\n\n invert() {\n return new AddMarkStep(this.from, this.to, this.mark)\n }\n\n map(mapping) {\n let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1)\n if (from.deleted && to.deleted || from.pos >= to.pos) return null\n return new RemoveMarkStep(from.pos, to.pos, this.mark)\n }\n\n merge(other) {\n if (other instanceof RemoveMarkStep &&\n other.mark.eq(this.mark) &&\n this.from <= other.to && this.to >= other.from)\n return new RemoveMarkStep(Math.min(this.from, other.from),\n Math.max(this.to, other.to), this.mark)\n }\n\n toJSON() {\n return {stepType: \"removeMark\", mark: this.mark.toJSON(),\n from: this.from, to: this.to}\n }\n\n static fromJSON(schema, json) {\n if (typeof json.from != \"number\" || typeof json.to != \"number\")\n throw new RangeError(\"Invalid input for RemoveMarkStep.fromJSON\")\n return new RemoveMarkStep(json.from, json.to, schema.markFromJSON(json.mark))\n }\n}\n\nStep.jsonID(\"removeMark\", RemoveMarkStep)\n","import {MarkType, Slice, Fragment} from \"prosemirror-model\"\n\nimport {Transform} from \"./transform\"\nimport {AddMarkStep, RemoveMarkStep} from \"./mark_step\"\nimport {ReplaceStep} from \"./replace_step\"\n\n// :: (number, number, Mark) → this\n// Add the given mark to the inline content between `from` and `to`.\nTransform.prototype.addMark = function(from, to, mark) {\n let removed = [], added = [], removing = null, adding = null\n this.doc.nodesBetween(from, to, (node, pos, parent) => {\n if (!node.isInline) return\n let marks = node.marks\n if (!mark.isInSet(marks) && parent.type.allowsMarkType(mark.type)) {\n let start = Math.max(pos, from), end = Math.min(pos + node.nodeSize, to)\n let newSet = mark.addToSet(marks)\n\n for (let i = 0; i < marks.length; i++) {\n if (!marks[i].isInSet(newSet)) {\n if (removing && removing.to == start && removing.mark.eq(marks[i]))\n removing.to = end\n else\n removed.push(removing = new RemoveMarkStep(start, end, marks[i]))\n }\n }\n\n if (adding && adding.to == start)\n adding.to = end\n else\n added.push(adding = new AddMarkStep(start, end, mark))\n }\n })\n\n removed.forEach(s => this.step(s))\n added.forEach(s => this.step(s))\n return this\n}\n\n// :: (number, number, ?union) → this\n// Remove marks from inline nodes between `from` and `to`. When `mark`\n// is a single mark, remove precisely that mark. When it is a mark type,\n// remove all marks of that type. When it is null, remove all marks of\n// any type.\nTransform.prototype.removeMark = function(from, to, mark = null) {\n let matched = [], step = 0\n this.doc.nodesBetween(from, to, (node, pos) => {\n if (!node.isInline) return\n step++\n let toRemove = null\n if (mark instanceof MarkType) {\n let found = mark.isInSet(node.marks)\n if (found) toRemove = [found]\n } else if (mark) {\n if (mark.isInSet(node.marks)) toRemove = [mark]\n } else {\n toRemove = node.marks\n }\n if (toRemove && toRemove.length) {\n let end = Math.min(pos + node.nodeSize, to)\n for (let i = 0; i < toRemove.length; i++) {\n let style = toRemove[i], found\n for (let j = 0; j < matched.length; j++) {\n let m = matched[j]\n if (m.step == step - 1 && style.eq(matched[j].style)) found = m\n }\n if (found) {\n found.to = end\n found.step = step\n } else {\n matched.push({style, from: Math.max(pos, from), to: end, step})\n }\n }\n }\n })\n matched.forEach(m => this.step(new RemoveMarkStep(m.from, m.to, m.style)))\n return this\n}\n\n// :: (number, NodeType, ?ContentMatch) → this\n// Removes all marks and nodes from the content of the node at `pos`\n// that don't match the given new parent node type. Accepts an\n// optional starting [content match](#model.ContentMatch) as third\n// argument.\nTransform.prototype.clearIncompatible = function(pos, parentType, match = parentType.contentMatch) {\n let node = this.doc.nodeAt(pos)\n let delSteps = [], cur = pos + 1\n for (let i = 0; i < node.childCount; i++) {\n let child = node.child(i), end = cur + child.nodeSize\n let allowed = match.matchType(child.type, child.attrs)\n if (!allowed) {\n delSteps.push(new ReplaceStep(cur, end, Slice.empty))\n } else {\n match = allowed\n for (let j = 0; j < child.marks.length; j++) if (!parentType.allowsMarkType(child.marks[j].type))\n this.step(new RemoveMarkStep(cur, end, child.marks[j]))\n }\n cur = end\n }\n if (!match.validEnd) {\n let fill = match.fillBefore(Fragment.empty, true)\n this.replace(cur, cur, new Slice(fill, 0, 0))\n }\n for (let i = delSteps.length - 1; i >= 0; i--) this.step(delSteps[i])\n return this\n}\n","import {Fragment, Slice} from \"prosemirror-model\"\n\nimport {ReplaceStep, ReplaceAroundStep} from \"./replace_step\"\nimport {Transform} from \"./transform\"\nimport {insertPoint} from \"./structure\"\n\n// :: (Node, number, ?number, ?Slice) → ?Step\n// ‘Fit’ a slice into a given position in the document, producing a\n// [step](#transform.Step) that inserts it. Will return null if\n// there's no meaningful way to insert the slice here, or inserting it\n// would be a no-op (an empty slice over an empty range).\nexport function replaceStep(doc, from, to = from, slice = Slice.empty) {\n if (from == to && !slice.size) return null\n\n let $from = doc.resolve(from), $to = doc.resolve(to)\n // Optimization -- avoid work if it's obvious that it's not needed.\n if (fitsTrivially($from, $to, slice)) return new ReplaceStep(from, to, slice)\n let placed = placeSlice($from, slice)\n\n let fittedLeft = fitLeft($from, placed)\n let fitted = fitRight($from, $to, fittedLeft)\n if (!fitted) return null\n if (fittedLeft.size != fitted.size && canMoveText($from, $to, fittedLeft)) {\n let d = $to.depth, after = $to.after(d)\n while (d > 1 && after == $to.end(--d)) ++after\n let fittedAfter = fitRight($from, doc.resolve(after), fittedLeft)\n if (fittedAfter)\n return new ReplaceAroundStep(from, after, to, $to.end(), fittedAfter, fittedLeft.size)\n }\n return fitted.size || from != to ? new ReplaceStep(from, to, fitted) : null\n}\n\n// :: (number, ?number, ?Slice) → this\n// Replace the part of the document between `from` and `to` with the\n// given `slice`.\nTransform.prototype.replace = function(from, to = from, slice = Slice.empty) {\n let step = replaceStep(this.doc, from, to, slice)\n if (step) this.step(step)\n return this\n}\n\n// :: (number, number, union) → this\n// Replace the given range with the given content, which may be a\n// fragment, node, or array of nodes.\nTransform.prototype.replaceWith = function(from, to, content) {\n return this.replace(from, to, new Slice(Fragment.from(content), 0, 0))\n}\n\n// :: (number, number) → this\n// Delete the content between the given positions.\nTransform.prototype.delete = function(from, to) {\n return this.replace(from, to, Slice.empty)\n}\n\n// :: (number, union) → this\n// Insert the given content at the given position.\nTransform.prototype.insert = function(pos, content) {\n return this.replaceWith(pos, pos, content)\n}\n\n\n\nfunction fitLeftInner($from, depth, placed, placedBelow) {\n let content = Fragment.empty, openEnd = 0, placedHere = placed[depth]\n if ($from.depth > depth) {\n let inner = fitLeftInner($from, depth + 1, placed, placedBelow || placedHere)\n openEnd = inner.openEnd + 1\n content = Fragment.from($from.node(depth + 1).copy(inner.content))\n }\n\n if (placedHere) {\n content = content.append(placedHere.content)\n openEnd = placedHere.openEnd\n }\n if (placedBelow) {\n content = content.append($from.node(depth).contentMatchAt($from.indexAfter(depth)).fillBefore(Fragment.empty, true))\n openEnd = 0\n }\n\n return {content, openEnd}\n}\n\nfunction fitLeft($from, placed) {\n let {content, openEnd} = fitLeftInner($from, 0, placed, false)\n return new Slice(content, $from.depth, openEnd || 0)\n}\n\nfunction fitRightJoin(content, parent, $from, $to, depth, openStart, openEnd) {\n let match, count = content.childCount, matchCount = count - (openEnd > 0 ? 1 : 0)\n let parentNode = openStart < 0 ? parent : $from.node(depth)\n if (openStart < 0)\n match = parentNode.contentMatchAt(matchCount)\n else if (count == 1 && openEnd > 0)\n match = parentNode.contentMatchAt(openStart ? $from.index(depth) : $from.indexAfter(depth))\n else\n match = parentNode.contentMatchAt($from.indexAfter(depth))\n .matchFragment(content, count > 0 && openStart ? 1 : 0, matchCount)\n\n let toNode = $to.node(depth)\n if (openEnd > 0 && depth < $to.depth) {\n let after = toNode.content.cutByIndex($to.indexAfter(depth)).addToStart(content.lastChild)\n let joinable = match.fillBefore(after, true)\n // Can't insert content if there's a single node stretched across this gap\n if (joinable && joinable.size && openStart > 0 && count == 1) joinable = null\n\n if (joinable) {\n let inner = fitRightJoin(content.lastChild.content, content.lastChild, $from, $to,\n depth + 1, count == 1 ? openStart - 1 : -1, openEnd - 1)\n if (inner) {\n let last = content.lastChild.copy(inner)\n if (joinable.size)\n return content.cutByIndex(0, count - 1).append(joinable).addToEnd(last)\n else\n return content.replaceChild(count - 1, last)\n }\n }\n }\n if (openEnd > 0)\n match = match.matchType((count == 1 && openStart > 0 ? $from.node(depth + 1) : content.lastChild).type)\n\n // If we're here, the next level can't be joined, so we see what\n // happens if we leave it open.\n let toIndex = $to.index(depth)\n if (toIndex == toNode.childCount && !toNode.type.compatibleContent(parent.type)) return null\n let joinable = match.fillBefore(toNode.content, true, toIndex)\n for (let i = toIndex; joinable && i < toNode.content.childCount; i++)\n if (!parentNode.type.allowsMarks(toNode.content.child(i).marks)) joinable = null\n if (!joinable) return null\n\n if (openEnd > 0) {\n let closed = fitRightClosed(content.lastChild, openEnd - 1, $from, depth + 1,\n count == 1 ? openStart - 1 : -1)\n content = content.replaceChild(count - 1, closed)\n }\n content = content.append(joinable)\n if ($to.depth > depth)\n content = content.addToEnd(fitRightSeparate($to, depth + 1))\n return content\n}\n\nfunction fitRightClosed(node, openEnd, $from, depth, openStart) {\n let match, content = node.content, count = content.childCount\n if (openStart >= 0)\n match = $from.node(depth).contentMatchAt($from.indexAfter(depth))\n .matchFragment(content, openStart > 0 ? 1 : 0, count)\n else\n match = node.contentMatchAt(count)\n\n if (openEnd > 0) {\n let closed = fitRightClosed(content.lastChild, openEnd - 1, $from, depth + 1,\n count == 1 ? openStart - 1 : -1)\n content = content.replaceChild(count - 1, closed)\n }\n\n return node.copy(content.append(match.fillBefore(Fragment.empty, true)))\n}\n\nfunction fitRightSeparate($to, depth) {\n let node = $to.node(depth)\n let fill = node.contentMatchAt(0).fillBefore(node.content, true, $to.index(depth))\n if ($to.depth > depth) fill = fill.addToEnd(fitRightSeparate($to, depth + 1))\n return node.copy(fill)\n}\n\nfunction normalizeSlice(content, openStart, openEnd) {\n while (openStart > 0 && openEnd > 0 && content.childCount == 1) {\n content = content.firstChild.content\n openStart--\n openEnd--\n }\n return new Slice(content, openStart, openEnd)\n}\n\n// : (ResolvedPos, ResolvedPos, number, Slice) → Slice\nfunction fitRight($from, $to, slice) {\n let fitted = fitRightJoin(slice.content, $from.node(0), $from, $to, 0, slice.openStart, slice.openEnd)\n if (!fitted) return null\n return normalizeSlice(fitted, slice.openStart, $to.depth)\n}\n\nfunction fitsTrivially($from, $to, slice) {\n return !slice.openStart && !slice.openEnd && $from.start() == $to.start() &&\n $from.parent.canReplace($from.index(), $to.index(), slice.content)\n}\n\nfunction canMoveText($from, $to, slice) {\n if (!$to.parent.isTextblock) return false\n\n let parent = slice.openEnd ? nodeRight(slice.content, slice.openEnd)\n : $from.node($from.depth - (slice.openStart - slice.openEnd))\n if (!parent.isTextblock) return false\n for (let i = $to.index(); i < $to.parent.childCount; i++)\n if (!parent.type.allowsMarks($to.parent.child(i).marks)) return false\n let match\n if (slice.openEnd) {\n match = parent.contentMatchAt(parent.childCount)\n } else {\n match = parent.contentMatchAt(parent.childCount)\n if (slice.size) match = match.matchFragment(slice.content, slice.openStart ? 1 : 0)\n }\n match = match.matchFragment($to.parent.content, $to.index())\n return match && match.validEnd\n}\n\nfunction nodeRight(content, depth) {\n for (let i = 1; i < depth; i++) content = content.lastChild.content\n return content.lastChild\n}\n\n// Algorithm for 'placing' the elements of a slice into a gap:\n//\n// We consider the content of each node that is open to the left to be\n// independently placeable. I.e. in , when the\n// paragraph on the left is open, \"foo\" can be placed (somewhere on\n// the left side of the replacement gap) independently from p(\"bar\").\n//\n// So placeSlice splits up a slice into a number of sub-slices,\n// along with information on where they can be placed on the given\n// left-side edge. It works by walking the open side of the slice,\n// from the inside out, and trying to find a landing spot for each\n// element, by simultaneously scanning over the gap side. When no\n// place is found for an open node's content, it is left in that node.\n\n// : (ResolvedPos, Slice) → [{content: Fragment, openEnd: number, depth: number}]\nfunction placeSlice($from, slice) {\n let frontier = new Frontier($from)\n for (let pass = 1; slice.size && pass <= 3; pass++) {\n let value = frontier.placeSlice(slice.content, slice.openStart, slice.openEnd, pass)\n if (pass == 3 && value != slice && value.size) pass = 0 // Restart if the 3rd pass made progress but left content\n slice = value\n }\n while (frontier.open.length) frontier.closeNode()\n return frontier.placed\n}\n\n// Helper class that models the open side of the insert position,\n// keeping track of the content match and already inserted content\n// at each depth.\nclass Frontier {\n constructor($pos) {\n // : [{parent: Node, match: ContentMatch, content: Fragment, wrapper: bool, openEnd: number, depth: number}]\n this.open = []\n for (let d = 0; d <= $pos.depth; d++) {\n let parent = $pos.node(d), match = parent.contentMatchAt($pos.indexAfter(d))\n this.open.push({parent, match, content: Fragment.empty, wrapper: false, openEnd: 0, depth: d})\n }\n this.placed = []\n }\n\n // : (Fragment, number, number, number, ?Node) → Slice\n // Tries to place the content of the given slice, and returns a\n // slice containing unplaced content.\n //\n // pass 1: try to fit directly\n // pass 2: allow wrapper nodes to be introduced\n // pass 3: allow unwrapping of nodes that aren't open\n placeSlice(fragment, openStart, openEnd, pass, parent) {\n if (openStart > 0) {\n let first = fragment.firstChild\n let inner = this.placeSlice(first.content, Math.max(0, openStart - 1),\n openEnd && fragment.childCount == 1 ? openEnd - 1 : 0,\n pass, first)\n if (inner.content != first.content) {\n if (inner.content.size) {\n fragment = fragment.replaceChild(0, first.copy(inner.content))\n openStart = inner.openStart + 1\n } else {\n if (fragment.childCount == 1) openEnd = 0\n fragment = fragment.cutByIndex(1)\n openStart = 0\n }\n }\n }\n let result = this.placeContent(fragment, openStart, openEnd, pass, parent)\n if (pass > 2 && result.size && openStart == 0) {\n let child = result.content.firstChild, single = result.content.childCount == 1\n this.placeContent(child.content, 0, openEnd && single ? openEnd - 1 : 0, pass, child)\n result = single ? Fragment.empty : new Slice(result.content.cutByIndex(1), 0, openEnd)\n }\n return result\n }\n\n placeContent(fragment, openStart, openEnd, pass, parent) {\n let i = 0\n // Go over the fragment's children\n for (; i < fragment.childCount; i++) {\n let child = fragment.child(i), placed = false, last = i == fragment.childCount - 1\n // Try each open node in turn, starting from the innermost\n for (let d = this.open.length - 1; d >= 0; d--) {\n let open = this.open[d], wrap\n\n // If pass > 1, it is allowed to wrap the node to help find a\n // fit, so if findWrapping returns something, we add open\n // nodes to the frontier for that wrapping.\n if (pass > 1 && (wrap = open.match.findWrapping(child.type)) &&\n !(parent && wrap.length && wrap[wrap.length - 1] == parent.type)) {\n while (this.open.length - 1 > d) this.closeNode()\n for (let w = 0; w < wrap.length; w++) {\n open.match = open.match.matchType(wrap[w])\n d++\n open = {parent: wrap[w].create(),\n match: wrap[w].contentMatch,\n content: Fragment.empty, wrapper: true, openEnd: 0, depth: d + w}\n this.open.push(open)\n }\n }\n\n // See if the child fits here\n let match = open.match.matchType(child.type)\n if (!match) {\n let fill = open.match.fillBefore(Fragment.from(child))\n if (fill) {\n for (let j = 0; j < fill.childCount; j++) {\n let ch = fill.child(j)\n this.addNode(open, ch, 0)\n match = open.match.matchFragment(ch)\n }\n } else if (parent && open.match.matchType(parent.type)) {\n // Don't continue looking further up if the parent node\n // would fit here.\n break\n } else {\n continue\n }\n }\n\n // Close open nodes above this one, since we're starting to\n // add to this.\n while (this.open.length - 1 > d) this.closeNode()\n // Strip marks from the child or close its start when necessary\n child = child.mark(open.parent.type.allowedMarks(child.marks))\n if (openStart) {\n child = closeNodeStart(child, openStart, last ? openEnd : 0)\n openStart = 0\n }\n // Add the child to this open node and adjust its metadata\n this.addNode(open, child, last ? openEnd : 0)\n open.match = match\n if (last) openEnd = 0\n placed = true\n break\n }\n // As soon as we've failed to place a node we stop looking at\n // later nodes\n if (!placed) break\n }\n // Close the current open node if it's not the the root and we\n // either placed up to the end of the node or the the current\n // slice depth's node type matches the open node's type\n if (this.open.length > 1 &&\n (i > 0 && i == fragment.childCount ||\n parent && this.open[this.open.length - 1].parent.type == parent.type))\n this.closeNode()\n\n return new Slice(fragment.cutByIndex(i), openStart, openEnd)\n }\n\n addNode(open, node, openEnd) {\n open.content = closeFragmentEnd(open.content, open.openEnd).addToEnd(node)\n open.openEnd = openEnd\n }\n\n closeNode() {\n let open = this.open.pop()\n if (open.content.size == 0) {\n // Nothing here\n } else if (open.wrapper) {\n this.addNode(this.open[this.open.length - 1], open.parent.copy(open.content), open.openEnd + 1)\n } else {\n this.placed[open.depth] = {depth: open.depth, content: open.content, openEnd: open.openEnd}\n }\n }\n}\n\nfunction closeNodeStart(node, openStart, openEnd) {\n let content = node.content\n if (openStart > 1) {\n let first = closeNodeStart(node.firstChild, openStart - 1, node.childCount == 1 ? openEnd - 1 : 0)\n content = node.content.replaceChild(0, first)\n }\n let fill = node.type.contentMatch.fillBefore(content, openEnd == 0)\n return node.copy(fill.append(content))\n}\n\nfunction closeNodeEnd(node, depth) {\n let content = node.content\n if (depth > 1) {\n let last = closeNodeEnd(node.lastChild, depth - 1)\n content = node.content.replaceChild(node.childCount - 1, last)\n }\n let fill = node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true)\n return node.copy(content.append(fill))\n}\n\nfunction closeFragmentEnd(fragment, depth) {\n return depth ? fragment.replaceChild(fragment.childCount - 1, closeNodeEnd(fragment.lastChild, depth)) : fragment\n}\n\n// :: (number, number, Slice) → this\n// Replace a range of the document with a given slice, using `from`,\n// `to`, and the slice's [`openStart`](#model.Slice.openStart) property\n// as hints, rather than fixed start and end points. This method may\n// grow the replaced area or close open nodes in the slice in order to\n// get a fit that is more in line with WYSIWYG expectations, by\n// dropping fully covered parent nodes of the replaced region when\n// they are marked [non-defining](#model.NodeSpec.defining), or\n// including an open parent node from the slice that _is_ marked as\n// [defining](#model.NodeSpec.defining).\n//\n// This is the method, for example, to handle paste. The similar\n// [`replace`](#transform.Transform.replace) method is a more\n// primitive tool which will _not_ move the start and end of its given\n// range, and is useful in situations where you need more precise\n// control over what happens.\nTransform.prototype.replaceRange = function(from, to, slice) {\n if (!slice.size) return this.deleteRange(from, to)\n\n let $from = this.doc.resolve(from), $to = this.doc.resolve(to)\n if (fitsTrivially($from, $to, slice))\n return this.step(new ReplaceStep(from, to, slice))\n\n let targetDepths = coveredDepths($from, this.doc.resolve(to))\n // Can't replace the whole document, so remove 0 if it's present\n if (targetDepths[targetDepths.length - 1] == 0) targetDepths.pop()\n // Negative numbers represent not expansion over the whole node at\n // that depth, but replacing from $from.before(-D) to $to.pos.\n let preferredTarget = -($from.depth + 1)\n targetDepths.unshift(preferredTarget)\n // This loop picks a preferred target depth, if one of the covering\n // depths is not outside of a defining node, and adds negative\n // depths for any depth that has $from at its start and does not\n // cross a defining node.\n for (let d = $from.depth, pos = $from.pos - 1; d > 0; d--, pos--) {\n let spec = $from.node(d).type.spec\n if (spec.defining || spec.isolating) break\n if (targetDepths.indexOf(d) > -1) preferredTarget = d\n else if ($from.before(d) == pos) targetDepths.splice(1, 0, -d)\n }\n // Try to fit each possible depth of the slice into each possible\n // target depth, starting with the preferred depths.\n let preferredTargetIndex = targetDepths.indexOf(preferredTarget)\n\n let leftNodes = [], preferredDepth = slice.openStart\n for (let content = slice.content, i = 0;; i++) {\n let node = content.firstChild\n leftNodes.push(node)\n if (i == slice.openStart) break\n content = node.content\n }\n // Back up if the node directly above openStart, or the node above\n // that separated only by a non-defining textblock node, is defining.\n if (preferredDepth > 0 && leftNodes[preferredDepth - 1].type.spec.defining &&\n $from.node(preferredTargetIndex).type != leftNodes[preferredDepth - 1].type)\n preferredDepth -= 1\n else if (preferredDepth >= 2 && leftNodes[preferredDepth - 1].isTextblock && leftNodes[preferredDepth - 2].type.spec.defining &&\n $from.node(preferredTargetIndex).type != leftNodes[preferredDepth - 2].type)\n preferredDepth -= 2\n\n for (let j = slice.openStart; j >= 0; j--) {\n let openDepth = (j + preferredDepth + 1) % (slice.openStart + 1)\n let insert = leftNodes[openDepth]\n if (!insert) continue\n for (let i = 0; i < targetDepths.length; i++) {\n // Loop over possible expansion levels, starting with the\n // preferred one\n let targetDepth = targetDepths[(i + preferredTargetIndex) % targetDepths.length], expand = true\n if (targetDepth < 0) { expand = false; targetDepth = -targetDepth }\n let parent = $from.node(targetDepth - 1), index = $from.index(targetDepth - 1)\n if (parent.canReplaceWith(index, index, insert.type, insert.marks))\n return this.replace($from.before(targetDepth), expand ? $to.after(targetDepth) : to,\n new Slice(closeFragment(slice.content, 0, slice.openStart, openDepth),\n openDepth, slice.openEnd))\n }\n }\n\n let startSteps = this.steps.length\n for (let i = targetDepths.length - 1; i >= 0; i--) {\n this.replace(from, to, slice)\n if (this.steps.length > startSteps) break\n let depth = targetDepths[i]\n if (i < 0) continue\n from = $from.before(depth); to = $to.after(depth)\n }\n return this\n}\n\nfunction closeFragment(fragment, depth, oldOpen, newOpen, parent) {\n if (depth < oldOpen) {\n let first = fragment.firstChild\n fragment = fragment.replaceChild(0, first.copy(closeFragment(first.content, depth + 1, oldOpen, newOpen, first)))\n }\n if (depth > newOpen) {\n let match = parent.contentMatchAt(0)\n let start = match.fillBefore(fragment).append(fragment)\n fragment = start.append(match.matchFragment(start).fillBefore(Fragment.empty, true))\n }\n return fragment\n}\n\n// :: (number, number, Node) → this\n// Replace the given range with a node, but use `from` and `to` as\n// hints, rather than precise positions. When from and to are the same\n// and are at the start or end of a parent node in which the given\n// node doesn't fit, this method may _move_ them out towards a parent\n// that does allow the given node to be placed. When the given range\n// completely covers a parent node, this method may completely replace\n// that parent node.\nTransform.prototype.replaceRangeWith = function(from, to, node) {\n if (!node.isInline && from == to && this.doc.resolve(from).parent.content.size) {\n let point = insertPoint(this.doc, from, node.type)\n if (point != null) from = to = point\n }\n return this.replaceRange(from, to, new Slice(Fragment.from(node), 0, 0))\n}\n\n// :: (number, number) → this\n// Delete the given range, expanding it to cover fully covered\n// parent nodes until a valid replace is found.\nTransform.prototype.deleteRange = function(from, to) {\n let $from = this.doc.resolve(from), $to = this.doc.resolve(to)\n let covered = coveredDepths($from, $to)\n for (let i = 0; i < covered.length; i++) {\n let depth = covered[i], last = i == covered.length - 1\n if ((last && depth == 0) || $from.node(depth).type.contentMatch.validEnd)\n return this.delete($from.start(depth), $to.end(depth))\n if (depth > 0 && (last || $from.node(depth - 1).canReplace($from.index(depth - 1), $to.indexAfter(depth - 1))))\n return this.delete($from.before(depth), $to.after(depth))\n }\n for (let d = 1; d <= $from.depth; d++) {\n if (from - $from.start(d) == $from.depth - d && to > $from.end(d) && $to.end(d) - to != $to.depth - d)\n return this.delete($from.before(d), to)\n }\n return this.delete(from, to)\n}\n\n// : (ResolvedPos, ResolvedPos) → [number]\n// Returns an array of all depths for which $from - $to spans the\n// whole content of the nodes at that depth.\nfunction coveredDepths($from, $to) {\n let result = [], minDepth = Math.min($from.depth, $to.depth)\n for (let d = minDepth; d >= 0; d--) {\n let start = $from.start(d)\n if (start < $from.pos - ($from.depth - d) ||\n $to.end(d) > $to.pos + ($to.depth - d) ||\n $from.node(d).type.spec.isolating ||\n $to.node(d).type.spec.isolating) break\n if (start == $to.start(d)) result.push(d)\n }\n return result\n}\n"],"names":["const","let","ReplaceError","super","Slice","slice","Fragment","d","splitting","this","index","MarkType","found","i","joinable"],"mappings":";;;;;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BAA,IAAM,OAAO,GAAG,OAAM;AACtBA,IAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAC;;AAEhC,SAAS,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,KAAK,GAAG,MAAM,GAAG,QAAQ,EAAE;AACxE,SAAS,YAAY,CAAC,KAAK,EAAE,EAAE,OAAO,KAAK,GAAG,OAAO,EAAE;AACvD,SAAS,aAAa,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,KAAK,IAAI,KAAK,GAAG,OAAO,CAAC,IAAI,QAAQ,EAAE;;;;AAI/E,IAAa,SAAS,GACpB,kBAAW,CAAC,GAAG,EAAE,OAAe,EAAE,OAAc,EAAE;mCAA1B,GAAG;mCAAc,GAAG;;;EAE1C,IAAI,CAAC,GAAG,GAAG,IAAG;;;EAGd,IAAI,CAAC,OAAO,GAAG,QAAO;EACtB,IAAI,CAAC,OAAO,GAAG,QAAO;CACvB,CACF;;;;;;;AAOD,IAAa,OAAO,GAKlB,gBAAW,CAAC,MAAM,EAAE,QAAgB,EAAE;qCAAV,GAAG;;EAC7B,IAAI,CAAC,MAAM,GAAG,OAAM;EACpB,IAAI,CAAC,QAAQ,GAAG,SAAQ;EACzB;;AAEH,kBAAE,4BAAQ,KAAK,EAAE;EACf,IAAM,IAAI,GAAG,CAAC,EAAE,KAAK,GAAG,YAAY,CAAC,KAAK,EAAC;EACzC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAE,KAAKC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE;IAClD,EAAE,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAC;EACzD,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC;EAC5D;;;AAGH,kBAAE,gCAAU,GAAG,EAAE,KAAS,EAAE;+BAAN,GAAG;CAAK,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,GAAE;;;AAGnE,kBAAE,oBAAI,GAAG,EAAE,KAAS,EAAE;+BAAN,GAAG;CAAK,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,GAAE;;AAE5D,kBAAE,sBAAK,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE;EACzB,IAAM,IAAI,GAAG,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC,QAAQ,GAAG,CAAC,GAAG,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC,QAAQ,GAAG,CAAC,GAAG,EAAC;EAChF,KAAKA,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE;IAC9CA,IAAI,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,QAAQ,GAAG,IAAI,GAAG,CAAC,EAAC;IACvD,IAAI,KAAK,GAAG,GAAG,IAAE,OAAK;IACtBA,IAAI,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,QAAQ,CAAC,EAAE,GAAG,GAAG,KAAK,GAAG,QAAO;IACnG,IAAI,GAAG,IAAI,GAAG,EAAE;MAChB,IAAM,IAAI,GAAG,CAAC,OAAO,GAAG,KAAK,GAAG,GAAG,IAAI,KAAK,GAAG,CAAC,CAAC,GAAG,GAAG,IAAI,GAAG,GAAG,CAAC,GAAG,MAAK;MACxEA,IAAI,MAAM,GAAG,KAAK,GAAG,IAAI,IAAI,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,OAAO,EAAC;MACpD,IAAI,MAAM,IAAE,OAAO,QAAM;MACzBA,IAAI,OAAO,GAAG,WAAW,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,KAAK,EAAC;MAC7C,OAAO,IAAI,SAAS,CAAC,MAAM,EAAE,KAAK,GAAG,CAAC,GAAG,GAAG,IAAI,KAAK,GAAG,GAAG,IAAI,GAAG,EAAE,OAAO,CAAC;KAC7E;IACD,IAAI,IAAI,OAAO,GAAG,QAAO;GAC1B;EACD,OAAO,MAAM,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,SAAS,CAAC,GAAG,GAAG,IAAI,CAAC;EACvD;;AAEH,kBAAE,4BAAQ,GAAG,EAAE,OAAO,EAAE;EACtB,IAAM,IAAI,GAAG,CAAC,EAAE,KAAK,GAAG,YAAY,CAAC,OAAO,EAAC;EAC7C,IAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,GAAG,CAAC,GAAG,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC,QAAQ,GAAG,CAAC,GAAG,EAAC;EACtE,KAAKA,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE;IAC9CA,IAAI,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,QAAQ,GAAG,IAAI,GAAG,CAAC,EAAC;IACvD,IAAI,KAAK,GAAG,GAAG,IAAE,OAAK;IACtBA,IAAI,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,QAAQ,CAAC,EAAE,GAAG,GAAG,KAAK,GAAG,QAAO;IAC9D,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,IAAI,KAAK,GAAG,CAAC,IAAE,OAAO,MAAI;IAC/C,IAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,QAAO;GAC5C;EACD,OAAO,KAAK;EACb;;;;;AAKH,kBAAE,4BAAQ,CAAC,EAAE;EACX,IAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,GAAG,CAAC,GAAG,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC,QAAQ,GAAG,CAAC,GAAG,EAAC;EACxE,KAAOA,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE;IACxDA,IAAI,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,QAAQ,GAAG,KAAK,IAAI,IAAI,CAAC,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,KAAK,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC,GAAG,IAAI,EAAC;IAC1H,IAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,QAAQ,EAAC;IAC5E,CAAC,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,EAAC;IAC7D,IAAI,IAAI,OAAO,GAAG,QAAO;GAC1B;EACF;;;;;AAKH,kBAAE,4BAAS;EACP,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC;EAChD;;AAEH,kBAAE,gCAAW;EACT,OAAO,CAAC,IAAI,CAAC,QAAQ,GAAG,GAAG,GAAG,EAAE,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;EAChE;;;;;;AAMD,QAAO,0BAAO,CAAC,EAAE;EACf,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;CAC5E,CACF;;AAED,OAAO,CAAC,KAAK,GAAG,IAAI,OAAO,CAAC,EAAE,EAAC;;;;;;;;;AAS/B,IAAa,OAAO,GAGlB,gBAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE;;;EAGlC,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,GAAE;;;;EAItB,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,EAAC;;;EAGrB,IAAI,CAAC,EAAE,GAAG,EAAE,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,GAAE;EAC5C,IAAI,CAAC,MAAM,GAAG,OAAM;EACrB;;;;AAIH,kBAAE,wBAAM,IAAQ,EAAE,EAAqB,EAAE;+BAA7B,GAAG;2BAAK,GAAG,IAAI,CAAC,IAAI,CAAC;;EAC7B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;EACrD;;AAEH,kBAAE,wBAAO;EACL,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;EAC9F;;;;;;AAMH,kBAAE,gCAAU,GAAG,EAAE,OAAO,EAAE;EACxB,IAAM,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAC;EAC7B,IAAI,OAAO,IAAI,IAAI,IAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,OAAO,IAAC;EACnE;;;;;AAKH,kBAAE,wCAAc,OAAO,EAAE;EACvB,KAAOA,IAAI,CAAC,GAAG,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;IAC5E,IAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,EAAC;IACjC,IAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,IAAI,IAAI,IAAI,GAAG,CAAC,GAAG,SAAS,GAAG,IAAI,GAAG,IAAI,EAAC;GACpF;EACF;;;;;;AAMH,kBAAE,gCAAU,CAAC,EAAE;EACb,IAAM,IAAI,CAAC,MAAM,IAAE,KAAKA,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE;IAC5D,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAE,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,OAAC;EACpE;;AAEH,kBAAE,gCAAU,CAAC,EAAE,CAAC,EAAE;EAChB,IAAM,CAAC,IAAI,CAAC,MAAM,IAAE,IAAI,CAAC,MAAM,GAAG,KAAE;EACpC,IAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAC;EACvB;;;;AAIH,kBAAE,wDAAsB,OAAO,EAAE;EAC7B,KAAKA,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;IACvG,IAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,EAAC;IAC/B,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,IAAI,IAAI,IAAI,IAAI,IAAI,GAAG,CAAC,GAAG,SAAS,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,EAAC;GACjG;EACF;;;;AAIH,kBAAE,4BAAS;EACPA,IAAI,OAAO,GAAG,IAAI,QAAO;EACzB,OAAO,CAAC,qBAAqB,CAAC,IAAI,EAAC;EACnC,OAAO,OAAO;EACf;;;;AAIH,kBAAE,oBAAI,GAAG,EAAE,KAAS,EAAE;iCAAN,GAAG;;EACf,IAAI,IAAI,CAAC,MAAM,IAAE,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,GAAC;EACnD,KAAKA,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE;IACxC,EAAE,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,IAAC;EACpC,OAAO,GAAG;EACX;;;;;AAKH,kBAAE,gCAAU,GAAG,EAAE,KAAS,EAAE;+BAAN,GAAG;CAAK,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,GAAE;;AAEnE,kBAAE,sBAAK,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE;EACzB,IAAM,OAAO,GAAG,KAAK,EAAE,YAAY,GAAG,KAAI;;EAExC,KAAKA,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE;IACxCA,IAAI,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,YAAY,IAAI,YAAY,CAAC,CAAC,EAAC;IAC7D,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE;MACxC,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,EAAC;MACtB,QAAQ;KACT;;IAEH,IAAM,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,KAAK,EAAC;IACtC,IAAI,MAAM,CAAC,OAAO,IAAI,IAAI,EAAE;MAC5B,IAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,EAAC;MAC5B,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,IAAI,CAAC,EAAE,EAAE;QAC9C,IAAI,MAAM,CAAC,OAAO,EAAE;UACpB,CAAG,GAAG,KAAI;UACR,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAC;UAC7C,QAAQ;SACT,MAAM;AACJ,CAAC,YAAY,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,MAAM,CAAC,QAAO;SAC/E;OACF;KACF;;IAED,IAAI,MAAM,CAAC,OAAO,IAAE,OAAO,GAAG,OAAI;IAClC,GAAG,GAAG,MAAM,CAAC,IAAG;GACjB;;EAEH,OAAS,MAAM,GAAG,GAAG,GAAG,IAAI,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC;CAClD,CACF;;AC5QM,SAAS,cAAc,CAAC,OAAO,EAAE;EACtCA,IAAI,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAC;EACnC,GAAG,CAAC,SAAS,GAAG,cAAc,CAAC,UAAS;EACxC,OAAO,GAAG;CACX;;AAED,cAAc,CAAC,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,EAAC;AACzD,cAAc,CAAC,SAAS,CAAC,WAAW,GAAG,eAAc;AACrD,cAAc,CAAC,SAAS,CAAC,IAAI,GAAG,iBAAgB;;;;;;;AAOhD,IAAa,SAAS,GAGpB,kBAAW,CAAC,GAAG,EAAE;;;;EAIf,IAAI,CAAC,GAAG,GAAG,IAAG;;;EAGd,IAAI,CAAC,KAAK,GAAG,GAAE;;;EAGf,IAAI,CAAC,IAAI,GAAG,GAAE;;;EAGd,IAAI,CAAC,OAAO,GAAG,IAAI,QAAO;;;+FAC3B;;;AAGH,mBAAM,yBAAS,EAAE,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,GAAE;;;;;AAKpE,oBAAE,sBAAK,MAAM,EAAE;EACb,IAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAC;EACnC,IAAI,MAAM,CAAC,MAAM,IAAE,MAAM,IAAI,cAAc,CAAC,MAAM,CAAC,MAAM,GAAC;EAC1D,OAAO,IAAI;EACZ;;;;;AAKH,oBAAE,gCAAU,IAAI,EAAE;EAChB,IAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAC;EACjC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,IAAC;EAClD,OAAO,MAAM;EACd;;;;;AAKH,mBAAM,6BAAa;EACf,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;EAC7B;;AAEH,oBAAE,4BAAQ,IAAI,EAAE,GAAG,EAAE;EACnB,IAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAC;EACxB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAC;EACvB,IAAM,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,EAAC;EACrC,IAAI,CAAC,GAAG,GAAG,IAAG;CACf;;mEACF;;AClED,SAAS,YAAY,GAAG,EAAE,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,EAAE;;AAE1DD,IAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAC;;;;;;;;;;;AAWrC,IAAa,IAAI;;eAMf,wBAAM,IAAI,EAAE,EAAE,OAAO,YAAY,EAAE,GAAE;;;;;;AAMvC,eAAE,4BAAS,EAAE,OAAO,OAAO,CAAC,KAAK,GAAE;;;;;AAKnC,eAAE,0BAAO,IAAI,EAAE,EAAE,OAAO,YAAY,EAAE,GAAE;;;;;;AAMxC,eAAE,oBAAI,QAAQ,EAAE,EAAE,OAAO,YAAY,EAAE,GAAE;;;;;;AAMzC,eAAE,wBAAM,MAAM,EAAE,EAAE,OAAO,IAAI,GAAE;;;;;;;AAO/B,eAAE,4BAAS,EAAE,OAAO,YAAY,EAAE,GAAE;;;;;AAKlC,KAAO,8BAAS,MAAM,EAAE,IAAI,EAAE;EAC5B,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAE,MAAM,IAAI,UAAU,CAAC,iCAAiC,GAAC;EACtF,IAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAC;EACnC,IAAI,CAAC,IAAI,IAAE,MAAM,IAAI,UAAU,qBAAiB,IAAI,CAAC,SAAQ,iBAAW;EAC1E,OAAS,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;EACnC;;;;;;;AAOD,KAAO,0BAAO,EAAE,EAAE,SAAS,EAAE;EAC3B,IAAI,EAAE,IAAI,SAAS,IAAE,MAAM,IAAI,UAAU,CAAC,gCAAgC,GAAG,EAAE,GAAC;EAChF,SAAS,CAAC,EAAE,CAAC,GAAG,UAAS;EACzB,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,GAAE;EAC/B,OAAO,SAAS;CACjB,CACF;;;;AAID,IAAa,UAAU,GAErB,mBAAW,CAAC,GAAG,EAAE,MAAM,EAAE;;EAEvB,IAAI,CAAC,GAAG,GAAG,IAAG;;EAEd,IAAI,CAAC,MAAM,GAAG,OAAM;EACrB;;;;AAID,WAAO,kBAAG,GAAG,EAAE,EAAE,OAAO,IAAI,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,GAAE;;;;AAInD,WAAO,sBAAK,OAAO,EAAE,EAAE,OAAO,IAAI,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,GAAE;;;;;;AAM/D,WAAS,oCAAY,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE;EACvC,IAAI;IACF,OAAO,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;GACnD,CAAC,OAAO,CAAC,EAAE;IACV,IAAI,CAAC,YAAYE,6BAAY,IAAE,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,GAAC;IAChE,MAAM,CAAC;GACR;CACF,CACF;;;ACvGD,IAAa,WAAW;EAStB,oBAAW,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE;IACtCC,SAAK,KAAC,EAAC;IACP,IAAI,CAAC,IAAI,GAAG,KAAI;IAChB,IAAI,CAAC,EAAE,GAAG,GAAE;IACZ,IAAI,CAAC,KAAK,GAAG,MAAK;IAClB,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,UAAS;;;;;kDAC7B;;wBAED,wBAAM,GAAG,EAAE;IACT,IAAI,IAAI,CAAC,SAAS,IAAI,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;QAC3D,OAAO,UAAU,CAAC,IAAI,CAAC,2CAA2C,GAAC;IACrE,OAAO,UAAU,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC;IACnE;;wBAED,4BAAS;IACP,OAAO,IAAI,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACtE;;wBAED,0BAAO,GAAG,EAAE;IACV,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IAC9F;;wBAED,oBAAI,OAAO,EAAE;IACXF,IAAI,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAC;IAC/E,IAAI,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,OAAO,IAAE,OAAO,MAAI;IAC3C,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC;IACzE;;wBAED,wBAAM,KAAK,EAAE;IACX,IAAI,EAAE,KAAK,YAAY,WAAW,CAAC,IAAI,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,IAAE,OAAO,MAAI;;IAErF,IAAI,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE;MAC9FA,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,GAAGG,sBAAK,CAAC,KAAK;YAC3D,IAAIA,sBAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,EAAC;MAC1G,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC;KAC5F,MAAM,IAAI,KAAK,CAAC,EAAE,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE;MACjFH,IAAII,OAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,GAAGD,sBAAK,CAAC,KAAK;YAC3D,IAAIA,sBAAK,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,EAAC;MAC1G,OAAO,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAEC,OAAK,EAAE,IAAI,CAAC,SAAS,CAAC;KACnE,MAAM;MACL,OAAO,IAAI;KACZ;IACF;;wBAED,4BAAS;IACPJ,IAAI,IAAI,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAC;IAC9D,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,IAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,KAAE;IACrD,IAAI,IAAI,CAAC,SAAS,IAAE,IAAI,CAAC,SAAS,GAAG,OAAI;IACzC,OAAO,IAAI;IACZ;;EAED,YAAO,8BAAS,MAAM,EAAE,IAAI,EAAE;IAC5B,IAAI,OAAO,IAAI,CAAC,IAAI,IAAI,QAAQ,IAAI,OAAO,IAAI,CAAC,EAAE,IAAI,QAAQ;QAC5D,MAAM,IAAI,UAAU,CAAC,wCAAwC,GAAC;IAChE,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAEG,sBAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;GACjG;;;EAhE8B,OAiEhC;;AAED,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,WAAW,EAAC;;;;;AAKnC,IAAa,iBAAiB;EAM5B,0BAAW,CAAC,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE;IAC9DD,SAAK,KAAC,EAAC;IACP,IAAI,CAAC,IAAI,GAAG,KAAI;IAChB,IAAI,CAAC,EAAE,GAAG,GAAE;IACZ,IAAI,CAAC,OAAO,GAAG,QAAO;IACtB,IAAI,CAAC,KAAK,GAAG,MAAK;IAClB,IAAI,CAAC,KAAK,GAAG,MAAK;IAClB,IAAI,CAAC,MAAM,GAAG,OAAM;IACpB,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,UAAS;;;;;8DAC7B;;8BAED,wBAAM,GAAG,EAAE;IACT,IAAI,IAAI,CAAC,SAAS,KAAK,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC;2BAC5C,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QAC9D,OAAO,UAAU,CAAC,IAAI,CAAC,+CAA+C,GAAC;;IAEzEF,IAAI,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,EAAC;IAC7C,IAAI,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,OAAO;QAC9B,OAAO,UAAU,CAAC,IAAI,CAAC,yBAAyB,GAAC;IACnDA,IAAI,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,OAAO,EAAC;IAC5D,IAAI,CAAC,QAAQ,IAAE,OAAO,UAAU,CAAC,IAAI,CAAC,6BAA6B,GAAC;IACpE,OAAO,UAAU,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,QAAQ,CAAC;IACjE;;8BAED,4BAAS;IACP,OAAO,IAAI,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM;wBAChD,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IACtF;;8BAED,0BAAO,GAAG,EAAE;IACVA,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,QAAO;IACnC,OAAO,IAAI,iBAAiB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG;iCAC5C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,GAAG,GAAG;iCACtD,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC;iCAC7F,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;IACvE;;8BAED,oBAAI,OAAO,EAAE;IACXA,IAAI,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAC;IAC/EA,IAAI,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAC;IAC/E,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,OAAO,KAAK,OAAO,GAAG,IAAI,CAAC,GAAG,IAAI,KAAK,GAAG,EAAE,CAAC,GAAG,IAAE,OAAO,MAAI;IACrF,OAAO,IAAI,iBAAiB,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC;IACxG;;8BAED,4BAAS;IACPA,IAAI,IAAI,GAAG,CAAC,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE;gBACvD,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAC;IAC1E,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,IAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,KAAE;IACrD,IAAI,IAAI,CAAC,SAAS,IAAE,IAAI,CAAC,SAAS,GAAG,OAAI;IACzC,OAAO,IAAI;IACZ;;EAED,kBAAO,8BAAS,MAAM,EAAE,IAAI,EAAE;IAC5B,IAAI,OAAO,IAAI,CAAC,IAAI,IAAI,QAAQ,IAAI,OAAO,IAAI,CAAC,EAAE,IAAI,QAAQ;QAC1D,OAAO,IAAI,CAAC,OAAO,IAAI,QAAQ,IAAI,OAAO,IAAI,CAAC,KAAK,IAAI,QAAQ,IAAI,OAAO,IAAI,CAAC,MAAM,IAAI,QAAQ;QACpG,MAAM,IAAI,UAAU,CAAC,8CAA8C,GAAC;IACtE,OAAO,IAAI,iBAAiB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK;iCAC5CG,sBAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;GAChG;;;EAhEoC,OAiEtC;;AAED,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,iBAAiB,EAAC;;AAE/C,SAAS,cAAc,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE;EACrCH,IAAI,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,GAAG,IAAI,EAAE,KAAK,GAAG,KAAK,CAAC,MAAK;EACpE,OAAO,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,UAAU,EAAE;IACvF,KAAK,GAAE;IACP,IAAI,GAAE;GACP;EACD,IAAI,IAAI,GAAG,CAAC,EAAE;IACZA,IAAI,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,EAAC;IAChE,OAAO,IAAI,GAAG,CAAC,EAAE;MACf,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,IAAE,OAAO,MAAI;MACrC,IAAI,GAAG,IAAI,CAAC,WAAU;MACtB,IAAI,GAAE;KACP;GACF;EACD,OAAO,KAAK;CACb;;AC7JD,SAAS,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE;EAChC,OAAO,CAAC,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC;KAC1D,GAAG,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;CACtD;;;;;;AAMD,AAAO,SAAS,UAAU,CAAC,KAAK,EAAE;EAChCA,IAAI,MAAM,GAAG,KAAK,CAAC,OAAM;EACzBA,IAAI,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,QAAQ,EAAC;EACzE,KAAKA,IAAI,KAAK,GAAG,KAAK,CAAC,KAAK,GAAG,EAAE,KAAK,EAAE;IACtCA,IAAI,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAC;IAClCA,IAAI,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,EAAC;IAC5E,IAAI,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC;QAClE,OAAO,OAAK;IACd,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAE,OAAK;GACpF;CACF;;;;;;;;AAQD,SAAS,CAAC,SAAS,CAAC,IAAI,GAAG,SAAS,KAAK,EAAE,MAAM,EAAE;EACjD;EAAY;EAAK,wBAAc;;EAE/BA,IAAI,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,EAAC;EACrEA,IAAI,KAAK,GAAG,QAAQ,EAAE,GAAG,GAAG,OAAM;;EAElCA,IAAI,MAAM,GAAGK,yBAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,EAAC;EAC1C,KAAKL,IAAI,CAAC,GAAG,KAAK,EAAE,SAAS,GAAG,KAAK,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE;MACpD,IAAI,SAAS,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;MACnC,SAAS,GAAG,KAAI;MAChB,MAAM,GAAGK,yBAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAC;MAClD,SAAS,GAAE;KACZ,MAAM;MACL,KAAK,GAAE;OACR;EACHL,IAAI,KAAK,GAAGK,yBAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,EAAC;EACvC,KAAKL,IAAIM,GAAC,GAAG,KAAK,EAAEC,WAAS,GAAG,KAAK,EAAED,GAAC,GAAG,MAAM,EAAEA,GAAC,EAAE;MACpD,IAAIC,WAAS,IAAI,GAAG,CAAC,KAAK,CAACD,GAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAACA,GAAC,CAAC,EAAE;MAC9CC,WAAS,GAAG,KAAI;MAChB,KAAK,GAAGF,yBAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAACC,GAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAC;MAC9C,OAAO,GAAE;KACV,MAAM;MACL,GAAG,GAAE;OACN;;EAEH,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM;yCAC5B,IAAIH,sBAAK,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC;yCACnD,MAAM,CAAC,IAAI,GAAG,SAAS,EAAE,IAAI,CAAC,CAAC;EACvE;;;;;;;;;AASD,AAAO,SAAS,YAAY,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAkB,EAAE;yCAAV,GAAG;;EAChEH,IAAI,MAAM,GAAG,mBAAmB,CAAC,KAAK,EAAE,QAAQ,EAAC;EACjDA,IAAI,KAAK,GAAG,MAAM,IAAI,kBAAkB,CAAC,UAAU,EAAE,QAAQ,EAAC;EAC9D,IAAI,CAAC,KAAK,IAAE,OAAO,MAAI;EACvB,OAAO,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,QAAQ,SAAE,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;CAC1F;;AAED,SAAS,SAAS,CAAC,IAAI,EAAE,EAAE,OAAO,OAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE;;AAEvD,SAAS,mBAAmB,CAAC,KAAK,EAAE,IAAI,EAAE;EACxC;EAAa;EAAY,8BAAiB;EAC1CA,IAAI,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,YAAY,CAAC,IAAI,EAAC;EACjE,IAAI,CAAC,MAAM,IAAE,OAAO,MAAI;EACxBA,IAAI,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,KAAI;EAC5C,OAAO,MAAM,CAAC,cAAc,CAAC,UAAU,EAAE,QAAQ,EAAE,KAAK,CAAC,GAAG,MAAM,GAAG,IAAI;CAC1E;;AAED,SAAS,kBAAkB,CAAC,KAAK,EAAE,IAAI,EAAE;EACvC;EAAa;EAAY,8BAAiB;EAC1CA,IAAI,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,EAAC;EACpCA,IAAI,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,EAAC;EACvD,IAAI,CAAC,MAAM,IAAE,OAAO,MAAI;EACxBA,IAAI,QAAQ,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,KAAI;EAC/DA,IAAI,UAAU,GAAG,QAAQ,CAAC,aAAY;EACtC,KAAKA,IAAI,CAAC,GAAG,UAAU,EAAE,UAAU,IAAI,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE;MACtD,UAAU,GAAG,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,IAAC;EACzD,IAAI,CAAC,UAAU,IAAI,CAAC,UAAU,CAAC,QAAQ,IAAE,OAAO,MAAI;EACpD,OAAO,MAAM;CACd;;;;;;AAMD,SAAS,CAAC,SAAS,CAAC,IAAI,GAAG,SAAS,KAAK,EAAE,QAAQ,EAAE;EACnDA,IAAI,OAAO,GAAGK,yBAAQ,CAAC,MAAK;EAC5B,KAAKL,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;MAC3C,OAAO,GAAGK,yBAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,IAAC;;EAE9EL,IAAI,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,GAAG,GAAG,KAAK,CAAC,IAAG;EACxC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,IAAIG,sBAAK,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;EACjH;;;;;AAKD,SAAS,CAAC,SAAS,CAAC,YAAY,GAAG,SAAS,IAAI,EAAE,EAAS,EAAE,IAAI,EAAE,KAAK,EAAE;;yBAAtB,GAAG;;EACrD,IAAI,CAAC,IAAI,CAAC,WAAW,IAAE,MAAM,IAAI,UAAU,CAAC,kDAAkD,GAAC;EAC/FH,IAAI,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAM;EAC/B,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,EAAE,YAAG,IAAI,EAAE,GAAG,EAAE;IAC1C,IAAI,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,aAAa,CAACQ,MAAI,CAAC,GAAG,EAAEA,MAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE;;MAE3HA,MAAI,CAAC,iBAAiB,CAACA,MAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAC;MACrER,IAAI,OAAO,GAAGQ,MAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAC;MACzCR,IAAI,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAC;MAC5EQ,MAAI,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC;sCAClC,IAAIL,sBAAK,CAACE,yBAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAC;MAC/G,OAAO,KAAK;KACb;GACF,EAAC;EACF,OAAO,IAAI;EACZ;;AAED,SAAS,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE;EACrCL,IAAI,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,KAAK,GAAE;EACjD,OAAO,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,EAAE,IAAI,CAAC;CAC1D;;;;;AAKD,SAAS,CAAC,SAAS,CAAC,aAAa,GAAG,SAAS,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE;EACpEA,IAAI,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAC;EAC/B,IAAI,CAAC,IAAI,IAAE,MAAM,IAAI,UAAU,CAAC,2BAA2B,GAAC;EAC5D,IAAI,CAAC,IAAI,IAAE,IAAI,GAAG,IAAI,CAAC,OAAI;EAC3BA,IAAI,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,IAAI,CAAC,KAAK,EAAC;EAC3D,IAAI,IAAI,CAAC,MAAM;MACb,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,OAAO,GAAC;;EAE5D,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC;MAClC,MAAM,IAAI,UAAU,CAAC,gCAAgC,GAAG,IAAI,CAAC,IAAI,GAAC;;EAEpE,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,QAAQ,GAAG,CAAC;yCAC1D,IAAIG,sBAAK,CAACE,yBAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;EAC1F;;;;AAID,AAAO,SAAS,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,KAAS,EAAE,UAAU,EAAE;+BAAlB,GAAG;;EACzCL,IAAI,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC,KAAK,GAAG,MAAK;EACtDA,IAAI,SAAS,GAAG,CAAC,UAAU,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,OAAM;EAChF,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS;MAC3C,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC;MAC7D,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;MACpG,OAAO,OAAK;EACd,KAAKA,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE;IAC9DA,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAES,OAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAC;IAC9C,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,IAAE,OAAO,OAAK;IAC1CT,IAAI,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAACS,OAAK,EAAE,IAAI,CAAC,UAAU,EAAC;IAC1DT,IAAI,KAAK,GAAG,CAAC,UAAU,IAAI,UAAU,CAAC,CAAC,CAAC,KAAK,KAAI;IACjD,IAAI,KAAK,IAAI,IAAI,IAAE,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAC;IAC9E,IAAI,CAAC,IAAI,CAAC,UAAU,CAACS,OAAK,GAAG,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;QAChF,OAAO,OAAK;GACf;EACDT,IAAI,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,EAAC;EACjCA,IAAI,QAAQ,GAAG,UAAU,IAAI,UAAU,CAAC,CAAC,EAAC;EAC1C,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,GAAG,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;CACzG;;;;;;;;AAQD,SAAS,CAAC,SAAS,CAAC,KAAK,GAAG,SAAS,GAAG,EAAE,KAAS,EAAE,UAAU,EAAE;+BAAlB,GAAG;;EAChDA,IAAI,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,GAAGK,yBAAQ,CAAC,KAAK,EAAE,KAAK,GAAGA,yBAAQ,CAAC,MAAK;EACjF,KAAKL,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,KAAK,EAAE,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE;IAC/E,MAAM,GAAGK,yBAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAC;IACjDL,IAAI,SAAS,GAAG,UAAU,IAAI,UAAU,CAAC,CAAC,EAAC;IAC3C,KAAK,GAAGK,yBAAQ,CAAC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAC;GAC5G;EACD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,IAAIF,sBAAK,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;EACjG;;;;;AAKD,AAAO,SAAS,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE;EAChCH,IAAI,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,KAAK,GAAE;EACjD,OAAO,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC;IAC9C,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC;CAC3C;;AAED,SAAS,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE;EACtB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;CAC7C;;;;;;AAMD,AAAO,SAAS,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,GAAQ,EAAE;2BAAP,GAAG,CAAC;;EACzCA,IAAI,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,EAAC;EAC3B,KAAKA,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,EAAE;IAC7BA,IAAI,iBAAM,EAAE,iBAAK;IACjB,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE;MACnB,MAAM,GAAG,IAAI,CAAC,WAAU;MACxB,KAAK,GAAG,IAAI,CAAC,UAAS;KACvB,MAAM,IAAI,GAAG,GAAG,CAAC,EAAE;MAClB,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAC;MACzB,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAC;KACnD,MAAM;MACL,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAC;MACnD,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAC;KACzB;IACD,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,IAAE,OAAO,KAAG;IACxE,IAAI,CAAC,IAAI,CAAC,IAAE,OAAK;IACjB,GAAG,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAC;GAC/C;CACF;;;;;AAKD,SAAS,CAAC,SAAS,CAAC,IAAI,GAAG,SAAS,GAAG,EAAE,KAAS,EAAE;+BAAN,GAAG;;EAC/CA,IAAI,IAAI,GAAG,IAAI,WAAW,CAAC,GAAG,GAAG,KAAK,EAAE,GAAG,GAAG,KAAK,EAAEG,sBAAK,CAAC,KAAK,EAAE,IAAI,EAAC;EACvE,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;EACvB;;;;;;;AAOD,AAAO,SAAS,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE;EAC9CH,IAAI,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,EAAC;EAC3B,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,EAAE,QAAQ,CAAC,IAAE,OAAO,KAAG;;EAEhF,IAAI,IAAI,CAAC,YAAY,IAAI,CAAC;MACxB,KAAKA,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;MACxCA,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAC;MACzB,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAE,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAC;MAClF,IAAI,KAAK,GAAG,CAAC,IAAE,OAAO,MAAI;OAC3B;EACH,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI;MAC/C,KAAKA,IAAIM,GAAC,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,EAAEA,GAAC,IAAI,CAAC,EAAEA,GAAC,EAAE,EAAE;MACxCN,IAAIS,OAAK,GAAG,IAAI,CAAC,UAAU,CAACH,GAAC,EAAC;MAC9B,IAAI,IAAI,CAAC,IAAI,CAACA,GAAC,CAAC,CAAC,cAAc,CAACG,OAAK,EAAEA,OAAK,EAAE,QAAQ,CAAC,IAAE,OAAO,IAAI,CAAC,KAAK,CAACH,GAAC,GAAG,CAAC,GAAC;MACjF,IAAIG,OAAK,GAAG,IAAI,CAAC,IAAI,CAACH,GAAC,CAAC,CAAC,UAAU,IAAE,OAAO,MAAI;OACjD;CACJ;;;;;;;AAOD,AAAO,SAAS,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE;EACzCN,IAAI,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,EAAC;EAC3B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,IAAE,OAAO,KAAG;EACnCA,IAAI,OAAO,GAAG,KAAK,CAAC,QAAO;EAC3B,KAAKA,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC,EAAE,IAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,UAAO;EAC9E,KAAKA,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,KAAK,KAAK,CAAC,SAAS,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE;IAC/E,KAAKA,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;MACpCA,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAC;MAC/FA,IAAI,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAC;MAClD,IAAI,IAAI,IAAI,CAAC;YACP,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC;YACtD,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;UAChF,OAAO,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAC;KAClF;GACF;EACD,OAAO,IAAI;CACZ;;ACxRD,SAAS,WAAW,CAAC,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE;EACxCA,IAAI,MAAM,GAAG,GAAE;EACf,KAAKA,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE;IAC5CA,IAAI,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAC;IAC7B,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,IAAE,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,IAAC;IAChF,IAAI,KAAK,CAAC,QAAQ,IAAE,KAAK,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,IAAC;IAC/C,MAAM,CAAC,IAAI,CAAC,KAAK,EAAC;GACnB;EACD,OAAOK,yBAAQ,CAAC,SAAS,CAAC,MAAM,CAAC;CAClC;;;AAGD,IAAa,WAAW;EAEtB,oBAAW,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE;IAC1BH,SAAK,KAAC,EAAC;IACP,IAAI,CAAC,IAAI,GAAG,KAAI;IAChB,IAAI,CAAC,EAAE,GAAG,GAAE;IACZ,IAAI,CAAC,IAAI,GAAG,KAAI;;;;;kDACjB;;wBAED,wBAAM,GAAG,EAAE;;;IACTF,IAAI,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAC;IAC5EA,IAAI,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,EAAC;IACnDA,IAAI,KAAK,GAAG,IAAIG,sBAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,YAAG,IAAI,EAAE,MAAM,EAAE;MACjE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAACK,MAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAE,OAAO,MAAI;MAC5D,OAAO,IAAI,CAAC,IAAI,CAACA,MAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;KACjD,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,OAAO,EAAC;IACjD,OAAO,UAAU,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC;IAC9D;;wBAED,4BAAS;IACP,OAAO,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC;IACzD;;wBAED,oBAAI,OAAO,EAAE;IACXR,IAAI,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAC;IAC/E,IAAI,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,OAAO,IAAI,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,IAAE,OAAO,MAAI;IACjE,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC;IACpD;;wBAED,wBAAM,KAAK,EAAE;IACX,IAAI,KAAK,YAAY,WAAW;QAC5B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;QACxB,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,IAAI,KAAK,CAAC,IAAI;QAChD,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC;6BAC/B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,GAAC;IACjE;;wBAED,4BAAS;IACP,OAAO,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAC7C,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC;IACtC;;EAED,YAAO,8BAAS,MAAM,EAAE,IAAI,EAAE;IAC5B,IAAI,OAAO,IAAI,CAAC,IAAI,IAAI,QAAQ,IAAI,OAAO,IAAI,CAAC,EAAE,IAAI,QAAQ;QAC5D,MAAM,IAAI,UAAU,CAAC,wCAAwC,GAAC;IAChE,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;GAC3E;;;EA9C8B,OA+ChC;;AAED,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,WAAW,EAAC;;;AAGnC,IAAa,cAAc;EAEzB,uBAAW,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE;IAC1BE,SAAK,KAAC,EAAC;IACP,IAAI,CAAC,IAAI,GAAG,KAAI;IAChB,IAAI,CAAC,EAAE,GAAG,GAAE;IACZ,IAAI,CAAC,IAAI,GAAG,KAAI;;;;;wDACjB;;2BAED,wBAAM,GAAG,EAAE;;;IACTF,IAAI,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAC;IAC5CA,IAAI,KAAK,GAAG,IAAIG,sBAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,YAAE,MAAK;MACvD,OAAO,IAAI,CAAC,IAAI,CAACK,MAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;KACtD,CAAC,EAAE,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,OAAO,EAAC;IACzC,OAAO,UAAU,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC;IAC9D;;2BAED,4BAAS;IACP,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC;IACtD;;2BAED,oBAAI,OAAO,EAAE;IACXR,IAAI,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAC;IAC/E,IAAI,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,OAAO,IAAI,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,IAAE,OAAO,MAAI;IACjE,OAAO,IAAI,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC;IACvD;;2BAED,wBAAM,KAAK,EAAE;IACX,IAAI,KAAK,YAAY,cAAc;QAC/B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;QACxB,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,IAAI,KAAK,CAAC,IAAI;QAChD,OAAO,IAAI,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC;gCAC/B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,GAAC;IACpE;;2BAED,4BAAS;IACP,OAAO,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAChD,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC;IACtC;;EAED,eAAO,8BAAS,MAAM,EAAE,IAAI,EAAE;IAC5B,IAAI,OAAO,IAAI,CAAC,IAAI,IAAI,QAAQ,IAAI,OAAO,IAAI,CAAC,EAAE,IAAI,QAAQ;QAC5D,MAAM,IAAI,UAAU,CAAC,2CAA2C,GAAC;IACnE,OAAO,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;GAC9E;;;EA5CiC,OA6CnC;;AAED,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,cAAc,CAAC;;;;AC1GzC,SAAS,CAAC,SAAS,CAAC,OAAO,GAAG,SAAS,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE;;;EACrDA,IAAI,OAAO,GAAG,EAAE,EAAE,KAAK,GAAG,EAAE,EAAE,QAAQ,GAAG,IAAI,EAAE,MAAM,GAAG,KAAI;EAC5D,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,EAAE,YAAG,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE;IAClD,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAE,QAAM;IAC1BA,IAAI,KAAK,GAAG,IAAI,CAAC,MAAK;IACtB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;MACjEA,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,EAAE,EAAC;MACxEA,IAAI,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAC;;MAEjC,KAAKA,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACrC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;UAC7B,IAAI,QAAQ,IAAI,QAAQ,CAAC,EAAE,IAAI,KAAK,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;cAChE,QAAQ,CAAC,EAAE,GAAG,MAAG;;cAEjB,OAAO,CAAC,IAAI,CAAC,QAAQ,GAAG,IAAI,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAC;SACpE;OACF;;MAED,IAAI,MAAM,IAAI,MAAM,CAAC,EAAE,IAAI,KAAK;UAC9B,MAAM,CAAC,EAAE,GAAG,MAAG;;UAEf,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,WAAW,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,IAAC;KACzD;GACF,EAAC;;EAEF,OAAO,CAAC,OAAO,WAAC,GAAE,SAAGQ,MAAI,CAAC,IAAI,CAAC,CAAC,IAAC,EAAC;EAClC,KAAK,CAAC,OAAO,WAAC,GAAE,SAAGA,MAAI,CAAC,IAAI,CAAC,CAAC,IAAC,EAAC;EAChC,OAAO,IAAI;EACZ;;;;;;;AAOD,SAAS,CAAC,SAAS,CAAC,UAAU,GAAG,SAAS,IAAI,EAAE,EAAE,EAAE,IAAW,EAAE;;6BAAT,GAAG;;EACzDR,IAAI,OAAO,GAAG,EAAE,EAAE,IAAI,GAAG,EAAC;EAC1B,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,EAAE,YAAG,IAAI,EAAE,GAAG,EAAE;IAC1C,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAE,QAAM;IAC1B,IAAI,GAAE;IACNA,IAAI,QAAQ,GAAG,KAAI;IACnB,IAAI,IAAI,YAAYU,yBAAQ,EAAE;MAC5BV,IAAI,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAC;MACpC,IAAI,KAAK,IAAE,QAAQ,GAAG,CAAC,KAAK,IAAC;KAC9B,MAAM,IAAI,IAAI,EAAE;MACf,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAE,QAAQ,GAAG,CAAC,IAAI,IAAC;KAChD,MAAM;MACL,QAAQ,GAAG,IAAI,CAAC,MAAK;KACtB;IACD,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,EAAE;MAC/BA,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,EAAE,EAAC;MAC3C,KAAKA,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACxCA,IAAI,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAEW,mBAAK;QAC9B,KAAKX,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;UACvCA,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,EAAC;UAClB,IAAI,CAAC,CAAC,IAAI,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAEW,OAAK,GAAG,IAAC;SAChE;QACD,IAAIA,OAAK,EAAE;UACTA,OAAK,CAAC,EAAE,GAAG,IAAG;UACdA,OAAK,CAAC,IAAI,GAAG,KAAI;SAClB,MAAM;UACL,OAAO,CAAC,IAAI,CAAC,QAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,QAAE,IAAI,CAAC,EAAC;SAChE;OACF;KACF;GACF,EAAC;EACF,OAAO,CAAC,OAAO,WAAC,GAAE,SAAGH,MAAI,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAC,EAAC;EAC1E,OAAO,IAAI;EACZ;;;;;;;AAOD,SAAS,CAAC,SAAS,CAAC,iBAAiB,GAAG,SAAS,GAAG,EAAE,UAAU,EAAE,KAA+B,EAAE;+BAA5B,GAAG,UAAU,CAAC;;EACnFR,IAAI,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAC;EAC/BA,IAAI,QAAQ,GAAG,EAAE,EAAE,GAAG,GAAG,GAAG,GAAG,EAAC;EAChC,KAAKA,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE;IACxCA,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,KAAK,CAAC,SAAQ;IACrDA,IAAI,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,EAAC;IACtD,IAAI,CAAC,OAAO,EAAE;MACZ,QAAQ,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,GAAG,EAAE,GAAG,EAAEG,sBAAK,CAAC,KAAK,CAAC,EAAC;KACtD,MAAM;MACL,KAAK,GAAG,QAAO;MACf,KAAKH,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,IAAE,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;UAC9F,IAAI,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAC;KAC1D;IACD,GAAG,GAAG,IAAG;GACV;EACD,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;IACnBA,IAAI,IAAI,GAAG,KAAK,CAAC,UAAU,CAACK,yBAAQ,CAAC,KAAK,EAAE,IAAI,EAAC;IACjD,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,IAAIF,sBAAK,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,EAAC;GAC9C;EACD,KAAKH,IAAIY,GAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAEA,GAAC,IAAI,CAAC,EAAEA,GAAC,EAAE,IAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAACA,GAAC,CAAC,IAAC;EACrE,OAAO,IAAI;CACZ;;;;;;;AC7FD,AAAO,SAAS,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,EAAS,EAAE,KAAmB,EAAE;yBAA9B,GAAG;+BAAW,GAAGT,sBAAK,CAAC;;EAC9D,IAAI,IAAI,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,IAAE,OAAO,MAAI;;EAE1CH,IAAI,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,EAAE,EAAC;;EAEpD,IAAI,aAAa,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,IAAE,OAAO,IAAI,WAAW,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,GAAC;EAC7EA,IAAI,MAAM,GAAG,UAAU,CAAC,KAAK,EAAE,KAAK,EAAC;;EAErCA,IAAI,UAAU,GAAG,OAAO,CAAC,KAAK,EAAE,MAAM,EAAC;EACvCA,IAAI,MAAM,GAAG,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE,UAAU,EAAC;EAC7C,IAAI,CAAC,MAAM,IAAE,OAAO,MAAI;EACxB,IAAI,UAAU,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,IAAI,WAAW,CAAC,KAAK,EAAE,GAAG,EAAE,UAAU,CAAC,EAAE;IACzEA,IAAI,CAAC,GAAG,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAC;IACvC,OAAO,CAAC,GAAG,CAAC,IAAI,KAAK,IAAI,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAE,EAAE,QAAK;IAC9CA,IAAI,WAAW,GAAG,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,UAAU,EAAC;IACjE,IAAI,WAAW;QACb,OAAO,IAAI,iBAAiB,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,UAAU,CAAC,IAAI,GAAC;GACzF;EACD,OAAO,MAAM,CAAC,IAAI,IAAI,IAAI,IAAI,EAAE,GAAG,IAAI,WAAW,CAAC,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,IAAI;CAC5E;;;;;AAKD,SAAS,CAAC,SAAS,CAAC,OAAO,GAAG,SAAS,IAAI,EAAE,EAAS,EAAE,KAAmB,EAAE;yBAA9B,GAAG;+BAAW,GAAGG,sBAAK,CAAC;;EACpEH,IAAI,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAC;EACjD,IAAI,IAAI,IAAE,IAAI,CAAC,IAAI,CAAC,IAAI,IAAC;EACzB,OAAO,IAAI;EACZ;;;;;AAKD,SAAS,CAAC,SAAS,CAAC,WAAW,GAAG,SAAS,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE;EAC5D,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,IAAIG,sBAAK,CAACE,yBAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;EACvE;;;;AAID,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,SAAS,IAAI,EAAE,EAAE,EAAE;EAC9C,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,EAAEF,sBAAK,CAAC,KAAK,CAAC;EAC3C;;;;AAID,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,SAAS,GAAG,EAAE,OAAO,EAAE;EAClD,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC;EAC3C;;;;AAID,SAAS,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE;EACvDH,IAAI,OAAO,GAAGK,yBAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC,KAAK,EAAC;EACrE,IAAI,KAAK,CAAC,KAAK,GAAG,KAAK,EAAE;IACvBL,IAAI,KAAK,GAAG,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,EAAE,MAAM,EAAE,WAAW,IAAI,UAAU,EAAC;IAC7E,OAAO,GAAG,KAAK,CAAC,OAAO,GAAG,EAAC;IAC3B,OAAO,GAAGK,yBAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAC;GACnE;;EAED,IAAI,UAAU,EAAE;IACd,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,EAAC;IAC5C,OAAO,GAAG,UAAU,CAAC,QAAO;GAC7B;EACD,IAAI,WAAW,EAAE;IACf,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAACA,yBAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,EAAC;IACpH,OAAO,GAAG,EAAC;GACZ;;EAED,OAAO,UAAC,OAAO,WAAE,OAAO,CAAC;CAC1B;;AAED,SAAS,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE;EAC9B,OAAsB,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK;EAAxD;EAAS,0BAAgD;EAC9D,OAAO,IAAIF,sBAAK,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,EAAE,OAAO,IAAI,CAAC,CAAC;CACrD;;AAED,SAAS,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE;EAC5EH,IAAI,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,UAAU,EAAE,UAAU,GAAG,KAAK,IAAI,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAC;EACjFA,IAAI,UAAU,GAAG,SAAS,GAAG,CAAC,GAAG,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,EAAC;EAC3D,IAAI,SAAS,GAAG,CAAC;MACf,KAAK,GAAG,UAAU,CAAC,cAAc,CAAC,UAAU,IAAC;OAC1C,IAAI,KAAK,IAAI,CAAC,IAAI,OAAO,GAAG,CAAC;MAChC,KAAK,GAAG,UAAU,CAAC,cAAc,CAAC,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,IAAC;;MAE3F,KAAK,GAAG,UAAU,CAAC,cAAc,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;OACvD,aAAa,CAAC,OAAO,EAAE,KAAK,GAAG,CAAC,IAAI,SAAS,GAAG,CAAC,GAAG,CAAC,EAAE,UAAU,IAAC;;EAEvEA,IAAI,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,EAAC;EAC5B,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,GAAG,GAAG,CAAC,KAAK,EAAE;IACpCA,IAAI,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,EAAC;IAC1FA,IAAIa,UAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,EAAC;;IAE5C,IAAIA,UAAQ,IAAIA,UAAQ,CAAC,IAAI,IAAI,SAAS,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,IAAEA,UAAQ,GAAG,OAAI;;IAE7E,IAAIA,UAAQ,EAAE;MACZb,IAAI,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,EAAE,KAAK,EAAE,GAAG;+BACxD,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,GAAG,SAAS,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,EAAC;MACjF,IAAI,KAAK,EAAE;QACTA,IAAI,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,EAAC;QACxC,IAAIa,UAAQ,CAAC,IAAI;YACf,OAAO,OAAO,CAAC,UAAU,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAACA,UAAQ,CAAC,CAAC,QAAQ,CAAC,IAAI,GAAC;;YAEvE,OAAO,OAAO,CAAC,YAAY,CAAC,KAAK,GAAG,CAAC,EAAE,IAAI,GAAC;OAC/C;KACF;GACF;EACD,IAAI,OAAO,GAAG,CAAC;MACb,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,SAAS,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,IAAC;;;;EAIzGb,IAAI,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,EAAC;EAC9B,IAAI,OAAO,IAAI,MAAM,CAAC,UAAU,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,IAAE,OAAO,MAAI;EAC5FA,IAAI,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAC;EAC9D,KAAKA,IAAI,CAAC,GAAG,OAAO,EAAE,QAAQ,IAAI,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,EAAE;MAClE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAE,QAAQ,GAAG,SAAI;EAClF,IAAI,CAAC,QAAQ,IAAE,OAAO,MAAI;;EAE1B,IAAI,OAAO,GAAG,CAAC,EAAE;IACfA,IAAI,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,GAAG,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC;gCAChD,KAAK,IAAI,CAAC,GAAG,SAAS,GAAG,CAAC,GAAG,CAAC,CAAC,EAAC;IAC5D,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,GAAG,CAAC,EAAE,MAAM,EAAC;GAClD;EACD,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAC;EAClC,IAAI,GAAG,CAAC,KAAK,GAAG,KAAK;MACnB,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,GAAG,EAAE,KAAK,GAAG,CAAC,CAAC,IAAC;EAC9D,OAAO,OAAO;CACf;;AAED,SAAS,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE;EAC9DA,IAAI,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,WAAU;EAC7D,IAAI,SAAS,IAAI,CAAC;MAChB,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;OAC9D,aAAa,CAAC,OAAO,EAAE,SAAS,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,IAAC;;MAEvD,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,IAAC;;EAEpC,IAAI,OAAO,GAAG,CAAC,EAAE;IACfA,IAAI,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,GAAG,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC;gCAChD,KAAK,IAAI,CAAC,GAAG,SAAS,GAAG,CAAC,GAAG,CAAC,CAAC,EAAC;IAC5D,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,GAAG,CAAC,EAAE,MAAM,EAAC;GAClD;;EAED,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAACK,yBAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;CACzE;;AAED,SAAS,gBAAgB,CAAC,GAAG,EAAE,KAAK,EAAE;EACpCL,IAAI,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,EAAC;EAC1BA,IAAI,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAC;EAClF,IAAI,GAAG,CAAC,KAAK,GAAG,KAAK,IAAE,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,GAAG,EAAE,KAAK,GAAG,CAAC,CAAC,IAAC;EAC7E,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;CACvB;;AAED,SAAS,cAAc,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE;EACnD,OAAO,SAAS,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC,IAAI,OAAO,CAAC,UAAU,IAAI,CAAC,EAAE;IAC9D,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,QAAO;IACpC,SAAS,GAAE;IACX,OAAO,GAAE;GACV;EACD,OAAO,IAAIG,sBAAK,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC;CAC9C;;;AAGD,SAAS,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE;EACnCH,IAAI,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,EAAC;EACtG,IAAI,CAAC,MAAM,IAAE,OAAO,MAAI;EACxB,OAAO,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,SAAS,EAAE,GAAG,CAAC,KAAK,CAAC;CAC1D;;AAED,SAAS,aAAa,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE;EACxC,OAAO,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,KAAK,EAAE,IAAI,GAAG,CAAC,KAAK,EAAE;IACvE,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,GAAG,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC;CACrE;;AAED,SAAS,WAAW,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE;EACtC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,IAAE,OAAO,OAAK;;EAEzCA,IAAI,MAAM,GAAG,KAAK,CAAC,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;QAC9D,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,EAAC;EACjE,IAAI,CAAC,MAAM,CAAC,WAAW,IAAE,OAAO,OAAK;EACrC,KAAKA,IAAI,CAAC,GAAG,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,EAAE;MACtD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAE,OAAO,SAAK;EACvEA,IAAI,MAAK;EACT,IAAI,KAAK,CAAC,OAAO,EAAE;IACjB,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,UAAU,EAAC;GACjD,MAAM;IACL,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,UAAU,EAAC;IAChD,IAAI,KAAK,CAAC,IAAI,IAAE,KAAK,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,SAAS,GAAG,CAAC,GAAG,CAAC,IAAC;GACpF;EACD,KAAK,GAAG,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,KAAK,EAAE,EAAC;EAC5D,OAAO,KAAK,IAAI,KAAK,CAAC,QAAQ;CAC/B;;AAED,SAAS,SAAS,CAAC,OAAO,EAAE,KAAK,EAAE;EACjC,KAAKA,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,IAAE,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,UAAO;EACnE,OAAO,OAAO,CAAC,SAAS;CACzB;;;;;;;;;;;;;;;;;AAiBD,SAAS,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE;EAChCA,IAAI,QAAQ,GAAG,IAAI,QAAQ,CAAC,KAAK,EAAC;EAClC,KAAKA,IAAI,IAAI,GAAG,CAAC,EAAE,KAAK,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE;IAClDA,IAAI,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,EAAC;IACpF,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,IAAE,IAAI,GAAG,IAAC;IACvD,KAAK,GAAG,MAAK;GACd;EACD,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,IAAE,QAAQ,CAAC,SAAS,KAAE;EACjD,OAAO,QAAQ,CAAC,MAAM;CACvB;;;;;AAKD,IAAM,QAAQ,GACZ,iBAAW,CAAC,IAAI,EAAE;;EAEhB,IAAI,CAAC,IAAI,GAAG,GAAE;EACd,KAAKA,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;IACtC,IAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAC;IAC5E,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAC,MAAM,SAAE,KAAK,EAAE,OAAO,EAAEK,yBAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAC;GAC/F;EACD,IAAI,CAAC,MAAM,GAAG,GAAE;EACjB;;;;;;;;;AASH,mBAAE,kCAAW,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE;EACrD,IAAI,SAAS,GAAG,CAAC,EAAE;IACjBL,IAAI,KAAK,GAAG,QAAQ,CAAC,WAAU;IACjC,IAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC;gCACzC,OAAO,IAAI,QAAQ,CAAC,UAAU,IAAI,CAAC,GAAG,OAAO,GAAG,CAAC,GAAG,CAAC;gCACvD,IAAM,EAAE,KAAK,EAAC;IAC1C,IAAM,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,EAAE;MAClC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE;QACtB,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAC;QAC9D,SAAS,GAAG,KAAK,CAAC,SAAS,GAAG,EAAC;OAChC,MAAM;QACP,IAAM,QAAQ,CAAC,UAAU,IAAI,CAAC,IAAE,OAAO,GAAG,IAAC;QACzC,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC,EAAC;QACnC,SAAW,GAAG,EAAC;OACd;KACF;GACF;EACDA,IAAI,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAC;EAC1E,IAAI,IAAI,GAAG,CAAC,IAAI,MAAM,CAAC,IAAI,IAAI,SAAS,IAAI,CAAC,EAAE;IAC7CA,IAAI,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,IAAI,EAAC;IAChF,IAAM,CAAC,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,OAAO,IAAI,MAAM,GAAG,OAAO,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,KAAK,EAAC;IACvF,MAAQ,GAAG,MAAM,GAAGK,yBAAQ,CAAC,KAAK,GAAG,IAAIF,sBAAK,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAC;GACvF;EACD,OAAO,MAAM;EACd;;AAEH,mBAAE,sCAAa,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE;EACvDH,IAAI,CAAC,GAAG,EAAC;;EAEX,OAAS,CAAC,GAAG,QAAQ,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE;IACrC,IAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,GAAG,KAAK,EAAE,IAAI,GAAG,CAAC,IAAI,QAAQ,CAAC,UAAU,GAAG,EAAC;;IAElF,KAAKA,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;MAChD,IAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,gBAAI;;;;;MAK7B,IAAI,IAAI,GAAG,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;UAC1D,EAAI,MAAM,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE;QACpE,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,IAAE,IAAI,CAAC,SAAS,KAAE;QACjD,KAAKA,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;UACpC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAC;UAC1C,CAAC,GAAE;UACL,IAAM,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE;kBACxB,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY;kBAC3B,OAAO,EAAEK,yBAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,EAAC;UACzE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAC;SACrB;OACF;;;MAGDL,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAC;MAC9C,IAAM,CAAC,KAAK,EAAE;QACVA,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAACK,yBAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAC;QACxD,IAAM,IAAI,EAAE;UACR,KAAKL,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE;YAC1C,IAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAC;YACxB,IAAM,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,EAAC;YAC3B,KAAO,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,EAAC;WACrC;SACF,MAAM,IAAI,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;;;UAGtD,KAAK;SACN,MAAM;UACL,QAAQ;SACT;OACF;;;;MAID,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,IAAE,IAAI,CAAC,SAAS,KAAE;;MAEjD,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,EAAC;MAChE,IAAM,SAAS,EAAE;QACb,KAAK,GAAG,cAAc,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,GAAG,OAAO,GAAG,CAAC,EAAC;QAC9D,SAAW,GAAG,EAAC;OACd;;MAED,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,GAAG,OAAO,GAAG,CAAC,EAAC;MAC7C,IAAI,CAAC,KAAK,GAAG,MAAK;MAClB,IAAI,IAAI,IAAE,OAAO,GAAG,IAAC;MACvB,MAAQ,GAAG,KAAI;MACb,KAAK;KACN;;;IAGD,IAAI,CAAC,MAAM,IAAE,OAAK;GACnB;;;;EAID,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;OACnB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,UAAU;OACnC,MAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC;IAC1E,EAAE,IAAI,CAAC,SAAS,KAAE;;EAElB,OAAO,IAAIG,sBAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC;EAC7D;;AAEH,mBAAE,4BAAQ,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE;EAC3B,IAAI,CAAC,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAC;EAC1E,IAAI,CAAC,OAAO,GAAG,QAAO;EACvB;;AAEH,mBAAE,kCAAY;EACZ,IAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,GAAE;EAC5B,IAAM,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,EAAE,CAE3B,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE;IACvB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO,GAAG,CAAC,EAAC;GAChG,MAAM;IACP,IAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAC;GAC5F;CACF,CACF;;AAED,SAAS,cAAc,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE;EAChDH,IAAI,OAAO,GAAG,IAAI,CAAC,QAAO;EAC1B,IAAI,SAAS,GAAG,CAAC,EAAE;IACjBA,IAAI,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,GAAG,CAAC,EAAE,IAAI,CAAC,UAAU,IAAI,CAAC,GAAG,OAAO,GAAG,CAAC,GAAG,CAAC,EAAC;IAClG,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,EAAE,KAAK,EAAC;GAC9C;EACDA,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,IAAI,CAAC,EAAC;EACnE,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;CACvC;;AAED,SAAS,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE;EACjCA,IAAI,OAAO,GAAG,IAAI,CAAC,QAAO;EAC1B,IAAI,KAAK,GAAG,CAAC,EAAE;IACbA,IAAI,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,GAAG,CAAC,EAAC;IAClD,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,EAAE,IAAI,EAAC;GAC/D;EACDA,IAAI,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,UAAU,CAACK,yBAAQ,CAAC,KAAK,EAAE,IAAI,EAAC;EAChF,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;CACvC;;AAED,SAAS,gBAAgB,CAAC,QAAQ,EAAE,KAAK,EAAE;EACzC,OAAO,KAAK,GAAG,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC,UAAU,GAAG,CAAC,EAAE,YAAY,CAAC,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,GAAG,QAAQ;CAClH;;;;;;;;;;;;;;;;;;AAkBD,SAAS,CAAC,SAAS,CAAC,YAAY,GAAG,SAAS,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE;EAC3D,IAAI,CAAC,KAAK,CAAC,IAAI,IAAE,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,GAAC;;EAElDL,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAC;EAC9D,IAAI,aAAa,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC;MAClC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,CAAC,GAAC;;EAEpDA,IAAI,YAAY,GAAG,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,EAAC;;EAE7D,IAAI,YAAY,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,IAAE,YAAY,CAAC,GAAG,KAAE;;;EAGlEA,IAAI,eAAe,GAAG,EAAE,KAAK,CAAC,KAAK,GAAG,CAAC,EAAC;EACxC,YAAY,CAAC,OAAO,CAAC,eAAe,EAAC;;;;;EAKrC,KAAKA,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,EAAE,GAAG,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE;IAChEA,IAAI,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAI;IAClC,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,SAAS,IAAE,OAAK;IAC1C,IAAI,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAE,eAAe,GAAG,IAAC;SAChD,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,IAAE,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAC;GAC/D;;;EAGDA,IAAI,oBAAoB,GAAG,YAAY,CAAC,OAAO,CAAC,eAAe,EAAC;;EAEhEA,IAAI,SAAS,GAAG,EAAE,EAAE,cAAc,GAAG,KAAK,CAAC,UAAS;EACpD,KAAKA,IAAI,OAAO,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE;IAC7CA,IAAI,IAAI,GAAG,OAAO,CAAC,WAAU;IAC7B,SAAS,CAAC,IAAI,CAAC,IAAI,EAAC;IACpB,IAAI,CAAC,IAAI,KAAK,CAAC,SAAS,IAAE,OAAK;IAC/B,OAAO,GAAG,IAAI,CAAC,QAAO;GACvB;;;EAGD,IAAI,cAAc,GAAG,CAAC,IAAI,SAAS,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ;MACtE,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,IAAI,IAAI,SAAS,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,IAAI;MAC7E,cAAc,IAAI,IAAC;OAChB,IAAI,cAAc,IAAI,CAAC,IAAI,SAAS,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,WAAW,IAAI,SAAS,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ;WACpH,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,IAAI,IAAI,SAAS,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,IAAI;MAClF,cAAc,IAAI,IAAC;;EAErB,KAAKA,IAAI,CAAC,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;IACzCA,IAAI,SAAS,GAAG,CAAC,CAAC,GAAG,cAAc,GAAG,CAAC,KAAK,KAAK,CAAC,SAAS,GAAG,CAAC,EAAC;IAChEA,IAAI,MAAM,GAAG,SAAS,CAAC,SAAS,EAAC;IACjC,IAAI,CAAC,MAAM,IAAE,UAAQ;IACrB,KAAKA,IAAIY,GAAC,GAAG,CAAC,EAAEA,GAAC,GAAG,YAAY,CAAC,MAAM,EAAEA,GAAC,EAAE,EAAE;;;MAG5CZ,IAAI,WAAW,GAAG,YAAY,CAAC,CAACY,GAAC,GAAG,oBAAoB,IAAI,YAAY,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,KAAI;MAC/F,IAAI,WAAW,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,WAAW,GAAG,CAAC,YAAW,EAAE;MACnEZ,IAAI,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,EAAC;MAC9E,IAAI,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC;UAChE,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;4BAC/D,IAAIG,sBAAK,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,SAAS,EAAE,SAAS,CAAC;sCAC3D,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,GAAC;KAC3D;GACF;;EAEDH,IAAI,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,OAAM;EAClC,KAAKA,IAAIY,GAAC,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,EAAEA,GAAC,IAAI,CAAC,EAAEA,GAAC,EAAE,EAAE;IACjD,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,EAAC;IAC7B,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,UAAU,IAAE,OAAK;IACzCZ,IAAI,KAAK,GAAG,YAAY,CAACY,GAAC,EAAC;IAC3B,IAAIA,GAAC,GAAG,CAAC,IAAE,UAAQ;IACnB,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,EAAC;GAClD;EACD,OAAO,IAAI;EACZ;;AAED,SAAS,aAAa,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE;EAChE,IAAI,KAAK,GAAG,OAAO,EAAE;IACnBZ,IAAI,KAAK,GAAG,QAAQ,CAAC,WAAU;IAC/B,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,GAAG,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,EAAC;GAClH;EACD,IAAI,KAAK,GAAG,OAAO,EAAE;IACnBA,IAAI,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC,EAAC;IACpCA,IAAI,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAC;IACvD,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,UAAU,CAACK,yBAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,EAAC;GACrF;EACD,OAAO,QAAQ;CAChB;;;;;;;;;;AAUD,SAAS,CAAC,SAAS,CAAC,gBAAgB,GAAG,SAAS,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE;EAC9D,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE;IAC9EL,IAAI,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAC;IAClD,IAAI,KAAK,IAAI,IAAI,IAAE,IAAI,GAAG,EAAE,GAAG,QAAK;GACrC;EACD,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,EAAE,EAAE,IAAIG,sBAAK,CAACE,yBAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;EACzE;;;;;AAKD,SAAS,CAAC,SAAS,CAAC,WAAW,GAAG,SAAS,IAAI,EAAE,EAAE,EAAE;EACnDL,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAC;EAC9DA,IAAI,OAAO,GAAG,aAAa,CAAC,KAAK,EAAE,GAAG,EAAC;EACvC,KAAKA,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;IACvCA,IAAI,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,EAAC;IACtD,IAAI,CAAC,IAAI,IAAI,KAAK,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ;QACtE,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,GAAC;IACxD,IAAI,KAAK,GAAG,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;QAC5G,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAC;GAC5D;EACD,KAAKA,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;IACrC,IAAI,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,GAAG,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,GAAG,CAAC,KAAK,GAAG,CAAC;QACnG,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,GAAC;GAC1C;EACD,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;EAC7B;;;;;AAKD,SAAS,aAAa,CAAC,KAAK,EAAE,GAAG,EAAE;EACjCA,IAAI,MAAM,GAAG,EAAE,EAAE,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,EAAC;EAC5D,KAAKA,IAAI,CAAC,GAAG,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;IAClCA,IAAI,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAC;IAC1B,IAAI,KAAK,GAAG,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC;QACrC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC;QACtC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS;QACjC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,IAAE,OAAK;IAC1C,IAAI,KAAK,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAE,MAAM,CAAC,IAAI,CAAC,CAAC,IAAC;GAC1C;EACD,OAAO,MAAM;CACd;;;;;;;;;;;;;;;;;;;;;;"} \ No newline at end of file diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/package.json b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/package.json new file mode 100644 index 0000000000..477e59efdd --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/package.json @@ -0,0 +1,35 @@ +{ + "name": "prosemirror-transform", + "version": "1.2.2", + "description": "ProseMirror document transformations", + "main": "dist/index.js", + "module": "dist/index.es.js", + "license": "MIT", + "maintainers": [ + { + "name": "Marijn Haverbeke", + "email": "marijnh@gmail.com", + "web": "http://marijnhaverbeke.nl" + } + ], + "repository": { + "type": "git", + "url": "git://github.com/prosemirror/prosemirror-transform.git" + }, + "dependencies": { + "prosemirror-model": "^1.0.0" + }, + "devDependencies": { + "mocha": "^3.0.2", + "ist": "^1.0.0", + "prosemirror-test-builder": "^1.0.0", + "rollup": "^1.26.3", + "@rollup/plugin-buble": "^0.20.0" + }, + "scripts": { + "test": "mocha test/test-*.js", + "build": "rollup -c", + "watch": "rollup -c -w", + "prepare": "npm run build" + } +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/rollup.config.js b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/rollup.config.js new file mode 100644 index 0000000000..156b12a278 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/rollup.config.js @@ -0,0 +1,14 @@ +module.exports = { + input: './src/index.js', + output: [{ + file: 'dist/index.js', + format: 'cjs', + sourcemap: true + }, { + file: 'dist/index.es.js', + format: 'es', + sourcemap: true + }], + plugins: [require('@rollup/plugin-buble')()], + external(id) { return !/^[\.\/]/.test(id) } +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/README.md b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/README.md new file mode 100644 index 0000000000..757498cbd7 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/README.md @@ -0,0 +1,55 @@ +This module defines a way of modifying documents that allows changes +to be recorded, replayed, and reordered. You can read more about +transformations in [the guide](/docs/guide/#transform). + +### Steps + +Transforming happens in `Step`s, which are atomic, well-defined +modifications to a document. [Applying](#transform.Step.apply) a step +produces a new document. + +Each step provides a [change map](#transform.StepMap) that maps +positions in the old document to position in the transformed document. +Steps can be [inverted](#transform.Step.invert) to create a step that +undoes their effect, and chained together in a convenience object +called a [`Transform`](#transform.Transform). + +@Step +@StepResult +@ReplaceStep +@ReplaceAroundStep +@AddMarkStep +@RemoveMarkStep + +### Position Mapping + +Mapping positions from one document to another by running through the +[step maps](#transform.StepMap) produced by steps is an important +operation in ProseMirror. It is used, for example, for updating the +selection when the document changes. + +@Mappable +@MapResult +@StepMap +@Mapping + +### Document transforms + +Because you often need to collect a number of steps together to effect +a composite change, ProseMirror provides an abstraction to make this +easy. [State transactions](#state.Transaction) are a subclass of +transforms. + +@Transform + +The following helper functions can be useful when creating +transformations or determining whether they are even possible. + +@replaceStep +@liftTarget +@findWrapping +@canSplit +@canJoin +@joinPoint +@insertPoint +@dropPoint diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/index.js b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/index.js new file mode 100644 index 0000000000..b870143729 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/index.js @@ -0,0 +1,8 @@ +export {Transform, TransformError} from "./transform" +export {Step, StepResult} from "./step" +export {joinPoint, canJoin, canSplit, insertPoint, dropPoint, liftTarget, findWrapping} from "./structure" +export {StepMap, MapResult, Mapping} from "./map" +export {AddMarkStep, RemoveMarkStep} from "./mark_step" +export {ReplaceStep, ReplaceAroundStep} from "./replace_step" +import "./mark" +export {replaceStep} from "./replace" diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/map.js b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/map.js new file mode 100644 index 0000000000..257cb0a2ea --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/map.js @@ -0,0 +1,271 @@ +// Mappable:: interface +// There are several things that positions can be mapped through. +// Such objects conform to this interface. +// +// map:: (pos: number, assoc: ?number) → number +// Map a position through this object. When given, `assoc` (should +// be -1 or 1, defaults to 1) determines with which side the +// position is associated, which determines in which direction to +// move when a chunk of content is inserted at the mapped position. +// +// mapResult:: (pos: number, assoc: ?number) → MapResult +// Map a position, and return an object containing additional +// information about the mapping. The result's `deleted` field tells +// you whether the position was deleted (completely enclosed in a +// replaced range) during the mapping. When content on only one side +// is deleted, the position itself is only considered deleted when +// `assoc` points in the direction of the deleted content. + +// Recovery values encode a range index and an offset. They are +// represented as numbers, because tons of them will be created when +// mapping, for example, a large number of decorations. The number's +// lower 16 bits provide the index, the remaining bits the offset. +// +// Note: We intentionally don't use bit shift operators to en- and +// decode these, since those clip to 32 bits, which we might in rare +// cases want to overflow. A 64-bit float can represent 48-bit +// integers precisely. + +const lower16 = 0xffff +const factor16 = Math.pow(2, 16) + +function makeRecover(index, offset) { return index + offset * factor16 } +function recoverIndex(value) { return value & lower16 } +function recoverOffset(value) { return (value - (value & lower16)) / factor16 } + +// ::- An object representing a mapped position with extra +// information. +export class MapResult { + constructor(pos, deleted = false, recover = null) { + // :: number The mapped version of the position. + this.pos = pos + // :: bool Tells you whether the position was deleted, that is, + // whether the step removed its surroundings from the document. + this.deleted = deleted + this.recover = recover + } +} + +// :: class extends Mappable +// A map describing the deletions and insertions made by a step, which +// can be used to find the correspondence between positions in the +// pre-step version of a document and the same position in the +// post-step version. +export class StepMap { + // :: ([number]) + // Create a position map. The modifications to the document are + // represented as an array of numbers, in which each group of three + // represents a modified chunk as `[start, oldSize, newSize]`. + constructor(ranges, inverted = false) { + this.ranges = ranges + this.inverted = inverted + } + + recover(value) { + let diff = 0, index = recoverIndex(value) + if (!this.inverted) for (let i = 0; i < index; i++) + diff += this.ranges[i * 3 + 2] - this.ranges[i * 3 + 1] + return this.ranges[index * 3] + diff + recoverOffset(value) + } + + // : (number, ?number) → MapResult + mapResult(pos, assoc = 1) { return this._map(pos, assoc, false) } + + // : (number, ?number) → number + map(pos, assoc = 1) { return this._map(pos, assoc, true) } + + _map(pos, assoc, simple) { + let diff = 0, oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2 + for (let i = 0; i < this.ranges.length; i += 3) { + let start = this.ranges[i] - (this.inverted ? diff : 0) + if (start > pos) break + let oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex], end = start + oldSize + if (pos <= end) { + let side = !oldSize ? assoc : pos == start ? -1 : pos == end ? 1 : assoc + let result = start + diff + (side < 0 ? 0 : newSize) + if (simple) return result + let recover = makeRecover(i / 3, pos - start) + return new MapResult(result, assoc < 0 ? pos != start : pos != end, recover) + } + diff += newSize - oldSize + } + return simple ? pos + diff : new MapResult(pos + diff) + } + + touches(pos, recover) { + let diff = 0, index = recoverIndex(recover) + let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2 + for (let i = 0; i < this.ranges.length; i += 3) { + let start = this.ranges[i] - (this.inverted ? diff : 0) + if (start > pos) break + let oldSize = this.ranges[i + oldIndex], end = start + oldSize + if (pos <= end && i == index * 3) return true + diff += this.ranges[i + newIndex] - oldSize + } + return false + } + + // :: ((oldStart: number, oldEnd: number, newStart: number, newEnd: number)) + // Calls the given function on each of the changed ranges included in + // this map. + forEach(f) { + let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2 + for (let i = 0, diff = 0; i < this.ranges.length; i += 3) { + let start = this.ranges[i], oldStart = start - (this.inverted ? diff : 0), newStart = start + (this.inverted ? 0 : diff) + let oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex] + f(oldStart, oldStart + oldSize, newStart, newStart + newSize) + diff += newSize - oldSize + } + } + + // :: () → StepMap + // Create an inverted version of this map. The result can be used to + // map positions in the post-step document to the pre-step document. + invert() { + return new StepMap(this.ranges, !this.inverted) + } + + toString() { + return (this.inverted ? "-" : "") + JSON.stringify(this.ranges) + } + + // :: (n: number) → StepMap + // Create a map that moves all positions by offset `n` (which may be + // negative). This can be useful when applying steps meant for a + // sub-document to a larger document, or vice-versa. + static offset(n) { + return n == 0 ? StepMap.empty : new StepMap(n < 0 ? [0, -n, 0] : [0, 0, n]) + } +} + +StepMap.empty = new StepMap([]) + +// :: class extends Mappable +// A mapping represents a pipeline of zero or more [step +// maps](#transform.StepMap). It has special provisions for losslessly +// handling mapping positions through a series of steps in which some +// steps are inverted versions of earlier steps. (This comes up when +// ‘[rebasing](/docs/guide/#transform.rebasing)’ steps for +// collaboration or history management.) +export class Mapping { + // :: (?[StepMap]) + // Create a new mapping with the given position maps. + constructor(maps, mirror, from, to) { + // :: [StepMap] + // The step maps in this mapping. + this.maps = maps || [] + // :: number + // The starting position in the `maps` array, used when `map` or + // `mapResult` is called. + this.from = from || 0 + // :: number + // The end position in the `maps` array. + this.to = to == null ? this.maps.length : to + this.mirror = mirror + } + + // :: (?number, ?number) → Mapping + // Create a mapping that maps only through a part of this one. + slice(from = 0, to = this.maps.length) { + return new Mapping(this.maps, this.mirror, from, to) + } + + copy() { + return new Mapping(this.maps.slice(), this.mirror && this.mirror.slice(), this.from, this.to) + } + + // :: (StepMap, ?number) + // Add a step map to the end of this mapping. If `mirrors` is + // given, it should be the index of the step map that is the mirror + // image of this one. + appendMap(map, mirrors) { + this.to = this.maps.push(map) + if (mirrors != null) this.setMirror(this.maps.length - 1, mirrors) + } + + // :: (Mapping) + // Add all the step maps in a given mapping to this one (preserving + // mirroring information). + appendMapping(mapping) { + for (let i = 0, startSize = this.maps.length; i < mapping.maps.length; i++) { + let mirr = mapping.getMirror(i) + this.appendMap(mapping.maps[i], mirr != null && mirr < i ? startSize + mirr : null) + } + } + + // :: (number) → ?number + // Finds the offset of the step map that mirrors the map at the + // given offset, in this mapping (as per the second argument to + // `appendMap`). + getMirror(n) { + if (this.mirror) for (let i = 0; i < this.mirror.length; i++) + if (this.mirror[i] == n) return this.mirror[i + (i % 2 ? -1 : 1)] + } + + setMirror(n, m) { + if (!this.mirror) this.mirror = [] + this.mirror.push(n, m) + } + + // :: (Mapping) + // Append the inverse of the given mapping to this one. + appendMappingInverted(mapping) { + for (let i = mapping.maps.length - 1, totalSize = this.maps.length + mapping.maps.length; i >= 0; i--) { + let mirr = mapping.getMirror(i) + this.appendMap(mapping.maps[i].invert(), mirr != null && mirr > i ? totalSize - mirr - 1 : null) + } + } + + // :: () → Mapping + // Create an inverted version of this mapping. + invert() { + let inverse = new Mapping + inverse.appendMappingInverted(this) + return inverse + } + + // : (number, ?number) → number + // Map a position through this mapping. + map(pos, assoc = 1) { + if (this.mirror) return this._map(pos, assoc, true) + for (let i = this.from; i < this.to; i++) + pos = this.maps[i].map(pos, assoc) + return pos + } + + // : (number, ?number) → MapResult + // Map a position through this mapping, returning a mapping + // result. + mapResult(pos, assoc = 1) { return this._map(pos, assoc, false) } + + _map(pos, assoc, simple) { + let deleted = false, recoverables = null + + for (let i = this.from; i < this.to; i++) { + let map = this.maps[i], rec = recoverables && recoverables[i] + if (rec != null && map.touches(pos, rec)) { + pos = map.recover(rec) + continue + } + + let result = map.mapResult(pos, assoc) + if (result.recover != null) { + let corr = this.getMirror(i) + if (corr != null && corr > i && corr < this.to) { + if (result.deleted) { + i = corr + pos = this.maps[corr].recover(result.recover) + continue + } else { + ;(recoverables || (recoverables = Object.create(null)))[corr] = result.recover + } + } + } + + if (result.deleted) deleted = true + pos = result.pos + } + + return simple ? pos : new MapResult(pos, deleted) + } +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/mark.js b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/mark.js new file mode 100644 index 0000000000..2cdbccb5b0 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/mark.js @@ -0,0 +1,105 @@ +import {MarkType, Slice, Fragment} from "prosemirror-model" + +import {Transform} from "./transform" +import {AddMarkStep, RemoveMarkStep} from "./mark_step" +import {ReplaceStep} from "./replace_step" + +// :: (number, number, Mark) → this +// Add the given mark to the inline content between `from` and `to`. +Transform.prototype.addMark = function(from, to, mark) { + let removed = [], added = [], removing = null, adding = null + this.doc.nodesBetween(from, to, (node, pos, parent) => { + if (!node.isInline) return + let marks = node.marks + if (!mark.isInSet(marks) && parent.type.allowsMarkType(mark.type)) { + let start = Math.max(pos, from), end = Math.min(pos + node.nodeSize, to) + let newSet = mark.addToSet(marks) + + for (let i = 0; i < marks.length; i++) { + if (!marks[i].isInSet(newSet)) { + if (removing && removing.to == start && removing.mark.eq(marks[i])) + removing.to = end + else + removed.push(removing = new RemoveMarkStep(start, end, marks[i])) + } + } + + if (adding && adding.to == start) + adding.to = end + else + added.push(adding = new AddMarkStep(start, end, mark)) + } + }) + + removed.forEach(s => this.step(s)) + added.forEach(s => this.step(s)) + return this +} + +// :: (number, number, ?union) → this +// Remove marks from inline nodes between `from` and `to`. When `mark` +// is a single mark, remove precisely that mark. When it is a mark type, +// remove all marks of that type. When it is null, remove all marks of +// any type. +Transform.prototype.removeMark = function(from, to, mark = null) { + let matched = [], step = 0 + this.doc.nodesBetween(from, to, (node, pos) => { + if (!node.isInline) return + step++ + let toRemove = null + if (mark instanceof MarkType) { + let found = mark.isInSet(node.marks) + if (found) toRemove = [found] + } else if (mark) { + if (mark.isInSet(node.marks)) toRemove = [mark] + } else { + toRemove = node.marks + } + if (toRemove && toRemove.length) { + let end = Math.min(pos + node.nodeSize, to) + for (let i = 0; i < toRemove.length; i++) { + let style = toRemove[i], found + for (let j = 0; j < matched.length; j++) { + let m = matched[j] + if (m.step == step - 1 && style.eq(matched[j].style)) found = m + } + if (found) { + found.to = end + found.step = step + } else { + matched.push({style, from: Math.max(pos, from), to: end, step}) + } + } + } + }) + matched.forEach(m => this.step(new RemoveMarkStep(m.from, m.to, m.style))) + return this +} + +// :: (number, NodeType, ?ContentMatch) → this +// Removes all marks and nodes from the content of the node at `pos` +// that don't match the given new parent node type. Accepts an +// optional starting [content match](#model.ContentMatch) as third +// argument. +Transform.prototype.clearIncompatible = function(pos, parentType, match = parentType.contentMatch) { + let node = this.doc.nodeAt(pos) + let delSteps = [], cur = pos + 1 + for (let i = 0; i < node.childCount; i++) { + let child = node.child(i), end = cur + child.nodeSize + let allowed = match.matchType(child.type, child.attrs) + if (!allowed) { + delSteps.push(new ReplaceStep(cur, end, Slice.empty)) + } else { + match = allowed + for (let j = 0; j < child.marks.length; j++) if (!parentType.allowsMarkType(child.marks[j].type)) + this.step(new RemoveMarkStep(cur, end, child.marks[j])) + } + cur = end + } + if (!match.validEnd) { + let fill = match.fillBefore(Fragment.empty, true) + this.replace(cur, cur, new Slice(fill, 0, 0)) + } + for (let i = delSteps.length - 1; i >= 0; i--) this.step(delSteps[i]) + return this +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/mark_step.js b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/mark_step.js new file mode 100644 index 0000000000..76d7533753 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/mark_step.js @@ -0,0 +1,115 @@ +import {Fragment, Slice} from "prosemirror-model" +import {Step, StepResult} from "./step" + +function mapFragment(fragment, f, parent) { + let mapped = [] + for (let i = 0; i < fragment.childCount; i++) { + let child = fragment.child(i) + if (child.content.size) child = child.copy(mapFragment(child.content, f, child)) + if (child.isInline) child = f(child, parent, i) + mapped.push(child) + } + return Fragment.fromArray(mapped) +} + +// ::- Add a mark to all inline content between two positions. +export class AddMarkStep extends Step { + // :: (number, number, Mark) + constructor(from, to, mark) { + super() + this.from = from + this.to = to + this.mark = mark + } + + apply(doc) { + let oldSlice = doc.slice(this.from, this.to), $from = doc.resolve(this.from) + let parent = $from.node($from.sharedDepth(this.to)) + let slice = new Slice(mapFragment(oldSlice.content, (node, parent) => { + if (!parent.type.allowsMarkType(this.mark.type)) return node + return node.mark(this.mark.addToSet(node.marks)) + }, parent), oldSlice.openStart, oldSlice.openEnd) + return StepResult.fromReplace(doc, this.from, this.to, slice) + } + + invert() { + return new RemoveMarkStep(this.from, this.to, this.mark) + } + + map(mapping) { + let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1) + if (from.deleted && to.deleted || from.pos >= to.pos) return null + return new AddMarkStep(from.pos, to.pos, this.mark) + } + + merge(other) { + if (other instanceof AddMarkStep && + other.mark.eq(this.mark) && + this.from <= other.to && this.to >= other.from) + return new AddMarkStep(Math.min(this.from, other.from), + Math.max(this.to, other.to), this.mark) + } + + toJSON() { + return {stepType: "addMark", mark: this.mark.toJSON(), + from: this.from, to: this.to} + } + + static fromJSON(schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + throw new RangeError("Invalid input for AddMarkStep.fromJSON") + return new AddMarkStep(json.from, json.to, schema.markFromJSON(json.mark)) + } +} + +Step.jsonID("addMark", AddMarkStep) + +// ::- Remove a mark from all inline content between two positions. +export class RemoveMarkStep extends Step { + // :: (number, number, Mark) + constructor(from, to, mark) { + super() + this.from = from + this.to = to + this.mark = mark + } + + apply(doc) { + let oldSlice = doc.slice(this.from, this.to) + let slice = new Slice(mapFragment(oldSlice.content, node => { + return node.mark(this.mark.removeFromSet(node.marks)) + }), oldSlice.openStart, oldSlice.openEnd) + return StepResult.fromReplace(doc, this.from, this.to, slice) + } + + invert() { + return new AddMarkStep(this.from, this.to, this.mark) + } + + map(mapping) { + let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1) + if (from.deleted && to.deleted || from.pos >= to.pos) return null + return new RemoveMarkStep(from.pos, to.pos, this.mark) + } + + merge(other) { + if (other instanceof RemoveMarkStep && + other.mark.eq(this.mark) && + this.from <= other.to && this.to >= other.from) + return new RemoveMarkStep(Math.min(this.from, other.from), + Math.max(this.to, other.to), this.mark) + } + + toJSON() { + return {stepType: "removeMark", mark: this.mark.toJSON(), + from: this.from, to: this.to} + } + + static fromJSON(schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + throw new RangeError("Invalid input for RemoveMarkStep.fromJSON") + return new RemoveMarkStep(json.from, json.to, schema.markFromJSON(json.mark)) + } +} + +Step.jsonID("removeMark", RemoveMarkStep) diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/replace.js b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/replace.js new file mode 100644 index 0000000000..8e0643c377 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/replace.js @@ -0,0 +1,550 @@ +import {Fragment, Slice} from "prosemirror-model" + +import {ReplaceStep, ReplaceAroundStep} from "./replace_step" +import {Transform} from "./transform" +import {insertPoint} from "./structure" + +// :: (Node, number, ?number, ?Slice) → ?Step +// ‘Fit’ a slice into a given position in the document, producing a +// [step](#transform.Step) that inserts it. Will return null if +// there's no meaningful way to insert the slice here, or inserting it +// would be a no-op (an empty slice over an empty range). +export function replaceStep(doc, from, to = from, slice = Slice.empty) { + if (from == to && !slice.size) return null + + let $from = doc.resolve(from), $to = doc.resolve(to) + // Optimization -- avoid work if it's obvious that it's not needed. + if (fitsTrivially($from, $to, slice)) return new ReplaceStep(from, to, slice) + let placed = placeSlice($from, slice) + + let fittedLeft = fitLeft($from, placed) + let fitted = fitRight($from, $to, fittedLeft) + if (!fitted) return null + if (fittedLeft.size != fitted.size && canMoveText($from, $to, fittedLeft)) { + let d = $to.depth, after = $to.after(d) + while (d > 1 && after == $to.end(--d)) ++after + let fittedAfter = fitRight($from, doc.resolve(after), fittedLeft) + if (fittedAfter) + return new ReplaceAroundStep(from, after, to, $to.end(), fittedAfter, fittedLeft.size) + } + return fitted.size || from != to ? new ReplaceStep(from, to, fitted) : null +} + +// :: (number, ?number, ?Slice) → this +// Replace the part of the document between `from` and `to` with the +// given `slice`. +Transform.prototype.replace = function(from, to = from, slice = Slice.empty) { + let step = replaceStep(this.doc, from, to, slice) + if (step) this.step(step) + return this +} + +// :: (number, number, union) → this +// Replace the given range with the given content, which may be a +// fragment, node, or array of nodes. +Transform.prototype.replaceWith = function(from, to, content) { + return this.replace(from, to, new Slice(Fragment.from(content), 0, 0)) +} + +// :: (number, number) → this +// Delete the content between the given positions. +Transform.prototype.delete = function(from, to) { + return this.replace(from, to, Slice.empty) +} + +// :: (number, union) → this +// Insert the given content at the given position. +Transform.prototype.insert = function(pos, content) { + return this.replaceWith(pos, pos, content) +} + + + +function fitLeftInner($from, depth, placed, placedBelow) { + let content = Fragment.empty, openEnd = 0, placedHere = placed[depth] + if ($from.depth > depth) { + let inner = fitLeftInner($from, depth + 1, placed, placedBelow || placedHere) + openEnd = inner.openEnd + 1 + content = Fragment.from($from.node(depth + 1).copy(inner.content)) + } + + if (placedHere) { + content = content.append(placedHere.content) + openEnd = placedHere.openEnd + } + if (placedBelow) { + content = content.append($from.node(depth).contentMatchAt($from.indexAfter(depth)).fillBefore(Fragment.empty, true)) + openEnd = 0 + } + + return {content, openEnd} +} + +function fitLeft($from, placed) { + let {content, openEnd} = fitLeftInner($from, 0, placed, false) + return new Slice(content, $from.depth, openEnd || 0) +} + +function fitRightJoin(content, parent, $from, $to, depth, openStart, openEnd) { + let match, count = content.childCount, matchCount = count - (openEnd > 0 ? 1 : 0) + let parentNode = openStart < 0 ? parent : $from.node(depth) + if (openStart < 0) + match = parentNode.contentMatchAt(matchCount) + else if (count == 1 && openEnd > 0) + match = parentNode.contentMatchAt(openStart ? $from.index(depth) : $from.indexAfter(depth)) + else + match = parentNode.contentMatchAt($from.indexAfter(depth)) + .matchFragment(content, count > 0 && openStart ? 1 : 0, matchCount) + + let toNode = $to.node(depth) + if (openEnd > 0 && depth < $to.depth) { + let after = toNode.content.cutByIndex($to.indexAfter(depth)).addToStart(content.lastChild) + let joinable = match.fillBefore(after, true) + // Can't insert content if there's a single node stretched across this gap + if (joinable && joinable.size && openStart > 0 && count == 1) joinable = null + + if (joinable) { + let inner = fitRightJoin(content.lastChild.content, content.lastChild, $from, $to, + depth + 1, count == 1 ? openStart - 1 : -1, openEnd - 1) + if (inner) { + let last = content.lastChild.copy(inner) + if (joinable.size) + return content.cutByIndex(0, count - 1).append(joinable).addToEnd(last) + else + return content.replaceChild(count - 1, last) + } + } + } + if (openEnd > 0) + match = match.matchType((count == 1 && openStart > 0 ? $from.node(depth + 1) : content.lastChild).type) + + // If we're here, the next level can't be joined, so we see what + // happens if we leave it open. + let toIndex = $to.index(depth) + if (toIndex == toNode.childCount && !toNode.type.compatibleContent(parent.type)) return null + let joinable = match.fillBefore(toNode.content, true, toIndex) + for (let i = toIndex; joinable && i < toNode.content.childCount; i++) + if (!parentNode.type.allowsMarks(toNode.content.child(i).marks)) joinable = null + if (!joinable) return null + + if (openEnd > 0) { + let closed = fitRightClosed(content.lastChild, openEnd - 1, $from, depth + 1, + count == 1 ? openStart - 1 : -1) + content = content.replaceChild(count - 1, closed) + } + content = content.append(joinable) + if ($to.depth > depth) + content = content.addToEnd(fitRightSeparate($to, depth + 1)) + return content +} + +function fitRightClosed(node, openEnd, $from, depth, openStart) { + let match, content = node.content, count = content.childCount + if (openStart >= 0) + match = $from.node(depth).contentMatchAt($from.indexAfter(depth)) + .matchFragment(content, openStart > 0 ? 1 : 0, count) + else + match = node.contentMatchAt(count) + + if (openEnd > 0) { + let closed = fitRightClosed(content.lastChild, openEnd - 1, $from, depth + 1, + count == 1 ? openStart - 1 : -1) + content = content.replaceChild(count - 1, closed) + } + + return node.copy(content.append(match.fillBefore(Fragment.empty, true))) +} + +function fitRightSeparate($to, depth) { + let node = $to.node(depth) + let fill = node.contentMatchAt(0).fillBefore(node.content, true, $to.index(depth)) + if ($to.depth > depth) fill = fill.addToEnd(fitRightSeparate($to, depth + 1)) + return node.copy(fill) +} + +function normalizeSlice(content, openStart, openEnd) { + while (openStart > 0 && openEnd > 0 && content.childCount == 1) { + content = content.firstChild.content + openStart-- + openEnd-- + } + return new Slice(content, openStart, openEnd) +} + +// : (ResolvedPos, ResolvedPos, number, Slice) → Slice +function fitRight($from, $to, slice) { + let fitted = fitRightJoin(slice.content, $from.node(0), $from, $to, 0, slice.openStart, slice.openEnd) + if (!fitted) return null + return normalizeSlice(fitted, slice.openStart, $to.depth) +} + +function fitsTrivially($from, $to, slice) { + return !slice.openStart && !slice.openEnd && $from.start() == $to.start() && + $from.parent.canReplace($from.index(), $to.index(), slice.content) +} + +function canMoveText($from, $to, slice) { + if (!$to.parent.isTextblock) return false + + let parent = slice.openEnd ? nodeRight(slice.content, slice.openEnd) + : $from.node($from.depth - (slice.openStart - slice.openEnd)) + if (!parent.isTextblock) return false + for (let i = $to.index(); i < $to.parent.childCount; i++) + if (!parent.type.allowsMarks($to.parent.child(i).marks)) return false + let match + if (slice.openEnd) { + match = parent.contentMatchAt(parent.childCount) + } else { + match = parent.contentMatchAt(parent.childCount) + if (slice.size) match = match.matchFragment(slice.content, slice.openStart ? 1 : 0) + } + match = match.matchFragment($to.parent.content, $to.index()) + return match && match.validEnd +} + +function nodeRight(content, depth) { + for (let i = 1; i < depth; i++) content = content.lastChild.content + return content.lastChild +} + +// Algorithm for 'placing' the elements of a slice into a gap: +// +// We consider the content of each node that is open to the left to be +// independently placeable. I.e. in , when the +// paragraph on the left is open, "foo" can be placed (somewhere on +// the left side of the replacement gap) independently from p("bar"). +// +// So placeSlice splits up a slice into a number of sub-slices, +// along with information on where they can be placed on the given +// left-side edge. It works by walking the open side of the slice, +// from the inside out, and trying to find a landing spot for each +// element, by simultaneously scanning over the gap side. When no +// place is found for an open node's content, it is left in that node. + +// : (ResolvedPos, Slice) → [{content: Fragment, openEnd: number, depth: number}] +function placeSlice($from, slice) { + let frontier = new Frontier($from) + for (let pass = 1; slice.size && pass <= 3; pass++) { + let value = frontier.placeSlice(slice.content, slice.openStart, slice.openEnd, pass) + if (pass == 3 && value != slice && value.size) pass = 0 // Restart if the 3rd pass made progress but left content + slice = value + } + while (frontier.open.length) frontier.closeNode() + return frontier.placed +} + +// Helper class that models the open side of the insert position, +// keeping track of the content match and already inserted content +// at each depth. +class Frontier { + constructor($pos) { + // : [{parent: Node, match: ContentMatch, content: Fragment, wrapper: bool, openEnd: number, depth: number}] + this.open = [] + for (let d = 0; d <= $pos.depth; d++) { + let parent = $pos.node(d), match = parent.contentMatchAt($pos.indexAfter(d)) + this.open.push({parent, match, content: Fragment.empty, wrapper: false, openEnd: 0, depth: d}) + } + this.placed = [] + } + + // : (Fragment, number, number, number, ?Node) → Slice + // Tries to place the content of the given slice, and returns a + // slice containing unplaced content. + // + // pass 1: try to fit directly + // pass 2: allow wrapper nodes to be introduced + // pass 3: allow unwrapping of nodes that aren't open + placeSlice(fragment, openStart, openEnd, pass, parent) { + if (openStart > 0) { + let first = fragment.firstChild + let inner = this.placeSlice(first.content, Math.max(0, openStart - 1), + openEnd && fragment.childCount == 1 ? openEnd - 1 : 0, + pass, first) + if (inner.content != first.content) { + if (inner.content.size) { + fragment = fragment.replaceChild(0, first.copy(inner.content)) + openStart = inner.openStart + 1 + } else { + if (fragment.childCount == 1) openEnd = 0 + fragment = fragment.cutByIndex(1) + openStart = 0 + } + } + } + let result = this.placeContent(fragment, openStart, openEnd, pass, parent) + if (pass > 2 && result.size && openStart == 0) { + let child = result.content.firstChild, single = result.content.childCount == 1 + this.placeContent(child.content, 0, openEnd && single ? openEnd - 1 : 0, pass, child) + result = single ? Fragment.empty : new Slice(result.content.cutByIndex(1), 0, openEnd) + } + return result + } + + placeContent(fragment, openStart, openEnd, pass, parent) { + let i = 0 + // Go over the fragment's children + for (; i < fragment.childCount; i++) { + let child = fragment.child(i), placed = false, last = i == fragment.childCount - 1 + // Try each open node in turn, starting from the innermost + for (let d = this.open.length - 1; d >= 0; d--) { + let open = this.open[d], wrap + + // If pass > 1, it is allowed to wrap the node to help find a + // fit, so if findWrapping returns something, we add open + // nodes to the frontier for that wrapping. + if (pass > 1 && (wrap = open.match.findWrapping(child.type)) && + !(parent && wrap.length && wrap[wrap.length - 1] == parent.type)) { + while (this.open.length - 1 > d) this.closeNode() + for (let w = 0; w < wrap.length; w++) { + open.match = open.match.matchType(wrap[w]) + d++ + open = {parent: wrap[w].create(), + match: wrap[w].contentMatch, + content: Fragment.empty, wrapper: true, openEnd: 0, depth: d + w} + this.open.push(open) + } + } + + // See if the child fits here + let match = open.match.matchType(child.type) + if (!match) { + let fill = open.match.fillBefore(Fragment.from(child)) + if (fill) { + for (let j = 0; j < fill.childCount; j++) { + let ch = fill.child(j) + this.addNode(open, ch, 0) + match = open.match.matchFragment(ch) + } + } else if (parent && open.match.matchType(parent.type)) { + // Don't continue looking further up if the parent node + // would fit here. + break + } else { + continue + } + } + + // Close open nodes above this one, since we're starting to + // add to this. + while (this.open.length - 1 > d) this.closeNode() + // Strip marks from the child or close its start when necessary + child = child.mark(open.parent.type.allowedMarks(child.marks)) + if (openStart) { + child = closeNodeStart(child, openStart, last ? openEnd : 0) + openStart = 0 + } + // Add the child to this open node and adjust its metadata + this.addNode(open, child, last ? openEnd : 0) + open.match = match + if (last) openEnd = 0 + placed = true + break + } + // As soon as we've failed to place a node we stop looking at + // later nodes + if (!placed) break + } + // Close the current open node if it's not the the root and we + // either placed up to the end of the node or the the current + // slice depth's node type matches the open node's type + if (this.open.length > 1 && + (i > 0 && i == fragment.childCount || + parent && this.open[this.open.length - 1].parent.type == parent.type)) + this.closeNode() + + return new Slice(fragment.cutByIndex(i), openStart, openEnd) + } + + addNode(open, node, openEnd) { + open.content = closeFragmentEnd(open.content, open.openEnd).addToEnd(node) + open.openEnd = openEnd + } + + closeNode() { + let open = this.open.pop() + if (open.content.size == 0) { + // Nothing here + } else if (open.wrapper) { + this.addNode(this.open[this.open.length - 1], open.parent.copy(open.content), open.openEnd + 1) + } else { + this.placed[open.depth] = {depth: open.depth, content: open.content, openEnd: open.openEnd} + } + } +} + +function closeNodeStart(node, openStart, openEnd) { + let content = node.content + if (openStart > 1) { + let first = closeNodeStart(node.firstChild, openStart - 1, node.childCount == 1 ? openEnd - 1 : 0) + content = node.content.replaceChild(0, first) + } + let fill = node.type.contentMatch.fillBefore(content, openEnd == 0) + return node.copy(fill.append(content)) +} + +function closeNodeEnd(node, depth) { + let content = node.content + if (depth > 1) { + let last = closeNodeEnd(node.lastChild, depth - 1) + content = node.content.replaceChild(node.childCount - 1, last) + } + let fill = node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true) + return node.copy(content.append(fill)) +} + +function closeFragmentEnd(fragment, depth) { + return depth ? fragment.replaceChild(fragment.childCount - 1, closeNodeEnd(fragment.lastChild, depth)) : fragment +} + +// :: (number, number, Slice) → this +// Replace a range of the document with a given slice, using `from`, +// `to`, and the slice's [`openStart`](#model.Slice.openStart) property +// as hints, rather than fixed start and end points. This method may +// grow the replaced area or close open nodes in the slice in order to +// get a fit that is more in line with WYSIWYG expectations, by +// dropping fully covered parent nodes of the replaced region when +// they are marked [non-defining](#model.NodeSpec.defining), or +// including an open parent node from the slice that _is_ marked as +// [defining](#model.NodeSpec.defining). +// +// This is the method, for example, to handle paste. The similar +// [`replace`](#transform.Transform.replace) method is a more +// primitive tool which will _not_ move the start and end of its given +// range, and is useful in situations where you need more precise +// control over what happens. +Transform.prototype.replaceRange = function(from, to, slice) { + if (!slice.size) return this.deleteRange(from, to) + + let $from = this.doc.resolve(from), $to = this.doc.resolve(to) + if (fitsTrivially($from, $to, slice)) + return this.step(new ReplaceStep(from, to, slice)) + + let targetDepths = coveredDepths($from, this.doc.resolve(to)) + // Can't replace the whole document, so remove 0 if it's present + if (targetDepths[targetDepths.length - 1] == 0) targetDepths.pop() + // Negative numbers represent not expansion over the whole node at + // that depth, but replacing from $from.before(-D) to $to.pos. + let preferredTarget = -($from.depth + 1) + targetDepths.unshift(preferredTarget) + // This loop picks a preferred target depth, if one of the covering + // depths is not outside of a defining node, and adds negative + // depths for any depth that has $from at its start and does not + // cross a defining node. + for (let d = $from.depth, pos = $from.pos - 1; d > 0; d--, pos--) { + let spec = $from.node(d).type.spec + if (spec.defining || spec.isolating) break + if (targetDepths.indexOf(d) > -1) preferredTarget = d + else if ($from.before(d) == pos) targetDepths.splice(1, 0, -d) + } + // Try to fit each possible depth of the slice into each possible + // target depth, starting with the preferred depths. + let preferredTargetIndex = targetDepths.indexOf(preferredTarget) + + let leftNodes = [], preferredDepth = slice.openStart + for (let content = slice.content, i = 0;; i++) { + let node = content.firstChild + leftNodes.push(node) + if (i == slice.openStart) break + content = node.content + } + // Back up if the node directly above openStart, or the node above + // that separated only by a non-defining textblock node, is defining. + if (preferredDepth > 0 && leftNodes[preferredDepth - 1].type.spec.defining && + $from.node(preferredTargetIndex).type != leftNodes[preferredDepth - 1].type) + preferredDepth -= 1 + else if (preferredDepth >= 2 && leftNodes[preferredDepth - 1].isTextblock && leftNodes[preferredDepth - 2].type.spec.defining && + $from.node(preferredTargetIndex).type != leftNodes[preferredDepth - 2].type) + preferredDepth -= 2 + + for (let j = slice.openStart; j >= 0; j--) { + let openDepth = (j + preferredDepth + 1) % (slice.openStart + 1) + let insert = leftNodes[openDepth] + if (!insert) continue + for (let i = 0; i < targetDepths.length; i++) { + // Loop over possible expansion levels, starting with the + // preferred one + let targetDepth = targetDepths[(i + preferredTargetIndex) % targetDepths.length], expand = true + if (targetDepth < 0) { expand = false; targetDepth = -targetDepth } + let parent = $from.node(targetDepth - 1), index = $from.index(targetDepth - 1) + if (parent.canReplaceWith(index, index, insert.type, insert.marks)) + return this.replace($from.before(targetDepth), expand ? $to.after(targetDepth) : to, + new Slice(closeFragment(slice.content, 0, slice.openStart, openDepth), + openDepth, slice.openEnd)) + } + } + + let startSteps = this.steps.length + for (let i = targetDepths.length - 1; i >= 0; i--) { + this.replace(from, to, slice) + if (this.steps.length > startSteps) break + let depth = targetDepths[i] + if (i < 0) continue + from = $from.before(depth); to = $to.after(depth) + } + return this +} + +function closeFragment(fragment, depth, oldOpen, newOpen, parent) { + if (depth < oldOpen) { + let first = fragment.firstChild + fragment = fragment.replaceChild(0, first.copy(closeFragment(first.content, depth + 1, oldOpen, newOpen, first))) + } + if (depth > newOpen) { + let match = parent.contentMatchAt(0) + let start = match.fillBefore(fragment).append(fragment) + fragment = start.append(match.matchFragment(start).fillBefore(Fragment.empty, true)) + } + return fragment +} + +// :: (number, number, Node) → this +// Replace the given range with a node, but use `from` and `to` as +// hints, rather than precise positions. When from and to are the same +// and are at the start or end of a parent node in which the given +// node doesn't fit, this method may _move_ them out towards a parent +// that does allow the given node to be placed. When the given range +// completely covers a parent node, this method may completely replace +// that parent node. +Transform.prototype.replaceRangeWith = function(from, to, node) { + if (!node.isInline && from == to && this.doc.resolve(from).parent.content.size) { + let point = insertPoint(this.doc, from, node.type) + if (point != null) from = to = point + } + return this.replaceRange(from, to, new Slice(Fragment.from(node), 0, 0)) +} + +// :: (number, number) → this +// Delete the given range, expanding it to cover fully covered +// parent nodes until a valid replace is found. +Transform.prototype.deleteRange = function(from, to) { + let $from = this.doc.resolve(from), $to = this.doc.resolve(to) + let covered = coveredDepths($from, $to) + for (let i = 0; i < covered.length; i++) { + let depth = covered[i], last = i == covered.length - 1 + if ((last && depth == 0) || $from.node(depth).type.contentMatch.validEnd) + return this.delete($from.start(depth), $to.end(depth)) + if (depth > 0 && (last || $from.node(depth - 1).canReplace($from.index(depth - 1), $to.indexAfter(depth - 1)))) + return this.delete($from.before(depth), $to.after(depth)) + } + for (let d = 1; d <= $from.depth; d++) { + if (from - $from.start(d) == $from.depth - d && to > $from.end(d) && $to.end(d) - to != $to.depth - d) + return this.delete($from.before(d), to) + } + return this.delete(from, to) +} + +// : (ResolvedPos, ResolvedPos) → [number] +// Returns an array of all depths for which $from - $to spans the +// whole content of the nodes at that depth. +function coveredDepths($from, $to) { + let result = [], minDepth = Math.min($from.depth, $to.depth) + for (let d = minDepth; d >= 0; d--) { + let start = $from.start(d) + if (start < $from.pos - ($from.depth - d) || + $to.end(d) > $to.pos + ($to.depth - d) || + $from.node(d).type.spec.isolating || + $to.node(d).type.spec.isolating) break + if (start == $to.start(d)) result.push(d) + } + return result +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/replace_step.js b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/replace_step.js new file mode 100644 index 0000000000..ac3840cb35 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/replace_step.js @@ -0,0 +1,163 @@ +import {Slice} from "prosemirror-model" + +import {Step, StepResult} from "./step" +import {StepMap} from "./map" + +// ::- Replace a part of the document with a slice of new content. +export class ReplaceStep extends Step { + // :: (number, number, Slice, ?bool) + // The given `slice` should fit the 'gap' between `from` and + // `to`—the depths must line up, and the surrounding nodes must be + // able to be joined with the open sides of the slice. When + // `structure` is true, the step will fail if the content between + // from and to is not just a sequence of closing and then opening + // tokens (this is to guard against rebased replace steps + // overwriting something they weren't supposed to). + constructor(from, to, slice, structure) { + super() + this.from = from + this.to = to + this.slice = slice + this.structure = !!structure + } + + apply(doc) { + if (this.structure && contentBetween(doc, this.from, this.to)) + return StepResult.fail("Structure replace would overwrite content") + return StepResult.fromReplace(doc, this.from, this.to, this.slice) + } + + getMap() { + return new StepMap([this.from, this.to - this.from, this.slice.size]) + } + + invert(doc) { + return new ReplaceStep(this.from, this.from + this.slice.size, doc.slice(this.from, this.to)) + } + + map(mapping) { + let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1) + if (from.deleted && to.deleted) return null + return new ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice) + } + + merge(other) { + if (!(other instanceof ReplaceStep) || other.structure != this.structure) return null + + if (this.from + this.slice.size == other.from && !this.slice.openEnd && !other.slice.openStart) { + let slice = this.slice.size + other.slice.size == 0 ? Slice.empty + : new Slice(this.slice.content.append(other.slice.content), this.slice.openStart, other.slice.openEnd) + return new ReplaceStep(this.from, this.to + (other.to - other.from), slice, this.structure) + } else if (other.to == this.from && !this.slice.openStart && !other.slice.openEnd) { + let slice = this.slice.size + other.slice.size == 0 ? Slice.empty + : new Slice(other.slice.content.append(this.slice.content), other.slice.openStart, this.slice.openEnd) + return new ReplaceStep(other.from, this.to, slice, this.structure) + } else { + return null + } + } + + toJSON() { + let json = {stepType: "replace", from: this.from, to: this.to} + if (this.slice.size) json.slice = this.slice.toJSON() + if (this.structure) json.structure = true + return json + } + + static fromJSON(schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + throw new RangeError("Invalid input for ReplaceStep.fromJSON") + return new ReplaceStep(json.from, json.to, Slice.fromJSON(schema, json.slice), !!json.structure) + } +} + +Step.jsonID("replace", ReplaceStep) + +// ::- Replace a part of the document with a slice of content, but +// preserve a range of the replaced content by moving it into the +// slice. +export class ReplaceAroundStep extends Step { + // :: (number, number, number, number, Slice, number, ?bool) + // Create a replace-around step with the given range and gap. + // `insert` should be the point in the slice into which the content + // of the gap should be moved. `structure` has the same meaning as + // it has in the [`ReplaceStep`](#transform.ReplaceStep) class. + constructor(from, to, gapFrom, gapTo, slice, insert, structure) { + super() + this.from = from + this.to = to + this.gapFrom = gapFrom + this.gapTo = gapTo + this.slice = slice + this.insert = insert + this.structure = !!structure + } + + apply(doc) { + if (this.structure && (contentBetween(doc, this.from, this.gapFrom) || + contentBetween(doc, this.gapTo, this.to))) + return StepResult.fail("Structure gap-replace would overwrite content") + + let gap = doc.slice(this.gapFrom, this.gapTo) + if (gap.openStart || gap.openEnd) + return StepResult.fail("Gap is not a flat range") + let inserted = this.slice.insertAt(this.insert, gap.content) + if (!inserted) return StepResult.fail("Content does not fit in gap") + return StepResult.fromReplace(doc, this.from, this.to, inserted) + } + + getMap() { + return new StepMap([this.from, this.gapFrom - this.from, this.insert, + this.gapTo, this.to - this.gapTo, this.slice.size - this.insert]) + } + + invert(doc) { + let gap = this.gapTo - this.gapFrom + return new ReplaceAroundStep(this.from, this.from + this.slice.size + gap, + this.from + this.insert, this.from + this.insert + gap, + doc.slice(this.from, this.to).removeBetween(this.gapFrom - this.from, this.gapTo - this.from), + this.gapFrom - this.from, this.structure) + } + + map(mapping) { + let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1) + let gapFrom = mapping.map(this.gapFrom, -1), gapTo = mapping.map(this.gapTo, 1) + if ((from.deleted && to.deleted) || gapFrom < from.pos || gapTo > to.pos) return null + return new ReplaceAroundStep(from.pos, to.pos, gapFrom, gapTo, this.slice, this.insert, this.structure) + } + + toJSON() { + let json = {stepType: "replaceAround", from: this.from, to: this.to, + gapFrom: this.gapFrom, gapTo: this.gapTo, insert: this.insert} + if (this.slice.size) json.slice = this.slice.toJSON() + if (this.structure) json.structure = true + return json + } + + static fromJSON(schema, json) { + if (typeof json.from != "number" || typeof json.to != "number" || + typeof json.gapFrom != "number" || typeof json.gapTo != "number" || typeof json.insert != "number") + throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON") + return new ReplaceAroundStep(json.from, json.to, json.gapFrom, json.gapTo, + Slice.fromJSON(schema, json.slice), json.insert, !!json.structure) + } +} + +Step.jsonID("replaceAround", ReplaceAroundStep) + +function contentBetween(doc, from, to) { + let $from = doc.resolve(from), dist = to - from, depth = $from.depth + while (dist > 0 && depth > 0 && $from.indexAfter(depth) == $from.node(depth).childCount) { + depth-- + dist-- + } + if (dist > 0) { + let next = $from.node(depth).maybeChild($from.indexAfter(depth)) + while (dist > 0) { + if (!next || next.isLeaf) return true + next = next.firstChild + dist-- + } + } + return false +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/step.js b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/step.js new file mode 100644 index 0000000000..a15485fd6a --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/step.js @@ -0,0 +1,110 @@ +import {ReplaceError} from "prosemirror-model" + +import {StepMap} from "./map" + +function mustOverride() { throw new Error("Override me") } + +const stepsByID = Object.create(null) + +// ::- A step object represents an atomic change. It generally applies +// only to the document it was created for, since the positions +// stored in it will only make sense for that document. +// +// New steps are defined by creating classes that extend `Step`, +// overriding the `apply`, `invert`, `map`, `getMap` and `fromJSON` +// methods, and registering your class with a unique +// JSON-serialization identifier using +// [`Step.jsonID`](#transform.Step^jsonID). +export class Step { + // :: (doc: Node) → StepResult + // Applies this step to the given document, returning a result + // object that either indicates failure, if the step can not be + // applied to this document, or indicates success by containing a + // transformed document. + apply(_doc) { return mustOverride() } + + // :: () → StepMap + // Get the step map that represents the changes made by this step, + // and which can be used to transform between positions in the old + // and the new document. + getMap() { return StepMap.empty } + + // :: (doc: Node) → Step + // Create an inverted version of this step. Needs the document as it + // was before the step as argument. + invert(_doc) { return mustOverride() } + + // :: (mapping: Mappable) → ?Step + // Map this step through a mappable thing, returning either a + // version of that step with its positions adjusted, or `null` if + // the step was entirely deleted by the mapping. + map(_mapping) { return mustOverride() } + + // :: (other: Step) → ?Step + // Try to merge this step with another one, to be applied directly + // after it. Returns the merged step when possible, null if the + // steps can't be merged. + merge(_other) { return null } + + // :: () → Object + // Create a JSON-serializeable representation of this step. When + // defining this for a custom subclass, make sure the result object + // includes the step type's [JSON id](#transform.Step^jsonID) under + // the `stepType` property. + toJSON() { return mustOverride() } + + // :: (Schema, Object) → Step + // Deserialize a step from its JSON representation. Will call + // through to the step class' own implementation of this method. + static fromJSON(schema, json) { + if (!json || !json.stepType) throw new RangeError("Invalid input for Step.fromJSON") + let type = stepsByID[json.stepType] + if (!type) throw new RangeError(`No step type ${json.stepType} defined`) + return type.fromJSON(schema, json) + } + + // :: (string, constructor) + // To be able to serialize steps to JSON, each step needs a string + // ID to attach to its JSON representation. Use this method to + // register an ID for your step classes. Try to pick something + // that's unlikely to clash with steps from other modules. + static jsonID(id, stepClass) { + if (id in stepsByID) throw new RangeError("Duplicate use of step JSON ID " + id) + stepsByID[id] = stepClass + stepClass.prototype.jsonID = id + return stepClass + } +} + +// ::- The result of [applying](#transform.Step.apply) a step. Contains either a +// new document or a failure value. +export class StepResult { + // : (?Node, ?string) + constructor(doc, failed) { + // :: ?Node The transformed document. + this.doc = doc + // :: ?string Text providing information about a failed step. + this.failed = failed + } + + // :: (Node) → StepResult + // Create a successful step result. + static ok(doc) { return new StepResult(doc, null) } + + // :: (string) → StepResult + // Create a failed step result. + static fail(message) { return new StepResult(null, message) } + + // :: (Node, number, number, Slice) → StepResult + // Call [`Node.replace`](#model.Node.replace) with the given + // arguments. Create a successful result if it succeeds, and a + // failed one if it throws a `ReplaceError`. + static fromReplace(doc, from, to, slice) { + try { + return StepResult.ok(doc.replace(from, to, slice)) + } catch (e) { + if (e instanceof ReplaceError) return StepResult.fail(e.message) + throw e + } + } +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/structure.js b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/structure.js new file mode 100644 index 0000000000..8e1fb7b5df --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/structure.js @@ -0,0 +1,284 @@ +import {Slice, Fragment} from "prosemirror-model" + +import {Transform} from "./transform" +import {ReplaceStep, ReplaceAroundStep} from "./replace_step" + +function canCut(node, start, end) { + return (start == 0 || node.canReplace(start, node.childCount)) && + (end == node.childCount || node.canReplace(0, end)) +} + +// :: (NodeRange) → ?number +// Try to find a target depth to which the content in the given range +// can be lifted. Will not go across +// [isolating](#model.NodeSpec.isolating) parent nodes. +export function liftTarget(range) { + let parent = range.parent + let content = parent.content.cutByIndex(range.startIndex, range.endIndex) + for (let depth = range.depth;; --depth) { + let node = range.$from.node(depth) + let index = range.$from.index(depth), endIndex = range.$to.indexAfter(depth) + if (depth < range.depth && node.canReplace(index, endIndex, content)) + return depth + if (depth == 0 || node.type.spec.isolating || !canCut(node, index, endIndex)) break + } +} + +// :: (NodeRange, number) → this +// Split the content in the given range off from its parent, if there +// is sibling content before or after it, and move it up the tree to +// the depth specified by `target`. You'll probably want to use +// [`liftTarget`](#transform.liftTarget) to compute `target`, to make +// sure the lift is valid. +Transform.prototype.lift = function(range, target) { + let {$from, $to, depth} = range + + let gapStart = $from.before(depth + 1), gapEnd = $to.after(depth + 1) + let start = gapStart, end = gapEnd + + let before = Fragment.empty, openStart = 0 + for (let d = depth, splitting = false; d > target; d--) + if (splitting || $from.index(d) > 0) { + splitting = true + before = Fragment.from($from.node(d).copy(before)) + openStart++ + } else { + start-- + } + let after = Fragment.empty, openEnd = 0 + for (let d = depth, splitting = false; d > target; d--) + if (splitting || $to.after(d + 1) < $to.end(d)) { + splitting = true + after = Fragment.from($to.node(d).copy(after)) + openEnd++ + } else { + end++ + } + + return this.step(new ReplaceAroundStep(start, end, gapStart, gapEnd, + new Slice(before.append(after), openStart, openEnd), + before.size - openStart, true)) +} + +// :: (NodeRange, NodeType, ?Object, ?NodeRange) → ?[{type: NodeType, attrs: ?Object}] +// Try to find a valid way to wrap the content in the given range in a +// node of the given type. May introduce extra nodes around and inside +// the wrapper node, if necessary. Returns null if no valid wrapping +// could be found. When `innerRange` is given, that range's content is +// used as the content to fit into the wrapping, instead of the +// content of `range`. +export function findWrapping(range, nodeType, attrs, innerRange = range) { + let around = findWrappingOutside(range, nodeType) + let inner = around && findWrappingInside(innerRange, nodeType) + if (!inner) return null + return around.map(withAttrs).concat({type: nodeType, attrs}).concat(inner.map(withAttrs)) +} + +function withAttrs(type) { return {type, attrs: null} } + +function findWrappingOutside(range, type) { + let {parent, startIndex, endIndex} = range + let around = parent.contentMatchAt(startIndex).findWrapping(type) + if (!around) return null + let outer = around.length ? around[0] : type + return parent.canReplaceWith(startIndex, endIndex, outer) ? around : null +} + +function findWrappingInside(range, type) { + let {parent, startIndex, endIndex} = range + let inner = parent.child(startIndex) + let inside = type.contentMatch.findWrapping(inner.type) + if (!inside) return null + let lastType = inside.length ? inside[inside.length - 1] : type + let innerMatch = lastType.contentMatch + for (let i = startIndex; innerMatch && i < endIndex; i++) + innerMatch = innerMatch.matchType(parent.child(i).type) + if (!innerMatch || !innerMatch.validEnd) return null + return inside +} + +// :: (NodeRange, [{type: NodeType, attrs: ?Object}]) → this +// Wrap the given [range](#model.NodeRange) in the given set of wrappers. +// The wrappers are assumed to be valid in this position, and should +// probably be computed with [`findWrapping`](#transform.findWrapping). +Transform.prototype.wrap = function(range, wrappers) { + let content = Fragment.empty + for (let i = wrappers.length - 1; i >= 0; i--) + content = Fragment.from(wrappers[i].type.create(wrappers[i].attrs, content)) + + let start = range.start, end = range.end + return this.step(new ReplaceAroundStep(start, end, start, end, new Slice(content, 0, 0), wrappers.length, true)) +} + +// :: (number, ?number, NodeType, ?Object) → this +// Set the type of all textblocks (partly) between `from` and `to` to +// the given node type with the given attributes. +Transform.prototype.setBlockType = function(from, to = from, type, attrs) { + if (!type.isTextblock) throw new RangeError("Type given to setBlockType should be a textblock") + let mapFrom = this.steps.length + this.doc.nodesBetween(from, to, (node, pos) => { + if (node.isTextblock && !node.hasMarkup(type, attrs) && canChangeType(this.doc, this.mapping.slice(mapFrom).map(pos), type)) { + // Ensure all markup that isn't allowed in the new node type is cleared + this.clearIncompatible(this.mapping.slice(mapFrom).map(pos, 1), type) + let mapping = this.mapping.slice(mapFrom) + let startM = mapping.map(pos, 1), endM = mapping.map(pos + node.nodeSize, 1) + this.step(new ReplaceAroundStep(startM, endM, startM + 1, endM - 1, + new Slice(Fragment.from(type.create(attrs, null, node.marks)), 0, 0), 1, true)) + return false + } + }) + return this +} + +function canChangeType(doc, pos, type) { + let $pos = doc.resolve(pos), index = $pos.index() + return $pos.parent.canReplaceWith(index, index + 1, type) +} + +// :: (number, ?NodeType, ?Object, ?[Mark]) → this +// Change the type, attributes, and/or marks of the node at `pos`. +// When `type` isn't given, the existing node type is preserved, +Transform.prototype.setNodeMarkup = function(pos, type, attrs, marks) { + let node = this.doc.nodeAt(pos) + if (!node) throw new RangeError("No node at given position") + if (!type) type = node.type + let newNode = type.create(attrs, null, marks || node.marks) + if (node.isLeaf) + return this.replaceWith(pos, pos + node.nodeSize, newNode) + + if (!type.validContent(node.content)) + throw new RangeError("Invalid content for node type " + type.name) + + return this.step(new ReplaceAroundStep(pos, pos + node.nodeSize, pos + 1, pos + node.nodeSize - 1, + new Slice(Fragment.from(newNode), 0, 0), 1, true)) +} + +// :: (Node, number, number, ?[?{type: NodeType, attrs: ?Object}]) → bool +// Check whether splitting at the given position is allowed. +export function canSplit(doc, pos, depth = 1, typesAfter) { + let $pos = doc.resolve(pos), base = $pos.depth - depth + let innerType = (typesAfter && typesAfter[typesAfter.length - 1]) || $pos.parent + if (base < 0 || $pos.parent.type.spec.isolating || + !$pos.parent.canReplace($pos.index(), $pos.parent.childCount) || + !innerType.type.validContent($pos.parent.content.cutByIndex($pos.index(), $pos.parent.childCount))) + return false + for (let d = $pos.depth - 1, i = depth - 2; d > base; d--, i--) { + let node = $pos.node(d), index = $pos.index(d) + if (node.type.spec.isolating) return false + let rest = node.content.cutByIndex(index, node.childCount) + let after = (typesAfter && typesAfter[i]) || node + if (after != node) rest = rest.replaceChild(0, after.type.create(after.attrs)) + if (!node.canReplace(index + 1, node.childCount) || !after.type.validContent(rest)) + return false + } + let index = $pos.indexAfter(base) + let baseType = typesAfter && typesAfter[0] + return $pos.node(base).canReplaceWith(index, index, baseType ? baseType.type : $pos.node(base + 1).type) +} + +// :: (number, ?number, ?[?{type: NodeType, attrs: ?Object}]) → this +// Split the node at the given position, and optionally, if `depth` is +// greater than one, any number of nodes above that. By default, the +// parts split off will inherit the node type of the original node. +// This can be changed by passing an array of types and attributes to +// use after the split. +Transform.prototype.split = function(pos, depth = 1, typesAfter) { + let $pos = this.doc.resolve(pos), before = Fragment.empty, after = Fragment.empty + for (let d = $pos.depth, e = $pos.depth - depth, i = depth - 1; d > e; d--, i--) { + before = Fragment.from($pos.node(d).copy(before)) + let typeAfter = typesAfter && typesAfter[i] + after = Fragment.from(typeAfter ? typeAfter.type.create(typeAfter.attrs, after) : $pos.node(d).copy(after)) + } + return this.step(new ReplaceStep(pos, pos, new Slice(before.append(after), depth, depth), true)) +} + +// :: (Node, number) → bool +// Test whether the blocks before and after a given position can be +// joined. +export function canJoin(doc, pos) { + let $pos = doc.resolve(pos), index = $pos.index() + return joinable($pos.nodeBefore, $pos.nodeAfter) && + $pos.parent.canReplace(index, index + 1) +} + +function joinable(a, b) { + return a && b && !a.isLeaf && a.canAppend(b) +} + +// :: (Node, number, ?number) → ?number +// Find an ancestor of the given position that can be joined to the +// block before (or after if `dir` is positive). Returns the joinable +// point, if any. +export function joinPoint(doc, pos, dir = -1) { + let $pos = doc.resolve(pos) + for (let d = $pos.depth;; d--) { + let before, after + if (d == $pos.depth) { + before = $pos.nodeBefore + after = $pos.nodeAfter + } else if (dir > 0) { + before = $pos.node(d + 1) + after = $pos.node(d).maybeChild($pos.index(d) + 1) + } else { + before = $pos.node(d).maybeChild($pos.index(d) - 1) + after = $pos.node(d + 1) + } + if (before && !before.isTextblock && joinable(before, after)) return pos + if (d == 0) break + pos = dir < 0 ? $pos.before(d) : $pos.after(d) + } +} + +// :: (number, ?number) → this +// Join the blocks around the given position. If depth is 2, their +// last and first siblings are also joined, and so on. +Transform.prototype.join = function(pos, depth = 1) { + let step = new ReplaceStep(pos - depth, pos + depth, Slice.empty, true) + return this.step(step) +} + +// :: (Node, number, NodeType) → ?number +// Try to find a point where a node of the given type can be inserted +// near `pos`, by searching up the node hierarchy when `pos` itself +// isn't a valid place but is at the start or end of a node. Return +// null if no position was found. +export function insertPoint(doc, pos, nodeType) { + let $pos = doc.resolve(pos) + if ($pos.parent.canReplaceWith($pos.index(), $pos.index(), nodeType)) return pos + + if ($pos.parentOffset == 0) + for (let d = $pos.depth - 1; d >= 0; d--) { + let index = $pos.index(d) + if ($pos.node(d).canReplaceWith(index, index, nodeType)) return $pos.before(d + 1) + if (index > 0) return null + } + if ($pos.parentOffset == $pos.parent.content.size) + for (let d = $pos.depth - 1; d >= 0; d--) { + let index = $pos.indexAfter(d) + if ($pos.node(d).canReplaceWith(index, index, nodeType)) return $pos.after(d + 1) + if (index < $pos.node(d).childCount) return null + } +} + +// :: (Node, number, Slice) → ?number +// Finds a position at or around the given position where the given +// slice can be inserted. Will look at parent nodes' nearest boundary +// and try there, even if the original position wasn't directly at the +// start or end of that node. Returns null when no position was found. +export function dropPoint(doc, pos, slice) { + let $pos = doc.resolve(pos) + if (!slice.content.size) return pos + let content = slice.content + for (let i = 0; i < slice.openStart; i++) content = content.firstChild.content + for (let pass = 1; pass <= (slice.openStart == 0 && slice.size ? 2 : 1); pass++) { + for (let d = $pos.depth; d >= 0; d--) { + let bias = d == $pos.depth ? 0 : $pos.pos <= ($pos.start(d + 1) + $pos.end(d + 1)) / 2 ? -1 : 1 + let insertPos = $pos.index(d) + (bias > 0 ? 1 : 0) + if (pass == 1 + ? $pos.node(d).canReplace(insertPos, insertPos, content) + : $pos.node(d).contentMatchAt(insertPos).findWrapping(content.firstChild.type)) + return bias == 0 ? $pos.pos : bias < 0 ? $pos.before(d + 1) : $pos.after(d + 1) + } + } + return null +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/transform.js b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/transform.js new file mode 100644 index 0000000000..f52d3387ec --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/node_modules/prosemirror-transform/src/transform.js @@ -0,0 +1,71 @@ +import {Mapping} from "./map" + +export function TransformError(message) { + let err = Error.call(this, message) + err.__proto__ = TransformError.prototype + return err +} + +TransformError.prototype = Object.create(Error.prototype) +TransformError.prototype.constructor = TransformError +TransformError.prototype.name = "TransformError" + +// ::- Abstraction to build up and track an array of +// [steps](#transform.Step) representing a document transformation. +// +// Most transforming methods return the `Transform` object itself, so +// that they can be chained. +export class Transform { + // :: (Node) + // Create a transform that starts with the given document. + constructor(doc) { + // :: Node + // The current document (the result of applying the steps in the + // transform). + this.doc = doc + // :: [Step] + // The steps in this transform. + this.steps = [] + // :: [Node] + // The documents before each of the steps. + this.docs = [] + // :: Mapping + // A mapping with the maps for each of the steps in this transform. + this.mapping = new Mapping + } + + // :: Node The starting document. + get before() { return this.docs.length ? this.docs[0] : this.doc } + + // :: (step: Step) → this + // Apply a new step in this transform, saving the result. Throws an + // error when the step fails. + step(object) { + let result = this.maybeStep(object) + if (result.failed) throw new TransformError(result.failed) + return this + } + + // :: (Step) → StepResult + // Try to apply a step in this transformation, ignoring it if it + // fails. Returns the step result. + maybeStep(step) { + let result = step.apply(this.doc) + if (!result.failed) this.addStep(step, result.doc) + return result + } + + // :: bool + // True when the document has been changed (when there are any + // steps). + get docChanged() { + return this.steps.length > 0 + } + + addStep(step, doc) { + this.docs.push(this.doc) + this.steps.push(step) + this.mapping.appendMap(step.getMap()) + this.doc = doc + } +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/package.json b/packages/tiptap-extensions/node_modules/prosemirror-view/package.json new file mode 100644 index 0000000000..87cdc8cbdc --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/package.json @@ -0,0 +1,40 @@ +{ + "name": "prosemirror-view", + "version": "1.13.7", + "description": "ProseMirror's view component", + "main": "dist/index.js", + "module": "dist/index.es.js", + "style": "style/prosemirror.css", + "license": "MIT", + "maintainers": [ + { + "name": "Marijn Haverbeke", + "email": "marijnh@gmail.com", + "web": "http://marijnhaverbeke.nl" + } + ], + "repository": { + "type": "git", + "url": "git://github.com/prosemirror/prosemirror-view.git" + }, + "dependencies": { + "prosemirror-model": "^1.1.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.1.0" + }, + "devDependencies": { + "ist": "^1.0.0", + "mocha": "^3.0.2", + "moduleserve": "^0.7.0", + "prosemirror-test-builder": "^1.0.0", + "rollup": "^1.26.3", + "@rollup/plugin-buble": "^0.20.0" + }, + "scripts": { + "test": "FIXME autorun browser tests", + "test-server": "node test/link-mocha-css.js && moduleserve test --port 8090", + "build": "rollup -c", + "watch": "rollup -c -w", + "prepare": "npm run build" + } +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/rollup.config.js b/packages/tiptap-extensions/node_modules/prosemirror-view/rollup.config.js new file mode 100644 index 0000000000..156b12a278 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/rollup.config.js @@ -0,0 +1,14 @@ +module.exports = { + input: './src/index.js', + output: [{ + file: 'dist/index.js', + format: 'cjs', + sourcemap: true + }, { + file: 'dist/index.es.js', + format: 'es', + sourcemap: true + }], + plugins: [require('@rollup/plugin-buble')()], + external(id) { return !/^[\.\/]/.test(id) } +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/src/README.md b/packages/tiptap-extensions/node_modules/prosemirror-view/src/README.md new file mode 100644 index 0000000000..1503890d36 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/src/README.md @@ -0,0 +1,26 @@ +ProseMirror's view module displays a given [editor +state](#state.EditorState) in the DOM, and handles user events. + +Make sure you load `style/prosemirror.css` as a stylesheet when using +this module. + +@EditorView + +### Props + +@EditorProps + +@DirectEditorProps + +@NodeView + +### Decorations + +Decorations make it possible to influence the way the document is +drawn, without actually changing the document. + +@Decoration + +@DecorationAttrs + +@DecorationSet diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/src/browser.js b/packages/tiptap-extensions/node_modules/prosemirror-view/src/browser.js new file mode 100644 index 0000000000..0cfcbf20a7 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/src/browser.js @@ -0,0 +1,22 @@ +const result = {} +export default result + +if (typeof navigator != "undefined" && typeof document != "undefined") { + const ie_edge = /Edge\/(\d+)/.exec(navigator.userAgent) + const ie_upto10 = /MSIE \d/.test(navigator.userAgent) + const ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent) + + result.mac = /Mac/.test(navigator.platform) + let ie = result.ie = !!(ie_upto10 || ie_11up || ie_edge) + result.ie_version = ie_upto10 ? document.documentMode || 6 : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : null + result.gecko = !ie && /gecko\/(\d+)/i.test(navigator.userAgent) + result.gecko_version = result.gecko && +(/Firefox\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1] + let chrome = !ie && /Chrome\/(\d+)/.exec(navigator.userAgent) + result.chrome = !!chrome + result.chrome_version = chrome && +chrome[1] + result.ios = !ie && /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent) + result.android = /Android \d/.test(navigator.userAgent) + result.webkit = !ie && 'WebkitAppearance' in document.documentElement.style + result.safari = /Apple Computer/.test(navigator.vendor) + result.webkit_version = result.webkit && +(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1] +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/src/capturekeys.js b/packages/tiptap-extensions/node_modules/prosemirror-view/src/capturekeys.js new file mode 100644 index 0000000000..2e70e76b5e --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/src/capturekeys.js @@ -0,0 +1,262 @@ +import {Selection, NodeSelection, TextSelection} from "prosemirror-state" +import browser from "./browser" +import {domIndex, selectionCollapsed} from "./dom" + +function moveSelectionBlock(state, dir) { + let {$anchor, $head} = state.selection + let $side = dir > 0 ? $anchor.max($head) : $anchor.min($head) + let $start = !$side.parent.inlineContent ? $side : $side.depth ? state.doc.resolve(dir > 0 ? $side.after() : $side.before()) : null + return $start && Selection.findFrom($start, dir) +} + +function apply(view, sel) { + view.dispatch(view.state.tr.setSelection(sel).scrollIntoView()) + return true +} + +function selectHorizontally(view, dir, mods) { + let sel = view.state.selection + if (sel instanceof TextSelection) { + if (!sel.empty || mods.indexOf("s") > -1) { + return false + } else if (view.endOfTextblock(dir > 0 ? "right" : "left")) { + let next = moveSelectionBlock(view.state, dir) + if (next && (next instanceof NodeSelection)) return apply(view, next) + return false + } else { + let $head = sel.$head, node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter, desc + if (!node || node.isText) return false + let nodePos = dir < 0 ? $head.pos - node.nodeSize : $head.pos + if (!(node.isAtom || (desc = view.docView.descAt(nodePos)) && !desc.contentDOM)) return false + if (NodeSelection.isSelectable(node)) { + return apply(view, new NodeSelection(dir < 0 ? view.state.doc.resolve($head.pos - node.nodeSize) : $head)) + } else if (browser.webkit) { + // Chrome and Safari will introduce extra pointless cursor + // positions around inline uneditable nodes, so we have to + // take over and move the cursor past them (#937) + return apply(view, new TextSelection(view.state.doc.resolve(dir < 0 ? nodePos : nodePos + node.nodeSize))) + } else { + return false + } + } + } else if (sel instanceof NodeSelection && sel.node.isInline) { + return apply(view, new TextSelection(dir > 0 ? sel.$to : sel.$from)) + } else { + let next = moveSelectionBlock(view.state, dir) + if (next) return apply(view, next) + return false + } +} + +function nodeLen(node) { + return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length +} + +function isIgnorable(dom) { + let desc = dom.pmViewDesc + return desc && desc.size == 0 && (dom.nextSibling || dom.nodeName != "BR") +} + +// Make sure the cursor isn't directly after one or more ignored +// nodes, which will confuse the browser's cursor motion logic. +function skipIgnoredNodesLeft(view) { + let sel = view.root.getSelection() + let node = sel.focusNode, offset = sel.focusOffset + if (!node) return + let moveNode, moveOffset, force = false + // Gecko will do odd things when the selection is directly in front + // of a non-editable node, so in that case, move it into the next + // node if possible. Issue prosemirror/prosemirror#832. + if (browser.gecko && node.nodeType == 1 && offset < nodeLen(node) && isIgnorable(node.childNodes[offset])) force = true + for (;;) { + if (offset > 0) { + if (node.nodeType != 1) { + break + } else { + let before = node.childNodes[offset - 1] + if (isIgnorable(before)) { + moveNode = node + moveOffset = --offset + } else if (before.nodeType == 3) { + node = before + offset = node.nodeValue.length + } else break + } + } else if (isBlockNode(node)) { + break + } else { + let prev = node.previousSibling + while (prev && isIgnorable(prev)) { + moveNode = node.parentNode + moveOffset = domIndex(prev) + prev = prev.previousSibling + } + if (!prev) { + node = node.parentNode + if (node == view.dom) break + offset = 0 + } else { + node = prev + offset = nodeLen(node) + } + } + } + if (force) setSelFocus(view, sel, node, offset) + else if (moveNode) setSelFocus(view, sel, moveNode, moveOffset) +} + +// Make sure the cursor isn't directly before one or more ignored +// nodes. +function skipIgnoredNodesRight(view) { + let sel = view.root.getSelection() + let node = sel.focusNode, offset = sel.focusOffset + if (!node) return + let len = nodeLen(node) + let moveNode, moveOffset + for (;;) { + if (offset < len) { + if (node.nodeType != 1) break + let after = node.childNodes[offset] + if (isIgnorable(after)) { + moveNode = node + moveOffset = ++offset + } + else break + } else if (isBlockNode(node)) { + break + } else { + let next = node.nextSibling + while (next && isIgnorable(next)) { + moveNode = next.parentNode + moveOffset = domIndex(next) + 1 + next = next.nextSibling + } + if (!next) { + node = node.parentNode + if (node == view.dom) break + offset = len = 0 + } else { + node = next + offset = 0 + len = nodeLen(node) + } + } + } + if (moveNode) setSelFocus(view, sel, moveNode, moveOffset) +} + +function isBlockNode(dom) { + let desc = dom.pmViewDesc + return desc && desc.node && desc.node.isBlock +} + +function setSelFocus(view, sel, node, offset) { + if (selectionCollapsed(sel)) { + let range = document.createRange() + range.setEnd(node, offset) + range.setStart(node, offset) + sel.removeAllRanges() + sel.addRange(range) + } else if (sel.extend) { + sel.extend(node, offset) + } + view.domObserver.setCurSelection() +} + +// : (EditorState, number) +// Check whether vertical selection motion would involve node +// selections. If so, apply it (if not, the result is left to the +// browser) +function selectVertically(view, dir, mods) { + let sel = view.state.selection + if (sel instanceof TextSelection && !sel.empty || mods.indexOf("s") > -1) return false + let {$from, $to} = sel + + if (!$from.parent.inlineContent || view.endOfTextblock(dir < 0 ? "up" : "down")) { + let next = moveSelectionBlock(view.state, dir) + if (next && (next instanceof NodeSelection)) + return apply(view, next) + } + if (!$from.parent.inlineContent) { + let beyond = Selection.findFrom(dir < 0 ? $from : $to, dir) + return beyond ? apply(view, beyond) : true + } + return false +} + +function stopNativeHorizontalDelete(view, dir) { + if (!(view.state.selection instanceof TextSelection)) return true + let {$head, $anchor, empty} = view.state.selection + if (!$head.sameParent($anchor)) return true + if (!empty) return false + if (view.endOfTextblock(dir > 0 ? "forward" : "backward")) return true + let nextNode = !$head.textOffset && (dir < 0 ? $head.nodeBefore : $head.nodeAfter) + if (nextNode && !nextNode.isText) { + let tr = view.state.tr + if (dir < 0) tr.delete($head.pos - nextNode.nodeSize, $head.pos) + else tr.delete($head.pos, $head.pos + nextNode.nodeSize) + view.dispatch(tr) + return true + } + return false +} + +function switchEditable(view, node, state) { + view.domObserver.stop() + node.contentEditable = state + view.domObserver.start() +} + +// Issue #867 / https://bugs.chromium.org/p/chromium/issues/detail?id=903821 +// In which Chrome does really wrong things when the down arrow is +// pressed when the cursor is directly at the start of a textblock and +// has an uneditable node after it +function chromeDownArrowBug(view) { + if (!browser.chrome || view.state.selection.$head.parentOffset > 0) return + let {focusNode, focusOffset} = view.root.getSelection() + if (focusNode && focusNode.nodeType == 1 && focusOffset == 0 && + focusNode.firstChild && focusNode.firstChild.contentEditable == "false") { + let child = focusNode.firstChild + switchEditable(view, child, true) + setTimeout(() => switchEditable(view, child, false), 20) + } +} + +// A backdrop key mapping used to make sure we always suppress keys +// that have a dangerous default effect, even if the commands they are +// bound to return false, and to make sure that cursor-motion keys +// find a cursor (as opposed to a node selection) when pressed. For +// cursor-motion keys, the code in the handlers also takes care of +// block selections. + +function getMods(event) { + let result = "" + if (event.ctrlKey) result += "c" + if (event.metaKey) result += "m" + if (event.altKey) result += "a" + if (event.shiftKey) result += "s" + return result +} + +export function captureKeyDown(view, event) { + let code = event.keyCode, mods = getMods(event) + if (code == 8 || (browser.mac && code == 72 && mods == "c")) { // Backspace, Ctrl-h on Mac + return stopNativeHorizontalDelete(view, -1) || skipIgnoredNodesLeft(view) + } else if (code == 46 || (browser.mac && code == 68 && mods == "c")) { // Delete, Ctrl-d on Mac + return stopNativeHorizontalDelete(view, 1) || skipIgnoredNodesRight(view) + } else if (code == 13 || code == 27) { // Enter, Esc + return true + } else if (code == 37) { // Left arrow + return selectHorizontally(view, -1, mods) || skipIgnoredNodesLeft(view) + } else if (code == 39) { // Right arrow + return selectHorizontally(view, 1, mods) || skipIgnoredNodesRight(view) + } else if (code == 38) { // Up arrow + return selectVertically(view, -1, mods) || skipIgnoredNodesLeft(view) + } else if (code == 40) { // Down arrow + return chromeDownArrowBug(view) || selectVertically(view, 1, mods) || skipIgnoredNodesRight(view) + } else if (mods == (browser.mac ? "m" : "c") && + (code == 66 || code == 73 || code == 89 || code == 90)) { // Mod-[biyz] + return true + } + return false +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/src/clipboard.js b/packages/tiptap-extensions/node_modules/prosemirror-view/src/clipboard.js new file mode 100644 index 0000000000..b13e091a7e --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/src/clipboard.js @@ -0,0 +1,187 @@ +import {Slice, Fragment, DOMParser, DOMSerializer} from "prosemirror-model" + +export function serializeForClipboard(view, slice) { + let context = [], {content, openStart, openEnd} = slice + while (openStart > 1 && openEnd > 1 && content.childCount == 1 && content.firstChild.childCount == 1) { + openStart-- + openEnd-- + let node = content.firstChild + context.push(node.type.name, node.type.hasRequiredAttrs() ? node.attrs : null) + content = node.content + } + + let serializer = view.someProp("clipboardSerializer") || DOMSerializer.fromSchema(view.state.schema) + let doc = detachedDoc(), wrap = doc.createElement("div") + wrap.appendChild(serializer.serializeFragment(content, {document: doc})) + + let firstChild = wrap.firstChild, needsWrap + while (firstChild && firstChild.nodeType == 1 && (needsWrap = wrapMap[firstChild.nodeName.toLowerCase()])) { + for (let i = needsWrap.length - 1; i >= 0; i--) { + let wrapper = doc.createElement(needsWrap[i]) + while (wrap.firstChild) wrapper.appendChild(wrap.firstChild) + wrap.appendChild(wrapper) + } + firstChild = wrap.firstChild + } + + if (firstChild && firstChild.nodeType == 1) + firstChild.setAttribute("data-pm-slice", `${openStart} ${openEnd} ${JSON.stringify(context)}`) + + let text = view.someProp("clipboardTextSerializer", f => f(slice)) || + slice.content.textBetween(0, slice.content.size, "\n\n") + + return {dom: wrap, text} +} + +// : (EditorView, string, string, ?bool, ResolvedPos) → ?Slice +// Read a slice of content from the clipboard (or drop data). +export function parseFromClipboard(view, text, html, plainText, $context) { + let dom, inCode = $context.parent.type.spec.code, slice + if (!html && !text) return null + let asText = text && (plainText || inCode || !html) + if (asText) { + view.someProp("transformPastedText", f => { text = f(text) }) + if (inCode) return new Slice(Fragment.from(view.state.schema.text(text)), 0, 0) + let parsed = view.someProp("clipboardTextParser", f => f(text, $context)) + if (parsed) { + slice = parsed + } else { + dom = document.createElement("div") + text.trim().split(/(?:\r\n?|\n)+/).forEach(block => { + dom.appendChild(document.createElement("p")).textContent = block + }) + } + } else { + view.someProp("transformPastedHTML", f => { html = f(html) }) + dom = readHTML(html) + } + + let contextNode = dom && dom.querySelector("[data-pm-slice]") + let sliceData = contextNode && /^(\d+) (\d+) (.*)/.exec(contextNode.getAttribute("data-pm-slice")) + if (!slice) { + let parser = view.someProp("clipboardParser") || view.someProp("domParser") || DOMParser.fromSchema(view.state.schema) + slice = parser.parseSlice(dom, {preserveWhitespace: !!(asText || sliceData), context: $context}) + } + if (sliceData) + slice = addContext(closeSlice(slice, +sliceData[1], +sliceData[2]), sliceData[3]) + else // HTML wasn't created by ProseMirror. Make sure top-level siblings are coherent + slice = Slice.maxOpen(normalizeSiblings(slice.content, $context), false) + + view.someProp("transformPasted", f => { slice = f(slice) }) + return slice +} + +// Takes a slice parsed with parseSlice, which means there hasn't been +// any content-expression checking done on the top nodes, tries to +// find a parent node in the current context that might fit the nodes, +// and if successful, rebuilds the slice so that it fits into that parent. +// +// This addresses the problem that Transform.replace expects a +// coherent slice, and will fail to place a set of siblings that don't +// fit anywhere in the schema. +function normalizeSiblings(fragment, $context) { + if (fragment.childCount < 2) return fragment + for (let d = $context.depth; d >= 0; d--) { + let parent = $context.node(d) + let match = parent.contentMatchAt($context.index(d)) + let lastWrap, result = [] + fragment.forEach(node => { + if (!result) return + let wrap = match.findWrapping(node.type), inLast + if (!wrap) return result = null + if (inLast = result.length && lastWrap.length && addToSibling(wrap, lastWrap, node, result[result.length - 1], 0)) { + result[result.length - 1] = inLast + } else { + if (result.length) result[result.length - 1] = closeRight(result[result.length - 1], lastWrap.length) + let wrapped = withWrappers(node, wrap) + result.push(wrapped) + match = match.matchType(wrapped.type, wrapped.attrs) + lastWrap = wrap + } + }) + if (result) return Fragment.from(result) + } + return fragment +} + +function withWrappers(node, wrap, from = 0) { + for (let i = wrap.length - 1; i >= from; i--) + node = wrap[i].create(null, Fragment.from(node)) + return node +} + +// Used to group adjacent nodes wrapped in similar parents by +// normalizeSiblings into the same parent node +function addToSibling(wrap, lastWrap, node, sibling, depth) { + if (depth < wrap.length && depth < lastWrap.length && wrap[depth] == lastWrap[depth]) { + let inner = addToSibling(wrap, lastWrap, node, sibling.lastChild, depth + 1) + if (inner) return sibling.copy(sibling.content.replaceChild(sibling.childCount - 1, inner)) + let match = sibling.contentMatchAt(sibling.childCount) + if (match.matchType(depth == wrap.length - 1 ? node.type : wrap[depth + 1])) + return sibling.copy(sibling.content.append(Fragment.from(withWrappers(node, wrap, depth + 1)))) + } +} + +function closeRight(node, depth) { + if (depth == 0) return node + let fragment = node.content.replaceChild(node.childCount - 1, closeRight(node.lastChild, depth - 1)) + let fill = node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true) + return node.copy(fragment.append(fill)) +} + +function closeRange(fragment, side, from, to, depth, openEnd) { + let node = side < 0 ? fragment.firstChild : fragment.lastChild, inner = node.content + if (depth < to - 1) inner = closeRange(inner, side, from, to, depth + 1, openEnd) + if (depth >= from) + inner = side < 0 ? node.contentMatchAt(0).fillBefore(inner, fragment.childCount > 1 || openEnd <= depth).append(inner) + : inner.append(node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true)) + return fragment.replaceChild(side < 0 ? 0 : fragment.childCount - 1, node.copy(inner)) +} + +function closeSlice(slice, openStart, openEnd) { + if (openStart < slice.openStart) + slice = new Slice(closeRange(slice.content, -1, openStart, slice.openStart, 0, slice.openEnd), openStart, slice.openEnd) + if (openEnd < slice.openEnd) + slice = new Slice(closeRange(slice.content, 1, openEnd, slice.openEnd, 0, 0), slice.openStart, openEnd) + return slice +} + +// Trick from jQuery -- some elements must be wrapped in other +// elements for innerHTML to work. I.e. if you do `div.innerHTML = +// ".."` the table cells are ignored. +const wrapMap = {thead: ["table"], colgroup: ["table"], col: ["table", "colgroup"], + tr: ["table", "tbody"], td: ["table", "tbody", "tr"], th: ["table", "tbody", "tr"]} + +let _detachedDoc = null +function detachedDoc() { + return _detachedDoc || (_detachedDoc = document.implementation.createHTMLDocument("title")) +} + +function readHTML(html) { + let metas = /(\s*]*>)*/.exec(html) + if (metas) html = html.slice(metas[0].length) + let elt = detachedDoc().createElement("div") + let firstTag = /(?:]*>)*<([a-z][^>\s]+)/i.exec(html), wrap, depth = 0 + if (wrap = firstTag && wrapMap[firstTag[1].toLowerCase()]) { + html = wrap.map(n => "<" + n + ">").join("") + html + wrap.map(n => "").reverse().join("") + depth = wrap.length + } + elt.innerHTML = html + for (let i = 0; i < depth; i++) elt = elt.firstChild + return elt +} + +function addContext(slice, context) { + if (!slice.size) return slice + let schema = slice.content.firstChild.type.schema, array + try { array = JSON.parse(context) } + catch(e) { return slice } + let {content, openStart, openEnd} = slice + for (let i = array.length - 2; i >= 0; i -= 2) { + let type = schema.nodes[array[i]] + if (!type || type.hasRequiredAttrs()) break + content = Fragment.from(type.create(array[i + 1], content)) + openStart++; openEnd++ + } + return new Slice(content, openStart, openEnd) +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/src/decoration.js b/packages/tiptap-extensions/node_modules/prosemirror-view/src/decoration.js new file mode 100644 index 0000000000..2c5796aa25 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/src/decoration.js @@ -0,0 +1,669 @@ +function compareObjs(a, b) { + if (a == b) return true + for (let p in a) if (a[p] !== b[p]) return false + for (let p in b) if (!(p in a)) return false + return true +} + +class WidgetType { + constructor(toDOM, spec) { + this.spec = spec || noSpec + this.side = this.spec.side || 0 + this.toDOM = toDOM + } + + map(mapping, span, offset, oldOffset) { + let {pos, deleted} = mapping.mapResult(span.from + oldOffset, this.side < 0 ? -1 : 1) + return deleted ? null : new Decoration(pos - offset, pos - offset, this) + } + + valid() { return true } + + eq(other) { + return this == other || + (other instanceof WidgetType && + (this.spec.key && this.spec.key == other.spec.key || + this.toDOM == other.toDOM && compareObjs(this.spec, other.spec))) + } +} + +class InlineType { + constructor(attrs, spec) { + this.spec = spec || noSpec + this.attrs = attrs + } + + map(mapping, span, offset, oldOffset) { + let from = mapping.map(span.from + oldOffset, this.spec.inclusiveStart ? -1 : 1) - offset + let to = mapping.map(span.to + oldOffset, this.spec.inclusiveEnd ? 1 : -1) - offset + return from >= to ? null : new Decoration(from, to, this) + } + + valid(_, span) { return span.from < span.to } + + eq(other) { + return this == other || + (other instanceof InlineType && compareObjs(this.attrs, other.attrs) && + compareObjs(this.spec, other.spec)) + } + + static is(span) { return span.type instanceof InlineType } +} + +class NodeType { + constructor(attrs, spec) { + this.spec = spec || noSpec + this.attrs = attrs + } + + map(mapping, span, offset, oldOffset) { + let from = mapping.mapResult(span.from + oldOffset, 1) + if (from.deleted) return null + let to = mapping.mapResult(span.to + oldOffset, -1) + if (to.deleted || to.pos <= from.pos) return null + return new Decoration(from.pos - offset, to.pos - offset, this) + } + + valid(node, span) { + let {index, offset} = node.content.findIndex(span.from) + return offset == span.from && offset + node.child(index).nodeSize == span.to + } + + eq(other) { + return this == other || + (other instanceof NodeType && compareObjs(this.attrs, other.attrs) && + compareObjs(this.spec, other.spec)) + } +} + +// ::- Decoration objects can be provided to the view through the +// [`decorations` prop](#view.EditorProps.decorations). They come in +// several variants—see the static members of this class for details. +export class Decoration { + constructor(from, to, type) { + // :: number + // The start position of the decoration. + this.from = from + // :: number + // The end position. Will be the same as `from` for [widget + // decorations](#view.Decoration^widget). + this.to = to + this.type = type + } + + copy(from, to) { + return new Decoration(from, to, this.type) + } + + eq(other) { + return this.type.eq(other.type) && this.from == other.from && this.to == other.to + } + + map(mapping, offset, oldOffset) { + return this.type.map(mapping, this, offset, oldOffset) + } + + // :: (number, union<(view: EditorView, getPos: () → number) → dom.Node, dom.Node>, ?Object) → Decoration + // Creates a widget decoration, which is a DOM node that's shown in + // the document at the given position. It is recommended that you + // delay rendering the widget by passing a function that will be + // called when the widget is actually drawn in a view, but you can + // also directly pass a DOM node. `getPos` can be used to find the + // widget's current document position. + // + // spec::- These options are supported: + // + // side:: ?number + // Controls which side of the document position this widget is + // associated with. When negative, it is drawn before a cursor + // at its position, and content inserted at that position ends + // up after the widget. When zero (the default) or positive, the + // widget is drawn after the cursor and content inserted there + // ends up before the widget. + // + // When there are multiple widgets at a given position, their + // `side` values determine the order in which they appear. Those + // with lower values appear first. The ordering of widgets with + // the same `side` value is unspecified. + // + // When `marks` is null, `side` also determines the marks that + // the widget is wrapped in—those of the node before when + // negative, those of the node after when positive. + // + // marks:: ?[Mark] + // The precise set of marks to draw around the widget. + // + // stopEvent:: ?(event: dom.Event) → bool + // Can be used to control which DOM events, when they bubble out + // of this widget, the editor view should ignore. + // + // key:: ?string + // When comparing decorations of this type (in order to decide + // whether it needs to be redrawn), ProseMirror will by default + // compare the widget DOM node by identity. If you pass a key, + // that key will be compared instead, which can be useful when + // you generate decorations on the fly and don't want to store + // and reuse DOM nodes. Make sure that any widgets with the same + // key are interchangeable—if widgets differ in, for example, + // the behavior of some event handler, they should get + // different keys. + static widget(pos, toDOM, spec) { + return new Decoration(pos, pos, new WidgetType(toDOM, spec)) + } + + // :: (number, number, DecorationAttrs, ?Object) → Decoration + // Creates an inline decoration, which adds the given attributes to + // each inline node between `from` and `to`. + // + // spec::- These options are recognized: + // + // inclusiveStart:: ?bool + // Determines how the left side of the decoration is + // [mapped](#transform.Position_Mapping) when content is + // inserted directly at that position. By default, the decoration + // won't include the new content, but you can set this to `true` + // to make it inclusive. + // + // inclusiveEnd:: ?bool + // Determines how the right side of the decoration is mapped. + // See + // [`inclusiveStart`](#view.Decoration^inline^spec.inclusiveStart). + static inline(from, to, attrs, spec) { + return new Decoration(from, to, new InlineType(attrs, spec)) + } + + // :: (number, number, DecorationAttrs, ?Object) → Decoration + // Creates a node decoration. `from` and `to` should point precisely + // before and after a node in the document. That node, and only that + // node, will receive the given attributes. + // + // spec::- + // + // Optional information to store with the decoration. It + // is also used when comparing decorators for equality. + static node(from, to, attrs, spec) { + return new Decoration(from, to, new NodeType(attrs, spec)) + } + + // :: Object + // The spec provided when creating this decoration. Can be useful + // if you've stored extra information in that object. + get spec() { return this.type.spec } +} + +// DecorationAttrs:: interface +// A set of attributes to add to a decorated node. Most properties +// simply directly correspond to DOM attributes of the same name, +// which will be set to the property's value. These are exceptions: +// +// class:: ?string +// A CSS class name or a space-separated set of class names to be +// _added_ to the classes that the node already had. +// +// style:: ?string +// A string of CSS to be _added_ to the node's existing `style` property. +// +// nodeName:: ?string +// When non-null, the target node is wrapped in a DOM element of +// this type (and the other attributes are applied to this element). + +const none = [], noSpec = {} + +// ::- A collection of [decorations](#view.Decoration), organized in +// such a way that the drawing algorithm can efficiently use and +// compare them. This is a persistent data structure—it is not +// modified, updates create a new value. +export class DecorationSet { + constructor(local, children) { + this.local = local && local.length ? local : none + this.children = children && children.length ? children : none + } + + // :: (Node, [Decoration]) → DecorationSet + // Create a set of decorations, using the structure of the given + // document. + static create(doc, decorations) { + return decorations.length ? buildTree(decorations, doc, 0, noSpec) : empty + } + + // :: (?number, ?number, ?(spec: Object) → bool) → [Decoration] + // Find all decorations in this set which touch the given range + // (including decorations that start or end directly at the + // boundaries) and match the given predicate on their spec. When + // `start` and `end` are omitted, all decorations in the set are + // considered. When `predicate` isn't given, all decorations are + // assumed to match. + find(start, end, predicate) { + let result = [] + this.findInner(start == null ? 0 : start, end == null ? 1e9 : end, result, 0, predicate) + return result + } + + findInner(start, end, result, offset, predicate) { + for (let i = 0; i < this.local.length; i++) { + let span = this.local[i] + if (span.from <= end && span.to >= start && (!predicate || predicate(span.spec))) + result.push(span.copy(span.from + offset, span.to + offset)) + } + for (let i = 0; i < this.children.length; i += 3) { + if (this.children[i] < end && this.children[i + 1] > start) { + let childOff = this.children[i] + 1 + this.children[i + 2].findInner(start - childOff, end - childOff, result, offset + childOff, predicate) + } + } + } + + // :: (Mapping, Node, ?Object) → DecorationSet + // Map the set of decorations in response to a change in the + // document. + // + // options::- An optional set of options. + // + // onRemove:: ?(decorationSpec: Object) + // When given, this function will be called for each decoration + // that gets dropped as a result of the mapping, passing the + // spec of that decoration. + map(mapping, doc, options) { + if (this == empty || mapping.maps.length == 0) return this + return this.mapInner(mapping, doc, 0, 0, options || noSpec) + } + + mapInner(mapping, node, offset, oldOffset, options) { + let newLocal + for (let i = 0; i < this.local.length; i++) { + let mapped = this.local[i].map(mapping, offset, oldOffset) + if (mapped && mapped.type.valid(node, mapped)) (newLocal || (newLocal = [])).push(mapped) + else if (options.onRemove) options.onRemove(this.local[i].spec) + } + + if (this.children.length) + return mapChildren(this.children, newLocal, mapping, node, offset, oldOffset, options) + else + return newLocal ? new DecorationSet(newLocal.sort(byPos)) : empty + } + + // :: (Node, [Decoration]) → DecorationSet + // Add the given array of decorations to the ones in the set, + // producing a new set. Needs access to the current document to + // create the appropriate tree structure. + add(doc, decorations) { + if (!decorations.length) return this + if (this == empty) return DecorationSet.create(doc, decorations) + return this.addInner(doc, decorations, 0) + } + + addInner(doc, decorations, offset) { + let children, childIndex = 0 + doc.forEach((childNode, childOffset) => { + let baseOffset = childOffset + offset, found + if (!(found = takeSpansForNode(decorations, childNode, baseOffset))) return + + if (!children) children = this.children.slice() + while (childIndex < children.length && children[childIndex] < childOffset) childIndex += 3 + if (children[childIndex] == childOffset) + children[childIndex + 2] = children[childIndex + 2].addInner(childNode, found, baseOffset + 1) + else + children.splice(childIndex, 0, childOffset, childOffset + childNode.nodeSize, buildTree(found, childNode, baseOffset + 1, noSpec)) + childIndex += 3 + }) + + let local = moveSpans(childIndex ? withoutNulls(decorations) : decorations, -offset) + return new DecorationSet(local.length ? this.local.concat(local).sort(byPos) : this.local, + children || this.children) + } + + // :: ([Decoration]) → DecorationSet + // Create a new set that contains the decorations in this set, minus + // the ones in the given array. + remove(decorations) { + if (decorations.length == 0 || this == empty) return this + return this.removeInner(decorations, 0) + } + + removeInner(decorations, offset) { + let children = this.children, local = this.local + for (let i = 0; i < children.length; i += 3) { + let found, from = children[i] + offset, to = children[i + 1] + offset + for (let j = 0, span; j < decorations.length; j++) if (span = decorations[j]) { + if (span.from > from && span.to < to) { + decorations[j] = null + ;(found || (found = [])).push(span) + } + } + if (!found) continue + if (children == this.children) children = this.children.slice() + let removed = children[i + 2].removeInner(found, from + 1) + if (removed != empty) { + children[i + 2] = removed + } else { + children.splice(i, 3) + i -= 3 + } + } + if (local.length) for (let i = 0, span; i < decorations.length; i++) if (span = decorations[i]) { + for (let j = 0; j < local.length; j++) if (local[j].type.eq(span.type)) { + if (local == this.local) local = this.local.slice() + local.splice(j--, 1) + } + } + if (children == this.children && local == this.local) return this + return local.length || children.length ? new DecorationSet(local, children) : empty + } + + forChild(offset, node) { + if (this == empty) return this + if (node.isLeaf) return DecorationSet.empty + + let child, local + for (let i = 0; i < this.children.length; i += 3) if (this.children[i] >= offset) { + if (this.children[i] == offset) child = this.children[i + 2] + break + } + let start = offset + 1, end = start + node.content.size + for (let i = 0; i < this.local.length; i++) { + let dec = this.local[i] + if (dec.from < end && dec.to > start && (dec.type instanceof InlineType)) { + let from = Math.max(start, dec.from) - start, to = Math.min(end, dec.to) - start + if (from < to) (local || (local = [])).push(dec.copy(from, to)) + } + } + if (local) { + let localSet = new DecorationSet(local.sort(byPos)) + return child ? new DecorationGroup([localSet, child]) : localSet + } + return child || empty + } + + eq(other) { + if (this == other) return true + if (!(other instanceof DecorationSet) || + this.local.length != other.local.length || + this.children.length != other.children.length) return false + for (let i = 0; i < this.local.length; i++) + if (!this.local[i].eq(other.local[i])) return false + for (let i = 0; i < this.children.length; i += 3) + if (this.children[i] != other.children[i] || + this.children[i + 1] != other.children[i + 1] || + !this.children[i + 2].eq(other.children[i + 2])) return false + return true + } + + locals(node) { + return removeOverlap(this.localsInner(node)) + } + + localsInner(node) { + if (this == empty) return none + if (node.inlineContent || !this.local.some(InlineType.is)) return this.local + let result = [] + for (let i = 0; i < this.local.length; i++) { + if (!(this.local[i].type instanceof InlineType)) + result.push(this.local[i]) + } + return result + } +} + +const empty = new DecorationSet() + +// :: DecorationSet +// The empty set of decorations. +DecorationSet.empty = empty + +DecorationSet.removeOverlap = removeOverlap + +// :- An abstraction that allows the code dealing with decorations to +// treat multiple DecorationSet objects as if it were a single object +// with (a subset of) the same interface. +class DecorationGroup { + constructor(members) { + this.members = members + } + + forChild(offset, child) { + if (child.isLeaf) return DecorationSet.empty + let found = [] + for (let i = 0; i < this.members.length; i++) { + let result = this.members[i].forChild(offset, child) + if (result == empty) continue + if (result instanceof DecorationGroup) found = found.concat(result.members) + else found.push(result) + } + return DecorationGroup.from(found) + } + + eq(other) { + if (!(other instanceof DecorationGroup) || + other.members.length != this.members.length) return false + for (let i = 0; i < this.members.length; i++) + if (!this.members[i].eq(other.members[i])) return false + return true + } + + locals(node) { + let result, sorted = true + for (let i = 0; i < this.members.length; i++) { + let locals = this.members[i].localsInner(node) + if (!locals.length) continue + if (!result) { + result = locals + } else { + if (sorted) { + result = result.slice() + sorted = false + } + for (let j = 0; j < locals.length; j++) result.push(locals[j]) + } + } + return result ? removeOverlap(sorted ? result : result.sort(byPos)) : none + } + + // : ([DecorationSet]) → union + // Create a group for the given array of decoration sets, or return + // a single set when possible. + static from(members) { + switch (members.length) { + case 0: return empty + case 1: return members[0] + default: return new DecorationGroup(members) + } + } +} + +function mapChildren(oldChildren, newLocal, mapping, node, offset, oldOffset, options) { + let children = oldChildren.slice() + + // Mark the children that are directly touched by changes, and + // move those that are after the changes. + let shift = (oldStart, oldEnd, newStart, newEnd) => { + for (let i = 0; i < children.length; i += 3) { + let end = children[i + 1], dSize + if (end == -1 || oldStart > end + oldOffset) continue + if (oldEnd >= children[i] + oldOffset) { + children[i + 1] = -1 + } else if (dSize = (newEnd - newStart) - (oldEnd - oldStart) + (oldOffset - offset)) { + children[i] += dSize + children[i + 1] += dSize + } + } + } + for (let i = 0; i < mapping.maps.length; i++) mapping.maps[i].forEach(shift) + + // Find the child nodes that still correspond to a single node, + // recursively call mapInner on them and update their positions. + let mustRebuild = false + for (let i = 0; i < children.length; i += 3) if (children[i + 1] == -1) { // Touched nodes + let from = mapping.map(children[i] + oldOffset), fromLocal = from - offset + if (fromLocal < 0 || fromLocal >= node.content.size) { + mustRebuild = true + continue + } + // Must read oldChildren because children was tagged with -1 + let to = mapping.map(oldChildren[i + 1] + oldOffset, -1), toLocal = to - offset + let {index, offset: childOffset} = node.content.findIndex(fromLocal) + let childNode = node.maybeChild(index) + if (childNode && childOffset == fromLocal && childOffset + childNode.nodeSize == toLocal) { + let mapped = children[i + 2].mapInner(mapping, childNode, from + 1, children[i] + oldOffset + 1, options) + if (mapped != empty) { + children[i] = fromLocal + children[i + 1] = toLocal + children[i + 2] = mapped + } else { + children[i + 1] = -2 + mustRebuild = true + } + } else { + mustRebuild = true + } + } + + // Remaining children must be collected and rebuilt into the appropriate structure + if (mustRebuild) { + let decorations = mapAndGatherRemainingDecorations(children, oldChildren, newLocal || [], mapping, + offset, oldOffset, options) + let built = buildTree(decorations, node, 0, options) + newLocal = built.local + for (let i = 0; i < children.length; i += 3) if (children[i + 1] < 0) { + children.splice(i, 3) + i -= 3 + } + for (let i = 0, j = 0; i < built.children.length; i += 3) { + let from = built.children[i] + while (j < children.length && children[j] < from) j += 3 + children.splice(j, 0, built.children[i], built.children[i + 1], built.children[i + 2]) + } + } + + return new DecorationSet(newLocal && newLocal.sort(byPos), children) +} + +function moveSpans(spans, offset) { + if (!offset || !spans.length) return spans + let result = [] + for (let i = 0; i < spans.length; i++) { + let span = spans[i] + result.push(new Decoration(span.from + offset, span.to + offset, span.type)) + } + return result +} + +function mapAndGatherRemainingDecorations(children, oldChildren, decorations, mapping, offset, oldOffset, options) { + // Gather all decorations from the remaining marked children + function gather(set, oldOffset) { + for (let i = 0; i < set.local.length; i++) { + let mapped = set.local[i].map(mapping, offset, oldOffset) + if (mapped) decorations.push(mapped) + else if (options.onRemove) options.onRemove(set.local[i].spec) + } + for (let i = 0; i < set.children.length; i += 3) + gather(set.children[i + 2], set.children[i] + oldOffset + 1) + } + for (let i = 0; i < children.length; i += 3) if (children[i + 1] == -1) + gather(children[i + 2], oldChildren[i] + oldOffset + 1) + + return decorations +} + +function takeSpansForNode(spans, node, offset) { + if (node.isLeaf) return null + let end = offset + node.nodeSize, found = null + for (let i = 0, span; i < spans.length; i++) { + if ((span = spans[i]) && span.from > offset && span.to < end) { + ;(found || (found = [])).push(span) + spans[i] = null + } + } + return found +} + +function withoutNulls(array) { + let result = [] + for (let i = 0; i < array.length; i++) + if (array[i] != null) result.push(array[i]) + return result +} + +// : ([Decoration], Node, number) → DecorationSet +// Build up a tree that corresponds to a set of decorations. `offset` +// is a base offset that should be subtractet from the `from` and `to` +// positions in the spans (so that we don't have to allocate new spans +// for recursive calls). +function buildTree(spans, node, offset, options) { + let children = [], hasNulls = false + node.forEach((childNode, localStart) => { + let found = takeSpansForNode(spans, childNode, localStart + offset) + if (found) { + hasNulls = true + let subtree = buildTree(found, childNode, offset + localStart + 1, options) + if (subtree != empty) + children.push(localStart, localStart + childNode.nodeSize, subtree) + } + }) + let locals = moveSpans(hasNulls ? withoutNulls(spans) : spans, -offset).sort(byPos) + for (let i = 0; i < locals.length; i++) if (!locals[i].type.valid(node, locals[i])) { + if (options.onRemove) options.onRemove(locals[i].spec) + locals.splice(i--, 1) + } + return locals.length || children.length ? new DecorationSet(locals, children) : empty +} + +// : (Decoration, Decoration) → number +// Used to sort decorations so that ones with a low start position +// come first, and within a set with the same start position, those +// with an smaller end position come first. +function byPos(a, b) { + return a.from - b.from || a.to - b.to +} + +// : ([Decoration]) → [Decoration] +// Scan a sorted array of decorations for partially overlapping spans, +// and split those so that only fully overlapping spans are left (to +// make subsequent rendering easier). Will return the input array if +// no partially overlapping spans are found (the common case). +function removeOverlap(spans) { + let working = spans + for (let i = 0; i < working.length - 1; i++) { + let span = working[i] + if (span.from != span.to) for (let j = i + 1; j < working.length; j++) { + let next = working[j] + if (next.from == span.from) { + if (next.to != span.to) { + if (working == spans) working = spans.slice() + // Followed by a partially overlapping larger span. Split that + // span. + working[j] = next.copy(next.from, span.to) + insertAhead(working, j + 1, next.copy(span.to, next.to)) + } + continue + } else { + if (next.from < span.to) { + if (working == spans) working = spans.slice() + // The end of this one overlaps with a subsequent span. Split + // this one. + working[i] = span.copy(span.from, next.from) + insertAhead(working, j, span.copy(next.from, span.to)) + } + break + } + } + } + return working +} + +function insertAhead(array, i, deco) { + while (i < array.length && byPos(deco, array[i]) > 0) i++ + array.splice(i, 0, deco) +} + +// : (EditorView) → union +// Get the decorations associated with the current props of a view. +export function viewDecorations(view) { + let found = [] + view.someProp("decorations", f => { + let result = f(view.state) + if (result && result != empty) found.push(result) + }) + if (view.cursorWrapper) + found.push(DecorationSet.create(view.state.doc, [view.cursorWrapper.deco])) + return DecorationGroup.from(found) +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/src/dom.js b/packages/tiptap-extensions/node_modules/prosemirror-view/src/dom.js new file mode 100644 index 0000000000..728f3b883f --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/src/dom.js @@ -0,0 +1,75 @@ +import browser from "./browser" + +export const domIndex = function(node) { + for (var index = 0;; index++) { + node = node.previousSibling + if (!node) return index + } +} + +export const parentNode = function(node) { + let parent = node.parentNode + return parent && parent.nodeType == 11 ? parent.host : parent +} + +export const textRange = function(node, from, to) { + let range = document.createRange() + range.setEnd(node, to == null ? node.nodeValue.length : to) + range.setStart(node, from || 0) + return range +} + +// Scans forward and backward through DOM positions equivalent to the +// given one to see if the two are in the same place (i.e. after a +// text node vs at the end of that text node) +export const isEquivalentPosition = function(node, off, targetNode, targetOff) { + return targetNode && (scanFor(node, off, targetNode, targetOff, -1) || + scanFor(node, off, targetNode, targetOff, 1)) +} + +const atomElements = /^(img|br|input|textarea|hr)$/i + +function scanFor(node, off, targetNode, targetOff, dir) { + for (;;) { + if (node == targetNode && off == targetOff) return true + if (off == (dir < 0 ? 0 : nodeSize(node))) { + let parent = node.parentNode + if (parent.nodeType != 1 || hasBlockDesc(node) || atomElements.test(node.nodeName) || node.contentEditable == "false") + return false + off = domIndex(node) + (dir < 0 ? 0 : 1) + node = parent + } else if (node.nodeType == 1) { + node = node.childNodes[off + (dir < 0 ? -1 : 0)] + off = dir < 0 ? nodeSize(node) : 0 + } else { + return false + } + } +} + +export function nodeSize(node) { + return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length +} + +function hasBlockDesc(dom) { + let desc + for (let cur = dom; cur; cur = cur.parentNode) if (desc = cur.pmViewDesc) break + return desc && desc.node && desc.node.isBlock && (desc.dom == dom || desc.contentDOM == dom) +} + +// Work around Chrome issue https://bugs.chromium.org/p/chromium/issues/detail?id=447523 +// (isCollapsed inappropriately returns true in shadow dom) +export const selectionCollapsed = function(domSel) { + let collapsed = domSel.isCollapsed + if (collapsed && browser.chrome && domSel.rangeCount && !domSel.getRangeAt(0).collapsed) + collapsed = false + return collapsed +} + +export function keyEvent(keyCode, key) { + let event = document.createEvent("Event") + event.initEvent("keydown", true, true) + event.keyCode = keyCode + event.key = event.code = key + return event +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/src/domchange.js b/packages/tiptap-extensions/node_modules/prosemirror-view/src/domchange.js new file mode 100644 index 0000000000..e1c3af7431 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/src/domchange.js @@ -0,0 +1,301 @@ +import {Fragment, DOMParser} from "prosemirror-model" +import {Selection, TextSelection} from "prosemirror-state" + +import {selectionBetween, selectionFromDOM, selectionToDOM} from "./selection" +import {selectionCollapsed, keyEvent} from "./dom" +import browser from "./browser" + +// Note that all referencing and parsing is done with the +// start-of-operation selection and document, since that's the one +// that the DOM represents. If any changes came in in the meantime, +// the modification is mapped over those before it is applied, in +// readDOMChange. + +function parseBetween(view, from_, to_) { + let {node: parent, fromOffset, toOffset, from, to} = view.docView.parseRange(from_, to_) + + let domSel = view.root.getSelection(), find = null, anchor = domSel.anchorNode + if (anchor && view.dom.contains(anchor.nodeType == 1 ? anchor : anchor.parentNode)) { + find = [{node: anchor, offset: domSel.anchorOffset}] + if (!selectionCollapsed(domSel)) + find.push({node: domSel.focusNode, offset: domSel.focusOffset}) + } + // Work around issue in Chrome where backspacing sometimes replaces + // the deleted content with a random BR node (issues #799, #831) + if (browser.chrome && view.lastKeyCode === 8) { + for (let off = toOffset; off > fromOffset; off--) { + let node = parent.childNodes[off - 1], desc = node.pmViewDesc + if (node.nodeType == "BR" && !desc) { toOffset = off; break } + if (!desc || desc.size) break + } + } + let startDoc = view.state.doc + let parser = view.someProp("domParser") || DOMParser.fromSchema(view.state.schema) + let $from = startDoc.resolve(from) + + let sel = null, doc = parser.parse(parent, { + topNode: $from.parent, + topMatch: $from.parent.contentMatchAt($from.index()), + topOpen: true, + from: fromOffset, + to: toOffset, + preserveWhitespace: $from.parent.type.spec.code ? "full" : true, + editableContent: true, + findPositions: find, + ruleFromNode, + context: $from + }) + if (find && find[0].pos != null) { + let anchor = find[0].pos, head = find[1] && find[1].pos + if (head == null) head = anchor + sel = {anchor: anchor + from, head: head + from} + } + return {doc, sel, from, to} +} + +function ruleFromNode(dom) { + let desc = dom.pmViewDesc + if (desc) { + return desc.parseRule() + } else if (dom.nodeName == "BR" && dom.parentNode) { + // Safari replaces the list item or table cell with a BR + // directly in the list node (?!) if you delete the last + // character in a list item or table cell (#708, #862) + if (browser.safari && /^(ul|ol)$/i.test(dom.parentNode.nodeName)) { + let skip = document.createElement("div") + skip.appendChild(document.createElement("li")) + return {skip} + } else if (dom.parentNode.lastChild == dom || browser.safari && /^(tr|table)$/i.test(dom.parentNode.nodeName)) { + return {ignore: true} + } + } else if (dom.nodeName == "IMG" && dom.getAttribute("mark-placeholder")) { + return {ignore: true} + } +} + +export function readDOMChange(view, from, to, typeOver) { + if (from < 0) { + let origin = view.lastSelectionTime > Date.now() - 50 ? view.lastSelectionOrigin : null + let newSel = selectionFromDOM(view, origin) + if (!view.state.selection.eq(newSel)) { + let tr = view.state.tr.setSelection(newSel) + if (origin == "pointer") tr.setMeta("pointer", true) + else if (origin == "key") tr.scrollIntoView() + view.dispatch(tr) + } + return + } + + let $before = view.state.doc.resolve(from) + let shared = $before.sharedDepth(to) + from = $before.before(shared + 1) + to = view.state.doc.resolve(to).after(shared + 1) + + let sel = view.state.selection + let parse = parseBetween(view, from, to) + + let doc = view.state.doc, compare = doc.slice(parse.from, parse.to) + let preferredPos, preferredSide + // Prefer anchoring to end when Backspace is pressed + if (view.lastKeyCode === 8 && Date.now() - 100 < view.lastKeyCodeTime) { + preferredPos = view.state.selection.to + preferredSide = "end" + } else { + preferredPos = view.state.selection.from + preferredSide = "start" + } + view.lastKeyCode = null + + let change = findDiff(compare.content, parse.doc.content, parse.from, preferredPos, preferredSide) + if (!change) { + if (typeOver && sel instanceof TextSelection && !sel.empty && sel.$head.sameParent(sel.$anchor) && + !view.composing && !(parse.sel && parse.sel.anchor != parse.sel.head)) { + change = {start: sel.from, endA: sel.to, endB: sel.to} + } else { + if (parse.sel) { + let sel = resolveSelection(view, view.state.doc, parse.sel) + if (sel && !sel.eq(view.state.selection)) view.dispatch(view.state.tr.setSelection(sel)) + } + return + } + } + view.domChangeCount++ + // Handle the case where overwriting a selection by typing matches + // the start or end of the selected content, creating a change + // that's smaller than what was actually overwritten. + if (view.state.selection.from < view.state.selection.to && + change.start == change.endB && + view.state.selection instanceof TextSelection) { + if (change.start > view.state.selection.from && change.start <= view.state.selection.from + 2) { + change.start = view.state.selection.from + } else if (change.endA < view.state.selection.to && change.endA >= view.state.selection.to - 2) { + change.endB += (view.state.selection.to - change.endA) + change.endA = view.state.selection.to + } + } + + // IE11 will insert a non-breaking space _ahead_ of the space after + // the cursor space when adding a space before another space. When + // that happened, adjust the change to cover the space instead. + if (browser.ie && browser.ie_version <= 11 && change.endB == change.start + 1 && + change.endA == change.start && change.start > parse.from && + parse.doc.textBetween(change.start - parse.from - 1, change.start - parse.from + 1) == " \u00a0") { + change.start-- + change.endA-- + change.endB-- + } + + let $from = parse.doc.resolveNoCache(change.start - parse.from) + let $to = parse.doc.resolveNoCache(change.endB - parse.from) + let nextSel + // If this looks like the effect of pressing Enter, just dispatch an + // Enter key instead. + if (!$from.sameParent($to) && $from.pos < parse.doc.content.size && + (nextSel = Selection.findFrom(parse.doc.resolve($from.pos + 1), 1, true)) && + nextSel.head == $to.pos && + view.someProp("handleKeyDown", f => f(view, keyEvent(13, "Enter")))) + return + // Same for backspace + if (view.state.selection.anchor > change.start && + looksLikeJoin(doc, change.start, change.endA, $from, $to) && + view.someProp("handleKeyDown", f => f(view, keyEvent(8, "Backspace")))) { + if (browser.android && browser.chrome) view.domObserver.suppressSelectionUpdates() // #820 + return + } + + let chFrom = change.start, chTo = change.endA + + let tr, storedMarks, markChange, $from1 + if ($from.sameParent($to) && $from.parent.inlineContent) { + if ($from.pos == $to.pos) { // Deletion + // IE11 sometimes weirdly moves the DOM selection around after + // backspacing out the first element in a textblock + if (browser.ie && browser.ie_version <= 11 && $from.parentOffset == 0) { + view.domObserver.suppressSelectionUpdates() + setTimeout(() => selectionToDOM(view), 20) + } + tr = view.state.tr.delete(chFrom, chTo) + storedMarks = doc.resolve(change.start).marksAcross(doc.resolve(change.endA)) + } else if ( // Adding or removing a mark + change.endA == change.endB && ($from1 = doc.resolve(change.start)) && + (markChange = isMarkChange($from.parent.content.cut($from.parentOffset, $to.parentOffset), + $from1.parent.content.cut($from1.parentOffset, change.endA - $from1.start()))) + ) { + tr = view.state.tr + if (markChange.type == "add") tr.addMark(chFrom, chTo, markChange.mark) + else tr.removeMark(chFrom, chTo, markChange.mark) + } else if ($from.parent.child($from.index()).isText && $from.index() == $to.index() - ($to.textOffset ? 0 : 1)) { + // Both positions in the same text node -- simply insert text + let text = $from.parent.textBetween($from.parentOffset, $to.parentOffset) + if (view.someProp("handleTextInput", f => f(view, chFrom, chTo, text))) return + tr = view.state.tr.insertText(text, chFrom, chTo) + } + } + + if (!tr) + tr = view.state.tr.replace(chFrom, chTo, parse.doc.slice(change.start - parse.from, change.endB - parse.from)) + if (parse.sel) { + let sel = resolveSelection(view, tr.doc, parse.sel) + // Chrome Android will sometimes, during composition, report the + // selection in the wrong place. If it looks like that is + // happening, don't update the selection. + // Edge just doesn't move the cursor forward when you start typing + // in an empty block or between br nodes. + if (sel && !(browser.chrome && browser.android && view.composing && sel.empty && sel.head == chFrom || + browser.ie && sel.empty && sel.head == chFrom)) + tr.setSelection(sel) + } + if (storedMarks) tr.ensureMarks(storedMarks) + view.dispatch(tr.scrollIntoView()) +} + +function resolveSelection(view, doc, parsedSel) { + if (Math.max(parsedSel.anchor, parsedSel.head) > doc.content.size) return null + return selectionBetween(view, doc.resolve(parsedSel.anchor), doc.resolve(parsedSel.head)) +} + +// : (Fragment, Fragment) → ?{mark: Mark, type: string} +// Given two same-length, non-empty fragments of inline content, +// determine whether the first could be created from the second by +// removing or adding a single mark type. +function isMarkChange(cur, prev) { + let curMarks = cur.firstChild.marks, prevMarks = prev.firstChild.marks + let added = curMarks, removed = prevMarks, type, mark, update + for (let i = 0; i < prevMarks.length; i++) added = prevMarks[i].removeFromSet(added) + for (let i = 0; i < curMarks.length; i++) removed = curMarks[i].removeFromSet(removed) + if (added.length == 1 && removed.length == 0) { + mark = added[0] + type = "add" + update = node => node.mark(mark.addToSet(node.marks)) + } else if (added.length == 0 && removed.length == 1) { + mark = removed[0] + type = "remove" + update = node => node.mark(mark.removeFromSet(node.marks)) + } else { + return null + } + let updated = [] + for (let i = 0; i < prev.childCount; i++) updated.push(update(prev.child(i))) + if (Fragment.from(updated).eq(cur)) return {mark, type} +} + +function looksLikeJoin(old, start, end, $newStart, $newEnd) { + if (!$newStart.parent.isTextblock || + // The content must have shrunk + end - start <= $newEnd.pos - $newStart.pos || + // newEnd must point directly at or after the end of the block that newStart points into + skipClosingAndOpening($newStart, true, false) < $newEnd.pos) + return false + + let $start = old.resolve(start) + // Start must be at the end of a block + if ($start.parentOffset < $start.parent.content.size || !$start.parent.isTextblock) + return false + let $next = old.resolve(skipClosingAndOpening($start, true, true)) + // The next textblock must start before end and end near it + if (!$next.parent.isTextblock || $next.pos > end || + skipClosingAndOpening($next, true, false) < end) + return false + + // The fragments after the join point must match + return $newStart.parent.content.cut($newStart.parentOffset).eq($next.parent.content) +} + +function skipClosingAndOpening($pos, fromEnd, mayOpen) { + let depth = $pos.depth, end = fromEnd ? $pos.end() : $pos.pos + while (depth > 0 && (fromEnd || $pos.indexAfter(depth) == $pos.node(depth).childCount)) { + depth-- + end++ + fromEnd = false + } + if (mayOpen) { + let next = $pos.node(depth).maybeChild($pos.indexAfter(depth)) + while (next && !next.isLeaf) { + next = next.firstChild + end++ + } + } + return end +} + +function findDiff(a, b, pos, preferredPos, preferredSide) { + let start = a.findDiffStart(b, pos) + if (start == null) return null + let {a: endA, b: endB} = a.findDiffEnd(b, pos + a.size, pos + b.size) + if (preferredSide == "end") { + let adjust = Math.max(0, start - Math.min(endA, endB)) + preferredPos -= endA + adjust - start + } + if (endA < start && a.size < b.size) { + let move = preferredPos <= start && preferredPos >= endA ? start - preferredPos : 0 + start -= move + endB = start + (endB - endA) + endA = start + } else if (endB < start) { + let move = preferredPos <= start && preferredPos >= endB ? start - preferredPos : 0 + start -= move + endA = start + (endA - endB) + endB = start + } + return {start, endA, endB} +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/src/domcoords.js b/packages/tiptap-extensions/node_modules/prosemirror-view/src/domcoords.js new file mode 100644 index 0000000000..6ead2ef7c0 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/src/domcoords.js @@ -0,0 +1,434 @@ +import {nodeSize, textRange, parentNode} from "./dom" +import browser from "./browser" + +function windowRect(win) { + return {left: 0, right: win.innerWidth, + top: 0, bottom: win.innerHeight} +} + +function getSide(value, side) { + return typeof value == "number" ? value : value[side] +} + +export function scrollRectIntoView(view, rect, startDOM) { + let scrollThreshold = view.someProp("scrollThreshold") || 0, scrollMargin = view.someProp("scrollMargin") || 5 + let doc = view.dom.ownerDocument, win = doc.defaultView + for (let parent = startDOM || view.dom;; parent = parentNode(parent)) { + if (!parent) break + if (parent.nodeType != 1) continue + let atTop = parent == doc.body || parent.nodeType != 1 + let bounding = atTop ? windowRect(win) : parent.getBoundingClientRect() + let moveX = 0, moveY = 0 + if (rect.top < bounding.top + getSide(scrollThreshold, "top")) + moveY = -(bounding.top - rect.top + getSide(scrollMargin, "top")) + else if (rect.bottom > bounding.bottom - getSide(scrollThreshold, "bottom")) + moveY = rect.bottom - bounding.bottom + getSide(scrollMargin, "bottom") + if (rect.left < bounding.left + getSide(scrollThreshold, "left")) + moveX = -(bounding.left - rect.left + getSide(scrollMargin, "left")) + else if (rect.right > bounding.right - getSide(scrollThreshold, "right")) + moveX = rect.right - bounding.right + getSide(scrollMargin, "right") + if (moveX || moveY) { + if (atTop) { + win.scrollBy(moveX, moveY) + } else { + if (moveY) parent.scrollTop += moveY + if (moveX) parent.scrollLeft += moveX + } + } + if (atTop) break + } +} + +// Store the scroll position of the editor's parent nodes, along with +// the top position of an element near the top of the editor, which +// will be used to make sure the visible viewport remains stable even +// when the size of the content above changes. +export function storeScrollPos(view) { + let rect = view.dom.getBoundingClientRect(), startY = Math.max(0, rect.top) + let refDOM, refTop + for (let x = (rect.left + rect.right) / 2, y = startY + 1; + y < Math.min(innerHeight, rect.bottom); y += 5) { + let dom = view.root.elementFromPoint(x, y) + if (dom == view.dom || !view.dom.contains(dom)) continue + let localRect = dom.getBoundingClientRect() + if (localRect.top >= startY - 20) { + refDOM = dom + refTop = localRect.top + break + } + } + return {refDOM, refTop, stack: scrollStack(view.dom)} +} + +function scrollStack(dom) { + let stack = [], doc = dom.ownerDocument + for (; dom; dom = parentNode(dom)) { + stack.push({dom, top: dom.scrollTop, left: dom.scrollLeft}) + if (dom == doc) break + } + return stack +} + +// Reset the scroll position of the editor's parent nodes to that what +// it was before, when storeScrollPos was called. +export function resetScrollPos({refDOM, refTop, stack}) { + let newRefTop = refDOM ? refDOM.getBoundingClientRect().top : 0 + restoreScrollStack(stack, newRefTop == 0 ? 0 : newRefTop - refTop) +} + +function restoreScrollStack(stack, dTop) { + for (let i = 0; i < stack.length; i++) { + let {dom, top, left} = stack[i] + if (dom.scrollTop != top + dTop) dom.scrollTop = top + dTop + if (dom.scrollLeft != left) dom.scrollLeft = left + } +} + +let preventScrollSupported = null +// Feature-detects support for .focus({preventScroll: true}), and uses +// a fallback kludge when not supported. +export function focusPreventScroll(dom) { + if (dom.setActive) return dom.setActive() // in IE + if (preventScrollSupported) return dom.focus(preventScrollSupported) + + let stored = scrollStack(dom) + dom.focus(preventScrollSupported == null ? { + get preventScroll() { + preventScrollSupported = {preventScroll: true} + return true + } + } : undefined) + if (!preventScrollSupported) { + preventScrollSupported = false + restoreScrollStack(stored, 0) + } +} + +function findOffsetInNode(node, coords) { + let closest, dxClosest = 2e8, coordsClosest, offset = 0 + let rowBot = coords.top, rowTop = coords.top + for (let child = node.firstChild, childIndex = 0; child; child = child.nextSibling, childIndex++) { + let rects + if (child.nodeType == 1) rects = child.getClientRects() + else if (child.nodeType == 3) rects = textRange(child).getClientRects() + else continue + + for (let i = 0; i < rects.length; i++) { + let rect = rects[i] + if (rect.top <= rowBot && rect.bottom >= rowTop) { + rowBot = Math.max(rect.bottom, rowBot) + rowTop = Math.min(rect.top, rowTop) + let dx = rect.left > coords.left ? rect.left - coords.left + : rect.right < coords.left ? coords.left - rect.right : 0 + if (dx < dxClosest) { + closest = child + dxClosest = dx + coordsClosest = dx && closest.nodeType == 3 ? {left: rect.right < coords.left ? rect.right : rect.left, top: coords.top} : coords + if (child.nodeType == 1 && dx) + offset = childIndex + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0) + continue + } + } + if (!closest && (coords.left >= rect.right && coords.top >= rect.top || + coords.left >= rect.left && coords.top >= rect.bottom)) + offset = childIndex + 1 + } + } + if (closest && closest.nodeType == 3) return findOffsetInText(closest, coordsClosest) + if (!closest || (dxClosest && closest.nodeType == 1)) return {node, offset} + return findOffsetInNode(closest, coordsClosest) +} + +function findOffsetInText(node, coords) { + let len = node.nodeValue.length + let range = document.createRange() + for (let i = 0; i < len; i++) { + range.setEnd(node, i + 1) + range.setStart(node, i) + let rect = singleRect(range, 1) + if (rect.top == rect.bottom) continue + if (inRect(coords, rect)) + return {node, offset: i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0)} + } + return {node, offset: 0} +} + +function inRect(coords, rect) { + return coords.left >= rect.left - 1 && coords.left <= rect.right + 1&& + coords.top >= rect.top - 1 && coords.top <= rect.bottom + 1 +} + +function targetKludge(dom, coords) { + let parent = dom.parentNode + if (parent && /^li$/i.test(parent.nodeName) && coords.left < dom.getBoundingClientRect().left) + return parent + return dom +} + +function posFromElement(view, elt, coords) { + let {node, offset} = findOffsetInNode(elt, coords), bias = -1 + if (node.nodeType == 1 && !node.firstChild) { + let rect = node.getBoundingClientRect() + bias = rect.left != rect.right && coords.left > (rect.left + rect.right) / 2 ? 1 : -1 + } + return view.docView.posFromDOM(node, offset, bias) +} + +function posFromCaret(view, node, offset, coords) { + // Browser (in caretPosition/RangeFromPoint) will agressively + // normalize towards nearby inline nodes. Since we are interested in + // positions between block nodes too, we first walk up the hierarchy + // of nodes to see if there are block nodes that the coordinates + // fall outside of. If so, we take the position before/after that + // block. If not, we call `posFromDOM` on the raw node/offset. + let outside = -1 + for (let cur = node;;) { + if (cur == view.dom) break + let desc = view.docView.nearestDesc(cur, true) + if (!desc) return null + if (desc.node.isBlock && desc.parent) { + let rect = desc.dom.getBoundingClientRect() + if (rect.left > coords.left || rect.top > coords.top) outside = desc.posBefore + else if (rect.right < coords.left || rect.bottom < coords.top) outside = desc.posAfter + else break + } + cur = desc.dom.parentNode + } + return outside > -1 ? outside : view.docView.posFromDOM(node, offset) +} + +function elementFromPoint(element, coords, box) { + let len = element.childNodes.length + if (len && box.top < box.bottom) { + for (let startI = Math.max(0, Math.min(len - 1, Math.floor(len * (coords.top - box.top) / (box.bottom - box.top)) - 2)), i = startI;;) { + let child = element.childNodes[i] + if (child.nodeType == 1) { + let rects = child.getClientRects() + for (let j = 0; j < rects.length; j++) { + let rect = rects[j] + if (inRect(coords, rect)) return elementFromPoint(child, coords, rect) + } + } + if ((i = (i + 1) % len) == startI) break + } + } + return element +} + +// Given an x,y position on the editor, get the position in the document. +export function posAtCoords(view, coords) { + let root = view.root, node, offset + if (root.caretPositionFromPoint) { + try { // Firefox throws for this call in hard-to-predict circumstances (#994) + let pos = root.caretPositionFromPoint(coords.left, coords.top) + if (pos) ({offsetNode: node, offset} = pos) + } catch (_) {} + } + if (!node && root.caretRangeFromPoint) { + let range = root.caretRangeFromPoint(coords.left, coords.top) + if (range) ({startContainer: node, startOffset: offset} = range) + } + + let elt = root.elementFromPoint(coords.left, coords.top + 1), pos + if (!elt || !view.dom.contains(elt.nodeType != 1 ? elt.parentNode : elt)) { + let box = view.dom.getBoundingClientRect() + if (!inRect(coords, box)) return null + elt = elementFromPoint(view.dom, coords, box) + if (!elt) return null + } + elt = targetKludge(elt, coords) + if (node) { + if (browser.gecko && node.nodeType == 1) { + // Firefox will sometimes return offsets into nodes, which + // have no actual children, from caretPositionFromPoint (#953) + offset = Math.min(offset, node.childNodes.length) + // It'll also move the returned position before image nodes, + // even if those are behind it. + if (offset < node.childNodes.length) { + let next = node.childNodes[offset], box + if (next.nodeName == "IMG" && (box = next.getBoundingClientRect()).right <= coords.left && + box.bottom > coords.top) + offset++ + } + } + // Suspiciously specific kludge to work around caret*FromPoint + // never returning a position at the end of the document + if (node == view.dom && offset == node.childNodes.length - 1 && node.lastChild.nodeType == 1 && + coords.top > node.lastChild.getBoundingClientRect().bottom) + pos = view.state.doc.content.size + // Ignore positions directly after a BR, since caret*FromPoint + // 'round up' positions that would be more accurately placed + // before the BR node. + else if (offset == 0 || node.nodeType != 1 || node.childNodes[offset - 1].nodeName != "BR") + pos = posFromCaret(view, node, offset, coords) + } + if (pos == null) pos = posFromElement(view, elt, coords) + + let desc = view.docView.nearestDesc(elt, true) + return {pos, inside: desc ? desc.posAtStart - desc.border : -1} +} + +function singleRect(object, bias) { + let rects = object.getClientRects() + return !rects.length ? object.getBoundingClientRect() : rects[bias < 0 ? 0 : rects.length - 1] +} + +// : (EditorView, number) → {left: number, top: number, right: number, bottom: number} +// Given a position in the document model, get a bounding box of the +// character at that position, relative to the window. +export function coordsAtPos(view, pos) { + let {node, offset} = view.docView.domFromPos(pos) + + // These browsers support querying empty text ranges + if (node.nodeType == 3 && (browser.chrome || browser.gecko)) { + let rect = singleRect(textRange(node, offset, offset), 0) + // Firefox returns bad results (the position before the space) + // when querying a position directly after line-broken + // whitespace. Detect this situation and and kludge around it + if (browser.gecko && offset && /\s/.test(node.nodeValue[offset - 1]) && offset < node.nodeValue.length) { + let rectBefore = singleRect(textRange(node, offset - 1, offset - 1), -1) + if (Math.abs(rectBefore.left - rect.left) < 1 && rectBefore.top == rect.top) { + let rectAfter = singleRect(textRange(node, offset, offset + 1), -1) + return flattenV(rectAfter, rectAfter.left < rectBefore.left) + } + } + return rect + } + + if (node.nodeType == 1 && !view.state.doc.resolve(pos).parent.inlineContent) { + // Return a horizontal line in block context + let top = true, rect + if (offset < node.childNodes.length) { + let after = node.childNodes[offset] + if (after.nodeType == 1) rect = after.getBoundingClientRect() + } + if (!rect && offset) { + let before = node.childNodes[offset - 1] + if (before.nodeType == 1) { rect = before.getBoundingClientRect(); top = false } + } + return flattenH(rect || node.getBoundingClientRect(), top) + } + + // Not Firefox/Chrome, or not in a text node, so we have to use + // actual element/character rectangles to get a solution (this part + // is not very bidi-safe) + // + // Try the left side first, fall back to the right one if that + // doesn't work. + for (let dir = -1; dir < 2; dir += 2) { + if (dir < 0 && offset) { + let prev, target = node.nodeType == 3 ? textRange(node, offset - 1, offset) + : (prev = node.childNodes[offset - 1]).nodeType == 3 ? textRange(prev) + : prev.nodeType == 1 && prev.nodeName != "BR" ? prev : null // BR nodes tend to only return the rectangle before them + if (target) { + let rect = singleRect(target, 1) + if (rect.top < rect.bottom) return flattenV(rect, false) + } + } else if (dir > 0 && offset < nodeSize(node)) { + let next, target = node.nodeType == 3 ? textRange(node, offset, offset + 1) + : (next = node.childNodes[offset]).nodeType == 3 ? textRange(next) + : next.nodeType == 1 ? next : null + if (target) { + let rect = singleRect(target, -1) + if (rect.top < rect.bottom) return flattenV(rect, true) + } + } + } + // All else failed, just try to get a rectangle for the target node + return flattenV(singleRect(node.nodeType == 3 ? textRange(node) : node, 0), false) +} + +function flattenV(rect, left) { + if (rect.width == 0) return rect + let x = left ? rect.left : rect.right + return {top: rect.top, bottom: rect.bottom, left: x, right: x} +} + +function flattenH(rect, top) { + if (rect.height == 0) return rect + let y = top ? rect.top : rect.bottom + return {top: y, bottom: y, left: rect.left, right: rect.right} +} + +function withFlushedState(view, state, f) { + let viewState = view.state, active = view.root.activeElement + if (viewState != state) view.updateState(state) + if (active != view.dom) view.focus() + try { + return f() + } finally { + if (viewState != state) view.updateState(viewState) + if (active != view.dom) active.focus() + } +} + +// : (EditorView, number, number) +// Whether vertical position motion in a given direction +// from a position would leave a text block. +function endOfTextblockVertical(view, state, dir) { + let sel = state.selection + let $pos = dir == "up" ? sel.$anchor.min(sel.$head) : sel.$anchor.max(sel.$head) + return withFlushedState(view, state, () => { + let {node: dom} = view.docView.domFromPos($pos.pos) + for (;;) { + let nearest = view.docView.nearestDesc(dom, true) + if (!nearest) break + if (nearest.node.isBlock) { dom = nearest.dom; break } + dom = nearest.dom.parentNode + } + let coords = coordsAtPos(view, $pos.pos) + for (let child = dom.firstChild; child; child = child.nextSibling) { + let boxes + if (child.nodeType == 1) boxes = child.getClientRects() + else if (child.nodeType == 3) boxes = textRange(child, 0, child.nodeValue.length).getClientRects() + else continue + for (let i = 0; i < boxes.length; i++) { + let box = boxes[i] + if (box.bottom > box.top && (dir == "up" ? box.bottom < coords.top + 1 : box.top > coords.bottom - 1)) + return false + } + } + return true + }) +} + +const maybeRTL = /[\u0590-\u08ac]/ + +function endOfTextblockHorizontal(view, state, dir) { + let {$head} = state.selection + if (!$head.parent.isTextblock) return false + let offset = $head.parentOffset, atStart = !offset, atEnd = offset == $head.parent.content.size + let sel = getSelection() + // If the textblock is all LTR, or the browser doesn't support + // Selection.modify (Edge), fall back to a primitive approach + if (!maybeRTL.test($head.parent.textContent) || !sel.modify) + return dir == "left" || dir == "backward" ? atStart : atEnd + + return withFlushedState(view, state, () => { + // This is a huge hack, but appears to be the best we can + // currently do: use `Selection.modify` to move the selection by + // one character, and see if that moves the cursor out of the + // textblock (or doesn't move it at all, when at the start/end of + // the document). + let oldRange = sel.getRangeAt(0), oldNode = sel.focusNode, oldOff = sel.focusOffset + let oldBidiLevel = sel.caretBidiLevel // Only for Firefox + sel.modify("move", dir, "character") + let parentDOM = $head.depth ? view.docView.domAfterPos($head.before()) : view.dom + let result = !parentDOM.contains(sel.focusNode.nodeType == 1 ? sel.focusNode : sel.focusNode.parentNode) || + (oldNode == sel.focusNode && oldOff == sel.focusOffset) + // Restore the previous selection + sel.removeAllRanges() + sel.addRange(oldRange) + if (oldBidiLevel != null) sel.caretBidiLevel = oldBidiLevel + return result + }) +} + +let cachedState = null, cachedDir = null, cachedResult = false +export function endOfTextblock(view, state, dir) { + if (cachedState == state && cachedDir == dir) return cachedResult + cachedState = state; cachedDir = dir + return cachedResult = dir == "up" || dir == "down" + ? endOfTextblockVertical(view, state, dir) + : endOfTextblockHorizontal(view, state, dir) +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/src/domobserver.js b/packages/tiptap-extensions/node_modules/prosemirror-view/src/domobserver.js new file mode 100644 index 0000000000..038eea1326 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/src/domobserver.js @@ -0,0 +1,226 @@ +import browser from "./browser" +import {domIndex, isEquivalentPosition} from "./dom" +import {hasFocusAndSelection, hasSelection, selectionToDOM} from "./selection" + +const observeOptions = { + childList: true, + characterData: true, + characterDataOldValue: true, + attributes: true, + attributeOldValue: true, + subtree: true +} +// IE11 has very broken mutation observers, so we also listen to DOMCharacterDataModified +const useCharData = browser.ie && browser.ie_version <= 11 + +class SelectionState { + constructor() { + this.anchorNode = this.anchorOffset = this.focusNode = this.focusOffset = null + } + + set(sel) { + this.anchorNode = sel.anchorNode; this.anchorOffset = sel.anchorOffset + this.focusNode = sel.focusNode; this.focusOffset = sel.focusOffset + } + + eq(sel) { + return sel.anchorNode == this.anchorNode && sel.anchorOffset == this.anchorOffset && + sel.focusNode == this.focusNode && sel.focusOffset == this.focusOffset + } +} + +export class DOMObserver { + constructor(view, handleDOMChange) { + this.view = view + this.handleDOMChange = handleDOMChange + this.queue = [] + this.flushingSoon = false + this.observer = window.MutationObserver && + new window.MutationObserver(mutations => { + for (let i = 0; i < mutations.length; i++) this.queue.push(mutations[i]) + // IE11 will sometimes (on backspacing out a single character + // text node after a BR node) call the observer callback + // before actually updating the DOM, which will cause + // ProseMirror to miss the change (see #930) + if (browser.ie && browser.ie_version <= 11 && mutations.some( + m => m.type == "childList" && m.removedNodes.length || + m.type == "characterData" && m.oldValue.length > m.target.nodeValue.length)) + this.flushSoon() + else + this.flush() + }) + this.currentSelection = new SelectionState + if (useCharData) { + this.onCharData = e => { + this.queue.push({target: e.target, type: "characterData", oldValue: e.prevValue}) + this.flushSoon() + } + } + this.onSelectionChange = this.onSelectionChange.bind(this) + this.suppressingSelectionUpdates = false + } + + flushSoon() { + if (!this.flushingSoon) { + this.flushingSoon = true + window.setTimeout(() => { this.flushingSoon = false; this.flush() }, 20) + } + } + + start() { + if (this.observer) + this.observer.observe(this.view.dom, observeOptions) + if (useCharData) + this.view.dom.addEventListener("DOMCharacterDataModified", this.onCharData) + this.connectSelection() + } + + stop() { + if (this.observer) { + let take = this.observer.takeRecords() + if (take.length) { + for (let i = 0; i < take.length; i++) this.queue.push(take[i]) + window.setTimeout(() => this.flush(), 20) + } + this.observer.disconnect() + } + if (useCharData) this.view.dom.removeEventListener("DOMCharacterDataModified", this.onCharData) + this.disconnectSelection() + } + + connectSelection() { + this.view.dom.ownerDocument.addEventListener("selectionchange", this.onSelectionChange) + } + + disconnectSelection() { + this.view.dom.ownerDocument.removeEventListener("selectionchange", this.onSelectionChange) + } + + suppressSelectionUpdates() { + this.suppressingSelectionUpdates = true + setTimeout(() => this.suppressingSelectionUpdates = false, 50) + } + + onSelectionChange() { + if (!hasFocusAndSelection(this.view)) return + if (this.suppressingSelectionUpdates) return selectionToDOM(this.view) + // Deletions on IE11 fire their events in the wrong order, giving + // us a selection change event before the DOM changes are + // reported. + if (browser.ie && browser.ie_version <= 11 && !this.view.state.selection.empty) { + let sel = this.view.root.getSelection() + // Selection.isCollapsed isn't reliable on IE + if (sel.focusNode && isEquivalentPosition(sel.focusNode, sel.focusOffset, sel.anchorNode, sel.anchorOffset)) + return this.flushSoon() + } + this.flush() + } + + setCurSelection() { + this.currentSelection.set(this.view.root.getSelection()) + } + + ignoreSelectionChange(sel) { + if (sel.rangeCount == 0) return true + let container = sel.getRangeAt(0).commonAncestorContainer + let desc = this.view.docView.nearestDesc(container) + return desc && desc.ignoreMutation({type: "selection", target: container.nodeType == 3 ? container.parentNode : container}) + } + + flush() { + if (!this.view.docView || this.flushingSoon) return + let mutations = this.observer ? this.observer.takeRecords() : [] + if (this.queue.length) { + mutations = this.queue.concat(mutations) + this.queue.length = 0 + } + + let sel = this.view.root.getSelection() + let newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasSelection(this.view) && !this.ignoreSelectionChange(sel) + + let from = -1, to = -1, typeOver = false, added = [] + if (this.view.editable) { + for (let i = 0; i < mutations.length; i++) { + let result = this.registerMutation(mutations[i], added) + if (result) { + from = from < 0 ? result.from : Math.min(result.from, from) + to = to < 0 ? result.to : Math.max(result.to, to) + if (result.typeOver && !this.view.composing) typeOver = true + } + } + } + + if (browser.gecko && added.length > 1) { + let brs = added.filter(n => n.nodeName == "BR") + if (brs.length == 2) { + let [a, b] = brs + if (a.parentNode && a.parentNode.parentNode == b.parentNode) b.remove() + else a.remove() + } + } + + if (from > -1 || newSel) { + if (from > -1) { + this.view.docView.markDirty(from, to) + checkCSS(this.view) + } + this.handleDOMChange(from, to, typeOver) + if (this.view.docView.dirty) this.view.updateState(this.view.state) + else if (!this.currentSelection.eq(sel)) selectionToDOM(this.view) + } + } + + registerMutation(mut, added) { + // Ignore mutations inside nodes that were already noted as inserted + if (added.indexOf(mut.target) > -1) return null + let desc = this.view.docView.nearestDesc(mut.target) + if (mut.type == "attributes" && + (desc == this.view.docView || mut.attributeName == "contenteditable" || + // Firefox sometimes fires spurious events for null/empty styles + (mut.attributeName == "style" && !mut.oldValue && !mut.target.getAttribute("style")))) + return null + if (!desc || desc.ignoreMutation(mut)) return null + + if (mut.type == "childList") { + let prev = mut.previousSibling, next = mut.nextSibling + if (browser.ie && browser.ie_version <= 11 && mut.addedNodes.length) { + // IE11 gives us incorrect next/prev siblings for some + // insertions, so if there are added nodes, recompute those + for (let i = 0; i < mut.addedNodes.length; i++) { + let {previousSibling, nextSibling} = mut.addedNodes[i] + if (!previousSibling || Array.prototype.indexOf.call(mut.addedNodes, previousSibling) < 0) prev = previousSibling + if (!nextSibling || Array.prototype.indexOf.call(mut.addedNodes, nextSibling) < 0) next = nextSibling + } + } + let fromOffset = prev && prev.parentNode == mut.target + ? domIndex(prev) + 1 : 0 + let from = desc.localPosFromDOM(mut.target, fromOffset, -1) + let toOffset = next && next.parentNode == mut.target + ? domIndex(next) : mut.target.childNodes.length + for (let i = 0; i < mut.addedNodes.length; i++) added.push(mut.addedNodes[i]) + let to = desc.localPosFromDOM(mut.target, toOffset, 1) + return {from, to} + } else if (mut.type == "attributes") { + return {from: desc.posAtStart - desc.border, to: desc.posAtEnd + desc.border} + } else { // "characterData" + return { + from: desc.posAtStart, + to: desc.posAtEnd, + // An event was generated for a text change that didn't change + // any text. Mark the dom change to fall back to assuming the + // selection was typed over with an identical value if it can't + // find another change. + typeOver: mut.target.nodeValue == mut.oldValue + } + } + } +} + +let cssChecked = false + +function checkCSS(view) { + if (cssChecked) return + cssChecked = true + if (getComputedStyle(view.dom).whiteSpace == "normal") + console["warn"]("ProseMirror expects the CSS white-space property to be set, preferably to 'pre-wrap'. It is recommended to load style/prosemirror.css from the prosemirror-view package.") +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/src/index.js b/packages/tiptap-extensions/node_modules/prosemirror-view/src/index.js new file mode 100644 index 0000000000..d879514fac --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/src/index.js @@ -0,0 +1,601 @@ +import {NodeSelection} from "prosemirror-state" + +import {scrollRectIntoView, posAtCoords, coordsAtPos, endOfTextblock, storeScrollPos, + resetScrollPos, focusPreventScroll} from "./domcoords" +import {docViewDesc} from "./viewdesc" +import {initInput, destroyInput, dispatchEvent, ensureListeners} from "./input" +import {selectionToDOM, anchorInRightPlace, syncNodeSelection} from "./selection" +import {Decoration, viewDecorations} from "./decoration" +import browser from "./browser" + +export {Decoration, DecorationSet} from "./decoration" + +// Exported for testing +export {serializeForClipboard as __serializeForClipboard, parseFromClipboard as __parseFromClipboard} from "./clipboard" +export {endComposition as __endComposition} from "./input" + +// ::- An editor view manages the DOM structure that represents an +// editable document. Its state and behavior are determined by its +// [props](#view.DirectEditorProps). +export class EditorView { + // :: (?union, DirectEditorProps) + // Create a view. `place` may be a DOM node that the editor should + // be appended to, a function that will place it into the document, + // or an object whose `mount` property holds the node to use as the + // document container. If it is `null`, the editor will not be added + // to the document. + constructor(place, props) { + this._props = props + // :: EditorState + // The view's current [state](#state.EditorState). + this.state = props.state + + this.dispatch = this.dispatch.bind(this) + + this._root = null + this.focused = false + + // :: dom.Element + // An editable DOM node containing the document. (You probably + // should not directly interfere with its content.) + this.dom = (place && place.mount) || document.createElement("div") + if (place) { + if (place.appendChild) place.appendChild(this.dom) + else if (place.apply) place(this.dom) + else if (place.mount) this.mounted = true + } + + // :: bool + // Indicates whether the editor is currently [editable](#view.EditorProps.editable). + this.editable = getEditable(this) + this.markCursor = null + this.cursorWrapper = null + updateCursorWrapper(this) + this.nodeViews = buildNodeViews(this) + this.docView = docViewDesc(this.state.doc, computeDocDeco(this), viewDecorations(this), this.dom, this) + + this.lastSelectedViewDesc = null + // :: ?{slice: Slice, move: bool} + // When editor content is being dragged, this object contains + // information about the dragged slice and whether it is being + // copied or moved. At any other time, it is null. + this.dragging = null + + initInput(this) + + this.pluginViews = [] + this.updatePluginViews() + } + + // composing:: boolean + // Holds `true` when a + // [composition](https://developer.mozilla.org/en-US/docs/Mozilla/IME_handling_guide) + // is active. + + // :: DirectEditorProps + // The view's current [props](#view.EditorProps). + get props() { + if (this._props.state != this.state) { + let prev = this._props + this._props = {} + for (let name in prev) this._props[name] = prev[name] + this._props.state = this.state + } + return this._props + } + + // :: (DirectEditorProps) + // Update the view's props. Will immediately cause an update to + // the DOM. + update(props) { + if (props.handleDOMEvents != this._props.handleDOMEvents) ensureListeners(this) + this._props = props + this.updateStateInner(props.state, true) + } + + // :: (DirectEditorProps) + // Update the view by updating existing props object with the object + // given as argument. Equivalent to `view.update(Object.assign({}, + // view.props, props))`. + setProps(props) { + let updated = {} + for (let name in this._props) updated[name] = this._props[name] + updated.state = this.state + for (let name in props) updated[name] = props[name] + this.update(updated) + } + + // :: (EditorState) + // Update the editor's `state` prop, without touching any of the + // other props. + updateState(state) { + this.updateStateInner(state, this.state.plugins != state.plugins) + } + + updateStateInner(state, reconfigured) { + let prev = this.state, redraw = false + this.state = state + if (reconfigured) { + let nodeViews = buildNodeViews(this) + if (changedNodeViews(nodeViews, this.nodeViews)) { + this.nodeViews = nodeViews + redraw = true + } + ensureListeners(this) + } + + this.editable = getEditable(this) + updateCursorWrapper(this) + let innerDeco = viewDecorations(this), outerDeco = computeDocDeco(this) + + let scroll = reconfigured ? "reset" + : state.scrollToSelection > prev.scrollToSelection ? "to selection" : "preserve" + let updateDoc = redraw || !this.docView.matchesNode(state.doc, outerDeco, innerDeco) + let updateSel = updateDoc || !state.selection.eq(prev.selection) + let oldScrollPos = scroll == "preserve" && updateSel && this.dom.style.overflowAnchor == null && storeScrollPos(this) + + if (updateSel) { + this.domObserver.stop() + // Work around an issue in Chrome, IE, and Edge where changing + // the DOM around an active selection puts it into a broken + // state where the thing the user sees differs from the + // selection reported by the Selection object (#710, #973, + // #1011, #1013). + let forceSelUpdate = updateDoc && (browser.ie || browser.chrome) && + !prev.selection.empty && !state.selection.empty && selectionContextChanged(prev.selection, state.selection) + if (updateDoc) { + if (redraw || !this.docView.update(state.doc, outerDeco, innerDeco, this)) { + this.docView.destroy() + this.docView = docViewDesc(state.doc, outerDeco, innerDeco, this.dom, this) + } + } + // Work around for an issue where an update arriving right between + // a DOM selection change and the "selectionchange" event for it + // can cause a spurious DOM selection update, disrupting mouse + // drag selection. + if (forceSelUpdate || + !(this.mouseDown && this.domObserver.currentSelection.eq(this.root.getSelection()) && anchorInRightPlace(this))) { + selectionToDOM(this, forceSelUpdate) + } else { + syncNodeSelection(this, state.selection) + this.domObserver.setCurSelection() + } + this.domObserver.start() + } + + this.updatePluginViews(prev) + + if (scroll == "reset") { + this.dom.scrollTop = 0 + } else if (scroll == "to selection") { + let startDOM = this.root.getSelection().focusNode + if (this.someProp("handleScrollToSelection", f => f(this))) + {} // Handled + else if (state.selection instanceof NodeSelection) + scrollRectIntoView(this, this.docView.domAfterPos(state.selection.from).getBoundingClientRect(), startDOM) + else + scrollRectIntoView(this, this.coordsAtPos(state.selection.head), startDOM) + } else if (oldScrollPos) { + resetScrollPos(oldScrollPos) + } + } + + destroyPluginViews() { + let view + while (view = this.pluginViews.pop()) if (view.destroy) view.destroy() + } + + updatePluginViews(prevState) { + if (!prevState || prevState.plugins != this.state.plugins) { + this.destroyPluginViews() + for (let i = 0; i < this.state.plugins.length; i++) { + let plugin = this.state.plugins[i] + if (plugin.spec.view) this.pluginViews.push(plugin.spec.view(this)) + } + } else { + for (let i = 0; i < this.pluginViews.length; i++) { + let pluginView = this.pluginViews[i] + if (pluginView.update) pluginView.update(this, prevState) + } + } + } + + // :: (string, ?(prop: *) → *) → * + // Goes over the values of a prop, first those provided directly, + // then those from plugins (in order), and calls `f` every time a + // non-undefined value is found. When `f` returns a truthy value, + // that is immediately returned. When `f` isn't provided, it is + // treated as the identity function (the prop value is returned + // directly). + someProp(propName, f) { + let prop = this._props && this._props[propName], value + if (prop != null && (value = f ? f(prop) : prop)) return value + let plugins = this.state.plugins + if (plugins) for (let i = 0; i < plugins.length; i++) { + let prop = plugins[i].props[propName] + if (prop != null && (value = f ? f(prop) : prop)) return value + } + } + + // :: () → bool + // Query whether the view has focus. + hasFocus() { + return this.root.activeElement == this.dom + } + + // :: () + // Focus the editor. + focus() { + this.domObserver.stop() + if (this.editable) focusPreventScroll(this.dom) + selectionToDOM(this) + this.domObserver.start() + } + + // :: union + // Get the document root in which the editor exists. This will + // usually be the top-level `document`, but might be a [shadow + // DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Shadow_DOM) + // root if the editor is inside one. + get root() { + let cached = this._root + if (cached == null) for (let search = this.dom.parentNode; search; search = search.parentNode) { + if (search.nodeType == 9 || (search.nodeType == 11 && search.host)) { + if (!search.getSelection) Object.getPrototypeOf(search).getSelection = () => document.getSelection() + return this._root = search + } + } + return cached || document + } + + // :: ({left: number, top: number}) → ?{pos: number, inside: number} + // Given a pair of viewport coordinates, return the document + // position that corresponds to them. May return null if the given + // coordinates aren't inside of the editor. When an object is + // returned, its `pos` property is the position nearest to the + // coordinates, and its `inside` property holds the position of the + // inner node that the position falls inside of, or -1 if it is at + // the top level, not in any node. + posAtCoords(coords) { + return posAtCoords(this, coords) + } + + // :: (number) → {left: number, right: number, top: number, bottom: number} + // Returns the viewport rectangle at a given document position. `left` + // and `right` will be the same number, as this returns a flat + // cursor-ish rectangle. + coordsAtPos(pos) { + return coordsAtPos(this, pos) + } + + // :: (number) → {node: dom.Node, offset: number} + // Find the DOM position that corresponds to the given document + // position. Note that you should **not** mutate the editor's + // internal DOM, only inspect it (and even that is usually not + // necessary). + domAtPos(pos) { + return this.docView.domFromPos(pos) + } + + // :: (number) → ?dom.Node + // Find the DOM node that represents the document node after the + // given position. May return `null` when the position doesn't point + // in front of a node or if the node is inside an opaque node view. + // + // This is intended to be able to call things like + // `getBoundingClientRect` on that DOM node. Do **not** mutate the + // editor DOM directly, or add styling this way, since that will be + // immediately overriden by the editor as it redraws the node. + nodeDOM(pos) { + let desc = this.docView.descAt(pos) + return desc ? desc.nodeDOM : null + } + + // :: (dom.Node, number, ?number) → number + // Find the document position that corresponds to a given DOM + // position. (Whenever possible, it is preferable to inspect the + // document structure directly, rather than poking around in the + // DOM, but sometimes—for example when interpreting an event + // target—you don't have a choice.) + // + // The `bias` parameter can be used to influence which side of a DOM + // node to use when the position is inside a leaf node. + posAtDOM(node, offset, bias = -1) { + let pos = this.docView.posFromDOM(node, offset, bias) + if (pos == null) throw new RangeError("DOM position not inside the editor") + return pos + } + + // :: (union<"up", "down", "left", "right", "forward", "backward">, ?EditorState) → bool + // Find out whether the selection is at the end of a textblock when + // moving in a given direction. When, for example, given `"left"`, + // it will return true if moving left from the current cursor + // position would leave that position's parent textblock. Will apply + // to the view's current state by default, but it is possible to + // pass a different state. + endOfTextblock(dir, state) { + return endOfTextblock(this, state || this.state, dir) + } + + // :: () + // Removes the editor from the DOM and destroys all [node + // views](#view.NodeView). + destroy() { + if (!this.docView) return + destroyInput(this) + this.destroyPluginViews() + if (this.mounted) { + this.docView.update(this.state.doc, [], viewDecorations(this), this) + this.dom.textContent = "" + } else if (this.dom.parentNode) { + this.dom.parentNode.removeChild(this.dom) + } + this.docView.destroy() + this.docView = null + } + + // Used for testing. + dispatchEvent(event) { + return dispatchEvent(this, event) + } + + // :: (Transaction) + // Dispatch a transaction. Will call + // [`dispatchTransaction`](#view.DirectEditorProps.dispatchTransaction) + // when given, and otherwise defaults to applying the transaction to + // the current state and calling + // [`updateState`](#view.EditorView.updateState) with the result. + // This method is bound to the view instance, so that it can be + // easily passed around. + dispatch(tr) { + let dispatchTransaction = this._props.dispatchTransaction + if (dispatchTransaction) dispatchTransaction.call(this, tr) + else this.updateState(this.state.apply(tr)) + } +} + +function computeDocDeco(view) { + let attrs = Object.create(null) + attrs.class = "ProseMirror" + attrs.contenteditable = String(view.editable) + + view.someProp("attributes", value => { + if (typeof value == "function") value = value(view.state) + if (value) for (let attr in value) { + if (attr == "class") + attrs.class += " " + value[attr] + else if (!attrs[attr] && attr != "contenteditable" && attr != "nodeName") + attrs[attr] = String(value[attr]) + } + }) + + return [Decoration.node(0, view.state.doc.content.size, attrs)] +} + +function updateCursorWrapper(view) { + let {$head, $anchor, visible} = view.state.selection + if (view.markCursor) { + let dom = document.createElement("img") + dom.setAttribute("mark-placeholder", "true") + view.cursorWrapper = {dom, deco: Decoration.widget($head.pos, dom, {raw: true, marks: view.markCursor})} + } else if (visible || $head.pos != $anchor.pos) { + view.cursorWrapper = null + } else { + let dom + if (!view.cursorWrapper || view.cursorWrapper.dom.childNodes.length) { + dom = document.createElement("div") + dom.style.position = "absolute" + dom.style.left = "-100000px" + } else if (view.cursorWrapper.deco.pos != $head.pos) { + dom = view.cursorWrapper.dom + } + if (dom) + view.cursorWrapper = {dom, deco: Decoration.widget($head.pos, dom, {raw: true})} + } +} + +function getEditable(view) { + return !view.someProp("editable", value => value(view.state) === false) +} + +function selectionContextChanged(sel1, sel2) { + let depth = Math.min(sel1.$anchor.sharedDepth(sel1.head), sel2.$anchor.sharedDepth(sel2.head)) + return sel1.$anchor.node(depth) != sel2.$anchor.node(depth) +} + +function buildNodeViews(view) { + let result = {} + view.someProp("nodeViews", obj => { + for (let prop in obj) if (!Object.prototype.hasOwnProperty.call(result, prop)) + result[prop] = obj[prop] + }) + return result +} + +function changedNodeViews(a, b) { + let nA = 0, nB = 0 + for (let prop in a) { + if (a[prop] != b[prop]) return true + nA++ + } + for (let _ in b) nB++ + return nA != nB +} + +// EditorProps:: interface +// +// Props are configuration values that can be passed to an editor view +// or included in a plugin. This interface lists the supported props. +// +// The various event-handling functions may all return `true` to +// indicate that they handled the given event. The view will then take +// care to call `preventDefault` on the event, except with +// `handleDOMEvents`, where the handler itself is responsible for that. +// +// How a prop is resolved depends on the prop. Handler functions are +// called one at a time, starting with the base props and then +// searching through the plugins (in order of appearance) until one of +// them returns true. For some props, the first plugin that yields a +// value gets precedence. +// +// handleDOMEvents:: ?Object<(view: EditorView, event: dom.Event) → bool> +// Can be an object mapping DOM event type names to functions that +// handle them. Such functions will be called before any handling +// ProseMirror does of events fired on the editable DOM element. +// Contrary to the other event handling props, when returning true +// from such a function, you are responsible for calling +// `preventDefault` yourself (or not, if you want to allow the +// default behavior). +// +// handleKeyDown:: ?(view: EditorView, event: dom.KeyboardEvent) → bool +// Called when the editor receives a `keydown` event. +// +// handleKeyPress:: ?(view: EditorView, event: dom.KeyboardEvent) → bool +// Handler for `keypress` events. +// +// handleTextInput:: ?(view: EditorView, from: number, to: number, text: string) → bool +// Whenever the user directly input text, this handler is called +// before the input is applied. If it returns `true`, the default +// behavior of actually inserting the text is suppressed. +// +// handleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool +// Called for each node around a click, from the inside out. The +// `direct` flag will be true for the inner node. +// +// handleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool +// Called when the editor is clicked, after `handleClickOn` handlers +// have been called. +// +// handleDoubleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool +// Called for each node around a double click. +// +// handleDoubleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool +// Called when the editor is double-clicked, after `handleDoubleClickOn`. +// +// handleTripleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool +// Called for each node around a triple click. +// +// handleTripleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool +// Called when the editor is triple-clicked, after `handleTripleClickOn`. +// +// handlePaste:: ?(view: EditorView, event: dom.Event, slice: Slice) → bool +// Can be used to override the behavior of pasting. `slice` is the +// pasted content parsed by the editor, but you can directly access +// the event to get at the raw content. +// +// handleDrop:: ?(view: EditorView, event: dom.Event, slice: Slice, moved: bool) → bool +// Called when something is dropped on the editor. `moved` will be +// true if this drop moves from the current selection (which should +// thus be deleted). +// +// handleScrollToSelection:: ?(view: EditorView) → bool +// Called when the view, after updating its state, tries to scroll +// the selection into view. A handler function may return false to +// indicate that it did not handle the scrolling and further +// handlers or the default behavior should be tried. +// +// createSelectionBetween:: ?(view: EditorView, anchor: ResolvedPos, head: ResolvedPos) → ?Selection +// Can be used to override the way a selection is created when +// reading a DOM selection between the given anchor and head. +// +// domParser:: ?DOMParser +// The [parser](#model.DOMParser) to use when reading editor changes +// from the DOM. Defaults to calling +// [`DOMParser.fromSchema`](#model.DOMParser^fromSchema) on the +// editor's schema. +// +// transformPastedHTML:: ?(html: string) → string +// Can be used to transform pasted HTML text, _before_ it is parsed, +// for example to clean it up. +// +// clipboardParser:: ?DOMParser +// The [parser](#model.DOMParser) to use when reading content from +// the clipboard. When not given, the value of the +// [`domParser`](#view.EditorProps.domParser) prop is used. +// +// transformPastedText:: ?(text: string) → string +// Transform pasted plain text. +// +// clipboardTextParser:: ?(text: string, $context: ResolvedPos) → Slice +// A function to parse text from the clipboard into a document +// slice. Called after +// [`transformPastedText`](#view.EditorProps.transformPastedText). +// The default behavior is to split the text into lines, wrap them +// in `

    ` tags, and call +// [`clipboardParser`](#view.EditorProps.clipboardParser) on it. +// +// transformPasted:: ?(Slice) → Slice +// Can be used to transform pasted content before it is applied to +// the document. +// +// nodeViews:: ?Object<(node: Node, view: EditorView, getPos: () → number, decorations: [Decoration]) → NodeView> +// Allows you to pass custom rendering and behavior logic for nodes +// and marks. Should map node and mark names to constructor +// functions that produce a [`NodeView`](#view.NodeView) object +// implementing the node's display behavior. For nodes, the third +// argument `getPos` is a function that can be called to get the +// node's current position, which can be useful when creating +// transactions to update it. For marks, the third argument is a +// boolean that indicates whether the mark's content is inline. +// +// `decorations` is an array of node or inline decorations that are +// active around the node. They are automatically drawn in the +// normal way, and you will usually just want to ignore this, but +// they can also be used as a way to provide context information to +// the node view without adding it to the document itself. +// +// clipboardSerializer:: ?DOMSerializer +// The DOM serializer to use when putting content onto the +// clipboard. If not given, the result of +// [`DOMSerializer.fromSchema`](#model.DOMSerializer^fromSchema) +// will be used. +// +// clipboardTextSerializer:: ?(Slice) → string +// A function that will be called to get the text for the current +// selection when copying text to the clipboard. By default, the +// editor will use [`textBetween`](#model.Node.textBetween) on the +// selected range. +// +// decorations:: ?(state: EditorState) → ?DecorationSet +// A set of [document decorations](#view.Decoration) to show in the +// view. +// +// editable:: ?(state: EditorState) → bool +// When this returns false, the content of the view is not directly +// editable. +// +// attributes:: ?union, (EditorState) → ?Object> +// Control the DOM attributes of the editable element. May be either +// an object or a function going from an editor state to an object. +// By default, the element will get a class `"ProseMirror"`, and +// will have its `contentEditable` attribute determined by the +// [`editable` prop](#view.EditorProps.editable). Additional classes +// provided here will be added to the class. For other attributes, +// the value provided first (as in +// [`someProp`](#view.EditorView.someProp)) will be used. +// +// scrollThreshold:: ?union +// Determines the distance (in pixels) between the cursor and the +// end of the visible viewport at which point, when scrolling the +// cursor into view, scrolling takes place. Defaults to 0. +// +// scrollMargin:: ?union +// Determines the extra space (in pixels) that is left above or +// below the cursor when it is scrolled into view. Defaults to 5. + +// DirectEditorProps:: interface extends EditorProps +// +// The props object given directly to the editor view supports two +// fields that can't be used in plugins: +// +// state:: EditorState +// The current state of the editor. +// +// dispatchTransaction:: ?(tr: Transaction) +// The callback over which to send transactions (state updates) +// produced by the view. If you specify this, you probably want to +// make sure this ends up calling the view's +// [`updateState`](#view.EditorView.updateState) method with a new +// state that has the transaction +// [applied](#state.EditorState.apply). The callback will be bound to have +// the view instance as its `this` binding. diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/src/input.js b/packages/tiptap-extensions/node_modules/prosemirror-view/src/input.js new file mode 100644 index 0000000000..a0e80460d1 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/src/input.js @@ -0,0 +1,644 @@ +import {Selection, NodeSelection, TextSelection} from "prosemirror-state" +import {dropPoint} from "prosemirror-transform" +import {Slice} from "prosemirror-model" + +import browser from "./browser" +import {captureKeyDown} from "./capturekeys" +import {readDOMChange} from "./domchange" +import {parseFromClipboard, serializeForClipboard} from "./clipboard" +import {DOMObserver} from "./domobserver" +import {selectionBetween} from "./selection" +import {keyEvent} from "./dom" + +// A collection of DOM events that occur within the editor, and callback functions +// to invoke when the event fires. +const handlers = {}, editHandlers = {} + +export function initInput(view) { + view.shiftKey = false + view.mouseDown = null + view.lastKeyCode = null + view.lastKeyCodeTime = 0 + view.lastClick = {time: 0, x: 0, y: 0, type: ""} + view.lastSelectionOrigin = null + view.lastSelectionTime = 0 + + view.composing = false + view.composingTimeout = null + view.compositionNodes = [] + view.compositionEndedAt = -2e8 + + view.domObserver = new DOMObserver(view, (from, to, typeOver) => readDOMChange(view, from, to, typeOver)) + view.domObserver.start() + // Used by hacks like the beforeinput handler to check whether anything happened in the DOM + view.domChangeCount = 0 + + view.eventHandlers = Object.create(null) + for (let event in handlers) { + let handler = handlers[event] + view.dom.addEventListener(event, view.eventHandlers[event] = event => { + if (eventBelongsToView(view, event) && !runCustomHandler(view, event) && + (view.editable || !(event.type in editHandlers))) + handler(view, event) + }) + } + // On Safari, for reasons beyond my understanding, adding an input + // event handler makes an issue where the composition vanishes when + // you press enter go away. + if (browser.safari) view.dom.addEventListener("input", () => null) + + ensureListeners(view) +} + +function setSelectionOrigin(view, origin) { + view.lastSelectionOrigin = origin + view.lastSelectionTime = Date.now() +} + +export function destroyInput(view) { + view.domObserver.stop() + for (let type in view.eventHandlers) + view.dom.removeEventListener(type, view.eventHandlers[type]) + clearTimeout(view.composingTimeout) +} + +export function ensureListeners(view) { + view.someProp("handleDOMEvents", currentHandlers => { + for (let type in currentHandlers) if (!view.eventHandlers[type]) + view.dom.addEventListener(type, view.eventHandlers[type] = event => runCustomHandler(view, event)) + }) +} + +function runCustomHandler(view, event) { + return view.someProp("handleDOMEvents", handlers => { + let handler = handlers[event.type] + return handler ? handler(view, event) || event.defaultPrevented : false + }) +} + +function eventBelongsToView(view, event) { + if (!event.bubbles) return true + if (event.defaultPrevented) return false + for (let node = event.target; node != view.dom; node = node.parentNode) + if (!node || node.nodeType == 11 || + (node.pmViewDesc && node.pmViewDesc.stopEvent(event))) + return false + return true +} + +export function dispatchEvent(view, event) { + if (!runCustomHandler(view, event) && handlers[event.type] && + (view.editable || !(event.type in editHandlers))) + handlers[event.type](view, event) +} + +editHandlers.keydown = (view, event) => { + view.shiftKey = event.keyCode == 16 || event.shiftKey + if (inOrNearComposition(view, event)) return + view.lastKeyCode = event.keyCode + view.lastKeyCodeTime = Date.now() + if (view.someProp("handleKeyDown", f => f(view, event)) || captureKeyDown(view, event)) + event.preventDefault() + else + setSelectionOrigin(view, "key") +} + +editHandlers.keyup = (view, e) => { + if (e.keyCode == 16) view.shiftKey = false +} + +editHandlers.keypress = (view, event) => { + if (inOrNearComposition(view, event) || !event.charCode || + event.ctrlKey && !event.altKey || browser.mac && event.metaKey) return + + if (view.someProp("handleKeyPress", f => f(view, event))) { + event.preventDefault() + return + } + + let sel = view.state.selection + if (!(sel instanceof TextSelection) || !sel.$from.sameParent(sel.$to)) { + let text = String.fromCharCode(event.charCode) + if (!view.someProp("handleTextInput", f => f(view, sel.$from.pos, sel.$to.pos, text))) + view.dispatch(view.state.tr.insertText(text).scrollIntoView()) + event.preventDefault() + } +} + +function eventCoords(event) { return {left: event.clientX, top: event.clientY} } + +function isNear(event, click) { + let dx = click.x - event.clientX, dy = click.y - event.clientY + return dx * dx + dy * dy < 100 +} + +function runHandlerOnContext(view, propName, pos, inside, event) { + if (inside == -1) return false + let $pos = view.state.doc.resolve(inside) + for (let i = $pos.depth + 1; i > 0; i--) { + if (view.someProp(propName, f => i > $pos.depth ? f(view, pos, $pos.nodeAfter, $pos.before(i), event, true) + : f(view, pos, $pos.node(i), $pos.before(i), event, false))) + return true + } + return false +} + +function updateSelection(view, selection, origin) { + if (!view.focused) view.focus() + let tr = view.state.tr.setSelection(selection) + if (origin == "pointer") tr.setMeta("pointer", true) + view.dispatch(tr) +} + +function selectClickedLeaf(view, inside) { + if (inside == -1) return false + let $pos = view.state.doc.resolve(inside), node = $pos.nodeAfter + if (node && node.isAtom && NodeSelection.isSelectable(node)) { + updateSelection(view, new NodeSelection($pos), "pointer") + return true + } + return false +} + +function selectClickedNode(view, inside) { + if (inside == -1) return false + let sel = view.state.selection, selectedNode, selectAt + if (sel instanceof NodeSelection) selectedNode = sel.node + + let $pos = view.state.doc.resolve(inside) + for (let i = $pos.depth + 1; i > 0; i--) { + let node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i) + if (NodeSelection.isSelectable(node)) { + if (selectedNode && sel.$from.depth > 0 && + i >= sel.$from.depth && $pos.before(sel.$from.depth + 1) == sel.$from.pos) + selectAt = $pos.before(sel.$from.depth) + else + selectAt = $pos.before(i) + break + } + } + + if (selectAt != null) { + updateSelection(view, NodeSelection.create(view.state.doc, selectAt), "pointer") + return true + } else { + return false + } +} + +function handleSingleClick(view, pos, inside, event, selectNode) { + return runHandlerOnContext(view, "handleClickOn", pos, inside, event) || + view.someProp("handleClick", f => f(view, pos, event)) || + (selectNode ? selectClickedNode(view, inside) : selectClickedLeaf(view, inside)) +} + +function handleDoubleClick(view, pos, inside, event) { + return runHandlerOnContext(view, "handleDoubleClickOn", pos, inside, event) || + view.someProp("handleDoubleClick", f => f(view, pos, event)) +} + +function handleTripleClick(view, pos, inside, event) { + return runHandlerOnContext(view, "handleTripleClickOn", pos, inside, event) || + view.someProp("handleTripleClick", f => f(view, pos, event)) || + defaultTripleClick(view, inside) +} + +function defaultTripleClick(view, inside) { + let doc = view.state.doc + if (inside == -1) { + if (doc.inlineContent) { + updateSelection(view, TextSelection.create(doc, 0, doc.content.size), "pointer") + return true + } + return false + } + + let $pos = doc.resolve(inside) + for (let i = $pos.depth + 1; i > 0; i--) { + let node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i) + let nodePos = $pos.before(i) + if (node.inlineContent) + updateSelection(view, TextSelection.create(doc, nodePos + 1, nodePos + 1 + node.content.size), "pointer") + else if (NodeSelection.isSelectable(node)) + updateSelection(view, NodeSelection.create(doc, nodePos), "pointer") + else + continue + return true + } +} + +function forceDOMFlush(view) { + return endComposition(view) +} + +const selectNodeModifier = browser.mac ? "metaKey" : "ctrlKey" + +handlers.mousedown = (view, event) => { + view.shiftKey = event.shiftKey + let flushed = forceDOMFlush(view) + let now = Date.now(), type = "singleClick" + if (now - view.lastClick.time < 500 && isNear(event, view.lastClick) && !event[selectNodeModifier]) { + if (view.lastClick.type == "singleClick") type = "doubleClick" + else if (view.lastClick.type == "doubleClick") type = "tripleClick" + } + view.lastClick = {time: now, x: event.clientX, y: event.clientY, type} + + let pos = view.posAtCoords(eventCoords(event)) + if (!pos) return + + if (type == "singleClick") + view.mouseDown = new MouseDown(view, pos, event, flushed) + else if ((type == "doubleClick" ? handleDoubleClick : handleTripleClick)(view, pos.pos, pos.inside, event)) + event.preventDefault() + else + setSelectionOrigin(view, "pointer") +} + +class MouseDown { + constructor(view, pos, event, flushed) { + this.view = view + this.startDoc = view.state.doc + this.pos = pos + this.event = event + this.flushed = flushed + this.selectNode = event[selectNodeModifier] + this.allowDefault = event.shiftKey + + let targetNode, targetPos + if (pos.inside > -1) { + targetNode = view.state.doc.nodeAt(pos.inside) + targetPos = pos.inside + } else { + let $pos = view.state.doc.resolve(pos.pos) + targetNode = $pos.parent + targetPos = $pos.depth ? $pos.before() : 0 + } + + this.mightDrag = null + + const target = flushed ? null : event.target + const targetDesc = target ? view.docView.nearestDesc(target, true) : null + this.target = targetDesc ? targetDesc.dom : null + + if (targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false || + view.state.selection instanceof NodeSelection && targetPos == view.state.selection.from) + this.mightDrag = {node: targetNode, + pos: targetPos, + addAttr: this.target && !this.target.draggable, + setUneditable: this.target && browser.gecko && !this.target.hasAttribute("contentEditable")} + + if (this.target && this.mightDrag && (this.mightDrag.addAttr || this.mightDrag.setUneditable)) { + this.view.domObserver.stop() + if (this.mightDrag.addAttr) this.target.draggable = true + if (this.mightDrag.setUneditable) + setTimeout(() => this.target.setAttribute("contentEditable", "false"), 20) + this.view.domObserver.start() + } + + view.root.addEventListener("mouseup", this.up = this.up.bind(this)) + view.root.addEventListener("mousemove", this.move = this.move.bind(this)) + setSelectionOrigin(view, "pointer") + } + + done() { + this.view.root.removeEventListener("mouseup", this.up) + this.view.root.removeEventListener("mousemove", this.move) + if (this.mightDrag && this.target) { + this.view.domObserver.stop() + if (this.mightDrag.addAttr) this.target.draggable = false + if (this.mightDrag.setUneditable) this.target.removeAttribute("contentEditable") + this.view.domObserver.start() + } + this.view.mouseDown = null + } + + up(event) { + this.done() + + if (!this.view.dom.contains(event.target.nodeType == 3 ? event.target.parentNode : event.target)) + return + + let pos = this.pos + if (this.view.state.doc != this.startDoc) pos = this.view.posAtCoords(eventCoords(event)) + + if (this.allowDefault || !pos) { + setSelectionOrigin(this.view, "pointer") + } else if (handleSingleClick(this.view, pos.pos, pos.inside, event, this.selectNode)) { + event.preventDefault() + } else if (this.flushed || + // Chrome will sometimes treat a node selection as a + // cursor, but still report that the node is selected + // when asked through getSelection. You'll then get a + // situation where clicking at the point where that + // (hidden) cursor is doesn't change the selection, and + // thus doesn't get a reaction from ProseMirror. This + // works around that. + (browser.chrome && !(this.view.state.selection instanceof TextSelection) && + (pos.pos == this.view.state.selection.from || pos.pos == this.view.state.selection.to))) { + updateSelection(this.view, Selection.near(this.view.state.doc.resolve(pos.pos)), "pointer") + event.preventDefault() + } else { + setSelectionOrigin(this.view, "pointer") + } + } + + move(event) { + if (!this.allowDefault && (Math.abs(this.event.x - event.clientX) > 4 || + Math.abs(this.event.y - event.clientY) > 4)) + this.allowDefault = true + setSelectionOrigin(this.view, "pointer") + } +} + +handlers.touchdown = view => { + forceDOMFlush(view) + setSelectionOrigin(view, "pointer") +} + +handlers.contextmenu = view => forceDOMFlush(view) + +function inOrNearComposition(view, event) { + if (view.composing) return true + // See https://www.stum.de/2016/06/24/handling-ime-events-in-javascript/. + // On Japanese input method editors (IMEs), the Enter key is used to confirm character + // selection. On Safari, when Enter is pressed, compositionend and keydown events are + // emitted. The keydown event triggers newline insertion, which we don't want. + // This method returns true if the keydown event should be ignored. + // We only ignore it once, as pressing Enter a second time *should* insert a newline. + // Furthermore, the keydown event timestamp must be close to the compositionEndedAt timestamp. + // This guards against the case where compositionend is triggered without the keyboard + // (e.g. character confirmation may be done with the mouse), and keydown is triggered + // afterwards- we wouldn't want to ignore the keydown event in this case. + if (browser.safari && Math.abs(event.timeStamp - view.compositionEndedAt) < 500) { + view.compositionEndedAt = -2e8 + return true + } + return false +} + +// Drop active composition after 5 seconds of inactivity on Android +const timeoutComposition = browser.android ? 5000 : -1 + +editHandlers.compositionstart = editHandlers.compositionupdate = view => { + if (!view.composing) { + view.domObserver.flush() + let {state} = view, $pos = state.selection.$from + if (state.selection.empty && + (state.storedMarks || (!$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some(m => m.type.spec.inclusive === false)))) { + // Need to wrap the cursor in mark nodes different from the ones in the DOM context + view.markCursor = view.state.storedMarks || $pos.marks() + endComposition(view, true) + view.markCursor = null + } else { + endComposition(view) + // In firefox, if the cursor is after but outside a marked node, + // the inserted text won't inherit the marks. So this moves it + // inside if necessary. + if (browser.gecko && state.selection.empty && $pos.parentOffset && !$pos.textOffset && $pos.nodeBefore.marks.length) { + let sel = view.root.getSelection() + for (let node = sel.focusNode, offset = sel.focusOffset; node && node.nodeType == 1 && offset != 0;) { + let before = offset < 0 ? node.lastChild : node.childNodes[offset - 1] + if (before.nodeType == 3) { + sel.collapse(before, before.nodeValue.length) + break + } else { + node = before + offset = -1 + } + } + } + } + view.composing = true + } + scheduleComposeEnd(view, timeoutComposition) +} + +editHandlers.compositionend = (view, event) => { + if (view.composing) { + view.composing = false + view.compositionEndedAt = event.timeStamp + scheduleComposeEnd(view, 20) + } +} + +function scheduleComposeEnd(view, delay) { + clearTimeout(view.composingTimeout) + if (delay > -1) view.composingTimeout = setTimeout(() => endComposition(view), delay) +} + +export function endComposition(view, forceUpdate) { + view.composing = false + while (view.compositionNodes.length > 0) view.compositionNodes.pop().markParentsDirty() + if (forceUpdate || view.docView.dirty) { + view.updateState(view.state) + return true + } + return false +} + +function captureCopy(view, dom) { + // The extra wrapper is somehow necessary on IE/Edge to prevent the + // content from being mangled when it is put onto the clipboard + let doc = view.dom.ownerDocument + let wrap = doc.body.appendChild(doc.createElement("div")) + wrap.appendChild(dom) + wrap.style.cssText = "position: fixed; left: -10000px; top: 10px" + let sel = getSelection(), range = doc.createRange() + range.selectNodeContents(dom) + // Done because IE will fire a selectionchange moving the selection + // to its start when removeAllRanges is called and the editor still + // has focus (which will mess up the editor's selection state). + view.dom.blur() + sel.removeAllRanges() + sel.addRange(range) + setTimeout(() => { + doc.body.removeChild(wrap) + view.focus() + }, 50) +} + +// This is very crude, but unfortunately both these browsers _pretend_ +// that they have a clipboard API—all the objects and methods are +// there, they just don't work, and they are hard to test. +const brokenClipboardAPI = (browser.ie && browser.ie_version < 15) || + (browser.ios && browser.webkit_version < 604) + +handlers.copy = editHandlers.cut = (view, e) => { + let sel = view.state.selection, cut = e.type == "cut" + if (sel.empty) return + + // IE and Edge's clipboard interface is completely broken + let data = brokenClipboardAPI ? null : e.clipboardData + let slice = sel.content(), {dom, text} = serializeForClipboard(view, slice) + if (data) { + e.preventDefault() + data.clearData() + data.setData("text/html", dom.innerHTML) + data.setData("text/plain", text) + } else { + captureCopy(view, dom) + } + if (cut) view.dispatch(view.state.tr.deleteSelection().scrollIntoView().setMeta("uiEvent", "cut")) +} + +function sliceSingleNode(slice) { + return slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1 ? slice.content.firstChild : null +} + +function capturePaste(view, e) { + let doc = view.dom.ownerDocument + let plainText = view.shiftKey || view.state.selection.$from.parent.type.spec.code + let target = doc.body.appendChild(doc.createElement(plainText ? "textarea" : "div")) + if (!plainText) target.contentEditable = "true" + target.style.cssText = "position: fixed; left: -10000px; top: 10px" + target.focus() + setTimeout(() => { + view.focus() + doc.body.removeChild(target) + if (plainText) doPaste(view, target.value, null, e) + else doPaste(view, target.textContent, target.innerHTML, e) + }, 50) +} + +function doPaste(view, text, html, e) { + let slice = parseFromClipboard(view, text, html, view.shiftKey, view.state.selection.$from) + if (view.someProp("handlePaste", f => f(view, e, slice || Slice.empty)) || !slice) return + + let singleNode = sliceSingleNode(slice) + let tr = singleNode ? view.state.tr.replaceSelectionWith(singleNode, view.shiftKey) : view.state.tr.replaceSelection(slice) + view.dispatch(tr.scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste")) +} + +editHandlers.paste = (view, e) => { + let data = brokenClipboardAPI ? null : e.clipboardData + let html = data && data.getData("text/html"), text = data && data.getData("text/plain") + if (data && (html || text || data.files.length)) { + doPaste(view, text, html, e) + e.preventDefault() + } else { + capturePaste(view, e) + } +} + +class Dragging { + constructor(slice, move) { + this.slice = slice + this.move = move + } +} + +const dragCopyModifier = browser.mac ? "altKey" : "ctrlKey" + +handlers.dragstart = (view, e) => { + let mouseDown = view.mouseDown + if (mouseDown) mouseDown.done() + if (!e.dataTransfer) return + + let sel = view.state.selection + let pos = sel.empty ? null : view.posAtCoords(eventCoords(e)) + if (pos && pos.pos >= sel.from && pos.pos <= (sel instanceof NodeSelection ? sel.to - 1: sel.to)) { + // In selection + } else if (mouseDown && mouseDown.mightDrag) { + view.dispatch(view.state.tr.setSelection(NodeSelection.create(view.state.doc, mouseDown.mightDrag.pos))) + } else if (e.target && e.target.nodeType == 1) { + let desc = view.docView.nearestDesc(e.target, true) + if (!desc || !desc.node.type.spec.draggable || desc == view.docView) return + view.dispatch(view.state.tr.setSelection(NodeSelection.create(view.state.doc, desc.posBefore))) + } + let slice = view.state.selection.content(), {dom, text} = serializeForClipboard(view, slice) + e.dataTransfer.clearData() + e.dataTransfer.setData(brokenClipboardAPI ? "Text" : "text/html", dom.innerHTML) + if (!brokenClipboardAPI) e.dataTransfer.setData("text/plain", text) + view.dragging = new Dragging(slice, !e[dragCopyModifier]) +} + +handlers.dragend = view => { + window.setTimeout(() => view.dragging = null, 50) +} + +editHandlers.dragover = editHandlers.dragenter = (_, e) => e.preventDefault() + +editHandlers.drop = (view, e) => { + let dragging = view.dragging + view.dragging = null + + if (!e.dataTransfer) return + + let eventPos = view.posAtCoords(eventCoords(e)) + if (!eventPos) return + let $mouse = view.state.doc.resolve(eventPos.pos) + if (!$mouse) return + let slice = dragging && dragging.slice || + parseFromClipboard(view, e.dataTransfer.getData(brokenClipboardAPI ? "Text" : "text/plain"), + brokenClipboardAPI ? null : e.dataTransfer.getData("text/html"), false, $mouse) + if (!slice) return + + e.preventDefault() + if (view.someProp("handleDrop", f => f(view, e, slice, dragging && dragging.move))) return + let insertPos = slice ? dropPoint(view.state.doc, $mouse.pos, slice) : $mouse.pos + if (insertPos == null) insertPos = $mouse.pos + + let tr = view.state.tr + if (dragging && dragging.move) tr.deleteSelection() + + let pos = tr.mapping.map(insertPos) + let isNode = slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1 + let beforeInsert = tr.doc + if (isNode) + tr.replaceRangeWith(pos, pos, slice.content.firstChild) + else + tr.replaceRange(pos, pos, slice) + if (tr.doc.eq(beforeInsert)) return + + let $pos = tr.doc.resolve(pos) + if (isNode && NodeSelection.isSelectable(slice.content.firstChild) && + $pos.nodeAfter && $pos.nodeAfter.sameMarkup(slice.content.firstChild)) + tr.setSelection(new NodeSelection($pos)) + else + tr.setSelection(selectionBetween(view, $pos, tr.doc.resolve(tr.mapping.map(insertPos)))) + view.focus() + view.dispatch(tr.setMeta("uiEvent", "drop")) +} + +handlers.focus = view => { + if (!view.focused) { + view.domObserver.stop() + view.dom.classList.add("ProseMirror-focused") + view.domObserver.start() + view.focused = true + } +} + +handlers.blur = view => { + if (view.focused) { + view.domObserver.stop() + view.dom.classList.remove("ProseMirror-focused") + view.domObserver.start() + view.domObserver.currentSelection.set({}) + view.focused = false + } +} + +handlers.beforeinput = (view, event) => { + // We should probably do more with beforeinput events, but support + // is so spotty that I'm still waiting to see where they are going. + + // Very specific hack to deal with backspace sometimes failing on + // Chrome Android when after an uneditable node. + if (browser.chrome && browser.android && event.inputType == "deleteContentBackward") { + let {domChangeCount} = view + setTimeout(() => { + if (view.domChangeCount != domChangeCount) return // Event already had some effect + // This bug tends to close the virtual keyboard, so we refocus + view.dom.blur() + view.focus() + if (view.someProp("handleKeyDown", f => f(view, keyEvent(8, "Backspace")))) return + let {$cursor} = view.state.selection + // Crude approximation of backspace behavior when no command handled it + if ($cursor && $cursor.pos > 0) view.dispatch(view.state.tr.delete($cursor.pos - 1, $cursor.pos).scrollIntoView()) + }, 50) + } +} + +// Make sure all handlers get registered +for (let prop in editHandlers) handlers[prop] = editHandlers[prop] diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/src/selection.js b/packages/tiptap-extensions/node_modules/prosemirror-view/src/selection.js new file mode 100644 index 0000000000..97d73bb21d --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/src/selection.js @@ -0,0 +1,167 @@ +import {TextSelection, NodeSelection} from "prosemirror-state" + +import browser from "./browser" +import {selectionCollapsed, isEquivalentPosition, domIndex} from "./dom" + +export function selectionFromDOM(view, origin) { + let domSel = view.root.getSelection(), doc = view.state.doc + let nearestDesc = view.docView.nearestDesc(domSel.focusNode), inWidget = nearestDesc && nearestDesc.size == 0 + let head = view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset) + let $head = doc.resolve(head), $anchor, selection + if (selectionCollapsed(domSel)) { + $anchor = $head + while (nearestDesc && !nearestDesc.node) nearestDesc = nearestDesc.parent + if (nearestDesc && nearestDesc.node.isAtom && NodeSelection.isSelectable(nearestDesc.node) && nearestDesc.parent) { + let pos = nearestDesc.posBefore + selection = new NodeSelection(head == pos ? $head : doc.resolve(pos)) + } + } else { + $anchor = doc.resolve(view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset)) + } + + if (!selection) { + let bias = origin == "pointer" || (view.state.selection.head < $head.pos && !inWidget) ? 1 : -1 + selection = selectionBetween(view, $anchor, $head, bias) + } + return selection +} + +export function selectionToDOM(view, force) { + let sel = view.state.selection + syncNodeSelection(view, sel) + + if (view.editable ? !view.hasFocus() : !(hasSelection(view) && document.activeElement.contains(view.dom))) return + + view.domObserver.disconnectSelection() + + if (view.cursorWrapper) { + selectCursorWrapper(view) + } else { + let {anchor, head} = sel, resetEditableFrom, resetEditableTo + if (brokenSelectBetweenUneditable && !(sel instanceof TextSelection)) { + if (!sel.$from.parent.inlineContent) + resetEditableFrom = temporarilyEditableNear(view, sel.from) + if (!sel.empty && !sel.$from.parent.inlineContent) + resetEditableTo = temporarilyEditableNear(view, sel.to) + } + view.docView.setSelection(anchor, head, view.root, force) + if (brokenSelectBetweenUneditable) { + if (resetEditableFrom) resetEditableFrom.contentEditable = "false" + if (resetEditableTo) resetEditableTo.contentEditable = "false" + } + if (sel.visible) { + view.dom.classList.remove("ProseMirror-hideselection") + } else if (anchor != head) { + view.dom.classList.add("ProseMirror-hideselection") + if ("onselectionchange" in document) removeClassOnSelectionChange(view) + } + } + + view.domObserver.setCurSelection() + view.domObserver.connectSelection() +} + +// Kludge to work around Webkit not allowing a selection to start/end +// between non-editable block nodes. We briefly make something +// editable, set the selection, then set it uneditable again. + +const brokenSelectBetweenUneditable = browser.safari || browser.chrome && browser.chrome_version < 63 + +function temporarilyEditableNear(view, pos) { + let {node, offset} = view.docView.domFromPos(pos) + let after = offset < node.childNodes.length ? node.childNodes[offset] : null + let before = offset ? node.childNodes[offset - 1] : null + if ((!after || after.contentEditable == "false") && (!before || before.contentEditable == "false")) { + if (after) { + after.contentEditable = "true" + return after + } else if (before) { + before.contentEditable = "true" + return before + } + } +} + +function removeClassOnSelectionChange(view) { + let doc = view.dom.ownerDocument + doc.removeEventListener("selectionchange", view.hideSelectionGuard) + let domSel = view.root.getSelection() + let node = domSel.anchorNode, offset = domSel.anchorOffset + doc.addEventListener("selectionchange", view.hideSelectionGuard = () => { + if (domSel.anchorNode != node || domSel.anchorOffset != offset) { + doc.removeEventListener("selectionchange", view.hideSelectionGuard) + view.dom.classList.remove("ProseMirror-hideselection") + } + }) +} + +function selectCursorWrapper(view) { + let domSel = view.root.getSelection(), range = document.createRange() + let node = view.cursorWrapper.dom, img = node.nodeName == "IMG" + if (img) range.setEnd(node.parentNode, domIndex(node) + 1) + else range.setEnd(node, 0) + range.collapse(false) + domSel.removeAllRanges() + domSel.addRange(range) + // Kludge to kill 'control selection' in IE11 when selecting an + // invisible cursor wrapper, since that would result in those weird + // resize handles and a selection that considers the absolutely + // positioned wrapper, rather than the root editable node, the + // focused element. + if (!img && !view.state.selection.visible && browser.ie && browser.ie_version <= 11) { + node.disabled = true + node.disabled = false + } +} + +export function syncNodeSelection(view, sel) { + if (sel instanceof NodeSelection) { + let desc = view.docView.descAt(sel.from) + if (desc != view.lastSelectedViewDesc) { + clearNodeSelection(view) + if (desc) desc.selectNode() + view.lastSelectedViewDesc = desc + } + } else { + clearNodeSelection(view) + } +} + +// Clear all DOM statefulness of the last node selection. +function clearNodeSelection(view) { + if (view.lastSelectedViewDesc) { + if (view.lastSelectedViewDesc.parent) + view.lastSelectedViewDesc.deselectNode() + view.lastSelectedViewDesc = null + } +} + +export function selectionBetween(view, $anchor, $head, bias) { + return view.someProp("createSelectionBetween", f => f(view, $anchor, $head)) + || TextSelection.between($anchor, $head, bias) +} + +export function hasFocusAndSelection(view) { + if (view.editable && view.root.activeElement != view.dom) return false + return hasSelection(view) +} + +export function hasSelection(view) { + let sel = view.root.getSelection() + if (!sel.anchorNode) return false + try { + // Firefox will raise 'permission denied' errors when accessing + // properties of `sel.anchorNode` when it's in a generated CSS + // element. + return view.dom.contains(sel.anchorNode.nodeType == 3 ? sel.anchorNode.parentNode : sel.anchorNode) && + (view.editable || view.dom.contains(sel.focusNode.nodeType == 3 ? sel.focusNode.parentNode : sel.focusNode)) + } catch(_) { + return false + } +} + +export function anchorInRightPlace(view) { + let anchorDOM = view.docView.domFromPos(view.state.selection.anchor) + let domSel = view.root.getSelection() + return isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset) +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/src/viewdesc.js b/packages/tiptap-extensions/node_modules/prosemirror-view/src/viewdesc.js new file mode 100644 index 0000000000..ad75372727 --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/src/viewdesc.js @@ -0,0 +1,1285 @@ +import {DOMSerializer, Fragment, Mark} from "prosemirror-model" +import {TextSelection} from "prosemirror-state" + +import {domIndex, isEquivalentPosition, nodeSize} from "./dom" +import browser from "./browser" + +// NodeView:: interface +// +// By default, document nodes are rendered using the result of the +// [`toDOM`](#model.NodeSpec.toDOM) method of their spec, and managed +// entirely by the editor. For some use cases, such as embedded +// node-specific editing interfaces, you want more control over +// the behavior of a node's in-editor representation, and need to +// [define](#view.EditorProps.nodeViews) a custom node view. +// +// Objects returned as node views must conform to this interface. +// +// dom:: ?dom.Node +// The outer DOM node that represents the document node. When not +// given, the default strategy is used to create a DOM node. +// +// contentDOM:: ?dom.Node +// The DOM node that should hold the node's content. Only meaningful +// if the node view also defines a `dom` property and if its node +// type is not a leaf node type. When this is present, ProseMirror +// will take care of rendering the node's children into it. When it +// is not present, the node view itself is responsible for rendering +// (or deciding not to render) its child nodes. +// +// update:: ?(node: Node, decorations: [Decoration]) → bool +// When given, this will be called when the view is updating itself. +// It will be given a node (possibly of a different type), and an +// array of active decorations (which are automatically drawn, and +// the node view may ignore if it isn't interested in them), and +// should return true if it was able to update to that node, and +// false otherwise. If the node view has a `contentDOM` property (or +// no `dom` property), updating its child nodes will be handled by +// ProseMirror. +// +// selectNode:: ?() +// Can be used to override the way the node's selected status (as a +// node selection) is displayed. +// +// deselectNode:: ?() +// When defining a `selectNode` method, you should also provide a +// `deselectNode` method to remove the effect again. +// +// setSelection:: ?(anchor: number, head: number, root: dom.Document) +// This will be called to handle setting the selection inside the +// node. The `anchor` and `head` positions are relative to the start +// of the node. By default, a DOM selection will be created between +// the DOM positions corresponding to those positions, but if you +// override it you can do something else. +// +// stopEvent:: ?(event: dom.Event) → bool +// Can be used to prevent the editor view from trying to handle some +// or all DOM events that bubble up from the node view. Events for +// which this returns true are not handled by the editor. +// +// ignoreMutation:: ?(dom.MutationRecord) → bool +// Called when a DOM +// [mutation](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) +// or a selection change happens within the view. When the change is +// a selection change, the record will have a `type` property of +// `"selection"` (which doesn't occur for native mutation records). +// Return false if the editor should re-read the selection or +// re-parse the range around the mutation, true if it can safely be +// ignored. +// +// destroy:: ?() +// Called when the node view is removed from the editor or the whole +// editor is destroyed. + +// View descriptions are data structures that describe the DOM that is +// used to represent the editor's content. They are used for: +// +// - Incremental redrawing when the document changes +// +// - Figuring out what part of the document a given DOM position +// corresponds to +// +// - Wiring in custom implementations of the editing interface for a +// given node +// +// They form a doubly-linked mutable tree, starting at `view.docView`. + +const NOT_DIRTY = 0, CHILD_DIRTY = 1, CONTENT_DIRTY = 2, NODE_DIRTY = 3 + +// Superclass for the various kinds of descriptions. Defines their +// basic structure and shared methods. +class ViewDesc { + // : (?ViewDesc, [ViewDesc], dom.Node, ?dom.Node) + constructor(parent, children, dom, contentDOM) { + this.parent = parent + this.children = children + this.dom = dom + // An expando property on the DOM node provides a link back to its + // description. + dom.pmViewDesc = this + // This is the node that holds the child views. It may be null for + // descs that don't have children. + this.contentDOM = contentDOM + this.dirty = NOT_DIRTY + } + + // Used to check whether a given description corresponds to a + // widget/mark/node. + matchesWidget() { return false } + matchesMark() { return false } + matchesNode() { return false } + matchesHack() { return false } + + get beforePosition() { return false } + + // : () → ?ParseRule + // When parsing in-editor content (in domchange.js), we allow + // descriptions to determine the parse rules that should be used to + // parse them. + parseRule() { return null } + + // : (dom.Event) → bool + // Used by the editor's event handler to ignore events that come + // from certain descs. + stopEvent() { return false } + + // The size of the content represented by this desc. + get size() { + let size = 0 + for (let i = 0; i < this.children.length; i++) size += this.children[i].size + return size + } + + // For block nodes, this represents the space taken up by their + // start/end tokens. + get border() { return 0 } + + destroy() { + this.parent = null + if (this.dom.pmViewDesc == this) this.dom.pmViewDesc = null + for (let i = 0; i < this.children.length; i++) + this.children[i].destroy() + } + + posBeforeChild(child) { + for (let i = 0, pos = this.posAtStart; i < this.children.length; i++) { + let cur = this.children[i] + if (cur == child) return pos + pos += cur.size + } + } + + get posBefore() { + return this.parent.posBeforeChild(this) + } + + get posAtStart() { + return this.parent ? this.parent.posBeforeChild(this) + this.border : 0 + } + + get posAfter() { + return this.posBefore + this.size + } + + get posAtEnd() { + return this.posAtStart + this.size - 2 * this.border + } + + // : (dom.Node, number, ?number) → number + localPosFromDOM(dom, offset, bias) { + // If the DOM position is in the content, use the child desc after + // it to figure out a position. + if (this.contentDOM && this.contentDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode)) { + if (bias < 0) { + let domBefore, desc + if (dom == this.contentDOM) { + domBefore = dom.childNodes[offset - 1] + } else { + while (dom.parentNode != this.contentDOM) dom = dom.parentNode + domBefore = dom.previousSibling + } + while (domBefore && !((desc = domBefore.pmViewDesc) && desc.parent == this)) domBefore = domBefore.previousSibling + return domBefore ? this.posBeforeChild(desc) + desc.size : this.posAtStart + } else { + let domAfter, desc + if (dom == this.contentDOM) { + domAfter = dom.childNodes[offset] + } else { + while (dom.parentNode != this.contentDOM) dom = dom.parentNode + domAfter = dom.nextSibling + } + while (domAfter && !((desc = domAfter.pmViewDesc) && desc.parent == this)) domAfter = domAfter.nextSibling + return domAfter ? this.posBeforeChild(desc) : this.posAtEnd + } + } + // Otherwise, use various heuristics, falling back on the bias + // parameter, to determine whether to return the position at the + // start or at the end of this view desc. + let atEnd + if (this.contentDOM && this.contentDOM != this.dom && this.dom.contains(this.contentDOM)) { + atEnd = dom.compareDocumentPosition(this.contentDOM) & 2 + } else if (this.dom.firstChild) { + if (offset == 0) for (let search = dom;; search = search.parentNode) { + if (search == this.dom) { atEnd = false; break } + if (search.parentNode.firstChild != search) break + } + if (atEnd == null && offset == dom.childNodes.length) for (let search = dom;; search = search.parentNode) { + if (search == this.dom) { atEnd = true; break } + if (search.parentNode.lastChild != search) break + } + } + return (atEnd == null ? bias > 0 : atEnd) ? this.posAtEnd : this.posAtStart + } + + // Scan up the dom finding the first desc that is a descendant of + // this one. + nearestDesc(dom, onlyNodes) { + for (let first = true, cur = dom; cur; cur = cur.parentNode) { + let desc = this.getDesc(cur) + if (desc && (!onlyNodes || desc.node)) { + // If dom is outside of this desc's nodeDOM, don't count it. + if (first && desc.nodeDOM && !(desc.nodeDOM.nodeType == 1 ? desc.nodeDOM.contains(dom) : desc.nodeDOM == dom)) first = false + else return desc + } + } + } + + getDesc(dom) { + let desc = dom.pmViewDesc + for (let cur = desc; cur; cur = cur.parent) if (cur == this) return desc + } + + posFromDOM(dom, offset, bias) { + for (let scan = dom;; scan = scan.parentNode) { + let desc = this.getDesc(scan) + if (desc) return desc.localPosFromDOM(dom, offset, bias) + } + } + + // : (number) → ?NodeViewDesc + // Find the desc for the node after the given pos, if any. (When a + // parent node overrode rendering, there might not be one.) + descAt(pos) { + for (let i = 0, offset = 0; i < this.children.length; i++) { + let child = this.children[i], end = offset + child.size + if (offset == pos && end != offset) { + while (!child.border && child.children.length) child = child.children[0] + return child + } + if (pos < end) return child.descAt(pos - offset - child.border) + offset = end + } + } + + // : (number) → {node: dom.Node, offset: number} + domFromPos(pos) { + if (!this.contentDOM) return {node: this.dom, offset: 0} + for (let offset = 0, i = 0;; i++) { + if (offset == pos) { + while (i < this.children.length && (this.children[i].beforePosition || this.children[i].dom.parentNode != this.contentDOM)) i++ + return {node: this.contentDOM, + offset: i == this.children.length ? this.contentDOM.childNodes.length : domIndex(this.children[i].dom)} + } + if (i == this.children.length) throw new Error("Invalid position " + pos) + let child = this.children[i], end = offset + child.size + if (pos < end) return child.domFromPos(pos - offset - child.border) + offset = end + } + } + + // Used to find a DOM range in a single parent for a given changed + // range. + parseRange(from, to, base = 0) { + if (this.children.length == 0) + return {node: this.contentDOM, from, to, fromOffset: 0, toOffset: this.contentDOM.childNodes.length} + + let fromOffset = -1, toOffset = -1 + for (let offset = base, i = 0;; i++) { + let child = this.children[i], end = offset + child.size + if (fromOffset == -1 && from <= end) { + let childBase = offset + child.border + // FIXME maybe descend mark views to parse a narrower range? + if (from >= childBase && to <= end - child.border && child.node && + child.contentDOM && this.contentDOM.contains(child.contentDOM)) + return child.parseRange(from, to, childBase) + + from = offset + for (let j = i; j > 0; j--) { + let prev = this.children[j - 1] + if (prev.size && prev.dom.parentNode == this.contentDOM && !prev.emptyChildAt(1)) { + fromOffset = domIndex(prev.dom) + 1 + break + } + from -= prev.size + } + if (fromOffset == -1) fromOffset = 0 + } + if (fromOffset > -1 && to <= end) { + to = end + for (let j = i + 1; j < this.children.length; j++) { + let next = this.children[j] + if (next.size && next.dom.parentNode == this.contentDOM && !next.emptyChildAt(-1)) { + toOffset = domIndex(next.dom) + break + } + to += next.size + } + if (toOffset == -1) toOffset = this.contentDOM.childNodes.length + break + } + offset = end + } + return {node: this.contentDOM, from, to, fromOffset, toOffset} + } + + emptyChildAt(side) { + if (this.border || !this.contentDOM || !this.children.length) return false + let child = this.children[side < 0 ? 0 : this.children.length - 1] + return child.size == 0 || child.emptyChildAt(side) + } + + // : (number) → dom.Node + domAfterPos(pos) { + let {node, offset} = this.domFromPos(pos) + if (node.nodeType != 1 || offset == node.childNodes.length) + throw new RangeError("No node after pos " + pos) + return node.childNodes[offset] + } + + // : (number, number, dom.Document) + // View descs are responsible for setting any selection that falls + // entirely inside of them, so that custom implementations can do + // custom things with the selection. Note that this falls apart when + // a selection starts in such a node and ends in another, in which + // case we just use whatever domFromPos produces as a best effort. + setSelection(anchor, head, root, force) { + // If the selection falls entirely in a child, give it to that child + let from = Math.min(anchor, head), to = Math.max(anchor, head) + for (let i = 0, offset = 0; i < this.children.length; i++) { + let child = this.children[i], end = offset + child.size + if (from > offset && to < end) + return child.setSelection(anchor - offset - child.border, head - offset - child.border, root, force) + offset = end + } + + let anchorDOM = this.domFromPos(anchor), headDOM = this.domFromPos(head) + let domSel = root.getSelection(), range = document.createRange() + if (!force && + isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset) && + isEquivalentPosition(headDOM.node, headDOM.offset, domSel.focusNode, domSel.focusOffset)) + return + + // Selection.extend can be used to create an 'inverted' selection + // (one where the focus is before the anchor), but not all + // browsers support it yet. + if (domSel.extend) { + range.setEnd(anchorDOM.node, anchorDOM.offset) + range.collapse(false) + } else { + if (anchor > head) { let tmp = anchorDOM; anchorDOM = headDOM; headDOM = tmp } + range.setEnd(headDOM.node, headDOM.offset) + range.setStart(anchorDOM.node, anchorDOM.offset) + } + domSel.removeAllRanges() + domSel.addRange(range) + if (domSel.extend) + domSel.extend(headDOM.node, headDOM.offset) + } + + // : (dom.MutationRecord) → bool + ignoreMutation(_mutation) { + return !this.contentDOM + } + + get contentLost() { + return this.contentDOM && this.contentDOM != this.dom && !this.dom.contains(this.contentDOM) + } + + // Remove a subtree of the element tree that has been touched + // by a DOM change, so that the next update will redraw it. + markDirty(from, to) { + for (let offset = 0, i = 0; i < this.children.length; i++) { + let child = this.children[i], end = offset + child.size + if (offset == end ? from <= end && to >= offset : from < end && to > offset) { + let startInside = offset + child.border, endInside = end - child.border + if (from >= startInside && to <= endInside) { + this.dirty = from == offset || to == end ? CONTENT_DIRTY : CHILD_DIRTY + if (from == startInside && to == endInside && + (child.contentLost || child.dom.parentNode != this.contentDOM)) child.dirty = NODE_DIRTY + else child.markDirty(from - startInside, to - startInside) + return + } else { + child.dirty = NODE_DIRTY + } + } + offset = end + } + this.dirty = CONTENT_DIRTY + } + + markParentsDirty() { + let level = 1 + for (let node = this.parent; node; node = node.parent) { + let dirty = level == 1 ? CONTENT_DIRTY : CHILD_DIRTY + if (node.dirty < dirty) node.dirty = dirty + } + } +} + +// Reused array to avoid allocating fresh arrays for things that will +// stay empty anyway. +const nothing = [] + +// A widget desc represents a widget decoration, which is a DOM node +// drawn between the document nodes. +class WidgetViewDesc extends ViewDesc { + // : (ViewDesc, Decoration) + constructor(parent, widget, view, pos) { + let self, dom = widget.type.toDOM + if (typeof dom == "function") dom = dom(view, () => { + if (!self) return pos + if (self.parent) return self.parent.posBeforeChild(self) + }) + if (!widget.type.spec.raw) { + if (dom.nodeType != 1) { + let wrap = document.createElement("span") + wrap.appendChild(dom) + dom = wrap + } + dom.contentEditable = false + dom.classList.add("ProseMirror-widget") + } + super(parent, nothing, dom, null) + this.widget = widget + self = this + } + + get beforePosition() { + return this.widget.type.side < 0 + } + + matchesWidget(widget) { + return this.dirty == NOT_DIRTY && widget.type.eq(this.widget.type) + } + + parseRule() { return {ignore: true} } + + stopEvent(event) { + let stop = this.widget.spec.stopEvent + return stop ? stop(event) : false + } +} + +class CompositionViewDesc extends ViewDesc { + constructor(parent, dom, textDOM, text) { + super(parent, nothing, dom, null) + this.textDOM = textDOM + this.text = text + } + + get size() { return this.text.length } + + localPosFromDOM(dom, offset) { + if (dom != this.textDOM) return this.posAtStart + (offset ? this.size : 0) + return this.posAtStart + offset + } + + domFromPos(pos) { + return {node: this.textDOM, offset: pos} + } + + ignoreMutation(mut) { + return mut.type === 'characterData' && mut.target.nodeValue == mut.oldValue + } +} + +// A mark desc represents a mark. May have multiple children, +// depending on how the mark is split. Note that marks are drawn using +// a fixed nesting order, for simplicity and predictability, so in +// some cases they will be split more often than would appear +// necessary. +class MarkViewDesc extends ViewDesc { + // : (ViewDesc, Mark, dom.Node) + constructor(parent, mark, dom, contentDOM) { + super(parent, [], dom, contentDOM) + this.mark = mark + } + + static create(parent, mark, inline, view) { + let custom = view.nodeViews[mark.type.name] + let spec = custom && custom(mark, view, inline) + if (!spec || !spec.dom) + spec = DOMSerializer.renderSpec(document, mark.type.spec.toDOM(mark, inline)) + return new MarkViewDesc(parent, mark, spec.dom, spec.contentDOM || spec.dom) + } + + parseRule() { return {mark: this.mark.type.name, attrs: this.mark.attrs, contentElement: this.contentDOM} } + + matchesMark(mark) { return this.dirty != NODE_DIRTY && this.mark.eq(mark) } + + markDirty(from, to) { + super.markDirty(from, to) + // Move dirty info to nearest node view + if (this.dirty != NOT_DIRTY) { + let parent = this.parent + while (!parent.node) parent = parent.parent + if (parent.dirty < this.dirty) parent.dirty = this.dirty + this.dirty = NOT_DIRTY + } + } + + slice(from, to, view) { + let copy = MarkViewDesc.create(this.parent, this.mark, true, view) + let nodes = this.children, size = this.size + if (to < size) nodes = replaceNodes(nodes, to, size, view) + if (from > 0) nodes = replaceNodes(nodes, 0, from, view) + for (let i = 0; i < nodes.length; i++) nodes[i].parent = copy + copy.children = nodes + return copy + } +} + +// Node view descs are the main, most common type of view desc, and +// correspond to an actual node in the document. Unlike mark descs, +// they populate their child array themselves. +class NodeViewDesc extends ViewDesc { + // : (?ViewDesc, Node, [Decoration], DecorationSet, dom.Node, ?dom.Node, EditorView) + constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos) { + super(parent, node.isLeaf ? nothing : [], dom, contentDOM) + this.nodeDOM = nodeDOM + this.node = node + this.outerDeco = outerDeco + this.innerDeco = innerDeco + if (contentDOM) this.updateChildren(view, pos) + } + + // By default, a node is rendered using the `toDOM` method from the + // node type spec. But client code can use the `nodeViews` spec to + // supply a custom node view, which can influence various aspects of + // the way the node works. + // + // (Using subclassing for this was intentionally decided against, + // since it'd require exposing a whole slew of finnicky + // implementation details to the user code that they probably will + // never need.) + static create(parent, node, outerDeco, innerDeco, view, pos) { + let custom = view.nodeViews[node.type.name], descObj + let spec = custom && custom(node, view, () => { + // (This is a function that allows the custom view to find its + // own position) + if (!descObj) return pos + if (descObj.parent) return descObj.parent.posBeforeChild(descObj) + }, outerDeco) + + let dom = spec && spec.dom, contentDOM = spec && spec.contentDOM + if (node.isText) { + if (!dom) dom = document.createTextNode(node.text) + else if (dom.nodeType != 3) throw new RangeError("Text must be rendered as a DOM text node") + } else if (!dom) { + ;({dom, contentDOM} = DOMSerializer.renderSpec(document, node.type.spec.toDOM(node))) + } + if (!contentDOM && !node.isText && dom.nodeName != "BR") { // Chrome gets confused by
    + if (!dom.hasAttribute("contenteditable")) dom.contentEditable = false + if (node.type.spec.draggable) dom.draggable = true + } + + let nodeDOM = dom + dom = applyOuterDeco(dom, outerDeco, node) + + if (spec) + return descObj = new CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, + spec, view, pos + 1) + else if (node.isText) + return new TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM, view) + else + return new NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos + 1) + } + + parseRule() { + // Experimental kludge to allow opt-in re-parsing of nodes + if (this.node.type.spec.reparseInView) return null + // FIXME the assumption that this can always return the current + // attrs means that if the user somehow manages to change the + // attrs in the dom, that won't be picked up. Not entirely sure + // whether this is a problem + let rule = {node: this.node.type.name, attrs: this.node.attrs} + if (this.node.type.spec.code) rule.preserveWhitespace = "full" + if (this.contentDOM && !this.contentLost) rule.contentElement = this.contentDOM + else rule.getContent = () => this.contentDOM ? Fragment.empty : this.node.content + return rule + } + + matchesNode(node, outerDeco, innerDeco) { + return this.dirty == NOT_DIRTY && node.eq(this.node) && + sameOuterDeco(outerDeco, this.outerDeco) && innerDeco.eq(this.innerDeco) + } + + get size() { return this.node.nodeSize } + + get border() { return this.node.isLeaf ? 0 : 1 } + + // Syncs `this.children` to match `this.node.content` and the local + // decorations, possibly introducing nesting for marks. Then, in a + // separate step, syncs the DOM inside `this.contentDOM` to + // `this.children`. + updateChildren(view, pos) { + let inline = this.node.inlineContent, off = pos + let composition = inline && view.composing && this.localCompositionNode(view, pos) + let updater = new ViewTreeUpdater(this, composition && composition.node) + iterDeco(this.node, this.innerDeco, (widget, i) => { + if (widget.spec.marks) + updater.syncToMarks(widget.spec.marks, inline, view) + else if (widget.type.side >= 0) + updater.syncToMarks(i == this.node.childCount ? Mark.none : this.node.child(i).marks, inline, view) + // If the next node is a desc matching this widget, reuse it, + // otherwise insert the widget as a new view desc. + updater.placeWidget(widget, view, off) + }, (child, outerDeco, innerDeco, i) => { + // Make sure the wrapping mark descs match the node's marks. + updater.syncToMarks(child.marks, inline, view) + // Either find an existing desc that exactly matches this node, + // and drop the descs before it. + updater.findNodeMatch(child, outerDeco, innerDeco, i) || + // Or try updating the next desc to reflect this node. + updater.updateNextNode(child, outerDeco, innerDeco, view, i) || + // Or just add it as a new desc. + updater.addNode(child, outerDeco, innerDeco, view, off) + off += child.nodeSize + }) + // Drop all remaining descs after the current position. + updater.syncToMarks(nothing, inline, view) + if (this.node.isTextblock) updater.addTextblockHacks() + updater.destroyRest() + + // Sync the DOM if anything changed + if (updater.changed || this.dirty == CONTENT_DIRTY) { + // May have to protect focused DOM from being changed if a composition is active + if (composition) this.protectLocalComposition(view, composition) + this.renderChildren() + } + } + + renderChildren() { + renderDescs(this.contentDOM, this.children, NodeViewDesc.is) + if (browser.ios) iosHacks(this.dom) + } + + localCompositionNode(view, pos) { + // Only do something if both the selection and a focused text node + // are inside of this node, and the node isn't already part of a + // view that's a child of this view + let {from, to} = view.state.selection + if (!(view.state.selection instanceof TextSelection) || from < pos || to > pos + this.node.content.size) return + let sel = view.root.getSelection() + let textNode = nearbyTextNode(sel.focusNode, sel.focusOffset) + if (!textNode || !this.dom.contains(textNode.parentNode)) return + + // Find the text in the focused node in the node, stop if it's not + // there (may have been modified through other means, in which + // case it should overwritten) + let text = textNode.nodeValue + let textPos = findTextInFragment(this.node.content, text, from - pos, to - pos) + + return textPos < 0 ? null : {node: textNode, pos: textPos, text} + } + + protectLocalComposition(view, {node, pos, text}) { + // The node is already part of a local view desc, leave it there + if (this.getDesc(node)) return + + // Create a composition view for the orphaned nodes + let topNode = node + for (;; topNode = topNode.parentNode) { + if (topNode.parentNode == this.contentDOM) break + while (topNode.previousSibling) topNode.parentNode.removeChild(topNode.previousSibling) + while (topNode.nextSibling) topNode.parentNode.removeChild(topNode.nextSibling) + if (topNode.pmViewDesc) topNode.pmViewDesc = null + } + let desc = new CompositionViewDesc(this, topNode, node, text) + view.compositionNodes.push(desc) + + // Patch up this.children to contain the composition view + this.children = replaceNodes(this.children, pos, pos + text.length, view, desc) + } + + // : (Node, [Decoration], DecorationSet, EditorView) → bool + // If this desc be updated to match the given node decoration, + // do so and return true. + update(node, outerDeco, innerDeco, view) { + if (this.dirty == NODE_DIRTY || + !node.sameMarkup(this.node)) return false + this.updateInner(node, outerDeco, innerDeco, view) + return true + } + + updateInner(node, outerDeco, innerDeco, view) { + this.updateOuterDeco(outerDeco) + this.node = node + this.innerDeco = innerDeco + if (this.contentDOM) this.updateChildren(view, this.posAtStart) + this.dirty = NOT_DIRTY + } + + updateOuterDeco(outerDeco) { + if (sameOuterDeco(outerDeco, this.outerDeco)) return + let needsWrap = this.nodeDOM.nodeType != 1 + let oldDOM = this.dom + this.dom = patchOuterDeco(this.dom, this.nodeDOM, + computeOuterDeco(this.outerDeco, this.node, needsWrap), + computeOuterDeco(outerDeco, this.node, needsWrap)) + if (this.dom != oldDOM) { + oldDOM.pmViewDesc = null + this.dom.pmViewDesc = this + } + this.outerDeco = outerDeco + } + + // Mark this node as being the selected node. + selectNode() { + this.nodeDOM.classList.add("ProseMirror-selectednode") + if (this.contentDOM || !this.node.type.spec.draggable) this.dom.draggable = true + } + + // Remove selected node marking from this node. + deselectNode() { + this.nodeDOM.classList.remove("ProseMirror-selectednode") + if (this.contentDOM || !this.node.type.spec.draggable) this.dom.draggable = false + } +} + +// Create a view desc for the top-level document node, to be exported +// and used by the view class. +export function docViewDesc(doc, outerDeco, innerDeco, dom, view) { + applyOuterDeco(dom, outerDeco, doc) + return new NodeViewDesc(null, doc, outerDeco, innerDeco, dom, dom, dom, view, 0) +} + +class TextViewDesc extends NodeViewDesc { + constructor(parent, node, outerDeco, innerDeco, dom, nodeDOM, view) { + super(parent, node, outerDeco, innerDeco, dom, null, nodeDOM, view) + } + + parseRule() { + return {skip: this.nodeDOM.parentNode || true} + } + + update(node, outerDeco) { + if (this.dirty == NODE_DIRTY || (this.dirty != NOT_DIRTY && !this.inParent()) || + !node.sameMarkup(this.node)) return false + this.updateOuterDeco(outerDeco) + if ((this.dirty != NOT_DIRTY || node.text != this.node.text) && node.text != this.nodeDOM.nodeValue) + this.nodeDOM.nodeValue = node.text + this.node = node + this.dirty = NOT_DIRTY + return true + } + + inParent() { + let parentDOM = this.parent.contentDOM + for (let n = this.nodeDOM; n; n = n.parentNode) if (n == parentDOM) return true + return false + } + + domFromPos(pos) { + return {node: this.nodeDOM, offset: pos} + } + + localPosFromDOM(dom, offset, bias) { + if (dom == this.nodeDOM) return this.posAtStart + Math.min(offset, this.node.text.length) + return super.localPosFromDOM(dom, offset, bias) + } + + ignoreMutation(mutation) { + return mutation.type != "characterData" && mutation.type != "selection" + } + + slice(from, to, view) { + let node = this.node.cut(from, to), dom = document.createTextNode(node.text) + return new TextViewDesc(this.parent, node, this.outerDeco, this.innerDeco, dom, dom, view) + } +} + +// A dummy desc used to tag trailing BR or span nodes created to work +// around contentEditable terribleness. +class BRHackViewDesc extends ViewDesc { + parseRule() { return {ignore: true} } + matchesHack() { return this.dirty == NOT_DIRTY } +} + +// A separate subclass is used for customized node views, so that the +// extra checks only have to be made for nodes that are actually +// customized. +class CustomNodeViewDesc extends NodeViewDesc { + // : (?ViewDesc, Node, [Decoration], DecorationSet, dom.Node, ?dom.Node, NodeView, EditorView) + constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, spec, view, pos) { + super(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos) + this.spec = spec + } + + // A custom `update` method gets to decide whether the update goes + // through. If it does, and there's a `contentDOM` node, our logic + // updates the children. + update(node, outerDeco, innerDeco, view) { + if (this.dirty == NODE_DIRTY) return false + if (this.spec.update) { + let result = this.spec.update(node, outerDeco) + if (result) this.updateInner(node, outerDeco, innerDeco, view) + return result + } else if (!this.contentDOM && !node.isLeaf) { + return false + } else { + return super.update(node, outerDeco, innerDeco, view) + } + } + + selectNode() { + this.spec.selectNode ? this.spec.selectNode() : super.selectNode() + } + + deselectNode() { + this.spec.deselectNode ? this.spec.deselectNode() : super.deselectNode() + } + + setSelection(anchor, head, root, force) { + this.spec.setSelection ? this.spec.setSelection(anchor, head, root) + : super.setSelection(anchor, head, root, force) + } + + destroy() { + if (this.spec.destroy) this.spec.destroy() + super.destroy() + } + + stopEvent(event) { + return this.spec.stopEvent ? this.spec.stopEvent(event) : false + } + + ignoreMutation(mutation) { + return this.spec.ignoreMutation ? this.spec.ignoreMutation(mutation) : super.ignoreMutation(mutation) + } +} + +// : (dom.Node, [ViewDesc]) +// Sync the content of the given DOM node with the nodes associated +// with the given array of view descs, recursing into mark descs +// because this should sync the subtree for a whole node at a time. +function renderDescs(parentDOM, descs) { + let dom = parentDOM.firstChild + for (let i = 0; i < descs.length; i++) { + let desc = descs[i], childDOM = desc.dom + if (childDOM.parentNode == parentDOM) { + while (childDOM != dom) dom = rm(dom) + dom = dom.nextSibling + } else { + parentDOM.insertBefore(childDOM, dom) + } + if (desc instanceof MarkViewDesc) { + let pos = dom ? dom.previousSibling : parentDOM.lastChild + renderDescs(desc.contentDOM, desc.children) + dom = pos ? pos.nextSibling : parentDOM.firstChild + } + } + while (dom) dom = rm(dom) +} + +function OuterDecoLevel(nodeName) { + if (nodeName) this.nodeName = nodeName +} +OuterDecoLevel.prototype = Object.create(null) + +const noDeco = [new OuterDecoLevel] + +function computeOuterDeco(outerDeco, node, needsWrap) { + if (outerDeco.length == 0) return noDeco + + let top = needsWrap ? noDeco[0] : new OuterDecoLevel, result = [top] + + for (let i = 0; i < outerDeco.length; i++) { + let attrs = outerDeco[i].type.attrs, cur = top + if (!attrs) continue + if (attrs.nodeName) + result.push(cur = new OuterDecoLevel(attrs.nodeName)) + + for (let name in attrs) { + let val = attrs[name] + if (val == null) continue + if (needsWrap && result.length == 1) + result.push(cur = top = new OuterDecoLevel(node.isInline ? "span" : "div")) + if (name == "class") cur.class = (cur.class ? cur.class + " " : "") + val + else if (name == "style") cur.style = (cur.style ? cur.style + ";" : "") + val + else if (name != "nodeName") cur[name] = val + } + } + + return result +} + +function patchOuterDeco(outerDOM, nodeDOM, prevComputed, curComputed) { + // Shortcut for trivial case + if (prevComputed == noDeco && curComputed == noDeco) return nodeDOM + + let curDOM = nodeDOM + for (let i = 0; i < curComputed.length; i++) { + let deco = curComputed[i], prev = prevComputed[i] + if (i) { + let parent + if (prev && prev.nodeName == deco.nodeName && curDOM != outerDOM && + (parent = curDOM.parentNode) && parent.tagName.toLowerCase() == deco.nodeName) { + curDOM = parent + } else { + parent = document.createElement(deco.nodeName) + parent.appendChild(curDOM) + prev = noDeco[0] + curDOM = parent + } + } + patchAttributes(curDOM, prev || noDeco[0], deco) + } + return curDOM +} + +function patchAttributes(dom, prev, cur) { + for (let name in prev) + if (name != "class" && name != "style" && name != "nodeName" && !(name in cur)) + dom.removeAttribute(name) + for (let name in cur) + if (name != "class" && name != "style" && name != "nodeName" && cur[name] != prev[name]) + dom.setAttribute(name, cur[name]) + if (prev.class != cur.class) { + let prevList = prev.class ? prev.class.split(" ") : nothing + let curList = cur.class ? cur.class.split(" ") : nothing + for (let i = 0; i < prevList.length; i++) if (curList.indexOf(prevList[i]) == -1) + dom.classList.remove(prevList[i]) + for (let i = 0; i < curList.length; i++) if (prevList.indexOf(curList[i]) == -1) + dom.classList.add(curList[i]) + } + if (prev.style != cur.style) { + if (prev.style) { + let prop = /\s*([\w\-\xa1-\uffff]+)\s*:(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*'|\(.*?\)|[^;])*/g, m + while (m = prop.exec(prev.style)) + dom.style.removeProperty(m[1]) + } + if (cur.style) + dom.style.cssText += cur.style + } +} + +function applyOuterDeco(dom, deco, node) { + return patchOuterDeco(dom, dom, noDeco, computeOuterDeco(deco, node, dom.nodeType != 1)) +} + +// : ([Decoration], [Decoration]) → bool +function sameOuterDeco(a, b) { + if (a.length != b.length) return false + for (let i = 0; i < a.length; i++) if (!a[i].type.eq(b[i].type)) return false + return true +} + +// Remove a DOM node and return its next sibling. +function rm(dom) { + let next = dom.nextSibling + dom.parentNode.removeChild(dom) + return next +} + +// Helper class for incrementally updating a tree of mark descs and +// the widget and node descs inside of them. +class ViewTreeUpdater { + // : (NodeViewDesc) + constructor(top, lockedNode) { + this.top = top + this.lock = lockedNode + // Index into `this.top`'s child array, represents the current + // update position. + this.index = 0 + // When entering a mark, the current top and index are pushed + // onto this. + this.stack = [] + // Tracks whether anything was changed + this.changed = false + + let pre = preMatch(top.node.content, top.children) + this.preMatched = pre.nodes + this.preMatchOffset = pre.offset + } + + getPreMatch(index) { + return index >= this.preMatchOffset ? this.preMatched[index - this.preMatchOffset] : null + } + + // Destroy and remove the children between the given indices in + // `this.top`. + destroyBetween(start, end) { + if (start == end) return + for (let i = start; i < end; i++) this.top.children[i].destroy() + this.top.children.splice(start, end - start) + this.changed = true + } + + // Destroy all remaining children in `this.top`. + destroyRest() { + this.destroyBetween(this.index, this.top.children.length) + } + + // : ([Mark], EditorView) + // Sync the current stack of mark descs with the given array of + // marks, reusing existing mark descs when possible. + syncToMarks(marks, inline, view) { + let keep = 0, depth = this.stack.length >> 1 + let maxKeep = Math.min(depth, marks.length) + while (keep < maxKeep && + (keep == depth - 1 ? this.top : this.stack[(keep + 1) << 1]).matchesMark(marks[keep]) && marks[keep].type.spec.spanning !== false) + keep++ + + while (keep < depth) { + this.destroyRest() + this.top.dirty = NOT_DIRTY + this.index = this.stack.pop() + this.top = this.stack.pop() + depth-- + } + while (depth < marks.length) { + this.stack.push(this.top, this.index + 1) + let found = -1 + for (let i = this.index; i < Math.min(this.index + 3, this.top.children.length); i++) { + if (this.top.children[i].matchesMark(marks[depth])) { found = i; break } + } + if (found > -1) { + if (found > this.index) { + this.changed = true + this.destroyBetween(this.index, found) + } + this.top = this.top.children[this.index] + } else { + let markDesc = MarkViewDesc.create(this.top, marks[depth], inline, view) + this.top.children.splice(this.index, 0, markDesc) + this.top = markDesc + this.changed = true + } + this.index = 0 + depth++ + } + } + + // : (Node, [Decoration], DecorationSet) → bool + // Try to find a node desc matching the given data. Skip over it and + // return true when successful. + findNodeMatch(node, outerDeco, innerDeco, index) { + let found = -1, preMatch = index < 0 ? undefined : this.getPreMatch(index), children = this.top.children + if (preMatch && preMatch.matchesNode(node, outerDeco, innerDeco)) { + found = children.indexOf(preMatch) + } else { + for (let i = this.index, e = Math.min(children.length, i + 5); i < e; i++) { + let child = children[i] + if (child.matchesNode(node, outerDeco, innerDeco) && this.preMatched.indexOf(child) < 0) { + found = i + break + } + } + } + if (found < 0) return false + this.destroyBetween(this.index, found) + this.index++ + return true + } + + // : (Node, [Decoration], DecorationSet, EditorView, Fragment, number) → bool + // Try to update the next node, if any, to the given data. Checks + // pre-matches to avoid overwriting nodes that could still be used. + updateNextNode(node, outerDeco, innerDeco, view, index) { + if (this.index == this.top.children.length) return false + let next = this.top.children[this.index] + if (next instanceof NodeViewDesc) { + let preMatch = this.preMatched.indexOf(next) + if (preMatch > -1 && preMatch + this.preMatchOffset != index) return false + let nextDOM = next.dom + + // Can't update if nextDOM is or contains this.lock, except if + // it's a text node whose content already matches the new text + // and whose decorations match the new ones. + let locked = this.lock && (nextDOM == this.lock || nextDOM.nodeType == 1 && nextDOM.contains(this.lock.parentNode)) && + !(node.isText && next.node && next.node.isText && next.nodeDOM.nodeValue == node.text && + next.dirty != NODE_DIRTY && sameOuterDeco(outerDeco, next.outerDeco)) + if (!locked && next.update(node, outerDeco, innerDeco, view)) { + if (next.dom != nextDOM) this.changed = true + this.index++ + return true + } + } + return false + } + + // : (Node, [Decoration], DecorationSet, EditorView) + // Insert the node as a newly created node desc. + addNode(node, outerDeco, innerDeco, view, pos) { + this.top.children.splice(this.index++, 0, NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos)) + this.changed = true + } + + placeWidget(widget, view, pos) { + if (this.index < this.top.children.length && this.top.children[this.index].matchesWidget(widget)) { + this.index++ + } else { + let desc = new WidgetViewDesc(this.top, widget, view, pos) + this.top.children.splice(this.index++, 0, desc) + this.changed = true + } + } + + // Make sure a textblock looks and behaves correctly in + // contentEditable. + addTextblockHacks() { + let lastChild = this.top.children[this.index - 1] + while (lastChild instanceof MarkViewDesc) lastChild = lastChild.children[lastChild.children.length - 1] + + if (!lastChild || // Empty textblock + !(lastChild instanceof TextViewDesc) || + /\n$/.test(lastChild.node.text)) { + if (this.index < this.top.children.length && this.top.children[this.index].matchesHack()) { + this.index++ + } else { + let dom = document.createElement("br") + this.top.children.splice(this.index++, 0, new BRHackViewDesc(this.top, nothing, dom, null)) + this.changed = true + } + } + } +} + +// : (Fragment, [ViewDesc]) → [ViewDesc] +// Iterate from the end of the fragment and array of descs to find +// directly matching ones, in order to avoid overeagerly reusing +// those for other nodes. Returns an array whose positions correspond +// to node positions in the fragment, and whose elements are either +// descs matched to the child at that index, or empty. +function preMatch(frag, descs) { + let result = [], end = frag.childCount + for (let i = descs.length - 1; end > 0 && i >= 0; i--) { + let desc = descs[i], node = desc.node + if (!node) continue + if (node != frag.child(end - 1)) break + result.push(desc) + --end + } + return {nodes: result.reverse(), offset: end} +} + +function compareSide(a, b) { return a.type.side - b.type.side } + +// : (ViewDesc, DecorationSet, (Decoration, number), (Node, [Decoration], DecorationSet, number)) +// This function abstracts iterating over the nodes and decorations in +// a fragment. Calls `onNode` for each node, with its local and child +// decorations. Splits text nodes when there is a decoration starting +// or ending inside of them. Calls `onWidget` for each widget. +function iterDeco(parent, deco, onWidget, onNode) { + let locals = deco.locals(parent), offset = 0 + // Simple, cheap variant for when there are no local decorations + if (locals.length == 0) { + for (let i = 0; i < parent.childCount; i++) { + let child = parent.child(i) + onNode(child, locals, deco.forChild(offset, child), i) + offset += child.nodeSize + } + return + } + + let decoIndex = 0, active = [], restNode = null + for (let parentIndex = 0;;) { + if (decoIndex < locals.length && locals[decoIndex].to == offset) { + let widget = locals[decoIndex++], widgets + while (decoIndex < locals.length && locals[decoIndex].to == offset) + (widgets || (widgets = [widget])).push(locals[decoIndex++]) + if (widgets) { + widgets.sort(compareSide) + for (let i = 0; i < widgets.length; i++) onWidget(widgets[i], parentIndex) + } else { + onWidget(widget, parentIndex) + } + } + + let child, index + if (restNode) { + index = -1 + child = restNode + restNode = null + } else if (parentIndex < parent.childCount) { + index = parentIndex + child = parent.child(parentIndex++) + } else { + break + } + + for (let i = 0; i < active.length; i++) if (active[i].to <= offset) active.splice(i--, 1) + while (decoIndex < locals.length && locals[decoIndex].from == offset) active.push(locals[decoIndex++]) + + let end = offset + child.nodeSize + if (child.isText) { + let cutAt = end + if (decoIndex < locals.length && locals[decoIndex].from < cutAt) cutAt = locals[decoIndex].from + for (let i = 0; i < active.length; i++) if (active[i].to < cutAt) cutAt = active[i].to + if (cutAt < end) { + restNode = child.cut(cutAt - offset) + child = child.cut(0, cutAt - offset) + end = cutAt + index = -1 + } + } + + onNode(child, active.length ? active.slice() : nothing, deco.forChild(offset, child), index) + offset = end + } +} + +// List markers in Mobile Safari will mysteriously disappear +// sometimes. This works around that. +function iosHacks(dom) { + if (dom.nodeName == "UL" || dom.nodeName == "OL") { + let oldCSS = dom.style.cssText + dom.style.cssText = oldCSS + "; list-style: square !important" + window.getComputedStyle(dom).listStyle + dom.style.cssText = oldCSS + } +} + +function nearbyTextNode(node, offset) { + for (;;) { + if (node.nodeType == 3) return node + if (node.nodeType == 1 && offset > 0) { + if (node.childNodes.length > offset && node.childNodes[offset].nodeType == 3) + return node.childNodes[offset] + node = node.childNodes[offset - 1] + offset = nodeSize(node) + } else if (node.nodeType == 1 && offset < node.childNodes.length) { + node = node.childNodes[offset] + offset = 0 + } else { + return null + } + } +} + +// Find a piece of text in an inline fragment, overlapping from-to +function findTextInFragment(frag, text, from, to) { + for (let str = "", i = 0, childPos = 0; i < frag.childCount; i++) { + let child = frag.child(i), end = childPos + child.nodeSize + if (child.isText) { + str += child.text + if (end >= to) { + let strStart = end - str.length, found = str.lastIndexOf(text) + while (found > -1 && strStart + found > from) found = str.lastIndexOf(text, found - 1) + if (found > -1 && strStart + found + text.length >= to) { + return strStart + found + } else if (end > to) { + break + } + } + } else { + str = "" + } + childPos = end + } + return -1 +} + +// Replace range from-to in an array of view descs with replacement +// (may be null to just delete). This goes very much against the grain +// of the rest of this code, which tends to create nodes with the +// right shape in one go, rather than messing with them after +// creation, but is necessary in the composition hack. +function replaceNodes(nodes, from, to, view, replacement) { + let result = [] + for (let i = 0, off = 0; i < nodes.length; i++) { + let child = nodes[i], start = off, end = off += child.size + if (start >= to || end <= from) { + result.push(child) + } else { + if (start < from) result.push(child.slice(0, from - start, view)) + if (replacement) { + result.push(replacement) + replacement = null + } + if (end > to) result.push(child.slice(to - start, child.size, view)) + } + } + return result +} diff --git a/packages/tiptap-extensions/node_modules/prosemirror-view/style/prosemirror.css b/packages/tiptap-extensions/node_modules/prosemirror-view/style/prosemirror.css new file mode 100644 index 0000000000..6d4fb54ebb --- /dev/null +++ b/packages/tiptap-extensions/node_modules/prosemirror-view/style/prosemirror.css @@ -0,0 +1,43 @@ +.ProseMirror { + position: relative; +} + +.ProseMirror { + word-wrap: break-word; + white-space: pre-wrap; + white-space: break-spaces; + -webkit-font-variant-ligatures: none; + font-variant-ligatures: none; + font-feature-settings: "liga" 0; /* the above doesn't seem to work in Edge */ +} + +.ProseMirror pre { + white-space: pre-wrap; +} + +.ProseMirror li { + position: relative; +} + +.ProseMirror-hideselection *::selection { background: transparent; } +.ProseMirror-hideselection *::-moz-selection { background: transparent; } +.ProseMirror-hideselection { caret-color: transparent; } + +.ProseMirror-selectednode { + outline: 2px solid #8cf; +} + +/* Make sure li selections wrap around markers */ + +li.ProseMirror-selectednode { + outline: none; +} + +li.ProseMirror-selectednode:after { + content: ""; + position: absolute; + left: -32px; + right: -2px; top: -2px; bottom: -2px; + border: 2px solid #8cf; + pointer-events: none; +} diff --git a/packages/tiptap-extensions/src/plugins/Suggestions.js b/packages/tiptap-extensions/src/plugins/Suggestions.js index 0f11f3ee69..e5438e19bf 100644 --- a/packages/tiptap-extensions/src/plugins/Suggestions.js +++ b/packages/tiptap-extensions/src/plugins/Suggestions.js @@ -21,7 +21,7 @@ function triggerCharacter({ const prefix = startOfLine ? '^' : '' const regexp = allowSpaces ? new RegExp(`${prefix}${escapedChar}.*?(?=\\s${escapedChar}|$)`, 'gm') - : new RegExp(`${prefix}(?:^)?${escapedChar}[^\\s${escapedChar}]*`, 'gm') + : new RegExp(`${prefix}(?:^)?${escapedChar}[^\\s|\\0${escapedChar}]*`, 'gm') // Lookup the boundaries of the current node const textFrom = $position.before() @@ -180,7 +180,7 @@ export default function SuggestionsPlugin({ // Apply changes to the plugin state from a view transaction. apply(tr, prev) { const { selection } = tr - const next = { ...prev } + const next = Object.assign({}, prev) // We can only be suggesting if there is no selection if (selection.from === selection.to) { diff --git a/packages/tiptap-utils/dist/utils.common.js b/packages/tiptap-utils/dist/utils.common.js new file mode 100644 index 0000000000..c4260b771d --- /dev/null +++ b/packages/tiptap-utils/dist/utils.common.js @@ -0,0 +1,136 @@ + + /*! + * tiptap-utils v1.8.3 + * (c) 2020 Scrumpy UG (limited liability) + * @license MIT + */ + +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +var prosemirrorUtils = require('prosemirror-utils'); + +function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); +} + +function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } +} + +function _iterableToArray(iter) { + if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); +} + +function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); +} + +function getMarkAttrs(state, type) { + var _state$selection = state.selection, + from = _state$selection.from, + to = _state$selection.to; + var marks = []; + state.doc.nodesBetween(from, to, function (node) { + marks = [].concat(_toConsumableArray(marks), _toConsumableArray(node.marks)); + }); + var mark = marks.find(function (markItem) { + return markItem.type.name === type.name; + }); + + if (mark) { + return mark.attrs; + } + + return {}; +} + +function getMarkRange() { + var $pos = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + + if (!$pos || !type) { + return false; + } + + var start = $pos.parent.childAfter($pos.parentOffset); + + if (!start.node) { + return false; + } + + var link = start.node.marks.find(function (mark) { + return mark.type === type; + }); + + if (!link) { + return false; + } + + var startIndex = $pos.index(); + var startPos = $pos.start() + start.offset; + var endIndex = startIndex + 1; + var endPos = startPos + start.node.nodeSize; + + while (startIndex > 0 && link.isInSet($pos.parent.child(startIndex - 1).marks)) { + startIndex -= 1; + startPos -= $pos.parent.child(startIndex).nodeSize; + } + + while (endIndex < $pos.parent.childCount && link.isInSet($pos.parent.child(endIndex).marks)) { + endPos += $pos.parent.child(endIndex).nodeSize; + endIndex += 1; + } + + return { + from: startPos, + to: endPos + }; +} + +function markIsActive(state, type) { + var _state$selection = state.selection, + from = _state$selection.from, + $from = _state$selection.$from, + to = _state$selection.to, + empty = _state$selection.empty; + + if (empty) { + return !!type.isInSet(state.storedMarks || $from.marks()); + } + + return !!state.doc.rangeHasMark(from, to, type); +} + +function nodeEqualsType(_ref) { + var types = _ref.types, + node = _ref.node; + return Array.isArray(types) && types.includes(node.type) || node.type === types; +} + +function nodeIsActive(state, type) { + var attrs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + + var predicate = function predicate(node) { + return node.type === type; + }; + + var node = prosemirrorUtils.findSelectedNodeOfType(type)(state.selection) || prosemirrorUtils.findParentNode(predicate)(state.selection); + + if (!Object.keys(attrs).length || !node) { + return !!node; + } + + return node.node.hasMarkup(type, attrs); +} + +exports.getMarkAttrs = getMarkAttrs; +exports.getMarkRange = getMarkRange; +exports.markIsActive = markIsActive; +exports.nodeEqualsType = nodeEqualsType; +exports.nodeIsActive = nodeIsActive; diff --git a/packages/tiptap-utils/dist/utils.esm.js b/packages/tiptap-utils/dist/utils.esm.js new file mode 100644 index 0000000000..33582ffef8 --- /dev/null +++ b/packages/tiptap-utils/dist/utils.esm.js @@ -0,0 +1,128 @@ + + /*! + * tiptap-utils v1.8.3 + * (c) 2020 Scrumpy UG (limited liability) + * @license MIT + */ + +import { findSelectedNodeOfType, findParentNode } from 'prosemirror-utils'; + +function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); +} + +function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } +} + +function _iterableToArray(iter) { + if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); +} + +function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); +} + +function getMarkAttrs(state, type) { + var _state$selection = state.selection, + from = _state$selection.from, + to = _state$selection.to; + var marks = []; + state.doc.nodesBetween(from, to, function (node) { + marks = [].concat(_toConsumableArray(marks), _toConsumableArray(node.marks)); + }); + var mark = marks.find(function (markItem) { + return markItem.type.name === type.name; + }); + + if (mark) { + return mark.attrs; + } + + return {}; +} + +function getMarkRange() { + var $pos = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + + if (!$pos || !type) { + return false; + } + + var start = $pos.parent.childAfter($pos.parentOffset); + + if (!start.node) { + return false; + } + + var link = start.node.marks.find(function (mark) { + return mark.type === type; + }); + + if (!link) { + return false; + } + + var startIndex = $pos.index(); + var startPos = $pos.start() + start.offset; + var endIndex = startIndex + 1; + var endPos = startPos + start.node.nodeSize; + + while (startIndex > 0 && link.isInSet($pos.parent.child(startIndex - 1).marks)) { + startIndex -= 1; + startPos -= $pos.parent.child(startIndex).nodeSize; + } + + while (endIndex < $pos.parent.childCount && link.isInSet($pos.parent.child(endIndex).marks)) { + endPos += $pos.parent.child(endIndex).nodeSize; + endIndex += 1; + } + + return { + from: startPos, + to: endPos + }; +} + +function markIsActive(state, type) { + var _state$selection = state.selection, + from = _state$selection.from, + $from = _state$selection.$from, + to = _state$selection.to, + empty = _state$selection.empty; + + if (empty) { + return !!type.isInSet(state.storedMarks || $from.marks()); + } + + return !!state.doc.rangeHasMark(from, to, type); +} + +function nodeEqualsType(_ref) { + var types = _ref.types, + node = _ref.node; + return Array.isArray(types) && types.includes(node.type) || node.type === types; +} + +function nodeIsActive(state, type) { + var attrs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + + var predicate = function predicate(node) { + return node.type === type; + }; + + var node = findSelectedNodeOfType(type)(state.selection) || findParentNode(predicate)(state.selection); + + if (!Object.keys(attrs).length || !node) { + return !!node; + } + + return node.node.hasMarkup(type, attrs); +} + +export { getMarkAttrs, getMarkRange, markIsActive, nodeEqualsType, nodeIsActive }; diff --git a/packages/tiptap-utils/dist/utils.js b/packages/tiptap-utils/dist/utils.js new file mode 100644 index 0000000000..e8dc1a4e01 --- /dev/null +++ b/packages/tiptap-utils/dist/utils.js @@ -0,0 +1,140 @@ + + /*! + * tiptap-utils v1.8.3 + * (c) 2020 Scrumpy UG (limited liability) + * @license MIT + */ + +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('prosemirror-utils')) : + typeof define === 'function' && define.amd ? define(['exports', 'prosemirror-utils'], factory) : + (global = global || self, factory(global.tiptapUtils = {}, global.prosemirrorUtils)); +}(this, (function (exports, prosemirrorUtils) { 'use strict'; + + function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); + } + + function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } + } + + function _iterableToArray(iter) { + if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); + } + + function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); + } + + function getMarkAttrs(state, type) { + var _state$selection = state.selection, + from = _state$selection.from, + to = _state$selection.to; + var marks = []; + state.doc.nodesBetween(from, to, function (node) { + marks = [].concat(_toConsumableArray(marks), _toConsumableArray(node.marks)); + }); + var mark = marks.find(function (markItem) { + return markItem.type.name === type.name; + }); + + if (mark) { + return mark.attrs; + } + + return {}; + } + + function getMarkRange() { + var $pos = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + + if (!$pos || !type) { + return false; + } + + var start = $pos.parent.childAfter($pos.parentOffset); + + if (!start.node) { + return false; + } + + var link = start.node.marks.find(function (mark) { + return mark.type === type; + }); + + if (!link) { + return false; + } + + var startIndex = $pos.index(); + var startPos = $pos.start() + start.offset; + var endIndex = startIndex + 1; + var endPos = startPos + start.node.nodeSize; + + while (startIndex > 0 && link.isInSet($pos.parent.child(startIndex - 1).marks)) { + startIndex -= 1; + startPos -= $pos.parent.child(startIndex).nodeSize; + } + + while (endIndex < $pos.parent.childCount && link.isInSet($pos.parent.child(endIndex).marks)) { + endPos += $pos.parent.child(endIndex).nodeSize; + endIndex += 1; + } + + return { + from: startPos, + to: endPos + }; + } + + function markIsActive(state, type) { + var _state$selection = state.selection, + from = _state$selection.from, + $from = _state$selection.$from, + to = _state$selection.to, + empty = _state$selection.empty; + + if (empty) { + return !!type.isInSet(state.storedMarks || $from.marks()); + } + + return !!state.doc.rangeHasMark(from, to, type); + } + + function nodeEqualsType(_ref) { + var types = _ref.types, + node = _ref.node; + return Array.isArray(types) && types.includes(node.type) || node.type === types; + } + + function nodeIsActive(state, type) { + var attrs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + + var predicate = function predicate(node) { + return node.type === type; + }; + + var node = prosemirrorUtils.findSelectedNodeOfType(type)(state.selection) || prosemirrorUtils.findParentNode(predicate)(state.selection); + + if (!Object.keys(attrs).length || !node) { + return !!node; + } + + return node.node.hasMarkup(type, attrs); + } + + exports.getMarkAttrs = getMarkAttrs; + exports.getMarkRange = getMarkRange; + exports.markIsActive = markIsActive; + exports.nodeEqualsType = nodeEqualsType; + exports.nodeIsActive = nodeIsActive; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}))); diff --git a/packages/tiptap-utils/dist/utils.min.js b/packages/tiptap-utils/dist/utils.min.js new file mode 100644 index 0000000000..b0ee08a605 --- /dev/null +++ b/packages/tiptap-utils/dist/utils.min.js @@ -0,0 +1,14 @@ + + /*! + * tiptap-utils v1.8.3 + * (c) 2020 Scrumpy UG (limited liability) + * @license MIT + */ + + +/*! + * tiptap-utils v1.8.3 + * (c) 2020 Scrumpy UG (limited liability) + * @license MIT + */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("prosemirror-utils")):"function"==typeof define&&define.amd?define(["exports","prosemirror-utils"],t):t((e=e||self).tiptapUtils={},e.prosemirrorUtils)}(this,(function(e,t){"use strict";function r(e){return function(e){if(Array.isArray(e)){for(var t=0,r=new Array(e.length);t0&&void 0!==arguments[0]?arguments[0]:null,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;if(!e||!t)return!1;var r=e.parent.childAfter(e.parentOffset);if(!r.node)return!1;var n=r.node.marks.find((function(e){return e.type===t}));if(!n)return!1;for(var o=e.index(),i=e.start()+r.offset,a=o+1,f=i+r.node.nodeSize;o>0&&n.isInSet(e.parent.child(o-1).marks);)o-=1,i-=e.parent.child(o).nodeSize;for(;a2&&void 0!==arguments[2]?arguments[2]:{},o=t.findSelectedNodeOfType(r)(e.selection)||t.findParentNode((function(e){return e.type===r}))(e.selection);return Object.keys(n).length&&o?o.node.hasMarkup(r,n):!!o},Object.defineProperty(e,"__esModule",{value:!0})})); \ No newline at end of file diff --git a/packages/tiptap/dist/tiptap.common.js b/packages/tiptap/dist/tiptap.common.js new file mode 100644 index 0000000000..6d1994da80 --- /dev/null +++ b/packages/tiptap/dist/tiptap.common.js @@ -0,0 +1,2183 @@ + + /*! + * tiptap v1.26.6 + * (c) 2020 Scrumpy UG (limited liability) + * @license MIT + */ + +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } + +var prosemirrorState = require('prosemirror-state'); +var prosemirrorView = require('prosemirror-view'); +var prosemirrorModel = require('prosemirror-model'); +var prosemirrorDropcursor = require('prosemirror-dropcursor'); +var prosemirrorGapcursor = require('prosemirror-gapcursor'); +var prosemirrorKeymap = require('prosemirror-keymap'); +var prosemirrorCommands = require('prosemirror-commands'); +var prosemirrorInputrules = require('prosemirror-inputrules'); +var tiptapUtils = require('tiptap-utils'); +var Vue = _interopDefault(require('vue')); +var tiptapCommands = require('tiptap-commands'); + +function _typeof(obj) { + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { + _typeof = function (obj) { + return typeof obj; + }; + } else { + _typeof = function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; + }; + } + + return _typeof(obj); +} + +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 _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 _slicedToArray(arr, i) { + return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); +} + +function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); +} + +function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } +} + +function _arrayWithHoles(arr) { + if (Array.isArray(arr)) return arr; +} + +function _iterableToArray(iter) { + if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); +} + +function _iterableToArrayLimit(arr, i) { + if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { + 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 _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); +} + +function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance"); +} + +function camelCase (str) { + return str.replace(/(?:^\w|[A-Z]|\b\w)/g, function (word, index) { + return index === 0 ? word.toLowerCase() : word.toUpperCase(); + }).replace(/\s+/g, ''); +} + +var ComponentView = +/*#__PURE__*/ +function () { + function ComponentView(component, _ref) { + var editor = _ref.editor, + extension = _ref.extension, + parent = _ref.parent, + node = _ref.node, + view = _ref.view, + decorations = _ref.decorations, + getPos = _ref.getPos; + + _classCallCheck(this, ComponentView); + + this.component = component; + this.editor = editor; + this.extension = extension; + this.parent = parent; + this.node = node; + this.view = view; + this.decorations = decorations; + this.isNode = !!this.node.marks; + this.isMark = !this.isNode; + this.getPos = this.isMark ? this.getMarkPos : getPos; + this.captureEvents = true; + this.dom = this.createDOM(); + this.contentDOM = this.vm.$refs.content; + } + + _createClass(ComponentView, [{ + key: "createDOM", + value: function createDOM() { + var _this = this; + + var Component = Vue.extend(this.component); + var props = { + editor: this.editor, + node: this.node, + view: this.view, + getPos: function getPos() { + return _this.getPos(); + }, + decorations: this.decorations, + selected: false, + options: this.extension.options, + updateAttrs: function updateAttrs(attrs) { + return _this.updateAttrs(attrs); + } + }; + + if (typeof this.extension.setSelection === 'function') { + this.setSelection = this.extension.setSelection; + } + + this.vm = new Component({ + parent: this.parent, + propsData: props + }).$mount(); + return this.vm.$el; + } + }, { + key: "update", + value: function update(node, decorations) { + if (node.type !== this.node.type) { + return false; + } + + if (node === this.node && this.decorations === decorations) { + return true; + } + + this.node = node; + this.decorations = decorations; + this.updateComponentProps({ + node: node, + decorations: decorations + }); + return true; + } + }, { + key: "updateComponentProps", + value: function updateComponentProps(props) { + var _this2 = this; + + if (!this.vm._props) { + return; + } // Update props in component + // TODO: Avoid mutating a prop directly. + // Maybe there is a better way to do this? + + + var originalSilent = Vue.config.silent; + Vue.config.silent = true; + Object.entries(props).forEach(function (_ref2) { + var _ref3 = _slicedToArray(_ref2, 2), + key = _ref3[0], + value = _ref3[1]; + + _this2.vm._props[key] = value; + }); // this.vm._props.node = node + // this.vm._props.decorations = decorations + + Vue.config.silent = originalSilent; + } + }, { + key: "updateAttrs", + value: function updateAttrs(attrs) { + if (!this.view.editable) { + return; + } + + var state = this.view.state; + var type = this.node.type; + var pos = this.getPos(); + + var newAttrs = _objectSpread2({}, this.node.attrs, {}, attrs); + + var transaction = this.isMark ? state.tr.removeMark(pos.from, pos.to, type).addMark(pos.from, pos.to, type.create(newAttrs)) : state.tr.setNodeMarkup(pos, null, newAttrs); + this.view.dispatch(transaction); + } // prevent a full re-render of the vue component on update + // we'll handle prop updates in `update()` + + }, { + key: "ignoreMutation", + value: function ignoreMutation(mutation) { + // allow leaf nodes to be selected + if (mutation.type === 'selection') { + return false; + } + + if (!this.contentDOM) { + return true; + } + + return !this.contentDOM.contains(mutation.target); + } // disable (almost) all prosemirror event listener for node views + + }, { + key: "stopEvent", + value: function stopEvent(event) { + var _this3 = this; + + if (typeof this.extension.stopEvent === 'function') { + return this.extension.stopEvent(event); + } + + var draggable = !!this.extension.schema.draggable; // support a custom drag handle + + if (draggable && event.type === 'mousedown') { + var dragHandle = event.target.closest && event.target.closest('[data-drag-handle]'); + var isValidDragHandle = dragHandle && (this.dom === dragHandle || this.dom.contains(dragHandle)); + + if (isValidDragHandle) { + this.captureEvents = false; + document.addEventListener('dragend', function () { + _this3.captureEvents = true; + }, { + once: true + }); + } + } + + var isCopy = event.type === 'copy'; + var isPaste = event.type === 'paste'; + var isCut = event.type === 'cut'; + var isDrag = event.type.startsWith('drag') || event.type === 'drop'; + + if (draggable && isDrag || isCopy || isPaste || isCut) { + return false; + } + + return this.captureEvents; + } + }, { + key: "selectNode", + value: function selectNode() { + this.updateComponentProps({ + selected: true + }); + } + }, { + key: "deselectNode", + value: function deselectNode() { + this.updateComponentProps({ + selected: false + }); + } + }, { + key: "getMarkPos", + value: function getMarkPos() { + var pos = this.view.posAtDOM(this.dom); + var resolvedPos = this.view.state.doc.resolve(pos); + var range = tiptapUtils.getMarkRange(resolvedPos, this.node.type); + return range; + } + }, { + key: "destroy", + value: function destroy() { + this.vm.$destroy(); + } + }]); + + return ComponentView; +}(); + +var Emitter = +/*#__PURE__*/ +function () { + function Emitter() { + _classCallCheck(this, Emitter); + } + + _createClass(Emitter, [{ + key: "on", + // Add an event listener for given event + value: function on(event, fn) { + this._callbacks = this._callbacks || {}; // Create namespace for this event + + if (!this._callbacks[event]) { + this._callbacks[event] = []; + } + + this._callbacks[event].push(fn); + + return this; + } + }, { + key: "emit", + value: function emit(event) { + var _this = this; + + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + this._callbacks = this._callbacks || {}; + var callbacks = this._callbacks[event]; + + if (callbacks) { + callbacks.forEach(function (callback) { + return callback.apply(_this, args); + }); + } + + return this; + } // Remove event listener for given event. + // If fn is not provided, all event listeners for that event will be removed. + // If neither is provided, all event listeners will be removed. + + }, { + key: "off", + value: function off(event, fn) { + if (!arguments.length) { + this._callbacks = {}; + } else { + // event listeners for the given event + var callbacks = this._callbacks ? this._callbacks[event] : null; + + if (callbacks) { + if (fn) { + this._callbacks[event] = callbacks.filter(function (cb) { + return cb !== fn; + }); // remove specific handler + } else { + delete this._callbacks[event]; // remove all handlers + } + } + } + + return this; + } + }]); + + return Emitter; +}(); + +var Extension = +/*#__PURE__*/ +function () { + function Extension() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, Extension); + + this.options = _objectSpread2({}, this.defaultOptions, {}, options); + } + + _createClass(Extension, [{ + key: "init", + value: function init() { + return null; + } + }, { + key: "bindEditor", + value: function bindEditor() { + var editor = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + this.editor = editor; + } + }, { + key: "inputRules", + value: function inputRules() { + return []; + } + }, { + key: "pasteRules", + value: function pasteRules() { + return []; + } + }, { + key: "keys", + value: function keys() { + return {}; + } + }, { + key: "name", + get: function get() { + return null; + } + }, { + key: "type", + get: function get() { + return 'extension'; + } + }, { + key: "update", + get: function get() { + return function () {}; + } + }, { + key: "defaultOptions", + get: function get() { + return {}; + } + }, { + key: "plugins", + get: function get() { + return []; + } + }]); + + return Extension; +}(); + +var ExtensionManager = +/*#__PURE__*/ +function () { + function ExtensionManager() { + var extensions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + var editor = arguments.length > 1 ? arguments[1] : undefined; + + _classCallCheck(this, ExtensionManager); + + extensions.forEach(function (extension) { + extension.bindEditor(editor); + extension.init(); + }); + this.extensions = extensions; + } + + _createClass(ExtensionManager, [{ + key: "keymaps", + value: function keymaps(_ref) { + var schema = _ref.schema; + var extensionKeymaps = this.extensions.filter(function (extension) { + return ['extension'].includes(extension.type); + }).filter(function (extension) { + return extension.keys; + }).map(function (extension) { + return extension.keys({ + schema: schema + }); + }); + var nodeMarkKeymaps = this.extensions.filter(function (extension) { + return ['node', 'mark'].includes(extension.type); + }).filter(function (extension) { + return extension.keys; + }).map(function (extension) { + return extension.keys({ + type: schema["".concat(extension.type, "s")][extension.name], + schema: schema + }); + }); + return [].concat(_toConsumableArray(extensionKeymaps), _toConsumableArray(nodeMarkKeymaps)).map(function (keys) { + return prosemirrorKeymap.keymap(keys); + }); + } + }, { + key: "inputRules", + value: function inputRules(_ref2) { + var schema = _ref2.schema, + excludedExtensions = _ref2.excludedExtensions; + if (!(excludedExtensions instanceof Array) && excludedExtensions) return []; + var allowedExtensions = excludedExtensions instanceof Array ? this.extensions.filter(function (extension) { + return !excludedExtensions.includes(extension.name); + }) : this.extensions; + var extensionInputRules = allowedExtensions.filter(function (extension) { + return ['extension'].includes(extension.type); + }).filter(function (extension) { + return extension.inputRules; + }).map(function (extension) { + return extension.inputRules({ + schema: schema + }); + }); + var nodeMarkInputRules = allowedExtensions.filter(function (extension) { + return ['node', 'mark'].includes(extension.type); + }).filter(function (extension) { + return extension.inputRules; + }).map(function (extension) { + return extension.inputRules({ + type: schema["".concat(extension.type, "s")][extension.name], + schema: schema + }); + }); + return [].concat(_toConsumableArray(extensionInputRules), _toConsumableArray(nodeMarkInputRules)).reduce(function (allInputRules, inputRules) { + return [].concat(_toConsumableArray(allInputRules), _toConsumableArray(inputRules)); + }, []); + } + }, { + key: "pasteRules", + value: function pasteRules(_ref3) { + var schema = _ref3.schema, + excludedExtensions = _ref3.excludedExtensions; + if (!(excludedExtensions instanceof Array) && excludedExtensions) return []; + var allowedExtensions = excludedExtensions instanceof Array ? this.extensions.filter(function (extension) { + return !excludedExtensions.includes(extension.name); + }) : this.extensions; + var extensionPasteRules = allowedExtensions.filter(function (extension) { + return ['extension'].includes(extension.type); + }).filter(function (extension) { + return extension.pasteRules; + }).map(function (extension) { + return extension.pasteRules({ + schema: schema + }); + }); + var nodeMarkPasteRules = allowedExtensions.filter(function (extension) { + return ['node', 'mark'].includes(extension.type); + }).filter(function (extension) { + return extension.pasteRules; + }).map(function (extension) { + return extension.pasteRules({ + type: schema["".concat(extension.type, "s")][extension.name], + schema: schema + }); + }); + return [].concat(_toConsumableArray(extensionPasteRules), _toConsumableArray(nodeMarkPasteRules)).reduce(function (allPasteRules, pasteRules) { + return [].concat(_toConsumableArray(allPasteRules), _toConsumableArray(pasteRules)); + }, []); + } + }, { + key: "commands", + value: function commands(_ref4) { + var schema = _ref4.schema, + view = _ref4.view; + return this.extensions.filter(function (extension) { + return extension.commands; + }).reduce(function (allCommands, extension) { + var name = extension.name, + type = extension.type; + var commands = {}; + var value = extension.commands(_objectSpread2({ + schema: schema + }, ['node', 'mark'].includes(type) ? { + type: schema["".concat(type, "s")][name] + } : {})); + + var apply = function apply(cb, attrs) { + if (!view.editable) { + return false; + } + + view.focus(); + return cb(attrs)(view.state, view.dispatch, view); + }; + + var handle = function handle(_name, _value) { + if (Array.isArray(_value)) { + commands[_name] = function (attrs) { + return _value.forEach(function (callback) { + return apply(callback, attrs); + }); + }; + } else if (typeof _value === 'function') { + commands[_name] = function (attrs) { + return apply(_value, attrs); + }; + } + }; + + if (_typeof(value) === 'object') { + Object.entries(value).forEach(function (_ref5) { + var _ref6 = _slicedToArray(_ref5, 2), + commandName = _ref6[0], + commandValue = _ref6[1]; + + handle(commandName, commandValue); + }); + } else { + handle(name, value); + } + + return _objectSpread2({}, allCommands, {}, commands); + }, {}); + } + }, { + key: "nodes", + get: function get() { + return this.extensions.filter(function (extension) { + return extension.type === 'node'; + }).reduce(function (nodes, _ref7) { + var name = _ref7.name, + schema = _ref7.schema; + return _objectSpread2({}, nodes, _defineProperty({}, name, schema)); + }, {}); + } + }, { + key: "options", + get: function get() { + var view = this.view; + return this.extensions.reduce(function (nodes, extension) { + return _objectSpread2({}, nodes, _defineProperty({}, extension.name, new Proxy(extension.options, { + set: function set(obj, prop, value) { + var changed = obj[prop] !== value; + Object.assign(obj, _defineProperty({}, prop, value)); + + if (changed) { + extension.update(view); + } + + return true; + } + }))); + }, {}); + } + }, { + key: "marks", + get: function get() { + return this.extensions.filter(function (extension) { + return extension.type === 'mark'; + }).reduce(function (marks, _ref8) { + var name = _ref8.name, + schema = _ref8.schema; + return _objectSpread2({}, marks, _defineProperty({}, name, schema)); + }, {}); + } + }, { + key: "plugins", + get: function get() { + return this.extensions.filter(function (extension) { + return extension.plugins; + }).reduce(function (allPlugins, _ref9) { + var plugins = _ref9.plugins; + return [].concat(_toConsumableArray(allPlugins), _toConsumableArray(plugins)); + }, []); + } + }]); + + return ExtensionManager; +}(); + +function injectCSS (css) { + if (process.env.NODE_ENV !== 'test') { + var style = document.createElement('style'); + style.type = 'text/css'; + style.textContent = css; + var _document = document, + head = _document.head; + var firstChild = head.firstChild; + + if (firstChild) { + head.insertBefore(style, firstChild); + } else { + head.appendChild(style); + } + } +} + +var Mark = +/*#__PURE__*/ +function (_Extension) { + _inherits(Mark, _Extension); + + function Mark() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, Mark); + + return _possibleConstructorReturn(this, _getPrototypeOf(Mark).call(this, options)); + } + + _createClass(Mark, [{ + key: "command", + value: function command() { + return function () {}; + } + }, { + key: "type", + get: function get() { + return 'mark'; + } + }, { + key: "view", + get: function get() { + return null; + } + }, { + key: "schema", + get: function get() { + return null; + } + }]); + + return Mark; +}(Extension); + +function minMax() { + var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + var min = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + var max = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + return Math.min(Math.max(parseInt(value, 10), min), max); +} + +var Node = +/*#__PURE__*/ +function (_Extension) { + _inherits(Node, _Extension); + + function Node() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, Node); + + return _possibleConstructorReturn(this, _getPrototypeOf(Node).call(this, options)); + } + + _createClass(Node, [{ + key: "command", + value: function command() { + return function () {}; + } + }, { + key: "type", + get: function get() { + return 'node'; + } + }, { + key: "view", + get: function get() { + return null; + } + }, { + key: "schema", + get: function get() { + return null; + } + }]); + + return Node; +}(Extension); + +var Doc = +/*#__PURE__*/ +function (_Node) { + _inherits(Doc, _Node); + + function Doc() { + _classCallCheck(this, Doc); + + return _possibleConstructorReturn(this, _getPrototypeOf(Doc).apply(this, arguments)); + } + + _createClass(Doc, [{ + key: "name", + get: function get() { + return 'doc'; + } + }, { + key: "schema", + get: function get() { + return { + content: 'block+' + }; + } + }]); + + return Doc; +}(Node); + +var Paragraph = +/*#__PURE__*/ +function (_Node) { + _inherits(Paragraph, _Node); + + function Paragraph() { + _classCallCheck(this, Paragraph); + + return _possibleConstructorReturn(this, _getPrototypeOf(Paragraph).apply(this, arguments)); + } + + _createClass(Paragraph, [{ + key: "commands", + value: function commands(_ref) { + var type = _ref.type; + return function () { + return tiptapCommands.setBlockType(type); + }; + } + }, { + key: "name", + get: function get() { + return 'paragraph'; + } + }, { + key: "schema", + get: function get() { + return { + content: 'inline*', + group: 'block', + draggable: false, + parseDOM: [{ + tag: 'p' + }], + toDOM: function toDOM() { + return ['p', 0]; + } + }; + } + }]); + + return Paragraph; +}(Node); + +var Text = +/*#__PURE__*/ +function (_Node) { + _inherits(Text, _Node); + + function Text() { + _classCallCheck(this, Text); + + return _possibleConstructorReturn(this, _getPrototypeOf(Text).apply(this, arguments)); + } + + _createClass(Text, [{ + key: "name", + get: function get() { + return 'text'; + } + }, { + key: "schema", + get: function get() { + return { + group: 'inline' + }; + } + }]); + + return Text; +}(Node); + +var css = ".ProseMirror {\n position: relative;\n}\n\n.ProseMirror {\n word-wrap: break-word;\n white-space: pre-wrap;\n -webkit-font-variant-ligatures: none;\n font-variant-ligatures: none;\n}\n\n.ProseMirror pre {\n white-space: pre-wrap;\n}\n\n.ProseMirror-gapcursor {\n display: none;\n pointer-events: none;\n position: absolute;\n}\n\n.ProseMirror-gapcursor:after {\n content: \"\";\n display: block;\n position: absolute;\n top: -2px;\n width: 20px;\n border-top: 1px solid black;\n animation: ProseMirror-cursor-blink 1.1s steps(2, start) infinite;\n}\n\n@keyframes ProseMirror-cursor-blink {\n to {\n visibility: hidden;\n }\n}\n\n.ProseMirror-hideselection *::selection {\n background: transparent;\n}\n\n.ProseMirror-hideselection *::-moz-selection {\n background: transparent;\n}\n\n.ProseMirror-hideselection * {\n caret-color: transparent;\n}\n\n.ProseMirror-focused .ProseMirror-gapcursor {\n display: block;\n}\n"; + +var Editor = +/*#__PURE__*/ +function (_Emitter) { + _inherits(Editor, _Emitter); + + function Editor() { + var _this; + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, Editor); + + _this = _possibleConstructorReturn(this, _getPrototypeOf(Editor).call(this)); + _this.defaultOptions = { + editorProps: {}, + editable: true, + autoFocus: null, + extensions: [], + content: '', + topNode: 'doc', + emptyDocument: { + type: 'doc', + content: [{ + type: 'paragraph' + }] + }, + useBuiltInExtensions: true, + disableInputRules: false, + disablePasteRules: false, + dropCursor: {}, + parseOptions: {}, + injectCSS: true, + onInit: function onInit() {}, + onTransaction: function onTransaction() {}, + onUpdate: function onUpdate() {}, + onFocus: function onFocus() {}, + onBlur: function onBlur() {}, + onPaste: function onPaste() {}, + onDrop: function onDrop() {} + }; + _this.events = ['init', 'transaction', 'update', 'focus', 'blur', 'paste', 'drop']; + + _this.init(options); + + return _this; + } + + _createClass(Editor, [{ + key: "init", + value: function init() { + var _this2 = this; + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + this.setOptions(_objectSpread2({}, this.defaultOptions, {}, options)); + this.focused = false; + this.selection = { + from: 0, + to: 0 + }; + this.element = document.createElement('div'); + this.extensions = this.createExtensions(); + this.nodes = this.createNodes(); + this.marks = this.createMarks(); + this.schema = this.createSchema(); + this.plugins = this.createPlugins(); + this.keymaps = this.createKeymaps(); + this.inputRules = this.createInputRules(); + this.pasteRules = this.createPasteRules(); + this.view = this.createView(); + this.commands = this.createCommands(); + this.setActiveNodesAndMarks(); + + if (this.options.injectCSS) { + injectCSS(css); + } + + if (this.options.autoFocus !== null) { + this.focus(this.options.autoFocus); + } + + this.events.forEach(function (name) { + _this2.on(name, _this2.options[camelCase("on ".concat(name))] || function () {}); + }); + this.emit('init', { + view: this.view, + state: this.state + }); // give extension manager access to our view + + this.extensions.view = this.view; + } + }, { + key: "setOptions", + value: function setOptions(options) { + this.options = _objectSpread2({}, this.options, {}, options); + + if (this.view && this.state) { + this.view.updateState(this.state); + } + } + }, { + key: "createExtensions", + value: function createExtensions() { + return new ExtensionManager([].concat(_toConsumableArray(this.builtInExtensions), _toConsumableArray(this.options.extensions)), this); + } + }, { + key: "createPlugins", + value: function createPlugins() { + return this.extensions.plugins; + } + }, { + key: "createKeymaps", + value: function createKeymaps() { + return this.extensions.keymaps({ + schema: this.schema + }); + } + }, { + key: "createInputRules", + value: function createInputRules() { + return this.extensions.inputRules({ + schema: this.schema, + excludedExtensions: this.options.disableInputRules + }); + } + }, { + key: "createPasteRules", + value: function createPasteRules() { + return this.extensions.pasteRules({ + schema: this.schema, + excludedExtensions: this.options.disablePasteRules + }); + } + }, { + key: "createCommands", + value: function createCommands() { + return this.extensions.commands({ + schema: this.schema, + view: this.view + }); + } + }, { + key: "createNodes", + value: function createNodes() { + return this.extensions.nodes; + } + }, { + key: "createMarks", + value: function createMarks() { + return this.extensions.marks; + } + }, { + key: "createSchema", + value: function createSchema() { + return new prosemirrorModel.Schema({ + topNode: this.options.topNode, + nodes: this.nodes, + marks: this.marks + }); + } + }, { + key: "createState", + value: function createState() { + var _this3 = this; + + return prosemirrorState.EditorState.create({ + schema: this.schema, + doc: this.createDocument(this.options.content), + plugins: [].concat(_toConsumableArray(this.plugins), [prosemirrorInputrules.inputRules({ + rules: this.inputRules + })], _toConsumableArray(this.pasteRules), _toConsumableArray(this.keymaps), [prosemirrorKeymap.keymap({ + Backspace: prosemirrorInputrules.undoInputRule + }), prosemirrorKeymap.keymap(prosemirrorCommands.baseKeymap), prosemirrorDropcursor.dropCursor(this.options.dropCursor), prosemirrorGapcursor.gapCursor(), new prosemirrorState.Plugin({ + key: new prosemirrorState.PluginKey('editable'), + props: { + editable: function editable() { + return _this3.options.editable; + } + } + }), new prosemirrorState.Plugin({ + props: { + attributes: { + tabindex: 0 + }, + handleDOMEvents: { + focus: function focus(view, event) { + _this3.focused = true; + + _this3.emit('focus', { + event: event, + state: view.state, + view: view + }); + + var transaction = _this3.state.tr.setMeta('focused', true); + + _this3.view.dispatch(transaction); + }, + blur: function blur(view, event) { + _this3.focused = false; + + _this3.emit('blur', { + event: event, + state: view.state, + view: view + }); + + var transaction = _this3.state.tr.setMeta('focused', false); + + _this3.view.dispatch(transaction); + } + } + } + }), new prosemirrorState.Plugin({ + props: this.options.editorProps + })]) + }); + } + }, { + key: "createDocument", + value: function createDocument(content) { + var parseOptions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.options.parseOptions; + + if (content === null) { + return this.schema.nodeFromJSON(this.options.emptyDocument); + } + + if (_typeof(content) === 'object') { + try { + return this.schema.nodeFromJSON(content); + } catch (error) { + console.warn('[tiptap warn]: Invalid content.', 'Passed value:', content, 'Error:', error); + return this.schema.nodeFromJSON(this.options.emptyDocument); + } + } + + if (typeof content === 'string') { + var element = document.createElement('div'); + element.innerHTML = content.trim(); + return prosemirrorModel.DOMParser.fromSchema(this.schema).parse(element, parseOptions); + } + + return false; + } + }, { + key: "createView", + value: function createView() { + var _this4 = this; + + return new prosemirrorView.EditorView(this.element, { + state: this.createState(), + handlePaste: function handlePaste() { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + _this4.emit.apply(_this4, ['paste'].concat(args)); + }, + handleDrop: function handleDrop() { + for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } + + _this4.emit.apply(_this4, ['drop'].concat(args)); + }, + dispatchTransaction: this.dispatchTransaction.bind(this) + }); + } + }, { + key: "setParentComponent", + value: function setParentComponent() { + var component = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + + if (!component) { + return; + } + + this.view.setProps({ + nodeViews: this.initNodeViews({ + parent: component, + extensions: [].concat(_toConsumableArray(this.builtInExtensions), _toConsumableArray(this.options.extensions)) + }) + }); + } + }, { + key: "initNodeViews", + value: function initNodeViews(_ref) { + var _this5 = this; + + var parent = _ref.parent, + extensions = _ref.extensions; + return extensions.filter(function (extension) { + return ['node', 'mark'].includes(extension.type); + }).filter(function (extension) { + return extension.view; + }).reduce(function (nodeViews, extension) { + var nodeView = function nodeView(node, view, getPos, decorations) { + var component = extension.view; + return new ComponentView(component, { + editor: _this5, + extension: extension, + parent: parent, + node: node, + view: view, + getPos: getPos, + decorations: decorations + }); + }; + + return _objectSpread2({}, nodeViews, _defineProperty({}, extension.name, nodeView)); + }, {}); + } + }, { + key: "dispatchTransaction", + value: function dispatchTransaction(transaction) { + var newState = this.state.apply(transaction); + this.view.updateState(newState); + this.selection = { + from: this.state.selection.from, + to: this.state.selection.to + }; + this.setActiveNodesAndMarks(); + this.emit('transaction', { + getHTML: this.getHTML.bind(this), + getJSON: this.getJSON.bind(this), + state: this.state, + transaction: transaction + }); + + if (!transaction.docChanged || transaction.getMeta('preventUpdate')) { + return; + } + + this.emitUpdate(transaction); + } + }, { + key: "emitUpdate", + value: function emitUpdate(transaction) { + this.emit('update', { + getHTML: this.getHTML.bind(this), + getJSON: this.getJSON.bind(this), + state: this.state, + transaction: transaction + }); + } + }, { + key: "resolveSelection", + value: function resolveSelection() { + var position = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + + if (this.selection && position === null) { + return this.selection; + } + + if (position === 'start' || position === true) { + return { + from: 0, + to: 0 + }; + } + + if (position === 'end') { + var doc = this.state.doc; + return { + from: doc.content.size, + to: doc.content.size + }; + } + + return { + from: position, + to: position + }; + } + }, { + key: "focus", + value: function focus() { + var _this6 = this; + + var position = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + + if (this.view.focused && position === null || position === false) { + return; + } + + var _this$resolveSelectio = this.resolveSelection(position), + from = _this$resolveSelectio.from, + to = _this$resolveSelectio.to; + + this.setSelection(from, to); + setTimeout(function () { + return _this6.view.focus(); + }, 10); + } + }, { + key: "setSelection", + value: function setSelection() { + var from = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + var to = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + var _this$state = this.state, + doc = _this$state.doc, + tr = _this$state.tr; + var resolvedFrom = minMax(from, 0, doc.content.size); + var resolvedEnd = minMax(to, 0, doc.content.size); + var selection = prosemirrorState.TextSelection.create(doc, resolvedFrom, resolvedEnd); + var transaction = tr.setSelection(selection); + this.view.dispatch(transaction); + } + }, { + key: "blur", + value: function blur() { + this.view.dom.blur(); + } + }, { + key: "getSchemaJSON", + value: function getSchemaJSON() { + return JSON.parse(JSON.stringify({ + nodes: this.extensions.nodes, + marks: this.extensions.marks + })); + } + }, { + key: "getHTML", + value: function getHTML() { + var div = document.createElement('div'); + var fragment = prosemirrorModel.DOMSerializer.fromSchema(this.schema).serializeFragment(this.state.doc.content); + div.appendChild(fragment); + return div.innerHTML; + } + }, { + key: "getJSON", + value: function getJSON() { + return this.state.doc.toJSON(); + } + }, { + key: "setContent", + value: function setContent() { + var content = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var emitUpdate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + var parseOptions = arguments.length > 2 ? arguments[2] : undefined; + var _this$state2 = this.state, + doc = _this$state2.doc, + tr = _this$state2.tr; + var document = this.createDocument(content, parseOptions); + var selection = prosemirrorState.TextSelection.create(doc, 0, doc.content.size); + var transaction = tr.setSelection(selection).replaceSelectionWith(document, false).setMeta('preventUpdate', !emitUpdate); + this.view.dispatch(transaction); + } + }, { + key: "clearContent", + value: function clearContent() { + var emitUpdate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + this.setContent(this.options.emptyDocument, emitUpdate); + } + }, { + key: "setActiveNodesAndMarks", + value: function setActiveNodesAndMarks() { + var _this7 = this; + + this.activeMarks = Object.entries(this.schema.marks).reduce(function (marks, _ref2) { + var _ref3 = _slicedToArray(_ref2, 2), + name = _ref3[0], + mark = _ref3[1]; + + return _objectSpread2({}, marks, _defineProperty({}, name, function () { + var attrs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + return tiptapUtils.markIsActive(_this7.state, mark, attrs); + })); + }, {}); + this.activeMarkAttrs = Object.entries(this.schema.marks).reduce(function (marks, _ref4) { + var _ref5 = _slicedToArray(_ref4, 2), + name = _ref5[0], + mark = _ref5[1]; + + return _objectSpread2({}, marks, _defineProperty({}, name, tiptapUtils.getMarkAttrs(_this7.state, mark))); + }, {}); + this.activeNodes = Object.entries(this.schema.nodes).reduce(function (nodes, _ref6) { + var _ref7 = _slicedToArray(_ref6, 2), + name = _ref7[0], + node = _ref7[1]; + + return _objectSpread2({}, nodes, _defineProperty({}, name, function () { + var attrs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + return tiptapUtils.nodeIsActive(_this7.state, node, attrs); + })); + }, {}); + } + }, { + key: "getMarkAttrs", + value: function getMarkAttrs() { + var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + return this.activeMarkAttrs[type]; + } + }, { + key: "registerPlugin", + value: function registerPlugin() { + var plugin = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + + if (!plugin) { + return; + } + + var newState = this.state.reconfigure({ + plugins: this.state.plugins.concat([plugin]) + }); + this.view.updateState(newState); + } + }, { + key: "unregisterPlugin", + value: function unregisterPlugin() { + var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + + if (!name || !this.view.docView) { + return; + } + + var newState = this.state.reconfigure({ + plugins: this.state.plugins.filter(function (plugin) { + return !plugin.key.startsWith("".concat(name, "$")); + }) + }); + this.view.updateState(newState); + } + }, { + key: "destroy", + value: function destroy() { + if (!this.view) { + return; + } + + this.view.destroy(); + } + }, { + key: "builtInExtensions", + get: function get() { + if (!this.options.useBuiltInExtensions) { + return []; + } + + return [new Doc(), new Text(), new Paragraph()]; + } + }, { + key: "state", + get: function get() { + return this.view ? this.view.state : null; + } + }, { + key: "isActive", + get: function get() { + return Object.entries(_objectSpread2({}, this.activeMarks, {}, this.activeNodes)).reduce(function (types, _ref8) { + var _ref9 = _slicedToArray(_ref8, 2), + name = _ref9[0], + value = _ref9[1]; + + return _objectSpread2({}, types, _defineProperty({}, name, function () { + var attrs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + return value(attrs); + })); + }, {}); + } + }]); + + return Editor; +}(Emitter); + +var EditorContent = { + props: { + editor: { + default: null, + type: Object + } + }, + watch: { + editor: { + immediate: true, + handler: function handler(editor) { + var _this = this; + + if (editor && editor.element) { + this.$nextTick(function () { + _this.$el.appendChild(editor.element.firstChild); + + editor.setParentComponent(_this); + }); + } + } + } + }, + render: function render(createElement) { + return createElement('div'); + }, + beforeDestroy: function beforeDestroy() { + this.editor.element = this.$el; + } +}; + +var Menu = +/*#__PURE__*/ +function () { + function Menu(_ref) { + var _this = this; + + var options = _ref.options; + + _classCallCheck(this, Menu); + + this.options = options; + this.preventHide = false; // the mousedown event is fired before blur so we can prevent it + + this.mousedownHandler = this.handleClick.bind(this); + this.options.element.addEventListener('mousedown', this.mousedownHandler); + this.options.editor.on('blur', function () { + if (_this.preventHide) { + _this.preventHide = false; + return; + } + + _this.options.editor.emit('menubar:focusUpdate', false); + }); + } + + _createClass(Menu, [{ + key: "handleClick", + value: function handleClick() { + this.preventHide = true; + } + }, { + key: "destroy", + value: function destroy() { + this.options.element.removeEventListener('mousedown', this.mousedownHandler); + } + }]); + + return Menu; +}(); + +function MenuBar (options) { + return new prosemirrorState.Plugin({ + key: new prosemirrorState.PluginKey('menu_bar'), + view: function view(editorView) { + return new Menu({ + editorView: editorView, + options: options + }); + } + }); +} + +var EditorMenuBar = { + props: { + editor: { + default: null, + type: Object + } + }, + data: function data() { + return { + focused: false + }; + }, + watch: { + editor: { + immediate: true, + handler: function handler(editor) { + var _this = this; + + if (editor) { + this.$nextTick(function () { + editor.registerPlugin(MenuBar({ + editor: editor, + element: _this.$el + })); + _this.focused = editor.focused; + editor.on('focus', function () { + _this.focused = true; + }); + editor.on('menubar:focusUpdate', function (focused) { + _this.focused = focused; + }); + }); + } + } + } + }, + render: function render() { + if (!this.editor) { + return null; + } + + return this.$scopedSlots.default({ + focused: this.focused, + focus: this.editor.focus, + commands: this.editor.commands, + isActive: this.editor.isActive, + getMarkAttrs: this.editor.getMarkAttrs.bind(this.editor) + }); + } +}; + +function textRange(node, from, to) { + var range = document.createRange(); + range.setEnd(node, to == null ? node.nodeValue.length : to); + range.setStart(node, from || 0); + return range; +} + +function singleRect(object, bias) { + var rects = object.getClientRects(); + return !rects.length ? object.getBoundingClientRect() : rects[bias < 0 ? 0 : rects.length - 1]; +} + +function coordsAtPos(view, pos) { + var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + + var _view$docView$domFrom = view.docView.domFromPos(pos), + node = _view$docView$domFrom.node, + offset = _view$docView$domFrom.offset; + + var side; + var rect; + + if (node.nodeType === 3) { + if (end && offset < node.nodeValue.length) { + rect = singleRect(textRange(node, offset - 1, offset), -1); + side = 'right'; + } else if (offset < node.nodeValue.length) { + rect = singleRect(textRange(node, offset, offset + 1), -1); + side = 'left'; + } + } else if (node.firstChild) { + if (offset < node.childNodes.length) { + var child = node.childNodes[offset]; + rect = singleRect(child.nodeType === 3 ? textRange(child) : child, -1); + side = 'left'; + } + + if ((!rect || rect.top === rect.bottom) && offset) { + var _child = node.childNodes[offset - 1]; + rect = singleRect(_child.nodeType === 3 ? textRange(_child) : _child, 1); + side = 'right'; + } + } else { + rect = node.getBoundingClientRect(); + side = 'left'; + } + + var x = rect[side]; + return { + top: rect.top, + bottom: rect.bottom, + left: x, + right: x + }; +} + +var Menu$1 = +/*#__PURE__*/ +function () { + function Menu(_ref) { + var _this = this; + + var options = _ref.options, + editorView = _ref.editorView; + + _classCallCheck(this, Menu); + + this.options = _objectSpread2({}, { + element: null, + keepInBounds: true, + onUpdate: function onUpdate() { + return false; + } + }, {}, options); + this.editorView = editorView; + this.isActive = false; + this.left = 0; + this.bottom = 0; + this.top = 0; + this.preventHide = false; // the mousedown event is fired before blur so we can prevent it + + this.mousedownHandler = this.handleClick.bind(this); + this.options.element.addEventListener('mousedown', this.mousedownHandler); + this.options.editor.on('focus', function (_ref2) { + var view = _ref2.view; + + _this.update(view); + }); + this.options.editor.on('blur', function (_ref3) { + var event = _ref3.event; + + if (_this.preventHide) { + _this.preventHide = false; + return; + } + + _this.hide(event); + }); + } + + _createClass(Menu, [{ + key: "handleClick", + value: function handleClick() { + this.preventHide = true; + } + }, { + key: "update", + value: function update(view, lastState) { + var state = view.state; + + if (view.composing) { + return; + } // Don't do anything if the document/selection didn't change + + + if (lastState && lastState.doc.eq(state.doc) && lastState.selection.eq(state.selection)) { + return; + } // Hide the tooltip if the selection is empty + + + if (state.selection.empty) { + this.hide(); + return; + } // Otherwise, reposition it and update its content + + + var _state$selection = state.selection, + from = _state$selection.from, + to = _state$selection.to; // These are in screen coordinates + // We can't use EditorView.cordsAtPos here because it can't handle linebreaks correctly + // See: https://github.com/ProseMirror/prosemirror-view/pull/47 + + var start = coordsAtPos(view, from); + var end = coordsAtPos(view, to, true); // The box in which the tooltip is positioned, to use as base + + var parent = this.options.element.offsetParent; + + if (!parent) { + this.hide(); + return; + } + + var box = parent.getBoundingClientRect(); + var el = this.options.element.getBoundingClientRect(); // Find a center-ish x position from the selection endpoints (when + // crossing lines, end may be more to the left) + + var left = (start.left + end.left) / 2 - box.left; // Keep the menuBubble in the bounding box of the offsetParent i + + this.left = Math.round(this.options.keepInBounds ? Math.min(box.width - el.width / 2, Math.max(left, el.width / 2)) : left); + this.bottom = Math.round(box.bottom - start.top); + this.top = Math.round(end.bottom - box.top); + this.isActive = true; + this.sendUpdate(); + } + }, { + key: "sendUpdate", + value: function sendUpdate() { + this.options.onUpdate({ + isActive: this.isActive, + left: this.left, + bottom: this.bottom, + top: this.top + }); + } + }, { + key: "hide", + value: function hide(event) { + if (event && event.relatedTarget && this.options.element.parentNode.contains(event.relatedTarget)) { + return; + } + + this.isActive = false; + this.sendUpdate(); + } + }, { + key: "destroy", + value: function destroy() { + this.options.element.removeEventListener('mousedown', this.mousedownHandler); + } + }]); + + return Menu; +}(); + +function MenuBubble (options) { + return new prosemirrorState.Plugin({ + key: new prosemirrorState.PluginKey('menu_bubble'), + view: function view(editorView) { + return new Menu$1({ + editorView: editorView, + options: options + }); + } + }); +} + +var EditorMenuBubble = { + props: { + editor: { + default: null, + type: Object + }, + keepInBounds: { + default: true, + type: Boolean + } + }, + data: function data() { + return { + menu: { + isActive: false, + left: 0, + bottom: 0 + } + }; + }, + watch: { + editor: { + immediate: true, + handler: function handler(editor) { + var _this = this; + + if (editor) { + this.$nextTick(function () { + editor.registerPlugin(MenuBubble({ + editor: editor, + element: _this.$el, + keepInBounds: _this.keepInBounds, + onUpdate: function onUpdate(menu) { + // the second check ensures event is fired only once + if (menu.isActive && _this.menu.isActive === false) { + _this.$emit('show', menu); + } else if (!menu.isActive && _this.menu.isActive === true) { + _this.$emit('hide', menu); + } + + _this.menu = menu; + } + })); + }); + } + } + } + }, + render: function render() { + if (!this.editor) { + return null; + } + + return this.$scopedSlots.default({ + focused: this.editor.view.focused, + focus: this.editor.focus, + commands: this.editor.commands, + isActive: this.editor.isActive, + getMarkAttrs: this.editor.getMarkAttrs.bind(this.editor), + menu: this.menu + }); + }, + beforeDestroy: function beforeDestroy() { + this.editor.unregisterPlugin('menu_bubble'); + } +}; + +var Menu$2 = +/*#__PURE__*/ +function () { + function Menu(_ref) { + var _this = this; + + var options = _ref.options, + editorView = _ref.editorView; + + _classCallCheck(this, Menu); + + this.options = _objectSpread2({}, { + resizeObserver: true, + element: null, + onUpdate: function onUpdate() { + return false; + } + }, {}, options); + this.preventHide = false; + this.editorView = editorView; + this.isActive = false; + this.top = 0; // the mousedown event is fired before blur so we can prevent it + + this.mousedownHandler = this.handleClick.bind(this); + this.options.element.addEventListener('mousedown', this.mousedownHandler); + this.options.editor.on('focus', function (_ref2) { + var view = _ref2.view; + + _this.update(view); + }); + this.options.editor.on('blur', function (_ref3) { + var event = _ref3.event; + + if (_this.preventHide) { + _this.preventHide = false; + return; + } + + _this.hide(event); + }); // sometimes we have to update the position + // because of a loaded images for example + + if (this.options.resizeObserver && window.ResizeObserver) { + this.resizeObserver = new ResizeObserver(function () { + if (_this.isActive) { + _this.update(_this.editorView); + } + }); + this.resizeObserver.observe(this.editorView.dom); + } + } + + _createClass(Menu, [{ + key: "handleClick", + value: function handleClick() { + this.preventHide = true; + } + }, { + key: "update", + value: function update(view, lastState) { + var state = view.state; // Don't do anything if the document/selection didn't change + + if (lastState && lastState.doc.eq(state.doc) && lastState.selection.eq(state.selection)) { + return; + } + + if (!state.selection.empty) { + this.hide(); + return; + } + + var currentDom = view.domAtPos(state.selection.anchor); + var isActive = currentDom.node.innerHTML === '
    ' && currentDom.node.tagName === 'P' && currentDom.node.parentNode === view.dom; + + if (!isActive) { + this.hide(); + return; + } + + var parent = this.options.element.offsetParent; + + if (!parent) { + this.hide(); + return; + } + + var editorBoundings = parent.getBoundingClientRect(); + var cursorBoundings = view.coordsAtPos(state.selection.anchor); + var top = cursorBoundings.top - editorBoundings.top; + this.isActive = true; + this.top = top; + this.sendUpdate(); + } + }, { + key: "sendUpdate", + value: function sendUpdate() { + this.options.onUpdate({ + isActive: this.isActive, + top: this.top + }); + } + }, { + key: "hide", + value: function hide(event) { + if (event && event.relatedTarget && this.options.element.parentNode.contains(event.relatedTarget)) { + return; + } + + this.isActive = false; + this.sendUpdate(); + } + }, { + key: "destroy", + value: function destroy() { + this.options.element.removeEventListener('mousedown', this.mousedownHandler); + + if (this.resizeObserver) { + this.resizeObserver.unobserve(this.editorView.dom); + } + } + }]); + + return Menu; +}(); + +function FloatingMenu (options) { + return new prosemirrorState.Plugin({ + key: new prosemirrorState.PluginKey('floating_menu'), + view: function view(editorView) { + return new Menu$2({ + editorView: editorView, + options: options + }); + } + }); +} + +var EditorFloatingMenu = { + props: { + editor: { + default: null, + type: Object + } + }, + data: function data() { + return { + menu: { + isActive: false, + left: 0, + bottom: 0 + } + }; + }, + watch: { + editor: { + immediate: true, + handler: function handler(editor) { + var _this = this; + + if (editor) { + this.$nextTick(function () { + editor.registerPlugin(FloatingMenu({ + editor: editor, + element: _this.$el, + onUpdate: function onUpdate(menu) { + // the second check ensures event is fired only once + if (menu.isActive && _this.menu.isActive === false) { + _this.$emit('show', menu); + } else if (!menu.isActive && _this.menu.isActive === true) { + _this.$emit('hide', menu); + } + + _this.menu = menu; + } + })); + }); + } + } + } + }, + render: function render() { + if (!this.editor) { + return null; + } + + return this.$scopedSlots.default({ + focused: this.editor.view.focused, + focus: this.editor.focus, + commands: this.editor.commands, + isActive: this.editor.isActive, + getMarkAttrs: this.editor.getMarkAttrs.bind(this.editor), + menu: this.menu + }); + }, + beforeDestroy: function beforeDestroy() { + this.editor.unregisterPlugin('floating_menu'); + } +}; + +Object.defineProperty(exports, 'NodeSelection', { + enumerable: true, + get: function () { + return prosemirrorState.NodeSelection; + } +}); +Object.defineProperty(exports, 'Plugin', { + enumerable: true, + get: function () { + return prosemirrorState.Plugin; + } +}); +Object.defineProperty(exports, 'PluginKey', { + enumerable: true, + get: function () { + return prosemirrorState.PluginKey; + } +}); +Object.defineProperty(exports, 'TextSelection', { + enumerable: true, + get: function () { + return prosemirrorState.TextSelection; + } +}); +exports.Doc = Doc; +exports.Editor = Editor; +exports.EditorContent = EditorContent; +exports.EditorFloatingMenu = EditorFloatingMenu; +exports.EditorMenuBar = EditorMenuBar; +exports.EditorMenuBubble = EditorMenuBubble; +exports.Extension = Extension; +exports.Mark = Mark; +exports.Node = Node; +exports.Paragraph = Paragraph; +exports.Text = Text; diff --git a/packages/tiptap/dist/tiptap.esm.js b/packages/tiptap/dist/tiptap.esm.js new file mode 100644 index 0000000000..b26dfdf151 --- /dev/null +++ b/packages/tiptap/dist/tiptap.esm.js @@ -0,0 +1,2144 @@ + + /*! + * tiptap v1.26.6 + * (c) 2020 Scrumpy UG (limited liability) + * @license MIT + */ + +import { EditorState, Plugin, PluginKey, TextSelection } from 'prosemirror-state'; +export { NodeSelection, Plugin, PluginKey, TextSelection } from 'prosemirror-state'; +import { EditorView } from 'prosemirror-view'; +import { Schema, DOMParser, DOMSerializer } from 'prosemirror-model'; +import { dropCursor } from 'prosemirror-dropcursor'; +import { gapCursor } from 'prosemirror-gapcursor'; +import { keymap } from 'prosemirror-keymap'; +import { baseKeymap } from 'prosemirror-commands'; +import { inputRules, undoInputRule } from 'prosemirror-inputrules'; +import { getMarkRange, getMarkAttrs, markIsActive, nodeIsActive } from 'tiptap-utils'; +import Vue from 'vue'; +import { setBlockType } from 'tiptap-commands'; + +function _typeof(obj) { + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { + _typeof = function (obj) { + return typeof obj; + }; + } else { + _typeof = function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; + }; + } + + return _typeof(obj); +} + +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 _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 _slicedToArray(arr, i) { + return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); +} + +function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); +} + +function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } +} + +function _arrayWithHoles(arr) { + if (Array.isArray(arr)) return arr; +} + +function _iterableToArray(iter) { + if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); +} + +function _iterableToArrayLimit(arr, i) { + if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { + 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 _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); +} + +function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance"); +} + +function camelCase (str) { + return str.replace(/(?:^\w|[A-Z]|\b\w)/g, function (word, index) { + return index === 0 ? word.toLowerCase() : word.toUpperCase(); + }).replace(/\s+/g, ''); +} + +var ComponentView = +/*#__PURE__*/ +function () { + function ComponentView(component, _ref) { + var editor = _ref.editor, + extension = _ref.extension, + parent = _ref.parent, + node = _ref.node, + view = _ref.view, + decorations = _ref.decorations, + getPos = _ref.getPos; + + _classCallCheck(this, ComponentView); + + this.component = component; + this.editor = editor; + this.extension = extension; + this.parent = parent; + this.node = node; + this.view = view; + this.decorations = decorations; + this.isNode = !!this.node.marks; + this.isMark = !this.isNode; + this.getPos = this.isMark ? this.getMarkPos : getPos; + this.captureEvents = true; + this.dom = this.createDOM(); + this.contentDOM = this.vm.$refs.content; + } + + _createClass(ComponentView, [{ + key: "createDOM", + value: function createDOM() { + var _this = this; + + var Component = Vue.extend(this.component); + var props = { + editor: this.editor, + node: this.node, + view: this.view, + getPos: function getPos() { + return _this.getPos(); + }, + decorations: this.decorations, + selected: false, + options: this.extension.options, + updateAttrs: function updateAttrs(attrs) { + return _this.updateAttrs(attrs); + } + }; + + if (typeof this.extension.setSelection === 'function') { + this.setSelection = this.extension.setSelection; + } + + this.vm = new Component({ + parent: this.parent, + propsData: props + }).$mount(); + return this.vm.$el; + } + }, { + key: "update", + value: function update(node, decorations) { + if (node.type !== this.node.type) { + return false; + } + + if (node === this.node && this.decorations === decorations) { + return true; + } + + this.node = node; + this.decorations = decorations; + this.updateComponentProps({ + node: node, + decorations: decorations + }); + return true; + } + }, { + key: "updateComponentProps", + value: function updateComponentProps(props) { + var _this2 = this; + + if (!this.vm._props) { + return; + } // Update props in component + // TODO: Avoid mutating a prop directly. + // Maybe there is a better way to do this? + + + var originalSilent = Vue.config.silent; + Vue.config.silent = true; + Object.entries(props).forEach(function (_ref2) { + var _ref3 = _slicedToArray(_ref2, 2), + key = _ref3[0], + value = _ref3[1]; + + _this2.vm._props[key] = value; + }); // this.vm._props.node = node + // this.vm._props.decorations = decorations + + Vue.config.silent = originalSilent; + } + }, { + key: "updateAttrs", + value: function updateAttrs(attrs) { + if (!this.view.editable) { + return; + } + + var state = this.view.state; + var type = this.node.type; + var pos = this.getPos(); + + var newAttrs = _objectSpread2({}, this.node.attrs, {}, attrs); + + var transaction = this.isMark ? state.tr.removeMark(pos.from, pos.to, type).addMark(pos.from, pos.to, type.create(newAttrs)) : state.tr.setNodeMarkup(pos, null, newAttrs); + this.view.dispatch(transaction); + } // prevent a full re-render of the vue component on update + // we'll handle prop updates in `update()` + + }, { + key: "ignoreMutation", + value: function ignoreMutation(mutation) { + // allow leaf nodes to be selected + if (mutation.type === 'selection') { + return false; + } + + if (!this.contentDOM) { + return true; + } + + return !this.contentDOM.contains(mutation.target); + } // disable (almost) all prosemirror event listener for node views + + }, { + key: "stopEvent", + value: function stopEvent(event) { + var _this3 = this; + + if (typeof this.extension.stopEvent === 'function') { + return this.extension.stopEvent(event); + } + + var draggable = !!this.extension.schema.draggable; // support a custom drag handle + + if (draggable && event.type === 'mousedown') { + var dragHandle = event.target.closest && event.target.closest('[data-drag-handle]'); + var isValidDragHandle = dragHandle && (this.dom === dragHandle || this.dom.contains(dragHandle)); + + if (isValidDragHandle) { + this.captureEvents = false; + document.addEventListener('dragend', function () { + _this3.captureEvents = true; + }, { + once: true + }); + } + } + + var isCopy = event.type === 'copy'; + var isPaste = event.type === 'paste'; + var isCut = event.type === 'cut'; + var isDrag = event.type.startsWith('drag') || event.type === 'drop'; + + if (draggable && isDrag || isCopy || isPaste || isCut) { + return false; + } + + return this.captureEvents; + } + }, { + key: "selectNode", + value: function selectNode() { + this.updateComponentProps({ + selected: true + }); + } + }, { + key: "deselectNode", + value: function deselectNode() { + this.updateComponentProps({ + selected: false + }); + } + }, { + key: "getMarkPos", + value: function getMarkPos() { + var pos = this.view.posAtDOM(this.dom); + var resolvedPos = this.view.state.doc.resolve(pos); + var range = getMarkRange(resolvedPos, this.node.type); + return range; + } + }, { + key: "destroy", + value: function destroy() { + this.vm.$destroy(); + } + }]); + + return ComponentView; +}(); + +var Emitter = +/*#__PURE__*/ +function () { + function Emitter() { + _classCallCheck(this, Emitter); + } + + _createClass(Emitter, [{ + key: "on", + // Add an event listener for given event + value: function on(event, fn) { + this._callbacks = this._callbacks || {}; // Create namespace for this event + + if (!this._callbacks[event]) { + this._callbacks[event] = []; + } + + this._callbacks[event].push(fn); + + return this; + } + }, { + key: "emit", + value: function emit(event) { + var _this = this; + + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + this._callbacks = this._callbacks || {}; + var callbacks = this._callbacks[event]; + + if (callbacks) { + callbacks.forEach(function (callback) { + return callback.apply(_this, args); + }); + } + + return this; + } // Remove event listener for given event. + // If fn is not provided, all event listeners for that event will be removed. + // If neither is provided, all event listeners will be removed. + + }, { + key: "off", + value: function off(event, fn) { + if (!arguments.length) { + this._callbacks = {}; + } else { + // event listeners for the given event + var callbacks = this._callbacks ? this._callbacks[event] : null; + + if (callbacks) { + if (fn) { + this._callbacks[event] = callbacks.filter(function (cb) { + return cb !== fn; + }); // remove specific handler + } else { + delete this._callbacks[event]; // remove all handlers + } + } + } + + return this; + } + }]); + + return Emitter; +}(); + +var Extension = +/*#__PURE__*/ +function () { + function Extension() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, Extension); + + this.options = _objectSpread2({}, this.defaultOptions, {}, options); + } + + _createClass(Extension, [{ + key: "init", + value: function init() { + return null; + } + }, { + key: "bindEditor", + value: function bindEditor() { + var editor = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + this.editor = editor; + } + }, { + key: "inputRules", + value: function inputRules() { + return []; + } + }, { + key: "pasteRules", + value: function pasteRules() { + return []; + } + }, { + key: "keys", + value: function keys() { + return {}; + } + }, { + key: "name", + get: function get() { + return null; + } + }, { + key: "type", + get: function get() { + return 'extension'; + } + }, { + key: "update", + get: function get() { + return function () {}; + } + }, { + key: "defaultOptions", + get: function get() { + return {}; + } + }, { + key: "plugins", + get: function get() { + return []; + } + }]); + + return Extension; +}(); + +var ExtensionManager = +/*#__PURE__*/ +function () { + function ExtensionManager() { + var extensions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + var editor = arguments.length > 1 ? arguments[1] : undefined; + + _classCallCheck(this, ExtensionManager); + + extensions.forEach(function (extension) { + extension.bindEditor(editor); + extension.init(); + }); + this.extensions = extensions; + } + + _createClass(ExtensionManager, [{ + key: "keymaps", + value: function keymaps(_ref) { + var schema = _ref.schema; + var extensionKeymaps = this.extensions.filter(function (extension) { + return ['extension'].includes(extension.type); + }).filter(function (extension) { + return extension.keys; + }).map(function (extension) { + return extension.keys({ + schema: schema + }); + }); + var nodeMarkKeymaps = this.extensions.filter(function (extension) { + return ['node', 'mark'].includes(extension.type); + }).filter(function (extension) { + return extension.keys; + }).map(function (extension) { + return extension.keys({ + type: schema["".concat(extension.type, "s")][extension.name], + schema: schema + }); + }); + return [].concat(_toConsumableArray(extensionKeymaps), _toConsumableArray(nodeMarkKeymaps)).map(function (keys) { + return keymap(keys); + }); + } + }, { + key: "inputRules", + value: function inputRules(_ref2) { + var schema = _ref2.schema, + excludedExtensions = _ref2.excludedExtensions; + if (!(excludedExtensions instanceof Array) && excludedExtensions) return []; + var allowedExtensions = excludedExtensions instanceof Array ? this.extensions.filter(function (extension) { + return !excludedExtensions.includes(extension.name); + }) : this.extensions; + var extensionInputRules = allowedExtensions.filter(function (extension) { + return ['extension'].includes(extension.type); + }).filter(function (extension) { + return extension.inputRules; + }).map(function (extension) { + return extension.inputRules({ + schema: schema + }); + }); + var nodeMarkInputRules = allowedExtensions.filter(function (extension) { + return ['node', 'mark'].includes(extension.type); + }).filter(function (extension) { + return extension.inputRules; + }).map(function (extension) { + return extension.inputRules({ + type: schema["".concat(extension.type, "s")][extension.name], + schema: schema + }); + }); + return [].concat(_toConsumableArray(extensionInputRules), _toConsumableArray(nodeMarkInputRules)).reduce(function (allInputRules, inputRules) { + return [].concat(_toConsumableArray(allInputRules), _toConsumableArray(inputRules)); + }, []); + } + }, { + key: "pasteRules", + value: function pasteRules(_ref3) { + var schema = _ref3.schema, + excludedExtensions = _ref3.excludedExtensions; + if (!(excludedExtensions instanceof Array) && excludedExtensions) return []; + var allowedExtensions = excludedExtensions instanceof Array ? this.extensions.filter(function (extension) { + return !excludedExtensions.includes(extension.name); + }) : this.extensions; + var extensionPasteRules = allowedExtensions.filter(function (extension) { + return ['extension'].includes(extension.type); + }).filter(function (extension) { + return extension.pasteRules; + }).map(function (extension) { + return extension.pasteRules({ + schema: schema + }); + }); + var nodeMarkPasteRules = allowedExtensions.filter(function (extension) { + return ['node', 'mark'].includes(extension.type); + }).filter(function (extension) { + return extension.pasteRules; + }).map(function (extension) { + return extension.pasteRules({ + type: schema["".concat(extension.type, "s")][extension.name], + schema: schema + }); + }); + return [].concat(_toConsumableArray(extensionPasteRules), _toConsumableArray(nodeMarkPasteRules)).reduce(function (allPasteRules, pasteRules) { + return [].concat(_toConsumableArray(allPasteRules), _toConsumableArray(pasteRules)); + }, []); + } + }, { + key: "commands", + value: function commands(_ref4) { + var schema = _ref4.schema, + view = _ref4.view; + return this.extensions.filter(function (extension) { + return extension.commands; + }).reduce(function (allCommands, extension) { + var name = extension.name, + type = extension.type; + var commands = {}; + var value = extension.commands(_objectSpread2({ + schema: schema + }, ['node', 'mark'].includes(type) ? { + type: schema["".concat(type, "s")][name] + } : {})); + + var apply = function apply(cb, attrs) { + if (!view.editable) { + return false; + } + + view.focus(); + return cb(attrs)(view.state, view.dispatch, view); + }; + + var handle = function handle(_name, _value) { + if (Array.isArray(_value)) { + commands[_name] = function (attrs) { + return _value.forEach(function (callback) { + return apply(callback, attrs); + }); + }; + } else if (typeof _value === 'function') { + commands[_name] = function (attrs) { + return apply(_value, attrs); + }; + } + }; + + if (_typeof(value) === 'object') { + Object.entries(value).forEach(function (_ref5) { + var _ref6 = _slicedToArray(_ref5, 2), + commandName = _ref6[0], + commandValue = _ref6[1]; + + handle(commandName, commandValue); + }); + } else { + handle(name, value); + } + + return _objectSpread2({}, allCommands, {}, commands); + }, {}); + } + }, { + key: "nodes", + get: function get() { + return this.extensions.filter(function (extension) { + return extension.type === 'node'; + }).reduce(function (nodes, _ref7) { + var name = _ref7.name, + schema = _ref7.schema; + return _objectSpread2({}, nodes, _defineProperty({}, name, schema)); + }, {}); + } + }, { + key: "options", + get: function get() { + var view = this.view; + return this.extensions.reduce(function (nodes, extension) { + return _objectSpread2({}, nodes, _defineProperty({}, extension.name, new Proxy(extension.options, { + set: function set(obj, prop, value) { + var changed = obj[prop] !== value; + Object.assign(obj, _defineProperty({}, prop, value)); + + if (changed) { + extension.update(view); + } + + return true; + } + }))); + }, {}); + } + }, { + key: "marks", + get: function get() { + return this.extensions.filter(function (extension) { + return extension.type === 'mark'; + }).reduce(function (marks, _ref8) { + var name = _ref8.name, + schema = _ref8.schema; + return _objectSpread2({}, marks, _defineProperty({}, name, schema)); + }, {}); + } + }, { + key: "plugins", + get: function get() { + return this.extensions.filter(function (extension) { + return extension.plugins; + }).reduce(function (allPlugins, _ref9) { + var plugins = _ref9.plugins; + return [].concat(_toConsumableArray(allPlugins), _toConsumableArray(plugins)); + }, []); + } + }]); + + return ExtensionManager; +}(); + +function injectCSS (css) { + if (process.env.NODE_ENV !== 'test') { + var style = document.createElement('style'); + style.type = 'text/css'; + style.textContent = css; + var _document = document, + head = _document.head; + var firstChild = head.firstChild; + + if (firstChild) { + head.insertBefore(style, firstChild); + } else { + head.appendChild(style); + } + } +} + +var Mark = +/*#__PURE__*/ +function (_Extension) { + _inherits(Mark, _Extension); + + function Mark() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, Mark); + + return _possibleConstructorReturn(this, _getPrototypeOf(Mark).call(this, options)); + } + + _createClass(Mark, [{ + key: "command", + value: function command() { + return function () {}; + } + }, { + key: "type", + get: function get() { + return 'mark'; + } + }, { + key: "view", + get: function get() { + return null; + } + }, { + key: "schema", + get: function get() { + return null; + } + }]); + + return Mark; +}(Extension); + +function minMax() { + var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + var min = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + var max = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + return Math.min(Math.max(parseInt(value, 10), min), max); +} + +var Node = +/*#__PURE__*/ +function (_Extension) { + _inherits(Node, _Extension); + + function Node() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, Node); + + return _possibleConstructorReturn(this, _getPrototypeOf(Node).call(this, options)); + } + + _createClass(Node, [{ + key: "command", + value: function command() { + return function () {}; + } + }, { + key: "type", + get: function get() { + return 'node'; + } + }, { + key: "view", + get: function get() { + return null; + } + }, { + key: "schema", + get: function get() { + return null; + } + }]); + + return Node; +}(Extension); + +var Doc = +/*#__PURE__*/ +function (_Node) { + _inherits(Doc, _Node); + + function Doc() { + _classCallCheck(this, Doc); + + return _possibleConstructorReturn(this, _getPrototypeOf(Doc).apply(this, arguments)); + } + + _createClass(Doc, [{ + key: "name", + get: function get() { + return 'doc'; + } + }, { + key: "schema", + get: function get() { + return { + content: 'block+' + }; + } + }]); + + return Doc; +}(Node); + +var Paragraph = +/*#__PURE__*/ +function (_Node) { + _inherits(Paragraph, _Node); + + function Paragraph() { + _classCallCheck(this, Paragraph); + + return _possibleConstructorReturn(this, _getPrototypeOf(Paragraph).apply(this, arguments)); + } + + _createClass(Paragraph, [{ + key: "commands", + value: function commands(_ref) { + var type = _ref.type; + return function () { + return setBlockType(type); + }; + } + }, { + key: "name", + get: function get() { + return 'paragraph'; + } + }, { + key: "schema", + get: function get() { + return { + content: 'inline*', + group: 'block', + draggable: false, + parseDOM: [{ + tag: 'p' + }], + toDOM: function toDOM() { + return ['p', 0]; + } + }; + } + }]); + + return Paragraph; +}(Node); + +var Text = +/*#__PURE__*/ +function (_Node) { + _inherits(Text, _Node); + + function Text() { + _classCallCheck(this, Text); + + return _possibleConstructorReturn(this, _getPrototypeOf(Text).apply(this, arguments)); + } + + _createClass(Text, [{ + key: "name", + get: function get() { + return 'text'; + } + }, { + key: "schema", + get: function get() { + return { + group: 'inline' + }; + } + }]); + + return Text; +}(Node); + +var css = ".ProseMirror {\n position: relative;\n}\n\n.ProseMirror {\n word-wrap: break-word;\n white-space: pre-wrap;\n -webkit-font-variant-ligatures: none;\n font-variant-ligatures: none;\n}\n\n.ProseMirror pre {\n white-space: pre-wrap;\n}\n\n.ProseMirror-gapcursor {\n display: none;\n pointer-events: none;\n position: absolute;\n}\n\n.ProseMirror-gapcursor:after {\n content: \"\";\n display: block;\n position: absolute;\n top: -2px;\n width: 20px;\n border-top: 1px solid black;\n animation: ProseMirror-cursor-blink 1.1s steps(2, start) infinite;\n}\n\n@keyframes ProseMirror-cursor-blink {\n to {\n visibility: hidden;\n }\n}\n\n.ProseMirror-hideselection *::selection {\n background: transparent;\n}\n\n.ProseMirror-hideselection *::-moz-selection {\n background: transparent;\n}\n\n.ProseMirror-hideselection * {\n caret-color: transparent;\n}\n\n.ProseMirror-focused .ProseMirror-gapcursor {\n display: block;\n}\n"; + +var Editor = +/*#__PURE__*/ +function (_Emitter) { + _inherits(Editor, _Emitter); + + function Editor() { + var _this; + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, Editor); + + _this = _possibleConstructorReturn(this, _getPrototypeOf(Editor).call(this)); + _this.defaultOptions = { + editorProps: {}, + editable: true, + autoFocus: null, + extensions: [], + content: '', + topNode: 'doc', + emptyDocument: { + type: 'doc', + content: [{ + type: 'paragraph' + }] + }, + useBuiltInExtensions: true, + disableInputRules: false, + disablePasteRules: false, + dropCursor: {}, + parseOptions: {}, + injectCSS: true, + onInit: function onInit() {}, + onTransaction: function onTransaction() {}, + onUpdate: function onUpdate() {}, + onFocus: function onFocus() {}, + onBlur: function onBlur() {}, + onPaste: function onPaste() {}, + onDrop: function onDrop() {} + }; + _this.events = ['init', 'transaction', 'update', 'focus', 'blur', 'paste', 'drop']; + + _this.init(options); + + return _this; + } + + _createClass(Editor, [{ + key: "init", + value: function init() { + var _this2 = this; + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + this.setOptions(_objectSpread2({}, this.defaultOptions, {}, options)); + this.focused = false; + this.selection = { + from: 0, + to: 0 + }; + this.element = document.createElement('div'); + this.extensions = this.createExtensions(); + this.nodes = this.createNodes(); + this.marks = this.createMarks(); + this.schema = this.createSchema(); + this.plugins = this.createPlugins(); + this.keymaps = this.createKeymaps(); + this.inputRules = this.createInputRules(); + this.pasteRules = this.createPasteRules(); + this.view = this.createView(); + this.commands = this.createCommands(); + this.setActiveNodesAndMarks(); + + if (this.options.injectCSS) { + injectCSS(css); + } + + if (this.options.autoFocus !== null) { + this.focus(this.options.autoFocus); + } + + this.events.forEach(function (name) { + _this2.on(name, _this2.options[camelCase("on ".concat(name))] || function () {}); + }); + this.emit('init', { + view: this.view, + state: this.state + }); // give extension manager access to our view + + this.extensions.view = this.view; + } + }, { + key: "setOptions", + value: function setOptions(options) { + this.options = _objectSpread2({}, this.options, {}, options); + + if (this.view && this.state) { + this.view.updateState(this.state); + } + } + }, { + key: "createExtensions", + value: function createExtensions() { + return new ExtensionManager([].concat(_toConsumableArray(this.builtInExtensions), _toConsumableArray(this.options.extensions)), this); + } + }, { + key: "createPlugins", + value: function createPlugins() { + return this.extensions.plugins; + } + }, { + key: "createKeymaps", + value: function createKeymaps() { + return this.extensions.keymaps({ + schema: this.schema + }); + } + }, { + key: "createInputRules", + value: function createInputRules() { + return this.extensions.inputRules({ + schema: this.schema, + excludedExtensions: this.options.disableInputRules + }); + } + }, { + key: "createPasteRules", + value: function createPasteRules() { + return this.extensions.pasteRules({ + schema: this.schema, + excludedExtensions: this.options.disablePasteRules + }); + } + }, { + key: "createCommands", + value: function createCommands() { + return this.extensions.commands({ + schema: this.schema, + view: this.view + }); + } + }, { + key: "createNodes", + value: function createNodes() { + return this.extensions.nodes; + } + }, { + key: "createMarks", + value: function createMarks() { + return this.extensions.marks; + } + }, { + key: "createSchema", + value: function createSchema() { + return new Schema({ + topNode: this.options.topNode, + nodes: this.nodes, + marks: this.marks + }); + } + }, { + key: "createState", + value: function createState() { + var _this3 = this; + + return EditorState.create({ + schema: this.schema, + doc: this.createDocument(this.options.content), + plugins: [].concat(_toConsumableArray(this.plugins), [inputRules({ + rules: this.inputRules + })], _toConsumableArray(this.pasteRules), _toConsumableArray(this.keymaps), [keymap({ + Backspace: undoInputRule + }), keymap(baseKeymap), dropCursor(this.options.dropCursor), gapCursor(), new Plugin({ + key: new PluginKey('editable'), + props: { + editable: function editable() { + return _this3.options.editable; + } + } + }), new Plugin({ + props: { + attributes: { + tabindex: 0 + }, + handleDOMEvents: { + focus: function focus(view, event) { + _this3.focused = true; + + _this3.emit('focus', { + event: event, + state: view.state, + view: view + }); + + var transaction = _this3.state.tr.setMeta('focused', true); + + _this3.view.dispatch(transaction); + }, + blur: function blur(view, event) { + _this3.focused = false; + + _this3.emit('blur', { + event: event, + state: view.state, + view: view + }); + + var transaction = _this3.state.tr.setMeta('focused', false); + + _this3.view.dispatch(transaction); + } + } + } + }), new Plugin({ + props: this.options.editorProps + })]) + }); + } + }, { + key: "createDocument", + value: function createDocument(content) { + var parseOptions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.options.parseOptions; + + if (content === null) { + return this.schema.nodeFromJSON(this.options.emptyDocument); + } + + if (_typeof(content) === 'object') { + try { + return this.schema.nodeFromJSON(content); + } catch (error) { + console.warn('[tiptap warn]: Invalid content.', 'Passed value:', content, 'Error:', error); + return this.schema.nodeFromJSON(this.options.emptyDocument); + } + } + + if (typeof content === 'string') { + var element = document.createElement('div'); + element.innerHTML = content.trim(); + return DOMParser.fromSchema(this.schema).parse(element, parseOptions); + } + + return false; + } + }, { + key: "createView", + value: function createView() { + var _this4 = this; + + return new EditorView(this.element, { + state: this.createState(), + handlePaste: function handlePaste() { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + _this4.emit.apply(_this4, ['paste'].concat(args)); + }, + handleDrop: function handleDrop() { + for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } + + _this4.emit.apply(_this4, ['drop'].concat(args)); + }, + dispatchTransaction: this.dispatchTransaction.bind(this) + }); + } + }, { + key: "setParentComponent", + value: function setParentComponent() { + var component = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + + if (!component) { + return; + } + + this.view.setProps({ + nodeViews: this.initNodeViews({ + parent: component, + extensions: [].concat(_toConsumableArray(this.builtInExtensions), _toConsumableArray(this.options.extensions)) + }) + }); + } + }, { + key: "initNodeViews", + value: function initNodeViews(_ref) { + var _this5 = this; + + var parent = _ref.parent, + extensions = _ref.extensions; + return extensions.filter(function (extension) { + return ['node', 'mark'].includes(extension.type); + }).filter(function (extension) { + return extension.view; + }).reduce(function (nodeViews, extension) { + var nodeView = function nodeView(node, view, getPos, decorations) { + var component = extension.view; + return new ComponentView(component, { + editor: _this5, + extension: extension, + parent: parent, + node: node, + view: view, + getPos: getPos, + decorations: decorations + }); + }; + + return _objectSpread2({}, nodeViews, _defineProperty({}, extension.name, nodeView)); + }, {}); + } + }, { + key: "dispatchTransaction", + value: function dispatchTransaction(transaction) { + var newState = this.state.apply(transaction); + this.view.updateState(newState); + this.selection = { + from: this.state.selection.from, + to: this.state.selection.to + }; + this.setActiveNodesAndMarks(); + this.emit('transaction', { + getHTML: this.getHTML.bind(this), + getJSON: this.getJSON.bind(this), + state: this.state, + transaction: transaction + }); + + if (!transaction.docChanged || transaction.getMeta('preventUpdate')) { + return; + } + + this.emitUpdate(transaction); + } + }, { + key: "emitUpdate", + value: function emitUpdate(transaction) { + this.emit('update', { + getHTML: this.getHTML.bind(this), + getJSON: this.getJSON.bind(this), + state: this.state, + transaction: transaction + }); + } + }, { + key: "resolveSelection", + value: function resolveSelection() { + var position = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + + if (this.selection && position === null) { + return this.selection; + } + + if (position === 'start' || position === true) { + return { + from: 0, + to: 0 + }; + } + + if (position === 'end') { + var doc = this.state.doc; + return { + from: doc.content.size, + to: doc.content.size + }; + } + + return { + from: position, + to: position + }; + } + }, { + key: "focus", + value: function focus() { + var _this6 = this; + + var position = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + + if (this.view.focused && position === null || position === false) { + return; + } + + var _this$resolveSelectio = this.resolveSelection(position), + from = _this$resolveSelectio.from, + to = _this$resolveSelectio.to; + + this.setSelection(from, to); + setTimeout(function () { + return _this6.view.focus(); + }, 10); + } + }, { + key: "setSelection", + value: function setSelection() { + var from = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + var to = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + var _this$state = this.state, + doc = _this$state.doc, + tr = _this$state.tr; + var resolvedFrom = minMax(from, 0, doc.content.size); + var resolvedEnd = minMax(to, 0, doc.content.size); + var selection = TextSelection.create(doc, resolvedFrom, resolvedEnd); + var transaction = tr.setSelection(selection); + this.view.dispatch(transaction); + } + }, { + key: "blur", + value: function blur() { + this.view.dom.blur(); + } + }, { + key: "getSchemaJSON", + value: function getSchemaJSON() { + return JSON.parse(JSON.stringify({ + nodes: this.extensions.nodes, + marks: this.extensions.marks + })); + } + }, { + key: "getHTML", + value: function getHTML() { + var div = document.createElement('div'); + var fragment = DOMSerializer.fromSchema(this.schema).serializeFragment(this.state.doc.content); + div.appendChild(fragment); + return div.innerHTML; + } + }, { + key: "getJSON", + value: function getJSON() { + return this.state.doc.toJSON(); + } + }, { + key: "setContent", + value: function setContent() { + var content = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var emitUpdate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + var parseOptions = arguments.length > 2 ? arguments[2] : undefined; + var _this$state2 = this.state, + doc = _this$state2.doc, + tr = _this$state2.tr; + var document = this.createDocument(content, parseOptions); + var selection = TextSelection.create(doc, 0, doc.content.size); + var transaction = tr.setSelection(selection).replaceSelectionWith(document, false).setMeta('preventUpdate', !emitUpdate); + this.view.dispatch(transaction); + } + }, { + key: "clearContent", + value: function clearContent() { + var emitUpdate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + this.setContent(this.options.emptyDocument, emitUpdate); + } + }, { + key: "setActiveNodesAndMarks", + value: function setActiveNodesAndMarks() { + var _this7 = this; + + this.activeMarks = Object.entries(this.schema.marks).reduce(function (marks, _ref2) { + var _ref3 = _slicedToArray(_ref2, 2), + name = _ref3[0], + mark = _ref3[1]; + + return _objectSpread2({}, marks, _defineProperty({}, name, function () { + var attrs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + return markIsActive(_this7.state, mark, attrs); + })); + }, {}); + this.activeMarkAttrs = Object.entries(this.schema.marks).reduce(function (marks, _ref4) { + var _ref5 = _slicedToArray(_ref4, 2), + name = _ref5[0], + mark = _ref5[1]; + + return _objectSpread2({}, marks, _defineProperty({}, name, getMarkAttrs(_this7.state, mark))); + }, {}); + this.activeNodes = Object.entries(this.schema.nodes).reduce(function (nodes, _ref6) { + var _ref7 = _slicedToArray(_ref6, 2), + name = _ref7[0], + node = _ref7[1]; + + return _objectSpread2({}, nodes, _defineProperty({}, name, function () { + var attrs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + return nodeIsActive(_this7.state, node, attrs); + })); + }, {}); + } + }, { + key: "getMarkAttrs", + value: function getMarkAttrs() { + var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + return this.activeMarkAttrs[type]; + } + }, { + key: "registerPlugin", + value: function registerPlugin() { + var plugin = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + + if (!plugin) { + return; + } + + var newState = this.state.reconfigure({ + plugins: this.state.plugins.concat([plugin]) + }); + this.view.updateState(newState); + } + }, { + key: "unregisterPlugin", + value: function unregisterPlugin() { + var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + + if (!name || !this.view.docView) { + return; + } + + var newState = this.state.reconfigure({ + plugins: this.state.plugins.filter(function (plugin) { + return !plugin.key.startsWith("".concat(name, "$")); + }) + }); + this.view.updateState(newState); + } + }, { + key: "destroy", + value: function destroy() { + if (!this.view) { + return; + } + + this.view.destroy(); + } + }, { + key: "builtInExtensions", + get: function get() { + if (!this.options.useBuiltInExtensions) { + return []; + } + + return [new Doc(), new Text(), new Paragraph()]; + } + }, { + key: "state", + get: function get() { + return this.view ? this.view.state : null; + } + }, { + key: "isActive", + get: function get() { + return Object.entries(_objectSpread2({}, this.activeMarks, {}, this.activeNodes)).reduce(function (types, _ref8) { + var _ref9 = _slicedToArray(_ref8, 2), + name = _ref9[0], + value = _ref9[1]; + + return _objectSpread2({}, types, _defineProperty({}, name, function () { + var attrs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + return value(attrs); + })); + }, {}); + } + }]); + + return Editor; +}(Emitter); + +var EditorContent = { + props: { + editor: { + default: null, + type: Object + } + }, + watch: { + editor: { + immediate: true, + handler: function handler(editor) { + var _this = this; + + if (editor && editor.element) { + this.$nextTick(function () { + _this.$el.appendChild(editor.element.firstChild); + + editor.setParentComponent(_this); + }); + } + } + } + }, + render: function render(createElement) { + return createElement('div'); + }, + beforeDestroy: function beforeDestroy() { + this.editor.element = this.$el; + } +}; + +var Menu = +/*#__PURE__*/ +function () { + function Menu(_ref) { + var _this = this; + + var options = _ref.options; + + _classCallCheck(this, Menu); + + this.options = options; + this.preventHide = false; // the mousedown event is fired before blur so we can prevent it + + this.mousedownHandler = this.handleClick.bind(this); + this.options.element.addEventListener('mousedown', this.mousedownHandler); + this.options.editor.on('blur', function () { + if (_this.preventHide) { + _this.preventHide = false; + return; + } + + _this.options.editor.emit('menubar:focusUpdate', false); + }); + } + + _createClass(Menu, [{ + key: "handleClick", + value: function handleClick() { + this.preventHide = true; + } + }, { + key: "destroy", + value: function destroy() { + this.options.element.removeEventListener('mousedown', this.mousedownHandler); + } + }]); + + return Menu; +}(); + +function MenuBar (options) { + return new Plugin({ + key: new PluginKey('menu_bar'), + view: function view(editorView) { + return new Menu({ + editorView: editorView, + options: options + }); + } + }); +} + +var EditorMenuBar = { + props: { + editor: { + default: null, + type: Object + } + }, + data: function data() { + return { + focused: false + }; + }, + watch: { + editor: { + immediate: true, + handler: function handler(editor) { + var _this = this; + + if (editor) { + this.$nextTick(function () { + editor.registerPlugin(MenuBar({ + editor: editor, + element: _this.$el + })); + _this.focused = editor.focused; + editor.on('focus', function () { + _this.focused = true; + }); + editor.on('menubar:focusUpdate', function (focused) { + _this.focused = focused; + }); + }); + } + } + } + }, + render: function render() { + if (!this.editor) { + return null; + } + + return this.$scopedSlots.default({ + focused: this.focused, + focus: this.editor.focus, + commands: this.editor.commands, + isActive: this.editor.isActive, + getMarkAttrs: this.editor.getMarkAttrs.bind(this.editor) + }); + } +}; + +function textRange(node, from, to) { + var range = document.createRange(); + range.setEnd(node, to == null ? node.nodeValue.length : to); + range.setStart(node, from || 0); + return range; +} + +function singleRect(object, bias) { + var rects = object.getClientRects(); + return !rects.length ? object.getBoundingClientRect() : rects[bias < 0 ? 0 : rects.length - 1]; +} + +function coordsAtPos(view, pos) { + var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + + var _view$docView$domFrom = view.docView.domFromPos(pos), + node = _view$docView$domFrom.node, + offset = _view$docView$domFrom.offset; + + var side; + var rect; + + if (node.nodeType === 3) { + if (end && offset < node.nodeValue.length) { + rect = singleRect(textRange(node, offset - 1, offset), -1); + side = 'right'; + } else if (offset < node.nodeValue.length) { + rect = singleRect(textRange(node, offset, offset + 1), -1); + side = 'left'; + } + } else if (node.firstChild) { + if (offset < node.childNodes.length) { + var child = node.childNodes[offset]; + rect = singleRect(child.nodeType === 3 ? textRange(child) : child, -1); + side = 'left'; + } + + if ((!rect || rect.top === rect.bottom) && offset) { + var _child = node.childNodes[offset - 1]; + rect = singleRect(_child.nodeType === 3 ? textRange(_child) : _child, 1); + side = 'right'; + } + } else { + rect = node.getBoundingClientRect(); + side = 'left'; + } + + var x = rect[side]; + return { + top: rect.top, + bottom: rect.bottom, + left: x, + right: x + }; +} + +var Menu$1 = +/*#__PURE__*/ +function () { + function Menu(_ref) { + var _this = this; + + var options = _ref.options, + editorView = _ref.editorView; + + _classCallCheck(this, Menu); + + this.options = _objectSpread2({}, { + element: null, + keepInBounds: true, + onUpdate: function onUpdate() { + return false; + } + }, {}, options); + this.editorView = editorView; + this.isActive = false; + this.left = 0; + this.bottom = 0; + this.top = 0; + this.preventHide = false; // the mousedown event is fired before blur so we can prevent it + + this.mousedownHandler = this.handleClick.bind(this); + this.options.element.addEventListener('mousedown', this.mousedownHandler); + this.options.editor.on('focus', function (_ref2) { + var view = _ref2.view; + + _this.update(view); + }); + this.options.editor.on('blur', function (_ref3) { + var event = _ref3.event; + + if (_this.preventHide) { + _this.preventHide = false; + return; + } + + _this.hide(event); + }); + } + + _createClass(Menu, [{ + key: "handleClick", + value: function handleClick() { + this.preventHide = true; + } + }, { + key: "update", + value: function update(view, lastState) { + var state = view.state; + + if (view.composing) { + return; + } // Don't do anything if the document/selection didn't change + + + if (lastState && lastState.doc.eq(state.doc) && lastState.selection.eq(state.selection)) { + return; + } // Hide the tooltip if the selection is empty + + + if (state.selection.empty) { + this.hide(); + return; + } // Otherwise, reposition it and update its content + + + var _state$selection = state.selection, + from = _state$selection.from, + to = _state$selection.to; // These are in screen coordinates + // We can't use EditorView.cordsAtPos here because it can't handle linebreaks correctly + // See: https://github.com/ProseMirror/prosemirror-view/pull/47 + + var start = coordsAtPos(view, from); + var end = coordsAtPos(view, to, true); // The box in which the tooltip is positioned, to use as base + + var parent = this.options.element.offsetParent; + + if (!parent) { + this.hide(); + return; + } + + var box = parent.getBoundingClientRect(); + var el = this.options.element.getBoundingClientRect(); // Find a center-ish x position from the selection endpoints (when + // crossing lines, end may be more to the left) + + var left = (start.left + end.left) / 2 - box.left; // Keep the menuBubble in the bounding box of the offsetParent i + + this.left = Math.round(this.options.keepInBounds ? Math.min(box.width - el.width / 2, Math.max(left, el.width / 2)) : left); + this.bottom = Math.round(box.bottom - start.top); + this.top = Math.round(end.bottom - box.top); + this.isActive = true; + this.sendUpdate(); + } + }, { + key: "sendUpdate", + value: function sendUpdate() { + this.options.onUpdate({ + isActive: this.isActive, + left: this.left, + bottom: this.bottom, + top: this.top + }); + } + }, { + key: "hide", + value: function hide(event) { + if (event && event.relatedTarget && this.options.element.parentNode.contains(event.relatedTarget)) { + return; + } + + this.isActive = false; + this.sendUpdate(); + } + }, { + key: "destroy", + value: function destroy() { + this.options.element.removeEventListener('mousedown', this.mousedownHandler); + } + }]); + + return Menu; +}(); + +function MenuBubble (options) { + return new Plugin({ + key: new PluginKey('menu_bubble'), + view: function view(editorView) { + return new Menu$1({ + editorView: editorView, + options: options + }); + } + }); +} + +var EditorMenuBubble = { + props: { + editor: { + default: null, + type: Object + }, + keepInBounds: { + default: true, + type: Boolean + } + }, + data: function data() { + return { + menu: { + isActive: false, + left: 0, + bottom: 0 + } + }; + }, + watch: { + editor: { + immediate: true, + handler: function handler(editor) { + var _this = this; + + if (editor) { + this.$nextTick(function () { + editor.registerPlugin(MenuBubble({ + editor: editor, + element: _this.$el, + keepInBounds: _this.keepInBounds, + onUpdate: function onUpdate(menu) { + // the second check ensures event is fired only once + if (menu.isActive && _this.menu.isActive === false) { + _this.$emit('show', menu); + } else if (!menu.isActive && _this.menu.isActive === true) { + _this.$emit('hide', menu); + } + + _this.menu = menu; + } + })); + }); + } + } + } + }, + render: function render() { + if (!this.editor) { + return null; + } + + return this.$scopedSlots.default({ + focused: this.editor.view.focused, + focus: this.editor.focus, + commands: this.editor.commands, + isActive: this.editor.isActive, + getMarkAttrs: this.editor.getMarkAttrs.bind(this.editor), + menu: this.menu + }); + }, + beforeDestroy: function beforeDestroy() { + this.editor.unregisterPlugin('menu_bubble'); + } +}; + +var Menu$2 = +/*#__PURE__*/ +function () { + function Menu(_ref) { + var _this = this; + + var options = _ref.options, + editorView = _ref.editorView; + + _classCallCheck(this, Menu); + + this.options = _objectSpread2({}, { + resizeObserver: true, + element: null, + onUpdate: function onUpdate() { + return false; + } + }, {}, options); + this.preventHide = false; + this.editorView = editorView; + this.isActive = false; + this.top = 0; // the mousedown event is fired before blur so we can prevent it + + this.mousedownHandler = this.handleClick.bind(this); + this.options.element.addEventListener('mousedown', this.mousedownHandler); + this.options.editor.on('focus', function (_ref2) { + var view = _ref2.view; + + _this.update(view); + }); + this.options.editor.on('blur', function (_ref3) { + var event = _ref3.event; + + if (_this.preventHide) { + _this.preventHide = false; + return; + } + + _this.hide(event); + }); // sometimes we have to update the position + // because of a loaded images for example + + if (this.options.resizeObserver && window.ResizeObserver) { + this.resizeObserver = new ResizeObserver(function () { + if (_this.isActive) { + _this.update(_this.editorView); + } + }); + this.resizeObserver.observe(this.editorView.dom); + } + } + + _createClass(Menu, [{ + key: "handleClick", + value: function handleClick() { + this.preventHide = true; + } + }, { + key: "update", + value: function update(view, lastState) { + var state = view.state; // Don't do anything if the document/selection didn't change + + if (lastState && lastState.doc.eq(state.doc) && lastState.selection.eq(state.selection)) { + return; + } + + if (!state.selection.empty) { + this.hide(); + return; + } + + var currentDom = view.domAtPos(state.selection.anchor); + var isActive = currentDom.node.innerHTML === '
    ' && currentDom.node.tagName === 'P' && currentDom.node.parentNode === view.dom; + + if (!isActive) { + this.hide(); + return; + } + + var parent = this.options.element.offsetParent; + + if (!parent) { + this.hide(); + return; + } + + var editorBoundings = parent.getBoundingClientRect(); + var cursorBoundings = view.coordsAtPos(state.selection.anchor); + var top = cursorBoundings.top - editorBoundings.top; + this.isActive = true; + this.top = top; + this.sendUpdate(); + } + }, { + key: "sendUpdate", + value: function sendUpdate() { + this.options.onUpdate({ + isActive: this.isActive, + top: this.top + }); + } + }, { + key: "hide", + value: function hide(event) { + if (event && event.relatedTarget && this.options.element.parentNode.contains(event.relatedTarget)) { + return; + } + + this.isActive = false; + this.sendUpdate(); + } + }, { + key: "destroy", + value: function destroy() { + this.options.element.removeEventListener('mousedown', this.mousedownHandler); + + if (this.resizeObserver) { + this.resizeObserver.unobserve(this.editorView.dom); + } + } + }]); + + return Menu; +}(); + +function FloatingMenu (options) { + return new Plugin({ + key: new PluginKey('floating_menu'), + view: function view(editorView) { + return new Menu$2({ + editorView: editorView, + options: options + }); + } + }); +} + +var EditorFloatingMenu = { + props: { + editor: { + default: null, + type: Object + } + }, + data: function data() { + return { + menu: { + isActive: false, + left: 0, + bottom: 0 + } + }; + }, + watch: { + editor: { + immediate: true, + handler: function handler(editor) { + var _this = this; + + if (editor) { + this.$nextTick(function () { + editor.registerPlugin(FloatingMenu({ + editor: editor, + element: _this.$el, + onUpdate: function onUpdate(menu) { + // the second check ensures event is fired only once + if (menu.isActive && _this.menu.isActive === false) { + _this.$emit('show', menu); + } else if (!menu.isActive && _this.menu.isActive === true) { + _this.$emit('hide', menu); + } + + _this.menu = menu; + } + })); + }); + } + } + } + }, + render: function render() { + if (!this.editor) { + return null; + } + + return this.$scopedSlots.default({ + focused: this.editor.view.focused, + focus: this.editor.focus, + commands: this.editor.commands, + isActive: this.editor.isActive, + getMarkAttrs: this.editor.getMarkAttrs.bind(this.editor), + menu: this.menu + }); + }, + beforeDestroy: function beforeDestroy() { + this.editor.unregisterPlugin('floating_menu'); + } +}; + +export { Doc, Editor, EditorContent, EditorFloatingMenu, EditorMenuBar, EditorMenuBubble, Extension, Mark, Node, Paragraph, Text }; diff --git a/packages/tiptap/dist/tiptap.js b/packages/tiptap/dist/tiptap.js new file mode 100644 index 0000000000..07d38d62fa --- /dev/null +++ b/packages/tiptap/dist/tiptap.js @@ -0,0 +1,2177 @@ + + /*! + * tiptap v1.26.6 + * (c) 2020 Scrumpy UG (limited liability) + * @license MIT + */ + +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('prosemirror-state'), require('prosemirror-view'), require('prosemirror-model'), require('prosemirror-dropcursor'), require('prosemirror-gapcursor'), require('prosemirror-keymap'), require('prosemirror-commands'), require('prosemirror-inputrules'), require('tiptap-utils'), require('vue'), require('tiptap-commands')) : + typeof define === 'function' && define.amd ? define(['exports', 'prosemirror-state', 'prosemirror-view', 'prosemirror-model', 'prosemirror-dropcursor', 'prosemirror-gapcursor', 'prosemirror-keymap', 'prosemirror-commands', 'prosemirror-inputrules', 'tiptap-utils', 'vue', 'tiptap-commands'], factory) : + (global = global || self, factory(global.tiptap = {}, global.prosemirrorState, global.prosemirrorView, global.prosemirrorModel, global.prosemirrorDropcursor, global.prosemirrorGapcursor, global.prosemirrorKeymap, global.prosemirrorCommands, global.prosemirrorInputrules, global.tiptapUtils, global.Vue, global.tiptapCommands)); +}(this, (function (exports, prosemirrorState, prosemirrorView, prosemirrorModel, prosemirrorDropcursor, prosemirrorGapcursor, prosemirrorKeymap, prosemirrorCommands, prosemirrorInputrules, tiptapUtils, Vue, tiptapCommands) { 'use strict'; + + Vue = Vue && Vue.hasOwnProperty('default') ? Vue['default'] : Vue; + + function _typeof(obj) { + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { + _typeof = function (obj) { + return typeof obj; + }; + } else { + _typeof = function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; + }; + } + + return _typeof(obj); + } + + 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 _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 _slicedToArray(arr, i) { + return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); + } + + function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); + } + + function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } + } + + function _arrayWithHoles(arr) { + if (Array.isArray(arr)) return arr; + } + + function _iterableToArray(iter) { + if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); + } + + function _iterableToArrayLimit(arr, i) { + if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { + 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 _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); + } + + function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance"); + } + + function camelCase (str) { + return str.replace(/(?:^\w|[A-Z]|\b\w)/g, function (word, index) { + return index === 0 ? word.toLowerCase() : word.toUpperCase(); + }).replace(/\s+/g, ''); + } + + var ComponentView = + /*#__PURE__*/ + function () { + function ComponentView(component, _ref) { + var editor = _ref.editor, + extension = _ref.extension, + parent = _ref.parent, + node = _ref.node, + view = _ref.view, + decorations = _ref.decorations, + getPos = _ref.getPos; + + _classCallCheck(this, ComponentView); + + this.component = component; + this.editor = editor; + this.extension = extension; + this.parent = parent; + this.node = node; + this.view = view; + this.decorations = decorations; + this.isNode = !!this.node.marks; + this.isMark = !this.isNode; + this.getPos = this.isMark ? this.getMarkPos : getPos; + this.captureEvents = true; + this.dom = this.createDOM(); + this.contentDOM = this.vm.$refs.content; + } + + _createClass(ComponentView, [{ + key: "createDOM", + value: function createDOM() { + var _this = this; + + var Component = Vue.extend(this.component); + var props = { + editor: this.editor, + node: this.node, + view: this.view, + getPos: function getPos() { + return _this.getPos(); + }, + decorations: this.decorations, + selected: false, + options: this.extension.options, + updateAttrs: function updateAttrs(attrs) { + return _this.updateAttrs(attrs); + } + }; + + if (typeof this.extension.setSelection === 'function') { + this.setSelection = this.extension.setSelection; + } + + this.vm = new Component({ + parent: this.parent, + propsData: props + }).$mount(); + return this.vm.$el; + } + }, { + key: "update", + value: function update(node, decorations) { + if (node.type !== this.node.type) { + return false; + } + + if (node === this.node && this.decorations === decorations) { + return true; + } + + this.node = node; + this.decorations = decorations; + this.updateComponentProps({ + node: node, + decorations: decorations + }); + return true; + } + }, { + key: "updateComponentProps", + value: function updateComponentProps(props) { + var _this2 = this; + + if (!this.vm._props) { + return; + } // Update props in component + // TODO: Avoid mutating a prop directly. + // Maybe there is a better way to do this? + + + var originalSilent = Vue.config.silent; + Vue.config.silent = true; + Object.entries(props).forEach(function (_ref2) { + var _ref3 = _slicedToArray(_ref2, 2), + key = _ref3[0], + value = _ref3[1]; + + _this2.vm._props[key] = value; + }); // this.vm._props.node = node + // this.vm._props.decorations = decorations + + Vue.config.silent = originalSilent; + } + }, { + key: "updateAttrs", + value: function updateAttrs(attrs) { + if (!this.view.editable) { + return; + } + + var state = this.view.state; + var type = this.node.type; + var pos = this.getPos(); + + var newAttrs = _objectSpread2({}, this.node.attrs, {}, attrs); + + var transaction = this.isMark ? state.tr.removeMark(pos.from, pos.to, type).addMark(pos.from, pos.to, type.create(newAttrs)) : state.tr.setNodeMarkup(pos, null, newAttrs); + this.view.dispatch(transaction); + } // prevent a full re-render of the vue component on update + // we'll handle prop updates in `update()` + + }, { + key: "ignoreMutation", + value: function ignoreMutation(mutation) { + // allow leaf nodes to be selected + if (mutation.type === 'selection') { + return false; + } + + if (!this.contentDOM) { + return true; + } + + return !this.contentDOM.contains(mutation.target); + } // disable (almost) all prosemirror event listener for node views + + }, { + key: "stopEvent", + value: function stopEvent(event) { + var _this3 = this; + + if (typeof this.extension.stopEvent === 'function') { + return this.extension.stopEvent(event); + } + + var draggable = !!this.extension.schema.draggable; // support a custom drag handle + + if (draggable && event.type === 'mousedown') { + var dragHandle = event.target.closest && event.target.closest('[data-drag-handle]'); + var isValidDragHandle = dragHandle && (this.dom === dragHandle || this.dom.contains(dragHandle)); + + if (isValidDragHandle) { + this.captureEvents = false; + document.addEventListener('dragend', function () { + _this3.captureEvents = true; + }, { + once: true + }); + } + } + + var isCopy = event.type === 'copy'; + var isPaste = event.type === 'paste'; + var isCut = event.type === 'cut'; + var isDrag = event.type.startsWith('drag') || event.type === 'drop'; + + if (draggable && isDrag || isCopy || isPaste || isCut) { + return false; + } + + return this.captureEvents; + } + }, { + key: "selectNode", + value: function selectNode() { + this.updateComponentProps({ + selected: true + }); + } + }, { + key: "deselectNode", + value: function deselectNode() { + this.updateComponentProps({ + selected: false + }); + } + }, { + key: "getMarkPos", + value: function getMarkPos() { + var pos = this.view.posAtDOM(this.dom); + var resolvedPos = this.view.state.doc.resolve(pos); + var range = tiptapUtils.getMarkRange(resolvedPos, this.node.type); + return range; + } + }, { + key: "destroy", + value: function destroy() { + this.vm.$destroy(); + } + }]); + + return ComponentView; + }(); + + var Emitter = + /*#__PURE__*/ + function () { + function Emitter() { + _classCallCheck(this, Emitter); + } + + _createClass(Emitter, [{ + key: "on", + // Add an event listener for given event + value: function on(event, fn) { + this._callbacks = this._callbacks || {}; // Create namespace for this event + + if (!this._callbacks[event]) { + this._callbacks[event] = []; + } + + this._callbacks[event].push(fn); + + return this; + } + }, { + key: "emit", + value: function emit(event) { + var _this = this; + + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + this._callbacks = this._callbacks || {}; + var callbacks = this._callbacks[event]; + + if (callbacks) { + callbacks.forEach(function (callback) { + return callback.apply(_this, args); + }); + } + + return this; + } // Remove event listener for given event. + // If fn is not provided, all event listeners for that event will be removed. + // If neither is provided, all event listeners will be removed. + + }, { + key: "off", + value: function off(event, fn) { + if (!arguments.length) { + this._callbacks = {}; + } else { + // event listeners for the given event + var callbacks = this._callbacks ? this._callbacks[event] : null; + + if (callbacks) { + if (fn) { + this._callbacks[event] = callbacks.filter(function (cb) { + return cb !== fn; + }); // remove specific handler + } else { + delete this._callbacks[event]; // remove all handlers + } + } + } + + return this; + } + }]); + + return Emitter; + }(); + + var Extension = + /*#__PURE__*/ + function () { + function Extension() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, Extension); + + this.options = _objectSpread2({}, this.defaultOptions, {}, options); + } + + _createClass(Extension, [{ + key: "init", + value: function init() { + return null; + } + }, { + key: "bindEditor", + value: function bindEditor() { + var editor = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + this.editor = editor; + } + }, { + key: "inputRules", + value: function inputRules() { + return []; + } + }, { + key: "pasteRules", + value: function pasteRules() { + return []; + } + }, { + key: "keys", + value: function keys() { + return {}; + } + }, { + key: "name", + get: function get() { + return null; + } + }, { + key: "type", + get: function get() { + return 'extension'; + } + }, { + key: "update", + get: function get() { + return function () {}; + } + }, { + key: "defaultOptions", + get: function get() { + return {}; + } + }, { + key: "plugins", + get: function get() { + return []; + } + }]); + + return Extension; + }(); + + var ExtensionManager = + /*#__PURE__*/ + function () { + function ExtensionManager() { + var extensions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + var editor = arguments.length > 1 ? arguments[1] : undefined; + + _classCallCheck(this, ExtensionManager); + + extensions.forEach(function (extension) { + extension.bindEditor(editor); + extension.init(); + }); + this.extensions = extensions; + } + + _createClass(ExtensionManager, [{ + key: "keymaps", + value: function keymaps(_ref) { + var schema = _ref.schema; + var extensionKeymaps = this.extensions.filter(function (extension) { + return ['extension'].includes(extension.type); + }).filter(function (extension) { + return extension.keys; + }).map(function (extension) { + return extension.keys({ + schema: schema + }); + }); + var nodeMarkKeymaps = this.extensions.filter(function (extension) { + return ['node', 'mark'].includes(extension.type); + }).filter(function (extension) { + return extension.keys; + }).map(function (extension) { + return extension.keys({ + type: schema["".concat(extension.type, "s")][extension.name], + schema: schema + }); + }); + return [].concat(_toConsumableArray(extensionKeymaps), _toConsumableArray(nodeMarkKeymaps)).map(function (keys) { + return prosemirrorKeymap.keymap(keys); + }); + } + }, { + key: "inputRules", + value: function inputRules(_ref2) { + var schema = _ref2.schema, + excludedExtensions = _ref2.excludedExtensions; + if (!(excludedExtensions instanceof Array) && excludedExtensions) return []; + var allowedExtensions = excludedExtensions instanceof Array ? this.extensions.filter(function (extension) { + return !excludedExtensions.includes(extension.name); + }) : this.extensions; + var extensionInputRules = allowedExtensions.filter(function (extension) { + return ['extension'].includes(extension.type); + }).filter(function (extension) { + return extension.inputRules; + }).map(function (extension) { + return extension.inputRules({ + schema: schema + }); + }); + var nodeMarkInputRules = allowedExtensions.filter(function (extension) { + return ['node', 'mark'].includes(extension.type); + }).filter(function (extension) { + return extension.inputRules; + }).map(function (extension) { + return extension.inputRules({ + type: schema["".concat(extension.type, "s")][extension.name], + schema: schema + }); + }); + return [].concat(_toConsumableArray(extensionInputRules), _toConsumableArray(nodeMarkInputRules)).reduce(function (allInputRules, inputRules) { + return [].concat(_toConsumableArray(allInputRules), _toConsumableArray(inputRules)); + }, []); + } + }, { + key: "pasteRules", + value: function pasteRules(_ref3) { + var schema = _ref3.schema, + excludedExtensions = _ref3.excludedExtensions; + if (!(excludedExtensions instanceof Array) && excludedExtensions) return []; + var allowedExtensions = excludedExtensions instanceof Array ? this.extensions.filter(function (extension) { + return !excludedExtensions.includes(extension.name); + }) : this.extensions; + var extensionPasteRules = allowedExtensions.filter(function (extension) { + return ['extension'].includes(extension.type); + }).filter(function (extension) { + return extension.pasteRules; + }).map(function (extension) { + return extension.pasteRules({ + schema: schema + }); + }); + var nodeMarkPasteRules = allowedExtensions.filter(function (extension) { + return ['node', 'mark'].includes(extension.type); + }).filter(function (extension) { + return extension.pasteRules; + }).map(function (extension) { + return extension.pasteRules({ + type: schema["".concat(extension.type, "s")][extension.name], + schema: schema + }); + }); + return [].concat(_toConsumableArray(extensionPasteRules), _toConsumableArray(nodeMarkPasteRules)).reduce(function (allPasteRules, pasteRules) { + return [].concat(_toConsumableArray(allPasteRules), _toConsumableArray(pasteRules)); + }, []); + } + }, { + key: "commands", + value: function commands(_ref4) { + var schema = _ref4.schema, + view = _ref4.view; + return this.extensions.filter(function (extension) { + return extension.commands; + }).reduce(function (allCommands, extension) { + var name = extension.name, + type = extension.type; + var commands = {}; + var value = extension.commands(_objectSpread2({ + schema: schema + }, ['node', 'mark'].includes(type) ? { + type: schema["".concat(type, "s")][name] + } : {})); + + var apply = function apply(cb, attrs) { + if (!view.editable) { + return false; + } + + view.focus(); + return cb(attrs)(view.state, view.dispatch, view); + }; + + var handle = function handle(_name, _value) { + if (Array.isArray(_value)) { + commands[_name] = function (attrs) { + return _value.forEach(function (callback) { + return apply(callback, attrs); + }); + }; + } else if (typeof _value === 'function') { + commands[_name] = function (attrs) { + return apply(_value, attrs); + }; + } + }; + + if (_typeof(value) === 'object') { + Object.entries(value).forEach(function (_ref5) { + var _ref6 = _slicedToArray(_ref5, 2), + commandName = _ref6[0], + commandValue = _ref6[1]; + + handle(commandName, commandValue); + }); + } else { + handle(name, value); + } + + return _objectSpread2({}, allCommands, {}, commands); + }, {}); + } + }, { + key: "nodes", + get: function get() { + return this.extensions.filter(function (extension) { + return extension.type === 'node'; + }).reduce(function (nodes, _ref7) { + var name = _ref7.name, + schema = _ref7.schema; + return _objectSpread2({}, nodes, _defineProperty({}, name, schema)); + }, {}); + } + }, { + key: "options", + get: function get() { + var view = this.view; + return this.extensions.reduce(function (nodes, extension) { + return _objectSpread2({}, nodes, _defineProperty({}, extension.name, new Proxy(extension.options, { + set: function set(obj, prop, value) { + var changed = obj[prop] !== value; + Object.assign(obj, _defineProperty({}, prop, value)); + + if (changed) { + extension.update(view); + } + + return true; + } + }))); + }, {}); + } + }, { + key: "marks", + get: function get() { + return this.extensions.filter(function (extension) { + return extension.type === 'mark'; + }).reduce(function (marks, _ref8) { + var name = _ref8.name, + schema = _ref8.schema; + return _objectSpread2({}, marks, _defineProperty({}, name, schema)); + }, {}); + } + }, { + key: "plugins", + get: function get() { + return this.extensions.filter(function (extension) { + return extension.plugins; + }).reduce(function (allPlugins, _ref9) { + var plugins = _ref9.plugins; + return [].concat(_toConsumableArray(allPlugins), _toConsumableArray(plugins)); + }, []); + } + }]); + + return ExtensionManager; + }(); + + function injectCSS (css) { + { + var style = document.createElement('style'); + style.type = 'text/css'; + style.textContent = css; + var _document = document, + head = _document.head; + var firstChild = head.firstChild; + + if (firstChild) { + head.insertBefore(style, firstChild); + } else { + head.appendChild(style); + } + } + } + + var Mark = + /*#__PURE__*/ + function (_Extension) { + _inherits(Mark, _Extension); + + function Mark() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, Mark); + + return _possibleConstructorReturn(this, _getPrototypeOf(Mark).call(this, options)); + } + + _createClass(Mark, [{ + key: "command", + value: function command() { + return function () {}; + } + }, { + key: "type", + get: function get() { + return 'mark'; + } + }, { + key: "view", + get: function get() { + return null; + } + }, { + key: "schema", + get: function get() { + return null; + } + }]); + + return Mark; + }(Extension); + + function minMax() { + var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + var min = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + var max = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + return Math.min(Math.max(parseInt(value, 10), min), max); + } + + var Node = + /*#__PURE__*/ + function (_Extension) { + _inherits(Node, _Extension); + + function Node() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, Node); + + return _possibleConstructorReturn(this, _getPrototypeOf(Node).call(this, options)); + } + + _createClass(Node, [{ + key: "command", + value: function command() { + return function () {}; + } + }, { + key: "type", + get: function get() { + return 'node'; + } + }, { + key: "view", + get: function get() { + return null; + } + }, { + key: "schema", + get: function get() { + return null; + } + }]); + + return Node; + }(Extension); + + var Doc = + /*#__PURE__*/ + function (_Node) { + _inherits(Doc, _Node); + + function Doc() { + _classCallCheck(this, Doc); + + return _possibleConstructorReturn(this, _getPrototypeOf(Doc).apply(this, arguments)); + } + + _createClass(Doc, [{ + key: "name", + get: function get() { + return 'doc'; + } + }, { + key: "schema", + get: function get() { + return { + content: 'block+' + }; + } + }]); + + return Doc; + }(Node); + + var Paragraph = + /*#__PURE__*/ + function (_Node) { + _inherits(Paragraph, _Node); + + function Paragraph() { + _classCallCheck(this, Paragraph); + + return _possibleConstructorReturn(this, _getPrototypeOf(Paragraph).apply(this, arguments)); + } + + _createClass(Paragraph, [{ + key: "commands", + value: function commands(_ref) { + var type = _ref.type; + return function () { + return tiptapCommands.setBlockType(type); + }; + } + }, { + key: "name", + get: function get() { + return 'paragraph'; + } + }, { + key: "schema", + get: function get() { + return { + content: 'inline*', + group: 'block', + draggable: false, + parseDOM: [{ + tag: 'p' + }], + toDOM: function toDOM() { + return ['p', 0]; + } + }; + } + }]); + + return Paragraph; + }(Node); + + var Text = + /*#__PURE__*/ + function (_Node) { + _inherits(Text, _Node); + + function Text() { + _classCallCheck(this, Text); + + return _possibleConstructorReturn(this, _getPrototypeOf(Text).apply(this, arguments)); + } + + _createClass(Text, [{ + key: "name", + get: function get() { + return 'text'; + } + }, { + key: "schema", + get: function get() { + return { + group: 'inline' + }; + } + }]); + + return Text; + }(Node); + + var css = ".ProseMirror {\n position: relative;\n}\n\n.ProseMirror {\n word-wrap: break-word;\n white-space: pre-wrap;\n -webkit-font-variant-ligatures: none;\n font-variant-ligatures: none;\n}\n\n.ProseMirror pre {\n white-space: pre-wrap;\n}\n\n.ProseMirror-gapcursor {\n display: none;\n pointer-events: none;\n position: absolute;\n}\n\n.ProseMirror-gapcursor:after {\n content: \"\";\n display: block;\n position: absolute;\n top: -2px;\n width: 20px;\n border-top: 1px solid black;\n animation: ProseMirror-cursor-blink 1.1s steps(2, start) infinite;\n}\n\n@keyframes ProseMirror-cursor-blink {\n to {\n visibility: hidden;\n }\n}\n\n.ProseMirror-hideselection *::selection {\n background: transparent;\n}\n\n.ProseMirror-hideselection *::-moz-selection {\n background: transparent;\n}\n\n.ProseMirror-hideselection * {\n caret-color: transparent;\n}\n\n.ProseMirror-focused .ProseMirror-gapcursor {\n display: block;\n}\n"; + + var Editor = + /*#__PURE__*/ + function (_Emitter) { + _inherits(Editor, _Emitter); + + function Editor() { + var _this; + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, Editor); + + _this = _possibleConstructorReturn(this, _getPrototypeOf(Editor).call(this)); + _this.defaultOptions = { + editorProps: {}, + editable: true, + autoFocus: null, + extensions: [], + content: '', + topNode: 'doc', + emptyDocument: { + type: 'doc', + content: [{ + type: 'paragraph' + }] + }, + useBuiltInExtensions: true, + disableInputRules: false, + disablePasteRules: false, + dropCursor: {}, + parseOptions: {}, + injectCSS: true, + onInit: function onInit() {}, + onTransaction: function onTransaction() {}, + onUpdate: function onUpdate() {}, + onFocus: function onFocus() {}, + onBlur: function onBlur() {}, + onPaste: function onPaste() {}, + onDrop: function onDrop() {} + }; + _this.events = ['init', 'transaction', 'update', 'focus', 'blur', 'paste', 'drop']; + + _this.init(options); + + return _this; + } + + _createClass(Editor, [{ + key: "init", + value: function init() { + var _this2 = this; + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + this.setOptions(_objectSpread2({}, this.defaultOptions, {}, options)); + this.focused = false; + this.selection = { + from: 0, + to: 0 + }; + this.element = document.createElement('div'); + this.extensions = this.createExtensions(); + this.nodes = this.createNodes(); + this.marks = this.createMarks(); + this.schema = this.createSchema(); + this.plugins = this.createPlugins(); + this.keymaps = this.createKeymaps(); + this.inputRules = this.createInputRules(); + this.pasteRules = this.createPasteRules(); + this.view = this.createView(); + this.commands = this.createCommands(); + this.setActiveNodesAndMarks(); + + if (this.options.injectCSS) { + injectCSS(css); + } + + if (this.options.autoFocus !== null) { + this.focus(this.options.autoFocus); + } + + this.events.forEach(function (name) { + _this2.on(name, _this2.options[camelCase("on ".concat(name))] || function () {}); + }); + this.emit('init', { + view: this.view, + state: this.state + }); // give extension manager access to our view + + this.extensions.view = this.view; + } + }, { + key: "setOptions", + value: function setOptions(options) { + this.options = _objectSpread2({}, this.options, {}, options); + + if (this.view && this.state) { + this.view.updateState(this.state); + } + } + }, { + key: "createExtensions", + value: function createExtensions() { + return new ExtensionManager([].concat(_toConsumableArray(this.builtInExtensions), _toConsumableArray(this.options.extensions)), this); + } + }, { + key: "createPlugins", + value: function createPlugins() { + return this.extensions.plugins; + } + }, { + key: "createKeymaps", + value: function createKeymaps() { + return this.extensions.keymaps({ + schema: this.schema + }); + } + }, { + key: "createInputRules", + value: function createInputRules() { + return this.extensions.inputRules({ + schema: this.schema, + excludedExtensions: this.options.disableInputRules + }); + } + }, { + key: "createPasteRules", + value: function createPasteRules() { + return this.extensions.pasteRules({ + schema: this.schema, + excludedExtensions: this.options.disablePasteRules + }); + } + }, { + key: "createCommands", + value: function createCommands() { + return this.extensions.commands({ + schema: this.schema, + view: this.view + }); + } + }, { + key: "createNodes", + value: function createNodes() { + return this.extensions.nodes; + } + }, { + key: "createMarks", + value: function createMarks() { + return this.extensions.marks; + } + }, { + key: "createSchema", + value: function createSchema() { + return new prosemirrorModel.Schema({ + topNode: this.options.topNode, + nodes: this.nodes, + marks: this.marks + }); + } + }, { + key: "createState", + value: function createState() { + var _this3 = this; + + return prosemirrorState.EditorState.create({ + schema: this.schema, + doc: this.createDocument(this.options.content), + plugins: [].concat(_toConsumableArray(this.plugins), [prosemirrorInputrules.inputRules({ + rules: this.inputRules + })], _toConsumableArray(this.pasteRules), _toConsumableArray(this.keymaps), [prosemirrorKeymap.keymap({ + Backspace: prosemirrorInputrules.undoInputRule + }), prosemirrorKeymap.keymap(prosemirrorCommands.baseKeymap), prosemirrorDropcursor.dropCursor(this.options.dropCursor), prosemirrorGapcursor.gapCursor(), new prosemirrorState.Plugin({ + key: new prosemirrorState.PluginKey('editable'), + props: { + editable: function editable() { + return _this3.options.editable; + } + } + }), new prosemirrorState.Plugin({ + props: { + attributes: { + tabindex: 0 + }, + handleDOMEvents: { + focus: function focus(view, event) { + _this3.focused = true; + + _this3.emit('focus', { + event: event, + state: view.state, + view: view + }); + + var transaction = _this3.state.tr.setMeta('focused', true); + + _this3.view.dispatch(transaction); + }, + blur: function blur(view, event) { + _this3.focused = false; + + _this3.emit('blur', { + event: event, + state: view.state, + view: view + }); + + var transaction = _this3.state.tr.setMeta('focused', false); + + _this3.view.dispatch(transaction); + } + } + } + }), new prosemirrorState.Plugin({ + props: this.options.editorProps + })]) + }); + } + }, { + key: "createDocument", + value: function createDocument(content) { + var parseOptions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.options.parseOptions; + + if (content === null) { + return this.schema.nodeFromJSON(this.options.emptyDocument); + } + + if (_typeof(content) === 'object') { + try { + return this.schema.nodeFromJSON(content); + } catch (error) { + console.warn('[tiptap warn]: Invalid content.', 'Passed value:', content, 'Error:', error); + return this.schema.nodeFromJSON(this.options.emptyDocument); + } + } + + if (typeof content === 'string') { + var element = document.createElement('div'); + element.innerHTML = content.trim(); + return prosemirrorModel.DOMParser.fromSchema(this.schema).parse(element, parseOptions); + } + + return false; + } + }, { + key: "createView", + value: function createView() { + var _this4 = this; + + return new prosemirrorView.EditorView(this.element, { + state: this.createState(), + handlePaste: function handlePaste() { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + _this4.emit.apply(_this4, ['paste'].concat(args)); + }, + handleDrop: function handleDrop() { + for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } + + _this4.emit.apply(_this4, ['drop'].concat(args)); + }, + dispatchTransaction: this.dispatchTransaction.bind(this) + }); + } + }, { + key: "setParentComponent", + value: function setParentComponent() { + var component = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + + if (!component) { + return; + } + + this.view.setProps({ + nodeViews: this.initNodeViews({ + parent: component, + extensions: [].concat(_toConsumableArray(this.builtInExtensions), _toConsumableArray(this.options.extensions)) + }) + }); + } + }, { + key: "initNodeViews", + value: function initNodeViews(_ref) { + var _this5 = this; + + var parent = _ref.parent, + extensions = _ref.extensions; + return extensions.filter(function (extension) { + return ['node', 'mark'].includes(extension.type); + }).filter(function (extension) { + return extension.view; + }).reduce(function (nodeViews, extension) { + var nodeView = function nodeView(node, view, getPos, decorations) { + var component = extension.view; + return new ComponentView(component, { + editor: _this5, + extension: extension, + parent: parent, + node: node, + view: view, + getPos: getPos, + decorations: decorations + }); + }; + + return _objectSpread2({}, nodeViews, _defineProperty({}, extension.name, nodeView)); + }, {}); + } + }, { + key: "dispatchTransaction", + value: function dispatchTransaction(transaction) { + var newState = this.state.apply(transaction); + this.view.updateState(newState); + this.selection = { + from: this.state.selection.from, + to: this.state.selection.to + }; + this.setActiveNodesAndMarks(); + this.emit('transaction', { + getHTML: this.getHTML.bind(this), + getJSON: this.getJSON.bind(this), + state: this.state, + transaction: transaction + }); + + if (!transaction.docChanged || transaction.getMeta('preventUpdate')) { + return; + } + + this.emitUpdate(transaction); + } + }, { + key: "emitUpdate", + value: function emitUpdate(transaction) { + this.emit('update', { + getHTML: this.getHTML.bind(this), + getJSON: this.getJSON.bind(this), + state: this.state, + transaction: transaction + }); + } + }, { + key: "resolveSelection", + value: function resolveSelection() { + var position = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + + if (this.selection && position === null) { + return this.selection; + } + + if (position === 'start' || position === true) { + return { + from: 0, + to: 0 + }; + } + + if (position === 'end') { + var doc = this.state.doc; + return { + from: doc.content.size, + to: doc.content.size + }; + } + + return { + from: position, + to: position + }; + } + }, { + key: "focus", + value: function focus() { + var _this6 = this; + + var position = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + + if (this.view.focused && position === null || position === false) { + return; + } + + var _this$resolveSelectio = this.resolveSelection(position), + from = _this$resolveSelectio.from, + to = _this$resolveSelectio.to; + + this.setSelection(from, to); + setTimeout(function () { + return _this6.view.focus(); + }, 10); + } + }, { + key: "setSelection", + value: function setSelection() { + var from = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + var to = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + var _this$state = this.state, + doc = _this$state.doc, + tr = _this$state.tr; + var resolvedFrom = minMax(from, 0, doc.content.size); + var resolvedEnd = minMax(to, 0, doc.content.size); + var selection = prosemirrorState.TextSelection.create(doc, resolvedFrom, resolvedEnd); + var transaction = tr.setSelection(selection); + this.view.dispatch(transaction); + } + }, { + key: "blur", + value: function blur() { + this.view.dom.blur(); + } + }, { + key: "getSchemaJSON", + value: function getSchemaJSON() { + return JSON.parse(JSON.stringify({ + nodes: this.extensions.nodes, + marks: this.extensions.marks + })); + } + }, { + key: "getHTML", + value: function getHTML() { + var div = document.createElement('div'); + var fragment = prosemirrorModel.DOMSerializer.fromSchema(this.schema).serializeFragment(this.state.doc.content); + div.appendChild(fragment); + return div.innerHTML; + } + }, { + key: "getJSON", + value: function getJSON() { + return this.state.doc.toJSON(); + } + }, { + key: "setContent", + value: function setContent() { + var content = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var emitUpdate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + var parseOptions = arguments.length > 2 ? arguments[2] : undefined; + var _this$state2 = this.state, + doc = _this$state2.doc, + tr = _this$state2.tr; + var document = this.createDocument(content, parseOptions); + var selection = prosemirrorState.TextSelection.create(doc, 0, doc.content.size); + var transaction = tr.setSelection(selection).replaceSelectionWith(document, false).setMeta('preventUpdate', !emitUpdate); + this.view.dispatch(transaction); + } + }, { + key: "clearContent", + value: function clearContent() { + var emitUpdate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + this.setContent(this.options.emptyDocument, emitUpdate); + } + }, { + key: "setActiveNodesAndMarks", + value: function setActiveNodesAndMarks() { + var _this7 = this; + + this.activeMarks = Object.entries(this.schema.marks).reduce(function (marks, _ref2) { + var _ref3 = _slicedToArray(_ref2, 2), + name = _ref3[0], + mark = _ref3[1]; + + return _objectSpread2({}, marks, _defineProperty({}, name, function () { + var attrs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + return tiptapUtils.markIsActive(_this7.state, mark, attrs); + })); + }, {}); + this.activeMarkAttrs = Object.entries(this.schema.marks).reduce(function (marks, _ref4) { + var _ref5 = _slicedToArray(_ref4, 2), + name = _ref5[0], + mark = _ref5[1]; + + return _objectSpread2({}, marks, _defineProperty({}, name, tiptapUtils.getMarkAttrs(_this7.state, mark))); + }, {}); + this.activeNodes = Object.entries(this.schema.nodes).reduce(function (nodes, _ref6) { + var _ref7 = _slicedToArray(_ref6, 2), + name = _ref7[0], + node = _ref7[1]; + + return _objectSpread2({}, nodes, _defineProperty({}, name, function () { + var attrs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + return tiptapUtils.nodeIsActive(_this7.state, node, attrs); + })); + }, {}); + } + }, { + key: "getMarkAttrs", + value: function getMarkAttrs() { + var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + return this.activeMarkAttrs[type]; + } + }, { + key: "registerPlugin", + value: function registerPlugin() { + var plugin = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + + if (!plugin) { + return; + } + + var newState = this.state.reconfigure({ + plugins: this.state.plugins.concat([plugin]) + }); + this.view.updateState(newState); + } + }, { + key: "unregisterPlugin", + value: function unregisterPlugin() { + var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + + if (!name || !this.view.docView) { + return; + } + + var newState = this.state.reconfigure({ + plugins: this.state.plugins.filter(function (plugin) { + return !plugin.key.startsWith("".concat(name, "$")); + }) + }); + this.view.updateState(newState); + } + }, { + key: "destroy", + value: function destroy() { + if (!this.view) { + return; + } + + this.view.destroy(); + } + }, { + key: "builtInExtensions", + get: function get() { + if (!this.options.useBuiltInExtensions) { + return []; + } + + return [new Doc(), new Text(), new Paragraph()]; + } + }, { + key: "state", + get: function get() { + return this.view ? this.view.state : null; + } + }, { + key: "isActive", + get: function get() { + return Object.entries(_objectSpread2({}, this.activeMarks, {}, this.activeNodes)).reduce(function (types, _ref8) { + var _ref9 = _slicedToArray(_ref8, 2), + name = _ref9[0], + value = _ref9[1]; + + return _objectSpread2({}, types, _defineProperty({}, name, function () { + var attrs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + return value(attrs); + })); + }, {}); + } + }]); + + return Editor; + }(Emitter); + + var EditorContent = { + props: { + editor: { + default: null, + type: Object + } + }, + watch: { + editor: { + immediate: true, + handler: function handler(editor) { + var _this = this; + + if (editor && editor.element) { + this.$nextTick(function () { + _this.$el.appendChild(editor.element.firstChild); + + editor.setParentComponent(_this); + }); + } + } + } + }, + render: function render(createElement) { + return createElement('div'); + }, + beforeDestroy: function beforeDestroy() { + this.editor.element = this.$el; + } + }; + + var Menu = + /*#__PURE__*/ + function () { + function Menu(_ref) { + var _this = this; + + var options = _ref.options; + + _classCallCheck(this, Menu); + + this.options = options; + this.preventHide = false; // the mousedown event is fired before blur so we can prevent it + + this.mousedownHandler = this.handleClick.bind(this); + this.options.element.addEventListener('mousedown', this.mousedownHandler); + this.options.editor.on('blur', function () { + if (_this.preventHide) { + _this.preventHide = false; + return; + } + + _this.options.editor.emit('menubar:focusUpdate', false); + }); + } + + _createClass(Menu, [{ + key: "handleClick", + value: function handleClick() { + this.preventHide = true; + } + }, { + key: "destroy", + value: function destroy() { + this.options.element.removeEventListener('mousedown', this.mousedownHandler); + } + }]); + + return Menu; + }(); + + function MenuBar (options) { + return new prosemirrorState.Plugin({ + key: new prosemirrorState.PluginKey('menu_bar'), + view: function view(editorView) { + return new Menu({ + editorView: editorView, + options: options + }); + } + }); + } + + var EditorMenuBar = { + props: { + editor: { + default: null, + type: Object + } + }, + data: function data() { + return { + focused: false + }; + }, + watch: { + editor: { + immediate: true, + handler: function handler(editor) { + var _this = this; + + if (editor) { + this.$nextTick(function () { + editor.registerPlugin(MenuBar({ + editor: editor, + element: _this.$el + })); + _this.focused = editor.focused; + editor.on('focus', function () { + _this.focused = true; + }); + editor.on('menubar:focusUpdate', function (focused) { + _this.focused = focused; + }); + }); + } + } + } + }, + render: function render() { + if (!this.editor) { + return null; + } + + return this.$scopedSlots.default({ + focused: this.focused, + focus: this.editor.focus, + commands: this.editor.commands, + isActive: this.editor.isActive, + getMarkAttrs: this.editor.getMarkAttrs.bind(this.editor) + }); + } + }; + + function textRange(node, from, to) { + var range = document.createRange(); + range.setEnd(node, to == null ? node.nodeValue.length : to); + range.setStart(node, from || 0); + return range; + } + + function singleRect(object, bias) { + var rects = object.getClientRects(); + return !rects.length ? object.getBoundingClientRect() : rects[bias < 0 ? 0 : rects.length - 1]; + } + + function coordsAtPos(view, pos) { + var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + + var _view$docView$domFrom = view.docView.domFromPos(pos), + node = _view$docView$domFrom.node, + offset = _view$docView$domFrom.offset; + + var side; + var rect; + + if (node.nodeType === 3) { + if (end && offset < node.nodeValue.length) { + rect = singleRect(textRange(node, offset - 1, offset), -1); + side = 'right'; + } else if (offset < node.nodeValue.length) { + rect = singleRect(textRange(node, offset, offset + 1), -1); + side = 'left'; + } + } else if (node.firstChild) { + if (offset < node.childNodes.length) { + var child = node.childNodes[offset]; + rect = singleRect(child.nodeType === 3 ? textRange(child) : child, -1); + side = 'left'; + } + + if ((!rect || rect.top === rect.bottom) && offset) { + var _child = node.childNodes[offset - 1]; + rect = singleRect(_child.nodeType === 3 ? textRange(_child) : _child, 1); + side = 'right'; + } + } else { + rect = node.getBoundingClientRect(); + side = 'left'; + } + + var x = rect[side]; + return { + top: rect.top, + bottom: rect.bottom, + left: x, + right: x + }; + } + + var Menu$1 = + /*#__PURE__*/ + function () { + function Menu(_ref) { + var _this = this; + + var options = _ref.options, + editorView = _ref.editorView; + + _classCallCheck(this, Menu); + + this.options = _objectSpread2({}, { + element: null, + keepInBounds: true, + onUpdate: function onUpdate() { + return false; + } + }, {}, options); + this.editorView = editorView; + this.isActive = false; + this.left = 0; + this.bottom = 0; + this.top = 0; + this.preventHide = false; // the mousedown event is fired before blur so we can prevent it + + this.mousedownHandler = this.handleClick.bind(this); + this.options.element.addEventListener('mousedown', this.mousedownHandler); + this.options.editor.on('focus', function (_ref2) { + var view = _ref2.view; + + _this.update(view); + }); + this.options.editor.on('blur', function (_ref3) { + var event = _ref3.event; + + if (_this.preventHide) { + _this.preventHide = false; + return; + } + + _this.hide(event); + }); + } + + _createClass(Menu, [{ + key: "handleClick", + value: function handleClick() { + this.preventHide = true; + } + }, { + key: "update", + value: function update(view, lastState) { + var state = view.state; + + if (view.composing) { + return; + } // Don't do anything if the document/selection didn't change + + + if (lastState && lastState.doc.eq(state.doc) && lastState.selection.eq(state.selection)) { + return; + } // Hide the tooltip if the selection is empty + + + if (state.selection.empty) { + this.hide(); + return; + } // Otherwise, reposition it and update its content + + + var _state$selection = state.selection, + from = _state$selection.from, + to = _state$selection.to; // These are in screen coordinates + // We can't use EditorView.cordsAtPos here because it can't handle linebreaks correctly + // See: https://github.com/ProseMirror/prosemirror-view/pull/47 + + var start = coordsAtPos(view, from); + var end = coordsAtPos(view, to, true); // The box in which the tooltip is positioned, to use as base + + var parent = this.options.element.offsetParent; + + if (!parent) { + this.hide(); + return; + } + + var box = parent.getBoundingClientRect(); + var el = this.options.element.getBoundingClientRect(); // Find a center-ish x position from the selection endpoints (when + // crossing lines, end may be more to the left) + + var left = (start.left + end.left) / 2 - box.left; // Keep the menuBubble in the bounding box of the offsetParent i + + this.left = Math.round(this.options.keepInBounds ? Math.min(box.width - el.width / 2, Math.max(left, el.width / 2)) : left); + this.bottom = Math.round(box.bottom - start.top); + this.top = Math.round(end.bottom - box.top); + this.isActive = true; + this.sendUpdate(); + } + }, { + key: "sendUpdate", + value: function sendUpdate() { + this.options.onUpdate({ + isActive: this.isActive, + left: this.left, + bottom: this.bottom, + top: this.top + }); + } + }, { + key: "hide", + value: function hide(event) { + if (event && event.relatedTarget && this.options.element.parentNode.contains(event.relatedTarget)) { + return; + } + + this.isActive = false; + this.sendUpdate(); + } + }, { + key: "destroy", + value: function destroy() { + this.options.element.removeEventListener('mousedown', this.mousedownHandler); + } + }]); + + return Menu; + }(); + + function MenuBubble (options) { + return new prosemirrorState.Plugin({ + key: new prosemirrorState.PluginKey('menu_bubble'), + view: function view(editorView) { + return new Menu$1({ + editorView: editorView, + options: options + }); + } + }); + } + + var EditorMenuBubble = { + props: { + editor: { + default: null, + type: Object + }, + keepInBounds: { + default: true, + type: Boolean + } + }, + data: function data() { + return { + menu: { + isActive: false, + left: 0, + bottom: 0 + } + }; + }, + watch: { + editor: { + immediate: true, + handler: function handler(editor) { + var _this = this; + + if (editor) { + this.$nextTick(function () { + editor.registerPlugin(MenuBubble({ + editor: editor, + element: _this.$el, + keepInBounds: _this.keepInBounds, + onUpdate: function onUpdate(menu) { + // the second check ensures event is fired only once + if (menu.isActive && _this.menu.isActive === false) { + _this.$emit('show', menu); + } else if (!menu.isActive && _this.menu.isActive === true) { + _this.$emit('hide', menu); + } + + _this.menu = menu; + } + })); + }); + } + } + } + }, + render: function render() { + if (!this.editor) { + return null; + } + + return this.$scopedSlots.default({ + focused: this.editor.view.focused, + focus: this.editor.focus, + commands: this.editor.commands, + isActive: this.editor.isActive, + getMarkAttrs: this.editor.getMarkAttrs.bind(this.editor), + menu: this.menu + }); + }, + beforeDestroy: function beforeDestroy() { + this.editor.unregisterPlugin('menu_bubble'); + } + }; + + var Menu$2 = + /*#__PURE__*/ + function () { + function Menu(_ref) { + var _this = this; + + var options = _ref.options, + editorView = _ref.editorView; + + _classCallCheck(this, Menu); + + this.options = _objectSpread2({}, { + resizeObserver: true, + element: null, + onUpdate: function onUpdate() { + return false; + } + }, {}, options); + this.preventHide = false; + this.editorView = editorView; + this.isActive = false; + this.top = 0; // the mousedown event is fired before blur so we can prevent it + + this.mousedownHandler = this.handleClick.bind(this); + this.options.element.addEventListener('mousedown', this.mousedownHandler); + this.options.editor.on('focus', function (_ref2) { + var view = _ref2.view; + + _this.update(view); + }); + this.options.editor.on('blur', function (_ref3) { + var event = _ref3.event; + + if (_this.preventHide) { + _this.preventHide = false; + return; + } + + _this.hide(event); + }); // sometimes we have to update the position + // because of a loaded images for example + + if (this.options.resizeObserver && window.ResizeObserver) { + this.resizeObserver = new ResizeObserver(function () { + if (_this.isActive) { + _this.update(_this.editorView); + } + }); + this.resizeObserver.observe(this.editorView.dom); + } + } + + _createClass(Menu, [{ + key: "handleClick", + value: function handleClick() { + this.preventHide = true; + } + }, { + key: "update", + value: function update(view, lastState) { + var state = view.state; // Don't do anything if the document/selection didn't change + + if (lastState && lastState.doc.eq(state.doc) && lastState.selection.eq(state.selection)) { + return; + } + + if (!state.selection.empty) { + this.hide(); + return; + } + + var currentDom = view.domAtPos(state.selection.anchor); + var isActive = currentDom.node.innerHTML === '
    ' && currentDom.node.tagName === 'P' && currentDom.node.parentNode === view.dom; + + if (!isActive) { + this.hide(); + return; + } + + var parent = this.options.element.offsetParent; + + if (!parent) { + this.hide(); + return; + } + + var editorBoundings = parent.getBoundingClientRect(); + var cursorBoundings = view.coordsAtPos(state.selection.anchor); + var top = cursorBoundings.top - editorBoundings.top; + this.isActive = true; + this.top = top; + this.sendUpdate(); + } + }, { + key: "sendUpdate", + value: function sendUpdate() { + this.options.onUpdate({ + isActive: this.isActive, + top: this.top + }); + } + }, { + key: "hide", + value: function hide(event) { + if (event && event.relatedTarget && this.options.element.parentNode.contains(event.relatedTarget)) { + return; + } + + this.isActive = false; + this.sendUpdate(); + } + }, { + key: "destroy", + value: function destroy() { + this.options.element.removeEventListener('mousedown', this.mousedownHandler); + + if (this.resizeObserver) { + this.resizeObserver.unobserve(this.editorView.dom); + } + } + }]); + + return Menu; + }(); + + function FloatingMenu (options) { + return new prosemirrorState.Plugin({ + key: new prosemirrorState.PluginKey('floating_menu'), + view: function view(editorView) { + return new Menu$2({ + editorView: editorView, + options: options + }); + } + }); + } + + var EditorFloatingMenu = { + props: { + editor: { + default: null, + type: Object + } + }, + data: function data() { + return { + menu: { + isActive: false, + left: 0, + bottom: 0 + } + }; + }, + watch: { + editor: { + immediate: true, + handler: function handler(editor) { + var _this = this; + + if (editor) { + this.$nextTick(function () { + editor.registerPlugin(FloatingMenu({ + editor: editor, + element: _this.$el, + onUpdate: function onUpdate(menu) { + // the second check ensures event is fired only once + if (menu.isActive && _this.menu.isActive === false) { + _this.$emit('show', menu); + } else if (!menu.isActive && _this.menu.isActive === true) { + _this.$emit('hide', menu); + } + + _this.menu = menu; + } + })); + }); + } + } + } + }, + render: function render() { + if (!this.editor) { + return null; + } + + return this.$scopedSlots.default({ + focused: this.editor.view.focused, + focus: this.editor.focus, + commands: this.editor.commands, + isActive: this.editor.isActive, + getMarkAttrs: this.editor.getMarkAttrs.bind(this.editor), + menu: this.menu + }); + }, + beforeDestroy: function beforeDestroy() { + this.editor.unregisterPlugin('floating_menu'); + } + }; + + Object.defineProperty(exports, 'NodeSelection', { + enumerable: true, + get: function () { + return prosemirrorState.NodeSelection; + } + }); + Object.defineProperty(exports, 'Plugin', { + enumerable: true, + get: function () { + return prosemirrorState.Plugin; + } + }); + Object.defineProperty(exports, 'PluginKey', { + enumerable: true, + get: function () { + return prosemirrorState.PluginKey; + } + }); + Object.defineProperty(exports, 'TextSelection', { + enumerable: true, + get: function () { + return prosemirrorState.TextSelection; + } + }); + exports.Doc = Doc; + exports.Editor = Editor; + exports.EditorContent = EditorContent; + exports.EditorFloatingMenu = EditorFloatingMenu; + exports.EditorMenuBar = EditorMenuBar; + exports.EditorMenuBubble = EditorMenuBubble; + exports.Extension = Extension; + exports.Mark = Mark; + exports.Node = Node; + exports.Paragraph = Paragraph; + exports.Text = Text; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}))); diff --git a/packages/tiptap/dist/tiptap.min.js b/packages/tiptap/dist/tiptap.min.js new file mode 100644 index 0000000000..d20f36bd43 --- /dev/null +++ b/packages/tiptap/dist/tiptap.min.js @@ -0,0 +1,14 @@ + + /*! + * tiptap v1.26.6 + * (c) 2020 Scrumpy UG (limited liability) + * @license MIT + */ + + +/*! + * tiptap v1.26.6 + * (c) 2020 Scrumpy UG (limited liability) + * @license MIT + */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("prosemirror-state"),require("prosemirror-view"),require("prosemirror-model"),require("prosemirror-dropcursor"),require("prosemirror-gapcursor"),require("prosemirror-keymap"),require("prosemirror-commands"),require("prosemirror-inputrules"),require("tiptap-utils"),require("vue"),require("tiptap-commands")):"function"==typeof define&&define.amd?define(["exports","prosemirror-state","prosemirror-view","prosemirror-model","prosemirror-dropcursor","prosemirror-gapcursor","prosemirror-keymap","prosemirror-commands","prosemirror-inputrules","tiptap-utils","vue","tiptap-commands"],t):t((e=e||self).tiptap={},e.prosemirrorState,e.prosemirrorView,e.prosemirrorModel,e.prosemirrorDropcursor,e.prosemirrorGapcursor,e.prosemirrorKeymap,e.prosemirrorCommands,e.prosemirrorInputrules,e.tiptapUtils,e.Vue,e.tiptapCommands)}(this,(function(e,t,n,i,r,o,s,u,a,c,l,h){"use strict";function d(e){return(d="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function p(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function f(e,t){for(var n=0;n1?n-1:0),r=1;r0&&void 0!==arguments[0]?arguments[0]:{};p(this,e),this.options=g({},this.defaultOptions,{},t)}return v(e,[{key:"init",value:function(){return null}},{key:"bindEditor",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;this.editor=e}},{key:"inputRules",value:function(){return[]}},{key:"pasteRules",value:function(){return[]}},{key:"keys",value:function(){return{}}},{key:"name",get:function(){return null}},{key:"type",get:function(){return"extension"}},{key:"update",get:function(){return function(){}}},{key:"defaultOptions",get:function(){return{}}},{key:"plugins",get:function(){return[]}}]),e}(),j=function(){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],n=arguments.length>1?arguments[1]:void 0;p(this,e),t.forEach((function(e){e.bindEditor(n),e.init()})),this.extensions=t}return v(e,[{key:"keymaps",value:function(e){var t=e.schema,n=this.extensions.filter((function(e){return["extension"].includes(e.type)})).filter((function(e){return e.keys})).map((function(e){return e.keys({schema:t})})),i=this.extensions.filter((function(e){return["node","mark"].includes(e.type)})).filter((function(e){return e.keys})).map((function(e){return e.keys({type:t["".concat(e.type,"s")][e.name],schema:t})}));return[].concat(x(n),x(i)).map((function(e){return s.keymap(e)}))}},{key:"inputRules",value:function(e){var t=e.schema,n=e.excludedExtensions;if(!(n instanceof Array)&&n)return[];var i=n instanceof Array?this.extensions.filter((function(e){return!n.includes(e.name)})):this.extensions,r=i.filter((function(e){return["extension"].includes(e.type)})).filter((function(e){return e.inputRules})).map((function(e){return e.inputRules({schema:t})})),o=i.filter((function(e){return["node","mark"].includes(e.type)})).filter((function(e){return e.inputRules})).map((function(e){return e.inputRules({type:t["".concat(e.type,"s")][e.name],schema:t})}));return[].concat(x(r),x(o)).reduce((function(e,t){return[].concat(x(e),x(t))}),[])}},{key:"pasteRules",value:function(e){var t=e.schema,n=e.excludedExtensions;if(!(n instanceof Array)&&n)return[];var i=n instanceof Array?this.extensions.filter((function(e){return!n.includes(e.name)})):this.extensions,r=i.filter((function(e){return["extension"].includes(e.type)})).filter((function(e){return e.pasteRules})).map((function(e){return e.pasteRules({schema:t})})),o=i.filter((function(e){return["node","mark"].includes(e.type)})).filter((function(e){return e.pasteRules})).map((function(e){return e.pasteRules({type:t["".concat(e.type,"s")][e.name],schema:t})}));return[].concat(x(r),x(o)).reduce((function(e,t){return[].concat(x(e),x(t))}),[])}},{key:"commands",value:function(e){var t=e.schema,n=e.view;return this.extensions.filter((function(e){return e.commands})).reduce((function(e,i){var r=i.name,o=i.type,s={},u=i.commands(g({schema:t},["node","mark"].includes(o)?{type:t["".concat(o,"s")][r]}:{})),a=function(e,t){return!!n.editable&&(n.focus(),e(t)(n.state,n.dispatch,n))},c=function(e,t){Array.isArray(t)?s[e]=function(e){return t.forEach((function(t){return a(t,e)}))}:"function"==typeof t&&(s[e]=function(e){return a(t,e)})};return"object"===d(u)?Object.entries(u).forEach((function(e){var t=P(e,2),n=t[0],i=t[1];c(n,i)})):c(r,u),g({},e,{},s)}),{})}},{key:"nodes",get:function(){return this.extensions.filter((function(e){return"node"===e.type})).reduce((function(e,t){return g({},e,m({},t.name,t.schema))}),{})}},{key:"options",get:function(){var e=this.view;return this.extensions.reduce((function(t,n){return g({},t,m({},n.name,new Proxy(n.options,{set:function(t,i,r){var o=t[i]!==r;return Object.assign(t,m({},i,r)),o&&n.update(e),!0}})))}),{})}},{key:"marks",get:function(){return this.extensions.filter((function(e){return"mark"===e.type})).reduce((function(e,t){return g({},e,m({},t.name,t.schema))}),{})}},{key:"plugins",get:function(){return this.extensions.filter((function(e){return e.plugins})).reduce((function(e,t){var n=t.plugins;return[].concat(x(e),x(n))}),[])}}]),e}();function C(e){var t=document.createElement("style");t.type="text/css",t.textContent=e;var n=document.head,i=n.firstChild;i?n.insertBefore(t,i):n.appendChild(t)}var N=function(e){function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return p(this,t),O(this,b(t).call(this,e))}return k(t,e),v(t,[{key:"command",value:function(){return function(){}}},{key:"type",get:function(){return"mark"}},{key:"view",get:function(){return null}},{key:"schema",get:function(){return null}}]),t}(E);function R(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;return Math.min(Math.max(parseInt(e,10),t),n)}var T=function(e){function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return p(this,t),O(this,b(t).call(this,e))}return k(t,e),v(t,[{key:"command",value:function(){return function(){}}},{key:"type",get:function(){return"node"}},{key:"view",get:function(){return null}},{key:"schema",get:function(){return null}}]),t}(E),D=function(e){function t(){return p(this,t),O(this,b(t).apply(this,arguments))}return k(t,e),v(t,[{key:"name",get:function(){return"doc"}},{key:"schema",get:function(){return{content:"block+"}}}]),t}(T),_=function(e){function t(){return p(this,t),O(this,b(t).apply(this,arguments))}return k(t,e),v(t,[{key:"commands",value:function(e){var t=e.type;return function(){return h.setBlockType(t)}}},{key:"name",get:function(){return"paragraph"}},{key:"schema",get:function(){return{content:"inline*",group:"block",draggable:!1,parseDOM:[{tag:"p"}],toDOM:function(){return["p",0]}}}}]),t}(T),H=function(e){function t(){return p(this,t),O(this,b(t).apply(this,arguments))}return k(t,e),v(t,[{key:"name",get:function(){return"text"}},{key:"schema",get:function(){return{group:"inline"}}}]),t}(T),I='.ProseMirror {\n position: relative;\n}\n\n.ProseMirror {\n word-wrap: break-word;\n white-space: pre-wrap;\n -webkit-font-variant-ligatures: none;\n font-variant-ligatures: none;\n}\n\n.ProseMirror pre {\n white-space: pre-wrap;\n}\n\n.ProseMirror-gapcursor {\n display: none;\n pointer-events: none;\n position: absolute;\n}\n\n.ProseMirror-gapcursor:after {\n content: "";\n display: block;\n position: absolute;\n top: -2px;\n width: 20px;\n border-top: 1px solid black;\n animation: ProseMirror-cursor-blink 1.1s steps(2, start) infinite;\n}\n\n@keyframes ProseMirror-cursor-blink {\n to {\n visibility: hidden;\n }\n}\n\n.ProseMirror-hideselection *::selection {\n background: transparent;\n}\n\n.ProseMirror-hideselection *::-moz-selection {\n background: transparent;\n}\n\n.ProseMirror-hideselection * {\n caret-color: transparent;\n}\n\n.ProseMirror-focused .ProseMirror-gapcursor {\n display: block;\n}\n',V=function(e){function l(){var e,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return p(this,l),(e=O(this,b(l).call(this))).defaultOptions={editorProps:{},editable:!0,autoFocus:null,extensions:[],content:"",topNode:"doc",emptyDocument:{type:"doc",content:[{type:"paragraph"}]},useBuiltInExtensions:!0,disableInputRules:!1,disablePasteRules:!1,dropCursor:{},parseOptions:{},injectCSS:!0,onInit:function(){},onTransaction:function(){},onUpdate:function(){},onFocus:function(){},onBlur:function(){},onPaste:function(){},onDrop:function(){}},e.events=["init","transaction","update","focus","blur","paste","drop"],e.init(t),e}return k(l,e),v(l,[{key:"init",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.setOptions(g({},this.defaultOptions,{},t)),this.focused=!1,this.selection={from:0,to:0},this.element=document.createElement("div"),this.extensions=this.createExtensions(),this.nodes=this.createNodes(),this.marks=this.createMarks(),this.schema=this.createSchema(),this.plugins=this.createPlugins(),this.keymaps=this.createKeymaps(),this.inputRules=this.createInputRules(),this.pasteRules=this.createPasteRules(),this.view=this.createView(),this.commands=this.createCommands(),this.setActiveNodesAndMarks(),this.options.injectCSS&&C(I),null!==this.options.autoFocus&&this.focus(this.options.autoFocus),this.events.forEach((function(t){e.on(t,e.options[M("on ".concat(t))]||function(){})})),this.emit("init",{view:this.view,state:this.state}),this.extensions.view=this.view}},{key:"setOptions",value:function(e){this.options=g({},this.options,{},e),this.view&&this.state&&this.view.updateState(this.state)}},{key:"createExtensions",value:function(){return new j([].concat(x(this.builtInExtensions),x(this.options.extensions)),this)}},{key:"createPlugins",value:function(){return this.extensions.plugins}},{key:"createKeymaps",value:function(){return this.extensions.keymaps({schema:this.schema})}},{key:"createInputRules",value:function(){return this.extensions.inputRules({schema:this.schema,excludedExtensions:this.options.disableInputRules})}},{key:"createPasteRules",value:function(){return this.extensions.pasteRules({schema:this.schema,excludedExtensions:this.options.disablePasteRules})}},{key:"createCommands",value:function(){return this.extensions.commands({schema:this.schema,view:this.view})}},{key:"createNodes",value:function(){return this.extensions.nodes}},{key:"createMarks",value:function(){return this.extensions.marks}},{key:"createSchema",value:function(){return new i.Schema({topNode:this.options.topNode,nodes:this.nodes,marks:this.marks})}},{key:"createState",value:function(){var e=this;return t.EditorState.create({schema:this.schema,doc:this.createDocument(this.options.content),plugins:[].concat(x(this.plugins),[a.inputRules({rules:this.inputRules})],x(this.pasteRules),x(this.keymaps),[s.keymap({Backspace:a.undoInputRule}),s.keymap(u.baseKeymap),r.dropCursor(this.options.dropCursor),o.gapCursor(),new t.Plugin({key:new t.PluginKey("editable"),props:{editable:function(){return e.options.editable}}}),new t.Plugin({props:{attributes:{tabindex:0},handleDOMEvents:{focus:function(t,n){e.focused=!0,e.emit("focus",{event:n,state:t.state,view:t});var i=e.state.tr.setMeta("focused",!0);e.view.dispatch(i)},blur:function(t,n){e.focused=!1,e.emit("blur",{event:n,state:t.state,view:t});var i=e.state.tr.setMeta("focused",!1);e.view.dispatch(i)}}}}),new t.Plugin({props:this.options.editorProps})])})}},{key:"createDocument",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.options.parseOptions;if(null===e)return this.schema.nodeFromJSON(this.options.emptyDocument);if("object"===d(e))try{return this.schema.nodeFromJSON(e)}catch(t){return console.warn("[tiptap warn]: Invalid content.","Passed value:",e,"Error:",t),this.schema.nodeFromJSON(this.options.emptyDocument)}if("string"==typeof e){var n=document.createElement("div");return n.innerHTML=e.trim(),i.DOMParser.fromSchema(this.schema).parse(n,t)}return!1}},{key:"createView",value:function(){var e=this;return new n.EditorView(this.element,{state:this.createState(),handlePaste:function(){for(var t=arguments.length,n=new Array(t),i=0;i0&&void 0!==arguments[0]?arguments[0]:null;e&&this.view.setProps({nodeViews:this.initNodeViews({parent:e,extensions:[].concat(x(this.builtInExtensions),x(this.options.extensions))})})}},{key:"initNodeViews",value:function(e){var t=this,n=e.parent;return e.extensions.filter((function(e){return["node","mark"].includes(e.type)})).filter((function(e){return e.view})).reduce((function(e,i){return g({},e,m({},i.name,(function(e,r,o,s){var u=i.view;return new A(u,{editor:t,extension:i,parent:n,node:e,view:r,getPos:o,decorations:s})})))}),{})}},{key:"dispatchTransaction",value:function(e){var t=this.state.apply(e);this.view.updateState(t),this.selection={from:this.state.selection.from,to:this.state.selection.to},this.setActiveNodesAndMarks(),this.emit("transaction",{getHTML:this.getHTML.bind(this),getJSON:this.getJSON.bind(this),state:this.state,transaction:e}),e.docChanged&&!e.getMeta("preventUpdate")&&this.emitUpdate(e)}},{key:"emitUpdate",value:function(e){this.emit("update",{getHTML:this.getHTML.bind(this),getJSON:this.getJSON.bind(this),state:this.state,transaction:e})}},{key:"resolveSelection",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;if(this.selection&&null===e)return this.selection;if("start"===e||!0===e)return{from:0,to:0};if("end"===e){var t=this.state.doc;return{from:t.content.size,to:t.content.size}}return{from:e,to:e}}},{key:"focus",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;if(!(this.view.focused&&null===t||!1===t)){var n=this.resolveSelection(t),i=n.from,r=n.to;this.setSelection(i,r),setTimeout((function(){return e.view.focus()}),10)}}},{key:"setSelection",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,i=this.state,r=i.doc,o=i.tr,s=R(e,0,r.content.size),u=R(n,0,r.content.size),a=t.TextSelection.create(r,s,u),c=o.setSelection(a);this.view.dispatch(c)}},{key:"blur",value:function(){this.view.dom.blur()}},{key:"getSchemaJSON",value:function(){return JSON.parse(JSON.stringify({nodes:this.extensions.nodes,marks:this.extensions.marks}))}},{key:"getHTML",value:function(){var e=document.createElement("div"),t=i.DOMSerializer.fromSchema(this.schema).serializeFragment(this.state.doc.content);return e.appendChild(t),e.innerHTML}},{key:"getJSON",value:function(){return this.state.doc.toJSON()}},{key:"setContent",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=arguments.length>2?arguments[2]:void 0,r=this.state,o=r.doc,s=r.tr,u=this.createDocument(e,i),a=t.TextSelection.create(o,0,o.content.size),c=s.setSelection(a).replaceSelectionWith(u,!1).setMeta("preventUpdate",!n);this.view.dispatch(c)}},{key:"clearContent",value:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];this.setContent(this.options.emptyDocument,e)}},{key:"setActiveNodesAndMarks",value:function(){var e=this;this.activeMarks=Object.entries(this.schema.marks).reduce((function(t,n){var i=P(n,2),r=i[0],o=i[1];return g({},t,m({},r,(function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return c.markIsActive(e.state,o,t)})))}),{}),this.activeMarkAttrs=Object.entries(this.schema.marks).reduce((function(t,n){var i=P(n,2),r=i[0],o=i[1];return g({},t,m({},r,c.getMarkAttrs(e.state,o)))}),{}),this.activeNodes=Object.entries(this.schema.nodes).reduce((function(t,n){var i=P(n,2),r=i[0],o=i[1];return g({},t,m({},r,(function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return c.nodeIsActive(e.state,o,t)})))}),{})}},{key:"getMarkAttrs",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;return this.activeMarkAttrs[e]}},{key:"registerPlugin",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;if(e){var t=this.state.reconfigure({plugins:this.state.plugins.concat([e])});this.view.updateState(t)}}},{key:"unregisterPlugin",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;if(e&&this.view.docView){var t=this.state.reconfigure({plugins:this.state.plugins.filter((function(t){return!t.key.startsWith("".concat(e,"$"))}))});this.view.updateState(t)}}},{key:"destroy",value:function(){this.view&&this.view.destroy()}},{key:"builtInExtensions",get:function(){return this.options.useBuiltInExtensions?[new D,new H,new _]:[]}},{key:"state",get:function(){return this.view?this.view.state:null}},{key:"isActive",get:function(){return Object.entries(g({},this.activeMarks,{},this.activeNodes)).reduce((function(e,t){var n=P(t,2),i=n[0],r=n[1];return g({},e,m({},i,(function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return r(e)})))}),{})}}]),l}(S),U={props:{editor:{default:null,type:Object}},watch:{editor:{immediate:!0,handler:function(e){var t=this;e&&e.element&&this.$nextTick((function(){t.$el.appendChild(e.element.firstChild),e.setParentComponent(t)}))}}},render:function(e){return e("div")},beforeDestroy:function(){this.editor.element=this.$el}},$=function(){function e(t){var n=this,i=t.options;p(this,e),this.options=i,this.preventHide=!1,this.mousedownHandler=this.handleClick.bind(this),this.options.element.addEventListener("mousedown",this.mousedownHandler),this.options.editor.on("blur",(function(){n.preventHide?n.preventHide=!1:n.options.editor.emit("menubar:focusUpdate",!1)}))}return v(e,[{key:"handleClick",value:function(){this.preventHide=!0}},{key:"destroy",value:function(){this.options.element.removeEventListener("mousedown",this.mousedownHandler)}}]),e}();var B={props:{editor:{default:null,type:Object}},data:function(){return{focused:!1}},watch:{editor:{immediate:!0,handler:function(e){var n=this;e&&this.$nextTick((function(){var i;e.registerPlugin((i={editor:e,element:n.$el},new t.Plugin({key:new t.PluginKey("menu_bar"),view:function(e){return new $({editorView:e,options:i})}}))),n.focused=e.focused,e.on("focus",(function(){n.focused=!0})),e.on("menubar:focusUpdate",(function(e){n.focused=e}))}))}}},render:function(){return this.editor?this.$scopedSlots.default({focused:this.focused,focus:this.editor.focus,commands:this.editor.commands,isActive:this.editor.isActive,getMarkAttrs:this.editor.getMarkAttrs.bind(this.editor)}):null}};function z(e,t,n){var i=document.createRange();return i.setEnd(e,null==n?e.nodeValue.length:n),i.setStart(e,t||0),i}function L(e,t){var n=e.getClientRects();return n.length?n[t<0?0:n.length-1]:e.getBoundingClientRect()}function q(e,t){var n,i,r=arguments.length>2&&void 0!==arguments[2]&&arguments[2],o=e.docView.domFromPos(t),s=o.node,u=o.offset;if(3===s.nodeType)r&&u"===i.node.innerHTML&&"P"===i.node.tagName&&i.node.parentNode===e.dom){var r=this.options.element.offsetParent;if(r){var o=r.getBoundingClientRect(),s=e.coordsAtPos(n.selection.anchor).top-o.top;this.isActive=!0,this.top=s,this.sendUpdate()}else this.hide()}else this.hide()}else this.hide()}},{key:"sendUpdate",value:function(){this.options.onUpdate({isActive:this.isActive,top:this.top})}},{key:"hide",value:function(e){e&&e.relatedTarget&&this.options.element.parentNode.contains(e.relatedTarget)||(this.isActive=!1,this.sendUpdate())}},{key:"destroy",value:function(){this.options.element.removeEventListener("mousedown",this.mousedownHandler),this.resizeObserver&&this.resizeObserver.unobserve(this.editorView.dom)}}]),e}();var W={props:{editor:{default:null,type:Object}},data:function(){return{menu:{isActive:!1,left:0,bottom:0}}},watch:{editor:{immediate:!0,handler:function(e){var n=this;e&&this.$nextTick((function(){var i;e.registerPlugin((i={editor:e,element:n.$el,onUpdate:function(e){e.isActive&&!1===n.menu.isActive?n.$emit("show",e):e.isActive||!0!==n.menu.isActive||n.$emit("hide",e),n.menu=e}},new t.Plugin({key:new t.PluginKey("floating_menu"),view:function(e){return new K({editorView:e,options:i})}})))}))}}},render:function(){return this.editor?this.$scopedSlots.default({focused:this.editor.view.focused,focus:this.editor.focus,commands:this.editor.commands,isActive:this.editor.isActive,getMarkAttrs:this.editor.getMarkAttrs.bind(this.editor),menu:this.menu}):null},beforeDestroy:function(){this.editor.unregisterPlugin("floating_menu")}};Object.defineProperty(e,"NodeSelection",{enumerable:!0,get:function(){return t.NodeSelection}}),Object.defineProperty(e,"Plugin",{enumerable:!0,get:function(){return t.Plugin}}),Object.defineProperty(e,"PluginKey",{enumerable:!0,get:function(){return t.PluginKey}}),Object.defineProperty(e,"TextSelection",{enumerable:!0,get:function(){return t.TextSelection}}),e.Doc=D,e.Editor=V,e.EditorContent=U,e.EditorFloatingMenu=W,e.EditorMenuBar=B,e.EditorMenuBubble=F,e.Extension=E,e.Mark=N,e.Node=T,e.Paragraph=_,e.Text=H,Object.defineProperty(e,"__esModule",{value:!0})})); \ No newline at end of file diff --git a/packages/tiptap/node_modules/prosemirror-view/.tern-project b/packages/tiptap/node_modules/prosemirror-view/.tern-project new file mode 100644 index 0000000000..dde39765e5 --- /dev/null +++ b/packages/tiptap/node_modules/prosemirror-view/.tern-project @@ -0,0 +1,8 @@ +{ + "libs": ["browser"], + "plugins": { + "node": {}, + "complete_strings": {}, + "es_modules": {} + } +} diff --git a/packages/tiptap/node_modules/prosemirror-view/CHANGELOG.md b/packages/tiptap/node_modules/prosemirror-view/CHANGELOG.md new file mode 100644 index 0000000000..7147b7ac3f --- /dev/null +++ b/packages/tiptap/node_modules/prosemirror-view/CHANGELOG.md @@ -0,0 +1,1233 @@ +## 1.13.7 (2019-12-16) + +### Bug fixes + +Fix a bug that caused the DOM to go out of sync with the decorations when updating inline decorations that added multiple wrapping nodes to a piece of content. + +## 1.13.6 (2019-12-13) + +### Bug fixes + +Fix a crash when deleting a list item in Safari while using a parse rule with a `context` property for `

  • ` elements. + +Work around another case where Chrome reports an incorrect selection. + +Work around issue where Firefox will insert a stray BR node when deleting a text node in some types of DOM structure. + +## 1.13.5 (2019-12-09) + +### Bug fixes + +Fix the way decorations update node styles to allow removing CSS custom properties. Link to https in readme and changelog + +The `root` accessor on views now makes sure that, when it returns a shadow root, that object has a `getSelection` method. + +Fix an issue where the DOM selection could get out of sync with ProseMirror's selection state in Edge. + +## 1.13.4 (2019-11-20) + +### Bug fixes + +Rename ES module files to use a .js extension, since Webpack gets confused by .mjs + +## 1.13.3 (2019-11-19) + +### Bug fixes + +Fix issue where the editor wouldn't update its internal selection when the editor was blurred, its selection was changed programatically, and then the editor was re-focused with its old DOM selection. + +The file referred to in the package's `module` field now is compiled down to ES5. + +## 1.13.2 (2019-11-14) + +### Bug fixes + +Fix issue where `EditorView.focus` would scroll the top of the document into view on Safari. + +## 1.13.1 (2019-11-12) + +### Bug fixes + +Work around selection jumping that sometimes occurs on Chrome when focusing the editor. + +## 1.13.0 (2019-11-08) + +### New features + +Add a `module` field to package json file. + +## 1.12.3 (2019-11-07) + +### Bug fixes + +Fix issue where paste events were stopped when the clipboard parser failed to make sense of the content. + +Fix issue where the `handlePaste` prop might be called multiple times for a single paste. + +## 1.12.2 (2019-11-05) + +### Bug fixes + +Set the editable element to use a `white-space: break-spaces` style so that whitespace at the end of a line properly moves the cursor to the next line. + +Fix issue where `posAtCoords` could throw an error in some circumstances on Firefox. + +Don't force focus back on the editor if a node view moves focus in its `setSelection` method. + +## 1.12.1 (2019-10-28) + +### Bug fixes + +Reduce unnecessary redraws when typing creates a new text node on Chrome. + +The default prosemirror.css now also turns off ligatures in Edge. + +Fix issue where the cursor stays before the typed text in Edge, when typing in an empty paragraph or between hard break nodes. + +## 1.12.0 (2019-10-21) + +### New features + +The mutation records passed to [`ignoreMutation`](https://prosemirror.net/docs/ref/#view.NodeView.ignoreMutation) now contain the old attribute value. + +## 1.11.7 (2019-10-15) + +### Bug fixes + +Enabling a mark and then starting a composition, on Chrome Android, will no longer cause the cursor to jump to the start of the composition. + +## 1.11.6 (2019-10-07) + +### Bug fixes + +Fix workaround for broken IE11 DOM change records when inserting between `
    ` nodes to handle more cases. + +## 1.11.5 (2019-10-04) + +### Bug fixes + +Don't leave DOM selection in place when it is inside a node view but not inside its content DOM element. + +## 1.11.4 (2019-09-27) + +### Bug fixes + +Fix an IE11 issue where marks would sometimes unexpectedly get dropped when inserting a space after marked text. + +Fixes an issue where `handleTextInput` wasn't called when typing over a single character with the same character. + +## 1.11.3 (2019-09-20) + +### Bug fixes + +Fix an issue where the DOM node representing a mark could be corrupted when the browser decides to replace it with another node but ProseMirror restored the old node after the change. + +Handle another case where typing over a selection in IE11 confused the editor. + +## 1.11.2 (2019-09-17) + +### Bug fixes + +Fix an issue where typing over a decorated piece of text would sometimes just act like deletion. + +Fix another problem in IE11 with typing over content, where typing over a decorated bit of text caused a crash. + +## 1.11.1 (2019-09-16) + +### Bug fixes + +Fix issue where typing over the entire contents of an inline node on IE11 would insert the typed content in the wrong position. + +## 1.11.0 (2019-09-16) + +### Bug fixes + +Fix an issue where IE11 would select the entire textblock after deleting content at its start. + +### New features + +View instances now have a public `editable` property that indicates whether they are in editable mode. + +## 1.10.3 (2019-09-04) + +### Bug fixes + +Fix a regression in 1.10.2 that broke copying on IE11. + +## 1.10.2 (2019-09-03) + +### Bug fixes + +Fix an issue where `posAtCoords` could crash by dereferencing undefined in some circumstances. + +Fix inserting text next to a hard break in IE11. + +Fix an issue where typing over a selection would result in two different transactions (once for the deletion, once for the insertion) on IE11. + +Selecting the word at the start of the document and typing over it no longer causes the text input to appear at the end of the document in IE11. + +## 1.10.1 (2019-08-28) + +### Bug fixes + +Copying content will no longer create elements in the main document, which prevents images from loading just because they appear in clipboard content. + +## 1.10.0 (2019-08-13) + +### Bug fixes + +Fix an issue that caused the cursor to be scrolled into view when `focus()` was called on IE11. + +Fix problem where the cursor cycled through pieces of right-to-left text on Firefox during horizontal motion when the gapcursor plugin was enabled. + +Fix spurious mutation events in Firefox causing mark replacement at end of composition. Restore call to dom.focus on view.focus + +Fix a bug that could cause node views in front of marked nodes to not be destroyed when deleted, and caused confusion in composition handling in some situations. + +Cursor wrappers (a kludge to make sure typed text gets wrapping DOM structure corresponding to the current marks) are now created less eagerly, and in a less invasive way, which resolves a number of problems with composition (especially on Safari) and bidirectional text. + +### New features + +Node views can now ignore selection change events through their [`ignoreMutation`](https://prosemirror.net/docs/ref/#view.NodeView.ignoreMutation) callback. + +## 1.9.13 (2019-07-29) + +### Bug fixes + +Fix an issue where copying content from a ProseMirror instance into an instance using another schema could, in some circumstances, insert schema-violating content. + +Fix comparison of decoration sets, which should solve unneccesary re-renders when updating decorations with an identical but newly allocated set. Don't update DOM selection in uneditable editors when the focus is elsewhere + +Fix a bug where the editor would steal focus from child elements when in non-editable mode. + +Fix error and corruption in IE11 when backspacing out a single character after a br node. + +## 1.9.12 (2019-07-16) + +### Bug fixes + +Fix a crash `posAtCoords` in Firefox when the coordinates are above a text input field. + +## 1.9.11 (2019-07-03) + +### Bug fixes + +Fix an issue where the DOM change handler would treat the parsed content as the wrong part of the document. + +Fix an issue in IE11 where deleting the last character in a textblock causes a crash. + +Fix an issue where backspacing out the first character in a textblock would cause IE11 to move the selection to some incorrect position. + +## 1.9.10 (2019-06-12) + +### Bug fixes + +Fix a crash in `coordsAtPos` caused by use of an incorrect variable name. + +## 1.9.9 (2019-06-09) + +### Bug fixes + +Fix arrowing over unselectable inline nodes in Chrome and Safari, which by default introduce an extra needless cursor position before the node. + +Fix a bug that caused DOM changes to be ignored when happening directly in front of some types of DOM events (such as focus/blur). + +## 1.9.8 (2019-05-29) + +### Bug fixes + +Fix an issue where moving focus from a node inside of the editor to the editor itself could sometimes lead to a node selection around the inner node rather than the intended selection (on Chrome). + +## 1.9.7 (2019-05-28) + +### Bug fixes + +ProseMirror will no longer try to stabilize the scroll position during updates on browsers that support [scroll anchoring](https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-anchor), since it'd inadvertently cancel the browser's behavior. + +Fix an issue in Safari where the editor would interrupt the composition spacebar menu because it incorrectly interpreted the mutation events fired by the browser as representing a replacement of the selection with identical text. + +Work around an issue where, on Safari, an IME composition started in an empty textblock would vanish when you press enter. + +## 1.9.6 (2019-05-17) + +### Bug fixes + +Fix bug in composition handling when the composition's parent node has an extra wrapper node around its content. + +## 1.9.5 (2019-05-14) + +### Bug fixes + +Fix regression in handling text editing events on IE11. + +## 1.9.4 (2019-05-13) + +### Bug fixes + +Fix a regression where all plugin views were recreated when calling [`setProps`](https://prosemirror.net/docs/ref/#view.EditorView.setProps). + +## 1.9.3 (2019-05-10) + +### Bug fixes + +Fix a bug where, if the document was changed at exactly the right moment, `handleClickOn` could be called with `null` as the node. + +## 1.9.2 (2019-05-08) + +### Bug fixes + +Fix a bug where updating to a reconfigured state would not recreate the view's plugin views. + +## 1.9.1 (2019-05-04) + +### Bug fixes + +Fix a regression where mouse selection would sometimes raise an error. + +## 1.9.0 (2019-05-03) + +### New features + +Changes made during compositions now immediately fire transactions on each update, rather than only a single one at the end of the composition. + +The view now immediately shows changes to the document or decorations during composition, even if they come from transactions not directly generated by the use's editing. The only exception is decorations that affect the focused text node—those are still delayed to avoid unneccesarily canceling the composition. + +## 1.8.9 (2019-04-18) + +### Bug fixes + +Improve display update times for nodes with thousands of children by fix an accidental piece of quadratic complexity. + +Fixes an issue where changes to the [`nodeViews` prop](https://prosemirror.net/docs/ref/#view.EditorProps.nodeViews) weren't noticed when using [`updateState`](https://prosemirror.net/docs/ref/#view.EditorView.updateState) to update the view. + +Fix issue where sometimes moving the selection back its last position with the mouse failed to update ProseMirror's selection state. + +No longer call [`deselectNode`](https://prosemirror.net/docs/ref/#view.NodeView.deselectNode) on already-destroyed node views. + +## 1.8.8 (2019-04-11) + +### Bug fixes + +Fix a regression from 1.8.4 that made it return unreasonable rectangles for positions between blocks. + +## 1.8.7 (2019-04-09) + +### Bug fixes + +The [`handlePaste`](https://prosemirror.net/docs/ref/#view.EditorProps.handlePaste) prop is now activated even when the default parser can't make any sense of the clipboard content. + +## 1.8.6 (2019-04-08) + +### Bug fixes + +Fix a bug where decorations splitting a text node would sometimes confuse the display updater and make decorated nodes disappear. + +## 1.8.5 (2019-04-08) + +### Bug fixes + +Multiple [`transformPastedHTML`](https://prosemirror.net/docs/ref/#view.EditorProps.transformPastedHTML) props are now all properly called in order, rather than only the first one. + +Fixes an issue where invalid change positions were computed when a composition happened concurrently with a change that inserted content at the same position. + +## 1.8.4 (2019-03-20) + +### Bug fixes + +[`EditorView.coordsAtPos`](https://prosemirror.net/docs/ref/#view.EditorView.coordsAtPos) is now more accurate in right-to-left text on Chrome and Firefox. + +[`EditorView.coordsAtPos`](https://prosemirror.net/docs/ref/#view.EditorView.coordsAtPos) returns more accurate coordinates when querying the position directly after a line wrap point. + +Fix an issue where clicking directly in front of a node selection doesn't clear the node selection markup. + +## 1.8.3 (2019-03-04) + +### Bug fixes + +Fix an issue where clicking when there's a non-text selection active sometimes doesn't cause the appropriate new selection. + +## 1.8.2 (2019-02-28) + +### Bug fixes + +Fix an issue where a view state update happening between a change to the DOM selection and the corresponding browser event could disrupt mouse selection. + +## 1.8.1 (2019-02-22) + +### Bug fixes + +Fix infinite loop in `coordsAtPos`. + +## 1.8.0 (2019-02-21) + +### Bug fixes + +Fix a bug where [`endOfTextblock`](https://prosemirror.net/docs/ref/#view.EditorView.endOfTextblock) spuriously returns true when the cursor is in a mark. + +### New features + +[`posAtCoords`](https://prosemirror.net/docs/ref/#view.EditorView.posAtCoords) will no longer return `null` when called with coordinates outside the browser's viewport. (It _will_ still return null for coordinates outside of the editor's bounding box.) + +## 1.7.3 (2019-02-20) + +### Bug fixes + +[`endOfTextblock`](https://prosemirror.net/docs/ref/#view.EditorView.endOfTextblock) now works on textblocks that are the editor's top-level node. + +## 1.7.2 (2019-02-20) + +### Bug fixes + +Pressing shift-left/right next to a selectable node no longer selects the node instead of creating a text selection across it. + +## 1.7.1 (2019-02-04) + +### Bug fixes + +Fix an issue on Safari where an Enter key events that was part of a composition is interpreted as stand-alone Enter press. + +## 1.7.0 (2019-01-29) + +### Bug fixes + +Fix an issue where node selections on uneditable nodes couldn't be copied or cut on Chrome. + +### New features + +The editable view now recognizes the [`spanning`](https://prosemirror.net/docs/ref/#model.MarkSpec.spanning) mark property. + +## 1.6.8 (2019-01-03) + +### Bug fixes + +When replacing a selection by typing over it with a letter that matches its start or end, the editor now generates a step that covers the whole replacement. + +Fixes dragging a node when the mouse is in a child DOM element that doesn't represent a document node. Work around Chrome bug in selection management + +Fixes an issue in Chrome where clicking at the start of a textblock after a selected node would sometimes not move the cursor there. + +Fix issue where a node view's `getPos` callback could sometimes return `NaN`. + +Fix an issue where deleting more than 5 nodes might cause the nodes after that to be needlessly redrawn. + +## 1.6.7 (2018-11-26) + +### Bug fixes + +Avoids redrawing of content with marks when other content in front of it is deleted. + +## 1.6.6 (2018-11-15) + +### Bug fixes + +Work around a Chrome bug where programmatic changes near the cursor sometimes cause the visible and reported selection to disagree. + +Changing the `nodeView` prop will no longer leave outdated node views in the DOM. + +Work around an issue where Chrome unfocuses the editor or scrolls way down when pressing down arrow with the cursor between the start of a textblock and an uneditable element. + +Fix a bug where mapping decoration sets through changes that changed the structure of decorated subtrees sometimes produced corrupted output. + +## 1.6.5 (2018-10-29) + +### Bug fixes + +Work around Safari issue where deleting the last bit of text in a table cell creates weird HTML with a BR in a table row. + +## 1.6.4 (2018-10-19) + +### Bug fixes + +Fix pasting when both text and files are present on the clipboard. + +## 1.6.3 (2018-10-12) + +### Bug fixes + +The editor will no longer try to handle file paste events with the old-browser compatibility kludge (which might cause scrolling and focus flickering). + +## 1.6.2 (2018-10-08) + +### Bug fixes + +Fixes an issue where event handlers were leaked when destroying an editor + +## 1.6.1 (2018-10-01) + +### Bug fixes + +Fixes situation where a vertical [`endOfTextblock`](https://prosemirror.net/docs/ref/#view.EditorView.endOfTextblock) query could get confused by nearby widgets or complex parent node representation. + +## 1.6.0 (2018-09-27) + +### Bug fixes + +Fixes a corner case in which DecorationSet.map would map decorations to incorrect new positions. + +When the editor contains scrollable elements, scrolling the cursor into view also scrolls those. + +### New features + +The `scrollMargin` and `scrollThreshold` props may now hold `{left, right, top, bottom}` objects to set different margins and thresholds for different sides. Make scrolling from a given start node more robust + +## 1.5.3 (2018-09-24) + +### Bug fixes + +The cursor is now scrolled into view after keyboard driven selection changes even when they were handled by the browser. + +## 1.5.2 (2018-09-07) + +### Bug fixes + +Improves selection management around widgets with no actual HTML content (possibly drawn using CSS pseudo elements). + +Fix extra whitespace in pasted HTML caused by previously-collapsed spacing. + +Slow triple-clicks are no longer treated as two double-clicks in a row. + +## 1.5.1 (2018-08-24) + +### Bug fixes + +Fix issue where some DOM selections would cause a non-editable view to crash when reading the selection. + +## 1.5.0 (2018-08-21) + +### New features + +Mark views are now passed a boolean that indicates whether the mark's content is inline as third argument. + +## 1.4.4 (2018-08-13) + +### Bug fixes + +Fix an issue where a non-empty DOM selection could stick around even though the state's selection is empty. + +Fix an issue where Firefox would create an extra cursor position when arrow-keying through a widget. + +## 1.4.3 (2018-08-12) + +### Bug fixes + +Fix an issue where the editor got stuck believing shift was down (and hence pasting as plain text) when it was unfocused with shift held down. + +## 1.4.2 (2018-08-03) + +### Bug fixes + +Fix an issue where reading the selection from the DOM might crash in non-editable mode. + +## 1.4.1 (2018-08-02) + +### Bug fixes + +Fixes an issue where backspacing out the last character between the start of a textblock and a widget in Chrome would insert a random hard break. + +## 1.4.0 (2018-07-26) + +### New features + +The `dispatchTransaction` prop is now called with `this` bound to the editor view. + +## 1.3.8 (2018-07-24) + +### Bug fixes + +Fix an issue where Chrome Android would move the cursor forward by one after backspace-joining two paragraphs. + +## 1.3.7 (2018-07-02) + +### Bug fixes + +Fix a crash when scrolling things into view when the editor isn't a child of `document.body`. + +## 1.3.6 (2018-06-21) + +### Bug fixes + +Make sure Safari version detection for clipboard support also works in iOS webview. + +## 1.3.5 (2018-06-20) + +### Bug fixes + +Use shared implementation of [`dropPoint`](https://prosemirror.net/docs/ref/#transform.dropPoint) to handle finding a drop position. + +## 1.3.4 (2018-06-20) + +### Bug fixes + +Enable use of browser clipboard API on Mobile Safari version 11 and up, which makes cut work on that platform and should generally improve clipboard handling. + +## 1.3.3 (2018-06-15) + +### Bug fixes + +Fix arrow-left cursor motion from cursor wrapper (for example after a link). + +Fix selection glitches when shift-selecting around widget decorations. + +Fix issue where a parsing a code block from the editor DOM might drop newlines in the code. + +## 1.3.2 (2018-06-15) + +### Bug fixes + +[`handleKeyDown`](https://prosemirror.net/docs/ref/#view.EditorProps.handleKeyDown) will now get notified of key events happening directly after a composition ends. + +## 1.3.1 (2018-06-08) + +### Bug fixes + +The package can now be loaded in a web worker context (where `navigator` is defined but `document` isn't) without crashing. + +Dropping something like a list item into a textblock will no longer split the textblock. + +## 1.3.0 (2018-04-24) + +### Bug fixes + +Fix mouse-selecting (in IE and Edge) from the end of links and other positions that cause a cursor wrapper. + +[Widget decorations](https://prosemirror.net/docs/ref/#view.Decoration^widget) with the same [key](https://prosemirror.net/docs/ref/#view.Decoration^widget^spec.key) are now considered equivalent, even if their other spec fields differ. + +### New features + +The new [`EditorView.posAtDOM` method](https://prosemirror.net/docs/ref/#view.EditorView.posAtDOM) can be used to find the document position corresponding to a given DOM position. + +The new [`EditorView.nodeDOM` method](https://prosemirror.net/docs/ref/#view.EditorView.nodeDOM) gives you the DOM node that is used to represent a specific node in the document. + +[`Decoration.widget`](https://prosemirror.net/docs/ref/#view.Decoration^widget) now accepts a function as second argument, which can be used to delay rendering of the widget until the document is drawn (at which point a reference to the view is available). + +The `getPos` function passed to a [node view constructor](https://prosemirror.net/docs/ref/#view.editorProps.nodeViews) can now be called immediately (it used to return undefined until rendering had finished). + +The function used to render a [widget](https://prosemirror.net/docs/ref/#view.Decoration^widget) is now passed a `getPos` method that event handlers can use to figure out where in the DOM the widget is. + +## 1.2.0 (2018-03-14) + +### Bug fixes + +Fix a problem where updating the state of a non-editable view would not set the selection, causing problems when the DOM was updated in a way that disrupted the DOM selection. + +Fix an issue where, on IE and Chrome, starting a drag selection in a position that required a cursor wrapper (on a mark boundary) would sometimes fail to work. + +Fix crash in key handling when the editor is focused but there is no DOM selection. + +Fixes a bug that prevented decorations inside node views with a [`contentDOM` property](https://prosemirror.net/docs/ref/#view.NodeView.contentDOM) from being drawn. + +Fixes an issue where, on Firefox, depending on a race condition, the skipping over insignificant DOM nodes done at keypress was canceled again before the keypress took effect. + +Fixes an issue where an `:after` pseudo-element on a non-inclusive mark could block the cursor, making it impossible to arrow past it. + +### New features + +The DOM structure for marks is no longer constrained to a single node. [Mark views](https://prosemirror.net/docs/ref/#view.NodeView) can have a `contentDOM` property, and [mark spec](https://prosemirror.net/docs/ref/#model.MarkSpec) `toDOM` methods can return structures with holes. + +[Widget decorations](https://prosemirror.net/docs/ref/#view.Decoration^widget) are now wrapped in the marks of the node after them when their [`side` option](https://prosemirror.net/docs/ref/#view.Decoration^widget^spec.side) is >= 0. + +[Widget decorations](https://prosemirror.net/docs/ref/#view.Decoration^widget) may now specify a [`marks` option](https://prosemirror.net/docs/ref/#view.Decoration^widget^spec.marks) to set the precise set of marks they should be wrapped in. + +## 1.1.1 (2018-03-01) + +### Bug fixes + +Fixes typo that broke paste. + +## 1.1.0 (2018-02-28) + +### Bug fixes + +Fixes issue where dragging a draggable node directly below a selected node would move the old selection rather than the target node. + +A drop that can't fit the dropped content will no longer dispatch an empty transaction. + +### New features + +Transactions generated for drop now have a `"uiEvent"` metadata field holding `"drop"`. Paste and cut transactions get that field set to `"paste"` or `"cut"`. + +## 1.0.11 (2018-02-16) + +### Bug fixes + +Fix issue where the cursor was visible when a node was selected on recent Chrome versions. + +## 1.0.10 (2018-01-24) + +### Bug fixes + +Improve preservation of open and closed nodes in slices taken from the clipboard. + +## 1.0.9 (2018-01-17) + +### Bug fixes + +Work around a Chrome cursor motion bug by making sure
    nodes don't get a contenteditable=false attribute. + +## 1.0.8 (2018-01-09) + +### Bug fixes + +Fix issue where [`Decoration.map`](https://prosemirror.net/docs/ref/#view.DecorationSet.map) would in some situations with nested nodes incorrectly map decoration positions. + +## 1.0.7 (2018-01-05) + +### Bug fixes + +Pasting from an external source no longer opens isolating nodes like table cells. + +## 1.0.6 (2017-12-26) + +### Bug fixes + +[`DecorationSet.remove`](https://prosemirror.net/docs/ref/#view.DecorationSet.remove) now uses a proper deep compare to determine if widgets are the same (it used to compare by identity). + +## 1.0.5 (2017-12-05) + +### Bug fixes + +Fix an issue where deeply nested decorations were mapped incorrectly in corner cases. + +## 1.0.4 (2017-11-27) + +### Bug fixes + +Fix a corner-case crash during drop. + +## 1.0.3 (2017-11-23) + +### Bug fixes + +Pressing backspace between two identical characters will no longer generate a transaction that deletes the second one. + +## 1.0.2 (2017-11-20) + +### Bug fixes + +Fix test for whether a node can be selected when arrowing onto it from the right. + +Calling [`posAtCoords`](https://prosemirror.net/docs/ref/#view.EditorView.posAtCoords) while a read from the DOM is pending will no longer return a malformed result. + +## 1.0.1 (2017-11-10) + +### Bug fixes + +Deleting the last character in a list item no longer results in a spurious hard_break node on Safari. + +Fixes a crash on IE11 when starting to drag. + +## 1.0.0 (2017-10-13) + +### Bug fixes + +Dragging nodes with a node view that handles its own mouse events should work better now. + +List item DOM nodes are no longer assigned `pointer-events: none` in the default style. Ctrl-clicking list markers now properly selects the list item again. + +Arrow-down through an empty textblock no longer causes the browser to forget the cursor's horizontal position. + +Copy-dragging on OS X is now done by holding option, rather than control, following the convention on that system. + +Fixes a crash related to decoration management. + +Fixes a problem where using cut on IE11 wouldn't actually remove the selected text. + +Copy/paste on Edge 15 and up now uses the clipboard API, fixing a problem that made them fail entirely. + +### New features + +The [`dragging`](https://prosemirror.net/docs/ref/#view.EditorView.dragging) property of a view, which contains information about editor content being dragged, is now part of the public interface. + +## 0.24.0 (2017-09-25) + +### New features + +The [`clipboardTextParser`](https://prosemirror.net/docs/ref/version/0.24.0.html#view.EditorProps.clipboardTextParser) prop is now passed a context position. + +## 0.23.0 (2017-09-13) + +### Breaking changes + +The `onFocus`, `onBlur`, and `handleContextMenu` props are no longer supported. You can achieve their effect with the [`handleDOMEvents`](https://prosemirror.net/docs/ref/version/0.23.0.html#view.EditorProps.handleDOMEvents) prop. + +### Bug fixes + +Fixes occasional crash when reading the selection in Firefox. + +Putting a table cell on the clipboard now properly wraps it in a table. + +The view will no longer scroll into view when receiving a state that isn't derived from its previous state. + +### New features + +Transactions caused by a paste now have their "paste" meta property set to true. + +Adds a new view prop, [`handleScrollToSelection`](https://prosemirror.net/docs/ref/version/0.23.0.html#view.EditorProps.handleScrollToSelection) to override the behavior of scrolling the selection into view. + +The new editor prop [`clipboardTextSerializer`](https://prosemirror.net/docs/ref/version/0.23.0.html#view.EditorProps.clipboardTextSerializer) allows you to override the way a piece of document is converted to clipboard text. + +Adds the editor prop [`clipboardTextParser`](https://prosemirror.net/docs/ref/version/0.23.0.html#view.EditorProps.clipboardTextParser), which can be used to define your own parsing strategy for clipboard text content. + +[`DecorationSet.find`](https://prosemirror.net/docs/ref/version/0.23.0.html#view.DecorationSet.find) now supports passing a predicate to filter decorations by spec. + +## 0.22.1 (2017-08-16) + +### Bug fixes + +Invisible selections that don't cover any content (i.e., a cursor) are now properly hidden. + +Initializing the editor view non-editable no longer causes a crash. + +## 0.22.0 (2017-06-29) + +### Bug fixes + +Fix an issue where moving the cursor through a text widget causes the editor to lose the selection in Chrome. + +Fixes an issue where down-arrow in front of a widget would sometimes not cause any cursor motion on Chrome. + +[Destroying](https://prosemirror.net/docs/ref/version/0.22.0.html#view.EditorView.destroy) a [mounted](https://prosemirror.net/docs/ref/version/0.22.0.html#view.EditorView.constructor) editor view no longer leaks event handlers. + +Display updates for regular, non-composition input are now synchronous, which should reduce flickering when, for example, updating decorations in response to typing. + +### New features + +The editor can now be initialized in a document other than the global document (say, an `iframe`). + +Editor views now have a [`domAtPos` method](https://prosemirror.net/docs/ref/version/0.22.0.html#view.EditorView.domAtPos), which gives you the DOM position corresponding to a given document position. + +## 0.21.1 (2017-05-09) + +### Bug fixes + +Copying and pasting table cells on Edge no longer strips the table structure. + +## 0.21.0 (2017-05-03) + +### Breaking changes + +The `associative` option to widget decorations is no longer supported. To make a widget left-associative, set its `side` option to a negative number. `associative` will continue to work with a warning until the next release. + +### New features + +[Widget decorations](https://prosemirror.net/docs/ref/version/0.21.0.html#view.Decoration^widget) now support a `side` option that controls which side of them the cursor is drawn, where they move when content is inserted at their position, and the order in which they appear relative to other widgets at the same position. + +## 0.20.5 (2017-05-02) + +### Bug fixes + +Fixes an issue where the DOM selection could be shown on the wrong side of hard break or image nodes. + +## 0.20.4 (2017-04-24) + +### Bug fixes + +Fix a bug that prevented the DOM selection from being updated when the new position was near the old one in some circumstances. + +Stop interfering with alt-d keypresses on OS X. + +Fix issue where reading a DOM change in a previously empty node could crash. + +Fixes crash when reading a change that removed a decorated text node from the DOM. + +## 0.20.3 (2017-04-12) + +### Bug fixes + +Shift-pasting and pasting into a code block now does the right thing on IE and Edge. + +## 0.20.2 (2017-04-05) + +### Bug fixes + +Fixes a bug that broke dragging from the editor. + +## 0.20.1 (2017-04-04) + +### Bug fixes + +Typing in code blocks no longer replaces newlines with spaces. + +Copy and paste on Internet Explorer, Edge, and mobile Safari should now behave more like it does on other browsers. Handlers are called, and the changes to the document are made by ProseMirror's code, not the browser. + +Fixes a problem where triple-clicking the editor would sometimes cause the scroll position to inexplicably jump around on IE11. + +## 0.20.0 (2017-04-03) + +### Breaking changes + +The `inclusiveLeft` and `inclusiveRight` options to inline decorations were renamed to [`inclusiveStart`](https://prosemirror.net/docs/ref/version/0.20.0.html#view.Decoration^inline^spec.inclusiveStart) and [`inclusiveEnd`](https://prosemirror.net/docs/ref/version/0.20.0.html#view.Decoration^inline^spec.inclusiveEnd) so that they also make sense in right-to-left text. The old names work with a warning until the next release. + +The default styling for lists and blockquotes was removed from `prosemirror.css`. (They were moved to the [`example-setup`](https://github.com/ProseMirror/prosemirror-example-setup) module.) + +### Bug fixes + +Fixes reading of selection in Chrome in a shadow DOM. + +Registering DOM event handlers that the editor doesn't listen to by default with the `handleDOMEvents` prop should work again. + +Backspacing after turning off a mark now works again in Firefox. + +### New features + +The new props [`handlePaste`](https://prosemirror.net/docs/ref/version/0.20.0.html#view.EditorProps.handlePaste) and [`handleDrop`](https://prosemirror.net/docs/ref/version/0.20.0.html#view.EditorProps.handleDrop) can be used to override drop and paste behavior. + +## 0.19.1 (2017-03-18) + +### Bug fixes + +Fixes a number of issues with characters being duplicated or disappearing when typing on mark boundaries. + +## 0.19.0 (2017-03-16) + +### Breaking changes + +[`endOfTextblock`](https://prosemirror.net/docs/ref/version/0.19.0.html#view.EditorView.endOfTextblock) no longer always returns false for horizontal motion on non-cursor selections, but checks the position of the selection head instead. + +### Bug fixes + +Typing after adding/removing a mark no longer briefly shows the new text with the wrong marks. + +[`posAtCoords`](https://prosemirror.net/docs/ref/version/0.19.0.html#view.EditorView.posAtCoords) is now more reliable on modern browsers by using browser APIs. + +Fix a bug where the view would in some circumstances leave superfluous DOM nodes around inside marks. + +### New features + +You can now override the selection the editor creates for a given DOM selection with the [`createSelectionBetween`](https://prosemirror.net/docs/ref/version/0.19.0.html#view.EditorProps.createSelectionBetween) prop. + +## 0.18.0 (2017-02-24) + +### Breaking changes + +`Decoration` objects now store their definition object under [`spec`](https://prosemirror.net/docs/ref/version/0.18.0.html#Decoration.spec), not `options`. The old property name still works, with a warning, until the next release. + +### Bug fixes + +Fix bug where calling [`focus`](https://prosemirror.net/docs/ref/version/0.18.0.html#view.EditorView.focus) when there was a text selection would sometimes result in `state.selection` receiving an incorrect value. + +[`EditorView.props`](https://prosemirror.net/docs/ref/version/0.18.0.html#view.EditorView.props) now has its `state` property updated when you call `updateState`. + +Putting decorations on or inside a node view with an `update` method now works. + +### New features + +[Plugin view](https://prosemirror.net/docs/ref/version/0.18.0.html#state.PluginSpec.view) update methods are now passed the view's previous state as second argument. + +The `place` agument to the [`EditorView` constructor](https://prosemirror.net/docs/ref/version/0.18.0.html#view.EditorView) can now be an object with a `mount` property to directly provide the node that should be made editable. + +The new [`EditorView.setProps` method](https://prosemirror.net/docs/ref/version/0.18.0.html#view.EditorView.setProps) makes it easier to update individual props. + +## 0.17.7 (2017-02-08) + +### Bug fixes + +Fixes crash in the code that maintains the scroll position when the document is empty or hidden. + +## 0.17.6 (2017-02-08) + +### Bug fixes + +Transactions that shouldn't [scroll the selection into view](https://prosemirror.net/docs/ref/version/0.17.0.html#state.transaction.scrollIntoView) now no longer do so. + +## 0.17.4 (2017-02-02) + +### Bug fixes + +Fixes bug where widget decorations would sometimes get parsed as content when editing near them. + +The editor now prevents the behavior of Ctrl-d and Ctrl-h on textblock boundaries on OS X, as intended. + +Make sure long words don't cause a horizontal scrollbar in Firefox + +Various behavior fixes for IE11. + +## 0.17.3 (2017-01-19) + +### Bug fixes + +DOM changes deleting a node's inner wrapping DOM element (for example the `` tag in a schema-basic code block) no longer break the editor. + +## 0.17.2 (2017-01-16) + +### Bug fixes + +Call custom click handlers before applying select-node behavior for a ctrl/cmd-click. + +Fix failure to apply DOM changes that start at document position 0. + +## 0.17.1 (2017-01-07) + +### Bug fixes + +Fix issue where a document update that left the selection in the same place sometimes led to an incorrect DOM selection. + +Make sure [`EditorView.focus`](https://prosemirror.net/docs/ref/version/0.17.0.html#view.EditorView.focus) doesn't cause the browser to scroll the top of the editor into view. + +## 0.17.0 (2017-01-05) + +### Breaking changes + +The `handleDOMEvent` prop has been dropped in favor of the [`handleDOMEvents`](https://prosemirror.net/docs/ref/version/0.17.0.html#view.EditorProps.handleDOMEvents) (plural) prop. + +The `onChange` prop has been replaced by a [`dispatchTransaction`](https://prosemirror.net/docs/ref/version/0.17.0.html#view.EditorProps.dispatchTransaction) prop (which takes a transaction instead of an action). + +### New features + +Added support for a [`handleDOMEvents` prop](https://prosemirror.net/docs/ref/version/0.17.0.html#view.EditorProps.handleDOMEvents), which allows you to provide handler functions per DOM event, and works even for events that the editor doesn't normally add a handler for. + +Add view method [`dispatch`](https://prosemirror.net/docs/ref/version/0.17.0.html#view.EditorView.dispatch), which provides a convenient way to dispatch transactions. + +The [`dispatchTransaction`](https://prosemirror.net/docs/ref/version/0.17.0.html#view.EditorProps.dispatchTransaction) (used to be `onAction`) prop is now optional, and will default to simply applying the transaction to the current view state. + +[Widget decorations](https://prosemirror.net/docs/ref/version/0.17.0.html#view.Decoration.widget) now accept an option `associative` which can be used to configure on which side of content inserted at their position they end up. + +Typing immediately after deleting text now preserves the marks of the deleted text. + +Transactions that update the selection because of mouse or touch input now get a metadata property `pointer` with the value `true`. + +## 0.16.0 (2016-12-23) + +### Bug fixes + +Solve problem where setting a node selection would trigger a DOM read, leading to the selection being reset. + +## 0.16.0 (2016-12-23) + +### Breaking changes + +The `spellcheck`, `label`, and `class` props are now replaced by an [`attributes` prop](https://prosemirror.net/docs/ref/version/0.16.0.html#view.EditorProps.attributes). + +### Bug fixes + +Ignoring/aborting an action should no longer lead to the DOM being stuck in an outdated state. + +Typing at the end of a textblock which ends in a non-text node now actually works. + +DOM nodes for leaf document nodes are now set as non-editable to prevent various issues such as stray cursors inside of them and Firefox adding image resize controls. + +Inserting a node no longer causes nodes of the same type after it to be neednessly redrawn. + +### New features + +Add a new editor prop [`editable`](https://prosemirror.net/docs/ref/version/0.16.0.html#view.EditorProps.editable) which controls whether the editor's `contentEditable` behavior is enabled. + +Plugins and props can now set any DOM attribute on the outer editor node using the [`attributes` prop](https://prosemirror.net/docs/ref/version/0.16.0.html#view.EditorProps.attributes). + +Node view constructors and update methods now have access to the node's wrapping decorations, which can be used to pass information to a node view without encoding it in the document. + +Attributes added or removed by node and inline [decorations](https://prosemirror.net/docs/ref/version/0.16.0.html#view.Decoration) no longer cause the nodes inside of them to be fully redrawn, making node views more stable and allowing CSS transitions to be used. + +## 0.15.2 (2016-12-10) + +### Bug fixes + +The native selection is now appropriately hidden when there is a node selection. + +## 0.15.1 (2016-12-10) + +### Bug fixes + +Fix DOM parsing for decorated text nodes. + +## 0.15.0 (2016-12-10) + +### Breaking changes + +The editor view no longer wraps its editable DOM element in a wrapper element. The `ProseMirror` CSS class now applies directly to the editable element. The `ProseMirror-content` CSS class is still present for ease of upgrading but will be dropped in the next release. + +The editor view no longer draws a drop cursor when dragging content over the editor. The new [`prosemirror-dropcursor`](https://github.com/prosemirror/prosemirror-dropcursor) module implements this as a plugin. + +### Bug fixes + +Simple typing and backspacing now gets handled by the browser without ProseMirror redrawing the touched nodes, making spell-checking and various platform-specific input tricks (long-press on OS X, double space on iOS) work in the editor. + +Improve tracking of DOM nodes that have been touched by user changes, so that [`updateState`](https://prosemirror.net/docs/ref/version/0.15.0.html#view.EditorView.updateState) can reliably fix them. + +Changes to the document that happen while dragging editor content no longer break moving of the content. + +Adding or removing a mark directly in the DOM (for example with the bold/italic buttons in iOS' context menu) now produces mark steps, rather than replace steps. + +Pressing backspace at the start of a paragraph on Android now allows key handlers for backspace to fire. + +Toggling a mark when there is no selection now works better on mobile platforms. + +### New features + +Introduces an [`endOfTextblock`](https://prosemirror.net/docs/ref/version/0.15.0.html#view.EditorView.endOfTextblock) method on views, which can be used to find out in a bidi- and layout-aware way whether the selection is on the edge of a textblock. + +## 0.14.4 (2016-12-02) + +### Bug fixes + +Fix issue where node decorations would stick around in the DOM after the decoration was removed. + +Setting or removing a node selection in an unfocused editor now properly updates the DOM to show that selection. + +## 0.14.2 (2016-11-30) + +### Bug fixes + +FIX: Avoid unneeded selection resets which sometimes confused browsers. + +## 0.14.2 (2016-11-29) + +### Bug fixes + +Fix a bug where inverted selections weren't created in the DOM correctly. + +## 0.14.1 (2016-11-29) + +### Bug fixes + +Restores previously broken kludge that allows the cursor to appear after non-text content at the end of a line. + +## 0.14.0 (2016-11-28) + +### Breaking changes + +Wrapping decorations are now created using the [`nodeName`](https://prosemirror.net/docs/ref/version/0.14.0.html#view.DecorationAttrs.nodeName) property. The `wrapper` property is no longer supported. + +The `onUnmountDOM` prop is no longer supported (use a node view with a [`destroy`](https://prosemirror.net/docs/ref/version/0.14.0.html#view.NodeView.destroy) method instead). + +The `domSerializer` prop is no longer supported. Use [node views](https://prosemirror.net/docs/ref/version/0.14.0.html#view.EditorProps.nodeViews) to configure editor-specific node representations. + +### New features + +Widget decorations can now be given a [`key`](https://prosemirror.net/docs/ref/version/0.14.0.html#view.Decoration.widget^options.key) property to prevent unneccesary redraws. + +The `EditorView` class now has a [`destroy`](https://prosemirror.net/docs/ref/version/0.14.0.html#view.EditorView.destroy) method for cleaning up. + +The [`handleClickOn`](https://prosemirror.net/docs/ref/version/0.14.0.html#view.EditorProps.handleClickOn) prop and friends now receive a `direct` boolean argument that indicates whether the node was clicked directly. + +[Widget decorations](https://prosemirror.net/docs/ref/version/0.14.0.html#view.Decoration^widget) now support a `stopEvent` option that can be used to control which DOM events that pass through them should be ignored by the editor view. + +You can now [specify](https://prosemirror.net/docs/ref/version/0.14.0.html#view.EditorProps.nodeViews) custom [node views](https://prosemirror.net/docs/ref/version/0.14.0.html#view.NodeView) for an editor view, which give you control over the way node of a given type are represented in the DOM. See the related [RFC](https://discuss.prosemirror.net/t/rfc-node-views-to-manage-the-representation-of-nodes/463). + +## 0.13.2 (2016-11-15) + +### Bug fixes + +Fixes an issue where widget decorations in the middle of text nodes would sometimes disappear. + +## 0.13.1 (2016-11-15) + +### Bug fixes + +Fixes event handler crash (and subsequent bad default behavior) when pasting some types of external HTML into an editor. + +## 0.13.0 (2016-11-11) + +### Breaking changes + +Selecting nodes on OS X is now done with cmd-leftclick rather than ctrl-leftclick. + +### Bug fixes + +Pasting text into a code block will now insert the raw text. + +Widget decorations at the start or end of a textblock no longer block horizontal cursor motion through them. + +Widget nodes at the end of textblocks are now reliably drawn during display updates. + +### New features + +[`DecorationSet.map`](https://prosemirror.net/docs/ref/version/0.13.0.html#view.DecorationSet.map) now takes an options object which allows you to specify an `onRemove` callback to be notified when remapping drops decorations. + +The [`transformPastedHTML`](https://prosemirror.net/docs/ref/version/0.13.0.html#view.EditorProps.transformPastedHTML) and [`transformPastedText`](https://prosemirror.net/docs/ref/version/0.13.0.html#view.EditorProps.transformPastedText) props were (re-)added, and can be used to clean up pasted content. + +## 0.12.2 (2016-11-02) + +### Bug fixes + +Inline decorations that span across an empty textblock no longer crash the display drawing code. + +## 0.12.1 (2016-11-01) + +### Bug fixes + +Use a separate document to parse pasted HTML to better protect +against cross-site scripting attacks. + +Specifying multiple classes in a decoration now actually works. + +Ignore empty inline decorations when building a decoration set. + +## 0.12.0 (2016-10-21) + +### Breaking changes + +The return value of +[`EditorView.posAtCoords`](https://prosemirror.net/docs/ref/version/0.12.0.html#view.EditorView.posAtCoords) changed to +contain an `inside` property pointing at the innermost node that the +coordinates are inside of. (Note that the docs for this method were +wrong in the previous release.) + +### Bug fixes + +Reduce reliance on shift-state tracking to minimize damage when +it gets out of sync. + +Fix bug that'd produce bogus document positions for DOM positions +inside non-document nodes. + +Don't treat fast ctrl-clicks as double or triple clicks. + +### New features + +Implement [decorations](https://prosemirror.net/docs/ref/version/0.12.0.html#view.Decoration), a way to +influence the way the document is drawn. Add the [`decorations` +prop](https://prosemirror.net/docs/ref/version/0.12.0.html#view.EditorProps.decorations) to specify them. + +## 0.11.2 (2016-10-04) + +### Bug fixes + +Pass actual event object to [`handleDOMEvent`](https://prosemirror.net/docs/ref/version/0.11.0.html#view.EditorProps.handleDOMEvent), rather than just its name. + +Fix display corruption caused by using the wrong state as previous version during IME. + +## 0.11.0 (2016-09-21) + +### Breaking changes + +Moved into a separate module from the old `edit` submodule. Completely +new approach to managing the editor's DOM representation and input. + +Event handlers and options are now replaced by +[props](https://prosemirror.net/docs/ref/version/0.11.0.html#view.EditorProps). The view's state is now 'shallow', +represented entirely by a set of props, one of which holds an editor +state value from the [state](https://prosemirror.net/docs/ref/version/0.11.0.html#state) module. + +When the user interacts with the editor, it will pass an +[action](https://prosemirror.net/docs/ref/version/0.11.0.html#state.Action) to its +[`onAction`](https://prosemirror.net/docs/ref/version/0.11.0.html#view.EditorProps.onAction) prop, which is responsible +for triggering an view update. + +The `markRange` system was dropped, to be replaced in the next release +by a 'decoration' system. + +There is no keymap support in the view module anymore. Use a +[keymap](https://prosemirror.net/docs/ref/version/0.11.0.html#keymap) plugin for that. + +The undo [history](https://prosemirror.net/docs/ref/version/0.11.0.html#history) is now a separate plugin. + +CSS needed by the editor is no longer injected implicitly into the +page. Instead, you should arrange for the `style/prosemirror.css` file +to be loaded into your page. + +### New features + +The DOM [parser](https://prosemirror.net/docs/ref/version/0.11.0.html#model.DOMParser) and +[serializer](https://prosemirror.net/docs/ref/version/0.11.0.html#model.DOMSerializer) used to interact with the visible +DOM and the clipboard can now be customized through +[props](https://prosemirror.net/docs/ref/version/0.11.0.html#view.EditorProps). + +You can now provide a catch-all DOM +[event handler](https://prosemirror.net/docs/ref/version/0.11.0.html#view.EditorProps.handleDOMEvent) to get a first +chance at handling DOM events. + +The [`onUnmountDOM`](https://prosemirror.net/docs/ref/version/0.11.0.html#view.EditorProps.onUnmountDOM) can be used to +be notified when a piece of the document DOM is thrown away (in case +cleanup is needed). + diff --git a/packages/tiptap/node_modules/prosemirror-view/CONTRIBUTING.md b/packages/tiptap/node_modules/prosemirror-view/CONTRIBUTING.md new file mode 100644 index 0000000000..f2a345d830 --- /dev/null +++ b/packages/tiptap/node_modules/prosemirror-view/CONTRIBUTING.md @@ -0,0 +1,104 @@ +# How to contribute + +- [Getting help](#getting-help) +- [Submitting bug reports](#submitting-bug-reports) +- [Contributing code](#contributing-code) + +## Getting help + +Community discussion, questions, and informal bug reporting is done on the +[discuss.ProseMirror forum](http://discuss.prosemirror.net). + +## Submitting bug reports + +Report bugs on the +[GitHub issue tracker](http://github.com/prosemirror/prosemirror/issues). +Before reporting a bug, please read these pointers. + +- The issue tracker is for *bugs*, not requests for help. Questions + should be asked on the [forum](http://discuss.prosemirror.net). + +- Include information about the version of the code that exhibits the + problem. For browser-related issues, include the browser and browser + version on which the problem occurred. + +- Mention very precisely what went wrong. "X is broken" is not a good + bug report. What did you expect to happen? What happened instead? + Describe the exact steps a maintainer has to take to make the + problem occur. A screencast can be useful, but is no substitute for + a textual description. + +- A great way to make it easy to reproduce your problem, if it can not + be trivially reproduced on the website demos, is to submit a script + that triggers the issue. + +## Contributing code + +If you want to make a change that involves a significant overhaul of +the code or introduces a user-visible new feature, create an +[RFC](https://github.com/ProseMirror/rfcs/) first with your proposal. + +- Make sure you have a [GitHub Account](https://github.com/signup/free) + +- Fork the relevant repository + ([how to fork a repo](https://help.github.com/articles/fork-a-repo)) + +- Create a local checkout of the code. You can use the + [main repository](https://github.com/prosemirror/prosemirror) to + easily check out all core modules. + +- Make your changes, and commit them + +- Follow the code style of the rest of the project (see below). Run + `npm run lint` (in the main repository checkout) to make sure that + the linter is happy. + +- If your changes are easy to test or likely to regress, add tests in + the relevant `test/` directory. Either put them in an existing + `test-*.js` file, if they fit there, or add a new file. + +- Make sure all tests pass. Run `npm run test` to verify tests pass + (you will need Node.js v6+). + +- Submit a pull request ([how to create a pull request](https://help.github.com/articles/fork-a-repo)). + Don't put more than one feature/fix in a single pull request. + +By contributing code to ProseMirror you + + - Agree to license the contributed code under the project's [MIT + license](https://github.com/ProseMirror/prosemirror/blob/master/LICENSE). + + - Confirm that you have the right to contribute and license the code + in question. (Either you hold all rights on the code, or the rights + holder has explicitly granted the right to use it like this, + through a compatible open source license or through a direct + agreement with you.) + +### Coding standards + +- ES6 syntax, targeting an ES5 runtime (i.e. don't use library + elements added by ES6, don't use ES7/ES.next syntax). + +- 2 spaces per indentation level, no tabs. + +- No semicolons except when necessary. + +- Follow the surrounding code when it comes to spacing, brace + placement, etc. + +- Brace-less single-statement bodies are encouraged (whenever they + don't impact readability). + +- [getdocs](https://github.com/marijnh/getdocs)-style doc comments + above items that are part of the public API. + +- When documenting non-public items, you can put the type after a + single colon, so that getdocs doesn't pick it up and add it to the + API reference. + +- The linter (`npm run lint`) complains about unused variables and + functions. Prefix their names with an underscore to muffle it. + +- ProseMirror does *not* follow JSHint or JSLint prescribed style. + Patches that try to 'fix' code to pass one of these linters will not + be accepted. diff --git a/packages/tiptap/node_modules/prosemirror-view/LICENSE b/packages/tiptap/node_modules/prosemirror-view/LICENSE new file mode 100644 index 0000000000..ef9326c512 --- /dev/null +++ b/packages/tiptap/node_modules/prosemirror-view/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2015-2017 by Marijn Haverbeke and others + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/tiptap/node_modules/prosemirror-view/README.md b/packages/tiptap/node_modules/prosemirror-view/README.md new file mode 100644 index 0000000000..e83dfb7e06 --- /dev/null +++ b/packages/tiptap/node_modules/prosemirror-view/README.md @@ -0,0 +1,28 @@ +# prosemirror-view + +[ [**WEBSITE**](https://prosemirror.net) | [**ISSUES**](https://github.com/prosemirror/prosemirror/issues) | [**FORUM**](https://discuss.prosemirror.net) | [**GITTER**](https://gitter.im/ProseMirror/prosemirror) | [**CHANGELOG**](https://github.com/ProseMirror/prosemirror-view/blob/master/CHANGELOG.md) ] + +This is a [core module](https://prosemirror.net/docs/ref/#view) of [ProseMirror](https://prosemirror.net). +ProseMirror is a well-behaved rich semantic content editor based on +contentEditable, with support for collaborative editing and custom +document schemas. + +This [module](https://prosemirror.net/docs/ref/#view) exports the editor +view, which renders the current document in the browser, and handles +user events. + +The [project page](https://prosemirror.net) has more information, a +number of [examples](https://prosemirror.net/examples/) and the +[documentation](https://prosemirror.net/docs/). + +This code is released under an +[MIT license](https://github.com/prosemirror/prosemirror/tree/master/LICENSE). +There's a [forum](http://discuss.prosemirror.net) for general +discussion and support requests, and the +[Github bug tracker](https://github.com/prosemirror/prosemirror/issues) +is the place to report issues. + +We aim to be an inclusive, welcoming community. To make that explicit, +we have a [code of +conduct](http://contributor-covenant.org/version/1/1/0/) that applies +to communication around the project. diff --git a/packages/tiptap/node_modules/prosemirror-view/dist/index.es.js b/packages/tiptap/node_modules/prosemirror-view/dist/index.es.js new file mode 100644 index 0000000000..e4084e773c --- /dev/null +++ b/packages/tiptap/node_modules/prosemirror-view/dist/index.es.js @@ -0,0 +1,4966 @@ +import { TextSelection, Selection, NodeSelection } from 'prosemirror-state'; +import { DOMSerializer, Fragment, Mark, DOMParser, Slice } from 'prosemirror-model'; +import { dropPoint } from 'prosemirror-transform'; + +var result = {}; + +if (typeof navigator != "undefined" && typeof document != "undefined") { + var ie_edge = /Edge\/(\d+)/.exec(navigator.userAgent); + var ie_upto10 = /MSIE \d/.test(navigator.userAgent); + var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent); + + result.mac = /Mac/.test(navigator.platform); + var ie = result.ie = !!(ie_upto10 || ie_11up || ie_edge); + result.ie_version = ie_upto10 ? document.documentMode || 6 : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : null; + result.gecko = !ie && /gecko\/(\d+)/i.test(navigator.userAgent); + result.gecko_version = result.gecko && +(/Firefox\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1]; + var chrome = !ie && /Chrome\/(\d+)/.exec(navigator.userAgent); + result.chrome = !!chrome; + result.chrome_version = chrome && +chrome[1]; + result.ios = !ie && /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent); + result.android = /Android \d/.test(navigator.userAgent); + result.webkit = !ie && 'WebkitAppearance' in document.documentElement.style; + result.safari = /Apple Computer/.test(navigator.vendor); + result.webkit_version = result.webkit && +(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1]; +} + +var domIndex = function(node) { + for (var index = 0;; index++) { + node = node.previousSibling; + if (!node) { return index } + } +}; + +var parentNode = function(node) { + var parent = node.parentNode; + return parent && parent.nodeType == 11 ? parent.host : parent +}; + +var textRange = function(node, from, to) { + var range = document.createRange(); + range.setEnd(node, to == null ? node.nodeValue.length : to); + range.setStart(node, from || 0); + return range +}; + +// Scans forward and backward through DOM positions equivalent to the +// given one to see if the two are in the same place (i.e. after a +// text node vs at the end of that text node) +var isEquivalentPosition = function(node, off, targetNode, targetOff) { + return targetNode && (scanFor(node, off, targetNode, targetOff, -1) || + scanFor(node, off, targetNode, targetOff, 1)) +}; + +var atomElements = /^(img|br|input|textarea|hr)$/i; + +function scanFor(node, off, targetNode, targetOff, dir) { + for (;;) { + if (node == targetNode && off == targetOff) { return true } + if (off == (dir < 0 ? 0 : nodeSize(node))) { + var parent = node.parentNode; + if (parent.nodeType != 1 || hasBlockDesc(node) || atomElements.test(node.nodeName) || node.contentEditable == "false") + { return false } + off = domIndex(node) + (dir < 0 ? 0 : 1); + node = parent; + } else if (node.nodeType == 1) { + node = node.childNodes[off + (dir < 0 ? -1 : 0)]; + off = dir < 0 ? nodeSize(node) : 0; + } else { + return false + } + } +} + +function nodeSize(node) { + return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length +} + +function hasBlockDesc(dom) { + var desc; + for (var cur = dom; cur; cur = cur.parentNode) { if (desc = cur.pmViewDesc) { break } } + return desc && desc.node && desc.node.isBlock && (desc.dom == dom || desc.contentDOM == dom) +} + +// Work around Chrome issue https://bugs.chromium.org/p/chromium/issues/detail?id=447523 +// (isCollapsed inappropriately returns true in shadow dom) +var selectionCollapsed = function(domSel) { + var collapsed = domSel.isCollapsed; + if (collapsed && result.chrome && domSel.rangeCount && !domSel.getRangeAt(0).collapsed) + { collapsed = false; } + return collapsed +}; + +function keyEvent(keyCode, key) { + var event = document.createEvent("Event"); + event.initEvent("keydown", true, true); + event.keyCode = keyCode; + event.key = event.code = key; + return event +} + +function windowRect(win) { + return {left: 0, right: win.innerWidth, + top: 0, bottom: win.innerHeight} +} + +function getSide(value, side) { + return typeof value == "number" ? value : value[side] +} + +function scrollRectIntoView(view, rect, startDOM) { + var scrollThreshold = view.someProp("scrollThreshold") || 0, scrollMargin = view.someProp("scrollMargin") || 5; + var doc = view.dom.ownerDocument, win = doc.defaultView; + for (var parent = startDOM || view.dom;; parent = parentNode(parent)) { + if (!parent) { break } + if (parent.nodeType != 1) { continue } + var atTop = parent == doc.body || parent.nodeType != 1; + var bounding = atTop ? windowRect(win) : parent.getBoundingClientRect(); + var moveX = 0, moveY = 0; + if (rect.top < bounding.top + getSide(scrollThreshold, "top")) + { moveY = -(bounding.top - rect.top + getSide(scrollMargin, "top")); } + else if (rect.bottom > bounding.bottom - getSide(scrollThreshold, "bottom")) + { moveY = rect.bottom - bounding.bottom + getSide(scrollMargin, "bottom"); } + if (rect.left < bounding.left + getSide(scrollThreshold, "left")) + { moveX = -(bounding.left - rect.left + getSide(scrollMargin, "left")); } + else if (rect.right > bounding.right - getSide(scrollThreshold, "right")) + { moveX = rect.right - bounding.right + getSide(scrollMargin, "right"); } + if (moveX || moveY) { + if (atTop) { + win.scrollBy(moveX, moveY); + } else { + if (moveY) { parent.scrollTop += moveY; } + if (moveX) { parent.scrollLeft += moveX; } + } + } + if (atTop) { break } + } +} + +// Store the scroll position of the editor's parent nodes, along with +// the top position of an element near the top of the editor, which +// will be used to make sure the visible viewport remains stable even +// when the size of the content above changes. +function storeScrollPos(view) { + var rect = view.dom.getBoundingClientRect(), startY = Math.max(0, rect.top); + var refDOM, refTop; + for (var x = (rect.left + rect.right) / 2, y = startY + 1; + y < Math.min(innerHeight, rect.bottom); y += 5) { + var dom = view.root.elementFromPoint(x, y); + if (dom == view.dom || !view.dom.contains(dom)) { continue } + var localRect = dom.getBoundingClientRect(); + if (localRect.top >= startY - 20) { + refDOM = dom; + refTop = localRect.top; + break + } + } + return {refDOM: refDOM, refTop: refTop, stack: scrollStack(view.dom)} +} + +function scrollStack(dom) { + var stack = [], doc = dom.ownerDocument; + for (; dom; dom = parentNode(dom)) { + stack.push({dom: dom, top: dom.scrollTop, left: dom.scrollLeft}); + if (dom == doc) { break } + } + return stack +} + +// Reset the scroll position of the editor's parent nodes to that what +// it was before, when storeScrollPos was called. +function resetScrollPos(ref) { + var refDOM = ref.refDOM; + var refTop = ref.refTop; + var stack = ref.stack; + + var newRefTop = refDOM ? refDOM.getBoundingClientRect().top : 0; + restoreScrollStack(stack, newRefTop == 0 ? 0 : newRefTop - refTop); +} + +function restoreScrollStack(stack, dTop) { + for (var i = 0; i < stack.length; i++) { + var ref = stack[i]; + var dom = ref.dom; + var top = ref.top; + var left = ref.left; + if (dom.scrollTop != top + dTop) { dom.scrollTop = top + dTop; } + if (dom.scrollLeft != left) { dom.scrollLeft = left; } + } +} + +var preventScrollSupported = null; +// Feature-detects support for .focus({preventScroll: true}), and uses +// a fallback kludge when not supported. +function focusPreventScroll(dom) { + if (dom.setActive) { return dom.setActive() } // in IE + if (preventScrollSupported) { return dom.focus(preventScrollSupported) } + + var stored = scrollStack(dom); + dom.focus(preventScrollSupported == null ? { + get preventScroll() { + preventScrollSupported = {preventScroll: true}; + return true + } + } : undefined); + if (!preventScrollSupported) { + preventScrollSupported = false; + restoreScrollStack(stored, 0); + } +} + +function findOffsetInNode(node, coords) { + var closest, dxClosest = 2e8, coordsClosest, offset = 0; + var rowBot = coords.top, rowTop = coords.top; + for (var child = node.firstChild, childIndex = 0; child; child = child.nextSibling, childIndex++) { + var rects = (void 0); + if (child.nodeType == 1) { rects = child.getClientRects(); } + else if (child.nodeType == 3) { rects = textRange(child).getClientRects(); } + else { continue } + + for (var i = 0; i < rects.length; i++) { + var rect = rects[i]; + if (rect.top <= rowBot && rect.bottom >= rowTop) { + rowBot = Math.max(rect.bottom, rowBot); + rowTop = Math.min(rect.top, rowTop); + var dx = rect.left > coords.left ? rect.left - coords.left + : rect.right < coords.left ? coords.left - rect.right : 0; + if (dx < dxClosest) { + closest = child; + dxClosest = dx; + coordsClosest = dx && closest.nodeType == 3 ? {left: rect.right < coords.left ? rect.right : rect.left, top: coords.top} : coords; + if (child.nodeType == 1 && dx) + { offset = childIndex + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0); } + continue + } + } + if (!closest && (coords.left >= rect.right && coords.top >= rect.top || + coords.left >= rect.left && coords.top >= rect.bottom)) + { offset = childIndex + 1; } + } + } + if (closest && closest.nodeType == 3) { return findOffsetInText(closest, coordsClosest) } + if (!closest || (dxClosest && closest.nodeType == 1)) { return {node: node, offset: offset} } + return findOffsetInNode(closest, coordsClosest) +} + +function findOffsetInText(node, coords) { + var len = node.nodeValue.length; + var range = document.createRange(); + for (var i = 0; i < len; i++) { + range.setEnd(node, i + 1); + range.setStart(node, i); + var rect = singleRect(range, 1); + if (rect.top == rect.bottom) { continue } + if (inRect(coords, rect)) + { return {node: node, offset: i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0)} } + } + return {node: node, offset: 0} +} + +function inRect(coords, rect) { + return coords.left >= rect.left - 1 && coords.left <= rect.right + 1&& + coords.top >= rect.top - 1 && coords.top <= rect.bottom + 1 +} + +function targetKludge(dom, coords) { + var parent = dom.parentNode; + if (parent && /^li$/i.test(parent.nodeName) && coords.left < dom.getBoundingClientRect().left) + { return parent } + return dom +} + +function posFromElement(view, elt, coords) { + var ref = findOffsetInNode(elt, coords); + var node = ref.node; + var offset = ref.offset; + var bias = -1; + if (node.nodeType == 1 && !node.firstChild) { + var rect = node.getBoundingClientRect(); + bias = rect.left != rect.right && coords.left > (rect.left + rect.right) / 2 ? 1 : -1; + } + return view.docView.posFromDOM(node, offset, bias) +} + +function posFromCaret(view, node, offset, coords) { + // Browser (in caretPosition/RangeFromPoint) will agressively + // normalize towards nearby inline nodes. Since we are interested in + // positions between block nodes too, we first walk up the hierarchy + // of nodes to see if there are block nodes that the coordinates + // fall outside of. If so, we take the position before/after that + // block. If not, we call `posFromDOM` on the raw node/offset. + var outside = -1; + for (var cur = node;;) { + if (cur == view.dom) { break } + var desc = view.docView.nearestDesc(cur, true); + if (!desc) { return null } + if (desc.node.isBlock && desc.parent) { + var rect = desc.dom.getBoundingClientRect(); + if (rect.left > coords.left || rect.top > coords.top) { outside = desc.posBefore; } + else if (rect.right < coords.left || rect.bottom < coords.top) { outside = desc.posAfter; } + else { break } + } + cur = desc.dom.parentNode; + } + return outside > -1 ? outside : view.docView.posFromDOM(node, offset) +} + +function elementFromPoint(element, coords, box) { + var len = element.childNodes.length; + if (len && box.top < box.bottom) { + for (var startI = Math.max(0, Math.min(len - 1, Math.floor(len * (coords.top - box.top) / (box.bottom - box.top)) - 2)), i = startI;;) { + var child = element.childNodes[i]; + if (child.nodeType == 1) { + var rects = child.getClientRects(); + for (var j = 0; j < rects.length; j++) { + var rect = rects[j]; + if (inRect(coords, rect)) { return elementFromPoint(child, coords, rect) } + } + } + if ((i = (i + 1) % len) == startI) { break } + } + } + return element +} + +// Given an x,y position on the editor, get the position in the document. +function posAtCoords(view, coords) { + var assign, assign$1; + + var root = view.root, node, offset; + if (root.caretPositionFromPoint) { + try { // Firefox throws for this call in hard-to-predict circumstances (#994) + var pos$1 = root.caretPositionFromPoint(coords.left, coords.top); + if (pos$1) { ((assign = pos$1, node = assign.offsetNode, offset = assign.offset)); } + } catch (_) {} + } + if (!node && root.caretRangeFromPoint) { + var range = root.caretRangeFromPoint(coords.left, coords.top); + if (range) { ((assign$1 = range, node = assign$1.startContainer, offset = assign$1.startOffset)); } + } + + var elt = root.elementFromPoint(coords.left, coords.top + 1), pos; + if (!elt || !view.dom.contains(elt.nodeType != 1 ? elt.parentNode : elt)) { + var box = view.dom.getBoundingClientRect(); + if (!inRect(coords, box)) { return null } + elt = elementFromPoint(view.dom, coords, box); + if (!elt) { return null } + } + elt = targetKludge(elt, coords); + if (node) { + if (result.gecko && node.nodeType == 1) { + // Firefox will sometimes return offsets into nodes, which + // have no actual children, from caretPositionFromPoint (#953) + offset = Math.min(offset, node.childNodes.length); + // It'll also move the returned position before image nodes, + // even if those are behind it. + if (offset < node.childNodes.length) { + var next = node.childNodes[offset], box$1; + if (next.nodeName == "IMG" && (box$1 = next.getBoundingClientRect()).right <= coords.left && + box$1.bottom > coords.top) + { offset++; } + } + } + // Suspiciously specific kludge to work around caret*FromPoint + // never returning a position at the end of the document + if (node == view.dom && offset == node.childNodes.length - 1 && node.lastChild.nodeType == 1 && + coords.top > node.lastChild.getBoundingClientRect().bottom) + { pos = view.state.doc.content.size; } + // Ignore positions directly after a BR, since caret*FromPoint + // 'round up' positions that would be more accurately placed + // before the BR node. + else if (offset == 0 || node.nodeType != 1 || node.childNodes[offset - 1].nodeName != "BR") + { pos = posFromCaret(view, node, offset, coords); } + } + if (pos == null) { pos = posFromElement(view, elt, coords); } + + var desc = view.docView.nearestDesc(elt, true); + return {pos: pos, inside: desc ? desc.posAtStart - desc.border : -1} +} + +function singleRect(object, bias) { + var rects = object.getClientRects(); + return !rects.length ? object.getBoundingClientRect() : rects[bias < 0 ? 0 : rects.length - 1] +} + +// : (EditorView, number) → {left: number, top: number, right: number, bottom: number} +// Given a position in the document model, get a bounding box of the +// character at that position, relative to the window. +function coordsAtPos(view, pos) { + var ref = view.docView.domFromPos(pos); + var node = ref.node; + var offset = ref.offset; + + // These browsers support querying empty text ranges + if (node.nodeType == 3 && (result.chrome || result.gecko)) { + var rect = singleRect(textRange(node, offset, offset), 0); + // Firefox returns bad results (the position before the space) + // when querying a position directly after line-broken + // whitespace. Detect this situation and and kludge around it + if (result.gecko && offset && /\s/.test(node.nodeValue[offset - 1]) && offset < node.nodeValue.length) { + var rectBefore = singleRect(textRange(node, offset - 1, offset - 1), -1); + if (Math.abs(rectBefore.left - rect.left) < 1 && rectBefore.top == rect.top) { + var rectAfter = singleRect(textRange(node, offset, offset + 1), -1); + return flattenV(rectAfter, rectAfter.left < rectBefore.left) + } + } + return rect + } + + if (node.nodeType == 1 && !view.state.doc.resolve(pos).parent.inlineContent) { + // Return a horizontal line in block context + var top = true, rect$1; + if (offset < node.childNodes.length) { + var after = node.childNodes[offset]; + if (after.nodeType == 1) { rect$1 = after.getBoundingClientRect(); } + } + if (!rect$1 && offset) { + var before = node.childNodes[offset - 1]; + if (before.nodeType == 1) { rect$1 = before.getBoundingClientRect(); top = false; } + } + return flattenH(rect$1 || node.getBoundingClientRect(), top) + } + + // Not Firefox/Chrome, or not in a text node, so we have to use + // actual element/character rectangles to get a solution (this part + // is not very bidi-safe) + // + // Try the left side first, fall back to the right one if that + // doesn't work. + for (var dir = -1; dir < 2; dir += 2) { + if (dir < 0 && offset) { + var prev = (void 0), target = node.nodeType == 3 ? textRange(node, offset - 1, offset) + : (prev = node.childNodes[offset - 1]).nodeType == 3 ? textRange(prev) + : prev.nodeType == 1 && prev.nodeName != "BR" ? prev : null; // BR nodes tend to only return the rectangle before them + if (target) { + var rect$2 = singleRect(target, 1); + if (rect$2.top < rect$2.bottom) { return flattenV(rect$2, false) } + } + } else if (dir > 0 && offset < nodeSize(node)) { + var next = (void 0), target$1 = node.nodeType == 3 ? textRange(node, offset, offset + 1) + : (next = node.childNodes[offset]).nodeType == 3 ? textRange(next) + : next.nodeType == 1 ? next : null; + if (target$1) { + var rect$3 = singleRect(target$1, -1); + if (rect$3.top < rect$3.bottom) { return flattenV(rect$3, true) } + } + } + } + // All else failed, just try to get a rectangle for the target node + return flattenV(singleRect(node.nodeType == 3 ? textRange(node) : node, 0), false) +} + +function flattenV(rect, left) { + if (rect.width == 0) { return rect } + var x = left ? rect.left : rect.right; + return {top: rect.top, bottom: rect.bottom, left: x, right: x} +} + +function flattenH(rect, top) { + if (rect.height == 0) { return rect } + var y = top ? rect.top : rect.bottom; + return {top: y, bottom: y, left: rect.left, right: rect.right} +} + +function withFlushedState(view, state, f) { + var viewState = view.state, active = view.root.activeElement; + if (viewState != state) { view.updateState(state); } + if (active != view.dom) { view.focus(); } + try { + return f() + } finally { + if (viewState != state) { view.updateState(viewState); } + if (active != view.dom) { active.focus(); } + } +} + +// : (EditorView, number, number) +// Whether vertical position motion in a given direction +// from a position would leave a text block. +function endOfTextblockVertical(view, state, dir) { + var sel = state.selection; + var $pos = dir == "up" ? sel.$anchor.min(sel.$head) : sel.$anchor.max(sel.$head); + return withFlushedState(view, state, function () { + var ref = view.docView.domFromPos($pos.pos); + var dom = ref.node; + for (;;) { + var nearest = view.docView.nearestDesc(dom, true); + if (!nearest) { break } + if (nearest.node.isBlock) { dom = nearest.dom; break } + dom = nearest.dom.parentNode; + } + var coords = coordsAtPos(view, $pos.pos); + for (var child = dom.firstChild; child; child = child.nextSibling) { + var boxes = (void 0); + if (child.nodeType == 1) { boxes = child.getClientRects(); } + else if (child.nodeType == 3) { boxes = textRange(child, 0, child.nodeValue.length).getClientRects(); } + else { continue } + for (var i = 0; i < boxes.length; i++) { + var box = boxes[i]; + if (box.bottom > box.top && (dir == "up" ? box.bottom < coords.top + 1 : box.top > coords.bottom - 1)) + { return false } + } + } + return true + }) +} + +var maybeRTL = /[\u0590-\u08ac]/; + +function endOfTextblockHorizontal(view, state, dir) { + var ref = state.selection; + var $head = ref.$head; + if (!$head.parent.isTextblock) { return false } + var offset = $head.parentOffset, atStart = !offset, atEnd = offset == $head.parent.content.size; + var sel = getSelection(); + // If the textblock is all LTR, or the browser doesn't support + // Selection.modify (Edge), fall back to a primitive approach + if (!maybeRTL.test($head.parent.textContent) || !sel.modify) + { return dir == "left" || dir == "backward" ? atStart : atEnd } + + return withFlushedState(view, state, function () { + // This is a huge hack, but appears to be the best we can + // currently do: use `Selection.modify` to move the selection by + // one character, and see if that moves the cursor out of the + // textblock (or doesn't move it at all, when at the start/end of + // the document). + var oldRange = sel.getRangeAt(0), oldNode = sel.focusNode, oldOff = sel.focusOffset; + var oldBidiLevel = sel.caretBidiLevel; // Only for Firefox + sel.modify("move", dir, "character"); + var parentDOM = $head.depth ? view.docView.domAfterPos($head.before()) : view.dom; + var result = !parentDOM.contains(sel.focusNode.nodeType == 1 ? sel.focusNode : sel.focusNode.parentNode) || + (oldNode == sel.focusNode && oldOff == sel.focusOffset); + // Restore the previous selection + sel.removeAllRanges(); + sel.addRange(oldRange); + if (oldBidiLevel != null) { sel.caretBidiLevel = oldBidiLevel; } + return result + }) +} + +var cachedState = null, cachedDir = null, cachedResult = false; +function endOfTextblock(view, state, dir) { + if (cachedState == state && cachedDir == dir) { return cachedResult } + cachedState = state; cachedDir = dir; + return cachedResult = dir == "up" || dir == "down" + ? endOfTextblockVertical(view, state, dir) + : endOfTextblockHorizontal(view, state, dir) +} + +// NodeView:: interface +// +// By default, document nodes are rendered using the result of the +// [`toDOM`](#model.NodeSpec.toDOM) method of their spec, and managed +// entirely by the editor. For some use cases, such as embedded +// node-specific editing interfaces, you want more control over +// the behavior of a node's in-editor representation, and need to +// [define](#view.EditorProps.nodeViews) a custom node view. +// +// Objects returned as node views must conform to this interface. +// +// dom:: ?dom.Node +// The outer DOM node that represents the document node. When not +// given, the default strategy is used to create a DOM node. +// +// contentDOM:: ?dom.Node +// The DOM node that should hold the node's content. Only meaningful +// if the node view also defines a `dom` property and if its node +// type is not a leaf node type. When this is present, ProseMirror +// will take care of rendering the node's children into it. When it +// is not present, the node view itself is responsible for rendering +// (or deciding not to render) its child nodes. +// +// update:: ?(node: Node, decorations: [Decoration]) → bool +// When given, this will be called when the view is updating itself. +// It will be given a node (possibly of a different type), and an +// array of active decorations (which are automatically drawn, and +// the node view may ignore if it isn't interested in them), and +// should return true if it was able to update to that node, and +// false otherwise. If the node view has a `contentDOM` property (or +// no `dom` property), updating its child nodes will be handled by +// ProseMirror. +// +// selectNode:: ?() +// Can be used to override the way the node's selected status (as a +// node selection) is displayed. +// +// deselectNode:: ?() +// When defining a `selectNode` method, you should also provide a +// `deselectNode` method to remove the effect again. +// +// setSelection:: ?(anchor: number, head: number, root: dom.Document) +// This will be called to handle setting the selection inside the +// node. The `anchor` and `head` positions are relative to the start +// of the node. By default, a DOM selection will be created between +// the DOM positions corresponding to those positions, but if you +// override it you can do something else. +// +// stopEvent:: ?(event: dom.Event) → bool +// Can be used to prevent the editor view from trying to handle some +// or all DOM events that bubble up from the node view. Events for +// which this returns true are not handled by the editor. +// +// ignoreMutation:: ?(dom.MutationRecord) → bool +// Called when a DOM +// [mutation](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) +// or a selection change happens within the view. When the change is +// a selection change, the record will have a `type` property of +// `"selection"` (which doesn't occur for native mutation records). +// Return false if the editor should re-read the selection or +// re-parse the range around the mutation, true if it can safely be +// ignored. +// +// destroy:: ?() +// Called when the node view is removed from the editor or the whole +// editor is destroyed. + +// View descriptions are data structures that describe the DOM that is +// used to represent the editor's content. They are used for: +// +// - Incremental redrawing when the document changes +// +// - Figuring out what part of the document a given DOM position +// corresponds to +// +// - Wiring in custom implementations of the editing interface for a +// given node +// +// They form a doubly-linked mutable tree, starting at `view.docView`. + +var NOT_DIRTY = 0, CHILD_DIRTY = 1, CONTENT_DIRTY = 2, NODE_DIRTY = 3; + +// Superclass for the various kinds of descriptions. Defines their +// basic structure and shared methods. +var ViewDesc = function ViewDesc(parent, children, dom, contentDOM) { + this.parent = parent; + this.children = children; + this.dom = dom; + // An expando property on the DOM node provides a link back to its + // description. + dom.pmViewDesc = this; + // This is the node that holds the child views. It may be null for + // descs that don't have children. + this.contentDOM = contentDOM; + this.dirty = NOT_DIRTY; +}; + +var prototypeAccessors = { beforePosition: { configurable: true },size: { configurable: true },border: { configurable: true },posBefore: { configurable: true },posAtStart: { configurable: true },posAfter: { configurable: true },posAtEnd: { configurable: true },contentLost: { configurable: true } }; + +// Used to check whether a given description corresponds to a +// widget/mark/node. +ViewDesc.prototype.matchesWidget = function matchesWidget () { return false }; +ViewDesc.prototype.matchesMark = function matchesMark () { return false }; +ViewDesc.prototype.matchesNode = function matchesNode () { return false }; +ViewDesc.prototype.matchesHack = function matchesHack () { return false }; + +prototypeAccessors.beforePosition.get = function () { return false }; + +// : () → ?ParseRule +// When parsing in-editor content (in domchange.js), we allow +// descriptions to determine the parse rules that should be used to +// parse them. +ViewDesc.prototype.parseRule = function parseRule () { return null }; + +// : (dom.Event) → bool +// Used by the editor's event handler to ignore events that come +// from certain descs. +ViewDesc.prototype.stopEvent = function stopEvent () { return false }; + +// The size of the content represented by this desc. +prototypeAccessors.size.get = function () { + var size = 0; + for (var i = 0; i < this.children.length; i++) { size += this.children[i].size; } + return size +}; + +// For block nodes, this represents the space taken up by their +// start/end tokens. +prototypeAccessors.border.get = function () { return 0 }; + +ViewDesc.prototype.destroy = function destroy () { + this.parent = null; + if (this.dom.pmViewDesc == this) { this.dom.pmViewDesc = null; } + for (var i = 0; i < this.children.length; i++) + { this.children[i].destroy(); } +}; + +ViewDesc.prototype.posBeforeChild = function posBeforeChild (child) { + for (var i = 0, pos = this.posAtStart; i < this.children.length; i++) { + var cur = this.children[i]; + if (cur == child) { return pos } + pos += cur.size; + } +}; + +prototypeAccessors.posBefore.get = function () { + return this.parent.posBeforeChild(this) +}; + +prototypeAccessors.posAtStart.get = function () { + return this.parent ? this.parent.posBeforeChild(this) + this.border : 0 +}; + +prototypeAccessors.posAfter.get = function () { + return this.posBefore + this.size +}; + +prototypeAccessors.posAtEnd.get = function () { + return this.posAtStart + this.size - 2 * this.border +}; + +// : (dom.Node, number, ?number) → number +ViewDesc.prototype.localPosFromDOM = function localPosFromDOM (dom, offset, bias) { + // If the DOM position is in the content, use the child desc after + // it to figure out a position. + if (this.contentDOM && this.contentDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode)) { + if (bias < 0) { + var domBefore, desc; + if (dom == this.contentDOM) { + domBefore = dom.childNodes[offset - 1]; + } else { + while (dom.parentNode != this.contentDOM) { dom = dom.parentNode; } + domBefore = dom.previousSibling; + } + while (domBefore && !((desc = domBefore.pmViewDesc) && desc.parent == this)) { domBefore = domBefore.previousSibling; } + return domBefore ? this.posBeforeChild(desc) + desc.size : this.posAtStart + } else { + var domAfter, desc$1; + if (dom == this.contentDOM) { + domAfter = dom.childNodes[offset]; + } else { + while (dom.parentNode != this.contentDOM) { dom = dom.parentNode; } + domAfter = dom.nextSibling; + } + while (domAfter && !((desc$1 = domAfter.pmViewDesc) && desc$1.parent == this)) { domAfter = domAfter.nextSibling; } + return domAfter ? this.posBeforeChild(desc$1) : this.posAtEnd + } + } + // Otherwise, use various heuristics, falling back on the bias + // parameter, to determine whether to return the position at the + // start or at the end of this view desc. + var atEnd; + if (this.contentDOM && this.contentDOM != this.dom && this.dom.contains(this.contentDOM)) { + atEnd = dom.compareDocumentPosition(this.contentDOM) & 2; + } else if (this.dom.firstChild) { + if (offset == 0) { for (var search = dom;; search = search.parentNode) { + if (search == this.dom) { atEnd = false; break } + if (search.parentNode.firstChild != search) { break } + } } + if (atEnd == null && offset == dom.childNodes.length) { for (var search$1 = dom;; search$1 = search$1.parentNode) { + if (search$1 == this.dom) { atEnd = true; break } + if (search$1.parentNode.lastChild != search$1) { break } + } } + } + return (atEnd == null ? bias > 0 : atEnd) ? this.posAtEnd : this.posAtStart +}; + +// Scan up the dom finding the first desc that is a descendant of +// this one. +ViewDesc.prototype.nearestDesc = function nearestDesc (dom, onlyNodes) { + for (var first = true, cur = dom; cur; cur = cur.parentNode) { + var desc = this.getDesc(cur); + if (desc && (!onlyNodes || desc.node)) { + // If dom is outside of this desc's nodeDOM, don't count it. + if (first && desc.nodeDOM && !(desc.nodeDOM.nodeType == 1 ? desc.nodeDOM.contains(dom) : desc.nodeDOM == dom)) { first = false; } + else { return desc } + } + } +}; + +ViewDesc.prototype.getDesc = function getDesc (dom) { + var desc = dom.pmViewDesc; + for (var cur = desc; cur; cur = cur.parent) { if (cur == this) { return desc } } +}; + +ViewDesc.prototype.posFromDOM = function posFromDOM (dom, offset, bias) { + for (var scan = dom;; scan = scan.parentNode) { + var desc = this.getDesc(scan); + if (desc) { return desc.localPosFromDOM(dom, offset, bias) } + } +}; + +// : (number) → ?NodeViewDesc +// Find the desc for the node after the given pos, if any. (When a +// parent node overrode rendering, there might not be one.) +ViewDesc.prototype.descAt = function descAt (pos) { + for (var i = 0, offset = 0; i < this.children.length; i++) { + var child = this.children[i], end = offset + child.size; + if (offset == pos && end != offset) { + while (!child.border && child.children.length) { child = child.children[0]; } + return child + } + if (pos < end) { return child.descAt(pos - offset - child.border) } + offset = end; + } +}; + +// : (number) → {node: dom.Node, offset: number} +ViewDesc.prototype.domFromPos = function domFromPos (pos) { + if (!this.contentDOM) { return {node: this.dom, offset: 0} } + for (var offset = 0, i = 0;; i++) { + if (offset == pos) { + while (i < this.children.length && (this.children[i].beforePosition || this.children[i].dom.parentNode != this.contentDOM)) { i++; } + return {node: this.contentDOM, + offset: i == this.children.length ? this.contentDOM.childNodes.length : domIndex(this.children[i].dom)} + } + if (i == this.children.length) { throw new Error("Invalid position " + pos) } + var child = this.children[i], end = offset + child.size; + if (pos < end) { return child.domFromPos(pos - offset - child.border) } + offset = end; + } +}; + +// Used to find a DOM range in a single parent for a given changed +// range. +ViewDesc.prototype.parseRange = function parseRange (from, to, base) { + if ( base === void 0 ) base = 0; + + if (this.children.length == 0) + { return {node: this.contentDOM, from: from, to: to, fromOffset: 0, toOffset: this.contentDOM.childNodes.length} } + + var fromOffset = -1, toOffset = -1; + for (var offset = base, i = 0;; i++) { + var child = this.children[i], end = offset + child.size; + if (fromOffset == -1 && from <= end) { + var childBase = offset + child.border; + // FIXME maybe descend mark views to parse a narrower range? + if (from >= childBase && to <= end - child.border && child.node && + child.contentDOM && this.contentDOM.contains(child.contentDOM)) + { return child.parseRange(from, to, childBase) } + + from = offset; + for (var j = i; j > 0; j--) { + var prev = this.children[j - 1]; + if (prev.size && prev.dom.parentNode == this.contentDOM && !prev.emptyChildAt(1)) { + fromOffset = domIndex(prev.dom) + 1; + break + } + from -= prev.size; + } + if (fromOffset == -1) { fromOffset = 0; } + } + if (fromOffset > -1 && to <= end) { + to = end; + for (var j$1 = i + 1; j$1 < this.children.length; j$1++) { + var next = this.children[j$1]; + if (next.size && next.dom.parentNode == this.contentDOM && !next.emptyChildAt(-1)) { + toOffset = domIndex(next.dom); + break + } + to += next.size; + } + if (toOffset == -1) { toOffset = this.contentDOM.childNodes.length; } + break + } + offset = end; + } + return {node: this.contentDOM, from: from, to: to, fromOffset: fromOffset, toOffset: toOffset} +}; + +ViewDesc.prototype.emptyChildAt = function emptyChildAt (side) { + if (this.border || !this.contentDOM || !this.children.length) { return false } + var child = this.children[side < 0 ? 0 : this.children.length - 1]; + return child.size == 0 || child.emptyChildAt(side) +}; + +// : (number) → dom.Node +ViewDesc.prototype.domAfterPos = function domAfterPos (pos) { + var ref = this.domFromPos(pos); + var node = ref.node; + var offset = ref.offset; + if (node.nodeType != 1 || offset == node.childNodes.length) + { throw new RangeError("No node after pos " + pos) } + return node.childNodes[offset] +}; + +// : (number, number, dom.Document) +// View descs are responsible for setting any selection that falls +// entirely inside of them, so that custom implementations can do +// custom things with the selection. Note that this falls apart when +// a selection starts in such a node and ends in another, in which +// case we just use whatever domFromPos produces as a best effort. +ViewDesc.prototype.setSelection = function setSelection (anchor, head, root, force) { + // If the selection falls entirely in a child, give it to that child + var from = Math.min(anchor, head), to = Math.max(anchor, head); + for (var i = 0, offset = 0; i < this.children.length; i++) { + var child = this.children[i], end = offset + child.size; + if (from > offset && to < end) + { return child.setSelection(anchor - offset - child.border, head - offset - child.border, root, force) } + offset = end; + } + + var anchorDOM = this.domFromPos(anchor), headDOM = this.domFromPos(head); + var domSel = root.getSelection(), range = document.createRange(); + if (!force && + isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset) && + isEquivalentPosition(headDOM.node, headDOM.offset, domSel.focusNode, domSel.focusOffset)) + { return } + + // Selection.extend can be used to create an 'inverted' selection + // (one where the focus is before the anchor), but not all + // browsers support it yet. + if (domSel.extend) { + range.setEnd(anchorDOM.node, anchorDOM.offset); + range.collapse(false); + } else { + if (anchor > head) { var tmp = anchorDOM; anchorDOM = headDOM; headDOM = tmp; } + range.setEnd(headDOM.node, headDOM.offset); + range.setStart(anchorDOM.node, anchorDOM.offset); + } + domSel.removeAllRanges(); + domSel.addRange(range); + if (domSel.extend) + { domSel.extend(headDOM.node, headDOM.offset); } +}; + +// : (dom.MutationRecord) → bool +ViewDesc.prototype.ignoreMutation = function ignoreMutation (_mutation) { + return !this.contentDOM +}; + +prototypeAccessors.contentLost.get = function () { + return this.contentDOM && this.contentDOM != this.dom && !this.dom.contains(this.contentDOM) +}; + +// Remove a subtree of the element tree that has been touched +// by a DOM change, so that the next update will redraw it. +ViewDesc.prototype.markDirty = function markDirty (from, to) { + for (var offset = 0, i = 0; i < this.children.length; i++) { + var child = this.children[i], end = offset + child.size; + if (offset == end ? from <= end && to >= offset : from < end && to > offset) { + var startInside = offset + child.border, endInside = end - child.border; + if (from >= startInside && to <= endInside) { + this.dirty = from == offset || to == end ? CONTENT_DIRTY : CHILD_DIRTY; + if (from == startInside && to == endInside && + (child.contentLost || child.dom.parentNode != this.contentDOM)) { child.dirty = NODE_DIRTY; } + else { child.markDirty(from - startInside, to - startInside); } + return + } else { + child.dirty = NODE_DIRTY; + } + } + offset = end; + } + this.dirty = CONTENT_DIRTY; +}; + +ViewDesc.prototype.markParentsDirty = function markParentsDirty () { + for (var node = this.parent; node; node = node.parent) { + var dirty = CONTENT_DIRTY ; + if (node.dirty < dirty) { node.dirty = dirty; } + } +}; + +Object.defineProperties( ViewDesc.prototype, prototypeAccessors ); + +// Reused array to avoid allocating fresh arrays for things that will +// stay empty anyway. +var nothing = []; + +// A widget desc represents a widget decoration, which is a DOM node +// drawn between the document nodes. +var WidgetViewDesc = /*@__PURE__*/(function (ViewDesc) { + function WidgetViewDesc(parent, widget, view, pos) { + var self, dom = widget.type.toDOM; + if (typeof dom == "function") { dom = dom(view, function () { + if (!self) { return pos } + if (self.parent) { return self.parent.posBeforeChild(self) } + }); } + if (!widget.type.spec.raw) { + if (dom.nodeType != 1) { + var wrap = document.createElement("span"); + wrap.appendChild(dom); + dom = wrap; + } + dom.contentEditable = false; + dom.classList.add("ProseMirror-widget"); + } + ViewDesc.call(this, parent, nothing, dom, null); + this.widget = widget; + self = this; + } + + if ( ViewDesc ) WidgetViewDesc.__proto__ = ViewDesc; + WidgetViewDesc.prototype = Object.create( ViewDesc && ViewDesc.prototype ); + WidgetViewDesc.prototype.constructor = WidgetViewDesc; + + var prototypeAccessors$1 = { beforePosition: { configurable: true } }; + + prototypeAccessors$1.beforePosition.get = function () { + return this.widget.type.side < 0 + }; + + WidgetViewDesc.prototype.matchesWidget = function matchesWidget (widget) { + return this.dirty == NOT_DIRTY && widget.type.eq(this.widget.type) + }; + + WidgetViewDesc.prototype.parseRule = function parseRule () { return {ignore: true} }; + + WidgetViewDesc.prototype.stopEvent = function stopEvent (event) { + var stop = this.widget.spec.stopEvent; + return stop ? stop(event) : false + }; + + Object.defineProperties( WidgetViewDesc.prototype, prototypeAccessors$1 ); + + return WidgetViewDesc; +}(ViewDesc)); + +var CompositionViewDesc = /*@__PURE__*/(function (ViewDesc) { + function CompositionViewDesc(parent, dom, textDOM, text) { + ViewDesc.call(this, parent, nothing, dom, null); + this.textDOM = textDOM; + this.text = text; + } + + if ( ViewDesc ) CompositionViewDesc.__proto__ = ViewDesc; + CompositionViewDesc.prototype = Object.create( ViewDesc && ViewDesc.prototype ); + CompositionViewDesc.prototype.constructor = CompositionViewDesc; + + var prototypeAccessors$2 = { size: { configurable: true } }; + + prototypeAccessors$2.size.get = function () { return this.text.length }; + + CompositionViewDesc.prototype.localPosFromDOM = function localPosFromDOM (dom, offset) { + if (dom != this.textDOM) { return this.posAtStart + (offset ? this.size : 0) } + return this.posAtStart + offset + }; + + CompositionViewDesc.prototype.domFromPos = function domFromPos (pos) { + return {node: this.textDOM, offset: pos} + }; + + CompositionViewDesc.prototype.ignoreMutation = function ignoreMutation (mut) { + return mut.type === 'characterData' && mut.target.nodeValue == mut.oldValue + }; + + Object.defineProperties( CompositionViewDesc.prototype, prototypeAccessors$2 ); + + return CompositionViewDesc; +}(ViewDesc)); + +// A mark desc represents a mark. May have multiple children, +// depending on how the mark is split. Note that marks are drawn using +// a fixed nesting order, for simplicity and predictability, so in +// some cases they will be split more often than would appear +// necessary. +var MarkViewDesc = /*@__PURE__*/(function (ViewDesc) { + function MarkViewDesc(parent, mark, dom, contentDOM) { + ViewDesc.call(this, parent, [], dom, contentDOM); + this.mark = mark; + } + + if ( ViewDesc ) MarkViewDesc.__proto__ = ViewDesc; + MarkViewDesc.prototype = Object.create( ViewDesc && ViewDesc.prototype ); + MarkViewDesc.prototype.constructor = MarkViewDesc; + + MarkViewDesc.create = function create (parent, mark, inline, view) { + var custom = view.nodeViews[mark.type.name]; + var spec = custom && custom(mark, view, inline); + if (!spec || !spec.dom) + { spec = DOMSerializer.renderSpec(document, mark.type.spec.toDOM(mark, inline)); } + return new MarkViewDesc(parent, mark, spec.dom, spec.contentDOM || spec.dom) + }; + + MarkViewDesc.prototype.parseRule = function parseRule () { return {mark: this.mark.type.name, attrs: this.mark.attrs, contentElement: this.contentDOM} }; + + MarkViewDesc.prototype.matchesMark = function matchesMark (mark) { return this.dirty != NODE_DIRTY && this.mark.eq(mark) }; + + MarkViewDesc.prototype.markDirty = function markDirty (from, to) { + ViewDesc.prototype.markDirty.call(this, from, to); + // Move dirty info to nearest node view + if (this.dirty != NOT_DIRTY) { + var parent = this.parent; + while (!parent.node) { parent = parent.parent; } + if (parent.dirty < this.dirty) { parent.dirty = this.dirty; } + this.dirty = NOT_DIRTY; + } + }; + + MarkViewDesc.prototype.slice = function slice (from, to, view) { + var copy = MarkViewDesc.create(this.parent, this.mark, true, view); + var nodes = this.children, size = this.size; + if (to < size) { nodes = replaceNodes(nodes, to, size, view); } + if (from > 0) { nodes = replaceNodes(nodes, 0, from, view); } + for (var i = 0; i < nodes.length; i++) { nodes[i].parent = copy; } + copy.children = nodes; + return copy + }; + + return MarkViewDesc; +}(ViewDesc)); + +// Node view descs are the main, most common type of view desc, and +// correspond to an actual node in the document. Unlike mark descs, +// they populate their child array themselves. +var NodeViewDesc = /*@__PURE__*/(function (ViewDesc) { + function NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos) { + ViewDesc.call(this, parent, node.isLeaf ? nothing : [], dom, contentDOM); + this.nodeDOM = nodeDOM; + this.node = node; + this.outerDeco = outerDeco; + this.innerDeco = innerDeco; + if (contentDOM) { this.updateChildren(view, pos); } + } + + if ( ViewDesc ) NodeViewDesc.__proto__ = ViewDesc; + NodeViewDesc.prototype = Object.create( ViewDesc && ViewDesc.prototype ); + NodeViewDesc.prototype.constructor = NodeViewDesc; + + var prototypeAccessors$3 = { size: { configurable: true },border: { configurable: true } }; + + // By default, a node is rendered using the `toDOM` method from the + // node type spec. But client code can use the `nodeViews` spec to + // supply a custom node view, which can influence various aspects of + // the way the node works. + // + // (Using subclassing for this was intentionally decided against, + // since it'd require exposing a whole slew of finnicky + // implementation details to the user code that they probably will + // never need.) + NodeViewDesc.create = function create (parent, node, outerDeco, innerDeco, view, pos) { + var assign; + + var custom = view.nodeViews[node.type.name], descObj; + var spec = custom && custom(node, view, function () { + // (This is a function that allows the custom view to find its + // own position) + if (!descObj) { return pos } + if (descObj.parent) { return descObj.parent.posBeforeChild(descObj) } + }, outerDeco); + + var dom = spec && spec.dom, contentDOM = spec && spec.contentDOM; + if (node.isText) { + if (!dom) { dom = document.createTextNode(node.text); } + else if (dom.nodeType != 3) { throw new RangeError("Text must be rendered as a DOM text node") } + } else if (!dom) { +((assign = DOMSerializer.renderSpec(document, node.type.spec.toDOM(node)), dom = assign.dom, contentDOM = assign.contentDOM)); + } + if (!contentDOM && !node.isText && dom.nodeName != "BR") { // Chrome gets confused by
    + if (!dom.hasAttribute("contenteditable")) { dom.contentEditable = false; } + if (node.type.spec.draggable) { dom.draggable = true; } + } + + var nodeDOM = dom; + dom = applyOuterDeco(dom, outerDeco, node); + + if (spec) + { return descObj = new CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, + spec, view, pos + 1) } + else if (node.isText) + { return new TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM, view) } + else + { return new NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos + 1) } + }; + + NodeViewDesc.prototype.parseRule = function parseRule () { + var this$1 = this; + + // Experimental kludge to allow opt-in re-parsing of nodes + if (this.node.type.spec.reparseInView) { return null } + // FIXME the assumption that this can always return the current + // attrs means that if the user somehow manages to change the + // attrs in the dom, that won't be picked up. Not entirely sure + // whether this is a problem + var rule = {node: this.node.type.name, attrs: this.node.attrs}; + if (this.node.type.spec.code) { rule.preserveWhitespace = "full"; } + if (this.contentDOM && !this.contentLost) { rule.contentElement = this.contentDOM; } + else { rule.getContent = function () { return this$1.contentDOM ? Fragment.empty : this$1.node.content; }; } + return rule + }; + + NodeViewDesc.prototype.matchesNode = function matchesNode (node, outerDeco, innerDeco) { + return this.dirty == NOT_DIRTY && node.eq(this.node) && + sameOuterDeco(outerDeco, this.outerDeco) && innerDeco.eq(this.innerDeco) + }; + + prototypeAccessors$3.size.get = function () { return this.node.nodeSize }; + + prototypeAccessors$3.border.get = function () { return this.node.isLeaf ? 0 : 1 }; + + // Syncs `this.children` to match `this.node.content` and the local + // decorations, possibly introducing nesting for marks. Then, in a + // separate step, syncs the DOM inside `this.contentDOM` to + // `this.children`. + NodeViewDesc.prototype.updateChildren = function updateChildren (view, pos) { + var this$1 = this; + + var inline = this.node.inlineContent, off = pos; + var composition = inline && view.composing && this.localCompositionNode(view, pos); + var updater = new ViewTreeUpdater(this, composition && composition.node); + iterDeco(this.node, this.innerDeco, function (widget, i) { + if (widget.spec.marks) + { updater.syncToMarks(widget.spec.marks, inline, view); } + else if (widget.type.side >= 0) + { updater.syncToMarks(i == this$1.node.childCount ? Mark.none : this$1.node.child(i).marks, inline, view); } + // If the next node is a desc matching this widget, reuse it, + // otherwise insert the widget as a new view desc. + updater.placeWidget(widget, view, off); + }, function (child, outerDeco, innerDeco, i) { + // Make sure the wrapping mark descs match the node's marks. + updater.syncToMarks(child.marks, inline, view); + // Either find an existing desc that exactly matches this node, + // and drop the descs before it. + updater.findNodeMatch(child, outerDeco, innerDeco, i) || + // Or try updating the next desc to reflect this node. + updater.updateNextNode(child, outerDeco, innerDeco, view, i) || + // Or just add it as a new desc. + updater.addNode(child, outerDeco, innerDeco, view, off); + off += child.nodeSize; + }); + // Drop all remaining descs after the current position. + updater.syncToMarks(nothing, inline, view); + if (this.node.isTextblock) { updater.addTextblockHacks(); } + updater.destroyRest(); + + // Sync the DOM if anything changed + if (updater.changed || this.dirty == CONTENT_DIRTY) { + // May have to protect focused DOM from being changed if a composition is active + if (composition) { this.protectLocalComposition(view, composition); } + this.renderChildren(); + } + }; + + NodeViewDesc.prototype.renderChildren = function renderChildren () { + renderDescs(this.contentDOM, this.children); + if (result.ios) { iosHacks(this.dom); } + }; + + NodeViewDesc.prototype.localCompositionNode = function localCompositionNode (view, pos) { + // Only do something if both the selection and a focused text node + // are inside of this node, and the node isn't already part of a + // view that's a child of this view + var ref = view.state.selection; + var from = ref.from; + var to = ref.to; + if (!(view.state.selection instanceof TextSelection) || from < pos || to > pos + this.node.content.size) { return } + var sel = view.root.getSelection(); + var textNode = nearbyTextNode(sel.focusNode, sel.focusOffset); + if (!textNode || !this.dom.contains(textNode.parentNode)) { return } + + // Find the text in the focused node in the node, stop if it's not + // there (may have been modified through other means, in which + // case it should overwritten) + var text = textNode.nodeValue; + var textPos = findTextInFragment(this.node.content, text, from - pos, to - pos); + + return textPos < 0 ? null : {node: textNode, pos: textPos, text: text} + }; + + NodeViewDesc.prototype.protectLocalComposition = function protectLocalComposition (view, ref) { + var node = ref.node; + var pos = ref.pos; + var text = ref.text; + + // The node is already part of a local view desc, leave it there + if (this.getDesc(node)) { return } + + // Create a composition view for the orphaned nodes + var topNode = node; + for (;; topNode = topNode.parentNode) { + if (topNode.parentNode == this.contentDOM) { break } + while (topNode.previousSibling) { topNode.parentNode.removeChild(topNode.previousSibling); } + while (topNode.nextSibling) { topNode.parentNode.removeChild(topNode.nextSibling); } + if (topNode.pmViewDesc) { topNode.pmViewDesc = null; } + } + var desc = new CompositionViewDesc(this, topNode, node, text); + view.compositionNodes.push(desc); + + // Patch up this.children to contain the composition view + this.children = replaceNodes(this.children, pos, pos + text.length, view, desc); + }; + + // : (Node, [Decoration], DecorationSet, EditorView) → bool + // If this desc be updated to match the given node decoration, + // do so and return true. + NodeViewDesc.prototype.update = function update (node, outerDeco, innerDeco, view) { + if (this.dirty == NODE_DIRTY || + !node.sameMarkup(this.node)) { return false } + this.updateInner(node, outerDeco, innerDeco, view); + return true + }; + + NodeViewDesc.prototype.updateInner = function updateInner (node, outerDeco, innerDeco, view) { + this.updateOuterDeco(outerDeco); + this.node = node; + this.innerDeco = innerDeco; + if (this.contentDOM) { this.updateChildren(view, this.posAtStart); } + this.dirty = NOT_DIRTY; + }; + + NodeViewDesc.prototype.updateOuterDeco = function updateOuterDeco (outerDeco) { + if (sameOuterDeco(outerDeco, this.outerDeco)) { return } + var needsWrap = this.nodeDOM.nodeType != 1; + var oldDOM = this.dom; + this.dom = patchOuterDeco(this.dom, this.nodeDOM, + computeOuterDeco(this.outerDeco, this.node, needsWrap), + computeOuterDeco(outerDeco, this.node, needsWrap)); + if (this.dom != oldDOM) { + oldDOM.pmViewDesc = null; + this.dom.pmViewDesc = this; + } + this.outerDeco = outerDeco; + }; + + // Mark this node as being the selected node. + NodeViewDesc.prototype.selectNode = function selectNode () { + this.nodeDOM.classList.add("ProseMirror-selectednode"); + if (this.contentDOM || !this.node.type.spec.draggable) { this.dom.draggable = true; } + }; + + // Remove selected node marking from this node. + NodeViewDesc.prototype.deselectNode = function deselectNode () { + this.nodeDOM.classList.remove("ProseMirror-selectednode"); + if (this.contentDOM || !this.node.type.spec.draggable) { this.dom.draggable = false; } + }; + + Object.defineProperties( NodeViewDesc.prototype, prototypeAccessors$3 ); + + return NodeViewDesc; +}(ViewDesc)); + +// Create a view desc for the top-level document node, to be exported +// and used by the view class. +function docViewDesc(doc, outerDeco, innerDeco, dom, view) { + applyOuterDeco(dom, outerDeco, doc); + return new NodeViewDesc(null, doc, outerDeco, innerDeco, dom, dom, dom, view, 0) +} + +var TextViewDesc = /*@__PURE__*/(function (NodeViewDesc) { + function TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM, view) { + NodeViewDesc.call(this, parent, node, outerDeco, innerDeco, dom, null, nodeDOM, view); + } + + if ( NodeViewDesc ) TextViewDesc.__proto__ = NodeViewDesc; + TextViewDesc.prototype = Object.create( NodeViewDesc && NodeViewDesc.prototype ); + TextViewDesc.prototype.constructor = TextViewDesc; + + TextViewDesc.prototype.parseRule = function parseRule () { + return {skip: this.nodeDOM.parentNode || true} + }; + + TextViewDesc.prototype.update = function update (node, outerDeco) { + if (this.dirty == NODE_DIRTY || (this.dirty != NOT_DIRTY && !this.inParent()) || + !node.sameMarkup(this.node)) { return false } + this.updateOuterDeco(outerDeco); + if ((this.dirty != NOT_DIRTY || node.text != this.node.text) && node.text != this.nodeDOM.nodeValue) + { this.nodeDOM.nodeValue = node.text; } + this.node = node; + this.dirty = NOT_DIRTY; + return true + }; + + TextViewDesc.prototype.inParent = function inParent () { + var parentDOM = this.parent.contentDOM; + for (var n = this.nodeDOM; n; n = n.parentNode) { if (n == parentDOM) { return true } } + return false + }; + + TextViewDesc.prototype.domFromPos = function domFromPos (pos) { + return {node: this.nodeDOM, offset: pos} + }; + + TextViewDesc.prototype.localPosFromDOM = function localPosFromDOM (dom, offset, bias) { + if (dom == this.nodeDOM) { return this.posAtStart + Math.min(offset, this.node.text.length) } + return NodeViewDesc.prototype.localPosFromDOM.call(this, dom, offset, bias) + }; + + TextViewDesc.prototype.ignoreMutation = function ignoreMutation (mutation) { + return mutation.type != "characterData" && mutation.type != "selection" + }; + + TextViewDesc.prototype.slice = function slice (from, to, view) { + var node = this.node.cut(from, to), dom = document.createTextNode(node.text); + return new TextViewDesc(this.parent, node, this.outerDeco, this.innerDeco, dom, dom, view) + }; + + return TextViewDesc; +}(NodeViewDesc)); + +// A dummy desc used to tag trailing BR or span nodes created to work +// around contentEditable terribleness. +var BRHackViewDesc = /*@__PURE__*/(function (ViewDesc) { + function BRHackViewDesc () { + ViewDesc.apply(this, arguments); + } + + if ( ViewDesc ) BRHackViewDesc.__proto__ = ViewDesc; + BRHackViewDesc.prototype = Object.create( ViewDesc && ViewDesc.prototype ); + BRHackViewDesc.prototype.constructor = BRHackViewDesc; + + BRHackViewDesc.prototype.parseRule = function parseRule () { return {ignore: true} }; + BRHackViewDesc.prototype.matchesHack = function matchesHack () { return this.dirty == NOT_DIRTY }; + + return BRHackViewDesc; +}(ViewDesc)); + +// A separate subclass is used for customized node views, so that the +// extra checks only have to be made for nodes that are actually +// customized. +var CustomNodeViewDesc = /*@__PURE__*/(function (NodeViewDesc) { + function CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, spec, view, pos) { + NodeViewDesc.call(this, parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos); + this.spec = spec; + } + + if ( NodeViewDesc ) CustomNodeViewDesc.__proto__ = NodeViewDesc; + CustomNodeViewDesc.prototype = Object.create( NodeViewDesc && NodeViewDesc.prototype ); + CustomNodeViewDesc.prototype.constructor = CustomNodeViewDesc; + + // A custom `update` method gets to decide whether the update goes + // through. If it does, and there's a `contentDOM` node, our logic + // updates the children. + CustomNodeViewDesc.prototype.update = function update (node, outerDeco, innerDeco, view) { + if (this.dirty == NODE_DIRTY) { return false } + if (this.spec.update) { + var result = this.spec.update(node, outerDeco); + if (result) { this.updateInner(node, outerDeco, innerDeco, view); } + return result + } else if (!this.contentDOM && !node.isLeaf) { + return false + } else { + return NodeViewDesc.prototype.update.call(this, node, outerDeco, innerDeco, view) + } + }; + + CustomNodeViewDesc.prototype.selectNode = function selectNode () { + this.spec.selectNode ? this.spec.selectNode() : NodeViewDesc.prototype.selectNode.call(this); + }; + + CustomNodeViewDesc.prototype.deselectNode = function deselectNode () { + this.spec.deselectNode ? this.spec.deselectNode() : NodeViewDesc.prototype.deselectNode.call(this); + }; + + CustomNodeViewDesc.prototype.setSelection = function setSelection (anchor, head, root, force) { + this.spec.setSelection ? this.spec.setSelection(anchor, head, root) + : NodeViewDesc.prototype.setSelection.call(this, anchor, head, root, force); + }; + + CustomNodeViewDesc.prototype.destroy = function destroy () { + if (this.spec.destroy) { this.spec.destroy(); } + NodeViewDesc.prototype.destroy.call(this); + }; + + CustomNodeViewDesc.prototype.stopEvent = function stopEvent (event) { + return this.spec.stopEvent ? this.spec.stopEvent(event) : false + }; + + CustomNodeViewDesc.prototype.ignoreMutation = function ignoreMutation (mutation) { + return this.spec.ignoreMutation ? this.spec.ignoreMutation(mutation) : NodeViewDesc.prototype.ignoreMutation.call(this, mutation) + }; + + return CustomNodeViewDesc; +}(NodeViewDesc)); + +// : (dom.Node, [ViewDesc]) +// Sync the content of the given DOM node with the nodes associated +// with the given array of view descs, recursing into mark descs +// because this should sync the subtree for a whole node at a time. +function renderDescs(parentDOM, descs) { + var dom = parentDOM.firstChild; + for (var i = 0; i < descs.length; i++) { + var desc = descs[i], childDOM = desc.dom; + if (childDOM.parentNode == parentDOM) { + while (childDOM != dom) { dom = rm(dom); } + dom = dom.nextSibling; + } else { + parentDOM.insertBefore(childDOM, dom); + } + if (desc instanceof MarkViewDesc) { + var pos = dom ? dom.previousSibling : parentDOM.lastChild; + renderDescs(desc.contentDOM, desc.children); + dom = pos ? pos.nextSibling : parentDOM.firstChild; + } + } + while (dom) { dom = rm(dom); } +} + +function OuterDecoLevel(nodeName) { + if (nodeName) { this.nodeName = nodeName; } +} +OuterDecoLevel.prototype = Object.create(null); + +var noDeco = [new OuterDecoLevel]; + +function computeOuterDeco(outerDeco, node, needsWrap) { + if (outerDeco.length == 0) { return noDeco } + + var top = needsWrap ? noDeco[0] : new OuterDecoLevel, result = [top]; + + for (var i = 0; i < outerDeco.length; i++) { + var attrs = outerDeco[i].type.attrs, cur = top; + if (!attrs) { continue } + if (attrs.nodeName) + { result.push(cur = new OuterDecoLevel(attrs.nodeName)); } + + for (var name in attrs) { + var val = attrs[name]; + if (val == null) { continue } + if (needsWrap && result.length == 1) + { result.push(cur = top = new OuterDecoLevel(node.isInline ? "span" : "div")); } + if (name == "class") { cur.class = (cur.class ? cur.class + " " : "") + val; } + else if (name == "style") { cur.style = (cur.style ? cur.style + ";" : "") + val; } + else if (name != "nodeName") { cur[name] = val; } + } + } + + return result +} + +function patchOuterDeco(outerDOM, nodeDOM, prevComputed, curComputed) { + // Shortcut for trivial case + if (prevComputed == noDeco && curComputed == noDeco) { return nodeDOM } + + var curDOM = nodeDOM; + for (var i = 0; i < curComputed.length; i++) { + var deco = curComputed[i], prev = prevComputed[i]; + if (i) { + var parent = (void 0); + if (prev && prev.nodeName == deco.nodeName && curDOM != outerDOM && + (parent = curDOM.parentNode) && parent.tagName.toLowerCase() == deco.nodeName) { + curDOM = parent; + } else { + parent = document.createElement(deco.nodeName); + parent.appendChild(curDOM); + prev = noDeco[0]; + curDOM = parent; + } + } + patchAttributes(curDOM, prev || noDeco[0], deco); + } + return curDOM +} + +function patchAttributes(dom, prev, cur) { + for (var name in prev) + { if (name != "class" && name != "style" && name != "nodeName" && !(name in cur)) + { dom.removeAttribute(name); } } + for (var name$1 in cur) + { if (name$1 != "class" && name$1 != "style" && name$1 != "nodeName" && cur[name$1] != prev[name$1]) + { dom.setAttribute(name$1, cur[name$1]); } } + if (prev.class != cur.class) { + var prevList = prev.class ? prev.class.split(" ") : nothing; + var curList = cur.class ? cur.class.split(" ") : nothing; + for (var i = 0; i < prevList.length; i++) { if (curList.indexOf(prevList[i]) == -1) + { dom.classList.remove(prevList[i]); } } + for (var i$1 = 0; i$1 < curList.length; i$1++) { if (prevList.indexOf(curList[i$1]) == -1) + { dom.classList.add(curList[i$1]); } } + } + if (prev.style != cur.style) { + if (prev.style) { + var prop = /\s*([\w\-\xa1-\uffff]+)\s*:(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*'|\(.*?\)|[^;])*/g, m; + while (m = prop.exec(prev.style)) + { dom.style.removeProperty(m[1]); } + } + if (cur.style) + { dom.style.cssText += cur.style; } + } +} + +function applyOuterDeco(dom, deco, node) { + return patchOuterDeco(dom, dom, noDeco, computeOuterDeco(deco, node, dom.nodeType != 1)) +} + +// : ([Decoration], [Decoration]) → bool +function sameOuterDeco(a, b) { + if (a.length != b.length) { return false } + for (var i = 0; i < a.length; i++) { if (!a[i].type.eq(b[i].type)) { return false } } + return true +} + +// Remove a DOM node and return its next sibling. +function rm(dom) { + var next = dom.nextSibling; + dom.parentNode.removeChild(dom); + return next +} + +// Helper class for incrementally updating a tree of mark descs and +// the widget and node descs inside of them. +var ViewTreeUpdater = function ViewTreeUpdater(top, lockedNode) { + this.top = top; + this.lock = lockedNode; + // Index into `this.top`'s child array, represents the current + // update position. + this.index = 0; + // When entering a mark, the current top and index are pushed + // onto this. + this.stack = []; + // Tracks whether anything was changed + this.changed = false; + + var pre = preMatch(top.node.content, top.children); + this.preMatched = pre.nodes; + this.preMatchOffset = pre.offset; +}; + +ViewTreeUpdater.prototype.getPreMatch = function getPreMatch (index) { + return index >= this.preMatchOffset ? this.preMatched[index - this.preMatchOffset] : null +}; + +// Destroy and remove the children between the given indices in +// `this.top`. +ViewTreeUpdater.prototype.destroyBetween = function destroyBetween (start, end) { + if (start == end) { return } + for (var i = start; i < end; i++) { this.top.children[i].destroy(); } + this.top.children.splice(start, end - start); + this.changed = true; +}; + +// Destroy all remaining children in `this.top`. +ViewTreeUpdater.prototype.destroyRest = function destroyRest () { + this.destroyBetween(this.index, this.top.children.length); +}; + +// : ([Mark], EditorView) +// Sync the current stack of mark descs with the given array of +// marks, reusing existing mark descs when possible. +ViewTreeUpdater.prototype.syncToMarks = function syncToMarks (marks, inline, view) { + var keep = 0, depth = this.stack.length >> 1; + var maxKeep = Math.min(depth, marks.length); + while (keep < maxKeep && + (keep == depth - 1 ? this.top : this.stack[(keep + 1) << 1]).matchesMark(marks[keep]) && marks[keep].type.spec.spanning !== false) + { keep++; } + + while (keep < depth) { + this.destroyRest(); + this.top.dirty = NOT_DIRTY; + this.index = this.stack.pop(); + this.top = this.stack.pop(); + depth--; + } + while (depth < marks.length) { + this.stack.push(this.top, this.index + 1); + var found = -1; + for (var i = this.index; i < Math.min(this.index + 3, this.top.children.length); i++) { + if (this.top.children[i].matchesMark(marks[depth])) { found = i; break } + } + if (found > -1) { + if (found > this.index) { + this.changed = true; + this.destroyBetween(this.index, found); + } + this.top = this.top.children[this.index]; + } else { + var markDesc = MarkViewDesc.create(this.top, marks[depth], inline, view); + this.top.children.splice(this.index, 0, markDesc); + this.top = markDesc; + this.changed = true; + } + this.index = 0; + depth++; + } +}; + +// : (Node, [Decoration], DecorationSet) → bool +// Try to find a node desc matching the given data. Skip over it and +// return true when successful. +ViewTreeUpdater.prototype.findNodeMatch = function findNodeMatch (node, outerDeco, innerDeco, index) { + var found = -1, preMatch = index < 0 ? undefined : this.getPreMatch(index), children = this.top.children; + if (preMatch && preMatch.matchesNode(node, outerDeco, innerDeco)) { + found = children.indexOf(preMatch); + } else { + for (var i = this.index, e = Math.min(children.length, i + 5); i < e; i++) { + var child = children[i]; + if (child.matchesNode(node, outerDeco, innerDeco) && this.preMatched.indexOf(child) < 0) { + found = i; + break + } + } + } + if (found < 0) { return false } + this.destroyBetween(this.index, found); + this.index++; + return true +}; + +// : (Node, [Decoration], DecorationSet, EditorView, Fragment, number) → bool +// Try to update the next node, if any, to the given data. Checks +// pre-matches to avoid overwriting nodes that could still be used. +ViewTreeUpdater.prototype.updateNextNode = function updateNextNode (node, outerDeco, innerDeco, view, index) { + if (this.index == this.top.children.length) { return false } + var next = this.top.children[this.index]; + if (next instanceof NodeViewDesc) { + var preMatch = this.preMatched.indexOf(next); + if (preMatch > -1 && preMatch + this.preMatchOffset != index) { return false } + var nextDOM = next.dom; + + // Can't update if nextDOM is or contains this.lock, except if + // it's a text node whose content already matches the new text + // and whose decorations match the new ones. + var locked = this.lock && (nextDOM == this.lock || nextDOM.nodeType == 1 && nextDOM.contains(this.lock.parentNode)) && + !(node.isText && next.node && next.node.isText && next.nodeDOM.nodeValue == node.text && + next.dirty != NODE_DIRTY && sameOuterDeco(outerDeco, next.outerDeco)); + if (!locked && next.update(node, outerDeco, innerDeco, view)) { + if (next.dom != nextDOM) { this.changed = true; } + this.index++; + return true + } + } + return false +}; + +// : (Node, [Decoration], DecorationSet, EditorView) +// Insert the node as a newly created node desc. +ViewTreeUpdater.prototype.addNode = function addNode (node, outerDeco, innerDeco, view, pos) { + this.top.children.splice(this.index++, 0, NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos)); + this.changed = true; +}; + +ViewTreeUpdater.prototype.placeWidget = function placeWidget (widget, view, pos) { + if (this.index < this.top.children.length && this.top.children[this.index].matchesWidget(widget)) { + this.index++; + } else { + var desc = new WidgetViewDesc(this.top, widget, view, pos); + this.top.children.splice(this.index++, 0, desc); + this.changed = true; + } +}; + +// Make sure a textblock looks and behaves correctly in +// contentEditable. +ViewTreeUpdater.prototype.addTextblockHacks = function addTextblockHacks () { + var lastChild = this.top.children[this.index - 1]; + while (lastChild instanceof MarkViewDesc) { lastChild = lastChild.children[lastChild.children.length - 1]; } + + if (!lastChild || // Empty textblock + !(lastChild instanceof TextViewDesc) || + /\n$/.test(lastChild.node.text)) { + if (this.index < this.top.children.length && this.top.children[this.index].matchesHack()) { + this.index++; + } else { + var dom = document.createElement("br"); + this.top.children.splice(this.index++, 0, new BRHackViewDesc(this.top, nothing, dom, null)); + this.changed = true; + } + } +}; + +// : (Fragment, [ViewDesc]) → [ViewDesc] +// Iterate from the end of the fragment and array of descs to find +// directly matching ones, in order to avoid overeagerly reusing +// those for other nodes. Returns an array whose positions correspond +// to node positions in the fragment, and whose elements are either +// descs matched to the child at that index, or empty. +function preMatch(frag, descs) { + var result = [], end = frag.childCount; + for (var i = descs.length - 1; end > 0 && i >= 0; i--) { + var desc = descs[i], node = desc.node; + if (!node) { continue } + if (node != frag.child(end - 1)) { break } + result.push(desc); + --end; + } + return {nodes: result.reverse(), offset: end} +} + +function compareSide(a, b) { return a.type.side - b.type.side } + +// : (ViewDesc, DecorationSet, (Decoration, number), (Node, [Decoration], DecorationSet, number)) +// This function abstracts iterating over the nodes and decorations in +// a fragment. Calls `onNode` for each node, with its local and child +// decorations. Splits text nodes when there is a decoration starting +// or ending inside of them. Calls `onWidget` for each widget. +function iterDeco(parent, deco, onWidget, onNode) { + var locals = deco.locals(parent), offset = 0; + // Simple, cheap variant for when there are no local decorations + if (locals.length == 0) { + for (var i = 0; i < parent.childCount; i++) { + var child = parent.child(i); + onNode(child, locals, deco.forChild(offset, child), i); + offset += child.nodeSize; + } + return + } + + var decoIndex = 0, active = [], restNode = null; + for (var parentIndex = 0;;) { + if (decoIndex < locals.length && locals[decoIndex].to == offset) { + var widget = locals[decoIndex++], widgets = (void 0); + while (decoIndex < locals.length && locals[decoIndex].to == offset) + { (widgets || (widgets = [widget])).push(locals[decoIndex++]); } + if (widgets) { + widgets.sort(compareSide); + for (var i$1 = 0; i$1 < widgets.length; i$1++) { onWidget(widgets[i$1], parentIndex); } + } else { + onWidget(widget, parentIndex); + } + } + + var child$1 = (void 0), index = (void 0); + if (restNode) { + index = -1; + child$1 = restNode; + restNode = null; + } else if (parentIndex < parent.childCount) { + index = parentIndex; + child$1 = parent.child(parentIndex++); + } else { + break + } + + for (var i$2 = 0; i$2 < active.length; i$2++) { if (active[i$2].to <= offset) { active.splice(i$2--, 1); } } + while (decoIndex < locals.length && locals[decoIndex].from == offset) { active.push(locals[decoIndex++]); } + + var end = offset + child$1.nodeSize; + if (child$1.isText) { + var cutAt = end; + if (decoIndex < locals.length && locals[decoIndex].from < cutAt) { cutAt = locals[decoIndex].from; } + for (var i$3 = 0; i$3 < active.length; i$3++) { if (active[i$3].to < cutAt) { cutAt = active[i$3].to; } } + if (cutAt < end) { + restNode = child$1.cut(cutAt - offset); + child$1 = child$1.cut(0, cutAt - offset); + end = cutAt; + index = -1; + } + } + + onNode(child$1, active.length ? active.slice() : nothing, deco.forChild(offset, child$1), index); + offset = end; + } +} + +// List markers in Mobile Safari will mysteriously disappear +// sometimes. This works around that. +function iosHacks(dom) { + if (dom.nodeName == "UL" || dom.nodeName == "OL") { + var oldCSS = dom.style.cssText; + dom.style.cssText = oldCSS + "; list-style: square !important"; + window.getComputedStyle(dom).listStyle; + dom.style.cssText = oldCSS; + } +} + +function nearbyTextNode(node, offset) { + for (;;) { + if (node.nodeType == 3) { return node } + if (node.nodeType == 1 && offset > 0) { + if (node.childNodes.length > offset && node.childNodes[offset].nodeType == 3) + { return node.childNodes[offset] } + node = node.childNodes[offset - 1]; + offset = nodeSize(node); + } else if (node.nodeType == 1 && offset < node.childNodes.length) { + node = node.childNodes[offset]; + offset = 0; + } else { + return null + } + } +} + +// Find a piece of text in an inline fragment, overlapping from-to +function findTextInFragment(frag, text, from, to) { + for (var str = "", i = 0, childPos = 0; i < frag.childCount; i++) { + var child = frag.child(i), end = childPos + child.nodeSize; + if (child.isText) { + str += child.text; + if (end >= to) { + var strStart = end - str.length, found = str.lastIndexOf(text); + while (found > -1 && strStart + found > from) { found = str.lastIndexOf(text, found - 1); } + if (found > -1 && strStart + found + text.length >= to) { + return strStart + found + } else if (end > to) { + break + } + } + } else { + str = ""; + } + childPos = end; + } + return -1 +} + +// Replace range from-to in an array of view descs with replacement +// (may be null to just delete). This goes very much against the grain +// of the rest of this code, which tends to create nodes with the +// right shape in one go, rather than messing with them after +// creation, but is necessary in the composition hack. +function replaceNodes(nodes, from, to, view, replacement) { + var result = []; + for (var i = 0, off = 0; i < nodes.length; i++) { + var child = nodes[i], start = off, end = off += child.size; + if (start >= to || end <= from) { + result.push(child); + } else { + if (start < from) { result.push(child.slice(0, from - start, view)); } + if (replacement) { + result.push(replacement); + replacement = null; + } + if (end > to) { result.push(child.slice(to - start, child.size, view)); } + } + } + return result +} + +function moveSelectionBlock(state, dir) { + var ref = state.selection; + var $anchor = ref.$anchor; + var $head = ref.$head; + var $side = dir > 0 ? $anchor.max($head) : $anchor.min($head); + var $start = !$side.parent.inlineContent ? $side : $side.depth ? state.doc.resolve(dir > 0 ? $side.after() : $side.before()) : null; + return $start && Selection.findFrom($start, dir) +} + +function apply(view, sel) { + view.dispatch(view.state.tr.setSelection(sel).scrollIntoView()); + return true +} + +function selectHorizontally(view, dir, mods) { + var sel = view.state.selection; + if (sel instanceof TextSelection) { + if (!sel.empty || mods.indexOf("s") > -1) { + return false + } else if (view.endOfTextblock(dir > 0 ? "right" : "left")) { + var next = moveSelectionBlock(view.state, dir); + if (next && (next instanceof NodeSelection)) { return apply(view, next) } + return false + } else { + var $head = sel.$head, node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter, desc; + if (!node || node.isText) { return false } + var nodePos = dir < 0 ? $head.pos - node.nodeSize : $head.pos; + if (!(node.isAtom || (desc = view.docView.descAt(nodePos)) && !desc.contentDOM)) { return false } + if (NodeSelection.isSelectable(node)) { + return apply(view, new NodeSelection(dir < 0 ? view.state.doc.resolve($head.pos - node.nodeSize) : $head)) + } else if (result.webkit) { + // Chrome and Safari will introduce extra pointless cursor + // positions around inline uneditable nodes, so we have to + // take over and move the cursor past them (#937) + return apply(view, new TextSelection(view.state.doc.resolve(dir < 0 ? nodePos : nodePos + node.nodeSize))) + } else { + return false + } + } + } else if (sel instanceof NodeSelection && sel.node.isInline) { + return apply(view, new TextSelection(dir > 0 ? sel.$to : sel.$from)) + } else { + var next$1 = moveSelectionBlock(view.state, dir); + if (next$1) { return apply(view, next$1) } + return false + } +} + +function nodeLen(node) { + return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length +} + +function isIgnorable(dom) { + var desc = dom.pmViewDesc; + return desc && desc.size == 0 && (dom.nextSibling || dom.nodeName != "BR") +} + +// Make sure the cursor isn't directly after one or more ignored +// nodes, which will confuse the browser's cursor motion logic. +function skipIgnoredNodesLeft(view) { + var sel = view.root.getSelection(); + var node = sel.focusNode, offset = sel.focusOffset; + if (!node) { return } + var moveNode, moveOffset, force = false; + // Gecko will do odd things when the selection is directly in front + // of a non-editable node, so in that case, move it into the next + // node if possible. Issue prosemirror/prosemirror#832. + if (result.gecko && node.nodeType == 1 && offset < nodeLen(node) && isIgnorable(node.childNodes[offset])) { force = true; } + for (;;) { + if (offset > 0) { + if (node.nodeType != 1) { + break + } else { + var before = node.childNodes[offset - 1]; + if (isIgnorable(before)) { + moveNode = node; + moveOffset = --offset; + } else if (before.nodeType == 3) { + node = before; + offset = node.nodeValue.length; + } else { break } + } + } else if (isBlockNode(node)) { + break + } else { + var prev = node.previousSibling; + while (prev && isIgnorable(prev)) { + moveNode = node.parentNode; + moveOffset = domIndex(prev); + prev = prev.previousSibling; + } + if (!prev) { + node = node.parentNode; + if (node == view.dom) { break } + offset = 0; + } else { + node = prev; + offset = nodeLen(node); + } + } + } + if (force) { setSelFocus(view, sel, node, offset); } + else if (moveNode) { setSelFocus(view, sel, moveNode, moveOffset); } +} + +// Make sure the cursor isn't directly before one or more ignored +// nodes. +function skipIgnoredNodesRight(view) { + var sel = view.root.getSelection(); + var node = sel.focusNode, offset = sel.focusOffset; + if (!node) { return } + var len = nodeLen(node); + var moveNode, moveOffset; + for (;;) { + if (offset < len) { + if (node.nodeType != 1) { break } + var after = node.childNodes[offset]; + if (isIgnorable(after)) { + moveNode = node; + moveOffset = ++offset; + } + else { break } + } else if (isBlockNode(node)) { + break + } else { + var next = node.nextSibling; + while (next && isIgnorable(next)) { + moveNode = next.parentNode; + moveOffset = domIndex(next) + 1; + next = next.nextSibling; + } + if (!next) { + node = node.parentNode; + if (node == view.dom) { break } + offset = len = 0; + } else { + node = next; + offset = 0; + len = nodeLen(node); + } + } + } + if (moveNode) { setSelFocus(view, sel, moveNode, moveOffset); } +} + +function isBlockNode(dom) { + var desc = dom.pmViewDesc; + return desc && desc.node && desc.node.isBlock +} + +function setSelFocus(view, sel, node, offset) { + if (selectionCollapsed(sel)) { + var range = document.createRange(); + range.setEnd(node, offset); + range.setStart(node, offset); + sel.removeAllRanges(); + sel.addRange(range); + } else if (sel.extend) { + sel.extend(node, offset); + } + view.domObserver.setCurSelection(); +} + +// : (EditorState, number) +// Check whether vertical selection motion would involve node +// selections. If so, apply it (if not, the result is left to the +// browser) +function selectVertically(view, dir, mods) { + var sel = view.state.selection; + if (sel instanceof TextSelection && !sel.empty || mods.indexOf("s") > -1) { return false } + var $from = sel.$from; + var $to = sel.$to; + + if (!$from.parent.inlineContent || view.endOfTextblock(dir < 0 ? "up" : "down")) { + var next = moveSelectionBlock(view.state, dir); + if (next && (next instanceof NodeSelection)) + { return apply(view, next) } + } + if (!$from.parent.inlineContent) { + var beyond = Selection.findFrom(dir < 0 ? $from : $to, dir); + return beyond ? apply(view, beyond) : true + } + return false +} + +function stopNativeHorizontalDelete(view, dir) { + if (!(view.state.selection instanceof TextSelection)) { return true } + var ref = view.state.selection; + var $head = ref.$head; + var $anchor = ref.$anchor; + var empty = ref.empty; + if (!$head.sameParent($anchor)) { return true } + if (!empty) { return false } + if (view.endOfTextblock(dir > 0 ? "forward" : "backward")) { return true } + var nextNode = !$head.textOffset && (dir < 0 ? $head.nodeBefore : $head.nodeAfter); + if (nextNode && !nextNode.isText) { + var tr = view.state.tr; + if (dir < 0) { tr.delete($head.pos - nextNode.nodeSize, $head.pos); } + else { tr.delete($head.pos, $head.pos + nextNode.nodeSize); } + view.dispatch(tr); + return true + } + return false +} + +function switchEditable(view, node, state) { + view.domObserver.stop(); + node.contentEditable = state; + view.domObserver.start(); +} + +// Issue #867 / https://bugs.chromium.org/p/chromium/issues/detail?id=903821 +// In which Chrome does really wrong things when the down arrow is +// pressed when the cursor is directly at the start of a textblock and +// has an uneditable node after it +function chromeDownArrowBug(view) { + if (!result.chrome || view.state.selection.$head.parentOffset > 0) { return } + var ref = view.root.getSelection(); + var focusNode = ref.focusNode; + var focusOffset = ref.focusOffset; + if (focusNode && focusNode.nodeType == 1 && focusOffset == 0 && + focusNode.firstChild && focusNode.firstChild.contentEditable == "false") { + var child = focusNode.firstChild; + switchEditable(view, child, true); + setTimeout(function () { return switchEditable(view, child, false); }, 20); + } +} + +// A backdrop key mapping used to make sure we always suppress keys +// that have a dangerous default effect, even if the commands they are +// bound to return false, and to make sure that cursor-motion keys +// find a cursor (as opposed to a node selection) when pressed. For +// cursor-motion keys, the code in the handlers also takes care of +// block selections. + +function getMods(event) { + var result = ""; + if (event.ctrlKey) { result += "c"; } + if (event.metaKey) { result += "m"; } + if (event.altKey) { result += "a"; } + if (event.shiftKey) { result += "s"; } + return result +} + +function captureKeyDown(view, event) { + var code = event.keyCode, mods = getMods(event); + if (code == 8 || (result.mac && code == 72 && mods == "c")) { // Backspace, Ctrl-h on Mac + return stopNativeHorizontalDelete(view, -1) || skipIgnoredNodesLeft(view) + } else if (code == 46 || (result.mac && code == 68 && mods == "c")) { // Delete, Ctrl-d on Mac + return stopNativeHorizontalDelete(view, 1) || skipIgnoredNodesRight(view) + } else if (code == 13 || code == 27) { // Enter, Esc + return true + } else if (code == 37) { // Left arrow + return selectHorizontally(view, -1, mods) || skipIgnoredNodesLeft(view) + } else if (code == 39) { // Right arrow + return selectHorizontally(view, 1, mods) || skipIgnoredNodesRight(view) + } else if (code == 38) { // Up arrow + return selectVertically(view, -1, mods) || skipIgnoredNodesLeft(view) + } else if (code == 40) { // Down arrow + return chromeDownArrowBug(view) || selectVertically(view, 1, mods) || skipIgnoredNodesRight(view) + } else if (mods == (result.mac ? "m" : "c") && + (code == 66 || code == 73 || code == 89 || code == 90)) { // Mod-[biyz] + return true + } + return false +} + +function selectionFromDOM(view, origin) { + var domSel = view.root.getSelection(), doc = view.state.doc; + var nearestDesc = view.docView.nearestDesc(domSel.focusNode), inWidget = nearestDesc && nearestDesc.size == 0; + var head = view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset); + var $head = doc.resolve(head), $anchor, selection; + if (selectionCollapsed(domSel)) { + $anchor = $head; + while (nearestDesc && !nearestDesc.node) { nearestDesc = nearestDesc.parent; } + if (nearestDesc && nearestDesc.node.isAtom && NodeSelection.isSelectable(nearestDesc.node) && nearestDesc.parent) { + var pos = nearestDesc.posBefore; + selection = new NodeSelection(head == pos ? $head : doc.resolve(pos)); + } + } else { + $anchor = doc.resolve(view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset)); + } + + if (!selection) { + var bias = origin == "pointer" || (view.state.selection.head < $head.pos && !inWidget) ? 1 : -1; + selection = selectionBetween(view, $anchor, $head, bias); + } + return selection +} + +function selectionToDOM(view, force) { + var sel = view.state.selection; + syncNodeSelection(view, sel); + + if (view.editable ? !view.hasFocus() : !(hasSelection(view) && document.activeElement.contains(view.dom))) { return } + + view.domObserver.disconnectSelection(); + + if (view.cursorWrapper) { + selectCursorWrapper(view); + } else { + var anchor = sel.anchor; + var head = sel.head; + var resetEditableFrom, resetEditableTo; + if (brokenSelectBetweenUneditable && !(sel instanceof TextSelection)) { + if (!sel.$from.parent.inlineContent) + { resetEditableFrom = temporarilyEditableNear(view, sel.from); } + if (!sel.empty && !sel.$from.parent.inlineContent) + { resetEditableTo = temporarilyEditableNear(view, sel.to); } + } + view.docView.setSelection(anchor, head, view.root, force); + if (brokenSelectBetweenUneditable) { + if (resetEditableFrom) { resetEditableFrom.contentEditable = "false"; } + if (resetEditableTo) { resetEditableTo.contentEditable = "false"; } + } + if (sel.visible) { + view.dom.classList.remove("ProseMirror-hideselection"); + } else if (anchor != head) { + view.dom.classList.add("ProseMirror-hideselection"); + if ("onselectionchange" in document) { removeClassOnSelectionChange(view); } + } + } + + view.domObserver.setCurSelection(); + view.domObserver.connectSelection(); +} + +// Kludge to work around Webkit not allowing a selection to start/end +// between non-editable block nodes. We briefly make something +// editable, set the selection, then set it uneditable again. + +var brokenSelectBetweenUneditable = result.safari || result.chrome && result.chrome_version < 63; + +function temporarilyEditableNear(view, pos) { + var ref = view.docView.domFromPos(pos); + var node = ref.node; + var offset = ref.offset; + var after = offset < node.childNodes.length ? node.childNodes[offset] : null; + var before = offset ? node.childNodes[offset - 1] : null; + if ((!after || after.contentEditable == "false") && (!before || before.contentEditable == "false")) { + if (after) { + after.contentEditable = "true"; + return after + } else if (before) { + before.contentEditable = "true"; + return before + } + } +} + +function removeClassOnSelectionChange(view) { + var doc = view.dom.ownerDocument; + doc.removeEventListener("selectionchange", view.hideSelectionGuard); + var domSel = view.root.getSelection(); + var node = domSel.anchorNode, offset = domSel.anchorOffset; + doc.addEventListener("selectionchange", view.hideSelectionGuard = function () { + if (domSel.anchorNode != node || domSel.anchorOffset != offset) { + doc.removeEventListener("selectionchange", view.hideSelectionGuard); + view.dom.classList.remove("ProseMirror-hideselection"); + } + }); +} + +function selectCursorWrapper(view) { + var domSel = view.root.getSelection(), range = document.createRange(); + var node = view.cursorWrapper.dom, img = node.nodeName == "IMG"; + if (img) { range.setEnd(node.parentNode, domIndex(node) + 1); } + else { range.setEnd(node, 0); } + range.collapse(false); + domSel.removeAllRanges(); + domSel.addRange(range); + // Kludge to kill 'control selection' in IE11 when selecting an + // invisible cursor wrapper, since that would result in those weird + // resize handles and a selection that considers the absolutely + // positioned wrapper, rather than the root editable node, the + // focused element. + if (!img && !view.state.selection.visible && result.ie && result.ie_version <= 11) { + node.disabled = true; + node.disabled = false; + } +} + +function syncNodeSelection(view, sel) { + if (sel instanceof NodeSelection) { + var desc = view.docView.descAt(sel.from); + if (desc != view.lastSelectedViewDesc) { + clearNodeSelection(view); + if (desc) { desc.selectNode(); } + view.lastSelectedViewDesc = desc; + } + } else { + clearNodeSelection(view); + } +} + +// Clear all DOM statefulness of the last node selection. +function clearNodeSelection(view) { + if (view.lastSelectedViewDesc) { + if (view.lastSelectedViewDesc.parent) + { view.lastSelectedViewDesc.deselectNode(); } + view.lastSelectedViewDesc = null; + } +} + +function selectionBetween(view, $anchor, $head, bias) { + return view.someProp("createSelectionBetween", function (f) { return f(view, $anchor, $head); }) + || TextSelection.between($anchor, $head, bias) +} + +function hasFocusAndSelection(view) { + if (view.editable && view.root.activeElement != view.dom) { return false } + return hasSelection(view) +} + +function hasSelection(view) { + var sel = view.root.getSelection(); + if (!sel.anchorNode) { return false } + try { + // Firefox will raise 'permission denied' errors when accessing + // properties of `sel.anchorNode` when it's in a generated CSS + // element. + return view.dom.contains(sel.anchorNode.nodeType == 3 ? sel.anchorNode.parentNode : sel.anchorNode) && + (view.editable || view.dom.contains(sel.focusNode.nodeType == 3 ? sel.focusNode.parentNode : sel.focusNode)) + } catch(_) { + return false + } +} + +function anchorInRightPlace(view) { + var anchorDOM = view.docView.domFromPos(view.state.selection.anchor); + var domSel = view.root.getSelection(); + return isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset) +} + +// Note that all referencing and parsing is done with the +// start-of-operation selection and document, since that's the one +// that the DOM represents. If any changes came in in the meantime, +// the modification is mapped over those before it is applied, in +// readDOMChange. + +function parseBetween(view, from_, to_) { + var ref = view.docView.parseRange(from_, to_); + var parent = ref.node; + var fromOffset = ref.fromOffset; + var toOffset = ref.toOffset; + var from = ref.from; + var to = ref.to; + + var domSel = view.root.getSelection(), find = null, anchor = domSel.anchorNode; + if (anchor && view.dom.contains(anchor.nodeType == 1 ? anchor : anchor.parentNode)) { + find = [{node: anchor, offset: domSel.anchorOffset}]; + if (!selectionCollapsed(domSel)) + { find.push({node: domSel.focusNode, offset: domSel.focusOffset}); } + } + // Work around issue in Chrome where backspacing sometimes replaces + // the deleted content with a random BR node (issues #799, #831) + if (result.chrome && view.lastKeyCode === 8) { + for (var off = toOffset; off > fromOffset; off--) { + var node = parent.childNodes[off - 1], desc = node.pmViewDesc; + if (node.nodeType == "BR" && !desc) { toOffset = off; break } + if (!desc || desc.size) { break } + } + } + var startDoc = view.state.doc; + var parser = view.someProp("domParser") || DOMParser.fromSchema(view.state.schema); + var $from = startDoc.resolve(from); + + var sel = null, doc = parser.parse(parent, { + topNode: $from.parent, + topMatch: $from.parent.contentMatchAt($from.index()), + topOpen: true, + from: fromOffset, + to: toOffset, + preserveWhitespace: $from.parent.type.spec.code ? "full" : true, + editableContent: true, + findPositions: find, + ruleFromNode: ruleFromNode, + context: $from + }); + if (find && find[0].pos != null) { + var anchor$1 = find[0].pos, head = find[1] && find[1].pos; + if (head == null) { head = anchor$1; } + sel = {anchor: anchor$1 + from, head: head + from}; + } + return {doc: doc, sel: sel, from: from, to: to} +} + +function ruleFromNode(dom) { + var desc = dom.pmViewDesc; + if (desc) { + return desc.parseRule() + } else if (dom.nodeName == "BR" && dom.parentNode) { + // Safari replaces the list item or table cell with a BR + // directly in the list node (?!) if you delete the last + // character in a list item or table cell (#708, #862) + if (result.safari && /^(ul|ol)$/i.test(dom.parentNode.nodeName)) { + var skip = document.createElement("div"); + skip.appendChild(document.createElement("li")); + return {skip: skip} + } else if (dom.parentNode.lastChild == dom || result.safari && /^(tr|table)$/i.test(dom.parentNode.nodeName)) { + return {ignore: true} + } + } else if (dom.nodeName == "IMG" && dom.getAttribute("mark-placeholder")) { + return {ignore: true} + } +} + +function readDOMChange(view, from, to, typeOver) { + if (from < 0) { + var origin = view.lastSelectionTime > Date.now() - 50 ? view.lastSelectionOrigin : null; + var newSel = selectionFromDOM(view, origin); + if (!view.state.selection.eq(newSel)) { + var tr$1 = view.state.tr.setSelection(newSel); + if (origin == "pointer") { tr$1.setMeta("pointer", true); } + else if (origin == "key") { tr$1.scrollIntoView(); } + view.dispatch(tr$1); + } + return + } + + var $before = view.state.doc.resolve(from); + var shared = $before.sharedDepth(to); + from = $before.before(shared + 1); + to = view.state.doc.resolve(to).after(shared + 1); + + var sel = view.state.selection; + var parse = parseBetween(view, from, to); + + var doc = view.state.doc, compare = doc.slice(parse.from, parse.to); + var preferredPos, preferredSide; + // Prefer anchoring to end when Backspace is pressed + if (view.lastKeyCode === 8 && Date.now() - 100 < view.lastKeyCodeTime) { + preferredPos = view.state.selection.to; + preferredSide = "end"; + } else { + preferredPos = view.state.selection.from; + preferredSide = "start"; + } + view.lastKeyCode = null; + + var change = findDiff(compare.content, parse.doc.content, parse.from, preferredPos, preferredSide); + if (!change) { + if (typeOver && sel instanceof TextSelection && !sel.empty && sel.$head.sameParent(sel.$anchor) && + !view.composing && !(parse.sel && parse.sel.anchor != parse.sel.head)) { + change = {start: sel.from, endA: sel.to, endB: sel.to}; + } else { + if (parse.sel) { + var sel$1 = resolveSelection(view, view.state.doc, parse.sel); + if (sel$1 && !sel$1.eq(view.state.selection)) { view.dispatch(view.state.tr.setSelection(sel$1)); } + } + return + } + } + view.domChangeCount++; + // Handle the case where overwriting a selection by typing matches + // the start or end of the selected content, creating a change + // that's smaller than what was actually overwritten. + if (view.state.selection.from < view.state.selection.to && + change.start == change.endB && + view.state.selection instanceof TextSelection) { + if (change.start > view.state.selection.from && change.start <= view.state.selection.from + 2) { + change.start = view.state.selection.from; + } else if (change.endA < view.state.selection.to && change.endA >= view.state.selection.to - 2) { + change.endB += (view.state.selection.to - change.endA); + change.endA = view.state.selection.to; + } + } + + // IE11 will insert a non-breaking space _ahead_ of the space after + // the cursor space when adding a space before another space. When + // that happened, adjust the change to cover the space instead. + if (result.ie && result.ie_version <= 11 && change.endB == change.start + 1 && + change.endA == change.start && change.start > parse.from && + parse.doc.textBetween(change.start - parse.from - 1, change.start - parse.from + 1) == " \u00a0") { + change.start--; + change.endA--; + change.endB--; + } + + var $from = parse.doc.resolveNoCache(change.start - parse.from); + var $to = parse.doc.resolveNoCache(change.endB - parse.from); + var nextSel; + // If this looks like the effect of pressing Enter, just dispatch an + // Enter key instead. + if (!$from.sameParent($to) && $from.pos < parse.doc.content.size && + (nextSel = Selection.findFrom(parse.doc.resolve($from.pos + 1), 1, true)) && + nextSel.head == $to.pos && + view.someProp("handleKeyDown", function (f) { return f(view, keyEvent(13, "Enter")); })) + { return } + // Same for backspace + if (view.state.selection.anchor > change.start && + looksLikeJoin(doc, change.start, change.endA, $from, $to) && + view.someProp("handleKeyDown", function (f) { return f(view, keyEvent(8, "Backspace")); })) { + if (result.android && result.chrome) { view.domObserver.suppressSelectionUpdates(); } // #820 + return + } + + var chFrom = change.start, chTo = change.endA; + + var tr, storedMarks, markChange, $from1; + if ($from.sameParent($to) && $from.parent.inlineContent) { + if ($from.pos == $to.pos) { // Deletion + // IE11 sometimes weirdly moves the DOM selection around after + // backspacing out the first element in a textblock + if (result.ie && result.ie_version <= 11 && $from.parentOffset == 0) { + view.domObserver.suppressSelectionUpdates(); + setTimeout(function () { return selectionToDOM(view); }, 20); + } + tr = view.state.tr.delete(chFrom, chTo); + storedMarks = doc.resolve(change.start).marksAcross(doc.resolve(change.endA)); + } else if ( // Adding or removing a mark + change.endA == change.endB && ($from1 = doc.resolve(change.start)) && + (markChange = isMarkChange($from.parent.content.cut($from.parentOffset, $to.parentOffset), + $from1.parent.content.cut($from1.parentOffset, change.endA - $from1.start()))) + ) { + tr = view.state.tr; + if (markChange.type == "add") { tr.addMark(chFrom, chTo, markChange.mark); } + else { tr.removeMark(chFrom, chTo, markChange.mark); } + } else if ($from.parent.child($from.index()).isText && $from.index() == $to.index() - ($to.textOffset ? 0 : 1)) { + // Both positions in the same text node -- simply insert text + var text = $from.parent.textBetween($from.parentOffset, $to.parentOffset); + if (view.someProp("handleTextInput", function (f) { return f(view, chFrom, chTo, text); })) { return } + tr = view.state.tr.insertText(text, chFrom, chTo); + } + } + + if (!tr) + { tr = view.state.tr.replace(chFrom, chTo, parse.doc.slice(change.start - parse.from, change.endB - parse.from)); } + if (parse.sel) { + var sel$2 = resolveSelection(view, tr.doc, parse.sel); + // Chrome Android will sometimes, during composition, report the + // selection in the wrong place. If it looks like that is + // happening, don't update the selection. + // Edge just doesn't move the cursor forward when you start typing + // in an empty block or between br nodes. + if (sel$2 && !(result.chrome && result.android && view.composing && sel$2.empty && sel$2.head == chFrom || + result.ie && sel$2.empty && sel$2.head == chFrom)) + { tr.setSelection(sel$2); } + } + if (storedMarks) { tr.ensureMarks(storedMarks); } + view.dispatch(tr.scrollIntoView()); +} + +function resolveSelection(view, doc, parsedSel) { + if (Math.max(parsedSel.anchor, parsedSel.head) > doc.content.size) { return null } + return selectionBetween(view, doc.resolve(parsedSel.anchor), doc.resolve(parsedSel.head)) +} + +// : (Fragment, Fragment) → ?{mark: Mark, type: string} +// Given two same-length, non-empty fragments of inline content, +// determine whether the first could be created from the second by +// removing or adding a single mark type. +function isMarkChange(cur, prev) { + var curMarks = cur.firstChild.marks, prevMarks = prev.firstChild.marks; + var added = curMarks, removed = prevMarks, type, mark, update; + for (var i = 0; i < prevMarks.length; i++) { added = prevMarks[i].removeFromSet(added); } + for (var i$1 = 0; i$1 < curMarks.length; i$1++) { removed = curMarks[i$1].removeFromSet(removed); } + if (added.length == 1 && removed.length == 0) { + mark = added[0]; + type = "add"; + update = function (node) { return node.mark(mark.addToSet(node.marks)); }; + } else if (added.length == 0 && removed.length == 1) { + mark = removed[0]; + type = "remove"; + update = function (node) { return node.mark(mark.removeFromSet(node.marks)); }; + } else { + return null + } + var updated = []; + for (var i$2 = 0; i$2 < prev.childCount; i$2++) { updated.push(update(prev.child(i$2))); } + if (Fragment.from(updated).eq(cur)) { return {mark: mark, type: type} } +} + +function looksLikeJoin(old, start, end, $newStart, $newEnd) { + if (!$newStart.parent.isTextblock || + // The content must have shrunk + end - start <= $newEnd.pos - $newStart.pos || + // newEnd must point directly at or after the end of the block that newStart points into + skipClosingAndOpening($newStart, true, false) < $newEnd.pos) + { return false } + + var $start = old.resolve(start); + // Start must be at the end of a block + if ($start.parentOffset < $start.parent.content.size || !$start.parent.isTextblock) + { return false } + var $next = old.resolve(skipClosingAndOpening($start, true, true)); + // The next textblock must start before end and end near it + if (!$next.parent.isTextblock || $next.pos > end || + skipClosingAndOpening($next, true, false) < end) + { return false } + + // The fragments after the join point must match + return $newStart.parent.content.cut($newStart.parentOffset).eq($next.parent.content) +} + +function skipClosingAndOpening($pos, fromEnd, mayOpen) { + var depth = $pos.depth, end = fromEnd ? $pos.end() : $pos.pos; + while (depth > 0 && (fromEnd || $pos.indexAfter(depth) == $pos.node(depth).childCount)) { + depth--; + end++; + fromEnd = false; + } + if (mayOpen) { + var next = $pos.node(depth).maybeChild($pos.indexAfter(depth)); + while (next && !next.isLeaf) { + next = next.firstChild; + end++; + } + } + return end +} + +function findDiff(a, b, pos, preferredPos, preferredSide) { + var start = a.findDiffStart(b, pos); + if (start == null) { return null } + var ref = a.findDiffEnd(b, pos + a.size, pos + b.size); + var endA = ref.a; + var endB = ref.b; + if (preferredSide == "end") { + var adjust = Math.max(0, start - Math.min(endA, endB)); + preferredPos -= endA + adjust - start; + } + if (endA < start && a.size < b.size) { + var move = preferredPos <= start && preferredPos >= endA ? start - preferredPos : 0; + start -= move; + endB = start + (endB - endA); + endA = start; + } else if (endB < start) { + var move$1 = preferredPos <= start && preferredPos >= endB ? start - preferredPos : 0; + start -= move$1; + endA = start + (endA - endB); + endB = start; + } + return {start: start, endA: endA, endB: endB} +} + +function serializeForClipboard(view, slice) { + var context = []; + var content = slice.content; + var openStart = slice.openStart; + var openEnd = slice.openEnd; + while (openStart > 1 && openEnd > 1 && content.childCount == 1 && content.firstChild.childCount == 1) { + openStart--; + openEnd--; + var node = content.firstChild; + context.push(node.type.name, node.type.hasRequiredAttrs() ? node.attrs : null); + content = node.content; + } + + var serializer = view.someProp("clipboardSerializer") || DOMSerializer.fromSchema(view.state.schema); + var doc = detachedDoc(), wrap = doc.createElement("div"); + wrap.appendChild(serializer.serializeFragment(content, {document: doc})); + + var firstChild = wrap.firstChild, needsWrap; + while (firstChild && firstChild.nodeType == 1 && (needsWrap = wrapMap[firstChild.nodeName.toLowerCase()])) { + for (var i = needsWrap.length - 1; i >= 0; i--) { + var wrapper = doc.createElement(needsWrap[i]); + while (wrap.firstChild) { wrapper.appendChild(wrap.firstChild); } + wrap.appendChild(wrapper); + } + firstChild = wrap.firstChild; + } + + if (firstChild && firstChild.nodeType == 1) + { firstChild.setAttribute("data-pm-slice", (openStart + " " + openEnd + " " + (JSON.stringify(context)))); } + + var text = view.someProp("clipboardTextSerializer", function (f) { return f(slice); }) || + slice.content.textBetween(0, slice.content.size, "\n\n"); + + return {dom: wrap, text: text} +} + +// : (EditorView, string, string, ?bool, ResolvedPos) → ?Slice +// Read a slice of content from the clipboard (or drop data). +function parseFromClipboard(view, text, html, plainText, $context) { + var dom, inCode = $context.parent.type.spec.code, slice; + if (!html && !text) { return null } + var asText = text && (plainText || inCode || !html); + if (asText) { + view.someProp("transformPastedText", function (f) { text = f(text); }); + if (inCode) { return new Slice(Fragment.from(view.state.schema.text(text)), 0, 0) } + var parsed = view.someProp("clipboardTextParser", function (f) { return f(text, $context); }); + if (parsed) { + slice = parsed; + } else { + dom = document.createElement("div"); + text.trim().split(/(?:\r\n?|\n)+/).forEach(function (block) { + dom.appendChild(document.createElement("p")).textContent = block; + }); + } + } else { + view.someProp("transformPastedHTML", function (f) { html = f(html); }); + dom = readHTML(html); + } + + var contextNode = dom && dom.querySelector("[data-pm-slice]"); + var sliceData = contextNode && /^(\d+) (\d+) (.*)/.exec(contextNode.getAttribute("data-pm-slice")); + if (!slice) { + var parser = view.someProp("clipboardParser") || view.someProp("domParser") || DOMParser.fromSchema(view.state.schema); + slice = parser.parseSlice(dom, {preserveWhitespace: !!(asText || sliceData), context: $context}); + } + if (sliceData) + { slice = addContext(closeSlice(slice, +sliceData[1], +sliceData[2]), sliceData[3]); } + else // HTML wasn't created by ProseMirror. Make sure top-level siblings are coherent + { slice = Slice.maxOpen(normalizeSiblings(slice.content, $context), false); } + + view.someProp("transformPasted", function (f) { slice = f(slice); }); + return slice +} + +// Takes a slice parsed with parseSlice, which means there hasn't been +// any content-expression checking done on the top nodes, tries to +// find a parent node in the current context that might fit the nodes, +// and if successful, rebuilds the slice so that it fits into that parent. +// +// This addresses the problem that Transform.replace expects a +// coherent slice, and will fail to place a set of siblings that don't +// fit anywhere in the schema. +function normalizeSiblings(fragment, $context) { + if (fragment.childCount < 2) { return fragment } + var loop = function ( d ) { + var parent = $context.node(d); + var match = parent.contentMatchAt($context.index(d)); + var lastWrap = (void 0), result = []; + fragment.forEach(function (node) { + if (!result) { return } + var wrap = match.findWrapping(node.type), inLast; + if (!wrap) { return result = null } + if (inLast = result.length && lastWrap.length && addToSibling(wrap, lastWrap, node, result[result.length - 1], 0)) { + result[result.length - 1] = inLast; + } else { + if (result.length) { result[result.length - 1] = closeRight(result[result.length - 1], lastWrap.length); } + var wrapped = withWrappers(node, wrap); + result.push(wrapped); + match = match.matchType(wrapped.type, wrapped.attrs); + lastWrap = wrap; + } + }); + if (result) { return { v: Fragment.from(result) } } + }; + + for (var d = $context.depth; d >= 0; d--) { + var returned = loop( d ); + + if ( returned ) return returned.v; + } + return fragment +} + +function withWrappers(node, wrap, from) { + if ( from === void 0 ) from = 0; + + for (var i = wrap.length - 1; i >= from; i--) + { node = wrap[i].create(null, Fragment.from(node)); } + return node +} + +// Used to group adjacent nodes wrapped in similar parents by +// normalizeSiblings into the same parent node +function addToSibling(wrap, lastWrap, node, sibling, depth) { + if (depth < wrap.length && depth < lastWrap.length && wrap[depth] == lastWrap[depth]) { + var inner = addToSibling(wrap, lastWrap, node, sibling.lastChild, depth + 1); + if (inner) { return sibling.copy(sibling.content.replaceChild(sibling.childCount - 1, inner)) } + var match = sibling.contentMatchAt(sibling.childCount); + if (match.matchType(depth == wrap.length - 1 ? node.type : wrap[depth + 1])) + { return sibling.copy(sibling.content.append(Fragment.from(withWrappers(node, wrap, depth + 1)))) } + } +} + +function closeRight(node, depth) { + if (depth == 0) { return node } + var fragment = node.content.replaceChild(node.childCount - 1, closeRight(node.lastChild, depth - 1)); + var fill = node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true); + return node.copy(fragment.append(fill)) +} + +function closeRange(fragment, side, from, to, depth, openEnd) { + var node = side < 0 ? fragment.firstChild : fragment.lastChild, inner = node.content; + if (depth < to - 1) { inner = closeRange(inner, side, from, to, depth + 1, openEnd); } + if (depth >= from) + { inner = side < 0 ? node.contentMatchAt(0).fillBefore(inner, fragment.childCount > 1 || openEnd <= depth).append(inner) + : inner.append(node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true)); } + return fragment.replaceChild(side < 0 ? 0 : fragment.childCount - 1, node.copy(inner)) +} + +function closeSlice(slice, openStart, openEnd) { + if (openStart < slice.openStart) + { slice = new Slice(closeRange(slice.content, -1, openStart, slice.openStart, 0, slice.openEnd), openStart, slice.openEnd); } + if (openEnd < slice.openEnd) + { slice = new Slice(closeRange(slice.content, 1, openEnd, slice.openEnd, 0, 0), slice.openStart, openEnd); } + return slice +} + +// Trick from jQuery -- some elements must be wrapped in other +// elements for innerHTML to work. I.e. if you do `div.innerHTML = +// ".."` the table cells are ignored. +var wrapMap = {thead: ["table"], colgroup: ["table"], col: ["table", "colgroup"], + tr: ["table", "tbody"], td: ["table", "tbody", "tr"], th: ["table", "tbody", "tr"]}; + +var _detachedDoc = null; +function detachedDoc() { + return _detachedDoc || (_detachedDoc = document.implementation.createHTMLDocument("title")) +} + +function readHTML(html) { + var metas = /(\s*]*>)*/.exec(html); + if (metas) { html = html.slice(metas[0].length); } + var elt = detachedDoc().createElement("div"); + var firstTag = /(?:]*>)*<([a-z][^>\s]+)/i.exec(html), wrap, depth = 0; + if (wrap = firstTag && wrapMap[firstTag[1].toLowerCase()]) { + html = wrap.map(function (n) { return "<" + n + ">"; }).join("") + html + wrap.map(function (n) { return ""; }).reverse().join(""); + depth = wrap.length; + } + elt.innerHTML = html; + for (var i = 0; i < depth; i++) { elt = elt.firstChild; } + return elt +} + +function addContext(slice, context) { + if (!slice.size) { return slice } + var schema = slice.content.firstChild.type.schema, array; + try { array = JSON.parse(context); } + catch(e) { return slice } + var content = slice.content; + var openStart = slice.openStart; + var openEnd = slice.openEnd; + for (var i = array.length - 2; i >= 0; i -= 2) { + var type = schema.nodes[array[i]]; + if (!type || type.hasRequiredAttrs()) { break } + content = Fragment.from(type.create(array[i + 1], content)); + openStart++; openEnd++; + } + return new Slice(content, openStart, openEnd) +} + +var observeOptions = { + childList: true, + characterData: true, + characterDataOldValue: true, + attributes: true, + attributeOldValue: true, + subtree: true +}; +// IE11 has very broken mutation observers, so we also listen to DOMCharacterDataModified +var useCharData = result.ie && result.ie_version <= 11; + +var SelectionState = function SelectionState() { + this.anchorNode = this.anchorOffset = this.focusNode = this.focusOffset = null; +}; + +SelectionState.prototype.set = function set (sel) { + this.anchorNode = sel.anchorNode; this.anchorOffset = sel.anchorOffset; + this.focusNode = sel.focusNode; this.focusOffset = sel.focusOffset; +}; + +SelectionState.prototype.eq = function eq (sel) { + return sel.anchorNode == this.anchorNode && sel.anchorOffset == this.anchorOffset && + sel.focusNode == this.focusNode && sel.focusOffset == this.focusOffset +}; + +var DOMObserver = function DOMObserver(view, handleDOMChange) { + var this$1 = this; + + this.view = view; + this.handleDOMChange = handleDOMChange; + this.queue = []; + this.flushingSoon = false; + this.observer = window.MutationObserver && + new window.MutationObserver(function (mutations) { + for (var i = 0; i < mutations.length; i++) { this$1.queue.push(mutations[i]); } + // IE11 will sometimes (on backspacing out a single character + // text node after a BR node) call the observer callback + // before actually updating the DOM, which will cause + // ProseMirror to miss the change (see #930) + if (result.ie && result.ie_version <= 11 && mutations.some( + function (m) { return m.type == "childList" && m.removedNodes.length || + m.type == "characterData" && m.oldValue.length > m.target.nodeValue.length; })) + { this$1.flushSoon(); } + else + { this$1.flush(); } + }); + this.currentSelection = new SelectionState; + if (useCharData) { + this.onCharData = function (e) { + this$1.queue.push({target: e.target, type: "characterData", oldValue: e.prevValue}); + this$1.flushSoon(); + }; + } + this.onSelectionChange = this.onSelectionChange.bind(this); + this.suppressingSelectionUpdates = false; +}; + +DOMObserver.prototype.flushSoon = function flushSoon () { + var this$1 = this; + + if (!this.flushingSoon) { + this.flushingSoon = true; + window.setTimeout(function () { this$1.flushingSoon = false; this$1.flush(); }, 20); + } +}; + +DOMObserver.prototype.start = function start () { + if (this.observer) + { this.observer.observe(this.view.dom, observeOptions); } + if (useCharData) + { this.view.dom.addEventListener("DOMCharacterDataModified", this.onCharData); } + this.connectSelection(); +}; + +DOMObserver.prototype.stop = function stop () { + var this$1 = this; + + if (this.observer) { + var take = this.observer.takeRecords(); + if (take.length) { + for (var i = 0; i < take.length; i++) { this.queue.push(take[i]); } + window.setTimeout(function () { return this$1.flush(); }, 20); + } + this.observer.disconnect(); + } + if (useCharData) { this.view.dom.removeEventListener("DOMCharacterDataModified", this.onCharData); } + this.disconnectSelection(); +}; + +DOMObserver.prototype.connectSelection = function connectSelection () { + this.view.dom.ownerDocument.addEventListener("selectionchange", this.onSelectionChange); +}; + +DOMObserver.prototype.disconnectSelection = function disconnectSelection () { + this.view.dom.ownerDocument.removeEventListener("selectionchange", this.onSelectionChange); +}; + +DOMObserver.prototype.suppressSelectionUpdates = function suppressSelectionUpdates () { + var this$1 = this; + + this.suppressingSelectionUpdates = true; + setTimeout(function () { return this$1.suppressingSelectionUpdates = false; }, 50); +}; + +DOMObserver.prototype.onSelectionChange = function onSelectionChange () { + if (!hasFocusAndSelection(this.view)) { return } + if (this.suppressingSelectionUpdates) { return selectionToDOM(this.view) } + // Deletions on IE11 fire their events in the wrong order, giving + // us a selection change event before the DOM changes are + // reported. + if (result.ie && result.ie_version <= 11 && !this.view.state.selection.empty) { + var sel = this.view.root.getSelection(); + // Selection.isCollapsed isn't reliable on IE + if (sel.focusNode && isEquivalentPosition(sel.focusNode, sel.focusOffset, sel.anchorNode, sel.anchorOffset)) + { return this.flushSoon() } + } + this.flush(); +}; + +DOMObserver.prototype.setCurSelection = function setCurSelection () { + this.currentSelection.set(this.view.root.getSelection()); +}; + +DOMObserver.prototype.ignoreSelectionChange = function ignoreSelectionChange (sel) { + if (sel.rangeCount == 0) { return true } + var container = sel.getRangeAt(0).commonAncestorContainer; + var desc = this.view.docView.nearestDesc(container); + return desc && desc.ignoreMutation({type: "selection", target: container.nodeType == 3 ? container.parentNode : container}) +}; + +DOMObserver.prototype.flush = function flush () { + if (!this.view.docView || this.flushingSoon) { return } + var mutations = this.observer ? this.observer.takeRecords() : []; + if (this.queue.length) { + mutations = this.queue.concat(mutations); + this.queue.length = 0; + } + + var sel = this.view.root.getSelection(); + var newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasSelection(this.view) && !this.ignoreSelectionChange(sel); + + var from = -1, to = -1, typeOver = false, added = []; + if (this.view.editable) { + for (var i = 0; i < mutations.length; i++) { + var result$1 = this.registerMutation(mutations[i], added); + if (result$1) { + from = from < 0 ? result$1.from : Math.min(result$1.from, from); + to = to < 0 ? result$1.to : Math.max(result$1.to, to); + if (result$1.typeOver && !this.view.composing) { typeOver = true; } + } + } + } + + if (result.gecko && added.length > 1) { + var brs = added.filter(function (n) { return n.nodeName == "BR"; }); + if (brs.length == 2) { + var a = brs[0]; + var b = brs[1]; + if (a.parentNode && a.parentNode.parentNode == b.parentNode) { b.remove(); } + else { a.remove(); } + } + } + + if (from > -1 || newSel) { + if (from > -1) { + this.view.docView.markDirty(from, to); + checkCSS(this.view); + } + this.handleDOMChange(from, to, typeOver); + if (this.view.docView.dirty) { this.view.updateState(this.view.state); } + else if (!this.currentSelection.eq(sel)) { selectionToDOM(this.view); } + } +}; + +DOMObserver.prototype.registerMutation = function registerMutation (mut, added) { + // Ignore mutations inside nodes that were already noted as inserted + if (added.indexOf(mut.target) > -1) { return null } + var desc = this.view.docView.nearestDesc(mut.target); + if (mut.type == "attributes" && + (desc == this.view.docView || mut.attributeName == "contenteditable" || + // Firefox sometimes fires spurious events for null/empty styles + (mut.attributeName == "style" && !mut.oldValue && !mut.target.getAttribute("style")))) + { return null } + if (!desc || desc.ignoreMutation(mut)) { return null } + + if (mut.type == "childList") { + var prev = mut.previousSibling, next = mut.nextSibling; + if (result.ie && result.ie_version <= 11 && mut.addedNodes.length) { + // IE11 gives us incorrect next/prev siblings for some + // insertions, so if there are added nodes, recompute those + for (var i = 0; i < mut.addedNodes.length; i++) { + var ref = mut.addedNodes[i]; + var previousSibling = ref.previousSibling; + var nextSibling = ref.nextSibling; + if (!previousSibling || Array.prototype.indexOf.call(mut.addedNodes, previousSibling) < 0) { prev = previousSibling; } + if (!nextSibling || Array.prototype.indexOf.call(mut.addedNodes, nextSibling) < 0) { next = nextSibling; } + } + } + var fromOffset = prev && prev.parentNode == mut.target + ? domIndex(prev) + 1 : 0; + var from = desc.localPosFromDOM(mut.target, fromOffset, -1); + var toOffset = next && next.parentNode == mut.target + ? domIndex(next) : mut.target.childNodes.length; + for (var i$1 = 0; i$1 < mut.addedNodes.length; i$1++) { added.push(mut.addedNodes[i$1]); } + var to = desc.localPosFromDOM(mut.target, toOffset, 1); + return {from: from, to: to} + } else if (mut.type == "attributes") { + return {from: desc.posAtStart - desc.border, to: desc.posAtEnd + desc.border} + } else { // "characterData" + return { + from: desc.posAtStart, + to: desc.posAtEnd, + // An event was generated for a text change that didn't change + // any text. Mark the dom change to fall back to assuming the + // selection was typed over with an identical value if it can't + // find another change. + typeOver: mut.target.nodeValue == mut.oldValue + } + } +}; + +var cssChecked = false; + +function checkCSS(view) { + if (cssChecked) { return } + cssChecked = true; + if (getComputedStyle(view.dom).whiteSpace == "normal") + { console["warn"]("ProseMirror expects the CSS white-space property to be set, preferably to 'pre-wrap'. It is recommended to load style/prosemirror.css from the prosemirror-view package."); } +} + +// A collection of DOM events that occur within the editor, and callback functions +// to invoke when the event fires. +var handlers = {}, editHandlers = {}; + +function initInput(view) { + view.shiftKey = false; + view.mouseDown = null; + view.lastKeyCode = null; + view.lastKeyCodeTime = 0; + view.lastClick = {time: 0, x: 0, y: 0, type: ""}; + view.lastSelectionOrigin = null; + view.lastSelectionTime = 0; + + view.composing = false; + view.composingTimeout = null; + view.compositionNodes = []; + view.compositionEndedAt = -2e8; + + view.domObserver = new DOMObserver(view, function (from, to, typeOver) { return readDOMChange(view, from, to, typeOver); }); + view.domObserver.start(); + // Used by hacks like the beforeinput handler to check whether anything happened in the DOM + view.domChangeCount = 0; + + view.eventHandlers = Object.create(null); + var loop = function ( event ) { + var handler = handlers[event]; + view.dom.addEventListener(event, view.eventHandlers[event] = function (event) { + if (eventBelongsToView(view, event) && !runCustomHandler(view, event) && + (view.editable || !(event.type in editHandlers))) + { handler(view, event); } + }); + }; + + for (var event in handlers) loop( event ); + // On Safari, for reasons beyond my understanding, adding an input + // event handler makes an issue where the composition vanishes when + // you press enter go away. + if (result.safari) { view.dom.addEventListener("input", function () { return null; }); } + + ensureListeners(view); +} + +function setSelectionOrigin(view, origin) { + view.lastSelectionOrigin = origin; + view.lastSelectionTime = Date.now(); +} + +function destroyInput(view) { + view.domObserver.stop(); + for (var type in view.eventHandlers) + { view.dom.removeEventListener(type, view.eventHandlers[type]); } + clearTimeout(view.composingTimeout); +} + +function ensureListeners(view) { + view.someProp("handleDOMEvents", function (currentHandlers) { + for (var type in currentHandlers) { if (!view.eventHandlers[type]) + { view.dom.addEventListener(type, view.eventHandlers[type] = function (event) { return runCustomHandler(view, event); }); } } + }); +} + +function runCustomHandler(view, event) { + return view.someProp("handleDOMEvents", function (handlers) { + var handler = handlers[event.type]; + return handler ? handler(view, event) || event.defaultPrevented : false + }) +} + +function eventBelongsToView(view, event) { + if (!event.bubbles) { return true } + if (event.defaultPrevented) { return false } + for (var node = event.target; node != view.dom; node = node.parentNode) + { if (!node || node.nodeType == 11 || + (node.pmViewDesc && node.pmViewDesc.stopEvent(event))) + { return false } } + return true +} + +function dispatchEvent(view, event) { + if (!runCustomHandler(view, event) && handlers[event.type] && + (view.editable || !(event.type in editHandlers))) + { handlers[event.type](view, event); } +} + +editHandlers.keydown = function (view, event) { + view.shiftKey = event.keyCode == 16 || event.shiftKey; + if (inOrNearComposition(view, event)) { return } + view.lastKeyCode = event.keyCode; + view.lastKeyCodeTime = Date.now(); + if (view.someProp("handleKeyDown", function (f) { return f(view, event); }) || captureKeyDown(view, event)) + { event.preventDefault(); } + else + { setSelectionOrigin(view, "key"); } +}; + +editHandlers.keyup = function (view, e) { + if (e.keyCode == 16) { view.shiftKey = false; } +}; + +editHandlers.keypress = function (view, event) { + if (inOrNearComposition(view, event) || !event.charCode || + event.ctrlKey && !event.altKey || result.mac && event.metaKey) { return } + + if (view.someProp("handleKeyPress", function (f) { return f(view, event); })) { + event.preventDefault(); + return + } + + var sel = view.state.selection; + if (!(sel instanceof TextSelection) || !sel.$from.sameParent(sel.$to)) { + var text = String.fromCharCode(event.charCode); + if (!view.someProp("handleTextInput", function (f) { return f(view, sel.$from.pos, sel.$to.pos, text); })) + { view.dispatch(view.state.tr.insertText(text).scrollIntoView()); } + event.preventDefault(); + } +}; + +function eventCoords(event) { return {left: event.clientX, top: event.clientY} } + +function isNear(event, click) { + var dx = click.x - event.clientX, dy = click.y - event.clientY; + return dx * dx + dy * dy < 100 +} + +function runHandlerOnContext(view, propName, pos, inside, event) { + if (inside == -1) { return false } + var $pos = view.state.doc.resolve(inside); + var loop = function ( i ) { + if (view.someProp(propName, function (f) { return i > $pos.depth ? f(view, pos, $pos.nodeAfter, $pos.before(i), event, true) + : f(view, pos, $pos.node(i), $pos.before(i), event, false); })) + { return { v: true } } + }; + + for (var i = $pos.depth + 1; i > 0; i--) { + var returned = loop( i ); + + if ( returned ) return returned.v; + } + return false +} + +function updateSelection(view, selection, origin) { + if (!view.focused) { view.focus(); } + var tr = view.state.tr.setSelection(selection); + if (origin == "pointer") { tr.setMeta("pointer", true); } + view.dispatch(tr); +} + +function selectClickedLeaf(view, inside) { + if (inside == -1) { return false } + var $pos = view.state.doc.resolve(inside), node = $pos.nodeAfter; + if (node && node.isAtom && NodeSelection.isSelectable(node)) { + updateSelection(view, new NodeSelection($pos), "pointer"); + return true + } + return false +} + +function selectClickedNode(view, inside) { + if (inside == -1) { return false } + var sel = view.state.selection, selectedNode, selectAt; + if (sel instanceof NodeSelection) { selectedNode = sel.node; } + + var $pos = view.state.doc.resolve(inside); + for (var i = $pos.depth + 1; i > 0; i--) { + var node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i); + if (NodeSelection.isSelectable(node)) { + if (selectedNode && sel.$from.depth > 0 && + i >= sel.$from.depth && $pos.before(sel.$from.depth + 1) == sel.$from.pos) + { selectAt = $pos.before(sel.$from.depth); } + else + { selectAt = $pos.before(i); } + break + } + } + + if (selectAt != null) { + updateSelection(view, NodeSelection.create(view.state.doc, selectAt), "pointer"); + return true + } else { + return false + } +} + +function handleSingleClick(view, pos, inside, event, selectNode) { + return runHandlerOnContext(view, "handleClickOn", pos, inside, event) || + view.someProp("handleClick", function (f) { return f(view, pos, event); }) || + (selectNode ? selectClickedNode(view, inside) : selectClickedLeaf(view, inside)) +} + +function handleDoubleClick(view, pos, inside, event) { + return runHandlerOnContext(view, "handleDoubleClickOn", pos, inside, event) || + view.someProp("handleDoubleClick", function (f) { return f(view, pos, event); }) +} + +function handleTripleClick(view, pos, inside, event) { + return runHandlerOnContext(view, "handleTripleClickOn", pos, inside, event) || + view.someProp("handleTripleClick", function (f) { return f(view, pos, event); }) || + defaultTripleClick(view, inside) +} + +function defaultTripleClick(view, inside) { + var doc = view.state.doc; + if (inside == -1) { + if (doc.inlineContent) { + updateSelection(view, TextSelection.create(doc, 0, doc.content.size), "pointer"); + return true + } + return false + } + + var $pos = doc.resolve(inside); + for (var i = $pos.depth + 1; i > 0; i--) { + var node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i); + var nodePos = $pos.before(i); + if (node.inlineContent) + { updateSelection(view, TextSelection.create(doc, nodePos + 1, nodePos + 1 + node.content.size), "pointer"); } + else if (NodeSelection.isSelectable(node)) + { updateSelection(view, NodeSelection.create(doc, nodePos), "pointer"); } + else + { continue } + return true + } +} + +function forceDOMFlush(view) { + return endComposition(view) +} + +var selectNodeModifier = result.mac ? "metaKey" : "ctrlKey"; + +handlers.mousedown = function (view, event) { + view.shiftKey = event.shiftKey; + var flushed = forceDOMFlush(view); + var now = Date.now(), type = "singleClick"; + if (now - view.lastClick.time < 500 && isNear(event, view.lastClick) && !event[selectNodeModifier]) { + if (view.lastClick.type == "singleClick") { type = "doubleClick"; } + else if (view.lastClick.type == "doubleClick") { type = "tripleClick"; } + } + view.lastClick = {time: now, x: event.clientX, y: event.clientY, type: type}; + + var pos = view.posAtCoords(eventCoords(event)); + if (!pos) { return } + + if (type == "singleClick") + { view.mouseDown = new MouseDown(view, pos, event, flushed); } + else if ((type == "doubleClick" ? handleDoubleClick : handleTripleClick)(view, pos.pos, pos.inside, event)) + { event.preventDefault(); } + else + { setSelectionOrigin(view, "pointer"); } +}; + +var MouseDown = function MouseDown(view, pos, event, flushed) { + var this$1 = this; + + this.view = view; + this.startDoc = view.state.doc; + this.pos = pos; + this.event = event; + this.flushed = flushed; + this.selectNode = event[selectNodeModifier]; + this.allowDefault = event.shiftKey; + + var targetNode, targetPos; + if (pos.inside > -1) { + targetNode = view.state.doc.nodeAt(pos.inside); + targetPos = pos.inside; + } else { + var $pos = view.state.doc.resolve(pos.pos); + targetNode = $pos.parent; + targetPos = $pos.depth ? $pos.before() : 0; + } + + this.mightDrag = null; + + var target = flushed ? null : event.target; + var targetDesc = target ? view.docView.nearestDesc(target, true) : null; + this.target = targetDesc ? targetDesc.dom : null; + + if (targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false || + view.state.selection instanceof NodeSelection && targetPos == view.state.selection.from) + { this.mightDrag = {node: targetNode, + pos: targetPos, + addAttr: this.target && !this.target.draggable, + setUneditable: this.target && result.gecko && !this.target.hasAttribute("contentEditable")}; } + + if (this.target && this.mightDrag && (this.mightDrag.addAttr || this.mightDrag.setUneditable)) { + this.view.domObserver.stop(); + if (this.mightDrag.addAttr) { this.target.draggable = true; } + if (this.mightDrag.setUneditable) + { setTimeout(function () { return this$1.target.setAttribute("contentEditable", "false"); }, 20); } + this.view.domObserver.start(); + } + + view.root.addEventListener("mouseup", this.up = this.up.bind(this)); + view.root.addEventListener("mousemove", this.move = this.move.bind(this)); + setSelectionOrigin(view, "pointer"); +}; + +MouseDown.prototype.done = function done () { + this.view.root.removeEventListener("mouseup", this.up); + this.view.root.removeEventListener("mousemove", this.move); + if (this.mightDrag && this.target) { + this.view.domObserver.stop(); + if (this.mightDrag.addAttr) { this.target.draggable = false; } + if (this.mightDrag.setUneditable) { this.target.removeAttribute("contentEditable"); } + this.view.domObserver.start(); + } + this.view.mouseDown = null; +}; + +MouseDown.prototype.up = function up (event) { + this.done(); + + if (!this.view.dom.contains(event.target.nodeType == 3 ? event.target.parentNode : event.target)) + { return } + + var pos = this.pos; + if (this.view.state.doc != this.startDoc) { pos = this.view.posAtCoords(eventCoords(event)); } + + if (this.allowDefault || !pos) { + setSelectionOrigin(this.view, "pointer"); + } else if (handleSingleClick(this.view, pos.pos, pos.inside, event, this.selectNode)) { + event.preventDefault(); + } else if (this.flushed || + // Chrome will sometimes treat a node selection as a + // cursor, but still report that the node is selected + // when asked through getSelection. You'll then get a + // situation where clicking at the point where that + // (hidden) cursor is doesn't change the selection, and + // thus doesn't get a reaction from ProseMirror. This + // works around that. + (result.chrome && !(this.view.state.selection instanceof TextSelection) && + (pos.pos == this.view.state.selection.from || pos.pos == this.view.state.selection.to))) { + updateSelection(this.view, Selection.near(this.view.state.doc.resolve(pos.pos)), "pointer"); + event.preventDefault(); + } else { + setSelectionOrigin(this.view, "pointer"); + } +}; + +MouseDown.prototype.move = function move (event) { + if (!this.allowDefault && (Math.abs(this.event.x - event.clientX) > 4 || + Math.abs(this.event.y - event.clientY) > 4)) + { this.allowDefault = true; } + setSelectionOrigin(this.view, "pointer"); +}; + +handlers.touchdown = function (view) { + forceDOMFlush(view); + setSelectionOrigin(view, "pointer"); +}; + +handlers.contextmenu = function (view) { return forceDOMFlush(view); }; + +function inOrNearComposition(view, event) { + if (view.composing) { return true } + // See https://www.stum.de/2016/06/24/handling-ime-events-in-javascript/. + // On Japanese input method editors (IMEs), the Enter key is used to confirm character + // selection. On Safari, when Enter is pressed, compositionend and keydown events are + // emitted. The keydown event triggers newline insertion, which we don't want. + // This method returns true if the keydown event should be ignored. + // We only ignore it once, as pressing Enter a second time *should* insert a newline. + // Furthermore, the keydown event timestamp must be close to the compositionEndedAt timestamp. + // This guards against the case where compositionend is triggered without the keyboard + // (e.g. character confirmation may be done with the mouse), and keydown is triggered + // afterwards- we wouldn't want to ignore the keydown event in this case. + if (result.safari && Math.abs(event.timeStamp - view.compositionEndedAt) < 500) { + view.compositionEndedAt = -2e8; + return true + } + return false +} + +// Drop active composition after 5 seconds of inactivity on Android +var timeoutComposition = result.android ? 5000 : -1; + +editHandlers.compositionstart = editHandlers.compositionupdate = function (view) { + if (!view.composing) { + view.domObserver.flush(); + var state = view.state; + var $pos = state.selection.$from; + if (state.selection.empty && + (state.storedMarks || (!$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some(function (m) { return m.type.spec.inclusive === false; })))) { + // Need to wrap the cursor in mark nodes different from the ones in the DOM context + view.markCursor = view.state.storedMarks || $pos.marks(); + endComposition(view, true); + view.markCursor = null; + } else { + endComposition(view); + // In firefox, if the cursor is after but outside a marked node, + // the inserted text won't inherit the marks. So this moves it + // inside if necessary. + if (result.gecko && state.selection.empty && $pos.parentOffset && !$pos.textOffset && $pos.nodeBefore.marks.length) { + var sel = view.root.getSelection(); + for (var node = sel.focusNode, offset = sel.focusOffset; node && node.nodeType == 1 && offset != 0;) { + var before = offset < 0 ? node.lastChild : node.childNodes[offset - 1]; + if (before.nodeType == 3) { + sel.collapse(before, before.nodeValue.length); + break + } else { + node = before; + offset = -1; + } + } + } + } + view.composing = true; + } + scheduleComposeEnd(view, timeoutComposition); +}; + +editHandlers.compositionend = function (view, event) { + if (view.composing) { + view.composing = false; + view.compositionEndedAt = event.timeStamp; + scheduleComposeEnd(view, 20); + } +}; + +function scheduleComposeEnd(view, delay) { + clearTimeout(view.composingTimeout); + if (delay > -1) { view.composingTimeout = setTimeout(function () { return endComposition(view); }, delay); } +} + +function endComposition(view, forceUpdate) { + view.composing = false; + while (view.compositionNodes.length > 0) { view.compositionNodes.pop().markParentsDirty(); } + if (forceUpdate || view.docView.dirty) { + view.updateState(view.state); + return true + } + return false +} + +function captureCopy(view, dom) { + // The extra wrapper is somehow necessary on IE/Edge to prevent the + // content from being mangled when it is put onto the clipboard + var doc = view.dom.ownerDocument; + var wrap = doc.body.appendChild(doc.createElement("div")); + wrap.appendChild(dom); + wrap.style.cssText = "position: fixed; left: -10000px; top: 10px"; + var sel = getSelection(), range = doc.createRange(); + range.selectNodeContents(dom); + // Done because IE will fire a selectionchange moving the selection + // to its start when removeAllRanges is called and the editor still + // has focus (which will mess up the editor's selection state). + view.dom.blur(); + sel.removeAllRanges(); + sel.addRange(range); + setTimeout(function () { + doc.body.removeChild(wrap); + view.focus(); + }, 50); +} + +// This is very crude, but unfortunately both these browsers _pretend_ +// that they have a clipboard API—all the objects and methods are +// there, they just don't work, and they are hard to test. +var brokenClipboardAPI = (result.ie && result.ie_version < 15) || + (result.ios && result.webkit_version < 604); + +handlers.copy = editHandlers.cut = function (view, e) { + var sel = view.state.selection, cut = e.type == "cut"; + if (sel.empty) { return } + + // IE and Edge's clipboard interface is completely broken + var data = brokenClipboardAPI ? null : e.clipboardData; + var slice = sel.content(); + var ref = serializeForClipboard(view, slice); + var dom = ref.dom; + var text = ref.text; + if (data) { + e.preventDefault(); + data.clearData(); + data.setData("text/html", dom.innerHTML); + data.setData("text/plain", text); + } else { + captureCopy(view, dom); + } + if (cut) { view.dispatch(view.state.tr.deleteSelection().scrollIntoView().setMeta("uiEvent", "cut")); } +}; + +function sliceSingleNode(slice) { + return slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1 ? slice.content.firstChild : null +} + +function capturePaste(view, e) { + var doc = view.dom.ownerDocument; + var plainText = view.shiftKey || view.state.selection.$from.parent.type.spec.code; + var target = doc.body.appendChild(doc.createElement(plainText ? "textarea" : "div")); + if (!plainText) { target.contentEditable = "true"; } + target.style.cssText = "position: fixed; left: -10000px; top: 10px"; + target.focus(); + setTimeout(function () { + view.focus(); + doc.body.removeChild(target); + if (plainText) { doPaste(view, target.value, null, e); } + else { doPaste(view, target.textContent, target.innerHTML, e); } + }, 50); +} + +function doPaste(view, text, html, e) { + var slice = parseFromClipboard(view, text, html, view.shiftKey, view.state.selection.$from); + if (view.someProp("handlePaste", function (f) { return f(view, e, slice || Slice.empty); }) || !slice) { return } + + var singleNode = sliceSingleNode(slice); + var tr = singleNode ? view.state.tr.replaceSelectionWith(singleNode, view.shiftKey) : view.state.tr.replaceSelection(slice); + view.dispatch(tr.scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste")); +} + +editHandlers.paste = function (view, e) { + var data = brokenClipboardAPI ? null : e.clipboardData; + var html = data && data.getData("text/html"), text = data && data.getData("text/plain"); + if (data && (html || text || data.files.length)) { + doPaste(view, text, html, e); + e.preventDefault(); + } else { + capturePaste(view, e); + } +}; + +var Dragging = function Dragging(slice, move) { + this.slice = slice; + this.move = move; +}; + +var dragCopyModifier = result.mac ? "altKey" : "ctrlKey"; + +handlers.dragstart = function (view, e) { + var mouseDown = view.mouseDown; + if (mouseDown) { mouseDown.done(); } + if (!e.dataTransfer) { return } + + var sel = view.state.selection; + var pos = sel.empty ? null : view.posAtCoords(eventCoords(e)); + if (pos && pos.pos >= sel.from && pos.pos <= (sel instanceof NodeSelection ? sel.to - 1: sel.to)) ; else if (mouseDown && mouseDown.mightDrag) { + view.dispatch(view.state.tr.setSelection(NodeSelection.create(view.state.doc, mouseDown.mightDrag.pos))); + } else if (e.target && e.target.nodeType == 1) { + var desc = view.docView.nearestDesc(e.target, true); + if (!desc || !desc.node.type.spec.draggable || desc == view.docView) { return } + view.dispatch(view.state.tr.setSelection(NodeSelection.create(view.state.doc, desc.posBefore))); + } + var slice = view.state.selection.content(); + var ref = serializeForClipboard(view, slice); + var dom = ref.dom; + var text = ref.text; + e.dataTransfer.clearData(); + e.dataTransfer.setData(brokenClipboardAPI ? "Text" : "text/html", dom.innerHTML); + if (!brokenClipboardAPI) { e.dataTransfer.setData("text/plain", text); } + view.dragging = new Dragging(slice, !e[dragCopyModifier]); +}; + +handlers.dragend = function (view) { + window.setTimeout(function () { return view.dragging = null; }, 50); +}; + +editHandlers.dragover = editHandlers.dragenter = function (_, e) { return e.preventDefault(); }; + +editHandlers.drop = function (view, e) { + var dragging = view.dragging; + view.dragging = null; + + if (!e.dataTransfer) { return } + + var eventPos = view.posAtCoords(eventCoords(e)); + if (!eventPos) { return } + var $mouse = view.state.doc.resolve(eventPos.pos); + if (!$mouse) { return } + var slice = dragging && dragging.slice || + parseFromClipboard(view, e.dataTransfer.getData(brokenClipboardAPI ? "Text" : "text/plain"), + brokenClipboardAPI ? null : e.dataTransfer.getData("text/html"), false, $mouse); + if (!slice) { return } + + e.preventDefault(); + if (view.someProp("handleDrop", function (f) { return f(view, e, slice, dragging && dragging.move); })) { return } + var insertPos = slice ? dropPoint(view.state.doc, $mouse.pos, slice) : $mouse.pos; + if (insertPos == null) { insertPos = $mouse.pos; } + + var tr = view.state.tr; + if (dragging && dragging.move) { tr.deleteSelection(); } + + var pos = tr.mapping.map(insertPos); + var isNode = slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1; + var beforeInsert = tr.doc; + if (isNode) + { tr.replaceRangeWith(pos, pos, slice.content.firstChild); } + else + { tr.replaceRange(pos, pos, slice); } + if (tr.doc.eq(beforeInsert)) { return } + + var $pos = tr.doc.resolve(pos); + if (isNode && NodeSelection.isSelectable(slice.content.firstChild) && + $pos.nodeAfter && $pos.nodeAfter.sameMarkup(slice.content.firstChild)) + { tr.setSelection(new NodeSelection($pos)); } + else + { tr.setSelection(selectionBetween(view, $pos, tr.doc.resolve(tr.mapping.map(insertPos)))); } + view.focus(); + view.dispatch(tr.setMeta("uiEvent", "drop")); +}; + +handlers.focus = function (view) { + if (!view.focused) { + view.domObserver.stop(); + view.dom.classList.add("ProseMirror-focused"); + view.domObserver.start(); + view.focused = true; + } +}; + +handlers.blur = function (view) { + if (view.focused) { + view.domObserver.stop(); + view.dom.classList.remove("ProseMirror-focused"); + view.domObserver.start(); + view.domObserver.currentSelection.set({}); + view.focused = false; + } +}; + +handlers.beforeinput = function (view, event) { + // We should probably do more with beforeinput events, but support + // is so spotty that I'm still waiting to see where they are going. + + // Very specific hack to deal with backspace sometimes failing on + // Chrome Android when after an uneditable node. + if (result.chrome && result.android && event.inputType == "deleteContentBackward") { + var domChangeCount = view.domChangeCount; + setTimeout(function () { + if (view.domChangeCount != domChangeCount) { return } // Event already had some effect + // This bug tends to close the virtual keyboard, so we refocus + view.dom.blur(); + view.focus(); + if (view.someProp("handleKeyDown", function (f) { return f(view, keyEvent(8, "Backspace")); })) { return } + var ref = view.state.selection; + var $cursor = ref.$cursor; + // Crude approximation of backspace behavior when no command handled it + if ($cursor && $cursor.pos > 0) { view.dispatch(view.state.tr.delete($cursor.pos - 1, $cursor.pos).scrollIntoView()); } + }, 50); + } +}; + +// Make sure all handlers get registered +for (var prop in editHandlers) { handlers[prop] = editHandlers[prop]; } + +function compareObjs(a, b) { + if (a == b) { return true } + for (var p in a) { if (a[p] !== b[p]) { return false } } + for (var p$1 in b) { if (!(p$1 in a)) { return false } } + return true +} + +var WidgetType = function WidgetType(toDOM, spec) { + this.spec = spec || noSpec; + this.side = this.spec.side || 0; + this.toDOM = toDOM; +}; + +WidgetType.prototype.map = function map (mapping, span, offset, oldOffset) { + var ref = mapping.mapResult(span.from + oldOffset, this.side < 0 ? -1 : 1); + var pos = ref.pos; + var deleted = ref.deleted; + return deleted ? null : new Decoration(pos - offset, pos - offset, this) +}; + +WidgetType.prototype.valid = function valid () { return true }; + +WidgetType.prototype.eq = function eq (other) { + return this == other || + (other instanceof WidgetType && + (this.spec.key && this.spec.key == other.spec.key || + this.toDOM == other.toDOM && compareObjs(this.spec, other.spec))) +}; + +var InlineType = function InlineType(attrs, spec) { + this.spec = spec || noSpec; + this.attrs = attrs; +}; + +InlineType.prototype.map = function map (mapping, span, offset, oldOffset) { + var from = mapping.map(span.from + oldOffset, this.spec.inclusiveStart ? -1 : 1) - offset; + var to = mapping.map(span.to + oldOffset, this.spec.inclusiveEnd ? 1 : -1) - offset; + return from >= to ? null : new Decoration(from, to, this) +}; + +InlineType.prototype.valid = function valid (_, span) { return span.from < span.to }; + +InlineType.prototype.eq = function eq (other) { + return this == other || + (other instanceof InlineType && compareObjs(this.attrs, other.attrs) && + compareObjs(this.spec, other.spec)) +}; + +InlineType.is = function is (span) { return span.type instanceof InlineType }; + +var NodeType = function NodeType(attrs, spec) { + this.spec = spec || noSpec; + this.attrs = attrs; +}; + +NodeType.prototype.map = function map (mapping, span, offset, oldOffset) { + var from = mapping.mapResult(span.from + oldOffset, 1); + if (from.deleted) { return null } + var to = mapping.mapResult(span.to + oldOffset, -1); + if (to.deleted || to.pos <= from.pos) { return null } + return new Decoration(from.pos - offset, to.pos - offset, this) +}; + +NodeType.prototype.valid = function valid (node, span) { + var ref = node.content.findIndex(span.from); + var index = ref.index; + var offset = ref.offset; + return offset == span.from && offset + node.child(index).nodeSize == span.to +}; + +NodeType.prototype.eq = function eq (other) { + return this == other || + (other instanceof NodeType && compareObjs(this.attrs, other.attrs) && + compareObjs(this.spec, other.spec)) +}; + +// ::- Decoration objects can be provided to the view through the +// [`decorations` prop](#view.EditorProps.decorations). They come in +// several variants—see the static members of this class for details. +var Decoration = function Decoration(from, to, type) { + // :: number + // The start position of the decoration. + this.from = from; + // :: number + // The end position. Will be the same as `from` for [widget + // decorations](#view.Decoration^widget). + this.to = to; + this.type = type; +}; + +var prototypeAccessors$1 = { spec: { configurable: true } }; + +Decoration.prototype.copy = function copy (from, to) { + return new Decoration(from, to, this.type) +}; + +Decoration.prototype.eq = function eq (other) { + return this.type.eq(other.type) && this.from == other.from && this.to == other.to +}; + +Decoration.prototype.map = function map (mapping, offset, oldOffset) { + return this.type.map(mapping, this, offset, oldOffset) +}; + +// :: (number, union<(view: EditorView, getPos: () → number) → dom.Node, dom.Node>, ?Object) → Decoration +// Creates a widget decoration, which is a DOM node that's shown in +// the document at the given position. It is recommended that you +// delay rendering the widget by passing a function that will be +// called when the widget is actually drawn in a view, but you can +// also directly pass a DOM node. `getPos` can be used to find the +// widget's current document position. +// +// spec::- These options are supported: +// +// side:: ?number +// Controls which side of the document position this widget is +// associated with. When negative, it is drawn before a cursor +// at its position, and content inserted at that position ends +// up after the widget. When zero (the default) or positive, the +// widget is drawn after the cursor and content inserted there +// ends up before the widget. +// +// When there are multiple widgets at a given position, their +// `side` values determine the order in which they appear. Those +// with lower values appear first. The ordering of widgets with +// the same `side` value is unspecified. +// +// When `marks` is null, `side` also determines the marks that +// the widget is wrapped in—those of the node before when +// negative, those of the node after when positive. +// +// marks:: ?[Mark] +// The precise set of marks to draw around the widget. +// +// stopEvent:: ?(event: dom.Event) → bool +// Can be used to control which DOM events, when they bubble out +// of this widget, the editor view should ignore. +// +// key:: ?string +// When comparing decorations of this type (in order to decide +// whether it needs to be redrawn), ProseMirror will by default +// compare the widget DOM node by identity. If you pass a key, +// that key will be compared instead, which can be useful when +// you generate decorations on the fly and don't want to store +// and reuse DOM nodes. Make sure that any widgets with the same +// key are interchangeable—if widgets differ in, for example, +// the behavior of some event handler, they should get +// different keys. +Decoration.widget = function widget (pos, toDOM, spec) { + return new Decoration(pos, pos, new WidgetType(toDOM, spec)) +}; + +// :: (number, number, DecorationAttrs, ?Object) → Decoration +// Creates an inline decoration, which adds the given attributes to +// each inline node between `from` and `to`. +// +// spec::- These options are recognized: +// +// inclusiveStart:: ?bool +// Determines how the left side of the decoration is +// [mapped](#transform.Position_Mapping) when content is +// inserted directly at that position. By default, the decoration +// won't include the new content, but you can set this to `true` +// to make it inclusive. +// +// inclusiveEnd:: ?bool +// Determines how the right side of the decoration is mapped. +// See +// [`inclusiveStart`](#view.Decoration^inline^spec.inclusiveStart). +Decoration.inline = function inline (from, to, attrs, spec) { + return new Decoration(from, to, new InlineType(attrs, spec)) +}; + +// :: (number, number, DecorationAttrs, ?Object) → Decoration +// Creates a node decoration. `from` and `to` should point precisely +// before and after a node in the document. That node, and only that +// node, will receive the given attributes. +// +// spec::- +// +// Optional information to store with the decoration. It +// is also used when comparing decorators for equality. +Decoration.node = function node (from, to, attrs, spec) { + return new Decoration(from, to, new NodeType(attrs, spec)) +}; + +// :: Object +// The spec provided when creating this decoration. Can be useful +// if you've stored extra information in that object. +prototypeAccessors$1.spec.get = function () { return this.type.spec }; + +Object.defineProperties( Decoration.prototype, prototypeAccessors$1 ); + +// DecorationAttrs:: interface +// A set of attributes to add to a decorated node. Most properties +// simply directly correspond to DOM attributes of the same name, +// which will be set to the property's value. These are exceptions: +// +// class:: ?string +// A CSS class name or a space-separated set of class names to be +// _added_ to the classes that the node already had. +// +// style:: ?string +// A string of CSS to be _added_ to the node's existing `style` property. +// +// nodeName:: ?string +// When non-null, the target node is wrapped in a DOM element of +// this type (and the other attributes are applied to this element). + +var none = [], noSpec = {}; + +// ::- A collection of [decorations](#view.Decoration), organized in +// such a way that the drawing algorithm can efficiently use and +// compare them. This is a persistent data structure—it is not +// modified, updates create a new value. +var DecorationSet = function DecorationSet(local, children) { + this.local = local && local.length ? local : none; + this.children = children && children.length ? children : none; +}; + +// :: (Node, [Decoration]) → DecorationSet +// Create a set of decorations, using the structure of the given +// document. +DecorationSet.create = function create (doc, decorations) { + return decorations.length ? buildTree(decorations, doc, 0, noSpec) : empty +}; + +// :: (?number, ?number, ?(spec: Object) → bool) → [Decoration] +// Find all decorations in this set which touch the given range +// (including decorations that start or end directly at the +// boundaries) and match the given predicate on their spec. When +// `start` and `end` are omitted, all decorations in the set are +// considered. When `predicate` isn't given, all decorations are +// assumed to match. +DecorationSet.prototype.find = function find (start, end, predicate) { + var result = []; + this.findInner(start == null ? 0 : start, end == null ? 1e9 : end, result, 0, predicate); + return result +}; + +DecorationSet.prototype.findInner = function findInner (start, end, result, offset, predicate) { + for (var i = 0; i < this.local.length; i++) { + var span = this.local[i]; + if (span.from <= end && span.to >= start && (!predicate || predicate(span.spec))) + { result.push(span.copy(span.from + offset, span.to + offset)); } + } + for (var i$1 = 0; i$1 < this.children.length; i$1 += 3) { + if (this.children[i$1] < end && this.children[i$1 + 1] > start) { + var childOff = this.children[i$1] + 1; + this.children[i$1 + 2].findInner(start - childOff, end - childOff, result, offset + childOff, predicate); + } + } +}; + +// :: (Mapping, Node, ?Object) → DecorationSet +// Map the set of decorations in response to a change in the +// document. +// +// options::- An optional set of options. +// +// onRemove:: ?(decorationSpec: Object) +// When given, this function will be called for each decoration +// that gets dropped as a result of the mapping, passing the +// spec of that decoration. +DecorationSet.prototype.map = function map (mapping, doc, options) { + if (this == empty || mapping.maps.length == 0) { return this } + return this.mapInner(mapping, doc, 0, 0, options || noSpec) +}; + +DecorationSet.prototype.mapInner = function mapInner (mapping, node, offset, oldOffset, options) { + var newLocal; + for (var i = 0; i < this.local.length; i++) { + var mapped = this.local[i].map(mapping, offset, oldOffset); + if (mapped && mapped.type.valid(node, mapped)) { (newLocal || (newLocal = [])).push(mapped); } + else if (options.onRemove) { options.onRemove(this.local[i].spec); } + } + + if (this.children.length) + { return mapChildren(this.children, newLocal, mapping, node, offset, oldOffset, options) } + else + { return newLocal ? new DecorationSet(newLocal.sort(byPos)) : empty } +}; + +// :: (Node, [Decoration]) → DecorationSet +// Add the given array of decorations to the ones in the set, +// producing a new set. Needs access to the current document to +// create the appropriate tree structure. +DecorationSet.prototype.add = function add (doc, decorations) { + if (!decorations.length) { return this } + if (this == empty) { return DecorationSet.create(doc, decorations) } + return this.addInner(doc, decorations, 0) +}; + +DecorationSet.prototype.addInner = function addInner (doc, decorations, offset) { + var this$1 = this; + + var children, childIndex = 0; + doc.forEach(function (childNode, childOffset) { + var baseOffset = childOffset + offset, found; + if (!(found = takeSpansForNode(decorations, childNode, baseOffset))) { return } + + if (!children) { children = this$1.children.slice(); } + while (childIndex < children.length && children[childIndex] < childOffset) { childIndex += 3; } + if (children[childIndex] == childOffset) + { children[childIndex + 2] = children[childIndex + 2].addInner(childNode, found, baseOffset + 1); } + else + { children.splice(childIndex, 0, childOffset, childOffset + childNode.nodeSize, buildTree(found, childNode, baseOffset + 1, noSpec)); } + childIndex += 3; + }); + + var local = moveSpans(childIndex ? withoutNulls(decorations) : decorations, -offset); + return new DecorationSet(local.length ? this.local.concat(local).sort(byPos) : this.local, + children || this.children) +}; + +// :: ([Decoration]) → DecorationSet +// Create a new set that contains the decorations in this set, minus +// the ones in the given array. +DecorationSet.prototype.remove = function remove (decorations) { + if (decorations.length == 0 || this == empty) { return this } + return this.removeInner(decorations, 0) +}; + +DecorationSet.prototype.removeInner = function removeInner (decorations, offset) { + var children = this.children, local = this.local; + for (var i = 0; i < children.length; i += 3) { + var found = (void 0), from = children[i] + offset, to = children[i + 1] + offset; + for (var j = 0, span = (void 0); j < decorations.length; j++) { if (span = decorations[j]) { + if (span.from > from && span.to < to) { + decorations[j] = null + ;(found || (found = [])).push(span); + } + } } + if (!found) { continue } + if (children == this.children) { children = this.children.slice(); } + var removed = children[i + 2].removeInner(found, from + 1); + if (removed != empty) { + children[i + 2] = removed; + } else { + children.splice(i, 3); + i -= 3; + } + } + if (local.length) { for (var i$1 = 0, span$1 = (void 0); i$1 < decorations.length; i$1++) { if (span$1 = decorations[i$1]) { + for (var j$1 = 0; j$1 < local.length; j$1++) { if (local[j$1].type.eq(span$1.type)) { + if (local == this.local) { local = this.local.slice(); } + local.splice(j$1--, 1); + } } + } } } + if (children == this.children && local == this.local) { return this } + return local.length || children.length ? new DecorationSet(local, children) : empty +}; + +DecorationSet.prototype.forChild = function forChild (offset, node) { + if (this == empty) { return this } + if (node.isLeaf) { return DecorationSet.empty } + + var child, local; + for (var i = 0; i < this.children.length; i += 3) { if (this.children[i] >= offset) { + if (this.children[i] == offset) { child = this.children[i + 2]; } + break + } } + var start = offset + 1, end = start + node.content.size; + for (var i$1 = 0; i$1 < this.local.length; i$1++) { + var dec = this.local[i$1]; + if (dec.from < end && dec.to > start && (dec.type instanceof InlineType)) { + var from = Math.max(start, dec.from) - start, to = Math.min(end, dec.to) - start; + if (from < to) { (local || (local = [])).push(dec.copy(from, to)); } + } + } + if (local) { + var localSet = new DecorationSet(local.sort(byPos)); + return child ? new DecorationGroup([localSet, child]) : localSet + } + return child || empty +}; + +DecorationSet.prototype.eq = function eq (other) { + if (this == other) { return true } + if (!(other instanceof DecorationSet) || + this.local.length != other.local.length || + this.children.length != other.children.length) { return false } + for (var i = 0; i < this.local.length; i++) + { if (!this.local[i].eq(other.local[i])) { return false } } + for (var i$1 = 0; i$1 < this.children.length; i$1 += 3) + { if (this.children[i$1] != other.children[i$1] || + this.children[i$1 + 1] != other.children[i$1 + 1] || + !this.children[i$1 + 2].eq(other.children[i$1 + 2])) { return false } } + return true +}; + +DecorationSet.prototype.locals = function locals (node) { + return removeOverlap(this.localsInner(node)) +}; + +DecorationSet.prototype.localsInner = function localsInner (node) { + if (this == empty) { return none } + if (node.inlineContent || !this.local.some(InlineType.is)) { return this.local } + var result = []; + for (var i = 0; i < this.local.length; i++) { + if (!(this.local[i].type instanceof InlineType)) + { result.push(this.local[i]); } + } + return result +}; + +var empty = new DecorationSet(); + +// :: DecorationSet +// The empty set of decorations. +DecorationSet.empty = empty; + +DecorationSet.removeOverlap = removeOverlap; + +// :- An abstraction that allows the code dealing with decorations to +// treat multiple DecorationSet objects as if it were a single object +// with (a subset of) the same interface. +var DecorationGroup = function DecorationGroup(members) { + this.members = members; +}; + +DecorationGroup.prototype.forChild = function forChild (offset, child) { + if (child.isLeaf) { return DecorationSet.empty } + var found = []; + for (var i = 0; i < this.members.length; i++) { + var result = this.members[i].forChild(offset, child); + if (result == empty) { continue } + if (result instanceof DecorationGroup) { found = found.concat(result.members); } + else { found.push(result); } + } + return DecorationGroup.from(found) +}; + +DecorationGroup.prototype.eq = function eq (other) { + if (!(other instanceof DecorationGroup) || + other.members.length != this.members.length) { return false } + for (var i = 0; i < this.members.length; i++) + { if (!this.members[i].eq(other.members[i])) { return false } } + return true +}; + +DecorationGroup.prototype.locals = function locals (node) { + var result, sorted = true; + for (var i = 0; i < this.members.length; i++) { + var locals = this.members[i].localsInner(node); + if (!locals.length) { continue } + if (!result) { + result = locals; + } else { + if (sorted) { + result = result.slice(); + sorted = false; + } + for (var j = 0; j < locals.length; j++) { result.push(locals[j]); } + } + } + return result ? removeOverlap(sorted ? result : result.sort(byPos)) : none +}; + +// : ([DecorationSet]) → union +// Create a group for the given array of decoration sets, or return +// a single set when possible. +DecorationGroup.from = function from (members) { + switch (members.length) { + case 0: return empty + case 1: return members[0] + default: return new DecorationGroup(members) + } +}; + +function mapChildren(oldChildren, newLocal, mapping, node, offset, oldOffset, options) { + var children = oldChildren.slice(); + + // Mark the children that are directly touched by changes, and + // move those that are after the changes. + var shift = function (oldStart, oldEnd, newStart, newEnd) { + for (var i = 0; i < children.length; i += 3) { + var end = children[i + 1], dSize = (void 0); + if (end == -1 || oldStart > end + oldOffset) { continue } + if (oldEnd >= children[i] + oldOffset) { + children[i + 1] = -1; + } else if (dSize = (newEnd - newStart) - (oldEnd - oldStart) + (oldOffset - offset)) { + children[i] += dSize; + children[i + 1] += dSize; + } + } + }; + for (var i = 0; i < mapping.maps.length; i++) { mapping.maps[i].forEach(shift); } + + // Find the child nodes that still correspond to a single node, + // recursively call mapInner on them and update their positions. + var mustRebuild = false; + for (var i$1 = 0; i$1 < children.length; i$1 += 3) { if (children[i$1 + 1] == -1) { // Touched nodes + var from = mapping.map(children[i$1] + oldOffset), fromLocal = from - offset; + if (fromLocal < 0 || fromLocal >= node.content.size) { + mustRebuild = true; + continue + } + // Must read oldChildren because children was tagged with -1 + var to = mapping.map(oldChildren[i$1 + 1] + oldOffset, -1), toLocal = to - offset; + var ref = node.content.findIndex(fromLocal); + var index = ref.index; + var childOffset = ref.offset; + var childNode = node.maybeChild(index); + if (childNode && childOffset == fromLocal && childOffset + childNode.nodeSize == toLocal) { + var mapped = children[i$1 + 2].mapInner(mapping, childNode, from + 1, children[i$1] + oldOffset + 1, options); + if (mapped != empty) { + children[i$1] = fromLocal; + children[i$1 + 1] = toLocal; + children[i$1 + 2] = mapped; + } else { + children[i$1 + 1] = -2; + mustRebuild = true; + } + } else { + mustRebuild = true; + } + } } + + // Remaining children must be collected and rebuilt into the appropriate structure + if (mustRebuild) { + var decorations = mapAndGatherRemainingDecorations(children, oldChildren, newLocal || [], mapping, + offset, oldOffset, options); + var built = buildTree(decorations, node, 0, options); + newLocal = built.local; + for (var i$2 = 0; i$2 < children.length; i$2 += 3) { if (children[i$2 + 1] < 0) { + children.splice(i$2, 3); + i$2 -= 3; + } } + for (var i$3 = 0, j = 0; i$3 < built.children.length; i$3 += 3) { + var from$1 = built.children[i$3]; + while (j < children.length && children[j] < from$1) { j += 3; } + children.splice(j, 0, built.children[i$3], built.children[i$3 + 1], built.children[i$3 + 2]); + } + } + + return new DecorationSet(newLocal && newLocal.sort(byPos), children) +} + +function moveSpans(spans, offset) { + if (!offset || !spans.length) { return spans } + var result = []; + for (var i = 0; i < spans.length; i++) { + var span = spans[i]; + result.push(new Decoration(span.from + offset, span.to + offset, span.type)); + } + return result +} + +function mapAndGatherRemainingDecorations(children, oldChildren, decorations, mapping, offset, oldOffset, options) { + // Gather all decorations from the remaining marked children + function gather(set, oldOffset) { + for (var i = 0; i < set.local.length; i++) { + var mapped = set.local[i].map(mapping, offset, oldOffset); + if (mapped) { decorations.push(mapped); } + else if (options.onRemove) { options.onRemove(set.local[i].spec); } + } + for (var i$1 = 0; i$1 < set.children.length; i$1 += 3) + { gather(set.children[i$1 + 2], set.children[i$1] + oldOffset + 1); } + } + for (var i = 0; i < children.length; i += 3) { if (children[i + 1] == -1) + { gather(children[i + 2], oldChildren[i] + oldOffset + 1); } } + + return decorations +} + +function takeSpansForNode(spans, node, offset) { + if (node.isLeaf) { return null } + var end = offset + node.nodeSize, found = null; + for (var i = 0, span = (void 0); i < spans.length; i++) { + if ((span = spans[i]) && span.from > offset && span.to < end) { +(found || (found = [])).push(span); + spans[i] = null; + } + } + return found +} + +function withoutNulls(array) { + var result = []; + for (var i = 0; i < array.length; i++) + { if (array[i] != null) { result.push(array[i]); } } + return result +} + +// : ([Decoration], Node, number) → DecorationSet +// Build up a tree that corresponds to a set of decorations. `offset` +// is a base offset that should be subtractet from the `from` and `to` +// positions in the spans (so that we don't have to allocate new spans +// for recursive calls). +function buildTree(spans, node, offset, options) { + var children = [], hasNulls = false; + node.forEach(function (childNode, localStart) { + var found = takeSpansForNode(spans, childNode, localStart + offset); + if (found) { + hasNulls = true; + var subtree = buildTree(found, childNode, offset + localStart + 1, options); + if (subtree != empty) + { children.push(localStart, localStart + childNode.nodeSize, subtree); } + } + }); + var locals = moveSpans(hasNulls ? withoutNulls(spans) : spans, -offset).sort(byPos); + for (var i = 0; i < locals.length; i++) { if (!locals[i].type.valid(node, locals[i])) { + if (options.onRemove) { options.onRemove(locals[i].spec); } + locals.splice(i--, 1); + } } + return locals.length || children.length ? new DecorationSet(locals, children) : empty +} + +// : (Decoration, Decoration) → number +// Used to sort decorations so that ones with a low start position +// come first, and within a set with the same start position, those +// with an smaller end position come first. +function byPos(a, b) { + return a.from - b.from || a.to - b.to +} + +// : ([Decoration]) → [Decoration] +// Scan a sorted array of decorations for partially overlapping spans, +// and split those so that only fully overlapping spans are left (to +// make subsequent rendering easier). Will return the input array if +// no partially overlapping spans are found (the common case). +function removeOverlap(spans) { + var working = spans; + for (var i = 0; i < working.length - 1; i++) { + var span = working[i]; + if (span.from != span.to) { for (var j = i + 1; j < working.length; j++) { + var next = working[j]; + if (next.from == span.from) { + if (next.to != span.to) { + if (working == spans) { working = spans.slice(); } + // Followed by a partially overlapping larger span. Split that + // span. + working[j] = next.copy(next.from, span.to); + insertAhead(working, j + 1, next.copy(span.to, next.to)); + } + continue + } else { + if (next.from < span.to) { + if (working == spans) { working = spans.slice(); } + // The end of this one overlaps with a subsequent span. Split + // this one. + working[i] = span.copy(span.from, next.from); + insertAhead(working, j, span.copy(next.from, span.to)); + } + break + } + } } + } + return working +} + +function insertAhead(array, i, deco) { + while (i < array.length && byPos(deco, array[i]) > 0) { i++; } + array.splice(i, 0, deco); +} + +// : (EditorView) → union +// Get the decorations associated with the current props of a view. +function viewDecorations(view) { + var found = []; + view.someProp("decorations", function (f) { + var result = f(view.state); + if (result && result != empty) { found.push(result); } + }); + if (view.cursorWrapper) + { found.push(DecorationSet.create(view.state.doc, [view.cursorWrapper.deco])); } + return DecorationGroup.from(found) +} + +// ::- An editor view manages the DOM structure that represents an +// editable document. Its state and behavior are determined by its +// [props](#view.DirectEditorProps). +var EditorView = function EditorView(place, props) { + this._props = props; + // :: EditorState + // The view's current [state](#state.EditorState). + this.state = props.state; + + this.dispatch = this.dispatch.bind(this); + + this._root = null; + this.focused = false; + + // :: dom.Element + // An editable DOM node containing the document. (You probably + // should not directly interfere with its content.) + this.dom = (place && place.mount) || document.createElement("div"); + if (place) { + if (place.appendChild) { place.appendChild(this.dom); } + else if (place.apply) { place(this.dom); } + else if (place.mount) { this.mounted = true; } + } + + // :: bool + // Indicates whether the editor is currently [editable](#view.EditorProps.editable). + this.editable = getEditable(this); + this.markCursor = null; + this.cursorWrapper = null; + updateCursorWrapper(this); + this.nodeViews = buildNodeViews(this); + this.docView = docViewDesc(this.state.doc, computeDocDeco(this), viewDecorations(this), this.dom, this); + + this.lastSelectedViewDesc = null; + // :: ?{slice: Slice, move: bool} + // When editor content is being dragged, this object contains + // information about the dragged slice and whether it is being + // copied or moved. At any other time, it is null. + this.dragging = null; + + initInput(this); + + this.pluginViews = []; + this.updatePluginViews(); +}; + +var prototypeAccessors$2 = { props: { configurable: true },root: { configurable: true } }; + +// composing:: boolean +// Holds `true` when a +// [composition](https://developer.mozilla.org/en-US/docs/Mozilla/IME_handling_guide) +// is active. + +// :: DirectEditorProps +// The view's current [props](#view.EditorProps). +prototypeAccessors$2.props.get = function () { + if (this._props.state != this.state) { + var prev = this._props; + this._props = {}; + for (var name in prev) { this._props[name] = prev[name]; } + this._props.state = this.state; + } + return this._props +}; + +// :: (DirectEditorProps) +// Update the view's props. Will immediately cause an update to +// the DOM. +EditorView.prototype.update = function update (props) { + if (props.handleDOMEvents != this._props.handleDOMEvents) { ensureListeners(this); } + this._props = props; + this.updateStateInner(props.state, true); +}; + +// :: (DirectEditorProps) +// Update the view by updating existing props object with the object +// given as argument. Equivalent to `view.update(Object.assign({}, +// view.props, props))`. +EditorView.prototype.setProps = function setProps (props) { + var updated = {}; + for (var name in this._props) { updated[name] = this._props[name]; } + updated.state = this.state; + for (var name$1 in props) { updated[name$1] = props[name$1]; } + this.update(updated); +}; + +// :: (EditorState) +// Update the editor's `state` prop, without touching any of the +// other props. +EditorView.prototype.updateState = function updateState (state) { + this.updateStateInner(state, this.state.plugins != state.plugins); +}; + +EditorView.prototype.updateStateInner = function updateStateInner (state, reconfigured) { + var this$1 = this; + + var prev = this.state, redraw = false; + this.state = state; + if (reconfigured) { + var nodeViews = buildNodeViews(this); + if (changedNodeViews(nodeViews, this.nodeViews)) { + this.nodeViews = nodeViews; + redraw = true; + } + ensureListeners(this); + } + + this.editable = getEditable(this); + updateCursorWrapper(this); + var innerDeco = viewDecorations(this), outerDeco = computeDocDeco(this); + + var scroll = reconfigured ? "reset" + : state.scrollToSelection > prev.scrollToSelection ? "to selection" : "preserve"; + var updateDoc = redraw || !this.docView.matchesNode(state.doc, outerDeco, innerDeco); + var updateSel = updateDoc || !state.selection.eq(prev.selection); + var oldScrollPos = scroll == "preserve" && updateSel && this.dom.style.overflowAnchor == null && storeScrollPos(this); + + if (updateSel) { + this.domObserver.stop(); + // Work around an issue in Chrome, IE, and Edge where changing + // the DOM around an active selection puts it into a broken + // state where the thing the user sees differs from the + // selection reported by the Selection object (#710, #973, + // #1011, #1013). + var forceSelUpdate = updateDoc && (result.ie || result.chrome) && + !prev.selection.empty && !state.selection.empty && selectionContextChanged(prev.selection, state.selection); + if (updateDoc) { + if (redraw || !this.docView.update(state.doc, outerDeco, innerDeco, this)) { + this.docView.destroy(); + this.docView = docViewDesc(state.doc, outerDeco, innerDeco, this.dom, this); + } + } + // Work around for an issue where an update arriving right between + // a DOM selection change and the "selectionchange" event for it + // can cause a spurious DOM selection update, disrupting mouse + // drag selection. + if (forceSelUpdate || + !(this.mouseDown && this.domObserver.currentSelection.eq(this.root.getSelection()) && anchorInRightPlace(this))) { + selectionToDOM(this, forceSelUpdate); + } else { + syncNodeSelection(this, state.selection); + this.domObserver.setCurSelection(); + } + this.domObserver.start(); + } + + this.updatePluginViews(prev); + + if (scroll == "reset") { + this.dom.scrollTop = 0; + } else if (scroll == "to selection") { + var startDOM = this.root.getSelection().focusNode; + if (this.someProp("handleScrollToSelection", function (f) { return f(this$1); })) + ; // Handled + else if (state.selection instanceof NodeSelection) + { scrollRectIntoView(this, this.docView.domAfterPos(state.selection.from).getBoundingClientRect(), startDOM); } + else + { scrollRectIntoView(this, this.coordsAtPos(state.selection.head), startDOM); } + } else if (oldScrollPos) { + resetScrollPos(oldScrollPos); + } +}; + +EditorView.prototype.destroyPluginViews = function destroyPluginViews () { + var view; + while (view = this.pluginViews.pop()) { if (view.destroy) { view.destroy(); } } +}; + +EditorView.prototype.updatePluginViews = function updatePluginViews (prevState) { + if (!prevState || prevState.plugins != this.state.plugins) { + this.destroyPluginViews(); + for (var i = 0; i < this.state.plugins.length; i++) { + var plugin = this.state.plugins[i]; + if (plugin.spec.view) { this.pluginViews.push(plugin.spec.view(this)); } + } + } else { + for (var i$1 = 0; i$1 < this.pluginViews.length; i$1++) { + var pluginView = this.pluginViews[i$1]; + if (pluginView.update) { pluginView.update(this, prevState); } + } + } +}; + +// :: (string, ?(prop: *) → *) → * +// Goes over the values of a prop, first those provided directly, +// then those from plugins (in order), and calls `f` every time a +// non-undefined value is found. When `f` returns a truthy value, +// that is immediately returned. When `f` isn't provided, it is +// treated as the identity function (the prop value is returned +// directly). +EditorView.prototype.someProp = function someProp (propName, f) { + var prop = this._props && this._props[propName], value; + if (prop != null && (value = f ? f(prop) : prop)) { return value } + var plugins = this.state.plugins; + if (plugins) { for (var i = 0; i < plugins.length; i++) { + var prop$1 = plugins[i].props[propName]; + if (prop$1 != null && (value = f ? f(prop$1) : prop$1)) { return value } + } } +}; + +// :: () → bool +// Query whether the view has focus. +EditorView.prototype.hasFocus = function hasFocus () { + return this.root.activeElement == this.dom +}; + +// :: () +// Focus the editor. +EditorView.prototype.focus = function focus () { + this.domObserver.stop(); + if (this.editable) { focusPreventScroll(this.dom); } + selectionToDOM(this); + this.domObserver.start(); +}; + +// :: union +// Get the document root in which the editor exists. This will +// usually be the top-level `document`, but might be a [shadow +// DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Shadow_DOM) +// root if the editor is inside one. +prototypeAccessors$2.root.get = function () { + var cached = this._root; + if (cached == null) { for (var search = this.dom.parentNode; search; search = search.parentNode) { + if (search.nodeType == 9 || (search.nodeType == 11 && search.host)) { + if (!search.getSelection) { Object.getPrototypeOf(search).getSelection = function () { return document.getSelection(); }; } + return this._root = search + } + } } + return cached || document +}; + +// :: ({left: number, top: number}) → ?{pos: number, inside: number} +// Given a pair of viewport coordinates, return the document +// position that corresponds to them. May return null if the given +// coordinates aren't inside of the editor. When an object is +// returned, its `pos` property is the position nearest to the +// coordinates, and its `inside` property holds the position of the +// inner node that the position falls inside of, or -1 if it is at +// the top level, not in any node. +EditorView.prototype.posAtCoords = function posAtCoords$1 (coords) { + return posAtCoords(this, coords) +}; + +// :: (number) → {left: number, right: number, top: number, bottom: number} +// Returns the viewport rectangle at a given document position. `left` +// and `right` will be the same number, as this returns a flat +// cursor-ish rectangle. +EditorView.prototype.coordsAtPos = function coordsAtPos$1 (pos) { + return coordsAtPos(this, pos) +}; + +// :: (number) → {node: dom.Node, offset: number} +// Find the DOM position that corresponds to the given document +// position. Note that you should **not** mutate the editor's +// internal DOM, only inspect it (and even that is usually not +// necessary). +EditorView.prototype.domAtPos = function domAtPos (pos) { + return this.docView.domFromPos(pos) +}; + +// :: (number) → ?dom.Node +// Find the DOM node that represents the document node after the +// given position. May return `null` when the position doesn't point +// in front of a node or if the node is inside an opaque node view. +// +// This is intended to be able to call things like +// `getBoundingClientRect` on that DOM node. Do **not** mutate the +// editor DOM directly, or add styling this way, since that will be +// immediately overriden by the editor as it redraws the node. +EditorView.prototype.nodeDOM = function nodeDOM (pos) { + var desc = this.docView.descAt(pos); + return desc ? desc.nodeDOM : null +}; + +// :: (dom.Node, number, ?number) → number +// Find the document position that corresponds to a given DOM +// position. (Whenever possible, it is preferable to inspect the +// document structure directly, rather than poking around in the +// DOM, but sometimes—for example when interpreting an event +// target—you don't have a choice.) +// +// The `bias` parameter can be used to influence which side of a DOM +// node to use when the position is inside a leaf node. +EditorView.prototype.posAtDOM = function posAtDOM (node, offset, bias) { + if ( bias === void 0 ) bias = -1; + + var pos = this.docView.posFromDOM(node, offset, bias); + if (pos == null) { throw new RangeError("DOM position not inside the editor") } + return pos +}; + +// :: (union<"up", "down", "left", "right", "forward", "backward">, ?EditorState) → bool +// Find out whether the selection is at the end of a textblock when +// moving in a given direction. When, for example, given `"left"`, +// it will return true if moving left from the current cursor +// position would leave that position's parent textblock. Will apply +// to the view's current state by default, but it is possible to +// pass a different state. +EditorView.prototype.endOfTextblock = function endOfTextblock$1 (dir, state) { + return endOfTextblock(this, state || this.state, dir) +}; + +// :: () +// Removes the editor from the DOM and destroys all [node +// views](#view.NodeView). +EditorView.prototype.destroy = function destroy () { + if (!this.docView) { return } + destroyInput(this); + this.destroyPluginViews(); + if (this.mounted) { + this.docView.update(this.state.doc, [], viewDecorations(this), this); + this.dom.textContent = ""; + } else if (this.dom.parentNode) { + this.dom.parentNode.removeChild(this.dom); + } + this.docView.destroy(); + this.docView = null; +}; + +// Used for testing. +EditorView.prototype.dispatchEvent = function dispatchEvent$1 (event) { + return dispatchEvent(this, event) +}; + +// :: (Transaction) +// Dispatch a transaction. Will call +// [`dispatchTransaction`](#view.DirectEditorProps.dispatchTransaction) +// when given, and otherwise defaults to applying the transaction to +// the current state and calling +// [`updateState`](#view.EditorView.updateState) with the result. +// This method is bound to the view instance, so that it can be +// easily passed around. +EditorView.prototype.dispatch = function dispatch (tr) { + var dispatchTransaction = this._props.dispatchTransaction; + if (dispatchTransaction) { dispatchTransaction.call(this, tr); } + else { this.updateState(this.state.apply(tr)); } +}; + +Object.defineProperties( EditorView.prototype, prototypeAccessors$2 ); + +function computeDocDeco(view) { + var attrs = Object.create(null); + attrs.class = "ProseMirror"; + attrs.contenteditable = String(view.editable); + + view.someProp("attributes", function (value) { + if (typeof value == "function") { value = value(view.state); } + if (value) { for (var attr in value) { + if (attr == "class") + { attrs.class += " " + value[attr]; } + else if (!attrs[attr] && attr != "contenteditable" && attr != "nodeName") + { attrs[attr] = String(value[attr]); } + } } + }); + + return [Decoration.node(0, view.state.doc.content.size, attrs)] +} + +function updateCursorWrapper(view) { + var ref = view.state.selection; + var $head = ref.$head; + var $anchor = ref.$anchor; + var visible = ref.visible; + if (view.markCursor) { + var dom = document.createElement("img"); + dom.setAttribute("mark-placeholder", "true"); + view.cursorWrapper = {dom: dom, deco: Decoration.widget($head.pos, dom, {raw: true, marks: view.markCursor})}; + } else if (visible || $head.pos != $anchor.pos) { + view.cursorWrapper = null; + } else { + var dom$1; + if (!view.cursorWrapper || view.cursorWrapper.dom.childNodes.length) { + dom$1 = document.createElement("div"); + dom$1.style.position = "absolute"; + dom$1.style.left = "-100000px"; + } else if (view.cursorWrapper.deco.pos != $head.pos) { + dom$1 = view.cursorWrapper.dom; + } + if (dom$1) + { view.cursorWrapper = {dom: dom$1, deco: Decoration.widget($head.pos, dom$1, {raw: true})}; } + } +} + +function getEditable(view) { + return !view.someProp("editable", function (value) { return value(view.state) === false; }) +} + +function selectionContextChanged(sel1, sel2) { + var depth = Math.min(sel1.$anchor.sharedDepth(sel1.head), sel2.$anchor.sharedDepth(sel2.head)); + return sel1.$anchor.node(depth) != sel2.$anchor.node(depth) +} + +function buildNodeViews(view) { + var result = {}; + view.someProp("nodeViews", function (obj) { + for (var prop in obj) { if (!Object.prototype.hasOwnProperty.call(result, prop)) + { result[prop] = obj[prop]; } } + }); + return result +} + +function changedNodeViews(a, b) { + var nA = 0, nB = 0; + for (var prop in a) { + if (a[prop] != b[prop]) { return true } + nA++; + } + for (var _ in b) { nB++; } + return nA != nB +} + +// EditorProps:: interface +// +// Props are configuration values that can be passed to an editor view +// or included in a plugin. This interface lists the supported props. +// +// The various event-handling functions may all return `true` to +// indicate that they handled the given event. The view will then take +// care to call `preventDefault` on the event, except with +// `handleDOMEvents`, where the handler itself is responsible for that. +// +// How a prop is resolved depends on the prop. Handler functions are +// called one at a time, starting with the base props and then +// searching through the plugins (in order of appearance) until one of +// them returns true. For some props, the first plugin that yields a +// value gets precedence. +// +// handleDOMEvents:: ?Object<(view: EditorView, event: dom.Event) → bool> +// Can be an object mapping DOM event type names to functions that +// handle them. Such functions will be called before any handling +// ProseMirror does of events fired on the editable DOM element. +// Contrary to the other event handling props, when returning true +// from such a function, you are responsible for calling +// `preventDefault` yourself (or not, if you want to allow the +// default behavior). +// +// handleKeyDown:: ?(view: EditorView, event: dom.KeyboardEvent) → bool +// Called when the editor receives a `keydown` event. +// +// handleKeyPress:: ?(view: EditorView, event: dom.KeyboardEvent) → bool +// Handler for `keypress` events. +// +// handleTextInput:: ?(view: EditorView, from: number, to: number, text: string) → bool +// Whenever the user directly input text, this handler is called +// before the input is applied. If it returns `true`, the default +// behavior of actually inserting the text is suppressed. +// +// handleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool +// Called for each node around a click, from the inside out. The +// `direct` flag will be true for the inner node. +// +// handleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool +// Called when the editor is clicked, after `handleClickOn` handlers +// have been called. +// +// handleDoubleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool +// Called for each node around a double click. +// +// handleDoubleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool +// Called when the editor is double-clicked, after `handleDoubleClickOn`. +// +// handleTripleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool +// Called for each node around a triple click. +// +// handleTripleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool +// Called when the editor is triple-clicked, after `handleTripleClickOn`. +// +// handlePaste:: ?(view: EditorView, event: dom.Event, slice: Slice) → bool +// Can be used to override the behavior of pasting. `slice` is the +// pasted content parsed by the editor, but you can directly access +// the event to get at the raw content. +// +// handleDrop:: ?(view: EditorView, event: dom.Event, slice: Slice, moved: bool) → bool +// Called when something is dropped on the editor. `moved` will be +// true if this drop moves from the current selection (which should +// thus be deleted). +// +// handleScrollToSelection:: ?(view: EditorView) → bool +// Called when the view, after updating its state, tries to scroll +// the selection into view. A handler function may return false to +// indicate that it did not handle the scrolling and further +// handlers or the default behavior should be tried. +// +// createSelectionBetween:: ?(view: EditorView, anchor: ResolvedPos, head: ResolvedPos) → ?Selection +// Can be used to override the way a selection is created when +// reading a DOM selection between the given anchor and head. +// +// domParser:: ?DOMParser +// The [parser](#model.DOMParser) to use when reading editor changes +// from the DOM. Defaults to calling +// [`DOMParser.fromSchema`](#model.DOMParser^fromSchema) on the +// editor's schema. +// +// transformPastedHTML:: ?(html: string) → string +// Can be used to transform pasted HTML text, _before_ it is parsed, +// for example to clean it up. +// +// clipboardParser:: ?DOMParser +// The [parser](#model.DOMParser) to use when reading content from +// the clipboard. When not given, the value of the +// [`domParser`](#view.EditorProps.domParser) prop is used. +// +// transformPastedText:: ?(text: string) → string +// Transform pasted plain text. +// +// clipboardTextParser:: ?(text: string, $context: ResolvedPos) → Slice +// A function to parse text from the clipboard into a document +// slice. Called after +// [`transformPastedText`](#view.EditorProps.transformPastedText). +// The default behavior is to split the text into lines, wrap them +// in `

    ` tags, and call +// [`clipboardParser`](#view.EditorProps.clipboardParser) on it. +// +// transformPasted:: ?(Slice) → Slice +// Can be used to transform pasted content before it is applied to +// the document. +// +// nodeViews:: ?Object<(node: Node, view: EditorView, getPos: () → number, decorations: [Decoration]) → NodeView> +// Allows you to pass custom rendering and behavior logic for nodes +// and marks. Should map node and mark names to constructor +// functions that produce a [`NodeView`](#view.NodeView) object +// implementing the node's display behavior. For nodes, the third +// argument `getPos` is a function that can be called to get the +// node's current position, which can be useful when creating +// transactions to update it. For marks, the third argument is a +// boolean that indicates whether the mark's content is inline. +// +// `decorations` is an array of node or inline decorations that are +// active around the node. They are automatically drawn in the +// normal way, and you will usually just want to ignore this, but +// they can also be used as a way to provide context information to +// the node view without adding it to the document itself. +// +// clipboardSerializer:: ?DOMSerializer +// The DOM serializer to use when putting content onto the +// clipboard. If not given, the result of +// [`DOMSerializer.fromSchema`](#model.DOMSerializer^fromSchema) +// will be used. +// +// clipboardTextSerializer:: ?(Slice) → string +// A function that will be called to get the text for the current +// selection when copying text to the clipboard. By default, the +// editor will use [`textBetween`](#model.Node.textBetween) on the +// selected range. +// +// decorations:: ?(state: EditorState) → ?DecorationSet +// A set of [document decorations](#view.Decoration) to show in the +// view. +// +// editable:: ?(state: EditorState) → bool +// When this returns false, the content of the view is not directly +// editable. +// +// attributes:: ?union, (EditorState) → ?Object> +// Control the DOM attributes of the editable element. May be either +// an object or a function going from an editor state to an object. +// By default, the element will get a class `"ProseMirror"`, and +// will have its `contentEditable` attribute determined by the +// [`editable` prop](#view.EditorProps.editable). Additional classes +// provided here will be added to the class. For other attributes, +// the value provided first (as in +// [`someProp`](#view.EditorView.someProp)) will be used. +// +// scrollThreshold:: ?union +// Determines the distance (in pixels) between the cursor and the +// end of the visible viewport at which point, when scrolling the +// cursor into view, scrolling takes place. Defaults to 0. +// +// scrollMargin:: ?union +// Determines the extra space (in pixels) that is left above or +// below the cursor when it is scrolled into view. Defaults to 5. + +// DirectEditorProps:: interface extends EditorProps +// +// The props object given directly to the editor view supports two +// fields that can't be used in plugins: +// +// state:: EditorState +// The current state of the editor. +// +// dispatchTransaction:: ?(tr: Transaction) +// The callback over which to send transactions (state updates) +// produced by the view. If you specify this, you probably want to +// make sure this ends up calling the view's +// [`updateState`](#view.EditorView.updateState) method with a new +// state that has the transaction +// [applied](#state.EditorState.apply). The callback will be bound to have +// the view instance as its `this` binding. + +export { Decoration, DecorationSet, EditorView, endComposition as __endComposition, parseFromClipboard as __parseFromClipboard, serializeForClipboard as __serializeForClipboard }; +//# sourceMappingURL=index.es.js.map diff --git a/packages/tiptap/node_modules/prosemirror-view/dist/index.es.js.map b/packages/tiptap/node_modules/prosemirror-view/dist/index.es.js.map new file mode 100644 index 0000000000..1d34e1aed9 --- /dev/null +++ b/packages/tiptap/node_modules/prosemirror-view/dist/index.es.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.es.js","sources":["../src/browser.js","../src/dom.js","../src/domcoords.js","../src/viewdesc.js","../src/capturekeys.js","../src/selection.js","../src/domchange.js","../src/clipboard.js","../src/domobserver.js","../src/input.js","../src/decoration.js","../src/index.js"],"sourcesContent":["const result = {}\nexport default result\n\nif (typeof navigator != \"undefined\" && typeof document != \"undefined\") {\n const ie_edge = /Edge\\/(\\d+)/.exec(navigator.userAgent)\n const ie_upto10 = /MSIE \\d/.test(navigator.userAgent)\n const ie_11up = /Trident\\/(?:[7-9]|\\d{2,})\\..*rv:(\\d+)/.exec(navigator.userAgent)\n\n result.mac = /Mac/.test(navigator.platform)\n let ie = result.ie = !!(ie_upto10 || ie_11up || ie_edge)\n result.ie_version = ie_upto10 ? document.documentMode || 6 : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : null\n result.gecko = !ie && /gecko\\/(\\d+)/i.test(navigator.userAgent)\n result.gecko_version = result.gecko && +(/Firefox\\/(\\d+)/.exec(navigator.userAgent) || [0, 0])[1]\n let chrome = !ie && /Chrome\\/(\\d+)/.exec(navigator.userAgent)\n result.chrome = !!chrome\n result.chrome_version = chrome && +chrome[1]\n result.ios = !ie && /AppleWebKit/.test(navigator.userAgent) && /Mobile\\/\\w+/.test(navigator.userAgent)\n result.android = /Android \\d/.test(navigator.userAgent)\n result.webkit = !ie && 'WebkitAppearance' in document.documentElement.style\n result.safari = /Apple Computer/.test(navigator.vendor)\n result.webkit_version = result.webkit && +(/\\bAppleWebKit\\/(\\d+)/.exec(navigator.userAgent) || [0, 0])[1]\n}\n","import browser from \"./browser\"\n\nexport const domIndex = function(node) {\n for (var index = 0;; index++) {\n node = node.previousSibling\n if (!node) return index\n }\n}\n\nexport const parentNode = function(node) {\n let parent = node.parentNode\n return parent && parent.nodeType == 11 ? parent.host : parent\n}\n\nexport const textRange = function(node, from, to) {\n let range = document.createRange()\n range.setEnd(node, to == null ? node.nodeValue.length : to)\n range.setStart(node, from || 0)\n return range\n}\n\n// Scans forward and backward through DOM positions equivalent to the\n// given one to see if the two are in the same place (i.e. after a\n// text node vs at the end of that text node)\nexport const isEquivalentPosition = function(node, off, targetNode, targetOff) {\n return targetNode && (scanFor(node, off, targetNode, targetOff, -1) ||\n scanFor(node, off, targetNode, targetOff, 1))\n}\n\nconst atomElements = /^(img|br|input|textarea|hr)$/i\n\nfunction scanFor(node, off, targetNode, targetOff, dir) {\n for (;;) {\n if (node == targetNode && off == targetOff) return true\n if (off == (dir < 0 ? 0 : nodeSize(node))) {\n let parent = node.parentNode\n if (parent.nodeType != 1 || hasBlockDesc(node) || atomElements.test(node.nodeName) || node.contentEditable == \"false\")\n return false\n off = domIndex(node) + (dir < 0 ? 0 : 1)\n node = parent\n } else if (node.nodeType == 1) {\n node = node.childNodes[off + (dir < 0 ? -1 : 0)]\n off = dir < 0 ? nodeSize(node) : 0\n } else {\n return false\n }\n }\n}\n\nexport function nodeSize(node) {\n return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length\n}\n\nfunction hasBlockDesc(dom) {\n let desc\n for (let cur = dom; cur; cur = cur.parentNode) if (desc = cur.pmViewDesc) break\n return desc && desc.node && desc.node.isBlock && (desc.dom == dom || desc.contentDOM == dom)\n}\n\n// Work around Chrome issue https://bugs.chromium.org/p/chromium/issues/detail?id=447523\n// (isCollapsed inappropriately returns true in shadow dom)\nexport const selectionCollapsed = function(domSel) {\n let collapsed = domSel.isCollapsed\n if (collapsed && browser.chrome && domSel.rangeCount && !domSel.getRangeAt(0).collapsed)\n collapsed = false\n return collapsed\n}\n\nexport function keyEvent(keyCode, key) {\n let event = document.createEvent(\"Event\")\n event.initEvent(\"keydown\", true, true)\n event.keyCode = keyCode\n event.key = event.code = key\n return event\n}\n","import {nodeSize, textRange, parentNode} from \"./dom\"\nimport browser from \"./browser\"\n\nfunction windowRect(win) {\n return {left: 0, right: win.innerWidth,\n top: 0, bottom: win.innerHeight}\n}\n\nfunction getSide(value, side) {\n return typeof value == \"number\" ? value : value[side]\n}\n\nexport function scrollRectIntoView(view, rect, startDOM) {\n let scrollThreshold = view.someProp(\"scrollThreshold\") || 0, scrollMargin = view.someProp(\"scrollMargin\") || 5\n let doc = view.dom.ownerDocument, win = doc.defaultView\n for (let parent = startDOM || view.dom;; parent = parentNode(parent)) {\n if (!parent) break\n if (parent.nodeType != 1) continue\n let atTop = parent == doc.body || parent.nodeType != 1\n let bounding = atTop ? windowRect(win) : parent.getBoundingClientRect()\n let moveX = 0, moveY = 0\n if (rect.top < bounding.top + getSide(scrollThreshold, \"top\"))\n moveY = -(bounding.top - rect.top + getSide(scrollMargin, \"top\"))\n else if (rect.bottom > bounding.bottom - getSide(scrollThreshold, \"bottom\"))\n moveY = rect.bottom - bounding.bottom + getSide(scrollMargin, \"bottom\")\n if (rect.left < bounding.left + getSide(scrollThreshold, \"left\"))\n moveX = -(bounding.left - rect.left + getSide(scrollMargin, \"left\"))\n else if (rect.right > bounding.right - getSide(scrollThreshold, \"right\"))\n moveX = rect.right - bounding.right + getSide(scrollMargin, \"right\")\n if (moveX || moveY) {\n if (atTop) {\n win.scrollBy(moveX, moveY)\n } else {\n if (moveY) parent.scrollTop += moveY\n if (moveX) parent.scrollLeft += moveX\n }\n }\n if (atTop) break\n }\n}\n\n// Store the scroll position of the editor's parent nodes, along with\n// the top position of an element near the top of the editor, which\n// will be used to make sure the visible viewport remains stable even\n// when the size of the content above changes.\nexport function storeScrollPos(view) {\n let rect = view.dom.getBoundingClientRect(), startY = Math.max(0, rect.top)\n let refDOM, refTop\n for (let x = (rect.left + rect.right) / 2, y = startY + 1;\n y < Math.min(innerHeight, rect.bottom); y += 5) {\n let dom = view.root.elementFromPoint(x, y)\n if (dom == view.dom || !view.dom.contains(dom)) continue\n let localRect = dom.getBoundingClientRect()\n if (localRect.top >= startY - 20) {\n refDOM = dom\n refTop = localRect.top\n break\n }\n }\n return {refDOM, refTop, stack: scrollStack(view.dom)}\n}\n\nfunction scrollStack(dom) {\n let stack = [], doc = dom.ownerDocument\n for (; dom; dom = parentNode(dom)) {\n stack.push({dom, top: dom.scrollTop, left: dom.scrollLeft})\n if (dom == doc) break\n }\n return stack\n}\n\n// Reset the scroll position of the editor's parent nodes to that what\n// it was before, when storeScrollPos was called.\nexport function resetScrollPos({refDOM, refTop, stack}) {\n let newRefTop = refDOM ? refDOM.getBoundingClientRect().top : 0\n restoreScrollStack(stack, newRefTop == 0 ? 0 : newRefTop - refTop)\n}\n\nfunction restoreScrollStack(stack, dTop) {\n for (let i = 0; i < stack.length; i++) {\n let {dom, top, left} = stack[i]\n if (dom.scrollTop != top + dTop) dom.scrollTop = top + dTop\n if (dom.scrollLeft != left) dom.scrollLeft = left\n }\n}\n\nlet preventScrollSupported = null\n// Feature-detects support for .focus({preventScroll: true}), and uses\n// a fallback kludge when not supported.\nexport function focusPreventScroll(dom) {\n if (dom.setActive) return dom.setActive() // in IE\n if (preventScrollSupported) return dom.focus(preventScrollSupported)\n\n let stored = scrollStack(dom)\n dom.focus(preventScrollSupported == null ? {\n get preventScroll() {\n preventScrollSupported = {preventScroll: true}\n return true\n }\n } : undefined)\n if (!preventScrollSupported) {\n preventScrollSupported = false\n restoreScrollStack(stored, 0)\n }\n}\n\nfunction findOffsetInNode(node, coords) {\n let closest, dxClosest = 2e8, coordsClosest, offset = 0\n let rowBot = coords.top, rowTop = coords.top\n for (let child = node.firstChild, childIndex = 0; child; child = child.nextSibling, childIndex++) {\n let rects\n if (child.nodeType == 1) rects = child.getClientRects()\n else if (child.nodeType == 3) rects = textRange(child).getClientRects()\n else continue\n\n for (let i = 0; i < rects.length; i++) {\n let rect = rects[i]\n if (rect.top <= rowBot && rect.bottom >= rowTop) {\n rowBot = Math.max(rect.bottom, rowBot)\n rowTop = Math.min(rect.top, rowTop)\n let dx = rect.left > coords.left ? rect.left - coords.left\n : rect.right < coords.left ? coords.left - rect.right : 0\n if (dx < dxClosest) {\n closest = child\n dxClosest = dx\n coordsClosest = dx && closest.nodeType == 3 ? {left: rect.right < coords.left ? rect.right : rect.left, top: coords.top} : coords\n if (child.nodeType == 1 && dx)\n offset = childIndex + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0)\n continue\n }\n }\n if (!closest && (coords.left >= rect.right && coords.top >= rect.top ||\n coords.left >= rect.left && coords.top >= rect.bottom))\n offset = childIndex + 1\n }\n }\n if (closest && closest.nodeType == 3) return findOffsetInText(closest, coordsClosest)\n if (!closest || (dxClosest && closest.nodeType == 1)) return {node, offset}\n return findOffsetInNode(closest, coordsClosest)\n}\n\nfunction findOffsetInText(node, coords) {\n let len = node.nodeValue.length\n let range = document.createRange()\n for (let i = 0; i < len; i++) {\n range.setEnd(node, i + 1)\n range.setStart(node, i)\n let rect = singleRect(range, 1)\n if (rect.top == rect.bottom) continue\n if (inRect(coords, rect))\n return {node, offset: i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0)}\n }\n return {node, offset: 0}\n}\n\nfunction inRect(coords, rect) {\n return coords.left >= rect.left - 1 && coords.left <= rect.right + 1&&\n coords.top >= rect.top - 1 && coords.top <= rect.bottom + 1\n}\n\nfunction targetKludge(dom, coords) {\n let parent = dom.parentNode\n if (parent && /^li$/i.test(parent.nodeName) && coords.left < dom.getBoundingClientRect().left)\n return parent\n return dom\n}\n\nfunction posFromElement(view, elt, coords) {\n let {node, offset} = findOffsetInNode(elt, coords), bias = -1\n if (node.nodeType == 1 && !node.firstChild) {\n let rect = node.getBoundingClientRect()\n bias = rect.left != rect.right && coords.left > (rect.left + rect.right) / 2 ? 1 : -1\n }\n return view.docView.posFromDOM(node, offset, bias)\n}\n\nfunction posFromCaret(view, node, offset, coords) {\n // Browser (in caretPosition/RangeFromPoint) will agressively\n // normalize towards nearby inline nodes. Since we are interested in\n // positions between block nodes too, we first walk up the hierarchy\n // of nodes to see if there are block nodes that the coordinates\n // fall outside of. If so, we take the position before/after that\n // block. If not, we call `posFromDOM` on the raw node/offset.\n let outside = -1\n for (let cur = node;;) {\n if (cur == view.dom) break\n let desc = view.docView.nearestDesc(cur, true)\n if (!desc) return null\n if (desc.node.isBlock && desc.parent) {\n let rect = desc.dom.getBoundingClientRect()\n if (rect.left > coords.left || rect.top > coords.top) outside = desc.posBefore\n else if (rect.right < coords.left || rect.bottom < coords.top) outside = desc.posAfter\n else break\n }\n cur = desc.dom.parentNode\n }\n return outside > -1 ? outside : view.docView.posFromDOM(node, offset)\n}\n\nfunction elementFromPoint(element, coords, box) {\n let len = element.childNodes.length\n if (len && box.top < box.bottom) {\n for (let startI = Math.max(0, Math.min(len - 1, Math.floor(len * (coords.top - box.top) / (box.bottom - box.top)) - 2)), i = startI;;) {\n let child = element.childNodes[i]\n if (child.nodeType == 1) {\n let rects = child.getClientRects()\n for (let j = 0; j < rects.length; j++) {\n let rect = rects[j]\n if (inRect(coords, rect)) return elementFromPoint(child, coords, rect)\n }\n }\n if ((i = (i + 1) % len) == startI) break\n }\n }\n return element\n}\n\n// Given an x,y position on the editor, get the position in the document.\nexport function posAtCoords(view, coords) {\n let root = view.root, node, offset\n if (root.caretPositionFromPoint) {\n try { // Firefox throws for this call in hard-to-predict circumstances (#994)\n let pos = root.caretPositionFromPoint(coords.left, coords.top)\n if (pos) ({offsetNode: node, offset} = pos)\n } catch (_) {}\n }\n if (!node && root.caretRangeFromPoint) {\n let range = root.caretRangeFromPoint(coords.left, coords.top)\n if (range) ({startContainer: node, startOffset: offset} = range)\n }\n\n let elt = root.elementFromPoint(coords.left, coords.top + 1), pos\n if (!elt || !view.dom.contains(elt.nodeType != 1 ? elt.parentNode : elt)) {\n let box = view.dom.getBoundingClientRect()\n if (!inRect(coords, box)) return null\n elt = elementFromPoint(view.dom, coords, box)\n if (!elt) return null\n }\n elt = targetKludge(elt, coords)\n if (node) {\n if (browser.gecko && node.nodeType == 1) {\n // Firefox will sometimes return offsets into nodes, which\n // have no actual children, from caretPositionFromPoint (#953)\n offset = Math.min(offset, node.childNodes.length)\n // It'll also move the returned position before image nodes,\n // even if those are behind it.\n if (offset < node.childNodes.length) {\n let next = node.childNodes[offset], box\n if (next.nodeName == \"IMG\" && (box = next.getBoundingClientRect()).right <= coords.left &&\n box.bottom > coords.top)\n offset++\n }\n }\n // Suspiciously specific kludge to work around caret*FromPoint\n // never returning a position at the end of the document\n if (node == view.dom && offset == node.childNodes.length - 1 && node.lastChild.nodeType == 1 &&\n coords.top > node.lastChild.getBoundingClientRect().bottom)\n pos = view.state.doc.content.size\n // Ignore positions directly after a BR, since caret*FromPoint\n // 'round up' positions that would be more accurately placed\n // before the BR node.\n else if (offset == 0 || node.nodeType != 1 || node.childNodes[offset - 1].nodeName != \"BR\")\n pos = posFromCaret(view, node, offset, coords)\n }\n if (pos == null) pos = posFromElement(view, elt, coords)\n\n let desc = view.docView.nearestDesc(elt, true)\n return {pos, inside: desc ? desc.posAtStart - desc.border : -1}\n}\n\nfunction singleRect(object, bias) {\n let rects = object.getClientRects()\n return !rects.length ? object.getBoundingClientRect() : rects[bias < 0 ? 0 : rects.length - 1]\n}\n\n// : (EditorView, number) → {left: number, top: number, right: number, bottom: number}\n// Given a position in the document model, get a bounding box of the\n// character at that position, relative to the window.\nexport function coordsAtPos(view, pos) {\n let {node, offset} = view.docView.domFromPos(pos)\n\n // These browsers support querying empty text ranges\n if (node.nodeType == 3 && (browser.chrome || browser.gecko)) {\n let rect = singleRect(textRange(node, offset, offset), 0)\n // Firefox returns bad results (the position before the space)\n // when querying a position directly after line-broken\n // whitespace. Detect this situation and and kludge around it\n if (browser.gecko && offset && /\\s/.test(node.nodeValue[offset - 1]) && offset < node.nodeValue.length) {\n let rectBefore = singleRect(textRange(node, offset - 1, offset - 1), -1)\n if (Math.abs(rectBefore.left - rect.left) < 1 && rectBefore.top == rect.top) {\n let rectAfter = singleRect(textRange(node, offset, offset + 1), -1)\n return flattenV(rectAfter, rectAfter.left < rectBefore.left)\n }\n }\n return rect\n }\n\n if (node.nodeType == 1 && !view.state.doc.resolve(pos).parent.inlineContent) {\n // Return a horizontal line in block context\n let top = true, rect\n if (offset < node.childNodes.length) {\n let after = node.childNodes[offset]\n if (after.nodeType == 1) rect = after.getBoundingClientRect()\n }\n if (!rect && offset) {\n let before = node.childNodes[offset - 1]\n if (before.nodeType == 1) { rect = before.getBoundingClientRect(); top = false }\n }\n return flattenH(rect || node.getBoundingClientRect(), top)\n }\n\n // Not Firefox/Chrome, or not in a text node, so we have to use\n // actual element/character rectangles to get a solution (this part\n // is not very bidi-safe)\n //\n // Try the left side first, fall back to the right one if that\n // doesn't work.\n for (let dir = -1; dir < 2; dir += 2) {\n if (dir < 0 && offset) {\n let prev, target = node.nodeType == 3 ? textRange(node, offset - 1, offset)\n : (prev = node.childNodes[offset - 1]).nodeType == 3 ? textRange(prev)\n : prev.nodeType == 1 && prev.nodeName != \"BR\" ? prev : null // BR nodes tend to only return the rectangle before them\n if (target) {\n let rect = singleRect(target, 1)\n if (rect.top < rect.bottom) return flattenV(rect, false)\n }\n } else if (dir > 0 && offset < nodeSize(node)) {\n let next, target = node.nodeType == 3 ? textRange(node, offset, offset + 1)\n : (next = node.childNodes[offset]).nodeType == 3 ? textRange(next)\n : next.nodeType == 1 ? next : null\n if (target) {\n let rect = singleRect(target, -1)\n if (rect.top < rect.bottom) return flattenV(rect, true)\n }\n }\n }\n // All else failed, just try to get a rectangle for the target node\n return flattenV(singleRect(node.nodeType == 3 ? textRange(node) : node, 0), false)\n}\n\nfunction flattenV(rect, left) {\n if (rect.width == 0) return rect\n let x = left ? rect.left : rect.right\n return {top: rect.top, bottom: rect.bottom, left: x, right: x}\n}\n\nfunction flattenH(rect, top) {\n if (rect.height == 0) return rect\n let y = top ? rect.top : rect.bottom\n return {top: y, bottom: y, left: rect.left, right: rect.right}\n}\n\nfunction withFlushedState(view, state, f) {\n let viewState = view.state, active = view.root.activeElement\n if (viewState != state) view.updateState(state)\n if (active != view.dom) view.focus()\n try {\n return f()\n } finally {\n if (viewState != state) view.updateState(viewState)\n if (active != view.dom) active.focus()\n }\n}\n\n// : (EditorView, number, number)\n// Whether vertical position motion in a given direction\n// from a position would leave a text block.\nfunction endOfTextblockVertical(view, state, dir) {\n let sel = state.selection\n let $pos = dir == \"up\" ? sel.$anchor.min(sel.$head) : sel.$anchor.max(sel.$head)\n return withFlushedState(view, state, () => {\n let {node: dom} = view.docView.domFromPos($pos.pos)\n for (;;) {\n let nearest = view.docView.nearestDesc(dom, true)\n if (!nearest) break\n if (nearest.node.isBlock) { dom = nearest.dom; break }\n dom = nearest.dom.parentNode\n }\n let coords = coordsAtPos(view, $pos.pos)\n for (let child = dom.firstChild; child; child = child.nextSibling) {\n let boxes\n if (child.nodeType == 1) boxes = child.getClientRects()\n else if (child.nodeType == 3) boxes = textRange(child, 0, child.nodeValue.length).getClientRects()\n else continue\n for (let i = 0; i < boxes.length; i++) {\n let box = boxes[i]\n if (box.bottom > box.top && (dir == \"up\" ? box.bottom < coords.top + 1 : box.top > coords.bottom - 1))\n return false\n }\n }\n return true\n })\n}\n\nconst maybeRTL = /[\\u0590-\\u08ac]/\n\nfunction endOfTextblockHorizontal(view, state, dir) {\n let {$head} = state.selection\n if (!$head.parent.isTextblock) return false\n let offset = $head.parentOffset, atStart = !offset, atEnd = offset == $head.parent.content.size\n let sel = getSelection()\n // If the textblock is all LTR, or the browser doesn't support\n // Selection.modify (Edge), fall back to a primitive approach\n if (!maybeRTL.test($head.parent.textContent) || !sel.modify)\n return dir == \"left\" || dir == \"backward\" ? atStart : atEnd\n\n return withFlushedState(view, state, () => {\n // This is a huge hack, but appears to be the best we can\n // currently do: use `Selection.modify` to move the selection by\n // one character, and see if that moves the cursor out of the\n // textblock (or doesn't move it at all, when at the start/end of\n // the document).\n let oldRange = sel.getRangeAt(0), oldNode = sel.focusNode, oldOff = sel.focusOffset\n let oldBidiLevel = sel.caretBidiLevel // Only for Firefox\n sel.modify(\"move\", dir, \"character\")\n let parentDOM = $head.depth ? view.docView.domAfterPos($head.before()) : view.dom\n let result = !parentDOM.contains(sel.focusNode.nodeType == 1 ? sel.focusNode : sel.focusNode.parentNode) ||\n (oldNode == sel.focusNode && oldOff == sel.focusOffset)\n // Restore the previous selection\n sel.removeAllRanges()\n sel.addRange(oldRange)\n if (oldBidiLevel != null) sel.caretBidiLevel = oldBidiLevel\n return result\n })\n}\n\nlet cachedState = null, cachedDir = null, cachedResult = false\nexport function endOfTextblock(view, state, dir) {\n if (cachedState == state && cachedDir == dir) return cachedResult\n cachedState = state; cachedDir = dir\n return cachedResult = dir == \"up\" || dir == \"down\"\n ? endOfTextblockVertical(view, state, dir)\n : endOfTextblockHorizontal(view, state, dir)\n}\n","import {DOMSerializer, Fragment, Mark} from \"prosemirror-model\"\nimport {TextSelection} from \"prosemirror-state\"\n\nimport {domIndex, isEquivalentPosition, nodeSize} from \"./dom\"\nimport browser from \"./browser\"\n\n// NodeView:: interface\n//\n// By default, document nodes are rendered using the result of the\n// [`toDOM`](#model.NodeSpec.toDOM) method of their spec, and managed\n// entirely by the editor. For some use cases, such as embedded\n// node-specific editing interfaces, you want more control over\n// the behavior of a node's in-editor representation, and need to\n// [define](#view.EditorProps.nodeViews) a custom node view.\n//\n// Objects returned as node views must conform to this interface.\n//\n// dom:: ?dom.Node\n// The outer DOM node that represents the document node. When not\n// given, the default strategy is used to create a DOM node.\n//\n// contentDOM:: ?dom.Node\n// The DOM node that should hold the node's content. Only meaningful\n// if the node view also defines a `dom` property and if its node\n// type is not a leaf node type. When this is present, ProseMirror\n// will take care of rendering the node's children into it. When it\n// is not present, the node view itself is responsible for rendering\n// (or deciding not to render) its child nodes.\n//\n// update:: ?(node: Node, decorations: [Decoration]) → bool\n// When given, this will be called when the view is updating itself.\n// It will be given a node (possibly of a different type), and an\n// array of active decorations (which are automatically drawn, and\n// the node view may ignore if it isn't interested in them), and\n// should return true if it was able to update to that node, and\n// false otherwise. If the node view has a `contentDOM` property (or\n// no `dom` property), updating its child nodes will be handled by\n// ProseMirror.\n//\n// selectNode:: ?()\n// Can be used to override the way the node's selected status (as a\n// node selection) is displayed.\n//\n// deselectNode:: ?()\n// When defining a `selectNode` method, you should also provide a\n// `deselectNode` method to remove the effect again.\n//\n// setSelection:: ?(anchor: number, head: number, root: dom.Document)\n// This will be called to handle setting the selection inside the\n// node. The `anchor` and `head` positions are relative to the start\n// of the node. By default, a DOM selection will be created between\n// the DOM positions corresponding to those positions, but if you\n// override it you can do something else.\n//\n// stopEvent:: ?(event: dom.Event) → bool\n// Can be used to prevent the editor view from trying to handle some\n// or all DOM events that bubble up from the node view. Events for\n// which this returns true are not handled by the editor.\n//\n// ignoreMutation:: ?(dom.MutationRecord) → bool\n// Called when a DOM\n// [mutation](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver)\n// or a selection change happens within the view. When the change is\n// a selection change, the record will have a `type` property of\n// `\"selection\"` (which doesn't occur for native mutation records).\n// Return false if the editor should re-read the selection or\n// re-parse the range around the mutation, true if it can safely be\n// ignored.\n//\n// destroy:: ?()\n// Called when the node view is removed from the editor or the whole\n// editor is destroyed.\n\n// View descriptions are data structures that describe the DOM that is\n// used to represent the editor's content. They are used for:\n//\n// - Incremental redrawing when the document changes\n//\n// - Figuring out what part of the document a given DOM position\n// corresponds to\n//\n// - Wiring in custom implementations of the editing interface for a\n// given node\n//\n// They form a doubly-linked mutable tree, starting at `view.docView`.\n\nconst NOT_DIRTY = 0, CHILD_DIRTY = 1, CONTENT_DIRTY = 2, NODE_DIRTY = 3\n\n// Superclass for the various kinds of descriptions. Defines their\n// basic structure and shared methods.\nclass ViewDesc {\n // : (?ViewDesc, [ViewDesc], dom.Node, ?dom.Node)\n constructor(parent, children, dom, contentDOM) {\n this.parent = parent\n this.children = children\n this.dom = dom\n // An expando property on the DOM node provides a link back to its\n // description.\n dom.pmViewDesc = this\n // This is the node that holds the child views. It may be null for\n // descs that don't have children.\n this.contentDOM = contentDOM\n this.dirty = NOT_DIRTY\n }\n\n // Used to check whether a given description corresponds to a\n // widget/mark/node.\n matchesWidget() { return false }\n matchesMark() { return false }\n matchesNode() { return false }\n matchesHack() { return false }\n\n get beforePosition() { return false }\n\n // : () → ?ParseRule\n // When parsing in-editor content (in domchange.js), we allow\n // descriptions to determine the parse rules that should be used to\n // parse them.\n parseRule() { return null }\n\n // : (dom.Event) → bool\n // Used by the editor's event handler to ignore events that come\n // from certain descs.\n stopEvent() { return false }\n\n // The size of the content represented by this desc.\n get size() {\n let size = 0\n for (let i = 0; i < this.children.length; i++) size += this.children[i].size\n return size\n }\n\n // For block nodes, this represents the space taken up by their\n // start/end tokens.\n get border() { return 0 }\n\n destroy() {\n this.parent = null\n if (this.dom.pmViewDesc == this) this.dom.pmViewDesc = null\n for (let i = 0; i < this.children.length; i++)\n this.children[i].destroy()\n }\n\n posBeforeChild(child) {\n for (let i = 0, pos = this.posAtStart; i < this.children.length; i++) {\n let cur = this.children[i]\n if (cur == child) return pos\n pos += cur.size\n }\n }\n\n get posBefore() {\n return this.parent.posBeforeChild(this)\n }\n\n get posAtStart() {\n return this.parent ? this.parent.posBeforeChild(this) + this.border : 0\n }\n\n get posAfter() {\n return this.posBefore + this.size\n }\n\n get posAtEnd() {\n return this.posAtStart + this.size - 2 * this.border\n }\n\n // : (dom.Node, number, ?number) → number\n localPosFromDOM(dom, offset, bias) {\n // If the DOM position is in the content, use the child desc after\n // it to figure out a position.\n if (this.contentDOM && this.contentDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode)) {\n if (bias < 0) {\n let domBefore, desc\n if (dom == this.contentDOM) {\n domBefore = dom.childNodes[offset - 1]\n } else {\n while (dom.parentNode != this.contentDOM) dom = dom.parentNode\n domBefore = dom.previousSibling\n }\n while (domBefore && !((desc = domBefore.pmViewDesc) && desc.parent == this)) domBefore = domBefore.previousSibling\n return domBefore ? this.posBeforeChild(desc) + desc.size : this.posAtStart\n } else {\n let domAfter, desc\n if (dom == this.contentDOM) {\n domAfter = dom.childNodes[offset]\n } else {\n while (dom.parentNode != this.contentDOM) dom = dom.parentNode\n domAfter = dom.nextSibling\n }\n while (domAfter && !((desc = domAfter.pmViewDesc) && desc.parent == this)) domAfter = domAfter.nextSibling\n return domAfter ? this.posBeforeChild(desc) : this.posAtEnd\n }\n }\n // Otherwise, use various heuristics, falling back on the bias\n // parameter, to determine whether to return the position at the\n // start or at the end of this view desc.\n let atEnd\n if (this.contentDOM && this.contentDOM != this.dom && this.dom.contains(this.contentDOM)) {\n atEnd = dom.compareDocumentPosition(this.contentDOM) & 2\n } else if (this.dom.firstChild) {\n if (offset == 0) for (let search = dom;; search = search.parentNode) {\n if (search == this.dom) { atEnd = false; break }\n if (search.parentNode.firstChild != search) break\n }\n if (atEnd == null && offset == dom.childNodes.length) for (let search = dom;; search = search.parentNode) {\n if (search == this.dom) { atEnd = true; break }\n if (search.parentNode.lastChild != search) break\n }\n }\n return (atEnd == null ? bias > 0 : atEnd) ? this.posAtEnd : this.posAtStart\n }\n\n // Scan up the dom finding the first desc that is a descendant of\n // this one.\n nearestDesc(dom, onlyNodes) {\n for (let first = true, cur = dom; cur; cur = cur.parentNode) {\n let desc = this.getDesc(cur)\n if (desc && (!onlyNodes || desc.node)) {\n // If dom is outside of this desc's nodeDOM, don't count it.\n if (first && desc.nodeDOM && !(desc.nodeDOM.nodeType == 1 ? desc.nodeDOM.contains(dom) : desc.nodeDOM == dom)) first = false\n else return desc\n }\n }\n }\n\n getDesc(dom) {\n let desc = dom.pmViewDesc\n for (let cur = desc; cur; cur = cur.parent) if (cur == this) return desc\n }\n\n posFromDOM(dom, offset, bias) {\n for (let scan = dom;; scan = scan.parentNode) {\n let desc = this.getDesc(scan)\n if (desc) return desc.localPosFromDOM(dom, offset, bias)\n }\n }\n\n // : (number) → ?NodeViewDesc\n // Find the desc for the node after the given pos, if any. (When a\n // parent node overrode rendering, there might not be one.)\n descAt(pos) {\n for (let i = 0, offset = 0; i < this.children.length; i++) {\n let child = this.children[i], end = offset + child.size\n if (offset == pos && end != offset) {\n while (!child.border && child.children.length) child = child.children[0]\n return child\n }\n if (pos < end) return child.descAt(pos - offset - child.border)\n offset = end\n }\n }\n\n // : (number) → {node: dom.Node, offset: number}\n domFromPos(pos) {\n if (!this.contentDOM) return {node: this.dom, offset: 0}\n for (let offset = 0, i = 0;; i++) {\n if (offset == pos) {\n while (i < this.children.length && (this.children[i].beforePosition || this.children[i].dom.parentNode != this.contentDOM)) i++\n return {node: this.contentDOM,\n offset: i == this.children.length ? this.contentDOM.childNodes.length : domIndex(this.children[i].dom)}\n }\n if (i == this.children.length) throw new Error(\"Invalid position \" + pos)\n let child = this.children[i], end = offset + child.size\n if (pos < end) return child.domFromPos(pos - offset - child.border)\n offset = end\n }\n }\n\n // Used to find a DOM range in a single parent for a given changed\n // range.\n parseRange(from, to, base = 0) {\n if (this.children.length == 0)\n return {node: this.contentDOM, from, to, fromOffset: 0, toOffset: this.contentDOM.childNodes.length}\n\n let fromOffset = -1, toOffset = -1\n for (let offset = base, i = 0;; i++) {\n let child = this.children[i], end = offset + child.size\n if (fromOffset == -1 && from <= end) {\n let childBase = offset + child.border\n // FIXME maybe descend mark views to parse a narrower range?\n if (from >= childBase && to <= end - child.border && child.node &&\n child.contentDOM && this.contentDOM.contains(child.contentDOM))\n return child.parseRange(from, to, childBase)\n\n from = offset\n for (let j = i; j > 0; j--) {\n let prev = this.children[j - 1]\n if (prev.size && prev.dom.parentNode == this.contentDOM && !prev.emptyChildAt(1)) {\n fromOffset = domIndex(prev.dom) + 1\n break\n }\n from -= prev.size\n }\n if (fromOffset == -1) fromOffset = 0\n }\n if (fromOffset > -1 && to <= end) {\n to = end\n for (let j = i + 1; j < this.children.length; j++) {\n let next = this.children[j]\n if (next.size && next.dom.parentNode == this.contentDOM && !next.emptyChildAt(-1)) {\n toOffset = domIndex(next.dom)\n break\n }\n to += next.size\n }\n if (toOffset == -1) toOffset = this.contentDOM.childNodes.length\n break\n }\n offset = end\n }\n return {node: this.contentDOM, from, to, fromOffset, toOffset}\n }\n\n emptyChildAt(side) {\n if (this.border || !this.contentDOM || !this.children.length) return false\n let child = this.children[side < 0 ? 0 : this.children.length - 1]\n return child.size == 0 || child.emptyChildAt(side)\n }\n\n // : (number) → dom.Node\n domAfterPos(pos) {\n let {node, offset} = this.domFromPos(pos)\n if (node.nodeType != 1 || offset == node.childNodes.length)\n throw new RangeError(\"No node after pos \" + pos)\n return node.childNodes[offset]\n }\n\n // : (number, number, dom.Document)\n // View descs are responsible for setting any selection that falls\n // entirely inside of them, so that custom implementations can do\n // custom things with the selection. Note that this falls apart when\n // a selection starts in such a node and ends in another, in which\n // case we just use whatever domFromPos produces as a best effort.\n setSelection(anchor, head, root, force) {\n // If the selection falls entirely in a child, give it to that child\n let from = Math.min(anchor, head), to = Math.max(anchor, head)\n for (let i = 0, offset = 0; i < this.children.length; i++) {\n let child = this.children[i], end = offset + child.size\n if (from > offset && to < end)\n return child.setSelection(anchor - offset - child.border, head - offset - child.border, root, force)\n offset = end\n }\n\n let anchorDOM = this.domFromPos(anchor), headDOM = this.domFromPos(head)\n let domSel = root.getSelection(), range = document.createRange()\n if (!force &&\n isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset) &&\n isEquivalentPosition(headDOM.node, headDOM.offset, domSel.focusNode, domSel.focusOffset))\n return\n\n // Selection.extend can be used to create an 'inverted' selection\n // (one where the focus is before the anchor), but not all\n // browsers support it yet.\n if (domSel.extend) {\n range.setEnd(anchorDOM.node, anchorDOM.offset)\n range.collapse(false)\n } else {\n if (anchor > head) { let tmp = anchorDOM; anchorDOM = headDOM; headDOM = tmp }\n range.setEnd(headDOM.node, headDOM.offset)\n range.setStart(anchorDOM.node, anchorDOM.offset)\n }\n domSel.removeAllRanges()\n domSel.addRange(range)\n if (domSel.extend)\n domSel.extend(headDOM.node, headDOM.offset)\n }\n\n // : (dom.MutationRecord) → bool\n ignoreMutation(_mutation) {\n return !this.contentDOM\n }\n\n get contentLost() {\n return this.contentDOM && this.contentDOM != this.dom && !this.dom.contains(this.contentDOM)\n }\n\n // Remove a subtree of the element tree that has been touched\n // by a DOM change, so that the next update will redraw it.\n markDirty(from, to) {\n for (let offset = 0, i = 0; i < this.children.length; i++) {\n let child = this.children[i], end = offset + child.size\n if (offset == end ? from <= end && to >= offset : from < end && to > offset) {\n let startInside = offset + child.border, endInside = end - child.border\n if (from >= startInside && to <= endInside) {\n this.dirty = from == offset || to == end ? CONTENT_DIRTY : CHILD_DIRTY\n if (from == startInside && to == endInside &&\n (child.contentLost || child.dom.parentNode != this.contentDOM)) child.dirty = NODE_DIRTY\n else child.markDirty(from - startInside, to - startInside)\n return\n } else {\n child.dirty = NODE_DIRTY\n }\n }\n offset = end\n }\n this.dirty = CONTENT_DIRTY\n }\n\n markParentsDirty() {\n let level = 1\n for (let node = this.parent; node; node = node.parent) {\n let dirty = level == 1 ? CONTENT_DIRTY : CHILD_DIRTY\n if (node.dirty < dirty) node.dirty = dirty\n }\n }\n}\n\n// Reused array to avoid allocating fresh arrays for things that will\n// stay empty anyway.\nconst nothing = []\n\n// A widget desc represents a widget decoration, which is a DOM node\n// drawn between the document nodes.\nclass WidgetViewDesc extends ViewDesc {\n // : (ViewDesc, Decoration)\n constructor(parent, widget, view, pos) {\n let self, dom = widget.type.toDOM\n if (typeof dom == \"function\") dom = dom(view, () => {\n if (!self) return pos\n if (self.parent) return self.parent.posBeforeChild(self)\n })\n if (!widget.type.spec.raw) {\n if (dom.nodeType != 1) {\n let wrap = document.createElement(\"span\")\n wrap.appendChild(dom)\n dom = wrap\n }\n dom.contentEditable = false\n dom.classList.add(\"ProseMirror-widget\")\n }\n super(parent, nothing, dom, null)\n this.widget = widget\n self = this\n }\n\n get beforePosition() {\n return this.widget.type.side < 0\n }\n\n matchesWidget(widget) {\n return this.dirty == NOT_DIRTY && widget.type.eq(this.widget.type)\n }\n\n parseRule() { return {ignore: true} }\n\n stopEvent(event) {\n let stop = this.widget.spec.stopEvent\n return stop ? stop(event) : false\n }\n}\n\nclass CompositionViewDesc extends ViewDesc {\n constructor(parent, dom, textDOM, text) {\n super(parent, nothing, dom, null)\n this.textDOM = textDOM\n this.text = text\n }\n\n get size() { return this.text.length }\n\n localPosFromDOM(dom, offset) {\n if (dom != this.textDOM) return this.posAtStart + (offset ? this.size : 0)\n return this.posAtStart + offset\n }\n\n domFromPos(pos) {\n return {node: this.textDOM, offset: pos}\n }\n\n ignoreMutation(mut) {\n return mut.type === 'characterData' && mut.target.nodeValue == mut.oldValue\n }\n}\n\n// A mark desc represents a mark. May have multiple children,\n// depending on how the mark is split. Note that marks are drawn using\n// a fixed nesting order, for simplicity and predictability, so in\n// some cases they will be split more often than would appear\n// necessary.\nclass MarkViewDesc extends ViewDesc {\n // : (ViewDesc, Mark, dom.Node)\n constructor(parent, mark, dom, contentDOM) {\n super(parent, [], dom, contentDOM)\n this.mark = mark\n }\n\n static create(parent, mark, inline, view) {\n let custom = view.nodeViews[mark.type.name]\n let spec = custom && custom(mark, view, inline)\n if (!spec || !spec.dom)\n spec = DOMSerializer.renderSpec(document, mark.type.spec.toDOM(mark, inline))\n return new MarkViewDesc(parent, mark, spec.dom, spec.contentDOM || spec.dom)\n }\n\n parseRule() { return {mark: this.mark.type.name, attrs: this.mark.attrs, contentElement: this.contentDOM} }\n\n matchesMark(mark) { return this.dirty != NODE_DIRTY && this.mark.eq(mark) }\n\n markDirty(from, to) {\n super.markDirty(from, to)\n // Move dirty info to nearest node view\n if (this.dirty != NOT_DIRTY) {\n let parent = this.parent\n while (!parent.node) parent = parent.parent\n if (parent.dirty < this.dirty) parent.dirty = this.dirty\n this.dirty = NOT_DIRTY\n }\n }\n\n slice(from, to, view) {\n let copy = MarkViewDesc.create(this.parent, this.mark, true, view)\n let nodes = this.children, size = this.size\n if (to < size) nodes = replaceNodes(nodes, to, size, view)\n if (from > 0) nodes = replaceNodes(nodes, 0, from, view)\n for (let i = 0; i < nodes.length; i++) nodes[i].parent = copy\n copy.children = nodes\n return copy\n }\n}\n\n// Node view descs are the main, most common type of view desc, and\n// correspond to an actual node in the document. Unlike mark descs,\n// they populate their child array themselves.\nclass NodeViewDesc extends ViewDesc {\n // : (?ViewDesc, Node, [Decoration], DecorationSet, dom.Node, ?dom.Node, EditorView)\n constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos) {\n super(parent, node.isLeaf ? nothing : [], dom, contentDOM)\n this.nodeDOM = nodeDOM\n this.node = node\n this.outerDeco = outerDeco\n this.innerDeco = innerDeco\n if (contentDOM) this.updateChildren(view, pos)\n }\n\n // By default, a node is rendered using the `toDOM` method from the\n // node type spec. But client code can use the `nodeViews` spec to\n // supply a custom node view, which can influence various aspects of\n // the way the node works.\n //\n // (Using subclassing for this was intentionally decided against,\n // since it'd require exposing a whole slew of finnicky\n // implementation details to the user code that they probably will\n // never need.)\n static create(parent, node, outerDeco, innerDeco, view, pos) {\n let custom = view.nodeViews[node.type.name], descObj\n let spec = custom && custom(node, view, () => {\n // (This is a function that allows the custom view to find its\n // own position)\n if (!descObj) return pos\n if (descObj.parent) return descObj.parent.posBeforeChild(descObj)\n }, outerDeco)\n\n let dom = spec && spec.dom, contentDOM = spec && spec.contentDOM\n if (node.isText) {\n if (!dom) dom = document.createTextNode(node.text)\n else if (dom.nodeType != 3) throw new RangeError(\"Text must be rendered as a DOM text node\")\n } else if (!dom) {\n ;({dom, contentDOM} = DOMSerializer.renderSpec(document, node.type.spec.toDOM(node)))\n }\n if (!contentDOM && !node.isText && dom.nodeName != \"BR\") { // Chrome gets confused by
    \n if (!dom.hasAttribute(\"contenteditable\")) dom.contentEditable = false\n if (node.type.spec.draggable) dom.draggable = true\n }\n\n let nodeDOM = dom\n dom = applyOuterDeco(dom, outerDeco, node)\n\n if (spec)\n return descObj = new CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM,\n spec, view, pos + 1)\n else if (node.isText)\n return new TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM, view)\n else\n return new NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos + 1)\n }\n\n parseRule() {\n // Experimental kludge to allow opt-in re-parsing of nodes\n if (this.node.type.spec.reparseInView) return null\n // FIXME the assumption that this can always return the current\n // attrs means that if the user somehow manages to change the\n // attrs in the dom, that won't be picked up. Not entirely sure\n // whether this is a problem\n let rule = {node: this.node.type.name, attrs: this.node.attrs}\n if (this.node.type.spec.code) rule.preserveWhitespace = \"full\"\n if (this.contentDOM && !this.contentLost) rule.contentElement = this.contentDOM\n else rule.getContent = () => this.contentDOM ? Fragment.empty : this.node.content\n return rule\n }\n\n matchesNode(node, outerDeco, innerDeco) {\n return this.dirty == NOT_DIRTY && node.eq(this.node) &&\n sameOuterDeco(outerDeco, this.outerDeco) && innerDeco.eq(this.innerDeco)\n }\n\n get size() { return this.node.nodeSize }\n\n get border() { return this.node.isLeaf ? 0 : 1 }\n\n // Syncs `this.children` to match `this.node.content` and the local\n // decorations, possibly introducing nesting for marks. Then, in a\n // separate step, syncs the DOM inside `this.contentDOM` to\n // `this.children`.\n updateChildren(view, pos) {\n let inline = this.node.inlineContent, off = pos\n let composition = inline && view.composing && this.localCompositionNode(view, pos)\n let updater = new ViewTreeUpdater(this, composition && composition.node)\n iterDeco(this.node, this.innerDeco, (widget, i) => {\n if (widget.spec.marks)\n updater.syncToMarks(widget.spec.marks, inline, view)\n else if (widget.type.side >= 0)\n updater.syncToMarks(i == this.node.childCount ? Mark.none : this.node.child(i).marks, inline, view)\n // If the next node is a desc matching this widget, reuse it,\n // otherwise insert the widget as a new view desc.\n updater.placeWidget(widget, view, off)\n }, (child, outerDeco, innerDeco, i) => {\n // Make sure the wrapping mark descs match the node's marks.\n updater.syncToMarks(child.marks, inline, view)\n // Either find an existing desc that exactly matches this node,\n // and drop the descs before it.\n updater.findNodeMatch(child, outerDeco, innerDeco, i) ||\n // Or try updating the next desc to reflect this node.\n updater.updateNextNode(child, outerDeco, innerDeco, view, i) ||\n // Or just add it as a new desc.\n updater.addNode(child, outerDeco, innerDeco, view, off)\n off += child.nodeSize\n })\n // Drop all remaining descs after the current position.\n updater.syncToMarks(nothing, inline, view)\n if (this.node.isTextblock) updater.addTextblockHacks()\n updater.destroyRest()\n\n // Sync the DOM if anything changed\n if (updater.changed || this.dirty == CONTENT_DIRTY) {\n // May have to protect focused DOM from being changed if a composition is active\n if (composition) this.protectLocalComposition(view, composition)\n this.renderChildren()\n }\n }\n\n renderChildren() {\n renderDescs(this.contentDOM, this.children, NodeViewDesc.is)\n if (browser.ios) iosHacks(this.dom)\n }\n\n localCompositionNode(view, pos) {\n // Only do something if both the selection and a focused text node\n // are inside of this node, and the node isn't already part of a\n // view that's a child of this view\n let {from, to} = view.state.selection\n if (!(view.state.selection instanceof TextSelection) || from < pos || to > pos + this.node.content.size) return\n let sel = view.root.getSelection()\n let textNode = nearbyTextNode(sel.focusNode, sel.focusOffset)\n if (!textNode || !this.dom.contains(textNode.parentNode)) return\n\n // Find the text in the focused node in the node, stop if it's not\n // there (may have been modified through other means, in which\n // case it should overwritten)\n let text = textNode.nodeValue\n let textPos = findTextInFragment(this.node.content, text, from - pos, to - pos)\n\n return textPos < 0 ? null : {node: textNode, pos: textPos, text}\n }\n\n protectLocalComposition(view, {node, pos, text}) {\n // The node is already part of a local view desc, leave it there\n if (this.getDesc(node)) return\n\n // Create a composition view for the orphaned nodes\n let topNode = node\n for (;; topNode = topNode.parentNode) {\n if (topNode.parentNode == this.contentDOM) break\n while (topNode.previousSibling) topNode.parentNode.removeChild(topNode.previousSibling)\n while (topNode.nextSibling) topNode.parentNode.removeChild(topNode.nextSibling)\n if (topNode.pmViewDesc) topNode.pmViewDesc = null\n }\n let desc = new CompositionViewDesc(this, topNode, node, text)\n view.compositionNodes.push(desc)\n\n // Patch up this.children to contain the composition view\n this.children = replaceNodes(this.children, pos, pos + text.length, view, desc)\n }\n\n // : (Node, [Decoration], DecorationSet, EditorView) → bool\n // If this desc be updated to match the given node decoration,\n // do so and return true.\n update(node, outerDeco, innerDeco, view) {\n if (this.dirty == NODE_DIRTY ||\n !node.sameMarkup(this.node)) return false\n this.updateInner(node, outerDeco, innerDeco, view)\n return true\n }\n\n updateInner(node, outerDeco, innerDeco, view) {\n this.updateOuterDeco(outerDeco)\n this.node = node\n this.innerDeco = innerDeco\n if (this.contentDOM) this.updateChildren(view, this.posAtStart)\n this.dirty = NOT_DIRTY\n }\n\n updateOuterDeco(outerDeco) {\n if (sameOuterDeco(outerDeco, this.outerDeco)) return\n let needsWrap = this.nodeDOM.nodeType != 1\n let oldDOM = this.dom\n this.dom = patchOuterDeco(this.dom, this.nodeDOM,\n computeOuterDeco(this.outerDeco, this.node, needsWrap),\n computeOuterDeco(outerDeco, this.node, needsWrap))\n if (this.dom != oldDOM) {\n oldDOM.pmViewDesc = null\n this.dom.pmViewDesc = this\n }\n this.outerDeco = outerDeco\n }\n\n // Mark this node as being the selected node.\n selectNode() {\n this.nodeDOM.classList.add(\"ProseMirror-selectednode\")\n if (this.contentDOM || !this.node.type.spec.draggable) this.dom.draggable = true\n }\n\n // Remove selected node marking from this node.\n deselectNode() {\n this.nodeDOM.classList.remove(\"ProseMirror-selectednode\")\n if (this.contentDOM || !this.node.type.spec.draggable) this.dom.draggable = false\n }\n}\n\n// Create a view desc for the top-level document node, to be exported\n// and used by the view class.\nexport function docViewDesc(doc, outerDeco, innerDeco, dom, view) {\n applyOuterDeco(dom, outerDeco, doc)\n return new NodeViewDesc(null, doc, outerDeco, innerDeco, dom, dom, dom, view, 0)\n}\n\nclass TextViewDesc extends NodeViewDesc {\n constructor(parent, node, outerDeco, innerDeco, dom, nodeDOM, view) {\n super(parent, node, outerDeco, innerDeco, dom, null, nodeDOM, view)\n }\n\n parseRule() {\n return {skip: this.nodeDOM.parentNode || true}\n }\n\n update(node, outerDeco) {\n if (this.dirty == NODE_DIRTY || (this.dirty != NOT_DIRTY && !this.inParent()) ||\n !node.sameMarkup(this.node)) return false\n this.updateOuterDeco(outerDeco)\n if ((this.dirty != NOT_DIRTY || node.text != this.node.text) && node.text != this.nodeDOM.nodeValue)\n this.nodeDOM.nodeValue = node.text\n this.node = node\n this.dirty = NOT_DIRTY\n return true\n }\n\n inParent() {\n let parentDOM = this.parent.contentDOM\n for (let n = this.nodeDOM; n; n = n.parentNode) if (n == parentDOM) return true\n return false\n }\n\n domFromPos(pos) {\n return {node: this.nodeDOM, offset: pos}\n }\n\n localPosFromDOM(dom, offset, bias) {\n if (dom == this.nodeDOM) return this.posAtStart + Math.min(offset, this.node.text.length)\n return super.localPosFromDOM(dom, offset, bias)\n }\n\n ignoreMutation(mutation) {\n return mutation.type != \"characterData\" && mutation.type != \"selection\"\n }\n\n slice(from, to, view) {\n let node = this.node.cut(from, to), dom = document.createTextNode(node.text)\n return new TextViewDesc(this.parent, node, this.outerDeco, this.innerDeco, dom, dom, view)\n }\n}\n\n// A dummy desc used to tag trailing BR or span nodes created to work\n// around contentEditable terribleness.\nclass BRHackViewDesc extends ViewDesc {\n parseRule() { return {ignore: true} }\n matchesHack() { return this.dirty == NOT_DIRTY }\n}\n\n// A separate subclass is used for customized node views, so that the\n// extra checks only have to be made for nodes that are actually\n// customized.\nclass CustomNodeViewDesc extends NodeViewDesc {\n // : (?ViewDesc, Node, [Decoration], DecorationSet, dom.Node, ?dom.Node, NodeView, EditorView)\n constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, spec, view, pos) {\n super(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos)\n this.spec = spec\n }\n\n // A custom `update` method gets to decide whether the update goes\n // through. If it does, and there's a `contentDOM` node, our logic\n // updates the children.\n update(node, outerDeco, innerDeco, view) {\n if (this.dirty == NODE_DIRTY) return false\n if (this.spec.update) {\n let result = this.spec.update(node, outerDeco)\n if (result) this.updateInner(node, outerDeco, innerDeco, view)\n return result\n } else if (!this.contentDOM && !node.isLeaf) {\n return false\n } else {\n return super.update(node, outerDeco, innerDeco, view)\n }\n }\n\n selectNode() {\n this.spec.selectNode ? this.spec.selectNode() : super.selectNode()\n }\n\n deselectNode() {\n this.spec.deselectNode ? this.spec.deselectNode() : super.deselectNode()\n }\n\n setSelection(anchor, head, root, force) {\n this.spec.setSelection ? this.spec.setSelection(anchor, head, root)\n : super.setSelection(anchor, head, root, force)\n }\n\n destroy() {\n if (this.spec.destroy) this.spec.destroy()\n super.destroy()\n }\n\n stopEvent(event) {\n return this.spec.stopEvent ? this.spec.stopEvent(event) : false\n }\n\n ignoreMutation(mutation) {\n return this.spec.ignoreMutation ? this.spec.ignoreMutation(mutation) : super.ignoreMutation(mutation)\n }\n}\n\n// : (dom.Node, [ViewDesc])\n// Sync the content of the given DOM node with the nodes associated\n// with the given array of view descs, recursing into mark descs\n// because this should sync the subtree for a whole node at a time.\nfunction renderDescs(parentDOM, descs) {\n let dom = parentDOM.firstChild\n for (let i = 0; i < descs.length; i++) {\n let desc = descs[i], childDOM = desc.dom\n if (childDOM.parentNode == parentDOM) {\n while (childDOM != dom) dom = rm(dom)\n dom = dom.nextSibling\n } else {\n parentDOM.insertBefore(childDOM, dom)\n }\n if (desc instanceof MarkViewDesc) {\n let pos = dom ? dom.previousSibling : parentDOM.lastChild\n renderDescs(desc.contentDOM, desc.children)\n dom = pos ? pos.nextSibling : parentDOM.firstChild\n }\n }\n while (dom) dom = rm(dom)\n}\n\nfunction OuterDecoLevel(nodeName) {\n if (nodeName) this.nodeName = nodeName\n}\nOuterDecoLevel.prototype = Object.create(null)\n\nconst noDeco = [new OuterDecoLevel]\n\nfunction computeOuterDeco(outerDeco, node, needsWrap) {\n if (outerDeco.length == 0) return noDeco\n\n let top = needsWrap ? noDeco[0] : new OuterDecoLevel, result = [top]\n\n for (let i = 0; i < outerDeco.length; i++) {\n let attrs = outerDeco[i].type.attrs, cur = top\n if (!attrs) continue\n if (attrs.nodeName)\n result.push(cur = new OuterDecoLevel(attrs.nodeName))\n\n for (let name in attrs) {\n let val = attrs[name]\n if (val == null) continue\n if (needsWrap && result.length == 1)\n result.push(cur = top = new OuterDecoLevel(node.isInline ? \"span\" : \"div\"))\n if (name == \"class\") cur.class = (cur.class ? cur.class + \" \" : \"\") + val\n else if (name == \"style\") cur.style = (cur.style ? cur.style + \";\" : \"\") + val\n else if (name != \"nodeName\") cur[name] = val\n }\n }\n\n return result\n}\n\nfunction patchOuterDeco(outerDOM, nodeDOM, prevComputed, curComputed) {\n // Shortcut for trivial case\n if (prevComputed == noDeco && curComputed == noDeco) return nodeDOM\n\n let curDOM = nodeDOM\n for (let i = 0; i < curComputed.length; i++) {\n let deco = curComputed[i], prev = prevComputed[i]\n if (i) {\n let parent\n if (prev && prev.nodeName == deco.nodeName && curDOM != outerDOM &&\n (parent = curDOM.parentNode) && parent.tagName.toLowerCase() == deco.nodeName) {\n curDOM = parent\n } else {\n parent = document.createElement(deco.nodeName)\n parent.appendChild(curDOM)\n prev = noDeco[0]\n curDOM = parent\n }\n }\n patchAttributes(curDOM, prev || noDeco[0], deco)\n }\n return curDOM\n}\n\nfunction patchAttributes(dom, prev, cur) {\n for (let name in prev)\n if (name != \"class\" && name != \"style\" && name != \"nodeName\" && !(name in cur))\n dom.removeAttribute(name)\n for (let name in cur)\n if (name != \"class\" && name != \"style\" && name != \"nodeName\" && cur[name] != prev[name])\n dom.setAttribute(name, cur[name])\n if (prev.class != cur.class) {\n let prevList = prev.class ? prev.class.split(\" \") : nothing\n let curList = cur.class ? cur.class.split(\" \") : nothing\n for (let i = 0; i < prevList.length; i++) if (curList.indexOf(prevList[i]) == -1)\n dom.classList.remove(prevList[i])\n for (let i = 0; i < curList.length; i++) if (prevList.indexOf(curList[i]) == -1)\n dom.classList.add(curList[i])\n }\n if (prev.style != cur.style) {\n if (prev.style) {\n let prop = /\\s*([\\w\\-\\xa1-\\uffff]+)\\s*:(?:\"(?:\\\\.|[^\"])*\"|'(?:\\\\.|[^'])*'|\\(.*?\\)|[^;])*/g, m\n while (m = prop.exec(prev.style))\n dom.style.removeProperty(m[1])\n }\n if (cur.style)\n dom.style.cssText += cur.style\n }\n}\n\nfunction applyOuterDeco(dom, deco, node) {\n return patchOuterDeco(dom, dom, noDeco, computeOuterDeco(deco, node, dom.nodeType != 1))\n}\n\n// : ([Decoration], [Decoration]) → bool\nfunction sameOuterDeco(a, b) {\n if (a.length != b.length) return false\n for (let i = 0; i < a.length; i++) if (!a[i].type.eq(b[i].type)) return false\n return true\n}\n\n// Remove a DOM node and return its next sibling.\nfunction rm(dom) {\n let next = dom.nextSibling\n dom.parentNode.removeChild(dom)\n return next\n}\n\n// Helper class for incrementally updating a tree of mark descs and\n// the widget and node descs inside of them.\nclass ViewTreeUpdater {\n // : (NodeViewDesc)\n constructor(top, lockedNode) {\n this.top = top\n this.lock = lockedNode\n // Index into `this.top`'s child array, represents the current\n // update position.\n this.index = 0\n // When entering a mark, the current top and index are pushed\n // onto this.\n this.stack = []\n // Tracks whether anything was changed\n this.changed = false\n\n let pre = preMatch(top.node.content, top.children)\n this.preMatched = pre.nodes\n this.preMatchOffset = pre.offset\n }\n\n getPreMatch(index) {\n return index >= this.preMatchOffset ? this.preMatched[index - this.preMatchOffset] : null\n }\n\n // Destroy and remove the children between the given indices in\n // `this.top`.\n destroyBetween(start, end) {\n if (start == end) return\n for (let i = start; i < end; i++) this.top.children[i].destroy()\n this.top.children.splice(start, end - start)\n this.changed = true\n }\n\n // Destroy all remaining children in `this.top`.\n destroyRest() {\n this.destroyBetween(this.index, this.top.children.length)\n }\n\n // : ([Mark], EditorView)\n // Sync the current stack of mark descs with the given array of\n // marks, reusing existing mark descs when possible.\n syncToMarks(marks, inline, view) {\n let keep = 0, depth = this.stack.length >> 1\n let maxKeep = Math.min(depth, marks.length)\n while (keep < maxKeep &&\n (keep == depth - 1 ? this.top : this.stack[(keep + 1) << 1]).matchesMark(marks[keep]) && marks[keep].type.spec.spanning !== false)\n keep++\n\n while (keep < depth) {\n this.destroyRest()\n this.top.dirty = NOT_DIRTY\n this.index = this.stack.pop()\n this.top = this.stack.pop()\n depth--\n }\n while (depth < marks.length) {\n this.stack.push(this.top, this.index + 1)\n let found = -1\n for (let i = this.index; i < Math.min(this.index + 3, this.top.children.length); i++) {\n if (this.top.children[i].matchesMark(marks[depth])) { found = i; break }\n }\n if (found > -1) {\n if (found > this.index) {\n this.changed = true\n this.destroyBetween(this.index, found)\n }\n this.top = this.top.children[this.index]\n } else {\n let markDesc = MarkViewDesc.create(this.top, marks[depth], inline, view)\n this.top.children.splice(this.index, 0, markDesc)\n this.top = markDesc\n this.changed = true\n }\n this.index = 0\n depth++\n }\n }\n\n // : (Node, [Decoration], DecorationSet) → bool\n // Try to find a node desc matching the given data. Skip over it and\n // return true when successful.\n findNodeMatch(node, outerDeco, innerDeco, index) {\n let found = -1, preMatch = index < 0 ? undefined : this.getPreMatch(index), children = this.top.children\n if (preMatch && preMatch.matchesNode(node, outerDeco, innerDeco)) {\n found = children.indexOf(preMatch)\n } else {\n for (let i = this.index, e = Math.min(children.length, i + 5); i < e; i++) {\n let child = children[i]\n if (child.matchesNode(node, outerDeco, innerDeco) && this.preMatched.indexOf(child) < 0) {\n found = i\n break\n }\n }\n }\n if (found < 0) return false\n this.destroyBetween(this.index, found)\n this.index++\n return true\n }\n\n // : (Node, [Decoration], DecorationSet, EditorView, Fragment, number) → bool\n // Try to update the next node, if any, to the given data. Checks\n // pre-matches to avoid overwriting nodes that could still be used.\n updateNextNode(node, outerDeco, innerDeco, view, index) {\n if (this.index == this.top.children.length) return false\n let next = this.top.children[this.index]\n if (next instanceof NodeViewDesc) {\n let preMatch = this.preMatched.indexOf(next)\n if (preMatch > -1 && preMatch + this.preMatchOffset != index) return false\n let nextDOM = next.dom\n\n // Can't update if nextDOM is or contains this.lock, except if\n // it's a text node whose content already matches the new text\n // and whose decorations match the new ones.\n let locked = this.lock && (nextDOM == this.lock || nextDOM.nodeType == 1 && nextDOM.contains(this.lock.parentNode)) &&\n !(node.isText && next.node && next.node.isText && next.nodeDOM.nodeValue == node.text &&\n next.dirty != NODE_DIRTY && sameOuterDeco(outerDeco, next.outerDeco))\n if (!locked && next.update(node, outerDeco, innerDeco, view)) {\n if (next.dom != nextDOM) this.changed = true\n this.index++\n return true\n }\n }\n return false\n }\n\n // : (Node, [Decoration], DecorationSet, EditorView)\n // Insert the node as a newly created node desc.\n addNode(node, outerDeco, innerDeco, view, pos) {\n this.top.children.splice(this.index++, 0, NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos))\n this.changed = true\n }\n\n placeWidget(widget, view, pos) {\n if (this.index < this.top.children.length && this.top.children[this.index].matchesWidget(widget)) {\n this.index++\n } else {\n let desc = new WidgetViewDesc(this.top, widget, view, pos)\n this.top.children.splice(this.index++, 0, desc)\n this.changed = true\n }\n }\n\n // Make sure a textblock looks and behaves correctly in\n // contentEditable.\n addTextblockHacks() {\n let lastChild = this.top.children[this.index - 1]\n while (lastChild instanceof MarkViewDesc) lastChild = lastChild.children[lastChild.children.length - 1]\n\n if (!lastChild || // Empty textblock\n !(lastChild instanceof TextViewDesc) ||\n /\\n$/.test(lastChild.node.text)) {\n if (this.index < this.top.children.length && this.top.children[this.index].matchesHack()) {\n this.index++\n } else {\n let dom = document.createElement(\"br\")\n this.top.children.splice(this.index++, 0, new BRHackViewDesc(this.top, nothing, dom, null))\n this.changed = true\n }\n }\n }\n}\n\n// : (Fragment, [ViewDesc]) → [ViewDesc]\n// Iterate from the end of the fragment and array of descs to find\n// directly matching ones, in order to avoid overeagerly reusing\n// those for other nodes. Returns an array whose positions correspond\n// to node positions in the fragment, and whose elements are either\n// descs matched to the child at that index, or empty.\nfunction preMatch(frag, descs) {\n let result = [], end = frag.childCount\n for (let i = descs.length - 1; end > 0 && i >= 0; i--) {\n let desc = descs[i], node = desc.node\n if (!node) continue\n if (node != frag.child(end - 1)) break\n result.push(desc)\n --end\n }\n return {nodes: result.reverse(), offset: end}\n}\n\nfunction compareSide(a, b) { return a.type.side - b.type.side }\n\n// : (ViewDesc, DecorationSet, (Decoration, number), (Node, [Decoration], DecorationSet, number))\n// This function abstracts iterating over the nodes and decorations in\n// a fragment. Calls `onNode` for each node, with its local and child\n// decorations. Splits text nodes when there is a decoration starting\n// or ending inside of them. Calls `onWidget` for each widget.\nfunction iterDeco(parent, deco, onWidget, onNode) {\n let locals = deco.locals(parent), offset = 0\n // Simple, cheap variant for when there are no local decorations\n if (locals.length == 0) {\n for (let i = 0; i < parent.childCount; i++) {\n let child = parent.child(i)\n onNode(child, locals, deco.forChild(offset, child), i)\n offset += child.nodeSize\n }\n return\n }\n\n let decoIndex = 0, active = [], restNode = null\n for (let parentIndex = 0;;) {\n if (decoIndex < locals.length && locals[decoIndex].to == offset) {\n let widget = locals[decoIndex++], widgets\n while (decoIndex < locals.length && locals[decoIndex].to == offset)\n (widgets || (widgets = [widget])).push(locals[decoIndex++])\n if (widgets) {\n widgets.sort(compareSide)\n for (let i = 0; i < widgets.length; i++) onWidget(widgets[i], parentIndex)\n } else {\n onWidget(widget, parentIndex)\n }\n }\n\n let child, index\n if (restNode) {\n index = -1\n child = restNode\n restNode = null\n } else if (parentIndex < parent.childCount) {\n index = parentIndex\n child = parent.child(parentIndex++)\n } else {\n break\n }\n\n for (let i = 0; i < active.length; i++) if (active[i].to <= offset) active.splice(i--, 1)\n while (decoIndex < locals.length && locals[decoIndex].from == offset) active.push(locals[decoIndex++])\n\n let end = offset + child.nodeSize\n if (child.isText) {\n let cutAt = end\n if (decoIndex < locals.length && locals[decoIndex].from < cutAt) cutAt = locals[decoIndex].from\n for (let i = 0; i < active.length; i++) if (active[i].to < cutAt) cutAt = active[i].to\n if (cutAt < end) {\n restNode = child.cut(cutAt - offset)\n child = child.cut(0, cutAt - offset)\n end = cutAt\n index = -1\n }\n }\n\n onNode(child, active.length ? active.slice() : nothing, deco.forChild(offset, child), index)\n offset = end\n }\n}\n\n// List markers in Mobile Safari will mysteriously disappear\n// sometimes. This works around that.\nfunction iosHacks(dom) {\n if (dom.nodeName == \"UL\" || dom.nodeName == \"OL\") {\n let oldCSS = dom.style.cssText\n dom.style.cssText = oldCSS + \"; list-style: square !important\"\n window.getComputedStyle(dom).listStyle\n dom.style.cssText = oldCSS\n }\n}\n\nfunction nearbyTextNode(node, offset) {\n for (;;) {\n if (node.nodeType == 3) return node\n if (node.nodeType == 1 && offset > 0) {\n if (node.childNodes.length > offset && node.childNodes[offset].nodeType == 3)\n return node.childNodes[offset]\n node = node.childNodes[offset - 1]\n offset = nodeSize(node)\n } else if (node.nodeType == 1 && offset < node.childNodes.length) {\n node = node.childNodes[offset]\n offset = 0\n } else {\n return null\n }\n }\n}\n\n// Find a piece of text in an inline fragment, overlapping from-to\nfunction findTextInFragment(frag, text, from, to) {\n for (let str = \"\", i = 0, childPos = 0; i < frag.childCount; i++) {\n let child = frag.child(i), end = childPos + child.nodeSize\n if (child.isText) {\n str += child.text\n if (end >= to) {\n let strStart = end - str.length, found = str.lastIndexOf(text)\n while (found > -1 && strStart + found > from) found = str.lastIndexOf(text, found - 1)\n if (found > -1 && strStart + found + text.length >= to) {\n return strStart + found\n } else if (end > to) {\n break\n }\n }\n } else {\n str = \"\"\n }\n childPos = end\n }\n return -1\n}\n\n// Replace range from-to in an array of view descs with replacement\n// (may be null to just delete). This goes very much against the grain\n// of the rest of this code, which tends to create nodes with the\n// right shape in one go, rather than messing with them after\n// creation, but is necessary in the composition hack.\nfunction replaceNodes(nodes, from, to, view, replacement) {\n let result = []\n for (let i = 0, off = 0; i < nodes.length; i++) {\n let child = nodes[i], start = off, end = off += child.size\n if (start >= to || end <= from) {\n result.push(child)\n } else {\n if (start < from) result.push(child.slice(0, from - start, view))\n if (replacement) {\n result.push(replacement)\n replacement = null\n }\n if (end > to) result.push(child.slice(to - start, child.size, view))\n }\n }\n return result\n}\n","import {Selection, NodeSelection, TextSelection} from \"prosemirror-state\"\nimport browser from \"./browser\"\nimport {domIndex, selectionCollapsed} from \"./dom\"\n\nfunction moveSelectionBlock(state, dir) {\n let {$anchor, $head} = state.selection\n let $side = dir > 0 ? $anchor.max($head) : $anchor.min($head)\n let $start = !$side.parent.inlineContent ? $side : $side.depth ? state.doc.resolve(dir > 0 ? $side.after() : $side.before()) : null\n return $start && Selection.findFrom($start, dir)\n}\n\nfunction apply(view, sel) {\n view.dispatch(view.state.tr.setSelection(sel).scrollIntoView())\n return true\n}\n\nfunction selectHorizontally(view, dir, mods) {\n let sel = view.state.selection\n if (sel instanceof TextSelection) {\n if (!sel.empty || mods.indexOf(\"s\") > -1) {\n return false\n } else if (view.endOfTextblock(dir > 0 ? \"right\" : \"left\")) {\n let next = moveSelectionBlock(view.state, dir)\n if (next && (next instanceof NodeSelection)) return apply(view, next)\n return false\n } else {\n let $head = sel.$head, node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter, desc\n if (!node || node.isText) return false\n let nodePos = dir < 0 ? $head.pos - node.nodeSize : $head.pos\n if (!(node.isAtom || (desc = view.docView.descAt(nodePos)) && !desc.contentDOM)) return false\n if (NodeSelection.isSelectable(node)) {\n return apply(view, new NodeSelection(dir < 0 ? view.state.doc.resolve($head.pos - node.nodeSize) : $head))\n } else if (browser.webkit) {\n // Chrome and Safari will introduce extra pointless cursor\n // positions around inline uneditable nodes, so we have to\n // take over and move the cursor past them (#937)\n return apply(view, new TextSelection(view.state.doc.resolve(dir < 0 ? nodePos : nodePos + node.nodeSize)))\n } else {\n return false\n }\n }\n } else if (sel instanceof NodeSelection && sel.node.isInline) {\n return apply(view, new TextSelection(dir > 0 ? sel.$to : sel.$from))\n } else {\n let next = moveSelectionBlock(view.state, dir)\n if (next) return apply(view, next)\n return false\n }\n}\n\nfunction nodeLen(node) {\n return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length\n}\n\nfunction isIgnorable(dom) {\n let desc = dom.pmViewDesc\n return desc && desc.size == 0 && (dom.nextSibling || dom.nodeName != \"BR\")\n}\n\n// Make sure the cursor isn't directly after one or more ignored\n// nodes, which will confuse the browser's cursor motion logic.\nfunction skipIgnoredNodesLeft(view) {\n let sel = view.root.getSelection()\n let node = sel.focusNode, offset = sel.focusOffset\n if (!node) return\n let moveNode, moveOffset, force = false\n // Gecko will do odd things when the selection is directly in front\n // of a non-editable node, so in that case, move it into the next\n // node if possible. Issue prosemirror/prosemirror#832.\n if (browser.gecko && node.nodeType == 1 && offset < nodeLen(node) && isIgnorable(node.childNodes[offset])) force = true\n for (;;) {\n if (offset > 0) {\n if (node.nodeType != 1) {\n break\n } else {\n let before = node.childNodes[offset - 1]\n if (isIgnorable(before)) {\n moveNode = node\n moveOffset = --offset\n } else if (before.nodeType == 3) {\n node = before\n offset = node.nodeValue.length\n } else break\n }\n } else if (isBlockNode(node)) {\n break\n } else {\n let prev = node.previousSibling\n while (prev && isIgnorable(prev)) {\n moveNode = node.parentNode\n moveOffset = domIndex(prev)\n prev = prev.previousSibling\n }\n if (!prev) {\n node = node.parentNode\n if (node == view.dom) break\n offset = 0\n } else {\n node = prev\n offset = nodeLen(node)\n }\n }\n }\n if (force) setSelFocus(view, sel, node, offset)\n else if (moveNode) setSelFocus(view, sel, moveNode, moveOffset)\n}\n\n// Make sure the cursor isn't directly before one or more ignored\n// nodes.\nfunction skipIgnoredNodesRight(view) {\n let sel = view.root.getSelection()\n let node = sel.focusNode, offset = sel.focusOffset\n if (!node) return\n let len = nodeLen(node)\n let moveNode, moveOffset\n for (;;) {\n if (offset < len) {\n if (node.nodeType != 1) break\n let after = node.childNodes[offset]\n if (isIgnorable(after)) {\n moveNode = node\n moveOffset = ++offset\n }\n else break\n } else if (isBlockNode(node)) {\n break\n } else {\n let next = node.nextSibling\n while (next && isIgnorable(next)) {\n moveNode = next.parentNode\n moveOffset = domIndex(next) + 1\n next = next.nextSibling\n }\n if (!next) {\n node = node.parentNode\n if (node == view.dom) break\n offset = len = 0\n } else {\n node = next\n offset = 0\n len = nodeLen(node)\n }\n }\n }\n if (moveNode) setSelFocus(view, sel, moveNode, moveOffset)\n}\n\nfunction isBlockNode(dom) {\n let desc = dom.pmViewDesc\n return desc && desc.node && desc.node.isBlock\n}\n\nfunction setSelFocus(view, sel, node, offset) {\n if (selectionCollapsed(sel)) {\n let range = document.createRange()\n range.setEnd(node, offset)\n range.setStart(node, offset)\n sel.removeAllRanges()\n sel.addRange(range)\n } else if (sel.extend) {\n sel.extend(node, offset)\n }\n view.domObserver.setCurSelection()\n}\n\n// : (EditorState, number)\n// Check whether vertical selection motion would involve node\n// selections. If so, apply it (if not, the result is left to the\n// browser)\nfunction selectVertically(view, dir, mods) {\n let sel = view.state.selection\n if (sel instanceof TextSelection && !sel.empty || mods.indexOf(\"s\") > -1) return false\n let {$from, $to} = sel\n\n if (!$from.parent.inlineContent || view.endOfTextblock(dir < 0 ? \"up\" : \"down\")) {\n let next = moveSelectionBlock(view.state, dir)\n if (next && (next instanceof NodeSelection))\n return apply(view, next)\n }\n if (!$from.parent.inlineContent) {\n let beyond = Selection.findFrom(dir < 0 ? $from : $to, dir)\n return beyond ? apply(view, beyond) : true\n }\n return false\n}\n\nfunction stopNativeHorizontalDelete(view, dir) {\n if (!(view.state.selection instanceof TextSelection)) return true\n let {$head, $anchor, empty} = view.state.selection\n if (!$head.sameParent($anchor)) return true\n if (!empty) return false\n if (view.endOfTextblock(dir > 0 ? \"forward\" : \"backward\")) return true\n let nextNode = !$head.textOffset && (dir < 0 ? $head.nodeBefore : $head.nodeAfter)\n if (nextNode && !nextNode.isText) {\n let tr = view.state.tr\n if (dir < 0) tr.delete($head.pos - nextNode.nodeSize, $head.pos)\n else tr.delete($head.pos, $head.pos + nextNode.nodeSize)\n view.dispatch(tr)\n return true\n }\n return false\n}\n\nfunction switchEditable(view, node, state) {\n view.domObserver.stop()\n node.contentEditable = state\n view.domObserver.start()\n}\n\n// Issue #867 / https://bugs.chromium.org/p/chromium/issues/detail?id=903821\n// In which Chrome does really wrong things when the down arrow is\n// pressed when the cursor is directly at the start of a textblock and\n// has an uneditable node after it\nfunction chromeDownArrowBug(view) {\n if (!browser.chrome || view.state.selection.$head.parentOffset > 0) return\n let {focusNode, focusOffset} = view.root.getSelection()\n if (focusNode && focusNode.nodeType == 1 && focusOffset == 0 &&\n focusNode.firstChild && focusNode.firstChild.contentEditable == \"false\") {\n let child = focusNode.firstChild\n switchEditable(view, child, true)\n setTimeout(() => switchEditable(view, child, false), 20)\n }\n}\n\n// A backdrop key mapping used to make sure we always suppress keys\n// that have a dangerous default effect, even if the commands they are\n// bound to return false, and to make sure that cursor-motion keys\n// find a cursor (as opposed to a node selection) when pressed. For\n// cursor-motion keys, the code in the handlers also takes care of\n// block selections.\n\nfunction getMods(event) {\n let result = \"\"\n if (event.ctrlKey) result += \"c\"\n if (event.metaKey) result += \"m\"\n if (event.altKey) result += \"a\"\n if (event.shiftKey) result += \"s\"\n return result\n}\n\nexport function captureKeyDown(view, event) {\n let code = event.keyCode, mods = getMods(event)\n if (code == 8 || (browser.mac && code == 72 && mods == \"c\")) { // Backspace, Ctrl-h on Mac\n return stopNativeHorizontalDelete(view, -1) || skipIgnoredNodesLeft(view)\n } else if (code == 46 || (browser.mac && code == 68 && mods == \"c\")) { // Delete, Ctrl-d on Mac\n return stopNativeHorizontalDelete(view, 1) || skipIgnoredNodesRight(view)\n } else if (code == 13 || code == 27) { // Enter, Esc\n return true\n } else if (code == 37) { // Left arrow\n return selectHorizontally(view, -1, mods) || skipIgnoredNodesLeft(view)\n } else if (code == 39) { // Right arrow\n return selectHorizontally(view, 1, mods) || skipIgnoredNodesRight(view)\n } else if (code == 38) { // Up arrow\n return selectVertically(view, -1, mods) || skipIgnoredNodesLeft(view)\n } else if (code == 40) { // Down arrow\n return chromeDownArrowBug(view) || selectVertically(view, 1, mods) || skipIgnoredNodesRight(view)\n } else if (mods == (browser.mac ? \"m\" : \"c\") &&\n (code == 66 || code == 73 || code == 89 || code == 90)) { // Mod-[biyz]\n return true\n }\n return false\n}\n","import {TextSelection, NodeSelection} from \"prosemirror-state\"\n\nimport browser from \"./browser\"\nimport {selectionCollapsed, isEquivalentPosition, domIndex} from \"./dom\"\n\nexport function selectionFromDOM(view, origin) {\n let domSel = view.root.getSelection(), doc = view.state.doc\n let nearestDesc = view.docView.nearestDesc(domSel.focusNode), inWidget = nearestDesc && nearestDesc.size == 0\n let head = view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset)\n let $head = doc.resolve(head), $anchor, selection\n if (selectionCollapsed(domSel)) {\n $anchor = $head\n while (nearestDesc && !nearestDesc.node) nearestDesc = nearestDesc.parent\n if (nearestDesc && nearestDesc.node.isAtom && NodeSelection.isSelectable(nearestDesc.node) && nearestDesc.parent) {\n let pos = nearestDesc.posBefore\n selection = new NodeSelection(head == pos ? $head : doc.resolve(pos))\n }\n } else {\n $anchor = doc.resolve(view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset))\n }\n\n if (!selection) {\n let bias = origin == \"pointer\" || (view.state.selection.head < $head.pos && !inWidget) ? 1 : -1\n selection = selectionBetween(view, $anchor, $head, bias)\n }\n return selection\n}\n\nexport function selectionToDOM(view, force) {\n let sel = view.state.selection\n syncNodeSelection(view, sel)\n\n if (view.editable ? !view.hasFocus() : !(hasSelection(view) && document.activeElement.contains(view.dom))) return\n\n view.domObserver.disconnectSelection()\n\n if (view.cursorWrapper) {\n selectCursorWrapper(view)\n } else {\n let {anchor, head} = sel, resetEditableFrom, resetEditableTo\n if (brokenSelectBetweenUneditable && !(sel instanceof TextSelection)) {\n if (!sel.$from.parent.inlineContent)\n resetEditableFrom = temporarilyEditableNear(view, sel.from)\n if (!sel.empty && !sel.$from.parent.inlineContent)\n resetEditableTo = temporarilyEditableNear(view, sel.to)\n }\n view.docView.setSelection(anchor, head, view.root, force)\n if (brokenSelectBetweenUneditable) {\n if (resetEditableFrom) resetEditableFrom.contentEditable = \"false\"\n if (resetEditableTo) resetEditableTo.contentEditable = \"false\"\n }\n if (sel.visible) {\n view.dom.classList.remove(\"ProseMirror-hideselection\")\n } else if (anchor != head) {\n view.dom.classList.add(\"ProseMirror-hideselection\")\n if (\"onselectionchange\" in document) removeClassOnSelectionChange(view)\n }\n }\n\n view.domObserver.setCurSelection()\n view.domObserver.connectSelection()\n}\n\n// Kludge to work around Webkit not allowing a selection to start/end\n// between non-editable block nodes. We briefly make something\n// editable, set the selection, then set it uneditable again.\n\nconst brokenSelectBetweenUneditable = browser.safari || browser.chrome && browser.chrome_version < 63\n\nfunction temporarilyEditableNear(view, pos) {\n let {node, offset} = view.docView.domFromPos(pos)\n let after = offset < node.childNodes.length ? node.childNodes[offset] : null\n let before = offset ? node.childNodes[offset - 1] : null\n if ((!after || after.contentEditable == \"false\") && (!before || before.contentEditable == \"false\")) {\n if (after) {\n after.contentEditable = \"true\"\n return after\n } else if (before) {\n before.contentEditable = \"true\"\n return before\n }\n }\n}\n\nfunction removeClassOnSelectionChange(view) {\n let doc = view.dom.ownerDocument\n doc.removeEventListener(\"selectionchange\", view.hideSelectionGuard)\n let domSel = view.root.getSelection()\n let node = domSel.anchorNode, offset = domSel.anchorOffset\n doc.addEventListener(\"selectionchange\", view.hideSelectionGuard = () => {\n if (domSel.anchorNode != node || domSel.anchorOffset != offset) {\n doc.removeEventListener(\"selectionchange\", view.hideSelectionGuard)\n view.dom.classList.remove(\"ProseMirror-hideselection\")\n }\n })\n}\n\nfunction selectCursorWrapper(view) {\n let domSel = view.root.getSelection(), range = document.createRange()\n let node = view.cursorWrapper.dom, img = node.nodeName == \"IMG\"\n if (img) range.setEnd(node.parentNode, domIndex(node) + 1)\n else range.setEnd(node, 0)\n range.collapse(false)\n domSel.removeAllRanges()\n domSel.addRange(range)\n // Kludge to kill 'control selection' in IE11 when selecting an\n // invisible cursor wrapper, since that would result in those weird\n // resize handles and a selection that considers the absolutely\n // positioned wrapper, rather than the root editable node, the\n // focused element.\n if (!img && !view.state.selection.visible && browser.ie && browser.ie_version <= 11) {\n node.disabled = true\n node.disabled = false\n }\n}\n\nexport function syncNodeSelection(view, sel) {\n if (sel instanceof NodeSelection) {\n let desc = view.docView.descAt(sel.from)\n if (desc != view.lastSelectedViewDesc) {\n clearNodeSelection(view)\n if (desc) desc.selectNode()\n view.lastSelectedViewDesc = desc\n }\n } else {\n clearNodeSelection(view)\n }\n}\n\n// Clear all DOM statefulness of the last node selection.\nfunction clearNodeSelection(view) {\n if (view.lastSelectedViewDesc) {\n if (view.lastSelectedViewDesc.parent)\n view.lastSelectedViewDesc.deselectNode()\n view.lastSelectedViewDesc = null\n }\n}\n\nexport function selectionBetween(view, $anchor, $head, bias) {\n return view.someProp(\"createSelectionBetween\", f => f(view, $anchor, $head))\n || TextSelection.between($anchor, $head, bias)\n}\n\nexport function hasFocusAndSelection(view) {\n if (view.editable && view.root.activeElement != view.dom) return false\n return hasSelection(view)\n}\n\nexport function hasSelection(view) {\n let sel = view.root.getSelection()\n if (!sel.anchorNode) return false\n try {\n // Firefox will raise 'permission denied' errors when accessing\n // properties of `sel.anchorNode` when it's in a generated CSS\n // element.\n return view.dom.contains(sel.anchorNode.nodeType == 3 ? sel.anchorNode.parentNode : sel.anchorNode) &&\n (view.editable || view.dom.contains(sel.focusNode.nodeType == 3 ? sel.focusNode.parentNode : sel.focusNode))\n } catch(_) {\n return false\n }\n}\n\nexport function anchorInRightPlace(view) {\n let anchorDOM = view.docView.domFromPos(view.state.selection.anchor)\n let domSel = view.root.getSelection()\n return isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset)\n}\n","import {Fragment, DOMParser} from \"prosemirror-model\"\nimport {Selection, TextSelection} from \"prosemirror-state\"\n\nimport {selectionBetween, selectionFromDOM, selectionToDOM} from \"./selection\"\nimport {selectionCollapsed, keyEvent} from \"./dom\"\nimport browser from \"./browser\"\n\n// Note that all referencing and parsing is done with the\n// start-of-operation selection and document, since that's the one\n// that the DOM represents. If any changes came in in the meantime,\n// the modification is mapped over those before it is applied, in\n// readDOMChange.\n\nfunction parseBetween(view, from_, to_) {\n let {node: parent, fromOffset, toOffset, from, to} = view.docView.parseRange(from_, to_)\n\n let domSel = view.root.getSelection(), find = null, anchor = domSel.anchorNode\n if (anchor && view.dom.contains(anchor.nodeType == 1 ? anchor : anchor.parentNode)) {\n find = [{node: anchor, offset: domSel.anchorOffset}]\n if (!selectionCollapsed(domSel))\n find.push({node: domSel.focusNode, offset: domSel.focusOffset})\n }\n // Work around issue in Chrome where backspacing sometimes replaces\n // the deleted content with a random BR node (issues #799, #831)\n if (browser.chrome && view.lastKeyCode === 8) {\n for (let off = toOffset; off > fromOffset; off--) {\n let node = parent.childNodes[off - 1], desc = node.pmViewDesc\n if (node.nodeType == \"BR\" && !desc) { toOffset = off; break }\n if (!desc || desc.size) break\n }\n }\n let startDoc = view.state.doc\n let parser = view.someProp(\"domParser\") || DOMParser.fromSchema(view.state.schema)\n let $from = startDoc.resolve(from)\n\n let sel = null, doc = parser.parse(parent, {\n topNode: $from.parent,\n topMatch: $from.parent.contentMatchAt($from.index()),\n topOpen: true,\n from: fromOffset,\n to: toOffset,\n preserveWhitespace: $from.parent.type.spec.code ? \"full\" : true,\n editableContent: true,\n findPositions: find,\n ruleFromNode,\n context: $from\n })\n if (find && find[0].pos != null) {\n let anchor = find[0].pos, head = find[1] && find[1].pos\n if (head == null) head = anchor\n sel = {anchor: anchor + from, head: head + from}\n }\n return {doc, sel, from, to}\n}\n\nfunction ruleFromNode(dom) {\n let desc = dom.pmViewDesc\n if (desc) {\n return desc.parseRule()\n } else if (dom.nodeName == \"BR\" && dom.parentNode) {\n // Safari replaces the list item or table cell with a BR\n // directly in the list node (?!) if you delete the last\n // character in a list item or table cell (#708, #862)\n if (browser.safari && /^(ul|ol)$/i.test(dom.parentNode.nodeName)) {\n let skip = document.createElement(\"div\")\n skip.appendChild(document.createElement(\"li\"))\n return {skip}\n } else if (dom.parentNode.lastChild == dom || browser.safari && /^(tr|table)$/i.test(dom.parentNode.nodeName)) {\n return {ignore: true}\n }\n } else if (dom.nodeName == \"IMG\" && dom.getAttribute(\"mark-placeholder\")) {\n return {ignore: true}\n }\n}\n\nexport function readDOMChange(view, from, to, typeOver) {\n if (from < 0) {\n let origin = view.lastSelectionTime > Date.now() - 50 ? view.lastSelectionOrigin : null\n let newSel = selectionFromDOM(view, origin)\n if (!view.state.selection.eq(newSel)) {\n let tr = view.state.tr.setSelection(newSel)\n if (origin == \"pointer\") tr.setMeta(\"pointer\", true)\n else if (origin == \"key\") tr.scrollIntoView()\n view.dispatch(tr)\n }\n return\n }\n\n let $before = view.state.doc.resolve(from)\n let shared = $before.sharedDepth(to)\n from = $before.before(shared + 1)\n to = view.state.doc.resolve(to).after(shared + 1)\n\n let sel = view.state.selection\n let parse = parseBetween(view, from, to)\n\n let doc = view.state.doc, compare = doc.slice(parse.from, parse.to)\n let preferredPos, preferredSide\n // Prefer anchoring to end when Backspace is pressed\n if (view.lastKeyCode === 8 && Date.now() - 100 < view.lastKeyCodeTime) {\n preferredPos = view.state.selection.to\n preferredSide = \"end\"\n } else {\n preferredPos = view.state.selection.from\n preferredSide = \"start\"\n }\n view.lastKeyCode = null\n\n let change = findDiff(compare.content, parse.doc.content, parse.from, preferredPos, preferredSide)\n if (!change) {\n if (typeOver && sel instanceof TextSelection && !sel.empty && sel.$head.sameParent(sel.$anchor) &&\n !view.composing && !(parse.sel && parse.sel.anchor != parse.sel.head)) {\n change = {start: sel.from, endA: sel.to, endB: sel.to}\n } else {\n if (parse.sel) {\n let sel = resolveSelection(view, view.state.doc, parse.sel)\n if (sel && !sel.eq(view.state.selection)) view.dispatch(view.state.tr.setSelection(sel))\n }\n return\n }\n }\n view.domChangeCount++\n // Handle the case where overwriting a selection by typing matches\n // the start or end of the selected content, creating a change\n // that's smaller than what was actually overwritten.\n if (view.state.selection.from < view.state.selection.to &&\n change.start == change.endB &&\n view.state.selection instanceof TextSelection) {\n if (change.start > view.state.selection.from && change.start <= view.state.selection.from + 2) {\n change.start = view.state.selection.from\n } else if (change.endA < view.state.selection.to && change.endA >= view.state.selection.to - 2) {\n change.endB += (view.state.selection.to - change.endA)\n change.endA = view.state.selection.to\n }\n }\n\n // IE11 will insert a non-breaking space _ahead_ of the space after\n // the cursor space when adding a space before another space. When\n // that happened, adjust the change to cover the space instead.\n if (browser.ie && browser.ie_version <= 11 && change.endB == change.start + 1 &&\n change.endA == change.start && change.start > parse.from &&\n parse.doc.textBetween(change.start - parse.from - 1, change.start - parse.from + 1) == \" \\u00a0\") {\n change.start--\n change.endA--\n change.endB--\n }\n\n let $from = parse.doc.resolveNoCache(change.start - parse.from)\n let $to = parse.doc.resolveNoCache(change.endB - parse.from)\n let nextSel\n // If this looks like the effect of pressing Enter, just dispatch an\n // Enter key instead.\n if (!$from.sameParent($to) && $from.pos < parse.doc.content.size &&\n (nextSel = Selection.findFrom(parse.doc.resolve($from.pos + 1), 1, true)) &&\n nextSel.head == $to.pos &&\n view.someProp(\"handleKeyDown\", f => f(view, keyEvent(13, \"Enter\"))))\n return\n // Same for backspace\n if (view.state.selection.anchor > change.start &&\n looksLikeJoin(doc, change.start, change.endA, $from, $to) &&\n view.someProp(\"handleKeyDown\", f => f(view, keyEvent(8, \"Backspace\")))) {\n if (browser.android && browser.chrome) view.domObserver.suppressSelectionUpdates() // #820\n return\n }\n\n let chFrom = change.start, chTo = change.endA\n\n let tr, storedMarks, markChange, $from1\n if ($from.sameParent($to) && $from.parent.inlineContent) {\n if ($from.pos == $to.pos) { // Deletion\n // IE11 sometimes weirdly moves the DOM selection around after\n // backspacing out the first element in a textblock\n if (browser.ie && browser.ie_version <= 11 && $from.parentOffset == 0) {\n view.domObserver.suppressSelectionUpdates()\n setTimeout(() => selectionToDOM(view), 20)\n }\n tr = view.state.tr.delete(chFrom, chTo)\n storedMarks = doc.resolve(change.start).marksAcross(doc.resolve(change.endA))\n } else if ( // Adding or removing a mark\n change.endA == change.endB && ($from1 = doc.resolve(change.start)) &&\n (markChange = isMarkChange($from.parent.content.cut($from.parentOffset, $to.parentOffset),\n $from1.parent.content.cut($from1.parentOffset, change.endA - $from1.start())))\n ) {\n tr = view.state.tr\n if (markChange.type == \"add\") tr.addMark(chFrom, chTo, markChange.mark)\n else tr.removeMark(chFrom, chTo, markChange.mark)\n } else if ($from.parent.child($from.index()).isText && $from.index() == $to.index() - ($to.textOffset ? 0 : 1)) {\n // Both positions in the same text node -- simply insert text\n let text = $from.parent.textBetween($from.parentOffset, $to.parentOffset)\n if (view.someProp(\"handleTextInput\", f => f(view, chFrom, chTo, text))) return\n tr = view.state.tr.insertText(text, chFrom, chTo)\n }\n }\n\n if (!tr)\n tr = view.state.tr.replace(chFrom, chTo, parse.doc.slice(change.start - parse.from, change.endB - parse.from))\n if (parse.sel) {\n let sel = resolveSelection(view, tr.doc, parse.sel)\n // Chrome Android will sometimes, during composition, report the\n // selection in the wrong place. If it looks like that is\n // happening, don't update the selection.\n // Edge just doesn't move the cursor forward when you start typing\n // in an empty block or between br nodes.\n if (sel && !(browser.chrome && browser.android && view.composing && sel.empty && sel.head == chFrom ||\n browser.ie && sel.empty && sel.head == chFrom))\n tr.setSelection(sel)\n }\n if (storedMarks) tr.ensureMarks(storedMarks)\n view.dispatch(tr.scrollIntoView())\n}\n\nfunction resolveSelection(view, doc, parsedSel) {\n if (Math.max(parsedSel.anchor, parsedSel.head) > doc.content.size) return null\n return selectionBetween(view, doc.resolve(parsedSel.anchor), doc.resolve(parsedSel.head))\n}\n\n// : (Fragment, Fragment) → ?{mark: Mark, type: string}\n// Given two same-length, non-empty fragments of inline content,\n// determine whether the first could be created from the second by\n// removing or adding a single mark type.\nfunction isMarkChange(cur, prev) {\n let curMarks = cur.firstChild.marks, prevMarks = prev.firstChild.marks\n let added = curMarks, removed = prevMarks, type, mark, update\n for (let i = 0; i < prevMarks.length; i++) added = prevMarks[i].removeFromSet(added)\n for (let i = 0; i < curMarks.length; i++) removed = curMarks[i].removeFromSet(removed)\n if (added.length == 1 && removed.length == 0) {\n mark = added[0]\n type = \"add\"\n update = node => node.mark(mark.addToSet(node.marks))\n } else if (added.length == 0 && removed.length == 1) {\n mark = removed[0]\n type = \"remove\"\n update = node => node.mark(mark.removeFromSet(node.marks))\n } else {\n return null\n }\n let updated = []\n for (let i = 0; i < prev.childCount; i++) updated.push(update(prev.child(i)))\n if (Fragment.from(updated).eq(cur)) return {mark, type}\n}\n\nfunction looksLikeJoin(old, start, end, $newStart, $newEnd) {\n if (!$newStart.parent.isTextblock ||\n // The content must have shrunk\n end - start <= $newEnd.pos - $newStart.pos ||\n // newEnd must point directly at or after the end of the block that newStart points into\n skipClosingAndOpening($newStart, true, false) < $newEnd.pos)\n return false\n\n let $start = old.resolve(start)\n // Start must be at the end of a block\n if ($start.parentOffset < $start.parent.content.size || !$start.parent.isTextblock)\n return false\n let $next = old.resolve(skipClosingAndOpening($start, true, true))\n // The next textblock must start before end and end near it\n if (!$next.parent.isTextblock || $next.pos > end ||\n skipClosingAndOpening($next, true, false) < end)\n return false\n\n // The fragments after the join point must match\n return $newStart.parent.content.cut($newStart.parentOffset).eq($next.parent.content)\n}\n\nfunction skipClosingAndOpening($pos, fromEnd, mayOpen) {\n let depth = $pos.depth, end = fromEnd ? $pos.end() : $pos.pos\n while (depth > 0 && (fromEnd || $pos.indexAfter(depth) == $pos.node(depth).childCount)) {\n depth--\n end++\n fromEnd = false\n }\n if (mayOpen) {\n let next = $pos.node(depth).maybeChild($pos.indexAfter(depth))\n while (next && !next.isLeaf) {\n next = next.firstChild\n end++\n }\n }\n return end\n}\n\nfunction findDiff(a, b, pos, preferredPos, preferredSide) {\n let start = a.findDiffStart(b, pos)\n if (start == null) return null\n let {a: endA, b: endB} = a.findDiffEnd(b, pos + a.size, pos + b.size)\n if (preferredSide == \"end\") {\n let adjust = Math.max(0, start - Math.min(endA, endB))\n preferredPos -= endA + adjust - start\n }\n if (endA < start && a.size < b.size) {\n let move = preferredPos <= start && preferredPos >= endA ? start - preferredPos : 0\n start -= move\n endB = start + (endB - endA)\n endA = start\n } else if (endB < start) {\n let move = preferredPos <= start && preferredPos >= endB ? start - preferredPos : 0\n start -= move\n endA = start + (endA - endB)\n endB = start\n }\n return {start, endA, endB}\n}\n","import {Slice, Fragment, DOMParser, DOMSerializer} from \"prosemirror-model\"\n\nexport function serializeForClipboard(view, slice) {\n let context = [], {content, openStart, openEnd} = slice\n while (openStart > 1 && openEnd > 1 && content.childCount == 1 && content.firstChild.childCount == 1) {\n openStart--\n openEnd--\n let node = content.firstChild\n context.push(node.type.name, node.type.hasRequiredAttrs() ? node.attrs : null)\n content = node.content\n }\n\n let serializer = view.someProp(\"clipboardSerializer\") || DOMSerializer.fromSchema(view.state.schema)\n let doc = detachedDoc(), wrap = doc.createElement(\"div\")\n wrap.appendChild(serializer.serializeFragment(content, {document: doc}))\n\n let firstChild = wrap.firstChild, needsWrap\n while (firstChild && firstChild.nodeType == 1 && (needsWrap = wrapMap[firstChild.nodeName.toLowerCase()])) {\n for (let i = needsWrap.length - 1; i >= 0; i--) {\n let wrapper = doc.createElement(needsWrap[i])\n while (wrap.firstChild) wrapper.appendChild(wrap.firstChild)\n wrap.appendChild(wrapper)\n }\n firstChild = wrap.firstChild\n }\n\n if (firstChild && firstChild.nodeType == 1)\n firstChild.setAttribute(\"data-pm-slice\", `${openStart} ${openEnd} ${JSON.stringify(context)}`)\n\n let text = view.someProp(\"clipboardTextSerializer\", f => f(slice)) ||\n slice.content.textBetween(0, slice.content.size, \"\\n\\n\")\n\n return {dom: wrap, text}\n}\n\n// : (EditorView, string, string, ?bool, ResolvedPos) → ?Slice\n// Read a slice of content from the clipboard (or drop data).\nexport function parseFromClipboard(view, text, html, plainText, $context) {\n let dom, inCode = $context.parent.type.spec.code, slice\n if (!html && !text) return null\n let asText = text && (plainText || inCode || !html)\n if (asText) {\n view.someProp(\"transformPastedText\", f => { text = f(text) })\n if (inCode) return new Slice(Fragment.from(view.state.schema.text(text)), 0, 0)\n let parsed = view.someProp(\"clipboardTextParser\", f => f(text, $context))\n if (parsed) {\n slice = parsed\n } else {\n dom = document.createElement(\"div\")\n text.trim().split(/(?:\\r\\n?|\\n)+/).forEach(block => {\n dom.appendChild(document.createElement(\"p\")).textContent = block\n })\n }\n } else {\n view.someProp(\"transformPastedHTML\", f => { html = f(html) })\n dom = readHTML(html)\n }\n\n let contextNode = dom && dom.querySelector(\"[data-pm-slice]\")\n let sliceData = contextNode && /^(\\d+) (\\d+) (.*)/.exec(contextNode.getAttribute(\"data-pm-slice\"))\n if (!slice) {\n let parser = view.someProp(\"clipboardParser\") || view.someProp(\"domParser\") || DOMParser.fromSchema(view.state.schema)\n slice = parser.parseSlice(dom, {preserveWhitespace: !!(asText || sliceData), context: $context})\n }\n if (sliceData)\n slice = addContext(closeSlice(slice, +sliceData[1], +sliceData[2]), sliceData[3])\n else // HTML wasn't created by ProseMirror. Make sure top-level siblings are coherent\n slice = Slice.maxOpen(normalizeSiblings(slice.content, $context), false)\n\n view.someProp(\"transformPasted\", f => { slice = f(slice) })\n return slice\n}\n\n// Takes a slice parsed with parseSlice, which means there hasn't been\n// any content-expression checking done on the top nodes, tries to\n// find a parent node in the current context that might fit the nodes,\n// and if successful, rebuilds the slice so that it fits into that parent.\n//\n// This addresses the problem that Transform.replace expects a\n// coherent slice, and will fail to place a set of siblings that don't\n// fit anywhere in the schema.\nfunction normalizeSiblings(fragment, $context) {\n if (fragment.childCount < 2) return fragment\n for (let d = $context.depth; d >= 0; d--) {\n let parent = $context.node(d)\n let match = parent.contentMatchAt($context.index(d))\n let lastWrap, result = []\n fragment.forEach(node => {\n if (!result) return\n let wrap = match.findWrapping(node.type), inLast\n if (!wrap) return result = null\n if (inLast = result.length && lastWrap.length && addToSibling(wrap, lastWrap, node, result[result.length - 1], 0)) {\n result[result.length - 1] = inLast\n } else {\n if (result.length) result[result.length - 1] = closeRight(result[result.length - 1], lastWrap.length)\n let wrapped = withWrappers(node, wrap)\n result.push(wrapped)\n match = match.matchType(wrapped.type, wrapped.attrs)\n lastWrap = wrap\n }\n })\n if (result) return Fragment.from(result)\n }\n return fragment\n}\n\nfunction withWrappers(node, wrap, from = 0) {\n for (let i = wrap.length - 1; i >= from; i--)\n node = wrap[i].create(null, Fragment.from(node))\n return node\n}\n\n// Used to group adjacent nodes wrapped in similar parents by\n// normalizeSiblings into the same parent node\nfunction addToSibling(wrap, lastWrap, node, sibling, depth) {\n if (depth < wrap.length && depth < lastWrap.length && wrap[depth] == lastWrap[depth]) {\n let inner = addToSibling(wrap, lastWrap, node, sibling.lastChild, depth + 1)\n if (inner) return sibling.copy(sibling.content.replaceChild(sibling.childCount - 1, inner))\n let match = sibling.contentMatchAt(sibling.childCount)\n if (match.matchType(depth == wrap.length - 1 ? node.type : wrap[depth + 1]))\n return sibling.copy(sibling.content.append(Fragment.from(withWrappers(node, wrap, depth + 1))))\n }\n}\n\nfunction closeRight(node, depth) {\n if (depth == 0) return node\n let fragment = node.content.replaceChild(node.childCount - 1, closeRight(node.lastChild, depth - 1))\n let fill = node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true)\n return node.copy(fragment.append(fill))\n}\n\nfunction closeRange(fragment, side, from, to, depth, openEnd) {\n let node = side < 0 ? fragment.firstChild : fragment.lastChild, inner = node.content\n if (depth < to - 1) inner = closeRange(inner, side, from, to, depth + 1, openEnd)\n if (depth >= from)\n inner = side < 0 ? node.contentMatchAt(0).fillBefore(inner, fragment.childCount > 1 || openEnd <= depth).append(inner)\n : inner.append(node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true))\n return fragment.replaceChild(side < 0 ? 0 : fragment.childCount - 1, node.copy(inner))\n}\n\nfunction closeSlice(slice, openStart, openEnd) {\n if (openStart < slice.openStart)\n slice = new Slice(closeRange(slice.content, -1, openStart, slice.openStart, 0, slice.openEnd), openStart, slice.openEnd)\n if (openEnd < slice.openEnd)\n slice = new Slice(closeRange(slice.content, 1, openEnd, slice.openEnd, 0, 0), slice.openStart, openEnd)\n return slice\n}\n\n// Trick from jQuery -- some elements must be wrapped in other\n// elements for innerHTML to work. I.e. if you do `div.innerHTML =\n// \"..\"` the table cells are ignored.\nconst wrapMap = {thead: [\"table\"], colgroup: [\"table\"], col: [\"table\", \"colgroup\"],\n tr: [\"table\", \"tbody\"], td: [\"table\", \"tbody\", \"tr\"], th: [\"table\", \"tbody\", \"tr\"]}\n\nlet _detachedDoc = null\nfunction detachedDoc() {\n return _detachedDoc || (_detachedDoc = document.implementation.createHTMLDocument(\"title\"))\n}\n\nfunction readHTML(html) {\n let metas = /(\\s*]*>)*/.exec(html)\n if (metas) html = html.slice(metas[0].length)\n let elt = detachedDoc().createElement(\"div\")\n let firstTag = /(?:]*>)*<([a-z][^>\\s]+)/i.exec(html), wrap, depth = 0\n if (wrap = firstTag && wrapMap[firstTag[1].toLowerCase()]) {\n html = wrap.map(n => \"<\" + n + \">\").join(\"\") + html + wrap.map(n => \"\").reverse().join(\"\")\n depth = wrap.length\n }\n elt.innerHTML = html\n for (let i = 0; i < depth; i++) elt = elt.firstChild\n return elt\n}\n\nfunction addContext(slice, context) {\n if (!slice.size) return slice\n let schema = slice.content.firstChild.type.schema, array\n try { array = JSON.parse(context) }\n catch(e) { return slice }\n let {content, openStart, openEnd} = slice\n for (let i = array.length - 2; i >= 0; i -= 2) {\n let type = schema.nodes[array[i]]\n if (!type || type.hasRequiredAttrs()) break\n content = Fragment.from(type.create(array[i + 1], content))\n openStart++; openEnd++\n }\n return new Slice(content, openStart, openEnd)\n}\n","import browser from \"./browser\"\nimport {domIndex, isEquivalentPosition} from \"./dom\"\nimport {hasFocusAndSelection, hasSelection, selectionToDOM} from \"./selection\"\n\nconst observeOptions = {\n childList: true,\n characterData: true,\n characterDataOldValue: true,\n attributes: true,\n attributeOldValue: true,\n subtree: true\n}\n// IE11 has very broken mutation observers, so we also listen to DOMCharacterDataModified\nconst useCharData = browser.ie && browser.ie_version <= 11\n\nclass SelectionState {\n constructor() {\n this.anchorNode = this.anchorOffset = this.focusNode = this.focusOffset = null\n }\n\n set(sel) {\n this.anchorNode = sel.anchorNode; this.anchorOffset = sel.anchorOffset\n this.focusNode = sel.focusNode; this.focusOffset = sel.focusOffset\n }\n\n eq(sel) {\n return sel.anchorNode == this.anchorNode && sel.anchorOffset == this.anchorOffset &&\n sel.focusNode == this.focusNode && sel.focusOffset == this.focusOffset\n }\n}\n\nexport class DOMObserver {\n constructor(view, handleDOMChange) {\n this.view = view\n this.handleDOMChange = handleDOMChange\n this.queue = []\n this.flushingSoon = false\n this.observer = window.MutationObserver &&\n new window.MutationObserver(mutations => {\n for (let i = 0; i < mutations.length; i++) this.queue.push(mutations[i])\n // IE11 will sometimes (on backspacing out a single character\n // text node after a BR node) call the observer callback\n // before actually updating the DOM, which will cause\n // ProseMirror to miss the change (see #930)\n if (browser.ie && browser.ie_version <= 11 && mutations.some(\n m => m.type == \"childList\" && m.removedNodes.length ||\n m.type == \"characterData\" && m.oldValue.length > m.target.nodeValue.length))\n this.flushSoon()\n else\n this.flush()\n })\n this.currentSelection = new SelectionState\n if (useCharData) {\n this.onCharData = e => {\n this.queue.push({target: e.target, type: \"characterData\", oldValue: e.prevValue})\n this.flushSoon()\n }\n }\n this.onSelectionChange = this.onSelectionChange.bind(this)\n this.suppressingSelectionUpdates = false\n }\n\n flushSoon() {\n if (!this.flushingSoon) {\n this.flushingSoon = true\n window.setTimeout(() => { this.flushingSoon = false; this.flush() }, 20)\n }\n }\n\n start() {\n if (this.observer)\n this.observer.observe(this.view.dom, observeOptions)\n if (useCharData)\n this.view.dom.addEventListener(\"DOMCharacterDataModified\", this.onCharData)\n this.connectSelection()\n }\n\n stop() {\n if (this.observer) {\n let take = this.observer.takeRecords()\n if (take.length) {\n for (let i = 0; i < take.length; i++) this.queue.push(take[i])\n window.setTimeout(() => this.flush(), 20)\n }\n this.observer.disconnect()\n }\n if (useCharData) this.view.dom.removeEventListener(\"DOMCharacterDataModified\", this.onCharData)\n this.disconnectSelection()\n }\n\n connectSelection() {\n this.view.dom.ownerDocument.addEventListener(\"selectionchange\", this.onSelectionChange)\n }\n\n disconnectSelection() {\n this.view.dom.ownerDocument.removeEventListener(\"selectionchange\", this.onSelectionChange)\n }\n\n suppressSelectionUpdates() {\n this.suppressingSelectionUpdates = true\n setTimeout(() => this.suppressingSelectionUpdates = false, 50)\n }\n\n onSelectionChange() {\n if (!hasFocusAndSelection(this.view)) return\n if (this.suppressingSelectionUpdates) return selectionToDOM(this.view)\n // Deletions on IE11 fire their events in the wrong order, giving\n // us a selection change event before the DOM changes are\n // reported.\n if (browser.ie && browser.ie_version <= 11 && !this.view.state.selection.empty) {\n let sel = this.view.root.getSelection()\n // Selection.isCollapsed isn't reliable on IE\n if (sel.focusNode && isEquivalentPosition(sel.focusNode, sel.focusOffset, sel.anchorNode, sel.anchorOffset))\n return this.flushSoon()\n }\n this.flush()\n }\n\n setCurSelection() {\n this.currentSelection.set(this.view.root.getSelection())\n }\n\n ignoreSelectionChange(sel) {\n if (sel.rangeCount == 0) return true\n let container = sel.getRangeAt(0).commonAncestorContainer\n let desc = this.view.docView.nearestDesc(container)\n return desc && desc.ignoreMutation({type: \"selection\", target: container.nodeType == 3 ? container.parentNode : container})\n }\n\n flush() {\n if (!this.view.docView || this.flushingSoon) return\n let mutations = this.observer ? this.observer.takeRecords() : []\n if (this.queue.length) {\n mutations = this.queue.concat(mutations)\n this.queue.length = 0\n }\n\n let sel = this.view.root.getSelection()\n let newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasSelection(this.view) && !this.ignoreSelectionChange(sel)\n\n let from = -1, to = -1, typeOver = false, added = []\n if (this.view.editable) {\n for (let i = 0; i < mutations.length; i++) {\n let result = this.registerMutation(mutations[i], added)\n if (result) {\n from = from < 0 ? result.from : Math.min(result.from, from)\n to = to < 0 ? result.to : Math.max(result.to, to)\n if (result.typeOver && !this.view.composing) typeOver = true\n }\n }\n }\n\n if (browser.gecko && added.length > 1) {\n let brs = added.filter(n => n.nodeName == \"BR\")\n if (brs.length == 2) {\n let [a, b] = brs\n if (a.parentNode && a.parentNode.parentNode == b.parentNode) b.remove()\n else a.remove()\n }\n }\n\n if (from > -1 || newSel) {\n if (from > -1) {\n this.view.docView.markDirty(from, to)\n checkCSS(this.view)\n }\n this.handleDOMChange(from, to, typeOver)\n if (this.view.docView.dirty) this.view.updateState(this.view.state)\n else if (!this.currentSelection.eq(sel)) selectionToDOM(this.view)\n }\n }\n\n registerMutation(mut, added) {\n // Ignore mutations inside nodes that were already noted as inserted\n if (added.indexOf(mut.target) > -1) return null\n let desc = this.view.docView.nearestDesc(mut.target)\n if (mut.type == \"attributes\" &&\n (desc == this.view.docView || mut.attributeName == \"contenteditable\" ||\n // Firefox sometimes fires spurious events for null/empty styles\n (mut.attributeName == \"style\" && !mut.oldValue && !mut.target.getAttribute(\"style\"))))\n return null\n if (!desc || desc.ignoreMutation(mut)) return null\n\n if (mut.type == \"childList\") {\n let prev = mut.previousSibling, next = mut.nextSibling\n if (browser.ie && browser.ie_version <= 11 && mut.addedNodes.length) {\n // IE11 gives us incorrect next/prev siblings for some\n // insertions, so if there are added nodes, recompute those\n for (let i = 0; i < mut.addedNodes.length; i++) {\n let {previousSibling, nextSibling} = mut.addedNodes[i]\n if (!previousSibling || Array.prototype.indexOf.call(mut.addedNodes, previousSibling) < 0) prev = previousSibling\n if (!nextSibling || Array.prototype.indexOf.call(mut.addedNodes, nextSibling) < 0) next = nextSibling\n }\n }\n let fromOffset = prev && prev.parentNode == mut.target\n ? domIndex(prev) + 1 : 0\n let from = desc.localPosFromDOM(mut.target, fromOffset, -1)\n let toOffset = next && next.parentNode == mut.target\n ? domIndex(next) : mut.target.childNodes.length\n for (let i = 0; i < mut.addedNodes.length; i++) added.push(mut.addedNodes[i])\n let to = desc.localPosFromDOM(mut.target, toOffset, 1)\n return {from, to}\n } else if (mut.type == \"attributes\") {\n return {from: desc.posAtStart - desc.border, to: desc.posAtEnd + desc.border}\n } else { // \"characterData\"\n return {\n from: desc.posAtStart,\n to: desc.posAtEnd,\n // An event was generated for a text change that didn't change\n // any text. Mark the dom change to fall back to assuming the\n // selection was typed over with an identical value if it can't\n // find another change.\n typeOver: mut.target.nodeValue == mut.oldValue\n }\n }\n }\n}\n\nlet cssChecked = false\n\nfunction checkCSS(view) {\n if (cssChecked) return\n cssChecked = true\n if (getComputedStyle(view.dom).whiteSpace == \"normal\")\n console[\"warn\"](\"ProseMirror expects the CSS white-space property to be set, preferably to 'pre-wrap'. It is recommended to load style/prosemirror.css from the prosemirror-view package.\")\n}\n","import {Selection, NodeSelection, TextSelection} from \"prosemirror-state\"\nimport {dropPoint} from \"prosemirror-transform\"\nimport {Slice} from \"prosemirror-model\"\n\nimport browser from \"./browser\"\nimport {captureKeyDown} from \"./capturekeys\"\nimport {readDOMChange} from \"./domchange\"\nimport {parseFromClipboard, serializeForClipboard} from \"./clipboard\"\nimport {DOMObserver} from \"./domobserver\"\nimport {selectionBetween} from \"./selection\"\nimport {keyEvent} from \"./dom\"\n\n// A collection of DOM events that occur within the editor, and callback functions\n// to invoke when the event fires.\nconst handlers = {}, editHandlers = {}\n\nexport function initInput(view) {\n view.shiftKey = false\n view.mouseDown = null\n view.lastKeyCode = null\n view.lastKeyCodeTime = 0\n view.lastClick = {time: 0, x: 0, y: 0, type: \"\"}\n view.lastSelectionOrigin = null\n view.lastSelectionTime = 0\n\n view.composing = false\n view.composingTimeout = null\n view.compositionNodes = []\n view.compositionEndedAt = -2e8\n\n view.domObserver = new DOMObserver(view, (from, to, typeOver) => readDOMChange(view, from, to, typeOver))\n view.domObserver.start()\n // Used by hacks like the beforeinput handler to check whether anything happened in the DOM\n view.domChangeCount = 0\n\n view.eventHandlers = Object.create(null)\n for (let event in handlers) {\n let handler = handlers[event]\n view.dom.addEventListener(event, view.eventHandlers[event] = event => {\n if (eventBelongsToView(view, event) && !runCustomHandler(view, event) &&\n (view.editable || !(event.type in editHandlers)))\n handler(view, event)\n })\n }\n // On Safari, for reasons beyond my understanding, adding an input\n // event handler makes an issue where the composition vanishes when\n // you press enter go away.\n if (browser.safari) view.dom.addEventListener(\"input\", () => null)\n\n ensureListeners(view)\n}\n\nfunction setSelectionOrigin(view, origin) {\n view.lastSelectionOrigin = origin\n view.lastSelectionTime = Date.now()\n}\n\nexport function destroyInput(view) {\n view.domObserver.stop()\n for (let type in view.eventHandlers)\n view.dom.removeEventListener(type, view.eventHandlers[type])\n clearTimeout(view.composingTimeout)\n}\n\nexport function ensureListeners(view) {\n view.someProp(\"handleDOMEvents\", currentHandlers => {\n for (let type in currentHandlers) if (!view.eventHandlers[type])\n view.dom.addEventListener(type, view.eventHandlers[type] = event => runCustomHandler(view, event))\n })\n}\n\nfunction runCustomHandler(view, event) {\n return view.someProp(\"handleDOMEvents\", handlers => {\n let handler = handlers[event.type]\n return handler ? handler(view, event) || event.defaultPrevented : false\n })\n}\n\nfunction eventBelongsToView(view, event) {\n if (!event.bubbles) return true\n if (event.defaultPrevented) return false\n for (let node = event.target; node != view.dom; node = node.parentNode)\n if (!node || node.nodeType == 11 ||\n (node.pmViewDesc && node.pmViewDesc.stopEvent(event)))\n return false\n return true\n}\n\nexport function dispatchEvent(view, event) {\n if (!runCustomHandler(view, event) && handlers[event.type] &&\n (view.editable || !(event.type in editHandlers)))\n handlers[event.type](view, event)\n}\n\neditHandlers.keydown = (view, event) => {\n view.shiftKey = event.keyCode == 16 || event.shiftKey\n if (inOrNearComposition(view, event)) return\n view.lastKeyCode = event.keyCode\n view.lastKeyCodeTime = Date.now()\n if (view.someProp(\"handleKeyDown\", f => f(view, event)) || captureKeyDown(view, event))\n event.preventDefault()\n else\n setSelectionOrigin(view, \"key\")\n}\n\neditHandlers.keyup = (view, e) => {\n if (e.keyCode == 16) view.shiftKey = false\n}\n\neditHandlers.keypress = (view, event) => {\n if (inOrNearComposition(view, event) || !event.charCode ||\n event.ctrlKey && !event.altKey || browser.mac && event.metaKey) return\n\n if (view.someProp(\"handleKeyPress\", f => f(view, event))) {\n event.preventDefault()\n return\n }\n\n let sel = view.state.selection\n if (!(sel instanceof TextSelection) || !sel.$from.sameParent(sel.$to)) {\n let text = String.fromCharCode(event.charCode)\n if (!view.someProp(\"handleTextInput\", f => f(view, sel.$from.pos, sel.$to.pos, text)))\n view.dispatch(view.state.tr.insertText(text).scrollIntoView())\n event.preventDefault()\n }\n}\n\nfunction eventCoords(event) { return {left: event.clientX, top: event.clientY} }\n\nfunction isNear(event, click) {\n let dx = click.x - event.clientX, dy = click.y - event.clientY\n return dx * dx + dy * dy < 100\n}\n\nfunction runHandlerOnContext(view, propName, pos, inside, event) {\n if (inside == -1) return false\n let $pos = view.state.doc.resolve(inside)\n for (let i = $pos.depth + 1; i > 0; i--) {\n if (view.someProp(propName, f => i > $pos.depth ? f(view, pos, $pos.nodeAfter, $pos.before(i), event, true)\n : f(view, pos, $pos.node(i), $pos.before(i), event, false)))\n return true\n }\n return false\n}\n\nfunction updateSelection(view, selection, origin) {\n if (!view.focused) view.focus()\n let tr = view.state.tr.setSelection(selection)\n if (origin == \"pointer\") tr.setMeta(\"pointer\", true)\n view.dispatch(tr)\n}\n\nfunction selectClickedLeaf(view, inside) {\n if (inside == -1) return false\n let $pos = view.state.doc.resolve(inside), node = $pos.nodeAfter\n if (node && node.isAtom && NodeSelection.isSelectable(node)) {\n updateSelection(view, new NodeSelection($pos), \"pointer\")\n return true\n }\n return false\n}\n\nfunction selectClickedNode(view, inside) {\n if (inside == -1) return false\n let sel = view.state.selection, selectedNode, selectAt\n if (sel instanceof NodeSelection) selectedNode = sel.node\n\n let $pos = view.state.doc.resolve(inside)\n for (let i = $pos.depth + 1; i > 0; i--) {\n let node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i)\n if (NodeSelection.isSelectable(node)) {\n if (selectedNode && sel.$from.depth > 0 &&\n i >= sel.$from.depth && $pos.before(sel.$from.depth + 1) == sel.$from.pos)\n selectAt = $pos.before(sel.$from.depth)\n else\n selectAt = $pos.before(i)\n break\n }\n }\n\n if (selectAt != null) {\n updateSelection(view, NodeSelection.create(view.state.doc, selectAt), \"pointer\")\n return true\n } else {\n return false\n }\n}\n\nfunction handleSingleClick(view, pos, inside, event, selectNode) {\n return runHandlerOnContext(view, \"handleClickOn\", pos, inside, event) ||\n view.someProp(\"handleClick\", f => f(view, pos, event)) ||\n (selectNode ? selectClickedNode(view, inside) : selectClickedLeaf(view, inside))\n}\n\nfunction handleDoubleClick(view, pos, inside, event) {\n return runHandlerOnContext(view, \"handleDoubleClickOn\", pos, inside, event) ||\n view.someProp(\"handleDoubleClick\", f => f(view, pos, event))\n}\n\nfunction handleTripleClick(view, pos, inside, event) {\n return runHandlerOnContext(view, \"handleTripleClickOn\", pos, inside, event) ||\n view.someProp(\"handleTripleClick\", f => f(view, pos, event)) ||\n defaultTripleClick(view, inside)\n}\n\nfunction defaultTripleClick(view, inside) {\n let doc = view.state.doc\n if (inside == -1) {\n if (doc.inlineContent) {\n updateSelection(view, TextSelection.create(doc, 0, doc.content.size), \"pointer\")\n return true\n }\n return false\n }\n\n let $pos = doc.resolve(inside)\n for (let i = $pos.depth + 1; i > 0; i--) {\n let node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i)\n let nodePos = $pos.before(i)\n if (node.inlineContent)\n updateSelection(view, TextSelection.create(doc, nodePos + 1, nodePos + 1 + node.content.size), \"pointer\")\n else if (NodeSelection.isSelectable(node))\n updateSelection(view, NodeSelection.create(doc, nodePos), \"pointer\")\n else\n continue\n return true\n }\n}\n\nfunction forceDOMFlush(view) {\n return endComposition(view)\n}\n\nconst selectNodeModifier = browser.mac ? \"metaKey\" : \"ctrlKey\"\n\nhandlers.mousedown = (view, event) => {\n view.shiftKey = event.shiftKey\n let flushed = forceDOMFlush(view)\n let now = Date.now(), type = \"singleClick\"\n if (now - view.lastClick.time < 500 && isNear(event, view.lastClick) && !event[selectNodeModifier]) {\n if (view.lastClick.type == \"singleClick\") type = \"doubleClick\"\n else if (view.lastClick.type == \"doubleClick\") type = \"tripleClick\"\n }\n view.lastClick = {time: now, x: event.clientX, y: event.clientY, type}\n\n let pos = view.posAtCoords(eventCoords(event))\n if (!pos) return\n\n if (type == \"singleClick\")\n view.mouseDown = new MouseDown(view, pos, event, flushed)\n else if ((type == \"doubleClick\" ? handleDoubleClick : handleTripleClick)(view, pos.pos, pos.inside, event))\n event.preventDefault()\n else\n setSelectionOrigin(view, \"pointer\")\n}\n\nclass MouseDown {\n constructor(view, pos, event, flushed) {\n this.view = view\n this.startDoc = view.state.doc\n this.pos = pos\n this.event = event\n this.flushed = flushed\n this.selectNode = event[selectNodeModifier]\n this.allowDefault = event.shiftKey\n\n let targetNode, targetPos\n if (pos.inside > -1) {\n targetNode = view.state.doc.nodeAt(pos.inside)\n targetPos = pos.inside\n } else {\n let $pos = view.state.doc.resolve(pos.pos)\n targetNode = $pos.parent\n targetPos = $pos.depth ? $pos.before() : 0\n }\n\n this.mightDrag = null\n\n const target = flushed ? null : event.target\n const targetDesc = target ? view.docView.nearestDesc(target, true) : null\n this.target = targetDesc ? targetDesc.dom : null\n\n if (targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false ||\n view.state.selection instanceof NodeSelection && targetPos == view.state.selection.from)\n this.mightDrag = {node: targetNode,\n pos: targetPos,\n addAttr: this.target && !this.target.draggable,\n setUneditable: this.target && browser.gecko && !this.target.hasAttribute(\"contentEditable\")}\n\n if (this.target && this.mightDrag && (this.mightDrag.addAttr || this.mightDrag.setUneditable)) {\n this.view.domObserver.stop()\n if (this.mightDrag.addAttr) this.target.draggable = true\n if (this.mightDrag.setUneditable)\n setTimeout(() => this.target.setAttribute(\"contentEditable\", \"false\"), 20)\n this.view.domObserver.start()\n }\n\n view.root.addEventListener(\"mouseup\", this.up = this.up.bind(this))\n view.root.addEventListener(\"mousemove\", this.move = this.move.bind(this))\n setSelectionOrigin(view, \"pointer\")\n }\n\n done() {\n this.view.root.removeEventListener(\"mouseup\", this.up)\n this.view.root.removeEventListener(\"mousemove\", this.move)\n if (this.mightDrag && this.target) {\n this.view.domObserver.stop()\n if (this.mightDrag.addAttr) this.target.draggable = false\n if (this.mightDrag.setUneditable) this.target.removeAttribute(\"contentEditable\")\n this.view.domObserver.start()\n }\n this.view.mouseDown = null\n }\n\n up(event) {\n this.done()\n\n if (!this.view.dom.contains(event.target.nodeType == 3 ? event.target.parentNode : event.target))\n return\n\n let pos = this.pos\n if (this.view.state.doc != this.startDoc) pos = this.view.posAtCoords(eventCoords(event))\n\n if (this.allowDefault || !pos) {\n setSelectionOrigin(this.view, \"pointer\")\n } else if (handleSingleClick(this.view, pos.pos, pos.inside, event, this.selectNode)) {\n event.preventDefault()\n } else if (this.flushed ||\n // Chrome will sometimes treat a node selection as a\n // cursor, but still report that the node is selected\n // when asked through getSelection. You'll then get a\n // situation where clicking at the point where that\n // (hidden) cursor is doesn't change the selection, and\n // thus doesn't get a reaction from ProseMirror. This\n // works around that.\n (browser.chrome && !(this.view.state.selection instanceof TextSelection) &&\n (pos.pos == this.view.state.selection.from || pos.pos == this.view.state.selection.to))) {\n updateSelection(this.view, Selection.near(this.view.state.doc.resolve(pos.pos)), \"pointer\")\n event.preventDefault()\n } else {\n setSelectionOrigin(this.view, \"pointer\")\n }\n }\n\n move(event) {\n if (!this.allowDefault && (Math.abs(this.event.x - event.clientX) > 4 ||\n Math.abs(this.event.y - event.clientY) > 4))\n this.allowDefault = true\n setSelectionOrigin(this.view, \"pointer\")\n }\n}\n\nhandlers.touchdown = view => {\n forceDOMFlush(view)\n setSelectionOrigin(view, \"pointer\")\n}\n\nhandlers.contextmenu = view => forceDOMFlush(view)\n\nfunction inOrNearComposition(view, event) {\n if (view.composing) return true\n // See https://www.stum.de/2016/06/24/handling-ime-events-in-javascript/.\n // On Japanese input method editors (IMEs), the Enter key is used to confirm character\n // selection. On Safari, when Enter is pressed, compositionend and keydown events are\n // emitted. The keydown event triggers newline insertion, which we don't want.\n // This method returns true if the keydown event should be ignored.\n // We only ignore it once, as pressing Enter a second time *should* insert a newline.\n // Furthermore, the keydown event timestamp must be close to the compositionEndedAt timestamp.\n // This guards against the case where compositionend is triggered without the keyboard\n // (e.g. character confirmation may be done with the mouse), and keydown is triggered\n // afterwards- we wouldn't want to ignore the keydown event in this case.\n if (browser.safari && Math.abs(event.timeStamp - view.compositionEndedAt) < 500) {\n view.compositionEndedAt = -2e8\n return true\n }\n return false\n}\n\n// Drop active composition after 5 seconds of inactivity on Android\nconst timeoutComposition = browser.android ? 5000 : -1\n\neditHandlers.compositionstart = editHandlers.compositionupdate = view => {\n if (!view.composing) {\n view.domObserver.flush()\n let {state} = view, $pos = state.selection.$from\n if (state.selection.empty &&\n (state.storedMarks || (!$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some(m => m.type.spec.inclusive === false)))) {\n // Need to wrap the cursor in mark nodes different from the ones in the DOM context\n view.markCursor = view.state.storedMarks || $pos.marks()\n endComposition(view, true)\n view.markCursor = null\n } else {\n endComposition(view)\n // In firefox, if the cursor is after but outside a marked node,\n // the inserted text won't inherit the marks. So this moves it\n // inside if necessary.\n if (browser.gecko && state.selection.empty && $pos.parentOffset && !$pos.textOffset && $pos.nodeBefore.marks.length) {\n let sel = view.root.getSelection()\n for (let node = sel.focusNode, offset = sel.focusOffset; node && node.nodeType == 1 && offset != 0;) {\n let before = offset < 0 ? node.lastChild : node.childNodes[offset - 1]\n if (before.nodeType == 3) {\n sel.collapse(before, before.nodeValue.length)\n break\n } else {\n node = before\n offset = -1\n }\n }\n }\n }\n view.composing = true\n }\n scheduleComposeEnd(view, timeoutComposition)\n}\n\neditHandlers.compositionend = (view, event) => {\n if (view.composing) {\n view.composing = false\n view.compositionEndedAt = event.timeStamp\n scheduleComposeEnd(view, 20)\n }\n}\n\nfunction scheduleComposeEnd(view, delay) {\n clearTimeout(view.composingTimeout)\n if (delay > -1) view.composingTimeout = setTimeout(() => endComposition(view), delay)\n}\n\nexport function endComposition(view, forceUpdate) {\n view.composing = false\n while (view.compositionNodes.length > 0) view.compositionNodes.pop().markParentsDirty()\n if (forceUpdate || view.docView.dirty) {\n view.updateState(view.state)\n return true\n }\n return false\n}\n\nfunction captureCopy(view, dom) {\n // The extra wrapper is somehow necessary on IE/Edge to prevent the\n // content from being mangled when it is put onto the clipboard\n let doc = view.dom.ownerDocument\n let wrap = doc.body.appendChild(doc.createElement(\"div\"))\n wrap.appendChild(dom)\n wrap.style.cssText = \"position: fixed; left: -10000px; top: 10px\"\n let sel = getSelection(), range = doc.createRange()\n range.selectNodeContents(dom)\n // Done because IE will fire a selectionchange moving the selection\n // to its start when removeAllRanges is called and the editor still\n // has focus (which will mess up the editor's selection state).\n view.dom.blur()\n sel.removeAllRanges()\n sel.addRange(range)\n setTimeout(() => {\n doc.body.removeChild(wrap)\n view.focus()\n }, 50)\n}\n\n// This is very crude, but unfortunately both these browsers _pretend_\n// that they have a clipboard API—all the objects and methods are\n// there, they just don't work, and they are hard to test.\nconst brokenClipboardAPI = (browser.ie && browser.ie_version < 15) ||\n (browser.ios && browser.webkit_version < 604)\n\nhandlers.copy = editHandlers.cut = (view, e) => {\n let sel = view.state.selection, cut = e.type == \"cut\"\n if (sel.empty) return\n\n // IE and Edge's clipboard interface is completely broken\n let data = brokenClipboardAPI ? null : e.clipboardData\n let slice = sel.content(), {dom, text} = serializeForClipboard(view, slice)\n if (data) {\n e.preventDefault()\n data.clearData()\n data.setData(\"text/html\", dom.innerHTML)\n data.setData(\"text/plain\", text)\n } else {\n captureCopy(view, dom)\n }\n if (cut) view.dispatch(view.state.tr.deleteSelection().scrollIntoView().setMeta(\"uiEvent\", \"cut\"))\n}\n\nfunction sliceSingleNode(slice) {\n return slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1 ? slice.content.firstChild : null\n}\n\nfunction capturePaste(view, e) {\n let doc = view.dom.ownerDocument\n let plainText = view.shiftKey || view.state.selection.$from.parent.type.spec.code\n let target = doc.body.appendChild(doc.createElement(plainText ? \"textarea\" : \"div\"))\n if (!plainText) target.contentEditable = \"true\"\n target.style.cssText = \"position: fixed; left: -10000px; top: 10px\"\n target.focus()\n setTimeout(() => {\n view.focus()\n doc.body.removeChild(target)\n if (plainText) doPaste(view, target.value, null, e)\n else doPaste(view, target.textContent, target.innerHTML, e)\n }, 50)\n}\n\nfunction doPaste(view, text, html, e) {\n let slice = parseFromClipboard(view, text, html, view.shiftKey, view.state.selection.$from)\n if (view.someProp(\"handlePaste\", f => f(view, e, slice || Slice.empty)) || !slice) return\n\n let singleNode = sliceSingleNode(slice)\n let tr = singleNode ? view.state.tr.replaceSelectionWith(singleNode, view.shiftKey) : view.state.tr.replaceSelection(slice)\n view.dispatch(tr.scrollIntoView().setMeta(\"paste\", true).setMeta(\"uiEvent\", \"paste\"))\n}\n\neditHandlers.paste = (view, e) => {\n let data = brokenClipboardAPI ? null : e.clipboardData\n let html = data && data.getData(\"text/html\"), text = data && data.getData(\"text/plain\")\n if (data && (html || text || data.files.length)) {\n doPaste(view, text, html, e)\n e.preventDefault()\n } else {\n capturePaste(view, e)\n }\n}\n\nclass Dragging {\n constructor(slice, move) {\n this.slice = slice\n this.move = move\n }\n}\n\nconst dragCopyModifier = browser.mac ? \"altKey\" : \"ctrlKey\"\n\nhandlers.dragstart = (view, e) => {\n let mouseDown = view.mouseDown\n if (mouseDown) mouseDown.done()\n if (!e.dataTransfer) return\n\n let sel = view.state.selection\n let pos = sel.empty ? null : view.posAtCoords(eventCoords(e))\n if (pos && pos.pos >= sel.from && pos.pos <= (sel instanceof NodeSelection ? sel.to - 1: sel.to)) {\n // In selection\n } else if (mouseDown && mouseDown.mightDrag) {\n view.dispatch(view.state.tr.setSelection(NodeSelection.create(view.state.doc, mouseDown.mightDrag.pos)))\n } else if (e.target && e.target.nodeType == 1) {\n let desc = view.docView.nearestDesc(e.target, true)\n if (!desc || !desc.node.type.spec.draggable || desc == view.docView) return\n view.dispatch(view.state.tr.setSelection(NodeSelection.create(view.state.doc, desc.posBefore)))\n }\n let slice = view.state.selection.content(), {dom, text} = serializeForClipboard(view, slice)\n e.dataTransfer.clearData()\n e.dataTransfer.setData(brokenClipboardAPI ? \"Text\" : \"text/html\", dom.innerHTML)\n if (!brokenClipboardAPI) e.dataTransfer.setData(\"text/plain\", text)\n view.dragging = new Dragging(slice, !e[dragCopyModifier])\n}\n\nhandlers.dragend = view => {\n window.setTimeout(() => view.dragging = null, 50)\n}\n\neditHandlers.dragover = editHandlers.dragenter = (_, e) => e.preventDefault()\n\neditHandlers.drop = (view, e) => {\n let dragging = view.dragging\n view.dragging = null\n\n if (!e.dataTransfer) return\n\n let eventPos = view.posAtCoords(eventCoords(e))\n if (!eventPos) return\n let $mouse = view.state.doc.resolve(eventPos.pos)\n if (!$mouse) return\n let slice = dragging && dragging.slice ||\n parseFromClipboard(view, e.dataTransfer.getData(brokenClipboardAPI ? \"Text\" : \"text/plain\"),\n brokenClipboardAPI ? null : e.dataTransfer.getData(\"text/html\"), false, $mouse)\n if (!slice) return\n\n e.preventDefault()\n if (view.someProp(\"handleDrop\", f => f(view, e, slice, dragging && dragging.move))) return\n let insertPos = slice ? dropPoint(view.state.doc, $mouse.pos, slice) : $mouse.pos\n if (insertPos == null) insertPos = $mouse.pos\n\n let tr = view.state.tr\n if (dragging && dragging.move) tr.deleteSelection()\n\n let pos = tr.mapping.map(insertPos)\n let isNode = slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1\n let beforeInsert = tr.doc\n if (isNode)\n tr.replaceRangeWith(pos, pos, slice.content.firstChild)\n else\n tr.replaceRange(pos, pos, slice)\n if (tr.doc.eq(beforeInsert)) return\n\n let $pos = tr.doc.resolve(pos)\n if (isNode && NodeSelection.isSelectable(slice.content.firstChild) &&\n $pos.nodeAfter && $pos.nodeAfter.sameMarkup(slice.content.firstChild))\n tr.setSelection(new NodeSelection($pos))\n else\n tr.setSelection(selectionBetween(view, $pos, tr.doc.resolve(tr.mapping.map(insertPos))))\n view.focus()\n view.dispatch(tr.setMeta(\"uiEvent\", \"drop\"))\n}\n\nhandlers.focus = view => {\n if (!view.focused) {\n view.domObserver.stop()\n view.dom.classList.add(\"ProseMirror-focused\")\n view.domObserver.start()\n view.focused = true\n }\n}\n\nhandlers.blur = view => {\n if (view.focused) {\n view.domObserver.stop()\n view.dom.classList.remove(\"ProseMirror-focused\")\n view.domObserver.start()\n view.domObserver.currentSelection.set({})\n view.focused = false\n }\n}\n\nhandlers.beforeinput = (view, event) => {\n // We should probably do more with beforeinput events, but support\n // is so spotty that I'm still waiting to see where they are going.\n\n // Very specific hack to deal with backspace sometimes failing on\n // Chrome Android when after an uneditable node.\n if (browser.chrome && browser.android && event.inputType == \"deleteContentBackward\") {\n let {domChangeCount} = view\n setTimeout(() => {\n if (view.domChangeCount != domChangeCount) return // Event already had some effect\n // This bug tends to close the virtual keyboard, so we refocus\n view.dom.blur()\n view.focus()\n if (view.someProp(\"handleKeyDown\", f => f(view, keyEvent(8, \"Backspace\")))) return\n let {$cursor} = view.state.selection\n // Crude approximation of backspace behavior when no command handled it\n if ($cursor && $cursor.pos > 0) view.dispatch(view.state.tr.delete($cursor.pos - 1, $cursor.pos).scrollIntoView())\n }, 50)\n }\n}\n\n// Make sure all handlers get registered\nfor (let prop in editHandlers) handlers[prop] = editHandlers[prop]\n","function compareObjs(a, b) {\n if (a == b) return true\n for (let p in a) if (a[p] !== b[p]) return false\n for (let p in b) if (!(p in a)) return false\n return true\n}\n\nclass WidgetType {\n constructor(toDOM, spec) {\n this.spec = spec || noSpec\n this.side = this.spec.side || 0\n this.toDOM = toDOM\n }\n\n map(mapping, span, offset, oldOffset) {\n let {pos, deleted} = mapping.mapResult(span.from + oldOffset, this.side < 0 ? -1 : 1)\n return deleted ? null : new Decoration(pos - offset, pos - offset, this)\n }\n\n valid() { return true }\n\n eq(other) {\n return this == other ||\n (other instanceof WidgetType &&\n (this.spec.key && this.spec.key == other.spec.key ||\n this.toDOM == other.toDOM && compareObjs(this.spec, other.spec)))\n }\n}\n\nclass InlineType {\n constructor(attrs, spec) {\n this.spec = spec || noSpec\n this.attrs = attrs\n }\n\n map(mapping, span, offset, oldOffset) {\n let from = mapping.map(span.from + oldOffset, this.spec.inclusiveStart ? -1 : 1) - offset\n let to = mapping.map(span.to + oldOffset, this.spec.inclusiveEnd ? 1 : -1) - offset\n return from >= to ? null : new Decoration(from, to, this)\n }\n\n valid(_, span) { return span.from < span.to }\n\n eq(other) {\n return this == other ||\n (other instanceof InlineType && compareObjs(this.attrs, other.attrs) &&\n compareObjs(this.spec, other.spec))\n }\n\n static is(span) { return span.type instanceof InlineType }\n}\n\nclass NodeType {\n constructor(attrs, spec) {\n this.spec = spec || noSpec\n this.attrs = attrs\n }\n\n map(mapping, span, offset, oldOffset) {\n let from = mapping.mapResult(span.from + oldOffset, 1)\n if (from.deleted) return null\n let to = mapping.mapResult(span.to + oldOffset, -1)\n if (to.deleted || to.pos <= from.pos) return null\n return new Decoration(from.pos - offset, to.pos - offset, this)\n }\n\n valid(node, span) {\n let {index, offset} = node.content.findIndex(span.from)\n return offset == span.from && offset + node.child(index).nodeSize == span.to\n }\n\n eq(other) {\n return this == other ||\n (other instanceof NodeType && compareObjs(this.attrs, other.attrs) &&\n compareObjs(this.spec, other.spec))\n }\n}\n\n// ::- Decoration objects can be provided to the view through the\n// [`decorations` prop](#view.EditorProps.decorations). They come in\n// several variants—see the static members of this class for details.\nexport class Decoration {\n constructor(from, to, type) {\n // :: number\n // The start position of the decoration.\n this.from = from\n // :: number\n // The end position. Will be the same as `from` for [widget\n // decorations](#view.Decoration^widget).\n this.to = to\n this.type = type\n }\n\n copy(from, to) {\n return new Decoration(from, to, this.type)\n }\n\n eq(other) {\n return this.type.eq(other.type) && this.from == other.from && this.to == other.to\n }\n\n map(mapping, offset, oldOffset) {\n return this.type.map(mapping, this, offset, oldOffset)\n }\n\n // :: (number, union<(view: EditorView, getPos: () → number) → dom.Node, dom.Node>, ?Object) → Decoration\n // Creates a widget decoration, which is a DOM node that's shown in\n // the document at the given position. It is recommended that you\n // delay rendering the widget by passing a function that will be\n // called when the widget is actually drawn in a view, but you can\n // also directly pass a DOM node. `getPos` can be used to find the\n // widget's current document position.\n //\n // spec::- These options are supported:\n //\n // side:: ?number\n // Controls which side of the document position this widget is\n // associated with. When negative, it is drawn before a cursor\n // at its position, and content inserted at that position ends\n // up after the widget. When zero (the default) or positive, the\n // widget is drawn after the cursor and content inserted there\n // ends up before the widget.\n //\n // When there are multiple widgets at a given position, their\n // `side` values determine the order in which they appear. Those\n // with lower values appear first. The ordering of widgets with\n // the same `side` value is unspecified.\n //\n // When `marks` is null, `side` also determines the marks that\n // the widget is wrapped in—those of the node before when\n // negative, those of the node after when positive.\n //\n // marks:: ?[Mark]\n // The precise set of marks to draw around the widget.\n //\n // stopEvent:: ?(event: dom.Event) → bool\n // Can be used to control which DOM events, when they bubble out\n // of this widget, the editor view should ignore.\n //\n // key:: ?string\n // When comparing decorations of this type (in order to decide\n // whether it needs to be redrawn), ProseMirror will by default\n // compare the widget DOM node by identity. If you pass a key,\n // that key will be compared instead, which can be useful when\n // you generate decorations on the fly and don't want to store\n // and reuse DOM nodes. Make sure that any widgets with the same\n // key are interchangeable—if widgets differ in, for example,\n // the behavior of some event handler, they should get\n // different keys.\n static widget(pos, toDOM, spec) {\n return new Decoration(pos, pos, new WidgetType(toDOM, spec))\n }\n\n // :: (number, number, DecorationAttrs, ?Object) → Decoration\n // Creates an inline decoration, which adds the given attributes to\n // each inline node between `from` and `to`.\n //\n // spec::- These options are recognized:\n //\n // inclusiveStart:: ?bool\n // Determines how the left side of the decoration is\n // [mapped](#transform.Position_Mapping) when content is\n // inserted directly at that position. By default, the decoration\n // won't include the new content, but you can set this to `true`\n // to make it inclusive.\n //\n // inclusiveEnd:: ?bool\n // Determines how the right side of the decoration is mapped.\n // See\n // [`inclusiveStart`](#view.Decoration^inline^spec.inclusiveStart).\n static inline(from, to, attrs, spec) {\n return new Decoration(from, to, new InlineType(attrs, spec))\n }\n\n // :: (number, number, DecorationAttrs, ?Object) → Decoration\n // Creates a node decoration. `from` and `to` should point precisely\n // before and after a node in the document. That node, and only that\n // node, will receive the given attributes.\n //\n // spec::-\n //\n // Optional information to store with the decoration. It\n // is also used when comparing decorators for equality.\n static node(from, to, attrs, spec) {\n return new Decoration(from, to, new NodeType(attrs, spec))\n }\n\n // :: Object\n // The spec provided when creating this decoration. Can be useful\n // if you've stored extra information in that object.\n get spec() { return this.type.spec }\n}\n\n// DecorationAttrs:: interface\n// A set of attributes to add to a decorated node. Most properties\n// simply directly correspond to DOM attributes of the same name,\n// which will be set to the property's value. These are exceptions:\n//\n// class:: ?string\n// A CSS class name or a space-separated set of class names to be\n// _added_ to the classes that the node already had.\n//\n// style:: ?string\n// A string of CSS to be _added_ to the node's existing `style` property.\n//\n// nodeName:: ?string\n// When non-null, the target node is wrapped in a DOM element of\n// this type (and the other attributes are applied to this element).\n\nconst none = [], noSpec = {}\n\n// ::- A collection of [decorations](#view.Decoration), organized in\n// such a way that the drawing algorithm can efficiently use and\n// compare them. This is a persistent data structure—it is not\n// modified, updates create a new value.\nexport class DecorationSet {\n constructor(local, children) {\n this.local = local && local.length ? local : none\n this.children = children && children.length ? children : none\n }\n\n // :: (Node, [Decoration]) → DecorationSet\n // Create a set of decorations, using the structure of the given\n // document.\n static create(doc, decorations) {\n return decorations.length ? buildTree(decorations, doc, 0, noSpec) : empty\n }\n\n // :: (?number, ?number, ?(spec: Object) → bool) → [Decoration]\n // Find all decorations in this set which touch the given range\n // (including decorations that start or end directly at the\n // boundaries) and match the given predicate on their spec. When\n // `start` and `end` are omitted, all decorations in the set are\n // considered. When `predicate` isn't given, all decorations are\n // assumed to match.\n find(start, end, predicate) {\n let result = []\n this.findInner(start == null ? 0 : start, end == null ? 1e9 : end, result, 0, predicate)\n return result\n }\n\n findInner(start, end, result, offset, predicate) {\n for (let i = 0; i < this.local.length; i++) {\n let span = this.local[i]\n if (span.from <= end && span.to >= start && (!predicate || predicate(span.spec)))\n result.push(span.copy(span.from + offset, span.to + offset))\n }\n for (let i = 0; i < this.children.length; i += 3) {\n if (this.children[i] < end && this.children[i + 1] > start) {\n let childOff = this.children[i] + 1\n this.children[i + 2].findInner(start - childOff, end - childOff, result, offset + childOff, predicate)\n }\n }\n }\n\n // :: (Mapping, Node, ?Object) → DecorationSet\n // Map the set of decorations in response to a change in the\n // document.\n //\n // options::- An optional set of options.\n //\n // onRemove:: ?(decorationSpec: Object)\n // When given, this function will be called for each decoration\n // that gets dropped as a result of the mapping, passing the\n // spec of that decoration.\n map(mapping, doc, options) {\n if (this == empty || mapping.maps.length == 0) return this\n return this.mapInner(mapping, doc, 0, 0, options || noSpec)\n }\n\n mapInner(mapping, node, offset, oldOffset, options) {\n let newLocal\n for (let i = 0; i < this.local.length; i++) {\n let mapped = this.local[i].map(mapping, offset, oldOffset)\n if (mapped && mapped.type.valid(node, mapped)) (newLocal || (newLocal = [])).push(mapped)\n else if (options.onRemove) options.onRemove(this.local[i].spec)\n }\n\n if (this.children.length)\n return mapChildren(this.children, newLocal, mapping, node, offset, oldOffset, options)\n else\n return newLocal ? new DecorationSet(newLocal.sort(byPos)) : empty\n }\n\n // :: (Node, [Decoration]) → DecorationSet\n // Add the given array of decorations to the ones in the set,\n // producing a new set. Needs access to the current document to\n // create the appropriate tree structure.\n add(doc, decorations) {\n if (!decorations.length) return this\n if (this == empty) return DecorationSet.create(doc, decorations)\n return this.addInner(doc, decorations, 0)\n }\n\n addInner(doc, decorations, offset) {\n let children, childIndex = 0\n doc.forEach((childNode, childOffset) => {\n let baseOffset = childOffset + offset, found\n if (!(found = takeSpansForNode(decorations, childNode, baseOffset))) return\n\n if (!children) children = this.children.slice()\n while (childIndex < children.length && children[childIndex] < childOffset) childIndex += 3\n if (children[childIndex] == childOffset)\n children[childIndex + 2] = children[childIndex + 2].addInner(childNode, found, baseOffset + 1)\n else\n children.splice(childIndex, 0, childOffset, childOffset + childNode.nodeSize, buildTree(found, childNode, baseOffset + 1, noSpec))\n childIndex += 3\n })\n\n let local = moveSpans(childIndex ? withoutNulls(decorations) : decorations, -offset)\n return new DecorationSet(local.length ? this.local.concat(local).sort(byPos) : this.local,\n children || this.children)\n }\n\n // :: ([Decoration]) → DecorationSet\n // Create a new set that contains the decorations in this set, minus\n // the ones in the given array.\n remove(decorations) {\n if (decorations.length == 0 || this == empty) return this\n return this.removeInner(decorations, 0)\n }\n\n removeInner(decorations, offset) {\n let children = this.children, local = this.local\n for (let i = 0; i < children.length; i += 3) {\n let found, from = children[i] + offset, to = children[i + 1] + offset\n for (let j = 0, span; j < decorations.length; j++) if (span = decorations[j]) {\n if (span.from > from && span.to < to) {\n decorations[j] = null\n ;(found || (found = [])).push(span)\n }\n }\n if (!found) continue\n if (children == this.children) children = this.children.slice()\n let removed = children[i + 2].removeInner(found, from + 1)\n if (removed != empty) {\n children[i + 2] = removed\n } else {\n children.splice(i, 3)\n i -= 3\n }\n }\n if (local.length) for (let i = 0, span; i < decorations.length; i++) if (span = decorations[i]) {\n for (let j = 0; j < local.length; j++) if (local[j].type.eq(span.type)) {\n if (local == this.local) local = this.local.slice()\n local.splice(j--, 1)\n }\n }\n if (children == this.children && local == this.local) return this\n return local.length || children.length ? new DecorationSet(local, children) : empty\n }\n\n forChild(offset, node) {\n if (this == empty) return this\n if (node.isLeaf) return DecorationSet.empty\n\n let child, local\n for (let i = 0; i < this.children.length; i += 3) if (this.children[i] >= offset) {\n if (this.children[i] == offset) child = this.children[i + 2]\n break\n }\n let start = offset + 1, end = start + node.content.size\n for (let i = 0; i < this.local.length; i++) {\n let dec = this.local[i]\n if (dec.from < end && dec.to > start && (dec.type instanceof InlineType)) {\n let from = Math.max(start, dec.from) - start, to = Math.min(end, dec.to) - start\n if (from < to) (local || (local = [])).push(dec.copy(from, to))\n }\n }\n if (local) {\n let localSet = new DecorationSet(local.sort(byPos))\n return child ? new DecorationGroup([localSet, child]) : localSet\n }\n return child || empty\n }\n\n eq(other) {\n if (this == other) return true\n if (!(other instanceof DecorationSet) ||\n this.local.length != other.local.length ||\n this.children.length != other.children.length) return false\n for (let i = 0; i < this.local.length; i++)\n if (!this.local[i].eq(other.local[i])) return false\n for (let i = 0; i < this.children.length; i += 3)\n if (this.children[i] != other.children[i] ||\n this.children[i + 1] != other.children[i + 1] ||\n !this.children[i + 2].eq(other.children[i + 2])) return false\n return true\n }\n\n locals(node) {\n return removeOverlap(this.localsInner(node))\n }\n\n localsInner(node) {\n if (this == empty) return none\n if (node.inlineContent || !this.local.some(InlineType.is)) return this.local\n let result = []\n for (let i = 0; i < this.local.length; i++) {\n if (!(this.local[i].type instanceof InlineType))\n result.push(this.local[i])\n }\n return result\n }\n}\n\nconst empty = new DecorationSet()\n\n// :: DecorationSet\n// The empty set of decorations.\nDecorationSet.empty = empty\n\nDecorationSet.removeOverlap = removeOverlap\n\n// :- An abstraction that allows the code dealing with decorations to\n// treat multiple DecorationSet objects as if it were a single object\n// with (a subset of) the same interface.\nclass DecorationGroup {\n constructor(members) {\n this.members = members\n }\n\n forChild(offset, child) {\n if (child.isLeaf) return DecorationSet.empty\n let found = []\n for (let i = 0; i < this.members.length; i++) {\n let result = this.members[i].forChild(offset, child)\n if (result == empty) continue\n if (result instanceof DecorationGroup) found = found.concat(result.members)\n else found.push(result)\n }\n return DecorationGroup.from(found)\n }\n\n eq(other) {\n if (!(other instanceof DecorationGroup) ||\n other.members.length != this.members.length) return false\n for (let i = 0; i < this.members.length; i++)\n if (!this.members[i].eq(other.members[i])) return false\n return true\n }\n\n locals(node) {\n let result, sorted = true\n for (let i = 0; i < this.members.length; i++) {\n let locals = this.members[i].localsInner(node)\n if (!locals.length) continue\n if (!result) {\n result = locals\n } else {\n if (sorted) {\n result = result.slice()\n sorted = false\n }\n for (let j = 0; j < locals.length; j++) result.push(locals[j])\n }\n }\n return result ? removeOverlap(sorted ? result : result.sort(byPos)) : none\n }\n\n // : ([DecorationSet]) → union\n // Create a group for the given array of decoration sets, or return\n // a single set when possible.\n static from(members) {\n switch (members.length) {\n case 0: return empty\n case 1: return members[0]\n default: return new DecorationGroup(members)\n }\n }\n}\n\nfunction mapChildren(oldChildren, newLocal, mapping, node, offset, oldOffset, options) {\n let children = oldChildren.slice()\n\n // Mark the children that are directly touched by changes, and\n // move those that are after the changes.\n let shift = (oldStart, oldEnd, newStart, newEnd) => {\n for (let i = 0; i < children.length; i += 3) {\n let end = children[i + 1], dSize\n if (end == -1 || oldStart > end + oldOffset) continue\n if (oldEnd >= children[i] + oldOffset) {\n children[i + 1] = -1\n } else if (dSize = (newEnd - newStart) - (oldEnd - oldStart) + (oldOffset - offset)) {\n children[i] += dSize\n children[i + 1] += dSize\n }\n }\n }\n for (let i = 0; i < mapping.maps.length; i++) mapping.maps[i].forEach(shift)\n\n // Find the child nodes that still correspond to a single node,\n // recursively call mapInner on them and update their positions.\n let mustRebuild = false\n for (let i = 0; i < children.length; i += 3) if (children[i + 1] == -1) { // Touched nodes\n let from = mapping.map(children[i] + oldOffset), fromLocal = from - offset\n if (fromLocal < 0 || fromLocal >= node.content.size) {\n mustRebuild = true\n continue\n }\n // Must read oldChildren because children was tagged with -1\n let to = mapping.map(oldChildren[i + 1] + oldOffset, -1), toLocal = to - offset\n let {index, offset: childOffset} = node.content.findIndex(fromLocal)\n let childNode = node.maybeChild(index)\n if (childNode && childOffset == fromLocal && childOffset + childNode.nodeSize == toLocal) {\n let mapped = children[i + 2].mapInner(mapping, childNode, from + 1, children[i] + oldOffset + 1, options)\n if (mapped != empty) {\n children[i] = fromLocal\n children[i + 1] = toLocal\n children[i + 2] = mapped\n } else {\n children[i + 1] = -2\n mustRebuild = true\n }\n } else {\n mustRebuild = true\n }\n }\n\n // Remaining children must be collected and rebuilt into the appropriate structure\n if (mustRebuild) {\n let decorations = mapAndGatherRemainingDecorations(children, oldChildren, newLocal || [], mapping,\n offset, oldOffset, options)\n let built = buildTree(decorations, node, 0, options)\n newLocal = built.local\n for (let i = 0; i < children.length; i += 3) if (children[i + 1] < 0) {\n children.splice(i, 3)\n i -= 3\n }\n for (let i = 0, j = 0; i < built.children.length; i += 3) {\n let from = built.children[i]\n while (j < children.length && children[j] < from) j += 3\n children.splice(j, 0, built.children[i], built.children[i + 1], built.children[i + 2])\n }\n }\n\n return new DecorationSet(newLocal && newLocal.sort(byPos), children)\n}\n\nfunction moveSpans(spans, offset) {\n if (!offset || !spans.length) return spans\n let result = []\n for (let i = 0; i < spans.length; i++) {\n let span = spans[i]\n result.push(new Decoration(span.from + offset, span.to + offset, span.type))\n }\n return result\n}\n\nfunction mapAndGatherRemainingDecorations(children, oldChildren, decorations, mapping, offset, oldOffset, options) {\n // Gather all decorations from the remaining marked children\n function gather(set, oldOffset) {\n for (let i = 0; i < set.local.length; i++) {\n let mapped = set.local[i].map(mapping, offset, oldOffset)\n if (mapped) decorations.push(mapped)\n else if (options.onRemove) options.onRemove(set.local[i].spec)\n }\n for (let i = 0; i < set.children.length; i += 3)\n gather(set.children[i + 2], set.children[i] + oldOffset + 1)\n }\n for (let i = 0; i < children.length; i += 3) if (children[i + 1] == -1)\n gather(children[i + 2], oldChildren[i] + oldOffset + 1)\n\n return decorations\n}\n\nfunction takeSpansForNode(spans, node, offset) {\n if (node.isLeaf) return null\n let end = offset + node.nodeSize, found = null\n for (let i = 0, span; i < spans.length; i++) {\n if ((span = spans[i]) && span.from > offset && span.to < end) {\n ;(found || (found = [])).push(span)\n spans[i] = null\n }\n }\n return found\n}\n\nfunction withoutNulls(array) {\n let result = []\n for (let i = 0; i < array.length; i++)\n if (array[i] != null) result.push(array[i])\n return result\n}\n\n// : ([Decoration], Node, number) → DecorationSet\n// Build up a tree that corresponds to a set of decorations. `offset`\n// is a base offset that should be subtractet from the `from` and `to`\n// positions in the spans (so that we don't have to allocate new spans\n// for recursive calls).\nfunction buildTree(spans, node, offset, options) {\n let children = [], hasNulls = false\n node.forEach((childNode, localStart) => {\n let found = takeSpansForNode(spans, childNode, localStart + offset)\n if (found) {\n hasNulls = true\n let subtree = buildTree(found, childNode, offset + localStart + 1, options)\n if (subtree != empty)\n children.push(localStart, localStart + childNode.nodeSize, subtree)\n }\n })\n let locals = moveSpans(hasNulls ? withoutNulls(spans) : spans, -offset).sort(byPos)\n for (let i = 0; i < locals.length; i++) if (!locals[i].type.valid(node, locals[i])) {\n if (options.onRemove) options.onRemove(locals[i].spec)\n locals.splice(i--, 1)\n }\n return locals.length || children.length ? new DecorationSet(locals, children) : empty\n}\n\n// : (Decoration, Decoration) → number\n// Used to sort decorations so that ones with a low start position\n// come first, and within a set with the same start position, those\n// with an smaller end position come first.\nfunction byPos(a, b) {\n return a.from - b.from || a.to - b.to\n}\n\n// : ([Decoration]) → [Decoration]\n// Scan a sorted array of decorations for partially overlapping spans,\n// and split those so that only fully overlapping spans are left (to\n// make subsequent rendering easier). Will return the input array if\n// no partially overlapping spans are found (the common case).\nfunction removeOverlap(spans) {\n let working = spans\n for (let i = 0; i < working.length - 1; i++) {\n let span = working[i]\n if (span.from != span.to) for (let j = i + 1; j < working.length; j++) {\n let next = working[j]\n if (next.from == span.from) {\n if (next.to != span.to) {\n if (working == spans) working = spans.slice()\n // Followed by a partially overlapping larger span. Split that\n // span.\n working[j] = next.copy(next.from, span.to)\n insertAhead(working, j + 1, next.copy(span.to, next.to))\n }\n continue\n } else {\n if (next.from < span.to) {\n if (working == spans) working = spans.slice()\n // The end of this one overlaps with a subsequent span. Split\n // this one.\n working[i] = span.copy(span.from, next.from)\n insertAhead(working, j, span.copy(next.from, span.to))\n }\n break\n }\n }\n }\n return working\n}\n\nfunction insertAhead(array, i, deco) {\n while (i < array.length && byPos(deco, array[i]) > 0) i++\n array.splice(i, 0, deco)\n}\n\n// : (EditorView) → union\n// Get the decorations associated with the current props of a view.\nexport function viewDecorations(view) {\n let found = []\n view.someProp(\"decorations\", f => {\n let result = f(view.state)\n if (result && result != empty) found.push(result)\n })\n if (view.cursorWrapper)\n found.push(DecorationSet.create(view.state.doc, [view.cursorWrapper.deco]))\n return DecorationGroup.from(found)\n}\n","import {NodeSelection} from \"prosemirror-state\"\n\nimport {scrollRectIntoView, posAtCoords, coordsAtPos, endOfTextblock, storeScrollPos,\n resetScrollPos, focusPreventScroll} from \"./domcoords\"\nimport {docViewDesc} from \"./viewdesc\"\nimport {initInput, destroyInput, dispatchEvent, ensureListeners} from \"./input\"\nimport {selectionToDOM, anchorInRightPlace, syncNodeSelection} from \"./selection\"\nimport {Decoration, viewDecorations} from \"./decoration\"\nimport browser from \"./browser\"\n\nexport {Decoration, DecorationSet} from \"./decoration\"\n\n// Exported for testing\nexport {serializeForClipboard as __serializeForClipboard, parseFromClipboard as __parseFromClipboard} from \"./clipboard\"\nexport {endComposition as __endComposition} from \"./input\"\n\n// ::- An editor view manages the DOM structure that represents an\n// editable document. Its state and behavior are determined by its\n// [props](#view.DirectEditorProps).\nexport class EditorView {\n // :: (?union, DirectEditorProps)\n // Create a view. `place` may be a DOM node that the editor should\n // be appended to, a function that will place it into the document,\n // or an object whose `mount` property holds the node to use as the\n // document container. If it is `null`, the editor will not be added\n // to the document.\n constructor(place, props) {\n this._props = props\n // :: EditorState\n // The view's current [state](#state.EditorState).\n this.state = props.state\n\n this.dispatch = this.dispatch.bind(this)\n\n this._root = null\n this.focused = false\n\n // :: dom.Element\n // An editable DOM node containing the document. (You probably\n // should not directly interfere with its content.)\n this.dom = (place && place.mount) || document.createElement(\"div\")\n if (place) {\n if (place.appendChild) place.appendChild(this.dom)\n else if (place.apply) place(this.dom)\n else if (place.mount) this.mounted = true\n }\n\n // :: bool\n // Indicates whether the editor is currently [editable](#view.EditorProps.editable).\n this.editable = getEditable(this)\n this.markCursor = null\n this.cursorWrapper = null\n updateCursorWrapper(this)\n this.nodeViews = buildNodeViews(this)\n this.docView = docViewDesc(this.state.doc, computeDocDeco(this), viewDecorations(this), this.dom, this)\n\n this.lastSelectedViewDesc = null\n // :: ?{slice: Slice, move: bool}\n // When editor content is being dragged, this object contains\n // information about the dragged slice and whether it is being\n // copied or moved. At any other time, it is null.\n this.dragging = null\n\n initInput(this)\n\n this.pluginViews = []\n this.updatePluginViews()\n }\n\n // composing:: boolean\n // Holds `true` when a\n // [composition](https://developer.mozilla.org/en-US/docs/Mozilla/IME_handling_guide)\n // is active.\n\n // :: DirectEditorProps\n // The view's current [props](#view.EditorProps).\n get props() {\n if (this._props.state != this.state) {\n let prev = this._props\n this._props = {}\n for (let name in prev) this._props[name] = prev[name]\n this._props.state = this.state\n }\n return this._props\n }\n\n // :: (DirectEditorProps)\n // Update the view's props. Will immediately cause an update to\n // the DOM.\n update(props) {\n if (props.handleDOMEvents != this._props.handleDOMEvents) ensureListeners(this)\n this._props = props\n this.updateStateInner(props.state, true)\n }\n\n // :: (DirectEditorProps)\n // Update the view by updating existing props object with the object\n // given as argument. Equivalent to `view.update(Object.assign({},\n // view.props, props))`.\n setProps(props) {\n let updated = {}\n for (let name in this._props) updated[name] = this._props[name]\n updated.state = this.state\n for (let name in props) updated[name] = props[name]\n this.update(updated)\n }\n\n // :: (EditorState)\n // Update the editor's `state` prop, without touching any of the\n // other props.\n updateState(state) {\n this.updateStateInner(state, this.state.plugins != state.plugins)\n }\n\n updateStateInner(state, reconfigured) {\n let prev = this.state, redraw = false\n this.state = state\n if (reconfigured) {\n let nodeViews = buildNodeViews(this)\n if (changedNodeViews(nodeViews, this.nodeViews)) {\n this.nodeViews = nodeViews\n redraw = true\n }\n ensureListeners(this)\n }\n\n this.editable = getEditable(this)\n updateCursorWrapper(this)\n let innerDeco = viewDecorations(this), outerDeco = computeDocDeco(this)\n\n let scroll = reconfigured ? \"reset\"\n : state.scrollToSelection > prev.scrollToSelection ? \"to selection\" : \"preserve\"\n let updateDoc = redraw || !this.docView.matchesNode(state.doc, outerDeco, innerDeco)\n let updateSel = updateDoc || !state.selection.eq(prev.selection)\n let oldScrollPos = scroll == \"preserve\" && updateSel && this.dom.style.overflowAnchor == null && storeScrollPos(this)\n\n if (updateSel) {\n this.domObserver.stop()\n // Work around an issue in Chrome, IE, and Edge where changing\n // the DOM around an active selection puts it into a broken\n // state where the thing the user sees differs from the\n // selection reported by the Selection object (#710, #973,\n // #1011, #1013).\n let forceSelUpdate = updateDoc && (browser.ie || browser.chrome) &&\n !prev.selection.empty && !state.selection.empty && selectionContextChanged(prev.selection, state.selection)\n if (updateDoc) {\n if (redraw || !this.docView.update(state.doc, outerDeco, innerDeco, this)) {\n this.docView.destroy()\n this.docView = docViewDesc(state.doc, outerDeco, innerDeco, this.dom, this)\n }\n }\n // Work around for an issue where an update arriving right between\n // a DOM selection change and the \"selectionchange\" event for it\n // can cause a spurious DOM selection update, disrupting mouse\n // drag selection.\n if (forceSelUpdate ||\n !(this.mouseDown && this.domObserver.currentSelection.eq(this.root.getSelection()) && anchorInRightPlace(this))) {\n selectionToDOM(this, forceSelUpdate)\n } else {\n syncNodeSelection(this, state.selection)\n this.domObserver.setCurSelection()\n }\n this.domObserver.start()\n }\n\n this.updatePluginViews(prev)\n\n if (scroll == \"reset\") {\n this.dom.scrollTop = 0\n } else if (scroll == \"to selection\") {\n let startDOM = this.root.getSelection().focusNode\n if (this.someProp(\"handleScrollToSelection\", f => f(this)))\n {} // Handled\n else if (state.selection instanceof NodeSelection)\n scrollRectIntoView(this, this.docView.domAfterPos(state.selection.from).getBoundingClientRect(), startDOM)\n else\n scrollRectIntoView(this, this.coordsAtPos(state.selection.head), startDOM)\n } else if (oldScrollPos) {\n resetScrollPos(oldScrollPos)\n }\n }\n\n destroyPluginViews() {\n let view\n while (view = this.pluginViews.pop()) if (view.destroy) view.destroy()\n }\n\n updatePluginViews(prevState) {\n if (!prevState || prevState.plugins != this.state.plugins) {\n this.destroyPluginViews()\n for (let i = 0; i < this.state.plugins.length; i++) {\n let plugin = this.state.plugins[i]\n if (plugin.spec.view) this.pluginViews.push(plugin.spec.view(this))\n }\n } else {\n for (let i = 0; i < this.pluginViews.length; i++) {\n let pluginView = this.pluginViews[i]\n if (pluginView.update) pluginView.update(this, prevState)\n }\n }\n }\n\n // :: (string, ?(prop: *) → *) → *\n // Goes over the values of a prop, first those provided directly,\n // then those from plugins (in order), and calls `f` every time a\n // non-undefined value is found. When `f` returns a truthy value,\n // that is immediately returned. When `f` isn't provided, it is\n // treated as the identity function (the prop value is returned\n // directly).\n someProp(propName, f) {\n let prop = this._props && this._props[propName], value\n if (prop != null && (value = f ? f(prop) : prop)) return value\n let plugins = this.state.plugins\n if (plugins) for (let i = 0; i < plugins.length; i++) {\n let prop = plugins[i].props[propName]\n if (prop != null && (value = f ? f(prop) : prop)) return value\n }\n }\n\n // :: () → bool\n // Query whether the view has focus.\n hasFocus() {\n return this.root.activeElement == this.dom\n }\n\n // :: ()\n // Focus the editor.\n focus() {\n this.domObserver.stop()\n if (this.editable) focusPreventScroll(this.dom)\n selectionToDOM(this)\n this.domObserver.start()\n }\n\n // :: union\n // Get the document root in which the editor exists. This will\n // usually be the top-level `document`, but might be a [shadow\n // DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Shadow_DOM)\n // root if the editor is inside one.\n get root() {\n let cached = this._root\n if (cached == null) for (let search = this.dom.parentNode; search; search = search.parentNode) {\n if (search.nodeType == 9 || (search.nodeType == 11 && search.host)) {\n if (!search.getSelection) Object.getPrototypeOf(search).getSelection = () => document.getSelection()\n return this._root = search\n }\n }\n return cached || document\n }\n\n // :: ({left: number, top: number}) → ?{pos: number, inside: number}\n // Given a pair of viewport coordinates, return the document\n // position that corresponds to them. May return null if the given\n // coordinates aren't inside of the editor. When an object is\n // returned, its `pos` property is the position nearest to the\n // coordinates, and its `inside` property holds the position of the\n // inner node that the position falls inside of, or -1 if it is at\n // the top level, not in any node.\n posAtCoords(coords) {\n return posAtCoords(this, coords)\n }\n\n // :: (number) → {left: number, right: number, top: number, bottom: number}\n // Returns the viewport rectangle at a given document position. `left`\n // and `right` will be the same number, as this returns a flat\n // cursor-ish rectangle.\n coordsAtPos(pos) {\n return coordsAtPos(this, pos)\n }\n\n // :: (number) → {node: dom.Node, offset: number}\n // Find the DOM position that corresponds to the given document\n // position. Note that you should **not** mutate the editor's\n // internal DOM, only inspect it (and even that is usually not\n // necessary).\n domAtPos(pos) {\n return this.docView.domFromPos(pos)\n }\n\n // :: (number) → ?dom.Node\n // Find the DOM node that represents the document node after the\n // given position. May return `null` when the position doesn't point\n // in front of a node or if the node is inside an opaque node view.\n //\n // This is intended to be able to call things like\n // `getBoundingClientRect` on that DOM node. Do **not** mutate the\n // editor DOM directly, or add styling this way, since that will be\n // immediately overriden by the editor as it redraws the node.\n nodeDOM(pos) {\n let desc = this.docView.descAt(pos)\n return desc ? desc.nodeDOM : null\n }\n\n // :: (dom.Node, number, ?number) → number\n // Find the document position that corresponds to a given DOM\n // position. (Whenever possible, it is preferable to inspect the\n // document structure directly, rather than poking around in the\n // DOM, but sometimes—for example when interpreting an event\n // target—you don't have a choice.)\n //\n // The `bias` parameter can be used to influence which side of a DOM\n // node to use when the position is inside a leaf node.\n posAtDOM(node, offset, bias = -1) {\n let pos = this.docView.posFromDOM(node, offset, bias)\n if (pos == null) throw new RangeError(\"DOM position not inside the editor\")\n return pos\n }\n\n // :: (union<\"up\", \"down\", \"left\", \"right\", \"forward\", \"backward\">, ?EditorState) → bool\n // Find out whether the selection is at the end of a textblock when\n // moving in a given direction. When, for example, given `\"left\"`,\n // it will return true if moving left from the current cursor\n // position would leave that position's parent textblock. Will apply\n // to the view's current state by default, but it is possible to\n // pass a different state.\n endOfTextblock(dir, state) {\n return endOfTextblock(this, state || this.state, dir)\n }\n\n // :: ()\n // Removes the editor from the DOM and destroys all [node\n // views](#view.NodeView).\n destroy() {\n if (!this.docView) return\n destroyInput(this)\n this.destroyPluginViews()\n if (this.mounted) {\n this.docView.update(this.state.doc, [], viewDecorations(this), this)\n this.dom.textContent = \"\"\n } else if (this.dom.parentNode) {\n this.dom.parentNode.removeChild(this.dom)\n }\n this.docView.destroy()\n this.docView = null\n }\n\n // Used for testing.\n dispatchEvent(event) {\n return dispatchEvent(this, event)\n }\n\n // :: (Transaction)\n // Dispatch a transaction. Will call\n // [`dispatchTransaction`](#view.DirectEditorProps.dispatchTransaction)\n // when given, and otherwise defaults to applying the transaction to\n // the current state and calling\n // [`updateState`](#view.EditorView.updateState) with the result.\n // This method is bound to the view instance, so that it can be\n // easily passed around.\n dispatch(tr) {\n let dispatchTransaction = this._props.dispatchTransaction\n if (dispatchTransaction) dispatchTransaction.call(this, tr)\n else this.updateState(this.state.apply(tr))\n }\n}\n\nfunction computeDocDeco(view) {\n let attrs = Object.create(null)\n attrs.class = \"ProseMirror\"\n attrs.contenteditable = String(view.editable)\n\n view.someProp(\"attributes\", value => {\n if (typeof value == \"function\") value = value(view.state)\n if (value) for (let attr in value) {\n if (attr == \"class\")\n attrs.class += \" \" + value[attr]\n else if (!attrs[attr] && attr != \"contenteditable\" && attr != \"nodeName\")\n attrs[attr] = String(value[attr])\n }\n })\n\n return [Decoration.node(0, view.state.doc.content.size, attrs)]\n}\n\nfunction updateCursorWrapper(view) {\n let {$head, $anchor, visible} = view.state.selection\n if (view.markCursor) {\n let dom = document.createElement(\"img\")\n dom.setAttribute(\"mark-placeholder\", \"true\")\n view.cursorWrapper = {dom, deco: Decoration.widget($head.pos, dom, {raw: true, marks: view.markCursor})}\n } else if (visible || $head.pos != $anchor.pos) {\n view.cursorWrapper = null\n } else {\n let dom\n if (!view.cursorWrapper || view.cursorWrapper.dom.childNodes.length) {\n dom = document.createElement(\"div\")\n dom.style.position = \"absolute\"\n dom.style.left = \"-100000px\"\n } else if (view.cursorWrapper.deco.pos != $head.pos) {\n dom = view.cursorWrapper.dom\n }\n if (dom)\n view.cursorWrapper = {dom, deco: Decoration.widget($head.pos, dom, {raw: true})}\n }\n}\n\nfunction getEditable(view) {\n return !view.someProp(\"editable\", value => value(view.state) === false)\n}\n\nfunction selectionContextChanged(sel1, sel2) {\n let depth = Math.min(sel1.$anchor.sharedDepth(sel1.head), sel2.$anchor.sharedDepth(sel2.head))\n return sel1.$anchor.node(depth) != sel2.$anchor.node(depth)\n}\n\nfunction buildNodeViews(view) {\n let result = {}\n view.someProp(\"nodeViews\", obj => {\n for (let prop in obj) if (!Object.prototype.hasOwnProperty.call(result, prop))\n result[prop] = obj[prop]\n })\n return result\n}\n\nfunction changedNodeViews(a, b) {\n let nA = 0, nB = 0\n for (let prop in a) {\n if (a[prop] != b[prop]) return true\n nA++\n }\n for (let _ in b) nB++\n return nA != nB\n}\n\n// EditorProps:: interface\n//\n// Props are configuration values that can be passed to an editor view\n// or included in a plugin. This interface lists the supported props.\n//\n// The various event-handling functions may all return `true` to\n// indicate that they handled the given event. The view will then take\n// care to call `preventDefault` on the event, except with\n// `handleDOMEvents`, where the handler itself is responsible for that.\n//\n// How a prop is resolved depends on the prop. Handler functions are\n// called one at a time, starting with the base props and then\n// searching through the plugins (in order of appearance) until one of\n// them returns true. For some props, the first plugin that yields a\n// value gets precedence.\n//\n// handleDOMEvents:: ?Object<(view: EditorView, event: dom.Event) → bool>\n// Can be an object mapping DOM event type names to functions that\n// handle them. Such functions will be called before any handling\n// ProseMirror does of events fired on the editable DOM element.\n// Contrary to the other event handling props, when returning true\n// from such a function, you are responsible for calling\n// `preventDefault` yourself (or not, if you want to allow the\n// default behavior).\n//\n// handleKeyDown:: ?(view: EditorView, event: dom.KeyboardEvent) → bool\n// Called when the editor receives a `keydown` event.\n//\n// handleKeyPress:: ?(view: EditorView, event: dom.KeyboardEvent) → bool\n// Handler for `keypress` events.\n//\n// handleTextInput:: ?(view: EditorView, from: number, to: number, text: string) → bool\n// Whenever the user directly input text, this handler is called\n// before the input is applied. If it returns `true`, the default\n// behavior of actually inserting the text is suppressed.\n//\n// handleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool\n// Called for each node around a click, from the inside out. The\n// `direct` flag will be true for the inner node.\n//\n// handleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool\n// Called when the editor is clicked, after `handleClickOn` handlers\n// have been called.\n//\n// handleDoubleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool\n// Called for each node around a double click.\n//\n// handleDoubleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool\n// Called when the editor is double-clicked, after `handleDoubleClickOn`.\n//\n// handleTripleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool\n// Called for each node around a triple click.\n//\n// handleTripleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool\n// Called when the editor is triple-clicked, after `handleTripleClickOn`.\n//\n// handlePaste:: ?(view: EditorView, event: dom.Event, slice: Slice) → bool\n// Can be used to override the behavior of pasting. `slice` is the\n// pasted content parsed by the editor, but you can directly access\n// the event to get at the raw content.\n//\n// handleDrop:: ?(view: EditorView, event: dom.Event, slice: Slice, moved: bool) → bool\n// Called when something is dropped on the editor. `moved` will be\n// true if this drop moves from the current selection (which should\n// thus be deleted).\n//\n// handleScrollToSelection:: ?(view: EditorView) → bool\n// Called when the view, after updating its state, tries to scroll\n// the selection into view. A handler function may return false to\n// indicate that it did not handle the scrolling and further\n// handlers or the default behavior should be tried.\n//\n// createSelectionBetween:: ?(view: EditorView, anchor: ResolvedPos, head: ResolvedPos) → ?Selection\n// Can be used to override the way a selection is created when\n// reading a DOM selection between the given anchor and head.\n//\n// domParser:: ?DOMParser\n// The [parser](#model.DOMParser) to use when reading editor changes\n// from the DOM. Defaults to calling\n// [`DOMParser.fromSchema`](#model.DOMParser^fromSchema) on the\n// editor's schema.\n//\n// transformPastedHTML:: ?(html: string) → string\n// Can be used to transform pasted HTML text, _before_ it is parsed,\n// for example to clean it up.\n//\n// clipboardParser:: ?DOMParser\n// The [parser](#model.DOMParser) to use when reading content from\n// the clipboard. When not given, the value of the\n// [`domParser`](#view.EditorProps.domParser) prop is used.\n//\n// transformPastedText:: ?(text: string) → string\n// Transform pasted plain text.\n//\n// clipboardTextParser:: ?(text: string, $context: ResolvedPos) → Slice\n// A function to parse text from the clipboard into a document\n// slice. Called after\n// [`transformPastedText`](#view.EditorProps.transformPastedText).\n// The default behavior is to split the text into lines, wrap them\n// in `

    ` tags, and call\n// [`clipboardParser`](#view.EditorProps.clipboardParser) on it.\n//\n// transformPasted:: ?(Slice) → Slice\n// Can be used to transform pasted content before it is applied to\n// the document.\n//\n// nodeViews:: ?Object<(node: Node, view: EditorView, getPos: () → number, decorations: [Decoration]) → NodeView>\n// Allows you to pass custom rendering and behavior logic for nodes\n// and marks. Should map node and mark names to constructor\n// functions that produce a [`NodeView`](#view.NodeView) object\n// implementing the node's display behavior. For nodes, the third\n// argument `getPos` is a function that can be called to get the\n// node's current position, which can be useful when creating\n// transactions to update it. For marks, the third argument is a\n// boolean that indicates whether the mark's content is inline.\n//\n// `decorations` is an array of node or inline decorations that are\n// active around the node. They are automatically drawn in the\n// normal way, and you will usually just want to ignore this, but\n// they can also be used as a way to provide context information to\n// the node view without adding it to the document itself.\n//\n// clipboardSerializer:: ?DOMSerializer\n// The DOM serializer to use when putting content onto the\n// clipboard. If not given, the result of\n// [`DOMSerializer.fromSchema`](#model.DOMSerializer^fromSchema)\n// will be used.\n//\n// clipboardTextSerializer:: ?(Slice) → string\n// A function that will be called to get the text for the current\n// selection when copying text to the clipboard. By default, the\n// editor will use [`textBetween`](#model.Node.textBetween) on the\n// selected range.\n//\n// decorations:: ?(state: EditorState) → ?DecorationSet\n// A set of [document decorations](#view.Decoration) to show in the\n// view.\n//\n// editable:: ?(state: EditorState) → bool\n// When this returns false, the content of the view is not directly\n// editable.\n//\n// attributes:: ?union, (EditorState) → ?Object>\n// Control the DOM attributes of the editable element. May be either\n// an object or a function going from an editor state to an object.\n// By default, the element will get a class `\"ProseMirror\"`, and\n// will have its `contentEditable` attribute determined by the\n// [`editable` prop](#view.EditorProps.editable). Additional classes\n// provided here will be added to the class. For other attributes,\n// the value provided first (as in\n// [`someProp`](#view.EditorView.someProp)) will be used.\n//\n// scrollThreshold:: ?union\n// Determines the distance (in pixels) between the cursor and the\n// end of the visible viewport at which point, when scrolling the\n// cursor into view, scrolling takes place. Defaults to 0.\n//\n// scrollMargin:: ?union\n// Determines the extra space (in pixels) that is left above or\n// below the cursor when it is scrolled into view. Defaults to 5.\n\n// DirectEditorProps:: interface extends EditorProps\n//\n// The props object given directly to the editor view supports two\n// fields that can't be used in plugins:\n//\n// state:: EditorState\n// The current state of the editor.\n//\n// dispatchTransaction:: ?(tr: Transaction)\n// The callback over which to send transactions (state updates)\n// produced by the view. If you specify this, you probably want to\n// make sure this ends up calling the view's\n// [`updateState`](#view.EditorView.updateState) method with a new\n// state that has the transaction\n// [applied](#state.EditorState.apply). The callback will be bound to have\n// the view instance as its `this` binding.\n"],"names":["const","let","browser","pos","box","rect","target","desc","search","j","super","this","name","i","child","next","anchor","tr","sel","move","d","result","p","prototypeAccessors","span","from","prop","dom"],"mappings":"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"} \ No newline at end of file diff --git a/packages/tiptap/node_modules/prosemirror-view/dist/index.js b/packages/tiptap/node_modules/prosemirror-view/dist/index.js new file mode 100644 index 0000000000..2a678bfdc1 --- /dev/null +++ b/packages/tiptap/node_modules/prosemirror-view/dist/index.js @@ -0,0 +1,4975 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +var prosemirrorState = require('prosemirror-state'); +var prosemirrorModel = require('prosemirror-model'); +var prosemirrorTransform = require('prosemirror-transform'); + +var result = {}; + +if (typeof navigator != "undefined" && typeof document != "undefined") { + var ie_edge = /Edge\/(\d+)/.exec(navigator.userAgent); + var ie_upto10 = /MSIE \d/.test(navigator.userAgent); + var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent); + + result.mac = /Mac/.test(navigator.platform); + var ie = result.ie = !!(ie_upto10 || ie_11up || ie_edge); + result.ie_version = ie_upto10 ? document.documentMode || 6 : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : null; + result.gecko = !ie && /gecko\/(\d+)/i.test(navigator.userAgent); + result.gecko_version = result.gecko && +(/Firefox\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1]; + var chrome = !ie && /Chrome\/(\d+)/.exec(navigator.userAgent); + result.chrome = !!chrome; + result.chrome_version = chrome && +chrome[1]; + result.ios = !ie && /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent); + result.android = /Android \d/.test(navigator.userAgent); + result.webkit = !ie && 'WebkitAppearance' in document.documentElement.style; + result.safari = /Apple Computer/.test(navigator.vendor); + result.webkit_version = result.webkit && +(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1]; +} + +var domIndex = function(node) { + for (var index = 0;; index++) { + node = node.previousSibling; + if (!node) { return index } + } +}; + +var parentNode = function(node) { + var parent = node.parentNode; + return parent && parent.nodeType == 11 ? parent.host : parent +}; + +var textRange = function(node, from, to) { + var range = document.createRange(); + range.setEnd(node, to == null ? node.nodeValue.length : to); + range.setStart(node, from || 0); + return range +}; + +// Scans forward and backward through DOM positions equivalent to the +// given one to see if the two are in the same place (i.e. after a +// text node vs at the end of that text node) +var isEquivalentPosition = function(node, off, targetNode, targetOff) { + return targetNode && (scanFor(node, off, targetNode, targetOff, -1) || + scanFor(node, off, targetNode, targetOff, 1)) +}; + +var atomElements = /^(img|br|input|textarea|hr)$/i; + +function scanFor(node, off, targetNode, targetOff, dir) { + for (;;) { + if (node == targetNode && off == targetOff) { return true } + if (off == (dir < 0 ? 0 : nodeSize(node))) { + var parent = node.parentNode; + if (parent.nodeType != 1 || hasBlockDesc(node) || atomElements.test(node.nodeName) || node.contentEditable == "false") + { return false } + off = domIndex(node) + (dir < 0 ? 0 : 1); + node = parent; + } else if (node.nodeType == 1) { + node = node.childNodes[off + (dir < 0 ? -1 : 0)]; + off = dir < 0 ? nodeSize(node) : 0; + } else { + return false + } + } +} + +function nodeSize(node) { + return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length +} + +function hasBlockDesc(dom) { + var desc; + for (var cur = dom; cur; cur = cur.parentNode) { if (desc = cur.pmViewDesc) { break } } + return desc && desc.node && desc.node.isBlock && (desc.dom == dom || desc.contentDOM == dom) +} + +// Work around Chrome issue https://bugs.chromium.org/p/chromium/issues/detail?id=447523 +// (isCollapsed inappropriately returns true in shadow dom) +var selectionCollapsed = function(domSel) { + var collapsed = domSel.isCollapsed; + if (collapsed && result.chrome && domSel.rangeCount && !domSel.getRangeAt(0).collapsed) + { collapsed = false; } + return collapsed +}; + +function keyEvent(keyCode, key) { + var event = document.createEvent("Event"); + event.initEvent("keydown", true, true); + event.keyCode = keyCode; + event.key = event.code = key; + return event +} + +function windowRect(win) { + return {left: 0, right: win.innerWidth, + top: 0, bottom: win.innerHeight} +} + +function getSide(value, side) { + return typeof value == "number" ? value : value[side] +} + +function scrollRectIntoView(view, rect, startDOM) { + var scrollThreshold = view.someProp("scrollThreshold") || 0, scrollMargin = view.someProp("scrollMargin") || 5; + var doc = view.dom.ownerDocument, win = doc.defaultView; + for (var parent = startDOM || view.dom;; parent = parentNode(parent)) { + if (!parent) { break } + if (parent.nodeType != 1) { continue } + var atTop = parent == doc.body || parent.nodeType != 1; + var bounding = atTop ? windowRect(win) : parent.getBoundingClientRect(); + var moveX = 0, moveY = 0; + if (rect.top < bounding.top + getSide(scrollThreshold, "top")) + { moveY = -(bounding.top - rect.top + getSide(scrollMargin, "top")); } + else if (rect.bottom > bounding.bottom - getSide(scrollThreshold, "bottom")) + { moveY = rect.bottom - bounding.bottom + getSide(scrollMargin, "bottom"); } + if (rect.left < bounding.left + getSide(scrollThreshold, "left")) + { moveX = -(bounding.left - rect.left + getSide(scrollMargin, "left")); } + else if (rect.right > bounding.right - getSide(scrollThreshold, "right")) + { moveX = rect.right - bounding.right + getSide(scrollMargin, "right"); } + if (moveX || moveY) { + if (atTop) { + win.scrollBy(moveX, moveY); + } else { + if (moveY) { parent.scrollTop += moveY; } + if (moveX) { parent.scrollLeft += moveX; } + } + } + if (atTop) { break } + } +} + +// Store the scroll position of the editor's parent nodes, along with +// the top position of an element near the top of the editor, which +// will be used to make sure the visible viewport remains stable even +// when the size of the content above changes. +function storeScrollPos(view) { + var rect = view.dom.getBoundingClientRect(), startY = Math.max(0, rect.top); + var refDOM, refTop; + for (var x = (rect.left + rect.right) / 2, y = startY + 1; + y < Math.min(innerHeight, rect.bottom); y += 5) { + var dom = view.root.elementFromPoint(x, y); + if (dom == view.dom || !view.dom.contains(dom)) { continue } + var localRect = dom.getBoundingClientRect(); + if (localRect.top >= startY - 20) { + refDOM = dom; + refTop = localRect.top; + break + } + } + return {refDOM: refDOM, refTop: refTop, stack: scrollStack(view.dom)} +} + +function scrollStack(dom) { + var stack = [], doc = dom.ownerDocument; + for (; dom; dom = parentNode(dom)) { + stack.push({dom: dom, top: dom.scrollTop, left: dom.scrollLeft}); + if (dom == doc) { break } + } + return stack +} + +// Reset the scroll position of the editor's parent nodes to that what +// it was before, when storeScrollPos was called. +function resetScrollPos(ref) { + var refDOM = ref.refDOM; + var refTop = ref.refTop; + var stack = ref.stack; + + var newRefTop = refDOM ? refDOM.getBoundingClientRect().top : 0; + restoreScrollStack(stack, newRefTop == 0 ? 0 : newRefTop - refTop); +} + +function restoreScrollStack(stack, dTop) { + for (var i = 0; i < stack.length; i++) { + var ref = stack[i]; + var dom = ref.dom; + var top = ref.top; + var left = ref.left; + if (dom.scrollTop != top + dTop) { dom.scrollTop = top + dTop; } + if (dom.scrollLeft != left) { dom.scrollLeft = left; } + } +} + +var preventScrollSupported = null; +// Feature-detects support for .focus({preventScroll: true}), and uses +// a fallback kludge when not supported. +function focusPreventScroll(dom) { + if (dom.setActive) { return dom.setActive() } // in IE + if (preventScrollSupported) { return dom.focus(preventScrollSupported) } + + var stored = scrollStack(dom); + dom.focus(preventScrollSupported == null ? { + get preventScroll() { + preventScrollSupported = {preventScroll: true}; + return true + } + } : undefined); + if (!preventScrollSupported) { + preventScrollSupported = false; + restoreScrollStack(stored, 0); + } +} + +function findOffsetInNode(node, coords) { + var closest, dxClosest = 2e8, coordsClosest, offset = 0; + var rowBot = coords.top, rowTop = coords.top; + for (var child = node.firstChild, childIndex = 0; child; child = child.nextSibling, childIndex++) { + var rects = (void 0); + if (child.nodeType == 1) { rects = child.getClientRects(); } + else if (child.nodeType == 3) { rects = textRange(child).getClientRects(); } + else { continue } + + for (var i = 0; i < rects.length; i++) { + var rect = rects[i]; + if (rect.top <= rowBot && rect.bottom >= rowTop) { + rowBot = Math.max(rect.bottom, rowBot); + rowTop = Math.min(rect.top, rowTop); + var dx = rect.left > coords.left ? rect.left - coords.left + : rect.right < coords.left ? coords.left - rect.right : 0; + if (dx < dxClosest) { + closest = child; + dxClosest = dx; + coordsClosest = dx && closest.nodeType == 3 ? {left: rect.right < coords.left ? rect.right : rect.left, top: coords.top} : coords; + if (child.nodeType == 1 && dx) + { offset = childIndex + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0); } + continue + } + } + if (!closest && (coords.left >= rect.right && coords.top >= rect.top || + coords.left >= rect.left && coords.top >= rect.bottom)) + { offset = childIndex + 1; } + } + } + if (closest && closest.nodeType == 3) { return findOffsetInText(closest, coordsClosest) } + if (!closest || (dxClosest && closest.nodeType == 1)) { return {node: node, offset: offset} } + return findOffsetInNode(closest, coordsClosest) +} + +function findOffsetInText(node, coords) { + var len = node.nodeValue.length; + var range = document.createRange(); + for (var i = 0; i < len; i++) { + range.setEnd(node, i + 1); + range.setStart(node, i); + var rect = singleRect(range, 1); + if (rect.top == rect.bottom) { continue } + if (inRect(coords, rect)) + { return {node: node, offset: i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0)} } + } + return {node: node, offset: 0} +} + +function inRect(coords, rect) { + return coords.left >= rect.left - 1 && coords.left <= rect.right + 1&& + coords.top >= rect.top - 1 && coords.top <= rect.bottom + 1 +} + +function targetKludge(dom, coords) { + var parent = dom.parentNode; + if (parent && /^li$/i.test(parent.nodeName) && coords.left < dom.getBoundingClientRect().left) + { return parent } + return dom +} + +function posFromElement(view, elt, coords) { + var ref = findOffsetInNode(elt, coords); + var node = ref.node; + var offset = ref.offset; + var bias = -1; + if (node.nodeType == 1 && !node.firstChild) { + var rect = node.getBoundingClientRect(); + bias = rect.left != rect.right && coords.left > (rect.left + rect.right) / 2 ? 1 : -1; + } + return view.docView.posFromDOM(node, offset, bias) +} + +function posFromCaret(view, node, offset, coords) { + // Browser (in caretPosition/RangeFromPoint) will agressively + // normalize towards nearby inline nodes. Since we are interested in + // positions between block nodes too, we first walk up the hierarchy + // of nodes to see if there are block nodes that the coordinates + // fall outside of. If so, we take the position before/after that + // block. If not, we call `posFromDOM` on the raw node/offset. + var outside = -1; + for (var cur = node;;) { + if (cur == view.dom) { break } + var desc = view.docView.nearestDesc(cur, true); + if (!desc) { return null } + if (desc.node.isBlock && desc.parent) { + var rect = desc.dom.getBoundingClientRect(); + if (rect.left > coords.left || rect.top > coords.top) { outside = desc.posBefore; } + else if (rect.right < coords.left || rect.bottom < coords.top) { outside = desc.posAfter; } + else { break } + } + cur = desc.dom.parentNode; + } + return outside > -1 ? outside : view.docView.posFromDOM(node, offset) +} + +function elementFromPoint(element, coords, box) { + var len = element.childNodes.length; + if (len && box.top < box.bottom) { + for (var startI = Math.max(0, Math.min(len - 1, Math.floor(len * (coords.top - box.top) / (box.bottom - box.top)) - 2)), i = startI;;) { + var child = element.childNodes[i]; + if (child.nodeType == 1) { + var rects = child.getClientRects(); + for (var j = 0; j < rects.length; j++) { + var rect = rects[j]; + if (inRect(coords, rect)) { return elementFromPoint(child, coords, rect) } + } + } + if ((i = (i + 1) % len) == startI) { break } + } + } + return element +} + +// Given an x,y position on the editor, get the position in the document. +function posAtCoords(view, coords) { + var assign, assign$1; + + var root = view.root, node, offset; + if (root.caretPositionFromPoint) { + try { // Firefox throws for this call in hard-to-predict circumstances (#994) + var pos$1 = root.caretPositionFromPoint(coords.left, coords.top); + if (pos$1) { ((assign = pos$1, node = assign.offsetNode, offset = assign.offset)); } + } catch (_) {} + } + if (!node && root.caretRangeFromPoint) { + var range = root.caretRangeFromPoint(coords.left, coords.top); + if (range) { ((assign$1 = range, node = assign$1.startContainer, offset = assign$1.startOffset)); } + } + + var elt = root.elementFromPoint(coords.left, coords.top + 1), pos; + if (!elt || !view.dom.contains(elt.nodeType != 1 ? elt.parentNode : elt)) { + var box = view.dom.getBoundingClientRect(); + if (!inRect(coords, box)) { return null } + elt = elementFromPoint(view.dom, coords, box); + if (!elt) { return null } + } + elt = targetKludge(elt, coords); + if (node) { + if (result.gecko && node.nodeType == 1) { + // Firefox will sometimes return offsets into nodes, which + // have no actual children, from caretPositionFromPoint (#953) + offset = Math.min(offset, node.childNodes.length); + // It'll also move the returned position before image nodes, + // even if those are behind it. + if (offset < node.childNodes.length) { + var next = node.childNodes[offset], box$1; + if (next.nodeName == "IMG" && (box$1 = next.getBoundingClientRect()).right <= coords.left && + box$1.bottom > coords.top) + { offset++; } + } + } + // Suspiciously specific kludge to work around caret*FromPoint + // never returning a position at the end of the document + if (node == view.dom && offset == node.childNodes.length - 1 && node.lastChild.nodeType == 1 && + coords.top > node.lastChild.getBoundingClientRect().bottom) + { pos = view.state.doc.content.size; } + // Ignore positions directly after a BR, since caret*FromPoint + // 'round up' positions that would be more accurately placed + // before the BR node. + else if (offset == 0 || node.nodeType != 1 || node.childNodes[offset - 1].nodeName != "BR") + { pos = posFromCaret(view, node, offset, coords); } + } + if (pos == null) { pos = posFromElement(view, elt, coords); } + + var desc = view.docView.nearestDesc(elt, true); + return {pos: pos, inside: desc ? desc.posAtStart - desc.border : -1} +} + +function singleRect(object, bias) { + var rects = object.getClientRects(); + return !rects.length ? object.getBoundingClientRect() : rects[bias < 0 ? 0 : rects.length - 1] +} + +// : (EditorView, number) → {left: number, top: number, right: number, bottom: number} +// Given a position in the document model, get a bounding box of the +// character at that position, relative to the window. +function coordsAtPos(view, pos) { + var ref = view.docView.domFromPos(pos); + var node = ref.node; + var offset = ref.offset; + + // These browsers support querying empty text ranges + if (node.nodeType == 3 && (result.chrome || result.gecko)) { + var rect = singleRect(textRange(node, offset, offset), 0); + // Firefox returns bad results (the position before the space) + // when querying a position directly after line-broken + // whitespace. Detect this situation and and kludge around it + if (result.gecko && offset && /\s/.test(node.nodeValue[offset - 1]) && offset < node.nodeValue.length) { + var rectBefore = singleRect(textRange(node, offset - 1, offset - 1), -1); + if (Math.abs(rectBefore.left - rect.left) < 1 && rectBefore.top == rect.top) { + var rectAfter = singleRect(textRange(node, offset, offset + 1), -1); + return flattenV(rectAfter, rectAfter.left < rectBefore.left) + } + } + return rect + } + + if (node.nodeType == 1 && !view.state.doc.resolve(pos).parent.inlineContent) { + // Return a horizontal line in block context + var top = true, rect$1; + if (offset < node.childNodes.length) { + var after = node.childNodes[offset]; + if (after.nodeType == 1) { rect$1 = after.getBoundingClientRect(); } + } + if (!rect$1 && offset) { + var before = node.childNodes[offset - 1]; + if (before.nodeType == 1) { rect$1 = before.getBoundingClientRect(); top = false; } + } + return flattenH(rect$1 || node.getBoundingClientRect(), top) + } + + // Not Firefox/Chrome, or not in a text node, so we have to use + // actual element/character rectangles to get a solution (this part + // is not very bidi-safe) + // + // Try the left side first, fall back to the right one if that + // doesn't work. + for (var dir = -1; dir < 2; dir += 2) { + if (dir < 0 && offset) { + var prev = (void 0), target = node.nodeType == 3 ? textRange(node, offset - 1, offset) + : (prev = node.childNodes[offset - 1]).nodeType == 3 ? textRange(prev) + : prev.nodeType == 1 && prev.nodeName != "BR" ? prev : null; // BR nodes tend to only return the rectangle before them + if (target) { + var rect$2 = singleRect(target, 1); + if (rect$2.top < rect$2.bottom) { return flattenV(rect$2, false) } + } + } else if (dir > 0 && offset < nodeSize(node)) { + var next = (void 0), target$1 = node.nodeType == 3 ? textRange(node, offset, offset + 1) + : (next = node.childNodes[offset]).nodeType == 3 ? textRange(next) + : next.nodeType == 1 ? next : null; + if (target$1) { + var rect$3 = singleRect(target$1, -1); + if (rect$3.top < rect$3.bottom) { return flattenV(rect$3, true) } + } + } + } + // All else failed, just try to get a rectangle for the target node + return flattenV(singleRect(node.nodeType == 3 ? textRange(node) : node, 0), false) +} + +function flattenV(rect, left) { + if (rect.width == 0) { return rect } + var x = left ? rect.left : rect.right; + return {top: rect.top, bottom: rect.bottom, left: x, right: x} +} + +function flattenH(rect, top) { + if (rect.height == 0) { return rect } + var y = top ? rect.top : rect.bottom; + return {top: y, bottom: y, left: rect.left, right: rect.right} +} + +function withFlushedState(view, state, f) { + var viewState = view.state, active = view.root.activeElement; + if (viewState != state) { view.updateState(state); } + if (active != view.dom) { view.focus(); } + try { + return f() + } finally { + if (viewState != state) { view.updateState(viewState); } + if (active != view.dom) { active.focus(); } + } +} + +// : (EditorView, number, number) +// Whether vertical position motion in a given direction +// from a position would leave a text block. +function endOfTextblockVertical(view, state, dir) { + var sel = state.selection; + var $pos = dir == "up" ? sel.$anchor.min(sel.$head) : sel.$anchor.max(sel.$head); + return withFlushedState(view, state, function () { + var ref = view.docView.domFromPos($pos.pos); + var dom = ref.node; + for (;;) { + var nearest = view.docView.nearestDesc(dom, true); + if (!nearest) { break } + if (nearest.node.isBlock) { dom = nearest.dom; break } + dom = nearest.dom.parentNode; + } + var coords = coordsAtPos(view, $pos.pos); + for (var child = dom.firstChild; child; child = child.nextSibling) { + var boxes = (void 0); + if (child.nodeType == 1) { boxes = child.getClientRects(); } + else if (child.nodeType == 3) { boxes = textRange(child, 0, child.nodeValue.length).getClientRects(); } + else { continue } + for (var i = 0; i < boxes.length; i++) { + var box = boxes[i]; + if (box.bottom > box.top && (dir == "up" ? box.bottom < coords.top + 1 : box.top > coords.bottom - 1)) + { return false } + } + } + return true + }) +} + +var maybeRTL = /[\u0590-\u08ac]/; + +function endOfTextblockHorizontal(view, state, dir) { + var ref = state.selection; + var $head = ref.$head; + if (!$head.parent.isTextblock) { return false } + var offset = $head.parentOffset, atStart = !offset, atEnd = offset == $head.parent.content.size; + var sel = getSelection(); + // If the textblock is all LTR, or the browser doesn't support + // Selection.modify (Edge), fall back to a primitive approach + if (!maybeRTL.test($head.parent.textContent) || !sel.modify) + { return dir == "left" || dir == "backward" ? atStart : atEnd } + + return withFlushedState(view, state, function () { + // This is a huge hack, but appears to be the best we can + // currently do: use `Selection.modify` to move the selection by + // one character, and see if that moves the cursor out of the + // textblock (or doesn't move it at all, when at the start/end of + // the document). + var oldRange = sel.getRangeAt(0), oldNode = sel.focusNode, oldOff = sel.focusOffset; + var oldBidiLevel = sel.caretBidiLevel; // Only for Firefox + sel.modify("move", dir, "character"); + var parentDOM = $head.depth ? view.docView.domAfterPos($head.before()) : view.dom; + var result = !parentDOM.contains(sel.focusNode.nodeType == 1 ? sel.focusNode : sel.focusNode.parentNode) || + (oldNode == sel.focusNode && oldOff == sel.focusOffset); + // Restore the previous selection + sel.removeAllRanges(); + sel.addRange(oldRange); + if (oldBidiLevel != null) { sel.caretBidiLevel = oldBidiLevel; } + return result + }) +} + +var cachedState = null, cachedDir = null, cachedResult = false; +function endOfTextblock(view, state, dir) { + if (cachedState == state && cachedDir == dir) { return cachedResult } + cachedState = state; cachedDir = dir; + return cachedResult = dir == "up" || dir == "down" + ? endOfTextblockVertical(view, state, dir) + : endOfTextblockHorizontal(view, state, dir) +} + +// NodeView:: interface +// +// By default, document nodes are rendered using the result of the +// [`toDOM`](#model.NodeSpec.toDOM) method of their spec, and managed +// entirely by the editor. For some use cases, such as embedded +// node-specific editing interfaces, you want more control over +// the behavior of a node's in-editor representation, and need to +// [define](#view.EditorProps.nodeViews) a custom node view. +// +// Objects returned as node views must conform to this interface. +// +// dom:: ?dom.Node +// The outer DOM node that represents the document node. When not +// given, the default strategy is used to create a DOM node. +// +// contentDOM:: ?dom.Node +// The DOM node that should hold the node's content. Only meaningful +// if the node view also defines a `dom` property and if its node +// type is not a leaf node type. When this is present, ProseMirror +// will take care of rendering the node's children into it. When it +// is not present, the node view itself is responsible for rendering +// (or deciding not to render) its child nodes. +// +// update:: ?(node: Node, decorations: [Decoration]) → bool +// When given, this will be called when the view is updating itself. +// It will be given a node (possibly of a different type), and an +// array of active decorations (which are automatically drawn, and +// the node view may ignore if it isn't interested in them), and +// should return true if it was able to update to that node, and +// false otherwise. If the node view has a `contentDOM` property (or +// no `dom` property), updating its child nodes will be handled by +// ProseMirror. +// +// selectNode:: ?() +// Can be used to override the way the node's selected status (as a +// node selection) is displayed. +// +// deselectNode:: ?() +// When defining a `selectNode` method, you should also provide a +// `deselectNode` method to remove the effect again. +// +// setSelection:: ?(anchor: number, head: number, root: dom.Document) +// This will be called to handle setting the selection inside the +// node. The `anchor` and `head` positions are relative to the start +// of the node. By default, a DOM selection will be created between +// the DOM positions corresponding to those positions, but if you +// override it you can do something else. +// +// stopEvent:: ?(event: dom.Event) → bool +// Can be used to prevent the editor view from trying to handle some +// or all DOM events that bubble up from the node view. Events for +// which this returns true are not handled by the editor. +// +// ignoreMutation:: ?(dom.MutationRecord) → bool +// Called when a DOM +// [mutation](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) +// or a selection change happens within the view. When the change is +// a selection change, the record will have a `type` property of +// `"selection"` (which doesn't occur for native mutation records). +// Return false if the editor should re-read the selection or +// re-parse the range around the mutation, true if it can safely be +// ignored. +// +// destroy:: ?() +// Called when the node view is removed from the editor or the whole +// editor is destroyed. + +// View descriptions are data structures that describe the DOM that is +// used to represent the editor's content. They are used for: +// +// - Incremental redrawing when the document changes +// +// - Figuring out what part of the document a given DOM position +// corresponds to +// +// - Wiring in custom implementations of the editing interface for a +// given node +// +// They form a doubly-linked mutable tree, starting at `view.docView`. + +var NOT_DIRTY = 0, CHILD_DIRTY = 1, CONTENT_DIRTY = 2, NODE_DIRTY = 3; + +// Superclass for the various kinds of descriptions. Defines their +// basic structure and shared methods. +var ViewDesc = function ViewDesc(parent, children, dom, contentDOM) { + this.parent = parent; + this.children = children; + this.dom = dom; + // An expando property on the DOM node provides a link back to its + // description. + dom.pmViewDesc = this; + // This is the node that holds the child views. It may be null for + // descs that don't have children. + this.contentDOM = contentDOM; + this.dirty = NOT_DIRTY; +}; + +var prototypeAccessors = { beforePosition: { configurable: true },size: { configurable: true },border: { configurable: true },posBefore: { configurable: true },posAtStart: { configurable: true },posAfter: { configurable: true },posAtEnd: { configurable: true },contentLost: { configurable: true } }; + +// Used to check whether a given description corresponds to a +// widget/mark/node. +ViewDesc.prototype.matchesWidget = function matchesWidget () { return false }; +ViewDesc.prototype.matchesMark = function matchesMark () { return false }; +ViewDesc.prototype.matchesNode = function matchesNode () { return false }; +ViewDesc.prototype.matchesHack = function matchesHack () { return false }; + +prototypeAccessors.beforePosition.get = function () { return false }; + +// : () → ?ParseRule +// When parsing in-editor content (in domchange.js), we allow +// descriptions to determine the parse rules that should be used to +// parse them. +ViewDesc.prototype.parseRule = function parseRule () { return null }; + +// : (dom.Event) → bool +// Used by the editor's event handler to ignore events that come +// from certain descs. +ViewDesc.prototype.stopEvent = function stopEvent () { return false }; + +// The size of the content represented by this desc. +prototypeAccessors.size.get = function () { + var size = 0; + for (var i = 0; i < this.children.length; i++) { size += this.children[i].size; } + return size +}; + +// For block nodes, this represents the space taken up by their +// start/end tokens. +prototypeAccessors.border.get = function () { return 0 }; + +ViewDesc.prototype.destroy = function destroy () { + this.parent = null; + if (this.dom.pmViewDesc == this) { this.dom.pmViewDesc = null; } + for (var i = 0; i < this.children.length; i++) + { this.children[i].destroy(); } +}; + +ViewDesc.prototype.posBeforeChild = function posBeforeChild (child) { + for (var i = 0, pos = this.posAtStart; i < this.children.length; i++) { + var cur = this.children[i]; + if (cur == child) { return pos } + pos += cur.size; + } +}; + +prototypeAccessors.posBefore.get = function () { + return this.parent.posBeforeChild(this) +}; + +prototypeAccessors.posAtStart.get = function () { + return this.parent ? this.parent.posBeforeChild(this) + this.border : 0 +}; + +prototypeAccessors.posAfter.get = function () { + return this.posBefore + this.size +}; + +prototypeAccessors.posAtEnd.get = function () { + return this.posAtStart + this.size - 2 * this.border +}; + +// : (dom.Node, number, ?number) → number +ViewDesc.prototype.localPosFromDOM = function localPosFromDOM (dom, offset, bias) { + // If the DOM position is in the content, use the child desc after + // it to figure out a position. + if (this.contentDOM && this.contentDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode)) { + if (bias < 0) { + var domBefore, desc; + if (dom == this.contentDOM) { + domBefore = dom.childNodes[offset - 1]; + } else { + while (dom.parentNode != this.contentDOM) { dom = dom.parentNode; } + domBefore = dom.previousSibling; + } + while (domBefore && !((desc = domBefore.pmViewDesc) && desc.parent == this)) { domBefore = domBefore.previousSibling; } + return domBefore ? this.posBeforeChild(desc) + desc.size : this.posAtStart + } else { + var domAfter, desc$1; + if (dom == this.contentDOM) { + domAfter = dom.childNodes[offset]; + } else { + while (dom.parentNode != this.contentDOM) { dom = dom.parentNode; } + domAfter = dom.nextSibling; + } + while (domAfter && !((desc$1 = domAfter.pmViewDesc) && desc$1.parent == this)) { domAfter = domAfter.nextSibling; } + return domAfter ? this.posBeforeChild(desc$1) : this.posAtEnd + } + } + // Otherwise, use various heuristics, falling back on the bias + // parameter, to determine whether to return the position at the + // start or at the end of this view desc. + var atEnd; + if (this.contentDOM && this.contentDOM != this.dom && this.dom.contains(this.contentDOM)) { + atEnd = dom.compareDocumentPosition(this.contentDOM) & 2; + } else if (this.dom.firstChild) { + if (offset == 0) { for (var search = dom;; search = search.parentNode) { + if (search == this.dom) { atEnd = false; break } + if (search.parentNode.firstChild != search) { break } + } } + if (atEnd == null && offset == dom.childNodes.length) { for (var search$1 = dom;; search$1 = search$1.parentNode) { + if (search$1 == this.dom) { atEnd = true; break } + if (search$1.parentNode.lastChild != search$1) { break } + } } + } + return (atEnd == null ? bias > 0 : atEnd) ? this.posAtEnd : this.posAtStart +}; + +// Scan up the dom finding the first desc that is a descendant of +// this one. +ViewDesc.prototype.nearestDesc = function nearestDesc (dom, onlyNodes) { + for (var first = true, cur = dom; cur; cur = cur.parentNode) { + var desc = this.getDesc(cur); + if (desc && (!onlyNodes || desc.node)) { + // If dom is outside of this desc's nodeDOM, don't count it. + if (first && desc.nodeDOM && !(desc.nodeDOM.nodeType == 1 ? desc.nodeDOM.contains(dom) : desc.nodeDOM == dom)) { first = false; } + else { return desc } + } + } +}; + +ViewDesc.prototype.getDesc = function getDesc (dom) { + var desc = dom.pmViewDesc; + for (var cur = desc; cur; cur = cur.parent) { if (cur == this) { return desc } } +}; + +ViewDesc.prototype.posFromDOM = function posFromDOM (dom, offset, bias) { + for (var scan = dom;; scan = scan.parentNode) { + var desc = this.getDesc(scan); + if (desc) { return desc.localPosFromDOM(dom, offset, bias) } + } +}; + +// : (number) → ?NodeViewDesc +// Find the desc for the node after the given pos, if any. (When a +// parent node overrode rendering, there might not be one.) +ViewDesc.prototype.descAt = function descAt (pos) { + for (var i = 0, offset = 0; i < this.children.length; i++) { + var child = this.children[i], end = offset + child.size; + if (offset == pos && end != offset) { + while (!child.border && child.children.length) { child = child.children[0]; } + return child + } + if (pos < end) { return child.descAt(pos - offset - child.border) } + offset = end; + } +}; + +// : (number) → {node: dom.Node, offset: number} +ViewDesc.prototype.domFromPos = function domFromPos (pos) { + if (!this.contentDOM) { return {node: this.dom, offset: 0} } + for (var offset = 0, i = 0;; i++) { + if (offset == pos) { + while (i < this.children.length && (this.children[i].beforePosition || this.children[i].dom.parentNode != this.contentDOM)) { i++; } + return {node: this.contentDOM, + offset: i == this.children.length ? this.contentDOM.childNodes.length : domIndex(this.children[i].dom)} + } + if (i == this.children.length) { throw new Error("Invalid position " + pos) } + var child = this.children[i], end = offset + child.size; + if (pos < end) { return child.domFromPos(pos - offset - child.border) } + offset = end; + } +}; + +// Used to find a DOM range in a single parent for a given changed +// range. +ViewDesc.prototype.parseRange = function parseRange (from, to, base) { + if ( base === void 0 ) base = 0; + + if (this.children.length == 0) + { return {node: this.contentDOM, from: from, to: to, fromOffset: 0, toOffset: this.contentDOM.childNodes.length} } + + var fromOffset = -1, toOffset = -1; + for (var offset = base, i = 0;; i++) { + var child = this.children[i], end = offset + child.size; + if (fromOffset == -1 && from <= end) { + var childBase = offset + child.border; + // FIXME maybe descend mark views to parse a narrower range? + if (from >= childBase && to <= end - child.border && child.node && + child.contentDOM && this.contentDOM.contains(child.contentDOM)) + { return child.parseRange(from, to, childBase) } + + from = offset; + for (var j = i; j > 0; j--) { + var prev = this.children[j - 1]; + if (prev.size && prev.dom.parentNode == this.contentDOM && !prev.emptyChildAt(1)) { + fromOffset = domIndex(prev.dom) + 1; + break + } + from -= prev.size; + } + if (fromOffset == -1) { fromOffset = 0; } + } + if (fromOffset > -1 && to <= end) { + to = end; + for (var j$1 = i + 1; j$1 < this.children.length; j$1++) { + var next = this.children[j$1]; + if (next.size && next.dom.parentNode == this.contentDOM && !next.emptyChildAt(-1)) { + toOffset = domIndex(next.dom); + break + } + to += next.size; + } + if (toOffset == -1) { toOffset = this.contentDOM.childNodes.length; } + break + } + offset = end; + } + return {node: this.contentDOM, from: from, to: to, fromOffset: fromOffset, toOffset: toOffset} +}; + +ViewDesc.prototype.emptyChildAt = function emptyChildAt (side) { + if (this.border || !this.contentDOM || !this.children.length) { return false } + var child = this.children[side < 0 ? 0 : this.children.length - 1]; + return child.size == 0 || child.emptyChildAt(side) +}; + +// : (number) → dom.Node +ViewDesc.prototype.domAfterPos = function domAfterPos (pos) { + var ref = this.domFromPos(pos); + var node = ref.node; + var offset = ref.offset; + if (node.nodeType != 1 || offset == node.childNodes.length) + { throw new RangeError("No node after pos " + pos) } + return node.childNodes[offset] +}; + +// : (number, number, dom.Document) +// View descs are responsible for setting any selection that falls +// entirely inside of them, so that custom implementations can do +// custom things with the selection. Note that this falls apart when +// a selection starts in such a node and ends in another, in which +// case we just use whatever domFromPos produces as a best effort. +ViewDesc.prototype.setSelection = function setSelection (anchor, head, root, force) { + // If the selection falls entirely in a child, give it to that child + var from = Math.min(anchor, head), to = Math.max(anchor, head); + for (var i = 0, offset = 0; i < this.children.length; i++) { + var child = this.children[i], end = offset + child.size; + if (from > offset && to < end) + { return child.setSelection(anchor - offset - child.border, head - offset - child.border, root, force) } + offset = end; + } + + var anchorDOM = this.domFromPos(anchor), headDOM = this.domFromPos(head); + var domSel = root.getSelection(), range = document.createRange(); + if (!force && + isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset) && + isEquivalentPosition(headDOM.node, headDOM.offset, domSel.focusNode, domSel.focusOffset)) + { return } + + // Selection.extend can be used to create an 'inverted' selection + // (one where the focus is before the anchor), but not all + // browsers support it yet. + if (domSel.extend) { + range.setEnd(anchorDOM.node, anchorDOM.offset); + range.collapse(false); + } else { + if (anchor > head) { var tmp = anchorDOM; anchorDOM = headDOM; headDOM = tmp; } + range.setEnd(headDOM.node, headDOM.offset); + range.setStart(anchorDOM.node, anchorDOM.offset); + } + domSel.removeAllRanges(); + domSel.addRange(range); + if (domSel.extend) + { domSel.extend(headDOM.node, headDOM.offset); } +}; + +// : (dom.MutationRecord) → bool +ViewDesc.prototype.ignoreMutation = function ignoreMutation (_mutation) { + return !this.contentDOM +}; + +prototypeAccessors.contentLost.get = function () { + return this.contentDOM && this.contentDOM != this.dom && !this.dom.contains(this.contentDOM) +}; + +// Remove a subtree of the element tree that has been touched +// by a DOM change, so that the next update will redraw it. +ViewDesc.prototype.markDirty = function markDirty (from, to) { + for (var offset = 0, i = 0; i < this.children.length; i++) { + var child = this.children[i], end = offset + child.size; + if (offset == end ? from <= end && to >= offset : from < end && to > offset) { + var startInside = offset + child.border, endInside = end - child.border; + if (from >= startInside && to <= endInside) { + this.dirty = from == offset || to == end ? CONTENT_DIRTY : CHILD_DIRTY; + if (from == startInside && to == endInside && + (child.contentLost || child.dom.parentNode != this.contentDOM)) { child.dirty = NODE_DIRTY; } + else { child.markDirty(from - startInside, to - startInside); } + return + } else { + child.dirty = NODE_DIRTY; + } + } + offset = end; + } + this.dirty = CONTENT_DIRTY; +}; + +ViewDesc.prototype.markParentsDirty = function markParentsDirty () { + for (var node = this.parent; node; node = node.parent) { + var dirty = CONTENT_DIRTY ; + if (node.dirty < dirty) { node.dirty = dirty; } + } +}; + +Object.defineProperties( ViewDesc.prototype, prototypeAccessors ); + +// Reused array to avoid allocating fresh arrays for things that will +// stay empty anyway. +var nothing = []; + +// A widget desc represents a widget decoration, which is a DOM node +// drawn between the document nodes. +var WidgetViewDesc = /*@__PURE__*/(function (ViewDesc) { + function WidgetViewDesc(parent, widget, view, pos) { + var self, dom = widget.type.toDOM; + if (typeof dom == "function") { dom = dom(view, function () { + if (!self) { return pos } + if (self.parent) { return self.parent.posBeforeChild(self) } + }); } + if (!widget.type.spec.raw) { + if (dom.nodeType != 1) { + var wrap = document.createElement("span"); + wrap.appendChild(dom); + dom = wrap; + } + dom.contentEditable = false; + dom.classList.add("ProseMirror-widget"); + } + ViewDesc.call(this, parent, nothing, dom, null); + this.widget = widget; + self = this; + } + + if ( ViewDesc ) WidgetViewDesc.__proto__ = ViewDesc; + WidgetViewDesc.prototype = Object.create( ViewDesc && ViewDesc.prototype ); + WidgetViewDesc.prototype.constructor = WidgetViewDesc; + + var prototypeAccessors$1 = { beforePosition: { configurable: true } }; + + prototypeAccessors$1.beforePosition.get = function () { + return this.widget.type.side < 0 + }; + + WidgetViewDesc.prototype.matchesWidget = function matchesWidget (widget) { + return this.dirty == NOT_DIRTY && widget.type.eq(this.widget.type) + }; + + WidgetViewDesc.prototype.parseRule = function parseRule () { return {ignore: true} }; + + WidgetViewDesc.prototype.stopEvent = function stopEvent (event) { + var stop = this.widget.spec.stopEvent; + return stop ? stop(event) : false + }; + + Object.defineProperties( WidgetViewDesc.prototype, prototypeAccessors$1 ); + + return WidgetViewDesc; +}(ViewDesc)); + +var CompositionViewDesc = /*@__PURE__*/(function (ViewDesc) { + function CompositionViewDesc(parent, dom, textDOM, text) { + ViewDesc.call(this, parent, nothing, dom, null); + this.textDOM = textDOM; + this.text = text; + } + + if ( ViewDesc ) CompositionViewDesc.__proto__ = ViewDesc; + CompositionViewDesc.prototype = Object.create( ViewDesc && ViewDesc.prototype ); + CompositionViewDesc.prototype.constructor = CompositionViewDesc; + + var prototypeAccessors$2 = { size: { configurable: true } }; + + prototypeAccessors$2.size.get = function () { return this.text.length }; + + CompositionViewDesc.prototype.localPosFromDOM = function localPosFromDOM (dom, offset) { + if (dom != this.textDOM) { return this.posAtStart + (offset ? this.size : 0) } + return this.posAtStart + offset + }; + + CompositionViewDesc.prototype.domFromPos = function domFromPos (pos) { + return {node: this.textDOM, offset: pos} + }; + + CompositionViewDesc.prototype.ignoreMutation = function ignoreMutation (mut) { + return mut.type === 'characterData' && mut.target.nodeValue == mut.oldValue + }; + + Object.defineProperties( CompositionViewDesc.prototype, prototypeAccessors$2 ); + + return CompositionViewDesc; +}(ViewDesc)); + +// A mark desc represents a mark. May have multiple children, +// depending on how the mark is split. Note that marks are drawn using +// a fixed nesting order, for simplicity and predictability, so in +// some cases they will be split more often than would appear +// necessary. +var MarkViewDesc = /*@__PURE__*/(function (ViewDesc) { + function MarkViewDesc(parent, mark, dom, contentDOM) { + ViewDesc.call(this, parent, [], dom, contentDOM); + this.mark = mark; + } + + if ( ViewDesc ) MarkViewDesc.__proto__ = ViewDesc; + MarkViewDesc.prototype = Object.create( ViewDesc && ViewDesc.prototype ); + MarkViewDesc.prototype.constructor = MarkViewDesc; + + MarkViewDesc.create = function create (parent, mark, inline, view) { + var custom = view.nodeViews[mark.type.name]; + var spec = custom && custom(mark, view, inline); + if (!spec || !spec.dom) + { spec = prosemirrorModel.DOMSerializer.renderSpec(document, mark.type.spec.toDOM(mark, inline)); } + return new MarkViewDesc(parent, mark, spec.dom, spec.contentDOM || spec.dom) + }; + + MarkViewDesc.prototype.parseRule = function parseRule () { return {mark: this.mark.type.name, attrs: this.mark.attrs, contentElement: this.contentDOM} }; + + MarkViewDesc.prototype.matchesMark = function matchesMark (mark) { return this.dirty != NODE_DIRTY && this.mark.eq(mark) }; + + MarkViewDesc.prototype.markDirty = function markDirty (from, to) { + ViewDesc.prototype.markDirty.call(this, from, to); + // Move dirty info to nearest node view + if (this.dirty != NOT_DIRTY) { + var parent = this.parent; + while (!parent.node) { parent = parent.parent; } + if (parent.dirty < this.dirty) { parent.dirty = this.dirty; } + this.dirty = NOT_DIRTY; + } + }; + + MarkViewDesc.prototype.slice = function slice (from, to, view) { + var copy = MarkViewDesc.create(this.parent, this.mark, true, view); + var nodes = this.children, size = this.size; + if (to < size) { nodes = replaceNodes(nodes, to, size, view); } + if (from > 0) { nodes = replaceNodes(nodes, 0, from, view); } + for (var i = 0; i < nodes.length; i++) { nodes[i].parent = copy; } + copy.children = nodes; + return copy + }; + + return MarkViewDesc; +}(ViewDesc)); + +// Node view descs are the main, most common type of view desc, and +// correspond to an actual node in the document. Unlike mark descs, +// they populate their child array themselves. +var NodeViewDesc = /*@__PURE__*/(function (ViewDesc) { + function NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos) { + ViewDesc.call(this, parent, node.isLeaf ? nothing : [], dom, contentDOM); + this.nodeDOM = nodeDOM; + this.node = node; + this.outerDeco = outerDeco; + this.innerDeco = innerDeco; + if (contentDOM) { this.updateChildren(view, pos); } + } + + if ( ViewDesc ) NodeViewDesc.__proto__ = ViewDesc; + NodeViewDesc.prototype = Object.create( ViewDesc && ViewDesc.prototype ); + NodeViewDesc.prototype.constructor = NodeViewDesc; + + var prototypeAccessors$3 = { size: { configurable: true },border: { configurable: true } }; + + // By default, a node is rendered using the `toDOM` method from the + // node type spec. But client code can use the `nodeViews` spec to + // supply a custom node view, which can influence various aspects of + // the way the node works. + // + // (Using subclassing for this was intentionally decided against, + // since it'd require exposing a whole slew of finnicky + // implementation details to the user code that they probably will + // never need.) + NodeViewDesc.create = function create (parent, node, outerDeco, innerDeco, view, pos) { + var assign; + + var custom = view.nodeViews[node.type.name], descObj; + var spec = custom && custom(node, view, function () { + // (This is a function that allows the custom view to find its + // own position) + if (!descObj) { return pos } + if (descObj.parent) { return descObj.parent.posBeforeChild(descObj) } + }, outerDeco); + + var dom = spec && spec.dom, contentDOM = spec && spec.contentDOM; + if (node.isText) { + if (!dom) { dom = document.createTextNode(node.text); } + else if (dom.nodeType != 3) { throw new RangeError("Text must be rendered as a DOM text node") } + } else if (!dom) { +((assign = prosemirrorModel.DOMSerializer.renderSpec(document, node.type.spec.toDOM(node)), dom = assign.dom, contentDOM = assign.contentDOM)); + } + if (!contentDOM && !node.isText && dom.nodeName != "BR") { // Chrome gets confused by
    + if (!dom.hasAttribute("contenteditable")) { dom.contentEditable = false; } + if (node.type.spec.draggable) { dom.draggable = true; } + } + + var nodeDOM = dom; + dom = applyOuterDeco(dom, outerDeco, node); + + if (spec) + { return descObj = new CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, + spec, view, pos + 1) } + else if (node.isText) + { return new TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM, view) } + else + { return new NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos + 1) } + }; + + NodeViewDesc.prototype.parseRule = function parseRule () { + var this$1 = this; + + // Experimental kludge to allow opt-in re-parsing of nodes + if (this.node.type.spec.reparseInView) { return null } + // FIXME the assumption that this can always return the current + // attrs means that if the user somehow manages to change the + // attrs in the dom, that won't be picked up. Not entirely sure + // whether this is a problem + var rule = {node: this.node.type.name, attrs: this.node.attrs}; + if (this.node.type.spec.code) { rule.preserveWhitespace = "full"; } + if (this.contentDOM && !this.contentLost) { rule.contentElement = this.contentDOM; } + else { rule.getContent = function () { return this$1.contentDOM ? prosemirrorModel.Fragment.empty : this$1.node.content; }; } + return rule + }; + + NodeViewDesc.prototype.matchesNode = function matchesNode (node, outerDeco, innerDeco) { + return this.dirty == NOT_DIRTY && node.eq(this.node) && + sameOuterDeco(outerDeco, this.outerDeco) && innerDeco.eq(this.innerDeco) + }; + + prototypeAccessors$3.size.get = function () { return this.node.nodeSize }; + + prototypeAccessors$3.border.get = function () { return this.node.isLeaf ? 0 : 1 }; + + // Syncs `this.children` to match `this.node.content` and the local + // decorations, possibly introducing nesting for marks. Then, in a + // separate step, syncs the DOM inside `this.contentDOM` to + // `this.children`. + NodeViewDesc.prototype.updateChildren = function updateChildren (view, pos) { + var this$1 = this; + + var inline = this.node.inlineContent, off = pos; + var composition = inline && view.composing && this.localCompositionNode(view, pos); + var updater = new ViewTreeUpdater(this, composition && composition.node); + iterDeco(this.node, this.innerDeco, function (widget, i) { + if (widget.spec.marks) + { updater.syncToMarks(widget.spec.marks, inline, view); } + else if (widget.type.side >= 0) + { updater.syncToMarks(i == this$1.node.childCount ? prosemirrorModel.Mark.none : this$1.node.child(i).marks, inline, view); } + // If the next node is a desc matching this widget, reuse it, + // otherwise insert the widget as a new view desc. + updater.placeWidget(widget, view, off); + }, function (child, outerDeco, innerDeco, i) { + // Make sure the wrapping mark descs match the node's marks. + updater.syncToMarks(child.marks, inline, view); + // Either find an existing desc that exactly matches this node, + // and drop the descs before it. + updater.findNodeMatch(child, outerDeco, innerDeco, i) || + // Or try updating the next desc to reflect this node. + updater.updateNextNode(child, outerDeco, innerDeco, view, i) || + // Or just add it as a new desc. + updater.addNode(child, outerDeco, innerDeco, view, off); + off += child.nodeSize; + }); + // Drop all remaining descs after the current position. + updater.syncToMarks(nothing, inline, view); + if (this.node.isTextblock) { updater.addTextblockHacks(); } + updater.destroyRest(); + + // Sync the DOM if anything changed + if (updater.changed || this.dirty == CONTENT_DIRTY) { + // May have to protect focused DOM from being changed if a composition is active + if (composition) { this.protectLocalComposition(view, composition); } + this.renderChildren(); + } + }; + + NodeViewDesc.prototype.renderChildren = function renderChildren () { + renderDescs(this.contentDOM, this.children); + if (result.ios) { iosHacks(this.dom); } + }; + + NodeViewDesc.prototype.localCompositionNode = function localCompositionNode (view, pos) { + // Only do something if both the selection and a focused text node + // are inside of this node, and the node isn't already part of a + // view that's a child of this view + var ref = view.state.selection; + var from = ref.from; + var to = ref.to; + if (!(view.state.selection instanceof prosemirrorState.TextSelection) || from < pos || to > pos + this.node.content.size) { return } + var sel = view.root.getSelection(); + var textNode = nearbyTextNode(sel.focusNode, sel.focusOffset); + if (!textNode || !this.dom.contains(textNode.parentNode)) { return } + + // Find the text in the focused node in the node, stop if it's not + // there (may have been modified through other means, in which + // case it should overwritten) + var text = textNode.nodeValue; + var textPos = findTextInFragment(this.node.content, text, from - pos, to - pos); + + return textPos < 0 ? null : {node: textNode, pos: textPos, text: text} + }; + + NodeViewDesc.prototype.protectLocalComposition = function protectLocalComposition (view, ref) { + var node = ref.node; + var pos = ref.pos; + var text = ref.text; + + // The node is already part of a local view desc, leave it there + if (this.getDesc(node)) { return } + + // Create a composition view for the orphaned nodes + var topNode = node; + for (;; topNode = topNode.parentNode) { + if (topNode.parentNode == this.contentDOM) { break } + while (topNode.previousSibling) { topNode.parentNode.removeChild(topNode.previousSibling); } + while (topNode.nextSibling) { topNode.parentNode.removeChild(topNode.nextSibling); } + if (topNode.pmViewDesc) { topNode.pmViewDesc = null; } + } + var desc = new CompositionViewDesc(this, topNode, node, text); + view.compositionNodes.push(desc); + + // Patch up this.children to contain the composition view + this.children = replaceNodes(this.children, pos, pos + text.length, view, desc); + }; + + // : (Node, [Decoration], DecorationSet, EditorView) → bool + // If this desc be updated to match the given node decoration, + // do so and return true. + NodeViewDesc.prototype.update = function update (node, outerDeco, innerDeco, view) { + if (this.dirty == NODE_DIRTY || + !node.sameMarkup(this.node)) { return false } + this.updateInner(node, outerDeco, innerDeco, view); + return true + }; + + NodeViewDesc.prototype.updateInner = function updateInner (node, outerDeco, innerDeco, view) { + this.updateOuterDeco(outerDeco); + this.node = node; + this.innerDeco = innerDeco; + if (this.contentDOM) { this.updateChildren(view, this.posAtStart); } + this.dirty = NOT_DIRTY; + }; + + NodeViewDesc.prototype.updateOuterDeco = function updateOuterDeco (outerDeco) { + if (sameOuterDeco(outerDeco, this.outerDeco)) { return } + var needsWrap = this.nodeDOM.nodeType != 1; + var oldDOM = this.dom; + this.dom = patchOuterDeco(this.dom, this.nodeDOM, + computeOuterDeco(this.outerDeco, this.node, needsWrap), + computeOuterDeco(outerDeco, this.node, needsWrap)); + if (this.dom != oldDOM) { + oldDOM.pmViewDesc = null; + this.dom.pmViewDesc = this; + } + this.outerDeco = outerDeco; + }; + + // Mark this node as being the selected node. + NodeViewDesc.prototype.selectNode = function selectNode () { + this.nodeDOM.classList.add("ProseMirror-selectednode"); + if (this.contentDOM || !this.node.type.spec.draggable) { this.dom.draggable = true; } + }; + + // Remove selected node marking from this node. + NodeViewDesc.prototype.deselectNode = function deselectNode () { + this.nodeDOM.classList.remove("ProseMirror-selectednode"); + if (this.contentDOM || !this.node.type.spec.draggable) { this.dom.draggable = false; } + }; + + Object.defineProperties( NodeViewDesc.prototype, prototypeAccessors$3 ); + + return NodeViewDesc; +}(ViewDesc)); + +// Create a view desc for the top-level document node, to be exported +// and used by the view class. +function docViewDesc(doc, outerDeco, innerDeco, dom, view) { + applyOuterDeco(dom, outerDeco, doc); + return new NodeViewDesc(null, doc, outerDeco, innerDeco, dom, dom, dom, view, 0) +} + +var TextViewDesc = /*@__PURE__*/(function (NodeViewDesc) { + function TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM, view) { + NodeViewDesc.call(this, parent, node, outerDeco, innerDeco, dom, null, nodeDOM, view); + } + + if ( NodeViewDesc ) TextViewDesc.__proto__ = NodeViewDesc; + TextViewDesc.prototype = Object.create( NodeViewDesc && NodeViewDesc.prototype ); + TextViewDesc.prototype.constructor = TextViewDesc; + + TextViewDesc.prototype.parseRule = function parseRule () { + return {skip: this.nodeDOM.parentNode || true} + }; + + TextViewDesc.prototype.update = function update (node, outerDeco) { + if (this.dirty == NODE_DIRTY || (this.dirty != NOT_DIRTY && !this.inParent()) || + !node.sameMarkup(this.node)) { return false } + this.updateOuterDeco(outerDeco); + if ((this.dirty != NOT_DIRTY || node.text != this.node.text) && node.text != this.nodeDOM.nodeValue) + { this.nodeDOM.nodeValue = node.text; } + this.node = node; + this.dirty = NOT_DIRTY; + return true + }; + + TextViewDesc.prototype.inParent = function inParent () { + var parentDOM = this.parent.contentDOM; + for (var n = this.nodeDOM; n; n = n.parentNode) { if (n == parentDOM) { return true } } + return false + }; + + TextViewDesc.prototype.domFromPos = function domFromPos (pos) { + return {node: this.nodeDOM, offset: pos} + }; + + TextViewDesc.prototype.localPosFromDOM = function localPosFromDOM (dom, offset, bias) { + if (dom == this.nodeDOM) { return this.posAtStart + Math.min(offset, this.node.text.length) } + return NodeViewDesc.prototype.localPosFromDOM.call(this, dom, offset, bias) + }; + + TextViewDesc.prototype.ignoreMutation = function ignoreMutation (mutation) { + return mutation.type != "characterData" && mutation.type != "selection" + }; + + TextViewDesc.prototype.slice = function slice (from, to, view) { + var node = this.node.cut(from, to), dom = document.createTextNode(node.text); + return new TextViewDesc(this.parent, node, this.outerDeco, this.innerDeco, dom, dom, view) + }; + + return TextViewDesc; +}(NodeViewDesc)); + +// A dummy desc used to tag trailing BR or span nodes created to work +// around contentEditable terribleness. +var BRHackViewDesc = /*@__PURE__*/(function (ViewDesc) { + function BRHackViewDesc () { + ViewDesc.apply(this, arguments); + } + + if ( ViewDesc ) BRHackViewDesc.__proto__ = ViewDesc; + BRHackViewDesc.prototype = Object.create( ViewDesc && ViewDesc.prototype ); + BRHackViewDesc.prototype.constructor = BRHackViewDesc; + + BRHackViewDesc.prototype.parseRule = function parseRule () { return {ignore: true} }; + BRHackViewDesc.prototype.matchesHack = function matchesHack () { return this.dirty == NOT_DIRTY }; + + return BRHackViewDesc; +}(ViewDesc)); + +// A separate subclass is used for customized node views, so that the +// extra checks only have to be made for nodes that are actually +// customized. +var CustomNodeViewDesc = /*@__PURE__*/(function (NodeViewDesc) { + function CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, spec, view, pos) { + NodeViewDesc.call(this, parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos); + this.spec = spec; + } + + if ( NodeViewDesc ) CustomNodeViewDesc.__proto__ = NodeViewDesc; + CustomNodeViewDesc.prototype = Object.create( NodeViewDesc && NodeViewDesc.prototype ); + CustomNodeViewDesc.prototype.constructor = CustomNodeViewDesc; + + // A custom `update` method gets to decide whether the update goes + // through. If it does, and there's a `contentDOM` node, our logic + // updates the children. + CustomNodeViewDesc.prototype.update = function update (node, outerDeco, innerDeco, view) { + if (this.dirty == NODE_DIRTY) { return false } + if (this.spec.update) { + var result = this.spec.update(node, outerDeco); + if (result) { this.updateInner(node, outerDeco, innerDeco, view); } + return result + } else if (!this.contentDOM && !node.isLeaf) { + return false + } else { + return NodeViewDesc.prototype.update.call(this, node, outerDeco, innerDeco, view) + } + }; + + CustomNodeViewDesc.prototype.selectNode = function selectNode () { + this.spec.selectNode ? this.spec.selectNode() : NodeViewDesc.prototype.selectNode.call(this); + }; + + CustomNodeViewDesc.prototype.deselectNode = function deselectNode () { + this.spec.deselectNode ? this.spec.deselectNode() : NodeViewDesc.prototype.deselectNode.call(this); + }; + + CustomNodeViewDesc.prototype.setSelection = function setSelection (anchor, head, root, force) { + this.spec.setSelection ? this.spec.setSelection(anchor, head, root) + : NodeViewDesc.prototype.setSelection.call(this, anchor, head, root, force); + }; + + CustomNodeViewDesc.prototype.destroy = function destroy () { + if (this.spec.destroy) { this.spec.destroy(); } + NodeViewDesc.prototype.destroy.call(this); + }; + + CustomNodeViewDesc.prototype.stopEvent = function stopEvent (event) { + return this.spec.stopEvent ? this.spec.stopEvent(event) : false + }; + + CustomNodeViewDesc.prototype.ignoreMutation = function ignoreMutation (mutation) { + return this.spec.ignoreMutation ? this.spec.ignoreMutation(mutation) : NodeViewDesc.prototype.ignoreMutation.call(this, mutation) + }; + + return CustomNodeViewDesc; +}(NodeViewDesc)); + +// : (dom.Node, [ViewDesc]) +// Sync the content of the given DOM node with the nodes associated +// with the given array of view descs, recursing into mark descs +// because this should sync the subtree for a whole node at a time. +function renderDescs(parentDOM, descs) { + var dom = parentDOM.firstChild; + for (var i = 0; i < descs.length; i++) { + var desc = descs[i], childDOM = desc.dom; + if (childDOM.parentNode == parentDOM) { + while (childDOM != dom) { dom = rm(dom); } + dom = dom.nextSibling; + } else { + parentDOM.insertBefore(childDOM, dom); + } + if (desc instanceof MarkViewDesc) { + var pos = dom ? dom.previousSibling : parentDOM.lastChild; + renderDescs(desc.contentDOM, desc.children); + dom = pos ? pos.nextSibling : parentDOM.firstChild; + } + } + while (dom) { dom = rm(dom); } +} + +function OuterDecoLevel(nodeName) { + if (nodeName) { this.nodeName = nodeName; } +} +OuterDecoLevel.prototype = Object.create(null); + +var noDeco = [new OuterDecoLevel]; + +function computeOuterDeco(outerDeco, node, needsWrap) { + if (outerDeco.length == 0) { return noDeco } + + var top = needsWrap ? noDeco[0] : new OuterDecoLevel, result = [top]; + + for (var i = 0; i < outerDeco.length; i++) { + var attrs = outerDeco[i].type.attrs, cur = top; + if (!attrs) { continue } + if (attrs.nodeName) + { result.push(cur = new OuterDecoLevel(attrs.nodeName)); } + + for (var name in attrs) { + var val = attrs[name]; + if (val == null) { continue } + if (needsWrap && result.length == 1) + { result.push(cur = top = new OuterDecoLevel(node.isInline ? "span" : "div")); } + if (name == "class") { cur.class = (cur.class ? cur.class + " " : "") + val; } + else if (name == "style") { cur.style = (cur.style ? cur.style + ";" : "") + val; } + else if (name != "nodeName") { cur[name] = val; } + } + } + + return result +} + +function patchOuterDeco(outerDOM, nodeDOM, prevComputed, curComputed) { + // Shortcut for trivial case + if (prevComputed == noDeco && curComputed == noDeco) { return nodeDOM } + + var curDOM = nodeDOM; + for (var i = 0; i < curComputed.length; i++) { + var deco = curComputed[i], prev = prevComputed[i]; + if (i) { + var parent = (void 0); + if (prev && prev.nodeName == deco.nodeName && curDOM != outerDOM && + (parent = curDOM.parentNode) && parent.tagName.toLowerCase() == deco.nodeName) { + curDOM = parent; + } else { + parent = document.createElement(deco.nodeName); + parent.appendChild(curDOM); + prev = noDeco[0]; + curDOM = parent; + } + } + patchAttributes(curDOM, prev || noDeco[0], deco); + } + return curDOM +} + +function patchAttributes(dom, prev, cur) { + for (var name in prev) + { if (name != "class" && name != "style" && name != "nodeName" && !(name in cur)) + { dom.removeAttribute(name); } } + for (var name$1 in cur) + { if (name$1 != "class" && name$1 != "style" && name$1 != "nodeName" && cur[name$1] != prev[name$1]) + { dom.setAttribute(name$1, cur[name$1]); } } + if (prev.class != cur.class) { + var prevList = prev.class ? prev.class.split(" ") : nothing; + var curList = cur.class ? cur.class.split(" ") : nothing; + for (var i = 0; i < prevList.length; i++) { if (curList.indexOf(prevList[i]) == -1) + { dom.classList.remove(prevList[i]); } } + for (var i$1 = 0; i$1 < curList.length; i$1++) { if (prevList.indexOf(curList[i$1]) == -1) + { dom.classList.add(curList[i$1]); } } + } + if (prev.style != cur.style) { + if (prev.style) { + var prop = /\s*([\w\-\xa1-\uffff]+)\s*:(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*'|\(.*?\)|[^;])*/g, m; + while (m = prop.exec(prev.style)) + { dom.style.removeProperty(m[1]); } + } + if (cur.style) + { dom.style.cssText += cur.style; } + } +} + +function applyOuterDeco(dom, deco, node) { + return patchOuterDeco(dom, dom, noDeco, computeOuterDeco(deco, node, dom.nodeType != 1)) +} + +// : ([Decoration], [Decoration]) → bool +function sameOuterDeco(a, b) { + if (a.length != b.length) { return false } + for (var i = 0; i < a.length; i++) { if (!a[i].type.eq(b[i].type)) { return false } } + return true +} + +// Remove a DOM node and return its next sibling. +function rm(dom) { + var next = dom.nextSibling; + dom.parentNode.removeChild(dom); + return next +} + +// Helper class for incrementally updating a tree of mark descs and +// the widget and node descs inside of them. +var ViewTreeUpdater = function ViewTreeUpdater(top, lockedNode) { + this.top = top; + this.lock = lockedNode; + // Index into `this.top`'s child array, represents the current + // update position. + this.index = 0; + // When entering a mark, the current top and index are pushed + // onto this. + this.stack = []; + // Tracks whether anything was changed + this.changed = false; + + var pre = preMatch(top.node.content, top.children); + this.preMatched = pre.nodes; + this.preMatchOffset = pre.offset; +}; + +ViewTreeUpdater.prototype.getPreMatch = function getPreMatch (index) { + return index >= this.preMatchOffset ? this.preMatched[index - this.preMatchOffset] : null +}; + +// Destroy and remove the children between the given indices in +// `this.top`. +ViewTreeUpdater.prototype.destroyBetween = function destroyBetween (start, end) { + if (start == end) { return } + for (var i = start; i < end; i++) { this.top.children[i].destroy(); } + this.top.children.splice(start, end - start); + this.changed = true; +}; + +// Destroy all remaining children in `this.top`. +ViewTreeUpdater.prototype.destroyRest = function destroyRest () { + this.destroyBetween(this.index, this.top.children.length); +}; + +// : ([Mark], EditorView) +// Sync the current stack of mark descs with the given array of +// marks, reusing existing mark descs when possible. +ViewTreeUpdater.prototype.syncToMarks = function syncToMarks (marks, inline, view) { + var keep = 0, depth = this.stack.length >> 1; + var maxKeep = Math.min(depth, marks.length); + while (keep < maxKeep && + (keep == depth - 1 ? this.top : this.stack[(keep + 1) << 1]).matchesMark(marks[keep]) && marks[keep].type.spec.spanning !== false) + { keep++; } + + while (keep < depth) { + this.destroyRest(); + this.top.dirty = NOT_DIRTY; + this.index = this.stack.pop(); + this.top = this.stack.pop(); + depth--; + } + while (depth < marks.length) { + this.stack.push(this.top, this.index + 1); + var found = -1; + for (var i = this.index; i < Math.min(this.index + 3, this.top.children.length); i++) { + if (this.top.children[i].matchesMark(marks[depth])) { found = i; break } + } + if (found > -1) { + if (found > this.index) { + this.changed = true; + this.destroyBetween(this.index, found); + } + this.top = this.top.children[this.index]; + } else { + var markDesc = MarkViewDesc.create(this.top, marks[depth], inline, view); + this.top.children.splice(this.index, 0, markDesc); + this.top = markDesc; + this.changed = true; + } + this.index = 0; + depth++; + } +}; + +// : (Node, [Decoration], DecorationSet) → bool +// Try to find a node desc matching the given data. Skip over it and +// return true when successful. +ViewTreeUpdater.prototype.findNodeMatch = function findNodeMatch (node, outerDeco, innerDeco, index) { + var found = -1, preMatch = index < 0 ? undefined : this.getPreMatch(index), children = this.top.children; + if (preMatch && preMatch.matchesNode(node, outerDeco, innerDeco)) { + found = children.indexOf(preMatch); + } else { + for (var i = this.index, e = Math.min(children.length, i + 5); i < e; i++) { + var child = children[i]; + if (child.matchesNode(node, outerDeco, innerDeco) && this.preMatched.indexOf(child) < 0) { + found = i; + break + } + } + } + if (found < 0) { return false } + this.destroyBetween(this.index, found); + this.index++; + return true +}; + +// : (Node, [Decoration], DecorationSet, EditorView, Fragment, number) → bool +// Try to update the next node, if any, to the given data. Checks +// pre-matches to avoid overwriting nodes that could still be used. +ViewTreeUpdater.prototype.updateNextNode = function updateNextNode (node, outerDeco, innerDeco, view, index) { + if (this.index == this.top.children.length) { return false } + var next = this.top.children[this.index]; + if (next instanceof NodeViewDesc) { + var preMatch = this.preMatched.indexOf(next); + if (preMatch > -1 && preMatch + this.preMatchOffset != index) { return false } + var nextDOM = next.dom; + + // Can't update if nextDOM is or contains this.lock, except if + // it's a text node whose content already matches the new text + // and whose decorations match the new ones. + var locked = this.lock && (nextDOM == this.lock || nextDOM.nodeType == 1 && nextDOM.contains(this.lock.parentNode)) && + !(node.isText && next.node && next.node.isText && next.nodeDOM.nodeValue == node.text && + next.dirty != NODE_DIRTY && sameOuterDeco(outerDeco, next.outerDeco)); + if (!locked && next.update(node, outerDeco, innerDeco, view)) { + if (next.dom != nextDOM) { this.changed = true; } + this.index++; + return true + } + } + return false +}; + +// : (Node, [Decoration], DecorationSet, EditorView) +// Insert the node as a newly created node desc. +ViewTreeUpdater.prototype.addNode = function addNode (node, outerDeco, innerDeco, view, pos) { + this.top.children.splice(this.index++, 0, NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos)); + this.changed = true; +}; + +ViewTreeUpdater.prototype.placeWidget = function placeWidget (widget, view, pos) { + if (this.index < this.top.children.length && this.top.children[this.index].matchesWidget(widget)) { + this.index++; + } else { + var desc = new WidgetViewDesc(this.top, widget, view, pos); + this.top.children.splice(this.index++, 0, desc); + this.changed = true; + } +}; + +// Make sure a textblock looks and behaves correctly in +// contentEditable. +ViewTreeUpdater.prototype.addTextblockHacks = function addTextblockHacks () { + var lastChild = this.top.children[this.index - 1]; + while (lastChild instanceof MarkViewDesc) { lastChild = lastChild.children[lastChild.children.length - 1]; } + + if (!lastChild || // Empty textblock + !(lastChild instanceof TextViewDesc) || + /\n$/.test(lastChild.node.text)) { + if (this.index < this.top.children.length && this.top.children[this.index].matchesHack()) { + this.index++; + } else { + var dom = document.createElement("br"); + this.top.children.splice(this.index++, 0, new BRHackViewDesc(this.top, nothing, dom, null)); + this.changed = true; + } + } +}; + +// : (Fragment, [ViewDesc]) → [ViewDesc] +// Iterate from the end of the fragment and array of descs to find +// directly matching ones, in order to avoid overeagerly reusing +// those for other nodes. Returns an array whose positions correspond +// to node positions in the fragment, and whose elements are either +// descs matched to the child at that index, or empty. +function preMatch(frag, descs) { + var result = [], end = frag.childCount; + for (var i = descs.length - 1; end > 0 && i >= 0; i--) { + var desc = descs[i], node = desc.node; + if (!node) { continue } + if (node != frag.child(end - 1)) { break } + result.push(desc); + --end; + } + return {nodes: result.reverse(), offset: end} +} + +function compareSide(a, b) { return a.type.side - b.type.side } + +// : (ViewDesc, DecorationSet, (Decoration, number), (Node, [Decoration], DecorationSet, number)) +// This function abstracts iterating over the nodes and decorations in +// a fragment. Calls `onNode` for each node, with its local and child +// decorations. Splits text nodes when there is a decoration starting +// or ending inside of them. Calls `onWidget` for each widget. +function iterDeco(parent, deco, onWidget, onNode) { + var locals = deco.locals(parent), offset = 0; + // Simple, cheap variant for when there are no local decorations + if (locals.length == 0) { + for (var i = 0; i < parent.childCount; i++) { + var child = parent.child(i); + onNode(child, locals, deco.forChild(offset, child), i); + offset += child.nodeSize; + } + return + } + + var decoIndex = 0, active = [], restNode = null; + for (var parentIndex = 0;;) { + if (decoIndex < locals.length && locals[decoIndex].to == offset) { + var widget = locals[decoIndex++], widgets = (void 0); + while (decoIndex < locals.length && locals[decoIndex].to == offset) + { (widgets || (widgets = [widget])).push(locals[decoIndex++]); } + if (widgets) { + widgets.sort(compareSide); + for (var i$1 = 0; i$1 < widgets.length; i$1++) { onWidget(widgets[i$1], parentIndex); } + } else { + onWidget(widget, parentIndex); + } + } + + var child$1 = (void 0), index = (void 0); + if (restNode) { + index = -1; + child$1 = restNode; + restNode = null; + } else if (parentIndex < parent.childCount) { + index = parentIndex; + child$1 = parent.child(parentIndex++); + } else { + break + } + + for (var i$2 = 0; i$2 < active.length; i$2++) { if (active[i$2].to <= offset) { active.splice(i$2--, 1); } } + while (decoIndex < locals.length && locals[decoIndex].from == offset) { active.push(locals[decoIndex++]); } + + var end = offset + child$1.nodeSize; + if (child$1.isText) { + var cutAt = end; + if (decoIndex < locals.length && locals[decoIndex].from < cutAt) { cutAt = locals[decoIndex].from; } + for (var i$3 = 0; i$3 < active.length; i$3++) { if (active[i$3].to < cutAt) { cutAt = active[i$3].to; } } + if (cutAt < end) { + restNode = child$1.cut(cutAt - offset); + child$1 = child$1.cut(0, cutAt - offset); + end = cutAt; + index = -1; + } + } + + onNode(child$1, active.length ? active.slice() : nothing, deco.forChild(offset, child$1), index); + offset = end; + } +} + +// List markers in Mobile Safari will mysteriously disappear +// sometimes. This works around that. +function iosHacks(dom) { + if (dom.nodeName == "UL" || dom.nodeName == "OL") { + var oldCSS = dom.style.cssText; + dom.style.cssText = oldCSS + "; list-style: square !important"; + window.getComputedStyle(dom).listStyle; + dom.style.cssText = oldCSS; + } +} + +function nearbyTextNode(node, offset) { + for (;;) { + if (node.nodeType == 3) { return node } + if (node.nodeType == 1 && offset > 0) { + if (node.childNodes.length > offset && node.childNodes[offset].nodeType == 3) + { return node.childNodes[offset] } + node = node.childNodes[offset - 1]; + offset = nodeSize(node); + } else if (node.nodeType == 1 && offset < node.childNodes.length) { + node = node.childNodes[offset]; + offset = 0; + } else { + return null + } + } +} + +// Find a piece of text in an inline fragment, overlapping from-to +function findTextInFragment(frag, text, from, to) { + for (var str = "", i = 0, childPos = 0; i < frag.childCount; i++) { + var child = frag.child(i), end = childPos + child.nodeSize; + if (child.isText) { + str += child.text; + if (end >= to) { + var strStart = end - str.length, found = str.lastIndexOf(text); + while (found > -1 && strStart + found > from) { found = str.lastIndexOf(text, found - 1); } + if (found > -1 && strStart + found + text.length >= to) { + return strStart + found + } else if (end > to) { + break + } + } + } else { + str = ""; + } + childPos = end; + } + return -1 +} + +// Replace range from-to in an array of view descs with replacement +// (may be null to just delete). This goes very much against the grain +// of the rest of this code, which tends to create nodes with the +// right shape in one go, rather than messing with them after +// creation, but is necessary in the composition hack. +function replaceNodes(nodes, from, to, view, replacement) { + var result = []; + for (var i = 0, off = 0; i < nodes.length; i++) { + var child = nodes[i], start = off, end = off += child.size; + if (start >= to || end <= from) { + result.push(child); + } else { + if (start < from) { result.push(child.slice(0, from - start, view)); } + if (replacement) { + result.push(replacement); + replacement = null; + } + if (end > to) { result.push(child.slice(to - start, child.size, view)); } + } + } + return result +} + +function moveSelectionBlock(state, dir) { + var ref = state.selection; + var $anchor = ref.$anchor; + var $head = ref.$head; + var $side = dir > 0 ? $anchor.max($head) : $anchor.min($head); + var $start = !$side.parent.inlineContent ? $side : $side.depth ? state.doc.resolve(dir > 0 ? $side.after() : $side.before()) : null; + return $start && prosemirrorState.Selection.findFrom($start, dir) +} + +function apply(view, sel) { + view.dispatch(view.state.tr.setSelection(sel).scrollIntoView()); + return true +} + +function selectHorizontally(view, dir, mods) { + var sel = view.state.selection; + if (sel instanceof prosemirrorState.TextSelection) { + if (!sel.empty || mods.indexOf("s") > -1) { + return false + } else if (view.endOfTextblock(dir > 0 ? "right" : "left")) { + var next = moveSelectionBlock(view.state, dir); + if (next && (next instanceof prosemirrorState.NodeSelection)) { return apply(view, next) } + return false + } else { + var $head = sel.$head, node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter, desc; + if (!node || node.isText) { return false } + var nodePos = dir < 0 ? $head.pos - node.nodeSize : $head.pos; + if (!(node.isAtom || (desc = view.docView.descAt(nodePos)) && !desc.contentDOM)) { return false } + if (prosemirrorState.NodeSelection.isSelectable(node)) { + return apply(view, new prosemirrorState.NodeSelection(dir < 0 ? view.state.doc.resolve($head.pos - node.nodeSize) : $head)) + } else if (result.webkit) { + // Chrome and Safari will introduce extra pointless cursor + // positions around inline uneditable nodes, so we have to + // take over and move the cursor past them (#937) + return apply(view, new prosemirrorState.TextSelection(view.state.doc.resolve(dir < 0 ? nodePos : nodePos + node.nodeSize))) + } else { + return false + } + } + } else if (sel instanceof prosemirrorState.NodeSelection && sel.node.isInline) { + return apply(view, new prosemirrorState.TextSelection(dir > 0 ? sel.$to : sel.$from)) + } else { + var next$1 = moveSelectionBlock(view.state, dir); + if (next$1) { return apply(view, next$1) } + return false + } +} + +function nodeLen(node) { + return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length +} + +function isIgnorable(dom) { + var desc = dom.pmViewDesc; + return desc && desc.size == 0 && (dom.nextSibling || dom.nodeName != "BR") +} + +// Make sure the cursor isn't directly after one or more ignored +// nodes, which will confuse the browser's cursor motion logic. +function skipIgnoredNodesLeft(view) { + var sel = view.root.getSelection(); + var node = sel.focusNode, offset = sel.focusOffset; + if (!node) { return } + var moveNode, moveOffset, force = false; + // Gecko will do odd things when the selection is directly in front + // of a non-editable node, so in that case, move it into the next + // node if possible. Issue prosemirror/prosemirror#832. + if (result.gecko && node.nodeType == 1 && offset < nodeLen(node) && isIgnorable(node.childNodes[offset])) { force = true; } + for (;;) { + if (offset > 0) { + if (node.nodeType != 1) { + break + } else { + var before = node.childNodes[offset - 1]; + if (isIgnorable(before)) { + moveNode = node; + moveOffset = --offset; + } else if (before.nodeType == 3) { + node = before; + offset = node.nodeValue.length; + } else { break } + } + } else if (isBlockNode(node)) { + break + } else { + var prev = node.previousSibling; + while (prev && isIgnorable(prev)) { + moveNode = node.parentNode; + moveOffset = domIndex(prev); + prev = prev.previousSibling; + } + if (!prev) { + node = node.parentNode; + if (node == view.dom) { break } + offset = 0; + } else { + node = prev; + offset = nodeLen(node); + } + } + } + if (force) { setSelFocus(view, sel, node, offset); } + else if (moveNode) { setSelFocus(view, sel, moveNode, moveOffset); } +} + +// Make sure the cursor isn't directly before one or more ignored +// nodes. +function skipIgnoredNodesRight(view) { + var sel = view.root.getSelection(); + var node = sel.focusNode, offset = sel.focusOffset; + if (!node) { return } + var len = nodeLen(node); + var moveNode, moveOffset; + for (;;) { + if (offset < len) { + if (node.nodeType != 1) { break } + var after = node.childNodes[offset]; + if (isIgnorable(after)) { + moveNode = node; + moveOffset = ++offset; + } + else { break } + } else if (isBlockNode(node)) { + break + } else { + var next = node.nextSibling; + while (next && isIgnorable(next)) { + moveNode = next.parentNode; + moveOffset = domIndex(next) + 1; + next = next.nextSibling; + } + if (!next) { + node = node.parentNode; + if (node == view.dom) { break } + offset = len = 0; + } else { + node = next; + offset = 0; + len = nodeLen(node); + } + } + } + if (moveNode) { setSelFocus(view, sel, moveNode, moveOffset); } +} + +function isBlockNode(dom) { + var desc = dom.pmViewDesc; + return desc && desc.node && desc.node.isBlock +} + +function setSelFocus(view, sel, node, offset) { + if (selectionCollapsed(sel)) { + var range = document.createRange(); + range.setEnd(node, offset); + range.setStart(node, offset); + sel.removeAllRanges(); + sel.addRange(range); + } else if (sel.extend) { + sel.extend(node, offset); + } + view.domObserver.setCurSelection(); +} + +// : (EditorState, number) +// Check whether vertical selection motion would involve node +// selections. If so, apply it (if not, the result is left to the +// browser) +function selectVertically(view, dir, mods) { + var sel = view.state.selection; + if (sel instanceof prosemirrorState.TextSelection && !sel.empty || mods.indexOf("s") > -1) { return false } + var $from = sel.$from; + var $to = sel.$to; + + if (!$from.parent.inlineContent || view.endOfTextblock(dir < 0 ? "up" : "down")) { + var next = moveSelectionBlock(view.state, dir); + if (next && (next instanceof prosemirrorState.NodeSelection)) + { return apply(view, next) } + } + if (!$from.parent.inlineContent) { + var beyond = prosemirrorState.Selection.findFrom(dir < 0 ? $from : $to, dir); + return beyond ? apply(view, beyond) : true + } + return false +} + +function stopNativeHorizontalDelete(view, dir) { + if (!(view.state.selection instanceof prosemirrorState.TextSelection)) { return true } + var ref = view.state.selection; + var $head = ref.$head; + var $anchor = ref.$anchor; + var empty = ref.empty; + if (!$head.sameParent($anchor)) { return true } + if (!empty) { return false } + if (view.endOfTextblock(dir > 0 ? "forward" : "backward")) { return true } + var nextNode = !$head.textOffset && (dir < 0 ? $head.nodeBefore : $head.nodeAfter); + if (nextNode && !nextNode.isText) { + var tr = view.state.tr; + if (dir < 0) { tr.delete($head.pos - nextNode.nodeSize, $head.pos); } + else { tr.delete($head.pos, $head.pos + nextNode.nodeSize); } + view.dispatch(tr); + return true + } + return false +} + +function switchEditable(view, node, state) { + view.domObserver.stop(); + node.contentEditable = state; + view.domObserver.start(); +} + +// Issue #867 / https://bugs.chromium.org/p/chromium/issues/detail?id=903821 +// In which Chrome does really wrong things when the down arrow is +// pressed when the cursor is directly at the start of a textblock and +// has an uneditable node after it +function chromeDownArrowBug(view) { + if (!result.chrome || view.state.selection.$head.parentOffset > 0) { return } + var ref = view.root.getSelection(); + var focusNode = ref.focusNode; + var focusOffset = ref.focusOffset; + if (focusNode && focusNode.nodeType == 1 && focusOffset == 0 && + focusNode.firstChild && focusNode.firstChild.contentEditable == "false") { + var child = focusNode.firstChild; + switchEditable(view, child, true); + setTimeout(function () { return switchEditable(view, child, false); }, 20); + } +} + +// A backdrop key mapping used to make sure we always suppress keys +// that have a dangerous default effect, even if the commands they are +// bound to return false, and to make sure that cursor-motion keys +// find a cursor (as opposed to a node selection) when pressed. For +// cursor-motion keys, the code in the handlers also takes care of +// block selections. + +function getMods(event) { + var result = ""; + if (event.ctrlKey) { result += "c"; } + if (event.metaKey) { result += "m"; } + if (event.altKey) { result += "a"; } + if (event.shiftKey) { result += "s"; } + return result +} + +function captureKeyDown(view, event) { + var code = event.keyCode, mods = getMods(event); + if (code == 8 || (result.mac && code == 72 && mods == "c")) { // Backspace, Ctrl-h on Mac + return stopNativeHorizontalDelete(view, -1) || skipIgnoredNodesLeft(view) + } else if (code == 46 || (result.mac && code == 68 && mods == "c")) { // Delete, Ctrl-d on Mac + return stopNativeHorizontalDelete(view, 1) || skipIgnoredNodesRight(view) + } else if (code == 13 || code == 27) { // Enter, Esc + return true + } else if (code == 37) { // Left arrow + return selectHorizontally(view, -1, mods) || skipIgnoredNodesLeft(view) + } else if (code == 39) { // Right arrow + return selectHorizontally(view, 1, mods) || skipIgnoredNodesRight(view) + } else if (code == 38) { // Up arrow + return selectVertically(view, -1, mods) || skipIgnoredNodesLeft(view) + } else if (code == 40) { // Down arrow + return chromeDownArrowBug(view) || selectVertically(view, 1, mods) || skipIgnoredNodesRight(view) + } else if (mods == (result.mac ? "m" : "c") && + (code == 66 || code == 73 || code == 89 || code == 90)) { // Mod-[biyz] + return true + } + return false +} + +function selectionFromDOM(view, origin) { + var domSel = view.root.getSelection(), doc = view.state.doc; + var nearestDesc = view.docView.nearestDesc(domSel.focusNode), inWidget = nearestDesc && nearestDesc.size == 0; + var head = view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset); + var $head = doc.resolve(head), $anchor, selection; + if (selectionCollapsed(domSel)) { + $anchor = $head; + while (nearestDesc && !nearestDesc.node) { nearestDesc = nearestDesc.parent; } + if (nearestDesc && nearestDesc.node.isAtom && prosemirrorState.NodeSelection.isSelectable(nearestDesc.node) && nearestDesc.parent) { + var pos = nearestDesc.posBefore; + selection = new prosemirrorState.NodeSelection(head == pos ? $head : doc.resolve(pos)); + } + } else { + $anchor = doc.resolve(view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset)); + } + + if (!selection) { + var bias = origin == "pointer" || (view.state.selection.head < $head.pos && !inWidget) ? 1 : -1; + selection = selectionBetween(view, $anchor, $head, bias); + } + return selection +} + +function selectionToDOM(view, force) { + var sel = view.state.selection; + syncNodeSelection(view, sel); + + if (view.editable ? !view.hasFocus() : !(hasSelection(view) && document.activeElement.contains(view.dom))) { return } + + view.domObserver.disconnectSelection(); + + if (view.cursorWrapper) { + selectCursorWrapper(view); + } else { + var anchor = sel.anchor; + var head = sel.head; + var resetEditableFrom, resetEditableTo; + if (brokenSelectBetweenUneditable && !(sel instanceof prosemirrorState.TextSelection)) { + if (!sel.$from.parent.inlineContent) + { resetEditableFrom = temporarilyEditableNear(view, sel.from); } + if (!sel.empty && !sel.$from.parent.inlineContent) + { resetEditableTo = temporarilyEditableNear(view, sel.to); } + } + view.docView.setSelection(anchor, head, view.root, force); + if (brokenSelectBetweenUneditable) { + if (resetEditableFrom) { resetEditableFrom.contentEditable = "false"; } + if (resetEditableTo) { resetEditableTo.contentEditable = "false"; } + } + if (sel.visible) { + view.dom.classList.remove("ProseMirror-hideselection"); + } else if (anchor != head) { + view.dom.classList.add("ProseMirror-hideselection"); + if ("onselectionchange" in document) { removeClassOnSelectionChange(view); } + } + } + + view.domObserver.setCurSelection(); + view.domObserver.connectSelection(); +} + +// Kludge to work around Webkit not allowing a selection to start/end +// between non-editable block nodes. We briefly make something +// editable, set the selection, then set it uneditable again. + +var brokenSelectBetweenUneditable = result.safari || result.chrome && result.chrome_version < 63; + +function temporarilyEditableNear(view, pos) { + var ref = view.docView.domFromPos(pos); + var node = ref.node; + var offset = ref.offset; + var after = offset < node.childNodes.length ? node.childNodes[offset] : null; + var before = offset ? node.childNodes[offset - 1] : null; + if ((!after || after.contentEditable == "false") && (!before || before.contentEditable == "false")) { + if (after) { + after.contentEditable = "true"; + return after + } else if (before) { + before.contentEditable = "true"; + return before + } + } +} + +function removeClassOnSelectionChange(view) { + var doc = view.dom.ownerDocument; + doc.removeEventListener("selectionchange", view.hideSelectionGuard); + var domSel = view.root.getSelection(); + var node = domSel.anchorNode, offset = domSel.anchorOffset; + doc.addEventListener("selectionchange", view.hideSelectionGuard = function () { + if (domSel.anchorNode != node || domSel.anchorOffset != offset) { + doc.removeEventListener("selectionchange", view.hideSelectionGuard); + view.dom.classList.remove("ProseMirror-hideselection"); + } + }); +} + +function selectCursorWrapper(view) { + var domSel = view.root.getSelection(), range = document.createRange(); + var node = view.cursorWrapper.dom, img = node.nodeName == "IMG"; + if (img) { range.setEnd(node.parentNode, domIndex(node) + 1); } + else { range.setEnd(node, 0); } + range.collapse(false); + domSel.removeAllRanges(); + domSel.addRange(range); + // Kludge to kill 'control selection' in IE11 when selecting an + // invisible cursor wrapper, since that would result in those weird + // resize handles and a selection that considers the absolutely + // positioned wrapper, rather than the root editable node, the + // focused element. + if (!img && !view.state.selection.visible && result.ie && result.ie_version <= 11) { + node.disabled = true; + node.disabled = false; + } +} + +function syncNodeSelection(view, sel) { + if (sel instanceof prosemirrorState.NodeSelection) { + var desc = view.docView.descAt(sel.from); + if (desc != view.lastSelectedViewDesc) { + clearNodeSelection(view); + if (desc) { desc.selectNode(); } + view.lastSelectedViewDesc = desc; + } + } else { + clearNodeSelection(view); + } +} + +// Clear all DOM statefulness of the last node selection. +function clearNodeSelection(view) { + if (view.lastSelectedViewDesc) { + if (view.lastSelectedViewDesc.parent) + { view.lastSelectedViewDesc.deselectNode(); } + view.lastSelectedViewDesc = null; + } +} + +function selectionBetween(view, $anchor, $head, bias) { + return view.someProp("createSelectionBetween", function (f) { return f(view, $anchor, $head); }) + || prosemirrorState.TextSelection.between($anchor, $head, bias) +} + +function hasFocusAndSelection(view) { + if (view.editable && view.root.activeElement != view.dom) { return false } + return hasSelection(view) +} + +function hasSelection(view) { + var sel = view.root.getSelection(); + if (!sel.anchorNode) { return false } + try { + // Firefox will raise 'permission denied' errors when accessing + // properties of `sel.anchorNode` when it's in a generated CSS + // element. + return view.dom.contains(sel.anchorNode.nodeType == 3 ? sel.anchorNode.parentNode : sel.anchorNode) && + (view.editable || view.dom.contains(sel.focusNode.nodeType == 3 ? sel.focusNode.parentNode : sel.focusNode)) + } catch(_) { + return false + } +} + +function anchorInRightPlace(view) { + var anchorDOM = view.docView.domFromPos(view.state.selection.anchor); + var domSel = view.root.getSelection(); + return isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset) +} + +// Note that all referencing and parsing is done with the +// start-of-operation selection and document, since that's the one +// that the DOM represents. If any changes came in in the meantime, +// the modification is mapped over those before it is applied, in +// readDOMChange. + +function parseBetween(view, from_, to_) { + var ref = view.docView.parseRange(from_, to_); + var parent = ref.node; + var fromOffset = ref.fromOffset; + var toOffset = ref.toOffset; + var from = ref.from; + var to = ref.to; + + var domSel = view.root.getSelection(), find = null, anchor = domSel.anchorNode; + if (anchor && view.dom.contains(anchor.nodeType == 1 ? anchor : anchor.parentNode)) { + find = [{node: anchor, offset: domSel.anchorOffset}]; + if (!selectionCollapsed(domSel)) + { find.push({node: domSel.focusNode, offset: domSel.focusOffset}); } + } + // Work around issue in Chrome where backspacing sometimes replaces + // the deleted content with a random BR node (issues #799, #831) + if (result.chrome && view.lastKeyCode === 8) { + for (var off = toOffset; off > fromOffset; off--) { + var node = parent.childNodes[off - 1], desc = node.pmViewDesc; + if (node.nodeType == "BR" && !desc) { toOffset = off; break } + if (!desc || desc.size) { break } + } + } + var startDoc = view.state.doc; + var parser = view.someProp("domParser") || prosemirrorModel.DOMParser.fromSchema(view.state.schema); + var $from = startDoc.resolve(from); + + var sel = null, doc = parser.parse(parent, { + topNode: $from.parent, + topMatch: $from.parent.contentMatchAt($from.index()), + topOpen: true, + from: fromOffset, + to: toOffset, + preserveWhitespace: $from.parent.type.spec.code ? "full" : true, + editableContent: true, + findPositions: find, + ruleFromNode: ruleFromNode, + context: $from + }); + if (find && find[0].pos != null) { + var anchor$1 = find[0].pos, head = find[1] && find[1].pos; + if (head == null) { head = anchor$1; } + sel = {anchor: anchor$1 + from, head: head + from}; + } + return {doc: doc, sel: sel, from: from, to: to} +} + +function ruleFromNode(dom) { + var desc = dom.pmViewDesc; + if (desc) { + return desc.parseRule() + } else if (dom.nodeName == "BR" && dom.parentNode) { + // Safari replaces the list item or table cell with a BR + // directly in the list node (?!) if you delete the last + // character in a list item or table cell (#708, #862) + if (result.safari && /^(ul|ol)$/i.test(dom.parentNode.nodeName)) { + var skip = document.createElement("div"); + skip.appendChild(document.createElement("li")); + return {skip: skip} + } else if (dom.parentNode.lastChild == dom || result.safari && /^(tr|table)$/i.test(dom.parentNode.nodeName)) { + return {ignore: true} + } + } else if (dom.nodeName == "IMG" && dom.getAttribute("mark-placeholder")) { + return {ignore: true} + } +} + +function readDOMChange(view, from, to, typeOver) { + if (from < 0) { + var origin = view.lastSelectionTime > Date.now() - 50 ? view.lastSelectionOrigin : null; + var newSel = selectionFromDOM(view, origin); + if (!view.state.selection.eq(newSel)) { + var tr$1 = view.state.tr.setSelection(newSel); + if (origin == "pointer") { tr$1.setMeta("pointer", true); } + else if (origin == "key") { tr$1.scrollIntoView(); } + view.dispatch(tr$1); + } + return + } + + var $before = view.state.doc.resolve(from); + var shared = $before.sharedDepth(to); + from = $before.before(shared + 1); + to = view.state.doc.resolve(to).after(shared + 1); + + var sel = view.state.selection; + var parse = parseBetween(view, from, to); + + var doc = view.state.doc, compare = doc.slice(parse.from, parse.to); + var preferredPos, preferredSide; + // Prefer anchoring to end when Backspace is pressed + if (view.lastKeyCode === 8 && Date.now() - 100 < view.lastKeyCodeTime) { + preferredPos = view.state.selection.to; + preferredSide = "end"; + } else { + preferredPos = view.state.selection.from; + preferredSide = "start"; + } + view.lastKeyCode = null; + + var change = findDiff(compare.content, parse.doc.content, parse.from, preferredPos, preferredSide); + if (!change) { + if (typeOver && sel instanceof prosemirrorState.TextSelection && !sel.empty && sel.$head.sameParent(sel.$anchor) && + !view.composing && !(parse.sel && parse.sel.anchor != parse.sel.head)) { + change = {start: sel.from, endA: sel.to, endB: sel.to}; + } else { + if (parse.sel) { + var sel$1 = resolveSelection(view, view.state.doc, parse.sel); + if (sel$1 && !sel$1.eq(view.state.selection)) { view.dispatch(view.state.tr.setSelection(sel$1)); } + } + return + } + } + view.domChangeCount++; + // Handle the case where overwriting a selection by typing matches + // the start or end of the selected content, creating a change + // that's smaller than what was actually overwritten. + if (view.state.selection.from < view.state.selection.to && + change.start == change.endB && + view.state.selection instanceof prosemirrorState.TextSelection) { + if (change.start > view.state.selection.from && change.start <= view.state.selection.from + 2) { + change.start = view.state.selection.from; + } else if (change.endA < view.state.selection.to && change.endA >= view.state.selection.to - 2) { + change.endB += (view.state.selection.to - change.endA); + change.endA = view.state.selection.to; + } + } + + // IE11 will insert a non-breaking space _ahead_ of the space after + // the cursor space when adding a space before another space. When + // that happened, adjust the change to cover the space instead. + if (result.ie && result.ie_version <= 11 && change.endB == change.start + 1 && + change.endA == change.start && change.start > parse.from && + parse.doc.textBetween(change.start - parse.from - 1, change.start - parse.from + 1) == " \u00a0") { + change.start--; + change.endA--; + change.endB--; + } + + var $from = parse.doc.resolveNoCache(change.start - parse.from); + var $to = parse.doc.resolveNoCache(change.endB - parse.from); + var nextSel; + // If this looks like the effect of pressing Enter, just dispatch an + // Enter key instead. + if (!$from.sameParent($to) && $from.pos < parse.doc.content.size && + (nextSel = prosemirrorState.Selection.findFrom(parse.doc.resolve($from.pos + 1), 1, true)) && + nextSel.head == $to.pos && + view.someProp("handleKeyDown", function (f) { return f(view, keyEvent(13, "Enter")); })) + { return } + // Same for backspace + if (view.state.selection.anchor > change.start && + looksLikeJoin(doc, change.start, change.endA, $from, $to) && + view.someProp("handleKeyDown", function (f) { return f(view, keyEvent(8, "Backspace")); })) { + if (result.android && result.chrome) { view.domObserver.suppressSelectionUpdates(); } // #820 + return + } + + var chFrom = change.start, chTo = change.endA; + + var tr, storedMarks, markChange, $from1; + if ($from.sameParent($to) && $from.parent.inlineContent) { + if ($from.pos == $to.pos) { // Deletion + // IE11 sometimes weirdly moves the DOM selection around after + // backspacing out the first element in a textblock + if (result.ie && result.ie_version <= 11 && $from.parentOffset == 0) { + view.domObserver.suppressSelectionUpdates(); + setTimeout(function () { return selectionToDOM(view); }, 20); + } + tr = view.state.tr.delete(chFrom, chTo); + storedMarks = doc.resolve(change.start).marksAcross(doc.resolve(change.endA)); + } else if ( // Adding or removing a mark + change.endA == change.endB && ($from1 = doc.resolve(change.start)) && + (markChange = isMarkChange($from.parent.content.cut($from.parentOffset, $to.parentOffset), + $from1.parent.content.cut($from1.parentOffset, change.endA - $from1.start()))) + ) { + tr = view.state.tr; + if (markChange.type == "add") { tr.addMark(chFrom, chTo, markChange.mark); } + else { tr.removeMark(chFrom, chTo, markChange.mark); } + } else if ($from.parent.child($from.index()).isText && $from.index() == $to.index() - ($to.textOffset ? 0 : 1)) { + // Both positions in the same text node -- simply insert text + var text = $from.parent.textBetween($from.parentOffset, $to.parentOffset); + if (view.someProp("handleTextInput", function (f) { return f(view, chFrom, chTo, text); })) { return } + tr = view.state.tr.insertText(text, chFrom, chTo); + } + } + + if (!tr) + { tr = view.state.tr.replace(chFrom, chTo, parse.doc.slice(change.start - parse.from, change.endB - parse.from)); } + if (parse.sel) { + var sel$2 = resolveSelection(view, tr.doc, parse.sel); + // Chrome Android will sometimes, during composition, report the + // selection in the wrong place. If it looks like that is + // happening, don't update the selection. + // Edge just doesn't move the cursor forward when you start typing + // in an empty block or between br nodes. + if (sel$2 && !(result.chrome && result.android && view.composing && sel$2.empty && sel$2.head == chFrom || + result.ie && sel$2.empty && sel$2.head == chFrom)) + { tr.setSelection(sel$2); } + } + if (storedMarks) { tr.ensureMarks(storedMarks); } + view.dispatch(tr.scrollIntoView()); +} + +function resolveSelection(view, doc, parsedSel) { + if (Math.max(parsedSel.anchor, parsedSel.head) > doc.content.size) { return null } + return selectionBetween(view, doc.resolve(parsedSel.anchor), doc.resolve(parsedSel.head)) +} + +// : (Fragment, Fragment) → ?{mark: Mark, type: string} +// Given two same-length, non-empty fragments of inline content, +// determine whether the first could be created from the second by +// removing or adding a single mark type. +function isMarkChange(cur, prev) { + var curMarks = cur.firstChild.marks, prevMarks = prev.firstChild.marks; + var added = curMarks, removed = prevMarks, type, mark, update; + for (var i = 0; i < prevMarks.length; i++) { added = prevMarks[i].removeFromSet(added); } + for (var i$1 = 0; i$1 < curMarks.length; i$1++) { removed = curMarks[i$1].removeFromSet(removed); } + if (added.length == 1 && removed.length == 0) { + mark = added[0]; + type = "add"; + update = function (node) { return node.mark(mark.addToSet(node.marks)); }; + } else if (added.length == 0 && removed.length == 1) { + mark = removed[0]; + type = "remove"; + update = function (node) { return node.mark(mark.removeFromSet(node.marks)); }; + } else { + return null + } + var updated = []; + for (var i$2 = 0; i$2 < prev.childCount; i$2++) { updated.push(update(prev.child(i$2))); } + if (prosemirrorModel.Fragment.from(updated).eq(cur)) { return {mark: mark, type: type} } +} + +function looksLikeJoin(old, start, end, $newStart, $newEnd) { + if (!$newStart.parent.isTextblock || + // The content must have shrunk + end - start <= $newEnd.pos - $newStart.pos || + // newEnd must point directly at or after the end of the block that newStart points into + skipClosingAndOpening($newStart, true, false) < $newEnd.pos) + { return false } + + var $start = old.resolve(start); + // Start must be at the end of a block + if ($start.parentOffset < $start.parent.content.size || !$start.parent.isTextblock) + { return false } + var $next = old.resolve(skipClosingAndOpening($start, true, true)); + // The next textblock must start before end and end near it + if (!$next.parent.isTextblock || $next.pos > end || + skipClosingAndOpening($next, true, false) < end) + { return false } + + // The fragments after the join point must match + return $newStart.parent.content.cut($newStart.parentOffset).eq($next.parent.content) +} + +function skipClosingAndOpening($pos, fromEnd, mayOpen) { + var depth = $pos.depth, end = fromEnd ? $pos.end() : $pos.pos; + while (depth > 0 && (fromEnd || $pos.indexAfter(depth) == $pos.node(depth).childCount)) { + depth--; + end++; + fromEnd = false; + } + if (mayOpen) { + var next = $pos.node(depth).maybeChild($pos.indexAfter(depth)); + while (next && !next.isLeaf) { + next = next.firstChild; + end++; + } + } + return end +} + +function findDiff(a, b, pos, preferredPos, preferredSide) { + var start = a.findDiffStart(b, pos); + if (start == null) { return null } + var ref = a.findDiffEnd(b, pos + a.size, pos + b.size); + var endA = ref.a; + var endB = ref.b; + if (preferredSide == "end") { + var adjust = Math.max(0, start - Math.min(endA, endB)); + preferredPos -= endA + adjust - start; + } + if (endA < start && a.size < b.size) { + var move = preferredPos <= start && preferredPos >= endA ? start - preferredPos : 0; + start -= move; + endB = start + (endB - endA); + endA = start; + } else if (endB < start) { + var move$1 = preferredPos <= start && preferredPos >= endB ? start - preferredPos : 0; + start -= move$1; + endA = start + (endA - endB); + endB = start; + } + return {start: start, endA: endA, endB: endB} +} + +function serializeForClipboard(view, slice) { + var context = []; + var content = slice.content; + var openStart = slice.openStart; + var openEnd = slice.openEnd; + while (openStart > 1 && openEnd > 1 && content.childCount == 1 && content.firstChild.childCount == 1) { + openStart--; + openEnd--; + var node = content.firstChild; + context.push(node.type.name, node.type.hasRequiredAttrs() ? node.attrs : null); + content = node.content; + } + + var serializer = view.someProp("clipboardSerializer") || prosemirrorModel.DOMSerializer.fromSchema(view.state.schema); + var doc = detachedDoc(), wrap = doc.createElement("div"); + wrap.appendChild(serializer.serializeFragment(content, {document: doc})); + + var firstChild = wrap.firstChild, needsWrap; + while (firstChild && firstChild.nodeType == 1 && (needsWrap = wrapMap[firstChild.nodeName.toLowerCase()])) { + for (var i = needsWrap.length - 1; i >= 0; i--) { + var wrapper = doc.createElement(needsWrap[i]); + while (wrap.firstChild) { wrapper.appendChild(wrap.firstChild); } + wrap.appendChild(wrapper); + } + firstChild = wrap.firstChild; + } + + if (firstChild && firstChild.nodeType == 1) + { firstChild.setAttribute("data-pm-slice", (openStart + " " + openEnd + " " + (JSON.stringify(context)))); } + + var text = view.someProp("clipboardTextSerializer", function (f) { return f(slice); }) || + slice.content.textBetween(0, slice.content.size, "\n\n"); + + return {dom: wrap, text: text} +} + +// : (EditorView, string, string, ?bool, ResolvedPos) → ?Slice +// Read a slice of content from the clipboard (or drop data). +function parseFromClipboard(view, text, html, plainText, $context) { + var dom, inCode = $context.parent.type.spec.code, slice; + if (!html && !text) { return null } + var asText = text && (plainText || inCode || !html); + if (asText) { + view.someProp("transformPastedText", function (f) { text = f(text); }); + if (inCode) { return new prosemirrorModel.Slice(prosemirrorModel.Fragment.from(view.state.schema.text(text)), 0, 0) } + var parsed = view.someProp("clipboardTextParser", function (f) { return f(text, $context); }); + if (parsed) { + slice = parsed; + } else { + dom = document.createElement("div"); + text.trim().split(/(?:\r\n?|\n)+/).forEach(function (block) { + dom.appendChild(document.createElement("p")).textContent = block; + }); + } + } else { + view.someProp("transformPastedHTML", function (f) { html = f(html); }); + dom = readHTML(html); + } + + var contextNode = dom && dom.querySelector("[data-pm-slice]"); + var sliceData = contextNode && /^(\d+) (\d+) (.*)/.exec(contextNode.getAttribute("data-pm-slice")); + if (!slice) { + var parser = view.someProp("clipboardParser") || view.someProp("domParser") || prosemirrorModel.DOMParser.fromSchema(view.state.schema); + slice = parser.parseSlice(dom, {preserveWhitespace: !!(asText || sliceData), context: $context}); + } + if (sliceData) + { slice = addContext(closeSlice(slice, +sliceData[1], +sliceData[2]), sliceData[3]); } + else // HTML wasn't created by ProseMirror. Make sure top-level siblings are coherent + { slice = prosemirrorModel.Slice.maxOpen(normalizeSiblings(slice.content, $context), false); } + + view.someProp("transformPasted", function (f) { slice = f(slice); }); + return slice +} + +// Takes a slice parsed with parseSlice, which means there hasn't been +// any content-expression checking done on the top nodes, tries to +// find a parent node in the current context that might fit the nodes, +// and if successful, rebuilds the slice so that it fits into that parent. +// +// This addresses the problem that Transform.replace expects a +// coherent slice, and will fail to place a set of siblings that don't +// fit anywhere in the schema. +function normalizeSiblings(fragment, $context) { + if (fragment.childCount < 2) { return fragment } + var loop = function ( d ) { + var parent = $context.node(d); + var match = parent.contentMatchAt($context.index(d)); + var lastWrap = (void 0), result = []; + fragment.forEach(function (node) { + if (!result) { return } + var wrap = match.findWrapping(node.type), inLast; + if (!wrap) { return result = null } + if (inLast = result.length && lastWrap.length && addToSibling(wrap, lastWrap, node, result[result.length - 1], 0)) { + result[result.length - 1] = inLast; + } else { + if (result.length) { result[result.length - 1] = closeRight(result[result.length - 1], lastWrap.length); } + var wrapped = withWrappers(node, wrap); + result.push(wrapped); + match = match.matchType(wrapped.type, wrapped.attrs); + lastWrap = wrap; + } + }); + if (result) { return { v: prosemirrorModel.Fragment.from(result) } } + }; + + for (var d = $context.depth; d >= 0; d--) { + var returned = loop( d ); + + if ( returned ) return returned.v; + } + return fragment +} + +function withWrappers(node, wrap, from) { + if ( from === void 0 ) from = 0; + + for (var i = wrap.length - 1; i >= from; i--) + { node = wrap[i].create(null, prosemirrorModel.Fragment.from(node)); } + return node +} + +// Used to group adjacent nodes wrapped in similar parents by +// normalizeSiblings into the same parent node +function addToSibling(wrap, lastWrap, node, sibling, depth) { + if (depth < wrap.length && depth < lastWrap.length && wrap[depth] == lastWrap[depth]) { + var inner = addToSibling(wrap, lastWrap, node, sibling.lastChild, depth + 1); + if (inner) { return sibling.copy(sibling.content.replaceChild(sibling.childCount - 1, inner)) } + var match = sibling.contentMatchAt(sibling.childCount); + if (match.matchType(depth == wrap.length - 1 ? node.type : wrap[depth + 1])) + { return sibling.copy(sibling.content.append(prosemirrorModel.Fragment.from(withWrappers(node, wrap, depth + 1)))) } + } +} + +function closeRight(node, depth) { + if (depth == 0) { return node } + var fragment = node.content.replaceChild(node.childCount - 1, closeRight(node.lastChild, depth - 1)); + var fill = node.contentMatchAt(node.childCount).fillBefore(prosemirrorModel.Fragment.empty, true); + return node.copy(fragment.append(fill)) +} + +function closeRange(fragment, side, from, to, depth, openEnd) { + var node = side < 0 ? fragment.firstChild : fragment.lastChild, inner = node.content; + if (depth < to - 1) { inner = closeRange(inner, side, from, to, depth + 1, openEnd); } + if (depth >= from) + { inner = side < 0 ? node.contentMatchAt(0).fillBefore(inner, fragment.childCount > 1 || openEnd <= depth).append(inner) + : inner.append(node.contentMatchAt(node.childCount).fillBefore(prosemirrorModel.Fragment.empty, true)); } + return fragment.replaceChild(side < 0 ? 0 : fragment.childCount - 1, node.copy(inner)) +} + +function closeSlice(slice, openStart, openEnd) { + if (openStart < slice.openStart) + { slice = new prosemirrorModel.Slice(closeRange(slice.content, -1, openStart, slice.openStart, 0, slice.openEnd), openStart, slice.openEnd); } + if (openEnd < slice.openEnd) + { slice = new prosemirrorModel.Slice(closeRange(slice.content, 1, openEnd, slice.openEnd, 0, 0), slice.openStart, openEnd); } + return slice +} + +// Trick from jQuery -- some elements must be wrapped in other +// elements for innerHTML to work. I.e. if you do `div.innerHTML = +// ".."` the table cells are ignored. +var wrapMap = {thead: ["table"], colgroup: ["table"], col: ["table", "colgroup"], + tr: ["table", "tbody"], td: ["table", "tbody", "tr"], th: ["table", "tbody", "tr"]}; + +var _detachedDoc = null; +function detachedDoc() { + return _detachedDoc || (_detachedDoc = document.implementation.createHTMLDocument("title")) +} + +function readHTML(html) { + var metas = /(\s*]*>)*/.exec(html); + if (metas) { html = html.slice(metas[0].length); } + var elt = detachedDoc().createElement("div"); + var firstTag = /(?:]*>)*<([a-z][^>\s]+)/i.exec(html), wrap, depth = 0; + if (wrap = firstTag && wrapMap[firstTag[1].toLowerCase()]) { + html = wrap.map(function (n) { return "<" + n + ">"; }).join("") + html + wrap.map(function (n) { return ""; }).reverse().join(""); + depth = wrap.length; + } + elt.innerHTML = html; + for (var i = 0; i < depth; i++) { elt = elt.firstChild; } + return elt +} + +function addContext(slice, context) { + if (!slice.size) { return slice } + var schema = slice.content.firstChild.type.schema, array; + try { array = JSON.parse(context); } + catch(e) { return slice } + var content = slice.content; + var openStart = slice.openStart; + var openEnd = slice.openEnd; + for (var i = array.length - 2; i >= 0; i -= 2) { + var type = schema.nodes[array[i]]; + if (!type || type.hasRequiredAttrs()) { break } + content = prosemirrorModel.Fragment.from(type.create(array[i + 1], content)); + openStart++; openEnd++; + } + return new prosemirrorModel.Slice(content, openStart, openEnd) +} + +var observeOptions = { + childList: true, + characterData: true, + characterDataOldValue: true, + attributes: true, + attributeOldValue: true, + subtree: true +}; +// IE11 has very broken mutation observers, so we also listen to DOMCharacterDataModified +var useCharData = result.ie && result.ie_version <= 11; + +var SelectionState = function SelectionState() { + this.anchorNode = this.anchorOffset = this.focusNode = this.focusOffset = null; +}; + +SelectionState.prototype.set = function set (sel) { + this.anchorNode = sel.anchorNode; this.anchorOffset = sel.anchorOffset; + this.focusNode = sel.focusNode; this.focusOffset = sel.focusOffset; +}; + +SelectionState.prototype.eq = function eq (sel) { + return sel.anchorNode == this.anchorNode && sel.anchorOffset == this.anchorOffset && + sel.focusNode == this.focusNode && sel.focusOffset == this.focusOffset +}; + +var DOMObserver = function DOMObserver(view, handleDOMChange) { + var this$1 = this; + + this.view = view; + this.handleDOMChange = handleDOMChange; + this.queue = []; + this.flushingSoon = false; + this.observer = window.MutationObserver && + new window.MutationObserver(function (mutations) { + for (var i = 0; i < mutations.length; i++) { this$1.queue.push(mutations[i]); } + // IE11 will sometimes (on backspacing out a single character + // text node after a BR node) call the observer callback + // before actually updating the DOM, which will cause + // ProseMirror to miss the change (see #930) + if (result.ie && result.ie_version <= 11 && mutations.some( + function (m) { return m.type == "childList" && m.removedNodes.length || + m.type == "characterData" && m.oldValue.length > m.target.nodeValue.length; })) + { this$1.flushSoon(); } + else + { this$1.flush(); } + }); + this.currentSelection = new SelectionState; + if (useCharData) { + this.onCharData = function (e) { + this$1.queue.push({target: e.target, type: "characterData", oldValue: e.prevValue}); + this$1.flushSoon(); + }; + } + this.onSelectionChange = this.onSelectionChange.bind(this); + this.suppressingSelectionUpdates = false; +}; + +DOMObserver.prototype.flushSoon = function flushSoon () { + var this$1 = this; + + if (!this.flushingSoon) { + this.flushingSoon = true; + window.setTimeout(function () { this$1.flushingSoon = false; this$1.flush(); }, 20); + } +}; + +DOMObserver.prototype.start = function start () { + if (this.observer) + { this.observer.observe(this.view.dom, observeOptions); } + if (useCharData) + { this.view.dom.addEventListener("DOMCharacterDataModified", this.onCharData); } + this.connectSelection(); +}; + +DOMObserver.prototype.stop = function stop () { + var this$1 = this; + + if (this.observer) { + var take = this.observer.takeRecords(); + if (take.length) { + for (var i = 0; i < take.length; i++) { this.queue.push(take[i]); } + window.setTimeout(function () { return this$1.flush(); }, 20); + } + this.observer.disconnect(); + } + if (useCharData) { this.view.dom.removeEventListener("DOMCharacterDataModified", this.onCharData); } + this.disconnectSelection(); +}; + +DOMObserver.prototype.connectSelection = function connectSelection () { + this.view.dom.ownerDocument.addEventListener("selectionchange", this.onSelectionChange); +}; + +DOMObserver.prototype.disconnectSelection = function disconnectSelection () { + this.view.dom.ownerDocument.removeEventListener("selectionchange", this.onSelectionChange); +}; + +DOMObserver.prototype.suppressSelectionUpdates = function suppressSelectionUpdates () { + var this$1 = this; + + this.suppressingSelectionUpdates = true; + setTimeout(function () { return this$1.suppressingSelectionUpdates = false; }, 50); +}; + +DOMObserver.prototype.onSelectionChange = function onSelectionChange () { + if (!hasFocusAndSelection(this.view)) { return } + if (this.suppressingSelectionUpdates) { return selectionToDOM(this.view) } + // Deletions on IE11 fire their events in the wrong order, giving + // us a selection change event before the DOM changes are + // reported. + if (result.ie && result.ie_version <= 11 && !this.view.state.selection.empty) { + var sel = this.view.root.getSelection(); + // Selection.isCollapsed isn't reliable on IE + if (sel.focusNode && isEquivalentPosition(sel.focusNode, sel.focusOffset, sel.anchorNode, sel.anchorOffset)) + { return this.flushSoon() } + } + this.flush(); +}; + +DOMObserver.prototype.setCurSelection = function setCurSelection () { + this.currentSelection.set(this.view.root.getSelection()); +}; + +DOMObserver.prototype.ignoreSelectionChange = function ignoreSelectionChange (sel) { + if (sel.rangeCount == 0) { return true } + var container = sel.getRangeAt(0).commonAncestorContainer; + var desc = this.view.docView.nearestDesc(container); + return desc && desc.ignoreMutation({type: "selection", target: container.nodeType == 3 ? container.parentNode : container}) +}; + +DOMObserver.prototype.flush = function flush () { + if (!this.view.docView || this.flushingSoon) { return } + var mutations = this.observer ? this.observer.takeRecords() : []; + if (this.queue.length) { + mutations = this.queue.concat(mutations); + this.queue.length = 0; + } + + var sel = this.view.root.getSelection(); + var newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasSelection(this.view) && !this.ignoreSelectionChange(sel); + + var from = -1, to = -1, typeOver = false, added = []; + if (this.view.editable) { + for (var i = 0; i < mutations.length; i++) { + var result$1 = this.registerMutation(mutations[i], added); + if (result$1) { + from = from < 0 ? result$1.from : Math.min(result$1.from, from); + to = to < 0 ? result$1.to : Math.max(result$1.to, to); + if (result$1.typeOver && !this.view.composing) { typeOver = true; } + } + } + } + + if (result.gecko && added.length > 1) { + var brs = added.filter(function (n) { return n.nodeName == "BR"; }); + if (brs.length == 2) { + var a = brs[0]; + var b = brs[1]; + if (a.parentNode && a.parentNode.parentNode == b.parentNode) { b.remove(); } + else { a.remove(); } + } + } + + if (from > -1 || newSel) { + if (from > -1) { + this.view.docView.markDirty(from, to); + checkCSS(this.view); + } + this.handleDOMChange(from, to, typeOver); + if (this.view.docView.dirty) { this.view.updateState(this.view.state); } + else if (!this.currentSelection.eq(sel)) { selectionToDOM(this.view); } + } +}; + +DOMObserver.prototype.registerMutation = function registerMutation (mut, added) { + // Ignore mutations inside nodes that were already noted as inserted + if (added.indexOf(mut.target) > -1) { return null } + var desc = this.view.docView.nearestDesc(mut.target); + if (mut.type == "attributes" && + (desc == this.view.docView || mut.attributeName == "contenteditable" || + // Firefox sometimes fires spurious events for null/empty styles + (mut.attributeName == "style" && !mut.oldValue && !mut.target.getAttribute("style")))) + { return null } + if (!desc || desc.ignoreMutation(mut)) { return null } + + if (mut.type == "childList") { + var prev = mut.previousSibling, next = mut.nextSibling; + if (result.ie && result.ie_version <= 11 && mut.addedNodes.length) { + // IE11 gives us incorrect next/prev siblings for some + // insertions, so if there are added nodes, recompute those + for (var i = 0; i < mut.addedNodes.length; i++) { + var ref = mut.addedNodes[i]; + var previousSibling = ref.previousSibling; + var nextSibling = ref.nextSibling; + if (!previousSibling || Array.prototype.indexOf.call(mut.addedNodes, previousSibling) < 0) { prev = previousSibling; } + if (!nextSibling || Array.prototype.indexOf.call(mut.addedNodes, nextSibling) < 0) { next = nextSibling; } + } + } + var fromOffset = prev && prev.parentNode == mut.target + ? domIndex(prev) + 1 : 0; + var from = desc.localPosFromDOM(mut.target, fromOffset, -1); + var toOffset = next && next.parentNode == mut.target + ? domIndex(next) : mut.target.childNodes.length; + for (var i$1 = 0; i$1 < mut.addedNodes.length; i$1++) { added.push(mut.addedNodes[i$1]); } + var to = desc.localPosFromDOM(mut.target, toOffset, 1); + return {from: from, to: to} + } else if (mut.type == "attributes") { + return {from: desc.posAtStart - desc.border, to: desc.posAtEnd + desc.border} + } else { // "characterData" + return { + from: desc.posAtStart, + to: desc.posAtEnd, + // An event was generated for a text change that didn't change + // any text. Mark the dom change to fall back to assuming the + // selection was typed over with an identical value if it can't + // find another change. + typeOver: mut.target.nodeValue == mut.oldValue + } + } +}; + +var cssChecked = false; + +function checkCSS(view) { + if (cssChecked) { return } + cssChecked = true; + if (getComputedStyle(view.dom).whiteSpace == "normal") + { console["warn"]("ProseMirror expects the CSS white-space property to be set, preferably to 'pre-wrap'. It is recommended to load style/prosemirror.css from the prosemirror-view package."); } +} + +// A collection of DOM events that occur within the editor, and callback functions +// to invoke when the event fires. +var handlers = {}, editHandlers = {}; + +function initInput(view) { + view.shiftKey = false; + view.mouseDown = null; + view.lastKeyCode = null; + view.lastKeyCodeTime = 0; + view.lastClick = {time: 0, x: 0, y: 0, type: ""}; + view.lastSelectionOrigin = null; + view.lastSelectionTime = 0; + + view.composing = false; + view.composingTimeout = null; + view.compositionNodes = []; + view.compositionEndedAt = -2e8; + + view.domObserver = new DOMObserver(view, function (from, to, typeOver) { return readDOMChange(view, from, to, typeOver); }); + view.domObserver.start(); + // Used by hacks like the beforeinput handler to check whether anything happened in the DOM + view.domChangeCount = 0; + + view.eventHandlers = Object.create(null); + var loop = function ( event ) { + var handler = handlers[event]; + view.dom.addEventListener(event, view.eventHandlers[event] = function (event) { + if (eventBelongsToView(view, event) && !runCustomHandler(view, event) && + (view.editable || !(event.type in editHandlers))) + { handler(view, event); } + }); + }; + + for (var event in handlers) loop( event ); + // On Safari, for reasons beyond my understanding, adding an input + // event handler makes an issue where the composition vanishes when + // you press enter go away. + if (result.safari) { view.dom.addEventListener("input", function () { return null; }); } + + ensureListeners(view); +} + +function setSelectionOrigin(view, origin) { + view.lastSelectionOrigin = origin; + view.lastSelectionTime = Date.now(); +} + +function destroyInput(view) { + view.domObserver.stop(); + for (var type in view.eventHandlers) + { view.dom.removeEventListener(type, view.eventHandlers[type]); } + clearTimeout(view.composingTimeout); +} + +function ensureListeners(view) { + view.someProp("handleDOMEvents", function (currentHandlers) { + for (var type in currentHandlers) { if (!view.eventHandlers[type]) + { view.dom.addEventListener(type, view.eventHandlers[type] = function (event) { return runCustomHandler(view, event); }); } } + }); +} + +function runCustomHandler(view, event) { + return view.someProp("handleDOMEvents", function (handlers) { + var handler = handlers[event.type]; + return handler ? handler(view, event) || event.defaultPrevented : false + }) +} + +function eventBelongsToView(view, event) { + if (!event.bubbles) { return true } + if (event.defaultPrevented) { return false } + for (var node = event.target; node != view.dom; node = node.parentNode) + { if (!node || node.nodeType == 11 || + (node.pmViewDesc && node.pmViewDesc.stopEvent(event))) + { return false } } + return true +} + +function dispatchEvent(view, event) { + if (!runCustomHandler(view, event) && handlers[event.type] && + (view.editable || !(event.type in editHandlers))) + { handlers[event.type](view, event); } +} + +editHandlers.keydown = function (view, event) { + view.shiftKey = event.keyCode == 16 || event.shiftKey; + if (inOrNearComposition(view, event)) { return } + view.lastKeyCode = event.keyCode; + view.lastKeyCodeTime = Date.now(); + if (view.someProp("handleKeyDown", function (f) { return f(view, event); }) || captureKeyDown(view, event)) + { event.preventDefault(); } + else + { setSelectionOrigin(view, "key"); } +}; + +editHandlers.keyup = function (view, e) { + if (e.keyCode == 16) { view.shiftKey = false; } +}; + +editHandlers.keypress = function (view, event) { + if (inOrNearComposition(view, event) || !event.charCode || + event.ctrlKey && !event.altKey || result.mac && event.metaKey) { return } + + if (view.someProp("handleKeyPress", function (f) { return f(view, event); })) { + event.preventDefault(); + return + } + + var sel = view.state.selection; + if (!(sel instanceof prosemirrorState.TextSelection) || !sel.$from.sameParent(sel.$to)) { + var text = String.fromCharCode(event.charCode); + if (!view.someProp("handleTextInput", function (f) { return f(view, sel.$from.pos, sel.$to.pos, text); })) + { view.dispatch(view.state.tr.insertText(text).scrollIntoView()); } + event.preventDefault(); + } +}; + +function eventCoords(event) { return {left: event.clientX, top: event.clientY} } + +function isNear(event, click) { + var dx = click.x - event.clientX, dy = click.y - event.clientY; + return dx * dx + dy * dy < 100 +} + +function runHandlerOnContext(view, propName, pos, inside, event) { + if (inside == -1) { return false } + var $pos = view.state.doc.resolve(inside); + var loop = function ( i ) { + if (view.someProp(propName, function (f) { return i > $pos.depth ? f(view, pos, $pos.nodeAfter, $pos.before(i), event, true) + : f(view, pos, $pos.node(i), $pos.before(i), event, false); })) + { return { v: true } } + }; + + for (var i = $pos.depth + 1; i > 0; i--) { + var returned = loop( i ); + + if ( returned ) return returned.v; + } + return false +} + +function updateSelection(view, selection, origin) { + if (!view.focused) { view.focus(); } + var tr = view.state.tr.setSelection(selection); + if (origin == "pointer") { tr.setMeta("pointer", true); } + view.dispatch(tr); +} + +function selectClickedLeaf(view, inside) { + if (inside == -1) { return false } + var $pos = view.state.doc.resolve(inside), node = $pos.nodeAfter; + if (node && node.isAtom && prosemirrorState.NodeSelection.isSelectable(node)) { + updateSelection(view, new prosemirrorState.NodeSelection($pos), "pointer"); + return true + } + return false +} + +function selectClickedNode(view, inside) { + if (inside == -1) { return false } + var sel = view.state.selection, selectedNode, selectAt; + if (sel instanceof prosemirrorState.NodeSelection) { selectedNode = sel.node; } + + var $pos = view.state.doc.resolve(inside); + for (var i = $pos.depth + 1; i > 0; i--) { + var node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i); + if (prosemirrorState.NodeSelection.isSelectable(node)) { + if (selectedNode && sel.$from.depth > 0 && + i >= sel.$from.depth && $pos.before(sel.$from.depth + 1) == sel.$from.pos) + { selectAt = $pos.before(sel.$from.depth); } + else + { selectAt = $pos.before(i); } + break + } + } + + if (selectAt != null) { + updateSelection(view, prosemirrorState.NodeSelection.create(view.state.doc, selectAt), "pointer"); + return true + } else { + return false + } +} + +function handleSingleClick(view, pos, inside, event, selectNode) { + return runHandlerOnContext(view, "handleClickOn", pos, inside, event) || + view.someProp("handleClick", function (f) { return f(view, pos, event); }) || + (selectNode ? selectClickedNode(view, inside) : selectClickedLeaf(view, inside)) +} + +function handleDoubleClick(view, pos, inside, event) { + return runHandlerOnContext(view, "handleDoubleClickOn", pos, inside, event) || + view.someProp("handleDoubleClick", function (f) { return f(view, pos, event); }) +} + +function handleTripleClick(view, pos, inside, event) { + return runHandlerOnContext(view, "handleTripleClickOn", pos, inside, event) || + view.someProp("handleTripleClick", function (f) { return f(view, pos, event); }) || + defaultTripleClick(view, inside) +} + +function defaultTripleClick(view, inside) { + var doc = view.state.doc; + if (inside == -1) { + if (doc.inlineContent) { + updateSelection(view, prosemirrorState.TextSelection.create(doc, 0, doc.content.size), "pointer"); + return true + } + return false + } + + var $pos = doc.resolve(inside); + for (var i = $pos.depth + 1; i > 0; i--) { + var node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i); + var nodePos = $pos.before(i); + if (node.inlineContent) + { updateSelection(view, prosemirrorState.TextSelection.create(doc, nodePos + 1, nodePos + 1 + node.content.size), "pointer"); } + else if (prosemirrorState.NodeSelection.isSelectable(node)) + { updateSelection(view, prosemirrorState.NodeSelection.create(doc, nodePos), "pointer"); } + else + { continue } + return true + } +} + +function forceDOMFlush(view) { + return endComposition(view) +} + +var selectNodeModifier = result.mac ? "metaKey" : "ctrlKey"; + +handlers.mousedown = function (view, event) { + view.shiftKey = event.shiftKey; + var flushed = forceDOMFlush(view); + var now = Date.now(), type = "singleClick"; + if (now - view.lastClick.time < 500 && isNear(event, view.lastClick) && !event[selectNodeModifier]) { + if (view.lastClick.type == "singleClick") { type = "doubleClick"; } + else if (view.lastClick.type == "doubleClick") { type = "tripleClick"; } + } + view.lastClick = {time: now, x: event.clientX, y: event.clientY, type: type}; + + var pos = view.posAtCoords(eventCoords(event)); + if (!pos) { return } + + if (type == "singleClick") + { view.mouseDown = new MouseDown(view, pos, event, flushed); } + else if ((type == "doubleClick" ? handleDoubleClick : handleTripleClick)(view, pos.pos, pos.inside, event)) + { event.preventDefault(); } + else + { setSelectionOrigin(view, "pointer"); } +}; + +var MouseDown = function MouseDown(view, pos, event, flushed) { + var this$1 = this; + + this.view = view; + this.startDoc = view.state.doc; + this.pos = pos; + this.event = event; + this.flushed = flushed; + this.selectNode = event[selectNodeModifier]; + this.allowDefault = event.shiftKey; + + var targetNode, targetPos; + if (pos.inside > -1) { + targetNode = view.state.doc.nodeAt(pos.inside); + targetPos = pos.inside; + } else { + var $pos = view.state.doc.resolve(pos.pos); + targetNode = $pos.parent; + targetPos = $pos.depth ? $pos.before() : 0; + } + + this.mightDrag = null; + + var target = flushed ? null : event.target; + var targetDesc = target ? view.docView.nearestDesc(target, true) : null; + this.target = targetDesc ? targetDesc.dom : null; + + if (targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false || + view.state.selection instanceof prosemirrorState.NodeSelection && targetPos == view.state.selection.from) + { this.mightDrag = {node: targetNode, + pos: targetPos, + addAttr: this.target && !this.target.draggable, + setUneditable: this.target && result.gecko && !this.target.hasAttribute("contentEditable")}; } + + if (this.target && this.mightDrag && (this.mightDrag.addAttr || this.mightDrag.setUneditable)) { + this.view.domObserver.stop(); + if (this.mightDrag.addAttr) { this.target.draggable = true; } + if (this.mightDrag.setUneditable) + { setTimeout(function () { return this$1.target.setAttribute("contentEditable", "false"); }, 20); } + this.view.domObserver.start(); + } + + view.root.addEventListener("mouseup", this.up = this.up.bind(this)); + view.root.addEventListener("mousemove", this.move = this.move.bind(this)); + setSelectionOrigin(view, "pointer"); +}; + +MouseDown.prototype.done = function done () { + this.view.root.removeEventListener("mouseup", this.up); + this.view.root.removeEventListener("mousemove", this.move); + if (this.mightDrag && this.target) { + this.view.domObserver.stop(); + if (this.mightDrag.addAttr) { this.target.draggable = false; } + if (this.mightDrag.setUneditable) { this.target.removeAttribute("contentEditable"); } + this.view.domObserver.start(); + } + this.view.mouseDown = null; +}; + +MouseDown.prototype.up = function up (event) { + this.done(); + + if (!this.view.dom.contains(event.target.nodeType == 3 ? event.target.parentNode : event.target)) + { return } + + var pos = this.pos; + if (this.view.state.doc != this.startDoc) { pos = this.view.posAtCoords(eventCoords(event)); } + + if (this.allowDefault || !pos) { + setSelectionOrigin(this.view, "pointer"); + } else if (handleSingleClick(this.view, pos.pos, pos.inside, event, this.selectNode)) { + event.preventDefault(); + } else if (this.flushed || + // Chrome will sometimes treat a node selection as a + // cursor, but still report that the node is selected + // when asked through getSelection. You'll then get a + // situation where clicking at the point where that + // (hidden) cursor is doesn't change the selection, and + // thus doesn't get a reaction from ProseMirror. This + // works around that. + (result.chrome && !(this.view.state.selection instanceof prosemirrorState.TextSelection) && + (pos.pos == this.view.state.selection.from || pos.pos == this.view.state.selection.to))) { + updateSelection(this.view, prosemirrorState.Selection.near(this.view.state.doc.resolve(pos.pos)), "pointer"); + event.preventDefault(); + } else { + setSelectionOrigin(this.view, "pointer"); + } +}; + +MouseDown.prototype.move = function move (event) { + if (!this.allowDefault && (Math.abs(this.event.x - event.clientX) > 4 || + Math.abs(this.event.y - event.clientY) > 4)) + { this.allowDefault = true; } + setSelectionOrigin(this.view, "pointer"); +}; + +handlers.touchdown = function (view) { + forceDOMFlush(view); + setSelectionOrigin(view, "pointer"); +}; + +handlers.contextmenu = function (view) { return forceDOMFlush(view); }; + +function inOrNearComposition(view, event) { + if (view.composing) { return true } + // See https://www.stum.de/2016/06/24/handling-ime-events-in-javascript/. + // On Japanese input method editors (IMEs), the Enter key is used to confirm character + // selection. On Safari, when Enter is pressed, compositionend and keydown events are + // emitted. The keydown event triggers newline insertion, which we don't want. + // This method returns true if the keydown event should be ignored. + // We only ignore it once, as pressing Enter a second time *should* insert a newline. + // Furthermore, the keydown event timestamp must be close to the compositionEndedAt timestamp. + // This guards against the case where compositionend is triggered without the keyboard + // (e.g. character confirmation may be done with the mouse), and keydown is triggered + // afterwards- we wouldn't want to ignore the keydown event in this case. + if (result.safari && Math.abs(event.timeStamp - view.compositionEndedAt) < 500) { + view.compositionEndedAt = -2e8; + return true + } + return false +} + +// Drop active composition after 5 seconds of inactivity on Android +var timeoutComposition = result.android ? 5000 : -1; + +editHandlers.compositionstart = editHandlers.compositionupdate = function (view) { + if (!view.composing) { + view.domObserver.flush(); + var state = view.state; + var $pos = state.selection.$from; + if (state.selection.empty && + (state.storedMarks || (!$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some(function (m) { return m.type.spec.inclusive === false; })))) { + // Need to wrap the cursor in mark nodes different from the ones in the DOM context + view.markCursor = view.state.storedMarks || $pos.marks(); + endComposition(view, true); + view.markCursor = null; + } else { + endComposition(view); + // In firefox, if the cursor is after but outside a marked node, + // the inserted text won't inherit the marks. So this moves it + // inside if necessary. + if (result.gecko && state.selection.empty && $pos.parentOffset && !$pos.textOffset && $pos.nodeBefore.marks.length) { + var sel = view.root.getSelection(); + for (var node = sel.focusNode, offset = sel.focusOffset; node && node.nodeType == 1 && offset != 0;) { + var before = offset < 0 ? node.lastChild : node.childNodes[offset - 1]; + if (before.nodeType == 3) { + sel.collapse(before, before.nodeValue.length); + break + } else { + node = before; + offset = -1; + } + } + } + } + view.composing = true; + } + scheduleComposeEnd(view, timeoutComposition); +}; + +editHandlers.compositionend = function (view, event) { + if (view.composing) { + view.composing = false; + view.compositionEndedAt = event.timeStamp; + scheduleComposeEnd(view, 20); + } +}; + +function scheduleComposeEnd(view, delay) { + clearTimeout(view.composingTimeout); + if (delay > -1) { view.composingTimeout = setTimeout(function () { return endComposition(view); }, delay); } +} + +function endComposition(view, forceUpdate) { + view.composing = false; + while (view.compositionNodes.length > 0) { view.compositionNodes.pop().markParentsDirty(); } + if (forceUpdate || view.docView.dirty) { + view.updateState(view.state); + return true + } + return false +} + +function captureCopy(view, dom) { + // The extra wrapper is somehow necessary on IE/Edge to prevent the + // content from being mangled when it is put onto the clipboard + var doc = view.dom.ownerDocument; + var wrap = doc.body.appendChild(doc.createElement("div")); + wrap.appendChild(dom); + wrap.style.cssText = "position: fixed; left: -10000px; top: 10px"; + var sel = getSelection(), range = doc.createRange(); + range.selectNodeContents(dom); + // Done because IE will fire a selectionchange moving the selection + // to its start when removeAllRanges is called and the editor still + // has focus (which will mess up the editor's selection state). + view.dom.blur(); + sel.removeAllRanges(); + sel.addRange(range); + setTimeout(function () { + doc.body.removeChild(wrap); + view.focus(); + }, 50); +} + +// This is very crude, but unfortunately both these browsers _pretend_ +// that they have a clipboard API—all the objects and methods are +// there, they just don't work, and they are hard to test. +var brokenClipboardAPI = (result.ie && result.ie_version < 15) || + (result.ios && result.webkit_version < 604); + +handlers.copy = editHandlers.cut = function (view, e) { + var sel = view.state.selection, cut = e.type == "cut"; + if (sel.empty) { return } + + // IE and Edge's clipboard interface is completely broken + var data = brokenClipboardAPI ? null : e.clipboardData; + var slice = sel.content(); + var ref = serializeForClipboard(view, slice); + var dom = ref.dom; + var text = ref.text; + if (data) { + e.preventDefault(); + data.clearData(); + data.setData("text/html", dom.innerHTML); + data.setData("text/plain", text); + } else { + captureCopy(view, dom); + } + if (cut) { view.dispatch(view.state.tr.deleteSelection().scrollIntoView().setMeta("uiEvent", "cut")); } +}; + +function sliceSingleNode(slice) { + return slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1 ? slice.content.firstChild : null +} + +function capturePaste(view, e) { + var doc = view.dom.ownerDocument; + var plainText = view.shiftKey || view.state.selection.$from.parent.type.spec.code; + var target = doc.body.appendChild(doc.createElement(plainText ? "textarea" : "div")); + if (!plainText) { target.contentEditable = "true"; } + target.style.cssText = "position: fixed; left: -10000px; top: 10px"; + target.focus(); + setTimeout(function () { + view.focus(); + doc.body.removeChild(target); + if (plainText) { doPaste(view, target.value, null, e); } + else { doPaste(view, target.textContent, target.innerHTML, e); } + }, 50); +} + +function doPaste(view, text, html, e) { + var slice = parseFromClipboard(view, text, html, view.shiftKey, view.state.selection.$from); + if (view.someProp("handlePaste", function (f) { return f(view, e, slice || prosemirrorModel.Slice.empty); }) || !slice) { return } + + var singleNode = sliceSingleNode(slice); + var tr = singleNode ? view.state.tr.replaceSelectionWith(singleNode, view.shiftKey) : view.state.tr.replaceSelection(slice); + view.dispatch(tr.scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste")); +} + +editHandlers.paste = function (view, e) { + var data = brokenClipboardAPI ? null : e.clipboardData; + var html = data && data.getData("text/html"), text = data && data.getData("text/plain"); + if (data && (html || text || data.files.length)) { + doPaste(view, text, html, e); + e.preventDefault(); + } else { + capturePaste(view, e); + } +}; + +var Dragging = function Dragging(slice, move) { + this.slice = slice; + this.move = move; +}; + +var dragCopyModifier = result.mac ? "altKey" : "ctrlKey"; + +handlers.dragstart = function (view, e) { + var mouseDown = view.mouseDown; + if (mouseDown) { mouseDown.done(); } + if (!e.dataTransfer) { return } + + var sel = view.state.selection; + var pos = sel.empty ? null : view.posAtCoords(eventCoords(e)); + if (pos && pos.pos >= sel.from && pos.pos <= (sel instanceof prosemirrorState.NodeSelection ? sel.to - 1: sel.to)) ; else if (mouseDown && mouseDown.mightDrag) { + view.dispatch(view.state.tr.setSelection(prosemirrorState.NodeSelection.create(view.state.doc, mouseDown.mightDrag.pos))); + } else if (e.target && e.target.nodeType == 1) { + var desc = view.docView.nearestDesc(e.target, true); + if (!desc || !desc.node.type.spec.draggable || desc == view.docView) { return } + view.dispatch(view.state.tr.setSelection(prosemirrorState.NodeSelection.create(view.state.doc, desc.posBefore))); + } + var slice = view.state.selection.content(); + var ref = serializeForClipboard(view, slice); + var dom = ref.dom; + var text = ref.text; + e.dataTransfer.clearData(); + e.dataTransfer.setData(brokenClipboardAPI ? "Text" : "text/html", dom.innerHTML); + if (!brokenClipboardAPI) { e.dataTransfer.setData("text/plain", text); } + view.dragging = new Dragging(slice, !e[dragCopyModifier]); +}; + +handlers.dragend = function (view) { + window.setTimeout(function () { return view.dragging = null; }, 50); +}; + +editHandlers.dragover = editHandlers.dragenter = function (_, e) { return e.preventDefault(); }; + +editHandlers.drop = function (view, e) { + var dragging = view.dragging; + view.dragging = null; + + if (!e.dataTransfer) { return } + + var eventPos = view.posAtCoords(eventCoords(e)); + if (!eventPos) { return } + var $mouse = view.state.doc.resolve(eventPos.pos); + if (!$mouse) { return } + var slice = dragging && dragging.slice || + parseFromClipboard(view, e.dataTransfer.getData(brokenClipboardAPI ? "Text" : "text/plain"), + brokenClipboardAPI ? null : e.dataTransfer.getData("text/html"), false, $mouse); + if (!slice) { return } + + e.preventDefault(); + if (view.someProp("handleDrop", function (f) { return f(view, e, slice, dragging && dragging.move); })) { return } + var insertPos = slice ? prosemirrorTransform.dropPoint(view.state.doc, $mouse.pos, slice) : $mouse.pos; + if (insertPos == null) { insertPos = $mouse.pos; } + + var tr = view.state.tr; + if (dragging && dragging.move) { tr.deleteSelection(); } + + var pos = tr.mapping.map(insertPos); + var isNode = slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1; + var beforeInsert = tr.doc; + if (isNode) + { tr.replaceRangeWith(pos, pos, slice.content.firstChild); } + else + { tr.replaceRange(pos, pos, slice); } + if (tr.doc.eq(beforeInsert)) { return } + + var $pos = tr.doc.resolve(pos); + if (isNode && prosemirrorState.NodeSelection.isSelectable(slice.content.firstChild) && + $pos.nodeAfter && $pos.nodeAfter.sameMarkup(slice.content.firstChild)) + { tr.setSelection(new prosemirrorState.NodeSelection($pos)); } + else + { tr.setSelection(selectionBetween(view, $pos, tr.doc.resolve(tr.mapping.map(insertPos)))); } + view.focus(); + view.dispatch(tr.setMeta("uiEvent", "drop")); +}; + +handlers.focus = function (view) { + if (!view.focused) { + view.domObserver.stop(); + view.dom.classList.add("ProseMirror-focused"); + view.domObserver.start(); + view.focused = true; + } +}; + +handlers.blur = function (view) { + if (view.focused) { + view.domObserver.stop(); + view.dom.classList.remove("ProseMirror-focused"); + view.domObserver.start(); + view.domObserver.currentSelection.set({}); + view.focused = false; + } +}; + +handlers.beforeinput = function (view, event) { + // We should probably do more with beforeinput events, but support + // is so spotty that I'm still waiting to see where they are going. + + // Very specific hack to deal with backspace sometimes failing on + // Chrome Android when after an uneditable node. + if (result.chrome && result.android && event.inputType == "deleteContentBackward") { + var domChangeCount = view.domChangeCount; + setTimeout(function () { + if (view.domChangeCount != domChangeCount) { return } // Event already had some effect + // This bug tends to close the virtual keyboard, so we refocus + view.dom.blur(); + view.focus(); + if (view.someProp("handleKeyDown", function (f) { return f(view, keyEvent(8, "Backspace")); })) { return } + var ref = view.state.selection; + var $cursor = ref.$cursor; + // Crude approximation of backspace behavior when no command handled it + if ($cursor && $cursor.pos > 0) { view.dispatch(view.state.tr.delete($cursor.pos - 1, $cursor.pos).scrollIntoView()); } + }, 50); + } +}; + +// Make sure all handlers get registered +for (var prop in editHandlers) { handlers[prop] = editHandlers[prop]; } + +function compareObjs(a, b) { + if (a == b) { return true } + for (var p in a) { if (a[p] !== b[p]) { return false } } + for (var p$1 in b) { if (!(p$1 in a)) { return false } } + return true +} + +var WidgetType = function WidgetType(toDOM, spec) { + this.spec = spec || noSpec; + this.side = this.spec.side || 0; + this.toDOM = toDOM; +}; + +WidgetType.prototype.map = function map (mapping, span, offset, oldOffset) { + var ref = mapping.mapResult(span.from + oldOffset, this.side < 0 ? -1 : 1); + var pos = ref.pos; + var deleted = ref.deleted; + return deleted ? null : new Decoration(pos - offset, pos - offset, this) +}; + +WidgetType.prototype.valid = function valid () { return true }; + +WidgetType.prototype.eq = function eq (other) { + return this == other || + (other instanceof WidgetType && + (this.spec.key && this.spec.key == other.spec.key || + this.toDOM == other.toDOM && compareObjs(this.spec, other.spec))) +}; + +var InlineType = function InlineType(attrs, spec) { + this.spec = spec || noSpec; + this.attrs = attrs; +}; + +InlineType.prototype.map = function map (mapping, span, offset, oldOffset) { + var from = mapping.map(span.from + oldOffset, this.spec.inclusiveStart ? -1 : 1) - offset; + var to = mapping.map(span.to + oldOffset, this.spec.inclusiveEnd ? 1 : -1) - offset; + return from >= to ? null : new Decoration(from, to, this) +}; + +InlineType.prototype.valid = function valid (_, span) { return span.from < span.to }; + +InlineType.prototype.eq = function eq (other) { + return this == other || + (other instanceof InlineType && compareObjs(this.attrs, other.attrs) && + compareObjs(this.spec, other.spec)) +}; + +InlineType.is = function is (span) { return span.type instanceof InlineType }; + +var NodeType = function NodeType(attrs, spec) { + this.spec = spec || noSpec; + this.attrs = attrs; +}; + +NodeType.prototype.map = function map (mapping, span, offset, oldOffset) { + var from = mapping.mapResult(span.from + oldOffset, 1); + if (from.deleted) { return null } + var to = mapping.mapResult(span.to + oldOffset, -1); + if (to.deleted || to.pos <= from.pos) { return null } + return new Decoration(from.pos - offset, to.pos - offset, this) +}; + +NodeType.prototype.valid = function valid (node, span) { + var ref = node.content.findIndex(span.from); + var index = ref.index; + var offset = ref.offset; + return offset == span.from && offset + node.child(index).nodeSize == span.to +}; + +NodeType.prototype.eq = function eq (other) { + return this == other || + (other instanceof NodeType && compareObjs(this.attrs, other.attrs) && + compareObjs(this.spec, other.spec)) +}; + +// ::- Decoration objects can be provided to the view through the +// [`decorations` prop](#view.EditorProps.decorations). They come in +// several variants—see the static members of this class for details. +var Decoration = function Decoration(from, to, type) { + // :: number + // The start position of the decoration. + this.from = from; + // :: number + // The end position. Will be the same as `from` for [widget + // decorations](#view.Decoration^widget). + this.to = to; + this.type = type; +}; + +var prototypeAccessors$1 = { spec: { configurable: true } }; + +Decoration.prototype.copy = function copy (from, to) { + return new Decoration(from, to, this.type) +}; + +Decoration.prototype.eq = function eq (other) { + return this.type.eq(other.type) && this.from == other.from && this.to == other.to +}; + +Decoration.prototype.map = function map (mapping, offset, oldOffset) { + return this.type.map(mapping, this, offset, oldOffset) +}; + +// :: (number, union<(view: EditorView, getPos: () → number) → dom.Node, dom.Node>, ?Object) → Decoration +// Creates a widget decoration, which is a DOM node that's shown in +// the document at the given position. It is recommended that you +// delay rendering the widget by passing a function that will be +// called when the widget is actually drawn in a view, but you can +// also directly pass a DOM node. `getPos` can be used to find the +// widget's current document position. +// +// spec::- These options are supported: +// +// side:: ?number +// Controls which side of the document position this widget is +// associated with. When negative, it is drawn before a cursor +// at its position, and content inserted at that position ends +// up after the widget. When zero (the default) or positive, the +// widget is drawn after the cursor and content inserted there +// ends up before the widget. +// +// When there are multiple widgets at a given position, their +// `side` values determine the order in which they appear. Those +// with lower values appear first. The ordering of widgets with +// the same `side` value is unspecified. +// +// When `marks` is null, `side` also determines the marks that +// the widget is wrapped in—those of the node before when +// negative, those of the node after when positive. +// +// marks:: ?[Mark] +// The precise set of marks to draw around the widget. +// +// stopEvent:: ?(event: dom.Event) → bool +// Can be used to control which DOM events, when they bubble out +// of this widget, the editor view should ignore. +// +// key:: ?string +// When comparing decorations of this type (in order to decide +// whether it needs to be redrawn), ProseMirror will by default +// compare the widget DOM node by identity. If you pass a key, +// that key will be compared instead, which can be useful when +// you generate decorations on the fly and don't want to store +// and reuse DOM nodes. Make sure that any widgets with the same +// key are interchangeable—if widgets differ in, for example, +// the behavior of some event handler, they should get +// different keys. +Decoration.widget = function widget (pos, toDOM, spec) { + return new Decoration(pos, pos, new WidgetType(toDOM, spec)) +}; + +// :: (number, number, DecorationAttrs, ?Object) → Decoration +// Creates an inline decoration, which adds the given attributes to +// each inline node between `from` and `to`. +// +// spec::- These options are recognized: +// +// inclusiveStart:: ?bool +// Determines how the left side of the decoration is +// [mapped](#transform.Position_Mapping) when content is +// inserted directly at that position. By default, the decoration +// won't include the new content, but you can set this to `true` +// to make it inclusive. +// +// inclusiveEnd:: ?bool +// Determines how the right side of the decoration is mapped. +// See +// [`inclusiveStart`](#view.Decoration^inline^spec.inclusiveStart). +Decoration.inline = function inline (from, to, attrs, spec) { + return new Decoration(from, to, new InlineType(attrs, spec)) +}; + +// :: (number, number, DecorationAttrs, ?Object) → Decoration +// Creates a node decoration. `from` and `to` should point precisely +// before and after a node in the document. That node, and only that +// node, will receive the given attributes. +// +// spec::- +// +// Optional information to store with the decoration. It +// is also used when comparing decorators for equality. +Decoration.node = function node (from, to, attrs, spec) { + return new Decoration(from, to, new NodeType(attrs, spec)) +}; + +// :: Object +// The spec provided when creating this decoration. Can be useful +// if you've stored extra information in that object. +prototypeAccessors$1.spec.get = function () { return this.type.spec }; + +Object.defineProperties( Decoration.prototype, prototypeAccessors$1 ); + +// DecorationAttrs:: interface +// A set of attributes to add to a decorated node. Most properties +// simply directly correspond to DOM attributes of the same name, +// which will be set to the property's value. These are exceptions: +// +// class:: ?string +// A CSS class name or a space-separated set of class names to be +// _added_ to the classes that the node already had. +// +// style:: ?string +// A string of CSS to be _added_ to the node's existing `style` property. +// +// nodeName:: ?string +// When non-null, the target node is wrapped in a DOM element of +// this type (and the other attributes are applied to this element). + +var none = [], noSpec = {}; + +// ::- A collection of [decorations](#view.Decoration), organized in +// such a way that the drawing algorithm can efficiently use and +// compare them. This is a persistent data structure—it is not +// modified, updates create a new value. +var DecorationSet = function DecorationSet(local, children) { + this.local = local && local.length ? local : none; + this.children = children && children.length ? children : none; +}; + +// :: (Node, [Decoration]) → DecorationSet +// Create a set of decorations, using the structure of the given +// document. +DecorationSet.create = function create (doc, decorations) { + return decorations.length ? buildTree(decorations, doc, 0, noSpec) : empty +}; + +// :: (?number, ?number, ?(spec: Object) → bool) → [Decoration] +// Find all decorations in this set which touch the given range +// (including decorations that start or end directly at the +// boundaries) and match the given predicate on their spec. When +// `start` and `end` are omitted, all decorations in the set are +// considered. When `predicate` isn't given, all decorations are +// assumed to match. +DecorationSet.prototype.find = function find (start, end, predicate) { + var result = []; + this.findInner(start == null ? 0 : start, end == null ? 1e9 : end, result, 0, predicate); + return result +}; + +DecorationSet.prototype.findInner = function findInner (start, end, result, offset, predicate) { + for (var i = 0; i < this.local.length; i++) { + var span = this.local[i]; + if (span.from <= end && span.to >= start && (!predicate || predicate(span.spec))) + { result.push(span.copy(span.from + offset, span.to + offset)); } + } + for (var i$1 = 0; i$1 < this.children.length; i$1 += 3) { + if (this.children[i$1] < end && this.children[i$1 + 1] > start) { + var childOff = this.children[i$1] + 1; + this.children[i$1 + 2].findInner(start - childOff, end - childOff, result, offset + childOff, predicate); + } + } +}; + +// :: (Mapping, Node, ?Object) → DecorationSet +// Map the set of decorations in response to a change in the +// document. +// +// options::- An optional set of options. +// +// onRemove:: ?(decorationSpec: Object) +// When given, this function will be called for each decoration +// that gets dropped as a result of the mapping, passing the +// spec of that decoration. +DecorationSet.prototype.map = function map (mapping, doc, options) { + if (this == empty || mapping.maps.length == 0) { return this } + return this.mapInner(mapping, doc, 0, 0, options || noSpec) +}; + +DecorationSet.prototype.mapInner = function mapInner (mapping, node, offset, oldOffset, options) { + var newLocal; + for (var i = 0; i < this.local.length; i++) { + var mapped = this.local[i].map(mapping, offset, oldOffset); + if (mapped && mapped.type.valid(node, mapped)) { (newLocal || (newLocal = [])).push(mapped); } + else if (options.onRemove) { options.onRemove(this.local[i].spec); } + } + + if (this.children.length) + { return mapChildren(this.children, newLocal, mapping, node, offset, oldOffset, options) } + else + { return newLocal ? new DecorationSet(newLocal.sort(byPos)) : empty } +}; + +// :: (Node, [Decoration]) → DecorationSet +// Add the given array of decorations to the ones in the set, +// producing a new set. Needs access to the current document to +// create the appropriate tree structure. +DecorationSet.prototype.add = function add (doc, decorations) { + if (!decorations.length) { return this } + if (this == empty) { return DecorationSet.create(doc, decorations) } + return this.addInner(doc, decorations, 0) +}; + +DecorationSet.prototype.addInner = function addInner (doc, decorations, offset) { + var this$1 = this; + + var children, childIndex = 0; + doc.forEach(function (childNode, childOffset) { + var baseOffset = childOffset + offset, found; + if (!(found = takeSpansForNode(decorations, childNode, baseOffset))) { return } + + if (!children) { children = this$1.children.slice(); } + while (childIndex < children.length && children[childIndex] < childOffset) { childIndex += 3; } + if (children[childIndex] == childOffset) + { children[childIndex + 2] = children[childIndex + 2].addInner(childNode, found, baseOffset + 1); } + else + { children.splice(childIndex, 0, childOffset, childOffset + childNode.nodeSize, buildTree(found, childNode, baseOffset + 1, noSpec)); } + childIndex += 3; + }); + + var local = moveSpans(childIndex ? withoutNulls(decorations) : decorations, -offset); + return new DecorationSet(local.length ? this.local.concat(local).sort(byPos) : this.local, + children || this.children) +}; + +// :: ([Decoration]) → DecorationSet +// Create a new set that contains the decorations in this set, minus +// the ones in the given array. +DecorationSet.prototype.remove = function remove (decorations) { + if (decorations.length == 0 || this == empty) { return this } + return this.removeInner(decorations, 0) +}; + +DecorationSet.prototype.removeInner = function removeInner (decorations, offset) { + var children = this.children, local = this.local; + for (var i = 0; i < children.length; i += 3) { + var found = (void 0), from = children[i] + offset, to = children[i + 1] + offset; + for (var j = 0, span = (void 0); j < decorations.length; j++) { if (span = decorations[j]) { + if (span.from > from && span.to < to) { + decorations[j] = null + ;(found || (found = [])).push(span); + } + } } + if (!found) { continue } + if (children == this.children) { children = this.children.slice(); } + var removed = children[i + 2].removeInner(found, from + 1); + if (removed != empty) { + children[i + 2] = removed; + } else { + children.splice(i, 3); + i -= 3; + } + } + if (local.length) { for (var i$1 = 0, span$1 = (void 0); i$1 < decorations.length; i$1++) { if (span$1 = decorations[i$1]) { + for (var j$1 = 0; j$1 < local.length; j$1++) { if (local[j$1].type.eq(span$1.type)) { + if (local == this.local) { local = this.local.slice(); } + local.splice(j$1--, 1); + } } + } } } + if (children == this.children && local == this.local) { return this } + return local.length || children.length ? new DecorationSet(local, children) : empty +}; + +DecorationSet.prototype.forChild = function forChild (offset, node) { + if (this == empty) { return this } + if (node.isLeaf) { return DecorationSet.empty } + + var child, local; + for (var i = 0; i < this.children.length; i += 3) { if (this.children[i] >= offset) { + if (this.children[i] == offset) { child = this.children[i + 2]; } + break + } } + var start = offset + 1, end = start + node.content.size; + for (var i$1 = 0; i$1 < this.local.length; i$1++) { + var dec = this.local[i$1]; + if (dec.from < end && dec.to > start && (dec.type instanceof InlineType)) { + var from = Math.max(start, dec.from) - start, to = Math.min(end, dec.to) - start; + if (from < to) { (local || (local = [])).push(dec.copy(from, to)); } + } + } + if (local) { + var localSet = new DecorationSet(local.sort(byPos)); + return child ? new DecorationGroup([localSet, child]) : localSet + } + return child || empty +}; + +DecorationSet.prototype.eq = function eq (other) { + if (this == other) { return true } + if (!(other instanceof DecorationSet) || + this.local.length != other.local.length || + this.children.length != other.children.length) { return false } + for (var i = 0; i < this.local.length; i++) + { if (!this.local[i].eq(other.local[i])) { return false } } + for (var i$1 = 0; i$1 < this.children.length; i$1 += 3) + { if (this.children[i$1] != other.children[i$1] || + this.children[i$1 + 1] != other.children[i$1 + 1] || + !this.children[i$1 + 2].eq(other.children[i$1 + 2])) { return false } } + return true +}; + +DecorationSet.prototype.locals = function locals (node) { + return removeOverlap(this.localsInner(node)) +}; + +DecorationSet.prototype.localsInner = function localsInner (node) { + if (this == empty) { return none } + if (node.inlineContent || !this.local.some(InlineType.is)) { return this.local } + var result = []; + for (var i = 0; i < this.local.length; i++) { + if (!(this.local[i].type instanceof InlineType)) + { result.push(this.local[i]); } + } + return result +}; + +var empty = new DecorationSet(); + +// :: DecorationSet +// The empty set of decorations. +DecorationSet.empty = empty; + +DecorationSet.removeOverlap = removeOverlap; + +// :- An abstraction that allows the code dealing with decorations to +// treat multiple DecorationSet objects as if it were a single object +// with (a subset of) the same interface. +var DecorationGroup = function DecorationGroup(members) { + this.members = members; +}; + +DecorationGroup.prototype.forChild = function forChild (offset, child) { + if (child.isLeaf) { return DecorationSet.empty } + var found = []; + for (var i = 0; i < this.members.length; i++) { + var result = this.members[i].forChild(offset, child); + if (result == empty) { continue } + if (result instanceof DecorationGroup) { found = found.concat(result.members); } + else { found.push(result); } + } + return DecorationGroup.from(found) +}; + +DecorationGroup.prototype.eq = function eq (other) { + if (!(other instanceof DecorationGroup) || + other.members.length != this.members.length) { return false } + for (var i = 0; i < this.members.length; i++) + { if (!this.members[i].eq(other.members[i])) { return false } } + return true +}; + +DecorationGroup.prototype.locals = function locals (node) { + var result, sorted = true; + for (var i = 0; i < this.members.length; i++) { + var locals = this.members[i].localsInner(node); + if (!locals.length) { continue } + if (!result) { + result = locals; + } else { + if (sorted) { + result = result.slice(); + sorted = false; + } + for (var j = 0; j < locals.length; j++) { result.push(locals[j]); } + } + } + return result ? removeOverlap(sorted ? result : result.sort(byPos)) : none +}; + +// : ([DecorationSet]) → union +// Create a group for the given array of decoration sets, or return +// a single set when possible. +DecorationGroup.from = function from (members) { + switch (members.length) { + case 0: return empty + case 1: return members[0] + default: return new DecorationGroup(members) + } +}; + +function mapChildren(oldChildren, newLocal, mapping, node, offset, oldOffset, options) { + var children = oldChildren.slice(); + + // Mark the children that are directly touched by changes, and + // move those that are after the changes. + var shift = function (oldStart, oldEnd, newStart, newEnd) { + for (var i = 0; i < children.length; i += 3) { + var end = children[i + 1], dSize = (void 0); + if (end == -1 || oldStart > end + oldOffset) { continue } + if (oldEnd >= children[i] + oldOffset) { + children[i + 1] = -1; + } else if (dSize = (newEnd - newStart) - (oldEnd - oldStart) + (oldOffset - offset)) { + children[i] += dSize; + children[i + 1] += dSize; + } + } + }; + for (var i = 0; i < mapping.maps.length; i++) { mapping.maps[i].forEach(shift); } + + // Find the child nodes that still correspond to a single node, + // recursively call mapInner on them and update their positions. + var mustRebuild = false; + for (var i$1 = 0; i$1 < children.length; i$1 += 3) { if (children[i$1 + 1] == -1) { // Touched nodes + var from = mapping.map(children[i$1] + oldOffset), fromLocal = from - offset; + if (fromLocal < 0 || fromLocal >= node.content.size) { + mustRebuild = true; + continue + } + // Must read oldChildren because children was tagged with -1 + var to = mapping.map(oldChildren[i$1 + 1] + oldOffset, -1), toLocal = to - offset; + var ref = node.content.findIndex(fromLocal); + var index = ref.index; + var childOffset = ref.offset; + var childNode = node.maybeChild(index); + if (childNode && childOffset == fromLocal && childOffset + childNode.nodeSize == toLocal) { + var mapped = children[i$1 + 2].mapInner(mapping, childNode, from + 1, children[i$1] + oldOffset + 1, options); + if (mapped != empty) { + children[i$1] = fromLocal; + children[i$1 + 1] = toLocal; + children[i$1 + 2] = mapped; + } else { + children[i$1 + 1] = -2; + mustRebuild = true; + } + } else { + mustRebuild = true; + } + } } + + // Remaining children must be collected and rebuilt into the appropriate structure + if (mustRebuild) { + var decorations = mapAndGatherRemainingDecorations(children, oldChildren, newLocal || [], mapping, + offset, oldOffset, options); + var built = buildTree(decorations, node, 0, options); + newLocal = built.local; + for (var i$2 = 0; i$2 < children.length; i$2 += 3) { if (children[i$2 + 1] < 0) { + children.splice(i$2, 3); + i$2 -= 3; + } } + for (var i$3 = 0, j = 0; i$3 < built.children.length; i$3 += 3) { + var from$1 = built.children[i$3]; + while (j < children.length && children[j] < from$1) { j += 3; } + children.splice(j, 0, built.children[i$3], built.children[i$3 + 1], built.children[i$3 + 2]); + } + } + + return new DecorationSet(newLocal && newLocal.sort(byPos), children) +} + +function moveSpans(spans, offset) { + if (!offset || !spans.length) { return spans } + var result = []; + for (var i = 0; i < spans.length; i++) { + var span = spans[i]; + result.push(new Decoration(span.from + offset, span.to + offset, span.type)); + } + return result +} + +function mapAndGatherRemainingDecorations(children, oldChildren, decorations, mapping, offset, oldOffset, options) { + // Gather all decorations from the remaining marked children + function gather(set, oldOffset) { + for (var i = 0; i < set.local.length; i++) { + var mapped = set.local[i].map(mapping, offset, oldOffset); + if (mapped) { decorations.push(mapped); } + else if (options.onRemove) { options.onRemove(set.local[i].spec); } + } + for (var i$1 = 0; i$1 < set.children.length; i$1 += 3) + { gather(set.children[i$1 + 2], set.children[i$1] + oldOffset + 1); } + } + for (var i = 0; i < children.length; i += 3) { if (children[i + 1] == -1) + { gather(children[i + 2], oldChildren[i] + oldOffset + 1); } } + + return decorations +} + +function takeSpansForNode(spans, node, offset) { + if (node.isLeaf) { return null } + var end = offset + node.nodeSize, found = null; + for (var i = 0, span = (void 0); i < spans.length; i++) { + if ((span = spans[i]) && span.from > offset && span.to < end) { +(found || (found = [])).push(span); + spans[i] = null; + } + } + return found +} + +function withoutNulls(array) { + var result = []; + for (var i = 0; i < array.length; i++) + { if (array[i] != null) { result.push(array[i]); } } + return result +} + +// : ([Decoration], Node, number) → DecorationSet +// Build up a tree that corresponds to a set of decorations. `offset` +// is a base offset that should be subtractet from the `from` and `to` +// positions in the spans (so that we don't have to allocate new spans +// for recursive calls). +function buildTree(spans, node, offset, options) { + var children = [], hasNulls = false; + node.forEach(function (childNode, localStart) { + var found = takeSpansForNode(spans, childNode, localStart + offset); + if (found) { + hasNulls = true; + var subtree = buildTree(found, childNode, offset + localStart + 1, options); + if (subtree != empty) + { children.push(localStart, localStart + childNode.nodeSize, subtree); } + } + }); + var locals = moveSpans(hasNulls ? withoutNulls(spans) : spans, -offset).sort(byPos); + for (var i = 0; i < locals.length; i++) { if (!locals[i].type.valid(node, locals[i])) { + if (options.onRemove) { options.onRemove(locals[i].spec); } + locals.splice(i--, 1); + } } + return locals.length || children.length ? new DecorationSet(locals, children) : empty +} + +// : (Decoration, Decoration) → number +// Used to sort decorations so that ones with a low start position +// come first, and within a set with the same start position, those +// with an smaller end position come first. +function byPos(a, b) { + return a.from - b.from || a.to - b.to +} + +// : ([Decoration]) → [Decoration] +// Scan a sorted array of decorations for partially overlapping spans, +// and split those so that only fully overlapping spans are left (to +// make subsequent rendering easier). Will return the input array if +// no partially overlapping spans are found (the common case). +function removeOverlap(spans) { + var working = spans; + for (var i = 0; i < working.length - 1; i++) { + var span = working[i]; + if (span.from != span.to) { for (var j = i + 1; j < working.length; j++) { + var next = working[j]; + if (next.from == span.from) { + if (next.to != span.to) { + if (working == spans) { working = spans.slice(); } + // Followed by a partially overlapping larger span. Split that + // span. + working[j] = next.copy(next.from, span.to); + insertAhead(working, j + 1, next.copy(span.to, next.to)); + } + continue + } else { + if (next.from < span.to) { + if (working == spans) { working = spans.slice(); } + // The end of this one overlaps with a subsequent span. Split + // this one. + working[i] = span.copy(span.from, next.from); + insertAhead(working, j, span.copy(next.from, span.to)); + } + break + } + } } + } + return working +} + +function insertAhead(array, i, deco) { + while (i < array.length && byPos(deco, array[i]) > 0) { i++; } + array.splice(i, 0, deco); +} + +// : (EditorView) → union +// Get the decorations associated with the current props of a view. +function viewDecorations(view) { + var found = []; + view.someProp("decorations", function (f) { + var result = f(view.state); + if (result && result != empty) { found.push(result); } + }); + if (view.cursorWrapper) + { found.push(DecorationSet.create(view.state.doc, [view.cursorWrapper.deco])); } + return DecorationGroup.from(found) +} + +// ::- An editor view manages the DOM structure that represents an +// editable document. Its state and behavior are determined by its +// [props](#view.DirectEditorProps). +var EditorView = function EditorView(place, props) { + this._props = props; + // :: EditorState + // The view's current [state](#state.EditorState). + this.state = props.state; + + this.dispatch = this.dispatch.bind(this); + + this._root = null; + this.focused = false; + + // :: dom.Element + // An editable DOM node containing the document. (You probably + // should not directly interfere with its content.) + this.dom = (place && place.mount) || document.createElement("div"); + if (place) { + if (place.appendChild) { place.appendChild(this.dom); } + else if (place.apply) { place(this.dom); } + else if (place.mount) { this.mounted = true; } + } + + // :: bool + // Indicates whether the editor is currently [editable](#view.EditorProps.editable). + this.editable = getEditable(this); + this.markCursor = null; + this.cursorWrapper = null; + updateCursorWrapper(this); + this.nodeViews = buildNodeViews(this); + this.docView = docViewDesc(this.state.doc, computeDocDeco(this), viewDecorations(this), this.dom, this); + + this.lastSelectedViewDesc = null; + // :: ?{slice: Slice, move: bool} + // When editor content is being dragged, this object contains + // information about the dragged slice and whether it is being + // copied or moved. At any other time, it is null. + this.dragging = null; + + initInput(this); + + this.pluginViews = []; + this.updatePluginViews(); +}; + +var prototypeAccessors$2 = { props: { configurable: true },root: { configurable: true } }; + +// composing:: boolean +// Holds `true` when a +// [composition](https://developer.mozilla.org/en-US/docs/Mozilla/IME_handling_guide) +// is active. + +// :: DirectEditorProps +// The view's current [props](#view.EditorProps). +prototypeAccessors$2.props.get = function () { + if (this._props.state != this.state) { + var prev = this._props; + this._props = {}; + for (var name in prev) { this._props[name] = prev[name]; } + this._props.state = this.state; + } + return this._props +}; + +// :: (DirectEditorProps) +// Update the view's props. Will immediately cause an update to +// the DOM. +EditorView.prototype.update = function update (props) { + if (props.handleDOMEvents != this._props.handleDOMEvents) { ensureListeners(this); } + this._props = props; + this.updateStateInner(props.state, true); +}; + +// :: (DirectEditorProps) +// Update the view by updating existing props object with the object +// given as argument. Equivalent to `view.update(Object.assign({}, +// view.props, props))`. +EditorView.prototype.setProps = function setProps (props) { + var updated = {}; + for (var name in this._props) { updated[name] = this._props[name]; } + updated.state = this.state; + for (var name$1 in props) { updated[name$1] = props[name$1]; } + this.update(updated); +}; + +// :: (EditorState) +// Update the editor's `state` prop, without touching any of the +// other props. +EditorView.prototype.updateState = function updateState (state) { + this.updateStateInner(state, this.state.plugins != state.plugins); +}; + +EditorView.prototype.updateStateInner = function updateStateInner (state, reconfigured) { + var this$1 = this; + + var prev = this.state, redraw = false; + this.state = state; + if (reconfigured) { + var nodeViews = buildNodeViews(this); + if (changedNodeViews(nodeViews, this.nodeViews)) { + this.nodeViews = nodeViews; + redraw = true; + } + ensureListeners(this); + } + + this.editable = getEditable(this); + updateCursorWrapper(this); + var innerDeco = viewDecorations(this), outerDeco = computeDocDeco(this); + + var scroll = reconfigured ? "reset" + : state.scrollToSelection > prev.scrollToSelection ? "to selection" : "preserve"; + var updateDoc = redraw || !this.docView.matchesNode(state.doc, outerDeco, innerDeco); + var updateSel = updateDoc || !state.selection.eq(prev.selection); + var oldScrollPos = scroll == "preserve" && updateSel && this.dom.style.overflowAnchor == null && storeScrollPos(this); + + if (updateSel) { + this.domObserver.stop(); + // Work around an issue in Chrome, IE, and Edge where changing + // the DOM around an active selection puts it into a broken + // state where the thing the user sees differs from the + // selection reported by the Selection object (#710, #973, + // #1011, #1013). + var forceSelUpdate = updateDoc && (result.ie || result.chrome) && + !prev.selection.empty && !state.selection.empty && selectionContextChanged(prev.selection, state.selection); + if (updateDoc) { + if (redraw || !this.docView.update(state.doc, outerDeco, innerDeco, this)) { + this.docView.destroy(); + this.docView = docViewDesc(state.doc, outerDeco, innerDeco, this.dom, this); + } + } + // Work around for an issue where an update arriving right between + // a DOM selection change and the "selectionchange" event for it + // can cause a spurious DOM selection update, disrupting mouse + // drag selection. + if (forceSelUpdate || + !(this.mouseDown && this.domObserver.currentSelection.eq(this.root.getSelection()) && anchorInRightPlace(this))) { + selectionToDOM(this, forceSelUpdate); + } else { + syncNodeSelection(this, state.selection); + this.domObserver.setCurSelection(); + } + this.domObserver.start(); + } + + this.updatePluginViews(prev); + + if (scroll == "reset") { + this.dom.scrollTop = 0; + } else if (scroll == "to selection") { + var startDOM = this.root.getSelection().focusNode; + if (this.someProp("handleScrollToSelection", function (f) { return f(this$1); })) + ; // Handled + else if (state.selection instanceof prosemirrorState.NodeSelection) + { scrollRectIntoView(this, this.docView.domAfterPos(state.selection.from).getBoundingClientRect(), startDOM); } + else + { scrollRectIntoView(this, this.coordsAtPos(state.selection.head), startDOM); } + } else if (oldScrollPos) { + resetScrollPos(oldScrollPos); + } +}; + +EditorView.prototype.destroyPluginViews = function destroyPluginViews () { + var view; + while (view = this.pluginViews.pop()) { if (view.destroy) { view.destroy(); } } +}; + +EditorView.prototype.updatePluginViews = function updatePluginViews (prevState) { + if (!prevState || prevState.plugins != this.state.plugins) { + this.destroyPluginViews(); + for (var i = 0; i < this.state.plugins.length; i++) { + var plugin = this.state.plugins[i]; + if (plugin.spec.view) { this.pluginViews.push(plugin.spec.view(this)); } + } + } else { + for (var i$1 = 0; i$1 < this.pluginViews.length; i$1++) { + var pluginView = this.pluginViews[i$1]; + if (pluginView.update) { pluginView.update(this, prevState); } + } + } +}; + +// :: (string, ?(prop: *) → *) → * +// Goes over the values of a prop, first those provided directly, +// then those from plugins (in order), and calls `f` every time a +// non-undefined value is found. When `f` returns a truthy value, +// that is immediately returned. When `f` isn't provided, it is +// treated as the identity function (the prop value is returned +// directly). +EditorView.prototype.someProp = function someProp (propName, f) { + var prop = this._props && this._props[propName], value; + if (prop != null && (value = f ? f(prop) : prop)) { return value } + var plugins = this.state.plugins; + if (plugins) { for (var i = 0; i < plugins.length; i++) { + var prop$1 = plugins[i].props[propName]; + if (prop$1 != null && (value = f ? f(prop$1) : prop$1)) { return value } + } } +}; + +// :: () → bool +// Query whether the view has focus. +EditorView.prototype.hasFocus = function hasFocus () { + return this.root.activeElement == this.dom +}; + +// :: () +// Focus the editor. +EditorView.prototype.focus = function focus () { + this.domObserver.stop(); + if (this.editable) { focusPreventScroll(this.dom); } + selectionToDOM(this); + this.domObserver.start(); +}; + +// :: union +// Get the document root in which the editor exists. This will +// usually be the top-level `document`, but might be a [shadow +// DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Shadow_DOM) +// root if the editor is inside one. +prototypeAccessors$2.root.get = function () { + var cached = this._root; + if (cached == null) { for (var search = this.dom.parentNode; search; search = search.parentNode) { + if (search.nodeType == 9 || (search.nodeType == 11 && search.host)) { + if (!search.getSelection) { Object.getPrototypeOf(search).getSelection = function () { return document.getSelection(); }; } + return this._root = search + } + } } + return cached || document +}; + +// :: ({left: number, top: number}) → ?{pos: number, inside: number} +// Given a pair of viewport coordinates, return the document +// position that corresponds to them. May return null if the given +// coordinates aren't inside of the editor. When an object is +// returned, its `pos` property is the position nearest to the +// coordinates, and its `inside` property holds the position of the +// inner node that the position falls inside of, or -1 if it is at +// the top level, not in any node. +EditorView.prototype.posAtCoords = function posAtCoords$1 (coords) { + return posAtCoords(this, coords) +}; + +// :: (number) → {left: number, right: number, top: number, bottom: number} +// Returns the viewport rectangle at a given document position. `left` +// and `right` will be the same number, as this returns a flat +// cursor-ish rectangle. +EditorView.prototype.coordsAtPos = function coordsAtPos$1 (pos) { + return coordsAtPos(this, pos) +}; + +// :: (number) → {node: dom.Node, offset: number} +// Find the DOM position that corresponds to the given document +// position. Note that you should **not** mutate the editor's +// internal DOM, only inspect it (and even that is usually not +// necessary). +EditorView.prototype.domAtPos = function domAtPos (pos) { + return this.docView.domFromPos(pos) +}; + +// :: (number) → ?dom.Node +// Find the DOM node that represents the document node after the +// given position. May return `null` when the position doesn't point +// in front of a node or if the node is inside an opaque node view. +// +// This is intended to be able to call things like +// `getBoundingClientRect` on that DOM node. Do **not** mutate the +// editor DOM directly, or add styling this way, since that will be +// immediately overriden by the editor as it redraws the node. +EditorView.prototype.nodeDOM = function nodeDOM (pos) { + var desc = this.docView.descAt(pos); + return desc ? desc.nodeDOM : null +}; + +// :: (dom.Node, number, ?number) → number +// Find the document position that corresponds to a given DOM +// position. (Whenever possible, it is preferable to inspect the +// document structure directly, rather than poking around in the +// DOM, but sometimes—for example when interpreting an event +// target—you don't have a choice.) +// +// The `bias` parameter can be used to influence which side of a DOM +// node to use when the position is inside a leaf node. +EditorView.prototype.posAtDOM = function posAtDOM (node, offset, bias) { + if ( bias === void 0 ) bias = -1; + + var pos = this.docView.posFromDOM(node, offset, bias); + if (pos == null) { throw new RangeError("DOM position not inside the editor") } + return pos +}; + +// :: (union<"up", "down", "left", "right", "forward", "backward">, ?EditorState) → bool +// Find out whether the selection is at the end of a textblock when +// moving in a given direction. When, for example, given `"left"`, +// it will return true if moving left from the current cursor +// position would leave that position's parent textblock. Will apply +// to the view's current state by default, but it is possible to +// pass a different state. +EditorView.prototype.endOfTextblock = function endOfTextblock$1 (dir, state) { + return endOfTextblock(this, state || this.state, dir) +}; + +// :: () +// Removes the editor from the DOM and destroys all [node +// views](#view.NodeView). +EditorView.prototype.destroy = function destroy () { + if (!this.docView) { return } + destroyInput(this); + this.destroyPluginViews(); + if (this.mounted) { + this.docView.update(this.state.doc, [], viewDecorations(this), this); + this.dom.textContent = ""; + } else if (this.dom.parentNode) { + this.dom.parentNode.removeChild(this.dom); + } + this.docView.destroy(); + this.docView = null; +}; + +// Used for testing. +EditorView.prototype.dispatchEvent = function dispatchEvent$1 (event) { + return dispatchEvent(this, event) +}; + +// :: (Transaction) +// Dispatch a transaction. Will call +// [`dispatchTransaction`](#view.DirectEditorProps.dispatchTransaction) +// when given, and otherwise defaults to applying the transaction to +// the current state and calling +// [`updateState`](#view.EditorView.updateState) with the result. +// This method is bound to the view instance, so that it can be +// easily passed around. +EditorView.prototype.dispatch = function dispatch (tr) { + var dispatchTransaction = this._props.dispatchTransaction; + if (dispatchTransaction) { dispatchTransaction.call(this, tr); } + else { this.updateState(this.state.apply(tr)); } +}; + +Object.defineProperties( EditorView.prototype, prototypeAccessors$2 ); + +function computeDocDeco(view) { + var attrs = Object.create(null); + attrs.class = "ProseMirror"; + attrs.contenteditable = String(view.editable); + + view.someProp("attributes", function (value) { + if (typeof value == "function") { value = value(view.state); } + if (value) { for (var attr in value) { + if (attr == "class") + { attrs.class += " " + value[attr]; } + else if (!attrs[attr] && attr != "contenteditable" && attr != "nodeName") + { attrs[attr] = String(value[attr]); } + } } + }); + + return [Decoration.node(0, view.state.doc.content.size, attrs)] +} + +function updateCursorWrapper(view) { + var ref = view.state.selection; + var $head = ref.$head; + var $anchor = ref.$anchor; + var visible = ref.visible; + if (view.markCursor) { + var dom = document.createElement("img"); + dom.setAttribute("mark-placeholder", "true"); + view.cursorWrapper = {dom: dom, deco: Decoration.widget($head.pos, dom, {raw: true, marks: view.markCursor})}; + } else if (visible || $head.pos != $anchor.pos) { + view.cursorWrapper = null; + } else { + var dom$1; + if (!view.cursorWrapper || view.cursorWrapper.dom.childNodes.length) { + dom$1 = document.createElement("div"); + dom$1.style.position = "absolute"; + dom$1.style.left = "-100000px"; + } else if (view.cursorWrapper.deco.pos != $head.pos) { + dom$1 = view.cursorWrapper.dom; + } + if (dom$1) + { view.cursorWrapper = {dom: dom$1, deco: Decoration.widget($head.pos, dom$1, {raw: true})}; } + } +} + +function getEditable(view) { + return !view.someProp("editable", function (value) { return value(view.state) === false; }) +} + +function selectionContextChanged(sel1, sel2) { + var depth = Math.min(sel1.$anchor.sharedDepth(sel1.head), sel2.$anchor.sharedDepth(sel2.head)); + return sel1.$anchor.node(depth) != sel2.$anchor.node(depth) +} + +function buildNodeViews(view) { + var result = {}; + view.someProp("nodeViews", function (obj) { + for (var prop in obj) { if (!Object.prototype.hasOwnProperty.call(result, prop)) + { result[prop] = obj[prop]; } } + }); + return result +} + +function changedNodeViews(a, b) { + var nA = 0, nB = 0; + for (var prop in a) { + if (a[prop] != b[prop]) { return true } + nA++; + } + for (var _ in b) { nB++; } + return nA != nB +} + +// EditorProps:: interface +// +// Props are configuration values that can be passed to an editor view +// or included in a plugin. This interface lists the supported props. +// +// The various event-handling functions may all return `true` to +// indicate that they handled the given event. The view will then take +// care to call `preventDefault` on the event, except with +// `handleDOMEvents`, where the handler itself is responsible for that. +// +// How a prop is resolved depends on the prop. Handler functions are +// called one at a time, starting with the base props and then +// searching through the plugins (in order of appearance) until one of +// them returns true. For some props, the first plugin that yields a +// value gets precedence. +// +// handleDOMEvents:: ?Object<(view: EditorView, event: dom.Event) → bool> +// Can be an object mapping DOM event type names to functions that +// handle them. Such functions will be called before any handling +// ProseMirror does of events fired on the editable DOM element. +// Contrary to the other event handling props, when returning true +// from such a function, you are responsible for calling +// `preventDefault` yourself (or not, if you want to allow the +// default behavior). +// +// handleKeyDown:: ?(view: EditorView, event: dom.KeyboardEvent) → bool +// Called when the editor receives a `keydown` event. +// +// handleKeyPress:: ?(view: EditorView, event: dom.KeyboardEvent) → bool +// Handler for `keypress` events. +// +// handleTextInput:: ?(view: EditorView, from: number, to: number, text: string) → bool +// Whenever the user directly input text, this handler is called +// before the input is applied. If it returns `true`, the default +// behavior of actually inserting the text is suppressed. +// +// handleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool +// Called for each node around a click, from the inside out. The +// `direct` flag will be true for the inner node. +// +// handleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool +// Called when the editor is clicked, after `handleClickOn` handlers +// have been called. +// +// handleDoubleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool +// Called for each node around a double click. +// +// handleDoubleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool +// Called when the editor is double-clicked, after `handleDoubleClickOn`. +// +// handleTripleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool +// Called for each node around a triple click. +// +// handleTripleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool +// Called when the editor is triple-clicked, after `handleTripleClickOn`. +// +// handlePaste:: ?(view: EditorView, event: dom.Event, slice: Slice) → bool +// Can be used to override the behavior of pasting. `slice` is the +// pasted content parsed by the editor, but you can directly access +// the event to get at the raw content. +// +// handleDrop:: ?(view: EditorView, event: dom.Event, slice: Slice, moved: bool) → bool +// Called when something is dropped on the editor. `moved` will be +// true if this drop moves from the current selection (which should +// thus be deleted). +// +// handleScrollToSelection:: ?(view: EditorView) → bool +// Called when the view, after updating its state, tries to scroll +// the selection into view. A handler function may return false to +// indicate that it did not handle the scrolling and further +// handlers or the default behavior should be tried. +// +// createSelectionBetween:: ?(view: EditorView, anchor: ResolvedPos, head: ResolvedPos) → ?Selection +// Can be used to override the way a selection is created when +// reading a DOM selection between the given anchor and head. +// +// domParser:: ?DOMParser +// The [parser](#model.DOMParser) to use when reading editor changes +// from the DOM. Defaults to calling +// [`DOMParser.fromSchema`](#model.DOMParser^fromSchema) on the +// editor's schema. +// +// transformPastedHTML:: ?(html: string) → string +// Can be used to transform pasted HTML text, _before_ it is parsed, +// for example to clean it up. +// +// clipboardParser:: ?DOMParser +// The [parser](#model.DOMParser) to use when reading content from +// the clipboard. When not given, the value of the +// [`domParser`](#view.EditorProps.domParser) prop is used. +// +// transformPastedText:: ?(text: string) → string +// Transform pasted plain text. +// +// clipboardTextParser:: ?(text: string, $context: ResolvedPos) → Slice +// A function to parse text from the clipboard into a document +// slice. Called after +// [`transformPastedText`](#view.EditorProps.transformPastedText). +// The default behavior is to split the text into lines, wrap them +// in `

    ` tags, and call +// [`clipboardParser`](#view.EditorProps.clipboardParser) on it. +// +// transformPasted:: ?(Slice) → Slice +// Can be used to transform pasted content before it is applied to +// the document. +// +// nodeViews:: ?Object<(node: Node, view: EditorView, getPos: () → number, decorations: [Decoration]) → NodeView> +// Allows you to pass custom rendering and behavior logic for nodes +// and marks. Should map node and mark names to constructor +// functions that produce a [`NodeView`](#view.NodeView) object +// implementing the node's display behavior. For nodes, the third +// argument `getPos` is a function that can be called to get the +// node's current position, which can be useful when creating +// transactions to update it. For marks, the third argument is a +// boolean that indicates whether the mark's content is inline. +// +// `decorations` is an array of node or inline decorations that are +// active around the node. They are automatically drawn in the +// normal way, and you will usually just want to ignore this, but +// they can also be used as a way to provide context information to +// the node view without adding it to the document itself. +// +// clipboardSerializer:: ?DOMSerializer +// The DOM serializer to use when putting content onto the +// clipboard. If not given, the result of +// [`DOMSerializer.fromSchema`](#model.DOMSerializer^fromSchema) +// will be used. +// +// clipboardTextSerializer:: ?(Slice) → string +// A function that will be called to get the text for the current +// selection when copying text to the clipboard. By default, the +// editor will use [`textBetween`](#model.Node.textBetween) on the +// selected range. +// +// decorations:: ?(state: EditorState) → ?DecorationSet +// A set of [document decorations](#view.Decoration) to show in the +// view. +// +// editable:: ?(state: EditorState) → bool +// When this returns false, the content of the view is not directly +// editable. +// +// attributes:: ?union, (EditorState) → ?Object> +// Control the DOM attributes of the editable element. May be either +// an object or a function going from an editor state to an object. +// By default, the element will get a class `"ProseMirror"`, and +// will have its `contentEditable` attribute determined by the +// [`editable` prop](#view.EditorProps.editable). Additional classes +// provided here will be added to the class. For other attributes, +// the value provided first (as in +// [`someProp`](#view.EditorView.someProp)) will be used. +// +// scrollThreshold:: ?union +// Determines the distance (in pixels) between the cursor and the +// end of the visible viewport at which point, when scrolling the +// cursor into view, scrolling takes place. Defaults to 0. +// +// scrollMargin:: ?union +// Determines the extra space (in pixels) that is left above or +// below the cursor when it is scrolled into view. Defaults to 5. + +// DirectEditorProps:: interface extends EditorProps +// +// The props object given directly to the editor view supports two +// fields that can't be used in plugins: +// +// state:: EditorState +// The current state of the editor. +// +// dispatchTransaction:: ?(tr: Transaction) +// The callback over which to send transactions (state updates) +// produced by the view. If you specify this, you probably want to +// make sure this ends up calling the view's +// [`updateState`](#view.EditorView.updateState) method with a new +// state that has the transaction +// [applied](#state.EditorState.apply). The callback will be bound to have +// the view instance as its `this` binding. + +exports.Decoration = Decoration; +exports.DecorationSet = DecorationSet; +exports.EditorView = EditorView; +exports.__endComposition = endComposition; +exports.__parseFromClipboard = parseFromClipboard; +exports.__serializeForClipboard = serializeForClipboard; +//# sourceMappingURL=index.js.map diff --git a/packages/tiptap/node_modules/prosemirror-view/dist/index.js.map b/packages/tiptap/node_modules/prosemirror-view/dist/index.js.map new file mode 100644 index 0000000000..4f813e9420 --- /dev/null +++ b/packages/tiptap/node_modules/prosemirror-view/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sources":["../src/browser.js","../src/dom.js","../src/domcoords.js","../src/viewdesc.js","../src/capturekeys.js","../src/selection.js","../src/domchange.js","../src/clipboard.js","../src/domobserver.js","../src/input.js","../src/decoration.js","../src/index.js"],"sourcesContent":["const result = {}\nexport default result\n\nif (typeof navigator != \"undefined\" && typeof document != \"undefined\") {\n const ie_edge = /Edge\\/(\\d+)/.exec(navigator.userAgent)\n const ie_upto10 = /MSIE \\d/.test(navigator.userAgent)\n const ie_11up = /Trident\\/(?:[7-9]|\\d{2,})\\..*rv:(\\d+)/.exec(navigator.userAgent)\n\n result.mac = /Mac/.test(navigator.platform)\n let ie = result.ie = !!(ie_upto10 || ie_11up || ie_edge)\n result.ie_version = ie_upto10 ? document.documentMode || 6 : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : null\n result.gecko = !ie && /gecko\\/(\\d+)/i.test(navigator.userAgent)\n result.gecko_version = result.gecko && +(/Firefox\\/(\\d+)/.exec(navigator.userAgent) || [0, 0])[1]\n let chrome = !ie && /Chrome\\/(\\d+)/.exec(navigator.userAgent)\n result.chrome = !!chrome\n result.chrome_version = chrome && +chrome[1]\n result.ios = !ie && /AppleWebKit/.test(navigator.userAgent) && /Mobile\\/\\w+/.test(navigator.userAgent)\n result.android = /Android \\d/.test(navigator.userAgent)\n result.webkit = !ie && 'WebkitAppearance' in document.documentElement.style\n result.safari = /Apple Computer/.test(navigator.vendor)\n result.webkit_version = result.webkit && +(/\\bAppleWebKit\\/(\\d+)/.exec(navigator.userAgent) || [0, 0])[1]\n}\n","import browser from \"./browser\"\n\nexport const domIndex = function(node) {\n for (var index = 0;; index++) {\n node = node.previousSibling\n if (!node) return index\n }\n}\n\nexport const parentNode = function(node) {\n let parent = node.parentNode\n return parent && parent.nodeType == 11 ? parent.host : parent\n}\n\nexport const textRange = function(node, from, to) {\n let range = document.createRange()\n range.setEnd(node, to == null ? node.nodeValue.length : to)\n range.setStart(node, from || 0)\n return range\n}\n\n// Scans forward and backward through DOM positions equivalent to the\n// given one to see if the two are in the same place (i.e. after a\n// text node vs at the end of that text node)\nexport const isEquivalentPosition = function(node, off, targetNode, targetOff) {\n return targetNode && (scanFor(node, off, targetNode, targetOff, -1) ||\n scanFor(node, off, targetNode, targetOff, 1))\n}\n\nconst atomElements = /^(img|br|input|textarea|hr)$/i\n\nfunction scanFor(node, off, targetNode, targetOff, dir) {\n for (;;) {\n if (node == targetNode && off == targetOff) return true\n if (off == (dir < 0 ? 0 : nodeSize(node))) {\n let parent = node.parentNode\n if (parent.nodeType != 1 || hasBlockDesc(node) || atomElements.test(node.nodeName) || node.contentEditable == \"false\")\n return false\n off = domIndex(node) + (dir < 0 ? 0 : 1)\n node = parent\n } else if (node.nodeType == 1) {\n node = node.childNodes[off + (dir < 0 ? -1 : 0)]\n off = dir < 0 ? nodeSize(node) : 0\n } else {\n return false\n }\n }\n}\n\nexport function nodeSize(node) {\n return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length\n}\n\nfunction hasBlockDesc(dom) {\n let desc\n for (let cur = dom; cur; cur = cur.parentNode) if (desc = cur.pmViewDesc) break\n return desc && desc.node && desc.node.isBlock && (desc.dom == dom || desc.contentDOM == dom)\n}\n\n// Work around Chrome issue https://bugs.chromium.org/p/chromium/issues/detail?id=447523\n// (isCollapsed inappropriately returns true in shadow dom)\nexport const selectionCollapsed = function(domSel) {\n let collapsed = domSel.isCollapsed\n if (collapsed && browser.chrome && domSel.rangeCount && !domSel.getRangeAt(0).collapsed)\n collapsed = false\n return collapsed\n}\n\nexport function keyEvent(keyCode, key) {\n let event = document.createEvent(\"Event\")\n event.initEvent(\"keydown\", true, true)\n event.keyCode = keyCode\n event.key = event.code = key\n return event\n}\n","import {nodeSize, textRange, parentNode} from \"./dom\"\nimport browser from \"./browser\"\n\nfunction windowRect(win) {\n return {left: 0, right: win.innerWidth,\n top: 0, bottom: win.innerHeight}\n}\n\nfunction getSide(value, side) {\n return typeof value == \"number\" ? value : value[side]\n}\n\nexport function scrollRectIntoView(view, rect, startDOM) {\n let scrollThreshold = view.someProp(\"scrollThreshold\") || 0, scrollMargin = view.someProp(\"scrollMargin\") || 5\n let doc = view.dom.ownerDocument, win = doc.defaultView\n for (let parent = startDOM || view.dom;; parent = parentNode(parent)) {\n if (!parent) break\n if (parent.nodeType != 1) continue\n let atTop = parent == doc.body || parent.nodeType != 1\n let bounding = atTop ? windowRect(win) : parent.getBoundingClientRect()\n let moveX = 0, moveY = 0\n if (rect.top < bounding.top + getSide(scrollThreshold, \"top\"))\n moveY = -(bounding.top - rect.top + getSide(scrollMargin, \"top\"))\n else if (rect.bottom > bounding.bottom - getSide(scrollThreshold, \"bottom\"))\n moveY = rect.bottom - bounding.bottom + getSide(scrollMargin, \"bottom\")\n if (rect.left < bounding.left + getSide(scrollThreshold, \"left\"))\n moveX = -(bounding.left - rect.left + getSide(scrollMargin, \"left\"))\n else if (rect.right > bounding.right - getSide(scrollThreshold, \"right\"))\n moveX = rect.right - bounding.right + getSide(scrollMargin, \"right\")\n if (moveX || moveY) {\n if (atTop) {\n win.scrollBy(moveX, moveY)\n } else {\n if (moveY) parent.scrollTop += moveY\n if (moveX) parent.scrollLeft += moveX\n }\n }\n if (atTop) break\n }\n}\n\n// Store the scroll position of the editor's parent nodes, along with\n// the top position of an element near the top of the editor, which\n// will be used to make sure the visible viewport remains stable even\n// when the size of the content above changes.\nexport function storeScrollPos(view) {\n let rect = view.dom.getBoundingClientRect(), startY = Math.max(0, rect.top)\n let refDOM, refTop\n for (let x = (rect.left + rect.right) / 2, y = startY + 1;\n y < Math.min(innerHeight, rect.bottom); y += 5) {\n let dom = view.root.elementFromPoint(x, y)\n if (dom == view.dom || !view.dom.contains(dom)) continue\n let localRect = dom.getBoundingClientRect()\n if (localRect.top >= startY - 20) {\n refDOM = dom\n refTop = localRect.top\n break\n }\n }\n return {refDOM, refTop, stack: scrollStack(view.dom)}\n}\n\nfunction scrollStack(dom) {\n let stack = [], doc = dom.ownerDocument\n for (; dom; dom = parentNode(dom)) {\n stack.push({dom, top: dom.scrollTop, left: dom.scrollLeft})\n if (dom == doc) break\n }\n return stack\n}\n\n// Reset the scroll position of the editor's parent nodes to that what\n// it was before, when storeScrollPos was called.\nexport function resetScrollPos({refDOM, refTop, stack}) {\n let newRefTop = refDOM ? refDOM.getBoundingClientRect().top : 0\n restoreScrollStack(stack, newRefTop == 0 ? 0 : newRefTop - refTop)\n}\n\nfunction restoreScrollStack(stack, dTop) {\n for (let i = 0; i < stack.length; i++) {\n let {dom, top, left} = stack[i]\n if (dom.scrollTop != top + dTop) dom.scrollTop = top + dTop\n if (dom.scrollLeft != left) dom.scrollLeft = left\n }\n}\n\nlet preventScrollSupported = null\n// Feature-detects support for .focus({preventScroll: true}), and uses\n// a fallback kludge when not supported.\nexport function focusPreventScroll(dom) {\n if (dom.setActive) return dom.setActive() // in IE\n if (preventScrollSupported) return dom.focus(preventScrollSupported)\n\n let stored = scrollStack(dom)\n dom.focus(preventScrollSupported == null ? {\n get preventScroll() {\n preventScrollSupported = {preventScroll: true}\n return true\n }\n } : undefined)\n if (!preventScrollSupported) {\n preventScrollSupported = false\n restoreScrollStack(stored, 0)\n }\n}\n\nfunction findOffsetInNode(node, coords) {\n let closest, dxClosest = 2e8, coordsClosest, offset = 0\n let rowBot = coords.top, rowTop = coords.top\n for (let child = node.firstChild, childIndex = 0; child; child = child.nextSibling, childIndex++) {\n let rects\n if (child.nodeType == 1) rects = child.getClientRects()\n else if (child.nodeType == 3) rects = textRange(child).getClientRects()\n else continue\n\n for (let i = 0; i < rects.length; i++) {\n let rect = rects[i]\n if (rect.top <= rowBot && rect.bottom >= rowTop) {\n rowBot = Math.max(rect.bottom, rowBot)\n rowTop = Math.min(rect.top, rowTop)\n let dx = rect.left > coords.left ? rect.left - coords.left\n : rect.right < coords.left ? coords.left - rect.right : 0\n if (dx < dxClosest) {\n closest = child\n dxClosest = dx\n coordsClosest = dx && closest.nodeType == 3 ? {left: rect.right < coords.left ? rect.right : rect.left, top: coords.top} : coords\n if (child.nodeType == 1 && dx)\n offset = childIndex + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0)\n continue\n }\n }\n if (!closest && (coords.left >= rect.right && coords.top >= rect.top ||\n coords.left >= rect.left && coords.top >= rect.bottom))\n offset = childIndex + 1\n }\n }\n if (closest && closest.nodeType == 3) return findOffsetInText(closest, coordsClosest)\n if (!closest || (dxClosest && closest.nodeType == 1)) return {node, offset}\n return findOffsetInNode(closest, coordsClosest)\n}\n\nfunction findOffsetInText(node, coords) {\n let len = node.nodeValue.length\n let range = document.createRange()\n for (let i = 0; i < len; i++) {\n range.setEnd(node, i + 1)\n range.setStart(node, i)\n let rect = singleRect(range, 1)\n if (rect.top == rect.bottom) continue\n if (inRect(coords, rect))\n return {node, offset: i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0)}\n }\n return {node, offset: 0}\n}\n\nfunction inRect(coords, rect) {\n return coords.left >= rect.left - 1 && coords.left <= rect.right + 1&&\n coords.top >= rect.top - 1 && coords.top <= rect.bottom + 1\n}\n\nfunction targetKludge(dom, coords) {\n let parent = dom.parentNode\n if (parent && /^li$/i.test(parent.nodeName) && coords.left < dom.getBoundingClientRect().left)\n return parent\n return dom\n}\n\nfunction posFromElement(view, elt, coords) {\n let {node, offset} = findOffsetInNode(elt, coords), bias = -1\n if (node.nodeType == 1 && !node.firstChild) {\n let rect = node.getBoundingClientRect()\n bias = rect.left != rect.right && coords.left > (rect.left + rect.right) / 2 ? 1 : -1\n }\n return view.docView.posFromDOM(node, offset, bias)\n}\n\nfunction posFromCaret(view, node, offset, coords) {\n // Browser (in caretPosition/RangeFromPoint) will agressively\n // normalize towards nearby inline nodes. Since we are interested in\n // positions between block nodes too, we first walk up the hierarchy\n // of nodes to see if there are block nodes that the coordinates\n // fall outside of. If so, we take the position before/after that\n // block. If not, we call `posFromDOM` on the raw node/offset.\n let outside = -1\n for (let cur = node;;) {\n if (cur == view.dom) break\n let desc = view.docView.nearestDesc(cur, true)\n if (!desc) return null\n if (desc.node.isBlock && desc.parent) {\n let rect = desc.dom.getBoundingClientRect()\n if (rect.left > coords.left || rect.top > coords.top) outside = desc.posBefore\n else if (rect.right < coords.left || rect.bottom < coords.top) outside = desc.posAfter\n else break\n }\n cur = desc.dom.parentNode\n }\n return outside > -1 ? outside : view.docView.posFromDOM(node, offset)\n}\n\nfunction elementFromPoint(element, coords, box) {\n let len = element.childNodes.length\n if (len && box.top < box.bottom) {\n for (let startI = Math.max(0, Math.min(len - 1, Math.floor(len * (coords.top - box.top) / (box.bottom - box.top)) - 2)), i = startI;;) {\n let child = element.childNodes[i]\n if (child.nodeType == 1) {\n let rects = child.getClientRects()\n for (let j = 0; j < rects.length; j++) {\n let rect = rects[j]\n if (inRect(coords, rect)) return elementFromPoint(child, coords, rect)\n }\n }\n if ((i = (i + 1) % len) == startI) break\n }\n }\n return element\n}\n\n// Given an x,y position on the editor, get the position in the document.\nexport function posAtCoords(view, coords) {\n let root = view.root, node, offset\n if (root.caretPositionFromPoint) {\n try { // Firefox throws for this call in hard-to-predict circumstances (#994)\n let pos = root.caretPositionFromPoint(coords.left, coords.top)\n if (pos) ({offsetNode: node, offset} = pos)\n } catch (_) {}\n }\n if (!node && root.caretRangeFromPoint) {\n let range = root.caretRangeFromPoint(coords.left, coords.top)\n if (range) ({startContainer: node, startOffset: offset} = range)\n }\n\n let elt = root.elementFromPoint(coords.left, coords.top + 1), pos\n if (!elt || !view.dom.contains(elt.nodeType != 1 ? elt.parentNode : elt)) {\n let box = view.dom.getBoundingClientRect()\n if (!inRect(coords, box)) return null\n elt = elementFromPoint(view.dom, coords, box)\n if (!elt) return null\n }\n elt = targetKludge(elt, coords)\n if (node) {\n if (browser.gecko && node.nodeType == 1) {\n // Firefox will sometimes return offsets into nodes, which\n // have no actual children, from caretPositionFromPoint (#953)\n offset = Math.min(offset, node.childNodes.length)\n // It'll also move the returned position before image nodes,\n // even if those are behind it.\n if (offset < node.childNodes.length) {\n let next = node.childNodes[offset], box\n if (next.nodeName == \"IMG\" && (box = next.getBoundingClientRect()).right <= coords.left &&\n box.bottom > coords.top)\n offset++\n }\n }\n // Suspiciously specific kludge to work around caret*FromPoint\n // never returning a position at the end of the document\n if (node == view.dom && offset == node.childNodes.length - 1 && node.lastChild.nodeType == 1 &&\n coords.top > node.lastChild.getBoundingClientRect().bottom)\n pos = view.state.doc.content.size\n // Ignore positions directly after a BR, since caret*FromPoint\n // 'round up' positions that would be more accurately placed\n // before the BR node.\n else if (offset == 0 || node.nodeType != 1 || node.childNodes[offset - 1].nodeName != \"BR\")\n pos = posFromCaret(view, node, offset, coords)\n }\n if (pos == null) pos = posFromElement(view, elt, coords)\n\n let desc = view.docView.nearestDesc(elt, true)\n return {pos, inside: desc ? desc.posAtStart - desc.border : -1}\n}\n\nfunction singleRect(object, bias) {\n let rects = object.getClientRects()\n return !rects.length ? object.getBoundingClientRect() : rects[bias < 0 ? 0 : rects.length - 1]\n}\n\n// : (EditorView, number) → {left: number, top: number, right: number, bottom: number}\n// Given a position in the document model, get a bounding box of the\n// character at that position, relative to the window.\nexport function coordsAtPos(view, pos) {\n let {node, offset} = view.docView.domFromPos(pos)\n\n // These browsers support querying empty text ranges\n if (node.nodeType == 3 && (browser.chrome || browser.gecko)) {\n let rect = singleRect(textRange(node, offset, offset), 0)\n // Firefox returns bad results (the position before the space)\n // when querying a position directly after line-broken\n // whitespace. Detect this situation and and kludge around it\n if (browser.gecko && offset && /\\s/.test(node.nodeValue[offset - 1]) && offset < node.nodeValue.length) {\n let rectBefore = singleRect(textRange(node, offset - 1, offset - 1), -1)\n if (Math.abs(rectBefore.left - rect.left) < 1 && rectBefore.top == rect.top) {\n let rectAfter = singleRect(textRange(node, offset, offset + 1), -1)\n return flattenV(rectAfter, rectAfter.left < rectBefore.left)\n }\n }\n return rect\n }\n\n if (node.nodeType == 1 && !view.state.doc.resolve(pos).parent.inlineContent) {\n // Return a horizontal line in block context\n let top = true, rect\n if (offset < node.childNodes.length) {\n let after = node.childNodes[offset]\n if (after.nodeType == 1) rect = after.getBoundingClientRect()\n }\n if (!rect && offset) {\n let before = node.childNodes[offset - 1]\n if (before.nodeType == 1) { rect = before.getBoundingClientRect(); top = false }\n }\n return flattenH(rect || node.getBoundingClientRect(), top)\n }\n\n // Not Firefox/Chrome, or not in a text node, so we have to use\n // actual element/character rectangles to get a solution (this part\n // is not very bidi-safe)\n //\n // Try the left side first, fall back to the right one if that\n // doesn't work.\n for (let dir = -1; dir < 2; dir += 2) {\n if (dir < 0 && offset) {\n let prev, target = node.nodeType == 3 ? textRange(node, offset - 1, offset)\n : (prev = node.childNodes[offset - 1]).nodeType == 3 ? textRange(prev)\n : prev.nodeType == 1 && prev.nodeName != \"BR\" ? prev : null // BR nodes tend to only return the rectangle before them\n if (target) {\n let rect = singleRect(target, 1)\n if (rect.top < rect.bottom) return flattenV(rect, false)\n }\n } else if (dir > 0 && offset < nodeSize(node)) {\n let next, target = node.nodeType == 3 ? textRange(node, offset, offset + 1)\n : (next = node.childNodes[offset]).nodeType == 3 ? textRange(next)\n : next.nodeType == 1 ? next : null\n if (target) {\n let rect = singleRect(target, -1)\n if (rect.top < rect.bottom) return flattenV(rect, true)\n }\n }\n }\n // All else failed, just try to get a rectangle for the target node\n return flattenV(singleRect(node.nodeType == 3 ? textRange(node) : node, 0), false)\n}\n\nfunction flattenV(rect, left) {\n if (rect.width == 0) return rect\n let x = left ? rect.left : rect.right\n return {top: rect.top, bottom: rect.bottom, left: x, right: x}\n}\n\nfunction flattenH(rect, top) {\n if (rect.height == 0) return rect\n let y = top ? rect.top : rect.bottom\n return {top: y, bottom: y, left: rect.left, right: rect.right}\n}\n\nfunction withFlushedState(view, state, f) {\n let viewState = view.state, active = view.root.activeElement\n if (viewState != state) view.updateState(state)\n if (active != view.dom) view.focus()\n try {\n return f()\n } finally {\n if (viewState != state) view.updateState(viewState)\n if (active != view.dom) active.focus()\n }\n}\n\n// : (EditorView, number, number)\n// Whether vertical position motion in a given direction\n// from a position would leave a text block.\nfunction endOfTextblockVertical(view, state, dir) {\n let sel = state.selection\n let $pos = dir == \"up\" ? sel.$anchor.min(sel.$head) : sel.$anchor.max(sel.$head)\n return withFlushedState(view, state, () => {\n let {node: dom} = view.docView.domFromPos($pos.pos)\n for (;;) {\n let nearest = view.docView.nearestDesc(dom, true)\n if (!nearest) break\n if (nearest.node.isBlock) { dom = nearest.dom; break }\n dom = nearest.dom.parentNode\n }\n let coords = coordsAtPos(view, $pos.pos)\n for (let child = dom.firstChild; child; child = child.nextSibling) {\n let boxes\n if (child.nodeType == 1) boxes = child.getClientRects()\n else if (child.nodeType == 3) boxes = textRange(child, 0, child.nodeValue.length).getClientRects()\n else continue\n for (let i = 0; i < boxes.length; i++) {\n let box = boxes[i]\n if (box.bottom > box.top && (dir == \"up\" ? box.bottom < coords.top + 1 : box.top > coords.bottom - 1))\n return false\n }\n }\n return true\n })\n}\n\nconst maybeRTL = /[\\u0590-\\u08ac]/\n\nfunction endOfTextblockHorizontal(view, state, dir) {\n let {$head} = state.selection\n if (!$head.parent.isTextblock) return false\n let offset = $head.parentOffset, atStart = !offset, atEnd = offset == $head.parent.content.size\n let sel = getSelection()\n // If the textblock is all LTR, or the browser doesn't support\n // Selection.modify (Edge), fall back to a primitive approach\n if (!maybeRTL.test($head.parent.textContent) || !sel.modify)\n return dir == \"left\" || dir == \"backward\" ? atStart : atEnd\n\n return withFlushedState(view, state, () => {\n // This is a huge hack, but appears to be the best we can\n // currently do: use `Selection.modify` to move the selection by\n // one character, and see if that moves the cursor out of the\n // textblock (or doesn't move it at all, when at the start/end of\n // the document).\n let oldRange = sel.getRangeAt(0), oldNode = sel.focusNode, oldOff = sel.focusOffset\n let oldBidiLevel = sel.caretBidiLevel // Only for Firefox\n sel.modify(\"move\", dir, \"character\")\n let parentDOM = $head.depth ? view.docView.domAfterPos($head.before()) : view.dom\n let result = !parentDOM.contains(sel.focusNode.nodeType == 1 ? sel.focusNode : sel.focusNode.parentNode) ||\n (oldNode == sel.focusNode && oldOff == sel.focusOffset)\n // Restore the previous selection\n sel.removeAllRanges()\n sel.addRange(oldRange)\n if (oldBidiLevel != null) sel.caretBidiLevel = oldBidiLevel\n return result\n })\n}\n\nlet cachedState = null, cachedDir = null, cachedResult = false\nexport function endOfTextblock(view, state, dir) {\n if (cachedState == state && cachedDir == dir) return cachedResult\n cachedState = state; cachedDir = dir\n return cachedResult = dir == \"up\" || dir == \"down\"\n ? endOfTextblockVertical(view, state, dir)\n : endOfTextblockHorizontal(view, state, dir)\n}\n","import {DOMSerializer, Fragment, Mark} from \"prosemirror-model\"\nimport {TextSelection} from \"prosemirror-state\"\n\nimport {domIndex, isEquivalentPosition, nodeSize} from \"./dom\"\nimport browser from \"./browser\"\n\n// NodeView:: interface\n//\n// By default, document nodes are rendered using the result of the\n// [`toDOM`](#model.NodeSpec.toDOM) method of their spec, and managed\n// entirely by the editor. For some use cases, such as embedded\n// node-specific editing interfaces, you want more control over\n// the behavior of a node's in-editor representation, and need to\n// [define](#view.EditorProps.nodeViews) a custom node view.\n//\n// Objects returned as node views must conform to this interface.\n//\n// dom:: ?dom.Node\n// The outer DOM node that represents the document node. When not\n// given, the default strategy is used to create a DOM node.\n//\n// contentDOM:: ?dom.Node\n// The DOM node that should hold the node's content. Only meaningful\n// if the node view also defines a `dom` property and if its node\n// type is not a leaf node type. When this is present, ProseMirror\n// will take care of rendering the node's children into it. When it\n// is not present, the node view itself is responsible for rendering\n// (or deciding not to render) its child nodes.\n//\n// update:: ?(node: Node, decorations: [Decoration]) → bool\n// When given, this will be called when the view is updating itself.\n// It will be given a node (possibly of a different type), and an\n// array of active decorations (which are automatically drawn, and\n// the node view may ignore if it isn't interested in them), and\n// should return true if it was able to update to that node, and\n// false otherwise. If the node view has a `contentDOM` property (or\n// no `dom` property), updating its child nodes will be handled by\n// ProseMirror.\n//\n// selectNode:: ?()\n// Can be used to override the way the node's selected status (as a\n// node selection) is displayed.\n//\n// deselectNode:: ?()\n// When defining a `selectNode` method, you should also provide a\n// `deselectNode` method to remove the effect again.\n//\n// setSelection:: ?(anchor: number, head: number, root: dom.Document)\n// This will be called to handle setting the selection inside the\n// node. The `anchor` and `head` positions are relative to the start\n// of the node. By default, a DOM selection will be created between\n// the DOM positions corresponding to those positions, but if you\n// override it you can do something else.\n//\n// stopEvent:: ?(event: dom.Event) → bool\n// Can be used to prevent the editor view from trying to handle some\n// or all DOM events that bubble up from the node view. Events for\n// which this returns true are not handled by the editor.\n//\n// ignoreMutation:: ?(dom.MutationRecord) → bool\n// Called when a DOM\n// [mutation](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver)\n// or a selection change happens within the view. When the change is\n// a selection change, the record will have a `type` property of\n// `\"selection\"` (which doesn't occur for native mutation records).\n// Return false if the editor should re-read the selection or\n// re-parse the range around the mutation, true if it can safely be\n// ignored.\n//\n// destroy:: ?()\n// Called when the node view is removed from the editor or the whole\n// editor is destroyed.\n\n// View descriptions are data structures that describe the DOM that is\n// used to represent the editor's content. They are used for:\n//\n// - Incremental redrawing when the document changes\n//\n// - Figuring out what part of the document a given DOM position\n// corresponds to\n//\n// - Wiring in custom implementations of the editing interface for a\n// given node\n//\n// They form a doubly-linked mutable tree, starting at `view.docView`.\n\nconst NOT_DIRTY = 0, CHILD_DIRTY = 1, CONTENT_DIRTY = 2, NODE_DIRTY = 3\n\n// Superclass for the various kinds of descriptions. Defines their\n// basic structure and shared methods.\nclass ViewDesc {\n // : (?ViewDesc, [ViewDesc], dom.Node, ?dom.Node)\n constructor(parent, children, dom, contentDOM) {\n this.parent = parent\n this.children = children\n this.dom = dom\n // An expando property on the DOM node provides a link back to its\n // description.\n dom.pmViewDesc = this\n // This is the node that holds the child views. It may be null for\n // descs that don't have children.\n this.contentDOM = contentDOM\n this.dirty = NOT_DIRTY\n }\n\n // Used to check whether a given description corresponds to a\n // widget/mark/node.\n matchesWidget() { return false }\n matchesMark() { return false }\n matchesNode() { return false }\n matchesHack() { return false }\n\n get beforePosition() { return false }\n\n // : () → ?ParseRule\n // When parsing in-editor content (in domchange.js), we allow\n // descriptions to determine the parse rules that should be used to\n // parse them.\n parseRule() { return null }\n\n // : (dom.Event) → bool\n // Used by the editor's event handler to ignore events that come\n // from certain descs.\n stopEvent() { return false }\n\n // The size of the content represented by this desc.\n get size() {\n let size = 0\n for (let i = 0; i < this.children.length; i++) size += this.children[i].size\n return size\n }\n\n // For block nodes, this represents the space taken up by their\n // start/end tokens.\n get border() { return 0 }\n\n destroy() {\n this.parent = null\n if (this.dom.pmViewDesc == this) this.dom.pmViewDesc = null\n for (let i = 0; i < this.children.length; i++)\n this.children[i].destroy()\n }\n\n posBeforeChild(child) {\n for (let i = 0, pos = this.posAtStart; i < this.children.length; i++) {\n let cur = this.children[i]\n if (cur == child) return pos\n pos += cur.size\n }\n }\n\n get posBefore() {\n return this.parent.posBeforeChild(this)\n }\n\n get posAtStart() {\n return this.parent ? this.parent.posBeforeChild(this) + this.border : 0\n }\n\n get posAfter() {\n return this.posBefore + this.size\n }\n\n get posAtEnd() {\n return this.posAtStart + this.size - 2 * this.border\n }\n\n // : (dom.Node, number, ?number) → number\n localPosFromDOM(dom, offset, bias) {\n // If the DOM position is in the content, use the child desc after\n // it to figure out a position.\n if (this.contentDOM && this.contentDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode)) {\n if (bias < 0) {\n let domBefore, desc\n if (dom == this.contentDOM) {\n domBefore = dom.childNodes[offset - 1]\n } else {\n while (dom.parentNode != this.contentDOM) dom = dom.parentNode\n domBefore = dom.previousSibling\n }\n while (domBefore && !((desc = domBefore.pmViewDesc) && desc.parent == this)) domBefore = domBefore.previousSibling\n return domBefore ? this.posBeforeChild(desc) + desc.size : this.posAtStart\n } else {\n let domAfter, desc\n if (dom == this.contentDOM) {\n domAfter = dom.childNodes[offset]\n } else {\n while (dom.parentNode != this.contentDOM) dom = dom.parentNode\n domAfter = dom.nextSibling\n }\n while (domAfter && !((desc = domAfter.pmViewDesc) && desc.parent == this)) domAfter = domAfter.nextSibling\n return domAfter ? this.posBeforeChild(desc) : this.posAtEnd\n }\n }\n // Otherwise, use various heuristics, falling back on the bias\n // parameter, to determine whether to return the position at the\n // start or at the end of this view desc.\n let atEnd\n if (this.contentDOM && this.contentDOM != this.dom && this.dom.contains(this.contentDOM)) {\n atEnd = dom.compareDocumentPosition(this.contentDOM) & 2\n } else if (this.dom.firstChild) {\n if (offset == 0) for (let search = dom;; search = search.parentNode) {\n if (search == this.dom) { atEnd = false; break }\n if (search.parentNode.firstChild != search) break\n }\n if (atEnd == null && offset == dom.childNodes.length) for (let search = dom;; search = search.parentNode) {\n if (search == this.dom) { atEnd = true; break }\n if (search.parentNode.lastChild != search) break\n }\n }\n return (atEnd == null ? bias > 0 : atEnd) ? this.posAtEnd : this.posAtStart\n }\n\n // Scan up the dom finding the first desc that is a descendant of\n // this one.\n nearestDesc(dom, onlyNodes) {\n for (let first = true, cur = dom; cur; cur = cur.parentNode) {\n let desc = this.getDesc(cur)\n if (desc && (!onlyNodes || desc.node)) {\n // If dom is outside of this desc's nodeDOM, don't count it.\n if (first && desc.nodeDOM && !(desc.nodeDOM.nodeType == 1 ? desc.nodeDOM.contains(dom) : desc.nodeDOM == dom)) first = false\n else return desc\n }\n }\n }\n\n getDesc(dom) {\n let desc = dom.pmViewDesc\n for (let cur = desc; cur; cur = cur.parent) if (cur == this) return desc\n }\n\n posFromDOM(dom, offset, bias) {\n for (let scan = dom;; scan = scan.parentNode) {\n let desc = this.getDesc(scan)\n if (desc) return desc.localPosFromDOM(dom, offset, bias)\n }\n }\n\n // : (number) → ?NodeViewDesc\n // Find the desc for the node after the given pos, if any. (When a\n // parent node overrode rendering, there might not be one.)\n descAt(pos) {\n for (let i = 0, offset = 0; i < this.children.length; i++) {\n let child = this.children[i], end = offset + child.size\n if (offset == pos && end != offset) {\n while (!child.border && child.children.length) child = child.children[0]\n return child\n }\n if (pos < end) return child.descAt(pos - offset - child.border)\n offset = end\n }\n }\n\n // : (number) → {node: dom.Node, offset: number}\n domFromPos(pos) {\n if (!this.contentDOM) return {node: this.dom, offset: 0}\n for (let offset = 0, i = 0;; i++) {\n if (offset == pos) {\n while (i < this.children.length && (this.children[i].beforePosition || this.children[i].dom.parentNode != this.contentDOM)) i++\n return {node: this.contentDOM,\n offset: i == this.children.length ? this.contentDOM.childNodes.length : domIndex(this.children[i].dom)}\n }\n if (i == this.children.length) throw new Error(\"Invalid position \" + pos)\n let child = this.children[i], end = offset + child.size\n if (pos < end) return child.domFromPos(pos - offset - child.border)\n offset = end\n }\n }\n\n // Used to find a DOM range in a single parent for a given changed\n // range.\n parseRange(from, to, base = 0) {\n if (this.children.length == 0)\n return {node: this.contentDOM, from, to, fromOffset: 0, toOffset: this.contentDOM.childNodes.length}\n\n let fromOffset = -1, toOffset = -1\n for (let offset = base, i = 0;; i++) {\n let child = this.children[i], end = offset + child.size\n if (fromOffset == -1 && from <= end) {\n let childBase = offset + child.border\n // FIXME maybe descend mark views to parse a narrower range?\n if (from >= childBase && to <= end - child.border && child.node &&\n child.contentDOM && this.contentDOM.contains(child.contentDOM))\n return child.parseRange(from, to, childBase)\n\n from = offset\n for (let j = i; j > 0; j--) {\n let prev = this.children[j - 1]\n if (prev.size && prev.dom.parentNode == this.contentDOM && !prev.emptyChildAt(1)) {\n fromOffset = domIndex(prev.dom) + 1\n break\n }\n from -= prev.size\n }\n if (fromOffset == -1) fromOffset = 0\n }\n if (fromOffset > -1 && to <= end) {\n to = end\n for (let j = i + 1; j < this.children.length; j++) {\n let next = this.children[j]\n if (next.size && next.dom.parentNode == this.contentDOM && !next.emptyChildAt(-1)) {\n toOffset = domIndex(next.dom)\n break\n }\n to += next.size\n }\n if (toOffset == -1) toOffset = this.contentDOM.childNodes.length\n break\n }\n offset = end\n }\n return {node: this.contentDOM, from, to, fromOffset, toOffset}\n }\n\n emptyChildAt(side) {\n if (this.border || !this.contentDOM || !this.children.length) return false\n let child = this.children[side < 0 ? 0 : this.children.length - 1]\n return child.size == 0 || child.emptyChildAt(side)\n }\n\n // : (number) → dom.Node\n domAfterPos(pos) {\n let {node, offset} = this.domFromPos(pos)\n if (node.nodeType != 1 || offset == node.childNodes.length)\n throw new RangeError(\"No node after pos \" + pos)\n return node.childNodes[offset]\n }\n\n // : (number, number, dom.Document)\n // View descs are responsible for setting any selection that falls\n // entirely inside of them, so that custom implementations can do\n // custom things with the selection. Note that this falls apart when\n // a selection starts in such a node and ends in another, in which\n // case we just use whatever domFromPos produces as a best effort.\n setSelection(anchor, head, root, force) {\n // If the selection falls entirely in a child, give it to that child\n let from = Math.min(anchor, head), to = Math.max(anchor, head)\n for (let i = 0, offset = 0; i < this.children.length; i++) {\n let child = this.children[i], end = offset + child.size\n if (from > offset && to < end)\n return child.setSelection(anchor - offset - child.border, head - offset - child.border, root, force)\n offset = end\n }\n\n let anchorDOM = this.domFromPos(anchor), headDOM = this.domFromPos(head)\n let domSel = root.getSelection(), range = document.createRange()\n if (!force &&\n isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset) &&\n isEquivalentPosition(headDOM.node, headDOM.offset, domSel.focusNode, domSel.focusOffset))\n return\n\n // Selection.extend can be used to create an 'inverted' selection\n // (one where the focus is before the anchor), but not all\n // browsers support it yet.\n if (domSel.extend) {\n range.setEnd(anchorDOM.node, anchorDOM.offset)\n range.collapse(false)\n } else {\n if (anchor > head) { let tmp = anchorDOM; anchorDOM = headDOM; headDOM = tmp }\n range.setEnd(headDOM.node, headDOM.offset)\n range.setStart(anchorDOM.node, anchorDOM.offset)\n }\n domSel.removeAllRanges()\n domSel.addRange(range)\n if (domSel.extend)\n domSel.extend(headDOM.node, headDOM.offset)\n }\n\n // : (dom.MutationRecord) → bool\n ignoreMutation(_mutation) {\n return !this.contentDOM\n }\n\n get contentLost() {\n return this.contentDOM && this.contentDOM != this.dom && !this.dom.contains(this.contentDOM)\n }\n\n // Remove a subtree of the element tree that has been touched\n // by a DOM change, so that the next update will redraw it.\n markDirty(from, to) {\n for (let offset = 0, i = 0; i < this.children.length; i++) {\n let child = this.children[i], end = offset + child.size\n if (offset == end ? from <= end && to >= offset : from < end && to > offset) {\n let startInside = offset + child.border, endInside = end - child.border\n if (from >= startInside && to <= endInside) {\n this.dirty = from == offset || to == end ? CONTENT_DIRTY : CHILD_DIRTY\n if (from == startInside && to == endInside &&\n (child.contentLost || child.dom.parentNode != this.contentDOM)) child.dirty = NODE_DIRTY\n else child.markDirty(from - startInside, to - startInside)\n return\n } else {\n child.dirty = NODE_DIRTY\n }\n }\n offset = end\n }\n this.dirty = CONTENT_DIRTY\n }\n\n markParentsDirty() {\n let level = 1\n for (let node = this.parent; node; node = node.parent) {\n let dirty = level == 1 ? CONTENT_DIRTY : CHILD_DIRTY\n if (node.dirty < dirty) node.dirty = dirty\n }\n }\n}\n\n// Reused array to avoid allocating fresh arrays for things that will\n// stay empty anyway.\nconst nothing = []\n\n// A widget desc represents a widget decoration, which is a DOM node\n// drawn between the document nodes.\nclass WidgetViewDesc extends ViewDesc {\n // : (ViewDesc, Decoration)\n constructor(parent, widget, view, pos) {\n let self, dom = widget.type.toDOM\n if (typeof dom == \"function\") dom = dom(view, () => {\n if (!self) return pos\n if (self.parent) return self.parent.posBeforeChild(self)\n })\n if (!widget.type.spec.raw) {\n if (dom.nodeType != 1) {\n let wrap = document.createElement(\"span\")\n wrap.appendChild(dom)\n dom = wrap\n }\n dom.contentEditable = false\n dom.classList.add(\"ProseMirror-widget\")\n }\n super(parent, nothing, dom, null)\n this.widget = widget\n self = this\n }\n\n get beforePosition() {\n return this.widget.type.side < 0\n }\n\n matchesWidget(widget) {\n return this.dirty == NOT_DIRTY && widget.type.eq(this.widget.type)\n }\n\n parseRule() { return {ignore: true} }\n\n stopEvent(event) {\n let stop = this.widget.spec.stopEvent\n return stop ? stop(event) : false\n }\n}\n\nclass CompositionViewDesc extends ViewDesc {\n constructor(parent, dom, textDOM, text) {\n super(parent, nothing, dom, null)\n this.textDOM = textDOM\n this.text = text\n }\n\n get size() { return this.text.length }\n\n localPosFromDOM(dom, offset) {\n if (dom != this.textDOM) return this.posAtStart + (offset ? this.size : 0)\n return this.posAtStart + offset\n }\n\n domFromPos(pos) {\n return {node: this.textDOM, offset: pos}\n }\n\n ignoreMutation(mut) {\n return mut.type === 'characterData' && mut.target.nodeValue == mut.oldValue\n }\n}\n\n// A mark desc represents a mark. May have multiple children,\n// depending on how the mark is split. Note that marks are drawn using\n// a fixed nesting order, for simplicity and predictability, so in\n// some cases they will be split more often than would appear\n// necessary.\nclass MarkViewDesc extends ViewDesc {\n // : (ViewDesc, Mark, dom.Node)\n constructor(parent, mark, dom, contentDOM) {\n super(parent, [], dom, contentDOM)\n this.mark = mark\n }\n\n static create(parent, mark, inline, view) {\n let custom = view.nodeViews[mark.type.name]\n let spec = custom && custom(mark, view, inline)\n if (!spec || !spec.dom)\n spec = DOMSerializer.renderSpec(document, mark.type.spec.toDOM(mark, inline))\n return new MarkViewDesc(parent, mark, spec.dom, spec.contentDOM || spec.dom)\n }\n\n parseRule() { return {mark: this.mark.type.name, attrs: this.mark.attrs, contentElement: this.contentDOM} }\n\n matchesMark(mark) { return this.dirty != NODE_DIRTY && this.mark.eq(mark) }\n\n markDirty(from, to) {\n super.markDirty(from, to)\n // Move dirty info to nearest node view\n if (this.dirty != NOT_DIRTY) {\n let parent = this.parent\n while (!parent.node) parent = parent.parent\n if (parent.dirty < this.dirty) parent.dirty = this.dirty\n this.dirty = NOT_DIRTY\n }\n }\n\n slice(from, to, view) {\n let copy = MarkViewDesc.create(this.parent, this.mark, true, view)\n let nodes = this.children, size = this.size\n if (to < size) nodes = replaceNodes(nodes, to, size, view)\n if (from > 0) nodes = replaceNodes(nodes, 0, from, view)\n for (let i = 0; i < nodes.length; i++) nodes[i].parent = copy\n copy.children = nodes\n return copy\n }\n}\n\n// Node view descs are the main, most common type of view desc, and\n// correspond to an actual node in the document. Unlike mark descs,\n// they populate their child array themselves.\nclass NodeViewDesc extends ViewDesc {\n // : (?ViewDesc, Node, [Decoration], DecorationSet, dom.Node, ?dom.Node, EditorView)\n constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos) {\n super(parent, node.isLeaf ? nothing : [], dom, contentDOM)\n this.nodeDOM = nodeDOM\n this.node = node\n this.outerDeco = outerDeco\n this.innerDeco = innerDeco\n if (contentDOM) this.updateChildren(view, pos)\n }\n\n // By default, a node is rendered using the `toDOM` method from the\n // node type spec. But client code can use the `nodeViews` spec to\n // supply a custom node view, which can influence various aspects of\n // the way the node works.\n //\n // (Using subclassing for this was intentionally decided against,\n // since it'd require exposing a whole slew of finnicky\n // implementation details to the user code that they probably will\n // never need.)\n static create(parent, node, outerDeco, innerDeco, view, pos) {\n let custom = view.nodeViews[node.type.name], descObj\n let spec = custom && custom(node, view, () => {\n // (This is a function that allows the custom view to find its\n // own position)\n if (!descObj) return pos\n if (descObj.parent) return descObj.parent.posBeforeChild(descObj)\n }, outerDeco)\n\n let dom = spec && spec.dom, contentDOM = spec && spec.contentDOM\n if (node.isText) {\n if (!dom) dom = document.createTextNode(node.text)\n else if (dom.nodeType != 3) throw new RangeError(\"Text must be rendered as a DOM text node\")\n } else if (!dom) {\n ;({dom, contentDOM} = DOMSerializer.renderSpec(document, node.type.spec.toDOM(node)))\n }\n if (!contentDOM && !node.isText && dom.nodeName != \"BR\") { // Chrome gets confused by
    \n if (!dom.hasAttribute(\"contenteditable\")) dom.contentEditable = false\n if (node.type.spec.draggable) dom.draggable = true\n }\n\n let nodeDOM = dom\n dom = applyOuterDeco(dom, outerDeco, node)\n\n if (spec)\n return descObj = new CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM,\n spec, view, pos + 1)\n else if (node.isText)\n return new TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM, view)\n else\n return new NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos + 1)\n }\n\n parseRule() {\n // Experimental kludge to allow opt-in re-parsing of nodes\n if (this.node.type.spec.reparseInView) return null\n // FIXME the assumption that this can always return the current\n // attrs means that if the user somehow manages to change the\n // attrs in the dom, that won't be picked up. Not entirely sure\n // whether this is a problem\n let rule = {node: this.node.type.name, attrs: this.node.attrs}\n if (this.node.type.spec.code) rule.preserveWhitespace = \"full\"\n if (this.contentDOM && !this.contentLost) rule.contentElement = this.contentDOM\n else rule.getContent = () => this.contentDOM ? Fragment.empty : this.node.content\n return rule\n }\n\n matchesNode(node, outerDeco, innerDeco) {\n return this.dirty == NOT_DIRTY && node.eq(this.node) &&\n sameOuterDeco(outerDeco, this.outerDeco) && innerDeco.eq(this.innerDeco)\n }\n\n get size() { return this.node.nodeSize }\n\n get border() { return this.node.isLeaf ? 0 : 1 }\n\n // Syncs `this.children` to match `this.node.content` and the local\n // decorations, possibly introducing nesting for marks. Then, in a\n // separate step, syncs the DOM inside `this.contentDOM` to\n // `this.children`.\n updateChildren(view, pos) {\n let inline = this.node.inlineContent, off = pos\n let composition = inline && view.composing && this.localCompositionNode(view, pos)\n let updater = new ViewTreeUpdater(this, composition && composition.node)\n iterDeco(this.node, this.innerDeco, (widget, i) => {\n if (widget.spec.marks)\n updater.syncToMarks(widget.spec.marks, inline, view)\n else if (widget.type.side >= 0)\n updater.syncToMarks(i == this.node.childCount ? Mark.none : this.node.child(i).marks, inline, view)\n // If the next node is a desc matching this widget, reuse it,\n // otherwise insert the widget as a new view desc.\n updater.placeWidget(widget, view, off)\n }, (child, outerDeco, innerDeco, i) => {\n // Make sure the wrapping mark descs match the node's marks.\n updater.syncToMarks(child.marks, inline, view)\n // Either find an existing desc that exactly matches this node,\n // and drop the descs before it.\n updater.findNodeMatch(child, outerDeco, innerDeco, i) ||\n // Or try updating the next desc to reflect this node.\n updater.updateNextNode(child, outerDeco, innerDeco, view, i) ||\n // Or just add it as a new desc.\n updater.addNode(child, outerDeco, innerDeco, view, off)\n off += child.nodeSize\n })\n // Drop all remaining descs after the current position.\n updater.syncToMarks(nothing, inline, view)\n if (this.node.isTextblock) updater.addTextblockHacks()\n updater.destroyRest()\n\n // Sync the DOM if anything changed\n if (updater.changed || this.dirty == CONTENT_DIRTY) {\n // May have to protect focused DOM from being changed if a composition is active\n if (composition) this.protectLocalComposition(view, composition)\n this.renderChildren()\n }\n }\n\n renderChildren() {\n renderDescs(this.contentDOM, this.children, NodeViewDesc.is)\n if (browser.ios) iosHacks(this.dom)\n }\n\n localCompositionNode(view, pos) {\n // Only do something if both the selection and a focused text node\n // are inside of this node, and the node isn't already part of a\n // view that's a child of this view\n let {from, to} = view.state.selection\n if (!(view.state.selection instanceof TextSelection) || from < pos || to > pos + this.node.content.size) return\n let sel = view.root.getSelection()\n let textNode = nearbyTextNode(sel.focusNode, sel.focusOffset)\n if (!textNode || !this.dom.contains(textNode.parentNode)) return\n\n // Find the text in the focused node in the node, stop if it's not\n // there (may have been modified through other means, in which\n // case it should overwritten)\n let text = textNode.nodeValue\n let textPos = findTextInFragment(this.node.content, text, from - pos, to - pos)\n\n return textPos < 0 ? null : {node: textNode, pos: textPos, text}\n }\n\n protectLocalComposition(view, {node, pos, text}) {\n // The node is already part of a local view desc, leave it there\n if (this.getDesc(node)) return\n\n // Create a composition view for the orphaned nodes\n let topNode = node\n for (;; topNode = topNode.parentNode) {\n if (topNode.parentNode == this.contentDOM) break\n while (topNode.previousSibling) topNode.parentNode.removeChild(topNode.previousSibling)\n while (topNode.nextSibling) topNode.parentNode.removeChild(topNode.nextSibling)\n if (topNode.pmViewDesc) topNode.pmViewDesc = null\n }\n let desc = new CompositionViewDesc(this, topNode, node, text)\n view.compositionNodes.push(desc)\n\n // Patch up this.children to contain the composition view\n this.children = replaceNodes(this.children, pos, pos + text.length, view, desc)\n }\n\n // : (Node, [Decoration], DecorationSet, EditorView) → bool\n // If this desc be updated to match the given node decoration,\n // do so and return true.\n update(node, outerDeco, innerDeco, view) {\n if (this.dirty == NODE_DIRTY ||\n !node.sameMarkup(this.node)) return false\n this.updateInner(node, outerDeco, innerDeco, view)\n return true\n }\n\n updateInner(node, outerDeco, innerDeco, view) {\n this.updateOuterDeco(outerDeco)\n this.node = node\n this.innerDeco = innerDeco\n if (this.contentDOM) this.updateChildren(view, this.posAtStart)\n this.dirty = NOT_DIRTY\n }\n\n updateOuterDeco(outerDeco) {\n if (sameOuterDeco(outerDeco, this.outerDeco)) return\n let needsWrap = this.nodeDOM.nodeType != 1\n let oldDOM = this.dom\n this.dom = patchOuterDeco(this.dom, this.nodeDOM,\n computeOuterDeco(this.outerDeco, this.node, needsWrap),\n computeOuterDeco(outerDeco, this.node, needsWrap))\n if (this.dom != oldDOM) {\n oldDOM.pmViewDesc = null\n this.dom.pmViewDesc = this\n }\n this.outerDeco = outerDeco\n }\n\n // Mark this node as being the selected node.\n selectNode() {\n this.nodeDOM.classList.add(\"ProseMirror-selectednode\")\n if (this.contentDOM || !this.node.type.spec.draggable) this.dom.draggable = true\n }\n\n // Remove selected node marking from this node.\n deselectNode() {\n this.nodeDOM.classList.remove(\"ProseMirror-selectednode\")\n if (this.contentDOM || !this.node.type.spec.draggable) this.dom.draggable = false\n }\n}\n\n// Create a view desc for the top-level document node, to be exported\n// and used by the view class.\nexport function docViewDesc(doc, outerDeco, innerDeco, dom, view) {\n applyOuterDeco(dom, outerDeco, doc)\n return new NodeViewDesc(null, doc, outerDeco, innerDeco, dom, dom, dom, view, 0)\n}\n\nclass TextViewDesc extends NodeViewDesc {\n constructor(parent, node, outerDeco, innerDeco, dom, nodeDOM, view) {\n super(parent, node, outerDeco, innerDeco, dom, null, nodeDOM, view)\n }\n\n parseRule() {\n return {skip: this.nodeDOM.parentNode || true}\n }\n\n update(node, outerDeco) {\n if (this.dirty == NODE_DIRTY || (this.dirty != NOT_DIRTY && !this.inParent()) ||\n !node.sameMarkup(this.node)) return false\n this.updateOuterDeco(outerDeco)\n if ((this.dirty != NOT_DIRTY || node.text != this.node.text) && node.text != this.nodeDOM.nodeValue)\n this.nodeDOM.nodeValue = node.text\n this.node = node\n this.dirty = NOT_DIRTY\n return true\n }\n\n inParent() {\n let parentDOM = this.parent.contentDOM\n for (let n = this.nodeDOM; n; n = n.parentNode) if (n == parentDOM) return true\n return false\n }\n\n domFromPos(pos) {\n return {node: this.nodeDOM, offset: pos}\n }\n\n localPosFromDOM(dom, offset, bias) {\n if (dom == this.nodeDOM) return this.posAtStart + Math.min(offset, this.node.text.length)\n return super.localPosFromDOM(dom, offset, bias)\n }\n\n ignoreMutation(mutation) {\n return mutation.type != \"characterData\" && mutation.type != \"selection\"\n }\n\n slice(from, to, view) {\n let node = this.node.cut(from, to), dom = document.createTextNode(node.text)\n return new TextViewDesc(this.parent, node, this.outerDeco, this.innerDeco, dom, dom, view)\n }\n}\n\n// A dummy desc used to tag trailing BR or span nodes created to work\n// around contentEditable terribleness.\nclass BRHackViewDesc extends ViewDesc {\n parseRule() { return {ignore: true} }\n matchesHack() { return this.dirty == NOT_DIRTY }\n}\n\n// A separate subclass is used for customized node views, so that the\n// extra checks only have to be made for nodes that are actually\n// customized.\nclass CustomNodeViewDesc extends NodeViewDesc {\n // : (?ViewDesc, Node, [Decoration], DecorationSet, dom.Node, ?dom.Node, NodeView, EditorView)\n constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, spec, view, pos) {\n super(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos)\n this.spec = spec\n }\n\n // A custom `update` method gets to decide whether the update goes\n // through. If it does, and there's a `contentDOM` node, our logic\n // updates the children.\n update(node, outerDeco, innerDeco, view) {\n if (this.dirty == NODE_DIRTY) return false\n if (this.spec.update) {\n let result = this.spec.update(node, outerDeco)\n if (result) this.updateInner(node, outerDeco, innerDeco, view)\n return result\n } else if (!this.contentDOM && !node.isLeaf) {\n return false\n } else {\n return super.update(node, outerDeco, innerDeco, view)\n }\n }\n\n selectNode() {\n this.spec.selectNode ? this.spec.selectNode() : super.selectNode()\n }\n\n deselectNode() {\n this.spec.deselectNode ? this.spec.deselectNode() : super.deselectNode()\n }\n\n setSelection(anchor, head, root, force) {\n this.spec.setSelection ? this.spec.setSelection(anchor, head, root)\n : super.setSelection(anchor, head, root, force)\n }\n\n destroy() {\n if (this.spec.destroy) this.spec.destroy()\n super.destroy()\n }\n\n stopEvent(event) {\n return this.spec.stopEvent ? this.spec.stopEvent(event) : false\n }\n\n ignoreMutation(mutation) {\n return this.spec.ignoreMutation ? this.spec.ignoreMutation(mutation) : super.ignoreMutation(mutation)\n }\n}\n\n// : (dom.Node, [ViewDesc])\n// Sync the content of the given DOM node with the nodes associated\n// with the given array of view descs, recursing into mark descs\n// because this should sync the subtree for a whole node at a time.\nfunction renderDescs(parentDOM, descs) {\n let dom = parentDOM.firstChild\n for (let i = 0; i < descs.length; i++) {\n let desc = descs[i], childDOM = desc.dom\n if (childDOM.parentNode == parentDOM) {\n while (childDOM != dom) dom = rm(dom)\n dom = dom.nextSibling\n } else {\n parentDOM.insertBefore(childDOM, dom)\n }\n if (desc instanceof MarkViewDesc) {\n let pos = dom ? dom.previousSibling : parentDOM.lastChild\n renderDescs(desc.contentDOM, desc.children)\n dom = pos ? pos.nextSibling : parentDOM.firstChild\n }\n }\n while (dom) dom = rm(dom)\n}\n\nfunction OuterDecoLevel(nodeName) {\n if (nodeName) this.nodeName = nodeName\n}\nOuterDecoLevel.prototype = Object.create(null)\n\nconst noDeco = [new OuterDecoLevel]\n\nfunction computeOuterDeco(outerDeco, node, needsWrap) {\n if (outerDeco.length == 0) return noDeco\n\n let top = needsWrap ? noDeco[0] : new OuterDecoLevel, result = [top]\n\n for (let i = 0; i < outerDeco.length; i++) {\n let attrs = outerDeco[i].type.attrs, cur = top\n if (!attrs) continue\n if (attrs.nodeName)\n result.push(cur = new OuterDecoLevel(attrs.nodeName))\n\n for (let name in attrs) {\n let val = attrs[name]\n if (val == null) continue\n if (needsWrap && result.length == 1)\n result.push(cur = top = new OuterDecoLevel(node.isInline ? \"span\" : \"div\"))\n if (name == \"class\") cur.class = (cur.class ? cur.class + \" \" : \"\") + val\n else if (name == \"style\") cur.style = (cur.style ? cur.style + \";\" : \"\") + val\n else if (name != \"nodeName\") cur[name] = val\n }\n }\n\n return result\n}\n\nfunction patchOuterDeco(outerDOM, nodeDOM, prevComputed, curComputed) {\n // Shortcut for trivial case\n if (prevComputed == noDeco && curComputed == noDeco) return nodeDOM\n\n let curDOM = nodeDOM\n for (let i = 0; i < curComputed.length; i++) {\n let deco = curComputed[i], prev = prevComputed[i]\n if (i) {\n let parent\n if (prev && prev.nodeName == deco.nodeName && curDOM != outerDOM &&\n (parent = curDOM.parentNode) && parent.tagName.toLowerCase() == deco.nodeName) {\n curDOM = parent\n } else {\n parent = document.createElement(deco.nodeName)\n parent.appendChild(curDOM)\n prev = noDeco[0]\n curDOM = parent\n }\n }\n patchAttributes(curDOM, prev || noDeco[0], deco)\n }\n return curDOM\n}\n\nfunction patchAttributes(dom, prev, cur) {\n for (let name in prev)\n if (name != \"class\" && name != \"style\" && name != \"nodeName\" && !(name in cur))\n dom.removeAttribute(name)\n for (let name in cur)\n if (name != \"class\" && name != \"style\" && name != \"nodeName\" && cur[name] != prev[name])\n dom.setAttribute(name, cur[name])\n if (prev.class != cur.class) {\n let prevList = prev.class ? prev.class.split(\" \") : nothing\n let curList = cur.class ? cur.class.split(\" \") : nothing\n for (let i = 0; i < prevList.length; i++) if (curList.indexOf(prevList[i]) == -1)\n dom.classList.remove(prevList[i])\n for (let i = 0; i < curList.length; i++) if (prevList.indexOf(curList[i]) == -1)\n dom.classList.add(curList[i])\n }\n if (prev.style != cur.style) {\n if (prev.style) {\n let prop = /\\s*([\\w\\-\\xa1-\\uffff]+)\\s*:(?:\"(?:\\\\.|[^\"])*\"|'(?:\\\\.|[^'])*'|\\(.*?\\)|[^;])*/g, m\n while (m = prop.exec(prev.style))\n dom.style.removeProperty(m[1])\n }\n if (cur.style)\n dom.style.cssText += cur.style\n }\n}\n\nfunction applyOuterDeco(dom, deco, node) {\n return patchOuterDeco(dom, dom, noDeco, computeOuterDeco(deco, node, dom.nodeType != 1))\n}\n\n// : ([Decoration], [Decoration]) → bool\nfunction sameOuterDeco(a, b) {\n if (a.length != b.length) return false\n for (let i = 0; i < a.length; i++) if (!a[i].type.eq(b[i].type)) return false\n return true\n}\n\n// Remove a DOM node and return its next sibling.\nfunction rm(dom) {\n let next = dom.nextSibling\n dom.parentNode.removeChild(dom)\n return next\n}\n\n// Helper class for incrementally updating a tree of mark descs and\n// the widget and node descs inside of them.\nclass ViewTreeUpdater {\n // : (NodeViewDesc)\n constructor(top, lockedNode) {\n this.top = top\n this.lock = lockedNode\n // Index into `this.top`'s child array, represents the current\n // update position.\n this.index = 0\n // When entering a mark, the current top and index are pushed\n // onto this.\n this.stack = []\n // Tracks whether anything was changed\n this.changed = false\n\n let pre = preMatch(top.node.content, top.children)\n this.preMatched = pre.nodes\n this.preMatchOffset = pre.offset\n }\n\n getPreMatch(index) {\n return index >= this.preMatchOffset ? this.preMatched[index - this.preMatchOffset] : null\n }\n\n // Destroy and remove the children between the given indices in\n // `this.top`.\n destroyBetween(start, end) {\n if (start == end) return\n for (let i = start; i < end; i++) this.top.children[i].destroy()\n this.top.children.splice(start, end - start)\n this.changed = true\n }\n\n // Destroy all remaining children in `this.top`.\n destroyRest() {\n this.destroyBetween(this.index, this.top.children.length)\n }\n\n // : ([Mark], EditorView)\n // Sync the current stack of mark descs with the given array of\n // marks, reusing existing mark descs when possible.\n syncToMarks(marks, inline, view) {\n let keep = 0, depth = this.stack.length >> 1\n let maxKeep = Math.min(depth, marks.length)\n while (keep < maxKeep &&\n (keep == depth - 1 ? this.top : this.stack[(keep + 1) << 1]).matchesMark(marks[keep]) && marks[keep].type.spec.spanning !== false)\n keep++\n\n while (keep < depth) {\n this.destroyRest()\n this.top.dirty = NOT_DIRTY\n this.index = this.stack.pop()\n this.top = this.stack.pop()\n depth--\n }\n while (depth < marks.length) {\n this.stack.push(this.top, this.index + 1)\n let found = -1\n for (let i = this.index; i < Math.min(this.index + 3, this.top.children.length); i++) {\n if (this.top.children[i].matchesMark(marks[depth])) { found = i; break }\n }\n if (found > -1) {\n if (found > this.index) {\n this.changed = true\n this.destroyBetween(this.index, found)\n }\n this.top = this.top.children[this.index]\n } else {\n let markDesc = MarkViewDesc.create(this.top, marks[depth], inline, view)\n this.top.children.splice(this.index, 0, markDesc)\n this.top = markDesc\n this.changed = true\n }\n this.index = 0\n depth++\n }\n }\n\n // : (Node, [Decoration], DecorationSet) → bool\n // Try to find a node desc matching the given data. Skip over it and\n // return true when successful.\n findNodeMatch(node, outerDeco, innerDeco, index) {\n let found = -1, preMatch = index < 0 ? undefined : this.getPreMatch(index), children = this.top.children\n if (preMatch && preMatch.matchesNode(node, outerDeco, innerDeco)) {\n found = children.indexOf(preMatch)\n } else {\n for (let i = this.index, e = Math.min(children.length, i + 5); i < e; i++) {\n let child = children[i]\n if (child.matchesNode(node, outerDeco, innerDeco) && this.preMatched.indexOf(child) < 0) {\n found = i\n break\n }\n }\n }\n if (found < 0) return false\n this.destroyBetween(this.index, found)\n this.index++\n return true\n }\n\n // : (Node, [Decoration], DecorationSet, EditorView, Fragment, number) → bool\n // Try to update the next node, if any, to the given data. Checks\n // pre-matches to avoid overwriting nodes that could still be used.\n updateNextNode(node, outerDeco, innerDeco, view, index) {\n if (this.index == this.top.children.length) return false\n let next = this.top.children[this.index]\n if (next instanceof NodeViewDesc) {\n let preMatch = this.preMatched.indexOf(next)\n if (preMatch > -1 && preMatch + this.preMatchOffset != index) return false\n let nextDOM = next.dom\n\n // Can't update if nextDOM is or contains this.lock, except if\n // it's a text node whose content already matches the new text\n // and whose decorations match the new ones.\n let locked = this.lock && (nextDOM == this.lock || nextDOM.nodeType == 1 && nextDOM.contains(this.lock.parentNode)) &&\n !(node.isText && next.node && next.node.isText && next.nodeDOM.nodeValue == node.text &&\n next.dirty != NODE_DIRTY && sameOuterDeco(outerDeco, next.outerDeco))\n if (!locked && next.update(node, outerDeco, innerDeco, view)) {\n if (next.dom != nextDOM) this.changed = true\n this.index++\n return true\n }\n }\n return false\n }\n\n // : (Node, [Decoration], DecorationSet, EditorView)\n // Insert the node as a newly created node desc.\n addNode(node, outerDeco, innerDeco, view, pos) {\n this.top.children.splice(this.index++, 0, NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos))\n this.changed = true\n }\n\n placeWidget(widget, view, pos) {\n if (this.index < this.top.children.length && this.top.children[this.index].matchesWidget(widget)) {\n this.index++\n } else {\n let desc = new WidgetViewDesc(this.top, widget, view, pos)\n this.top.children.splice(this.index++, 0, desc)\n this.changed = true\n }\n }\n\n // Make sure a textblock looks and behaves correctly in\n // contentEditable.\n addTextblockHacks() {\n let lastChild = this.top.children[this.index - 1]\n while (lastChild instanceof MarkViewDesc) lastChild = lastChild.children[lastChild.children.length - 1]\n\n if (!lastChild || // Empty textblock\n !(lastChild instanceof TextViewDesc) ||\n /\\n$/.test(lastChild.node.text)) {\n if (this.index < this.top.children.length && this.top.children[this.index].matchesHack()) {\n this.index++\n } else {\n let dom = document.createElement(\"br\")\n this.top.children.splice(this.index++, 0, new BRHackViewDesc(this.top, nothing, dom, null))\n this.changed = true\n }\n }\n }\n}\n\n// : (Fragment, [ViewDesc]) → [ViewDesc]\n// Iterate from the end of the fragment and array of descs to find\n// directly matching ones, in order to avoid overeagerly reusing\n// those for other nodes. Returns an array whose positions correspond\n// to node positions in the fragment, and whose elements are either\n// descs matched to the child at that index, or empty.\nfunction preMatch(frag, descs) {\n let result = [], end = frag.childCount\n for (let i = descs.length - 1; end > 0 && i >= 0; i--) {\n let desc = descs[i], node = desc.node\n if (!node) continue\n if (node != frag.child(end - 1)) break\n result.push(desc)\n --end\n }\n return {nodes: result.reverse(), offset: end}\n}\n\nfunction compareSide(a, b) { return a.type.side - b.type.side }\n\n// : (ViewDesc, DecorationSet, (Decoration, number), (Node, [Decoration], DecorationSet, number))\n// This function abstracts iterating over the nodes and decorations in\n// a fragment. Calls `onNode` for each node, with its local and child\n// decorations. Splits text nodes when there is a decoration starting\n// or ending inside of them. Calls `onWidget` for each widget.\nfunction iterDeco(parent, deco, onWidget, onNode) {\n let locals = deco.locals(parent), offset = 0\n // Simple, cheap variant for when there are no local decorations\n if (locals.length == 0) {\n for (let i = 0; i < parent.childCount; i++) {\n let child = parent.child(i)\n onNode(child, locals, deco.forChild(offset, child), i)\n offset += child.nodeSize\n }\n return\n }\n\n let decoIndex = 0, active = [], restNode = null\n for (let parentIndex = 0;;) {\n if (decoIndex < locals.length && locals[decoIndex].to == offset) {\n let widget = locals[decoIndex++], widgets\n while (decoIndex < locals.length && locals[decoIndex].to == offset)\n (widgets || (widgets = [widget])).push(locals[decoIndex++])\n if (widgets) {\n widgets.sort(compareSide)\n for (let i = 0; i < widgets.length; i++) onWidget(widgets[i], parentIndex)\n } else {\n onWidget(widget, parentIndex)\n }\n }\n\n let child, index\n if (restNode) {\n index = -1\n child = restNode\n restNode = null\n } else if (parentIndex < parent.childCount) {\n index = parentIndex\n child = parent.child(parentIndex++)\n } else {\n break\n }\n\n for (let i = 0; i < active.length; i++) if (active[i].to <= offset) active.splice(i--, 1)\n while (decoIndex < locals.length && locals[decoIndex].from == offset) active.push(locals[decoIndex++])\n\n let end = offset + child.nodeSize\n if (child.isText) {\n let cutAt = end\n if (decoIndex < locals.length && locals[decoIndex].from < cutAt) cutAt = locals[decoIndex].from\n for (let i = 0; i < active.length; i++) if (active[i].to < cutAt) cutAt = active[i].to\n if (cutAt < end) {\n restNode = child.cut(cutAt - offset)\n child = child.cut(0, cutAt - offset)\n end = cutAt\n index = -1\n }\n }\n\n onNode(child, active.length ? active.slice() : nothing, deco.forChild(offset, child), index)\n offset = end\n }\n}\n\n// List markers in Mobile Safari will mysteriously disappear\n// sometimes. This works around that.\nfunction iosHacks(dom) {\n if (dom.nodeName == \"UL\" || dom.nodeName == \"OL\") {\n let oldCSS = dom.style.cssText\n dom.style.cssText = oldCSS + \"; list-style: square !important\"\n window.getComputedStyle(dom).listStyle\n dom.style.cssText = oldCSS\n }\n}\n\nfunction nearbyTextNode(node, offset) {\n for (;;) {\n if (node.nodeType == 3) return node\n if (node.nodeType == 1 && offset > 0) {\n if (node.childNodes.length > offset && node.childNodes[offset].nodeType == 3)\n return node.childNodes[offset]\n node = node.childNodes[offset - 1]\n offset = nodeSize(node)\n } else if (node.nodeType == 1 && offset < node.childNodes.length) {\n node = node.childNodes[offset]\n offset = 0\n } else {\n return null\n }\n }\n}\n\n// Find a piece of text in an inline fragment, overlapping from-to\nfunction findTextInFragment(frag, text, from, to) {\n for (let str = \"\", i = 0, childPos = 0; i < frag.childCount; i++) {\n let child = frag.child(i), end = childPos + child.nodeSize\n if (child.isText) {\n str += child.text\n if (end >= to) {\n let strStart = end - str.length, found = str.lastIndexOf(text)\n while (found > -1 && strStart + found > from) found = str.lastIndexOf(text, found - 1)\n if (found > -1 && strStart + found + text.length >= to) {\n return strStart + found\n } else if (end > to) {\n break\n }\n }\n } else {\n str = \"\"\n }\n childPos = end\n }\n return -1\n}\n\n// Replace range from-to in an array of view descs with replacement\n// (may be null to just delete). This goes very much against the grain\n// of the rest of this code, which tends to create nodes with the\n// right shape in one go, rather than messing with them after\n// creation, but is necessary in the composition hack.\nfunction replaceNodes(nodes, from, to, view, replacement) {\n let result = []\n for (let i = 0, off = 0; i < nodes.length; i++) {\n let child = nodes[i], start = off, end = off += child.size\n if (start >= to || end <= from) {\n result.push(child)\n } else {\n if (start < from) result.push(child.slice(0, from - start, view))\n if (replacement) {\n result.push(replacement)\n replacement = null\n }\n if (end > to) result.push(child.slice(to - start, child.size, view))\n }\n }\n return result\n}\n","import {Selection, NodeSelection, TextSelection} from \"prosemirror-state\"\nimport browser from \"./browser\"\nimport {domIndex, selectionCollapsed} from \"./dom\"\n\nfunction moveSelectionBlock(state, dir) {\n let {$anchor, $head} = state.selection\n let $side = dir > 0 ? $anchor.max($head) : $anchor.min($head)\n let $start = !$side.parent.inlineContent ? $side : $side.depth ? state.doc.resolve(dir > 0 ? $side.after() : $side.before()) : null\n return $start && Selection.findFrom($start, dir)\n}\n\nfunction apply(view, sel) {\n view.dispatch(view.state.tr.setSelection(sel).scrollIntoView())\n return true\n}\n\nfunction selectHorizontally(view, dir, mods) {\n let sel = view.state.selection\n if (sel instanceof TextSelection) {\n if (!sel.empty || mods.indexOf(\"s\") > -1) {\n return false\n } else if (view.endOfTextblock(dir > 0 ? \"right\" : \"left\")) {\n let next = moveSelectionBlock(view.state, dir)\n if (next && (next instanceof NodeSelection)) return apply(view, next)\n return false\n } else {\n let $head = sel.$head, node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter, desc\n if (!node || node.isText) return false\n let nodePos = dir < 0 ? $head.pos - node.nodeSize : $head.pos\n if (!(node.isAtom || (desc = view.docView.descAt(nodePos)) && !desc.contentDOM)) return false\n if (NodeSelection.isSelectable(node)) {\n return apply(view, new NodeSelection(dir < 0 ? view.state.doc.resolve($head.pos - node.nodeSize) : $head))\n } else if (browser.webkit) {\n // Chrome and Safari will introduce extra pointless cursor\n // positions around inline uneditable nodes, so we have to\n // take over and move the cursor past them (#937)\n return apply(view, new TextSelection(view.state.doc.resolve(dir < 0 ? nodePos : nodePos + node.nodeSize)))\n } else {\n return false\n }\n }\n } else if (sel instanceof NodeSelection && sel.node.isInline) {\n return apply(view, new TextSelection(dir > 0 ? sel.$to : sel.$from))\n } else {\n let next = moveSelectionBlock(view.state, dir)\n if (next) return apply(view, next)\n return false\n }\n}\n\nfunction nodeLen(node) {\n return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length\n}\n\nfunction isIgnorable(dom) {\n let desc = dom.pmViewDesc\n return desc && desc.size == 0 && (dom.nextSibling || dom.nodeName != \"BR\")\n}\n\n// Make sure the cursor isn't directly after one or more ignored\n// nodes, which will confuse the browser's cursor motion logic.\nfunction skipIgnoredNodesLeft(view) {\n let sel = view.root.getSelection()\n let node = sel.focusNode, offset = sel.focusOffset\n if (!node) return\n let moveNode, moveOffset, force = false\n // Gecko will do odd things when the selection is directly in front\n // of a non-editable node, so in that case, move it into the next\n // node if possible. Issue prosemirror/prosemirror#832.\n if (browser.gecko && node.nodeType == 1 && offset < nodeLen(node) && isIgnorable(node.childNodes[offset])) force = true\n for (;;) {\n if (offset > 0) {\n if (node.nodeType != 1) {\n break\n } else {\n let before = node.childNodes[offset - 1]\n if (isIgnorable(before)) {\n moveNode = node\n moveOffset = --offset\n } else if (before.nodeType == 3) {\n node = before\n offset = node.nodeValue.length\n } else break\n }\n } else if (isBlockNode(node)) {\n break\n } else {\n let prev = node.previousSibling\n while (prev && isIgnorable(prev)) {\n moveNode = node.parentNode\n moveOffset = domIndex(prev)\n prev = prev.previousSibling\n }\n if (!prev) {\n node = node.parentNode\n if (node == view.dom) break\n offset = 0\n } else {\n node = prev\n offset = nodeLen(node)\n }\n }\n }\n if (force) setSelFocus(view, sel, node, offset)\n else if (moveNode) setSelFocus(view, sel, moveNode, moveOffset)\n}\n\n// Make sure the cursor isn't directly before one or more ignored\n// nodes.\nfunction skipIgnoredNodesRight(view) {\n let sel = view.root.getSelection()\n let node = sel.focusNode, offset = sel.focusOffset\n if (!node) return\n let len = nodeLen(node)\n let moveNode, moveOffset\n for (;;) {\n if (offset < len) {\n if (node.nodeType != 1) break\n let after = node.childNodes[offset]\n if (isIgnorable(after)) {\n moveNode = node\n moveOffset = ++offset\n }\n else break\n } else if (isBlockNode(node)) {\n break\n } else {\n let next = node.nextSibling\n while (next && isIgnorable(next)) {\n moveNode = next.parentNode\n moveOffset = domIndex(next) + 1\n next = next.nextSibling\n }\n if (!next) {\n node = node.parentNode\n if (node == view.dom) break\n offset = len = 0\n } else {\n node = next\n offset = 0\n len = nodeLen(node)\n }\n }\n }\n if (moveNode) setSelFocus(view, sel, moveNode, moveOffset)\n}\n\nfunction isBlockNode(dom) {\n let desc = dom.pmViewDesc\n return desc && desc.node && desc.node.isBlock\n}\n\nfunction setSelFocus(view, sel, node, offset) {\n if (selectionCollapsed(sel)) {\n let range = document.createRange()\n range.setEnd(node, offset)\n range.setStart(node, offset)\n sel.removeAllRanges()\n sel.addRange(range)\n } else if (sel.extend) {\n sel.extend(node, offset)\n }\n view.domObserver.setCurSelection()\n}\n\n// : (EditorState, number)\n// Check whether vertical selection motion would involve node\n// selections. If so, apply it (if not, the result is left to the\n// browser)\nfunction selectVertically(view, dir, mods) {\n let sel = view.state.selection\n if (sel instanceof TextSelection && !sel.empty || mods.indexOf(\"s\") > -1) return false\n let {$from, $to} = sel\n\n if (!$from.parent.inlineContent || view.endOfTextblock(dir < 0 ? \"up\" : \"down\")) {\n let next = moveSelectionBlock(view.state, dir)\n if (next && (next instanceof NodeSelection))\n return apply(view, next)\n }\n if (!$from.parent.inlineContent) {\n let beyond = Selection.findFrom(dir < 0 ? $from : $to, dir)\n return beyond ? apply(view, beyond) : true\n }\n return false\n}\n\nfunction stopNativeHorizontalDelete(view, dir) {\n if (!(view.state.selection instanceof TextSelection)) return true\n let {$head, $anchor, empty} = view.state.selection\n if (!$head.sameParent($anchor)) return true\n if (!empty) return false\n if (view.endOfTextblock(dir > 0 ? \"forward\" : \"backward\")) return true\n let nextNode = !$head.textOffset && (dir < 0 ? $head.nodeBefore : $head.nodeAfter)\n if (nextNode && !nextNode.isText) {\n let tr = view.state.tr\n if (dir < 0) tr.delete($head.pos - nextNode.nodeSize, $head.pos)\n else tr.delete($head.pos, $head.pos + nextNode.nodeSize)\n view.dispatch(tr)\n return true\n }\n return false\n}\n\nfunction switchEditable(view, node, state) {\n view.domObserver.stop()\n node.contentEditable = state\n view.domObserver.start()\n}\n\n// Issue #867 / https://bugs.chromium.org/p/chromium/issues/detail?id=903821\n// In which Chrome does really wrong things when the down arrow is\n// pressed when the cursor is directly at the start of a textblock and\n// has an uneditable node after it\nfunction chromeDownArrowBug(view) {\n if (!browser.chrome || view.state.selection.$head.parentOffset > 0) return\n let {focusNode, focusOffset} = view.root.getSelection()\n if (focusNode && focusNode.nodeType == 1 && focusOffset == 0 &&\n focusNode.firstChild && focusNode.firstChild.contentEditable == \"false\") {\n let child = focusNode.firstChild\n switchEditable(view, child, true)\n setTimeout(() => switchEditable(view, child, false), 20)\n }\n}\n\n// A backdrop key mapping used to make sure we always suppress keys\n// that have a dangerous default effect, even if the commands they are\n// bound to return false, and to make sure that cursor-motion keys\n// find a cursor (as opposed to a node selection) when pressed. For\n// cursor-motion keys, the code in the handlers also takes care of\n// block selections.\n\nfunction getMods(event) {\n let result = \"\"\n if (event.ctrlKey) result += \"c\"\n if (event.metaKey) result += \"m\"\n if (event.altKey) result += \"a\"\n if (event.shiftKey) result += \"s\"\n return result\n}\n\nexport function captureKeyDown(view, event) {\n let code = event.keyCode, mods = getMods(event)\n if (code == 8 || (browser.mac && code == 72 && mods == \"c\")) { // Backspace, Ctrl-h on Mac\n return stopNativeHorizontalDelete(view, -1) || skipIgnoredNodesLeft(view)\n } else if (code == 46 || (browser.mac && code == 68 && mods == \"c\")) { // Delete, Ctrl-d on Mac\n return stopNativeHorizontalDelete(view, 1) || skipIgnoredNodesRight(view)\n } else if (code == 13 || code == 27) { // Enter, Esc\n return true\n } else if (code == 37) { // Left arrow\n return selectHorizontally(view, -1, mods) || skipIgnoredNodesLeft(view)\n } else if (code == 39) { // Right arrow\n return selectHorizontally(view, 1, mods) || skipIgnoredNodesRight(view)\n } else if (code == 38) { // Up arrow\n return selectVertically(view, -1, mods) || skipIgnoredNodesLeft(view)\n } else if (code == 40) { // Down arrow\n return chromeDownArrowBug(view) || selectVertically(view, 1, mods) || skipIgnoredNodesRight(view)\n } else if (mods == (browser.mac ? \"m\" : \"c\") &&\n (code == 66 || code == 73 || code == 89 || code == 90)) { // Mod-[biyz]\n return true\n }\n return false\n}\n","import {TextSelection, NodeSelection} from \"prosemirror-state\"\n\nimport browser from \"./browser\"\nimport {selectionCollapsed, isEquivalentPosition, domIndex} from \"./dom\"\n\nexport function selectionFromDOM(view, origin) {\n let domSel = view.root.getSelection(), doc = view.state.doc\n let nearestDesc = view.docView.nearestDesc(domSel.focusNode), inWidget = nearestDesc && nearestDesc.size == 0\n let head = view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset)\n let $head = doc.resolve(head), $anchor, selection\n if (selectionCollapsed(domSel)) {\n $anchor = $head\n while (nearestDesc && !nearestDesc.node) nearestDesc = nearestDesc.parent\n if (nearestDesc && nearestDesc.node.isAtom && NodeSelection.isSelectable(nearestDesc.node) && nearestDesc.parent) {\n let pos = nearestDesc.posBefore\n selection = new NodeSelection(head == pos ? $head : doc.resolve(pos))\n }\n } else {\n $anchor = doc.resolve(view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset))\n }\n\n if (!selection) {\n let bias = origin == \"pointer\" || (view.state.selection.head < $head.pos && !inWidget) ? 1 : -1\n selection = selectionBetween(view, $anchor, $head, bias)\n }\n return selection\n}\n\nexport function selectionToDOM(view, force) {\n let sel = view.state.selection\n syncNodeSelection(view, sel)\n\n if (view.editable ? !view.hasFocus() : !(hasSelection(view) && document.activeElement.contains(view.dom))) return\n\n view.domObserver.disconnectSelection()\n\n if (view.cursorWrapper) {\n selectCursorWrapper(view)\n } else {\n let {anchor, head} = sel, resetEditableFrom, resetEditableTo\n if (brokenSelectBetweenUneditable && !(sel instanceof TextSelection)) {\n if (!sel.$from.parent.inlineContent)\n resetEditableFrom = temporarilyEditableNear(view, sel.from)\n if (!sel.empty && !sel.$from.parent.inlineContent)\n resetEditableTo = temporarilyEditableNear(view, sel.to)\n }\n view.docView.setSelection(anchor, head, view.root, force)\n if (brokenSelectBetweenUneditable) {\n if (resetEditableFrom) resetEditableFrom.contentEditable = \"false\"\n if (resetEditableTo) resetEditableTo.contentEditable = \"false\"\n }\n if (sel.visible) {\n view.dom.classList.remove(\"ProseMirror-hideselection\")\n } else if (anchor != head) {\n view.dom.classList.add(\"ProseMirror-hideselection\")\n if (\"onselectionchange\" in document) removeClassOnSelectionChange(view)\n }\n }\n\n view.domObserver.setCurSelection()\n view.domObserver.connectSelection()\n}\n\n// Kludge to work around Webkit not allowing a selection to start/end\n// between non-editable block nodes. We briefly make something\n// editable, set the selection, then set it uneditable again.\n\nconst brokenSelectBetweenUneditable = browser.safari || browser.chrome && browser.chrome_version < 63\n\nfunction temporarilyEditableNear(view, pos) {\n let {node, offset} = view.docView.domFromPos(pos)\n let after = offset < node.childNodes.length ? node.childNodes[offset] : null\n let before = offset ? node.childNodes[offset - 1] : null\n if ((!after || after.contentEditable == \"false\") && (!before || before.contentEditable == \"false\")) {\n if (after) {\n after.contentEditable = \"true\"\n return after\n } else if (before) {\n before.contentEditable = \"true\"\n return before\n }\n }\n}\n\nfunction removeClassOnSelectionChange(view) {\n let doc = view.dom.ownerDocument\n doc.removeEventListener(\"selectionchange\", view.hideSelectionGuard)\n let domSel = view.root.getSelection()\n let node = domSel.anchorNode, offset = domSel.anchorOffset\n doc.addEventListener(\"selectionchange\", view.hideSelectionGuard = () => {\n if (domSel.anchorNode != node || domSel.anchorOffset != offset) {\n doc.removeEventListener(\"selectionchange\", view.hideSelectionGuard)\n view.dom.classList.remove(\"ProseMirror-hideselection\")\n }\n })\n}\n\nfunction selectCursorWrapper(view) {\n let domSel = view.root.getSelection(), range = document.createRange()\n let node = view.cursorWrapper.dom, img = node.nodeName == \"IMG\"\n if (img) range.setEnd(node.parentNode, domIndex(node) + 1)\n else range.setEnd(node, 0)\n range.collapse(false)\n domSel.removeAllRanges()\n domSel.addRange(range)\n // Kludge to kill 'control selection' in IE11 when selecting an\n // invisible cursor wrapper, since that would result in those weird\n // resize handles and a selection that considers the absolutely\n // positioned wrapper, rather than the root editable node, the\n // focused element.\n if (!img && !view.state.selection.visible && browser.ie && browser.ie_version <= 11) {\n node.disabled = true\n node.disabled = false\n }\n}\n\nexport function syncNodeSelection(view, sel) {\n if (sel instanceof NodeSelection) {\n let desc = view.docView.descAt(sel.from)\n if (desc != view.lastSelectedViewDesc) {\n clearNodeSelection(view)\n if (desc) desc.selectNode()\n view.lastSelectedViewDesc = desc\n }\n } else {\n clearNodeSelection(view)\n }\n}\n\n// Clear all DOM statefulness of the last node selection.\nfunction clearNodeSelection(view) {\n if (view.lastSelectedViewDesc) {\n if (view.lastSelectedViewDesc.parent)\n view.lastSelectedViewDesc.deselectNode()\n view.lastSelectedViewDesc = null\n }\n}\n\nexport function selectionBetween(view, $anchor, $head, bias) {\n return view.someProp(\"createSelectionBetween\", f => f(view, $anchor, $head))\n || TextSelection.between($anchor, $head, bias)\n}\n\nexport function hasFocusAndSelection(view) {\n if (view.editable && view.root.activeElement != view.dom) return false\n return hasSelection(view)\n}\n\nexport function hasSelection(view) {\n let sel = view.root.getSelection()\n if (!sel.anchorNode) return false\n try {\n // Firefox will raise 'permission denied' errors when accessing\n // properties of `sel.anchorNode` when it's in a generated CSS\n // element.\n return view.dom.contains(sel.anchorNode.nodeType == 3 ? sel.anchorNode.parentNode : sel.anchorNode) &&\n (view.editable || view.dom.contains(sel.focusNode.nodeType == 3 ? sel.focusNode.parentNode : sel.focusNode))\n } catch(_) {\n return false\n }\n}\n\nexport function anchorInRightPlace(view) {\n let anchorDOM = view.docView.domFromPos(view.state.selection.anchor)\n let domSel = view.root.getSelection()\n return isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset)\n}\n","import {Fragment, DOMParser} from \"prosemirror-model\"\nimport {Selection, TextSelection} from \"prosemirror-state\"\n\nimport {selectionBetween, selectionFromDOM, selectionToDOM} from \"./selection\"\nimport {selectionCollapsed, keyEvent} from \"./dom\"\nimport browser from \"./browser\"\n\n// Note that all referencing and parsing is done with the\n// start-of-operation selection and document, since that's the one\n// that the DOM represents. If any changes came in in the meantime,\n// the modification is mapped over those before it is applied, in\n// readDOMChange.\n\nfunction parseBetween(view, from_, to_) {\n let {node: parent, fromOffset, toOffset, from, to} = view.docView.parseRange(from_, to_)\n\n let domSel = view.root.getSelection(), find = null, anchor = domSel.anchorNode\n if (anchor && view.dom.contains(anchor.nodeType == 1 ? anchor : anchor.parentNode)) {\n find = [{node: anchor, offset: domSel.anchorOffset}]\n if (!selectionCollapsed(domSel))\n find.push({node: domSel.focusNode, offset: domSel.focusOffset})\n }\n // Work around issue in Chrome where backspacing sometimes replaces\n // the deleted content with a random BR node (issues #799, #831)\n if (browser.chrome && view.lastKeyCode === 8) {\n for (let off = toOffset; off > fromOffset; off--) {\n let node = parent.childNodes[off - 1], desc = node.pmViewDesc\n if (node.nodeType == \"BR\" && !desc) { toOffset = off; break }\n if (!desc || desc.size) break\n }\n }\n let startDoc = view.state.doc\n let parser = view.someProp(\"domParser\") || DOMParser.fromSchema(view.state.schema)\n let $from = startDoc.resolve(from)\n\n let sel = null, doc = parser.parse(parent, {\n topNode: $from.parent,\n topMatch: $from.parent.contentMatchAt($from.index()),\n topOpen: true,\n from: fromOffset,\n to: toOffset,\n preserveWhitespace: $from.parent.type.spec.code ? \"full\" : true,\n editableContent: true,\n findPositions: find,\n ruleFromNode,\n context: $from\n })\n if (find && find[0].pos != null) {\n let anchor = find[0].pos, head = find[1] && find[1].pos\n if (head == null) head = anchor\n sel = {anchor: anchor + from, head: head + from}\n }\n return {doc, sel, from, to}\n}\n\nfunction ruleFromNode(dom) {\n let desc = dom.pmViewDesc\n if (desc) {\n return desc.parseRule()\n } else if (dom.nodeName == \"BR\" && dom.parentNode) {\n // Safari replaces the list item or table cell with a BR\n // directly in the list node (?!) if you delete the last\n // character in a list item or table cell (#708, #862)\n if (browser.safari && /^(ul|ol)$/i.test(dom.parentNode.nodeName)) {\n let skip = document.createElement(\"div\")\n skip.appendChild(document.createElement(\"li\"))\n return {skip}\n } else if (dom.parentNode.lastChild == dom || browser.safari && /^(tr|table)$/i.test(dom.parentNode.nodeName)) {\n return {ignore: true}\n }\n } else if (dom.nodeName == \"IMG\" && dom.getAttribute(\"mark-placeholder\")) {\n return {ignore: true}\n }\n}\n\nexport function readDOMChange(view, from, to, typeOver) {\n if (from < 0) {\n let origin = view.lastSelectionTime > Date.now() - 50 ? view.lastSelectionOrigin : null\n let newSel = selectionFromDOM(view, origin)\n if (!view.state.selection.eq(newSel)) {\n let tr = view.state.tr.setSelection(newSel)\n if (origin == \"pointer\") tr.setMeta(\"pointer\", true)\n else if (origin == \"key\") tr.scrollIntoView()\n view.dispatch(tr)\n }\n return\n }\n\n let $before = view.state.doc.resolve(from)\n let shared = $before.sharedDepth(to)\n from = $before.before(shared + 1)\n to = view.state.doc.resolve(to).after(shared + 1)\n\n let sel = view.state.selection\n let parse = parseBetween(view, from, to)\n\n let doc = view.state.doc, compare = doc.slice(parse.from, parse.to)\n let preferredPos, preferredSide\n // Prefer anchoring to end when Backspace is pressed\n if (view.lastKeyCode === 8 && Date.now() - 100 < view.lastKeyCodeTime) {\n preferredPos = view.state.selection.to\n preferredSide = \"end\"\n } else {\n preferredPos = view.state.selection.from\n preferredSide = \"start\"\n }\n view.lastKeyCode = null\n\n let change = findDiff(compare.content, parse.doc.content, parse.from, preferredPos, preferredSide)\n if (!change) {\n if (typeOver && sel instanceof TextSelection && !sel.empty && sel.$head.sameParent(sel.$anchor) &&\n !view.composing && !(parse.sel && parse.sel.anchor != parse.sel.head)) {\n change = {start: sel.from, endA: sel.to, endB: sel.to}\n } else {\n if (parse.sel) {\n let sel = resolveSelection(view, view.state.doc, parse.sel)\n if (sel && !sel.eq(view.state.selection)) view.dispatch(view.state.tr.setSelection(sel))\n }\n return\n }\n }\n view.domChangeCount++\n // Handle the case where overwriting a selection by typing matches\n // the start or end of the selected content, creating a change\n // that's smaller than what was actually overwritten.\n if (view.state.selection.from < view.state.selection.to &&\n change.start == change.endB &&\n view.state.selection instanceof TextSelection) {\n if (change.start > view.state.selection.from && change.start <= view.state.selection.from + 2) {\n change.start = view.state.selection.from\n } else if (change.endA < view.state.selection.to && change.endA >= view.state.selection.to - 2) {\n change.endB += (view.state.selection.to - change.endA)\n change.endA = view.state.selection.to\n }\n }\n\n // IE11 will insert a non-breaking space _ahead_ of the space after\n // the cursor space when adding a space before another space. When\n // that happened, adjust the change to cover the space instead.\n if (browser.ie && browser.ie_version <= 11 && change.endB == change.start + 1 &&\n change.endA == change.start && change.start > parse.from &&\n parse.doc.textBetween(change.start - parse.from - 1, change.start - parse.from + 1) == \" \\u00a0\") {\n change.start--\n change.endA--\n change.endB--\n }\n\n let $from = parse.doc.resolveNoCache(change.start - parse.from)\n let $to = parse.doc.resolveNoCache(change.endB - parse.from)\n let nextSel\n // If this looks like the effect of pressing Enter, just dispatch an\n // Enter key instead.\n if (!$from.sameParent($to) && $from.pos < parse.doc.content.size &&\n (nextSel = Selection.findFrom(parse.doc.resolve($from.pos + 1), 1, true)) &&\n nextSel.head == $to.pos &&\n view.someProp(\"handleKeyDown\", f => f(view, keyEvent(13, \"Enter\"))))\n return\n // Same for backspace\n if (view.state.selection.anchor > change.start &&\n looksLikeJoin(doc, change.start, change.endA, $from, $to) &&\n view.someProp(\"handleKeyDown\", f => f(view, keyEvent(8, \"Backspace\")))) {\n if (browser.android && browser.chrome) view.domObserver.suppressSelectionUpdates() // #820\n return\n }\n\n let chFrom = change.start, chTo = change.endA\n\n let tr, storedMarks, markChange, $from1\n if ($from.sameParent($to) && $from.parent.inlineContent) {\n if ($from.pos == $to.pos) { // Deletion\n // IE11 sometimes weirdly moves the DOM selection around after\n // backspacing out the first element in a textblock\n if (browser.ie && browser.ie_version <= 11 && $from.parentOffset == 0) {\n view.domObserver.suppressSelectionUpdates()\n setTimeout(() => selectionToDOM(view), 20)\n }\n tr = view.state.tr.delete(chFrom, chTo)\n storedMarks = doc.resolve(change.start).marksAcross(doc.resolve(change.endA))\n } else if ( // Adding or removing a mark\n change.endA == change.endB && ($from1 = doc.resolve(change.start)) &&\n (markChange = isMarkChange($from.parent.content.cut($from.parentOffset, $to.parentOffset),\n $from1.parent.content.cut($from1.parentOffset, change.endA - $from1.start())))\n ) {\n tr = view.state.tr\n if (markChange.type == \"add\") tr.addMark(chFrom, chTo, markChange.mark)\n else tr.removeMark(chFrom, chTo, markChange.mark)\n } else if ($from.parent.child($from.index()).isText && $from.index() == $to.index() - ($to.textOffset ? 0 : 1)) {\n // Both positions in the same text node -- simply insert text\n let text = $from.parent.textBetween($from.parentOffset, $to.parentOffset)\n if (view.someProp(\"handleTextInput\", f => f(view, chFrom, chTo, text))) return\n tr = view.state.tr.insertText(text, chFrom, chTo)\n }\n }\n\n if (!tr)\n tr = view.state.tr.replace(chFrom, chTo, parse.doc.slice(change.start - parse.from, change.endB - parse.from))\n if (parse.sel) {\n let sel = resolveSelection(view, tr.doc, parse.sel)\n // Chrome Android will sometimes, during composition, report the\n // selection in the wrong place. If it looks like that is\n // happening, don't update the selection.\n // Edge just doesn't move the cursor forward when you start typing\n // in an empty block or between br nodes.\n if (sel && !(browser.chrome && browser.android && view.composing && sel.empty && sel.head == chFrom ||\n browser.ie && sel.empty && sel.head == chFrom))\n tr.setSelection(sel)\n }\n if (storedMarks) tr.ensureMarks(storedMarks)\n view.dispatch(tr.scrollIntoView())\n}\n\nfunction resolveSelection(view, doc, parsedSel) {\n if (Math.max(parsedSel.anchor, parsedSel.head) > doc.content.size) return null\n return selectionBetween(view, doc.resolve(parsedSel.anchor), doc.resolve(parsedSel.head))\n}\n\n// : (Fragment, Fragment) → ?{mark: Mark, type: string}\n// Given two same-length, non-empty fragments of inline content,\n// determine whether the first could be created from the second by\n// removing or adding a single mark type.\nfunction isMarkChange(cur, prev) {\n let curMarks = cur.firstChild.marks, prevMarks = prev.firstChild.marks\n let added = curMarks, removed = prevMarks, type, mark, update\n for (let i = 0; i < prevMarks.length; i++) added = prevMarks[i].removeFromSet(added)\n for (let i = 0; i < curMarks.length; i++) removed = curMarks[i].removeFromSet(removed)\n if (added.length == 1 && removed.length == 0) {\n mark = added[0]\n type = \"add\"\n update = node => node.mark(mark.addToSet(node.marks))\n } else if (added.length == 0 && removed.length == 1) {\n mark = removed[0]\n type = \"remove\"\n update = node => node.mark(mark.removeFromSet(node.marks))\n } else {\n return null\n }\n let updated = []\n for (let i = 0; i < prev.childCount; i++) updated.push(update(prev.child(i)))\n if (Fragment.from(updated).eq(cur)) return {mark, type}\n}\n\nfunction looksLikeJoin(old, start, end, $newStart, $newEnd) {\n if (!$newStart.parent.isTextblock ||\n // The content must have shrunk\n end - start <= $newEnd.pos - $newStart.pos ||\n // newEnd must point directly at or after the end of the block that newStart points into\n skipClosingAndOpening($newStart, true, false) < $newEnd.pos)\n return false\n\n let $start = old.resolve(start)\n // Start must be at the end of a block\n if ($start.parentOffset < $start.parent.content.size || !$start.parent.isTextblock)\n return false\n let $next = old.resolve(skipClosingAndOpening($start, true, true))\n // The next textblock must start before end and end near it\n if (!$next.parent.isTextblock || $next.pos > end ||\n skipClosingAndOpening($next, true, false) < end)\n return false\n\n // The fragments after the join point must match\n return $newStart.parent.content.cut($newStart.parentOffset).eq($next.parent.content)\n}\n\nfunction skipClosingAndOpening($pos, fromEnd, mayOpen) {\n let depth = $pos.depth, end = fromEnd ? $pos.end() : $pos.pos\n while (depth > 0 && (fromEnd || $pos.indexAfter(depth) == $pos.node(depth).childCount)) {\n depth--\n end++\n fromEnd = false\n }\n if (mayOpen) {\n let next = $pos.node(depth).maybeChild($pos.indexAfter(depth))\n while (next && !next.isLeaf) {\n next = next.firstChild\n end++\n }\n }\n return end\n}\n\nfunction findDiff(a, b, pos, preferredPos, preferredSide) {\n let start = a.findDiffStart(b, pos)\n if (start == null) return null\n let {a: endA, b: endB} = a.findDiffEnd(b, pos + a.size, pos + b.size)\n if (preferredSide == \"end\") {\n let adjust = Math.max(0, start - Math.min(endA, endB))\n preferredPos -= endA + adjust - start\n }\n if (endA < start && a.size < b.size) {\n let move = preferredPos <= start && preferredPos >= endA ? start - preferredPos : 0\n start -= move\n endB = start + (endB - endA)\n endA = start\n } else if (endB < start) {\n let move = preferredPos <= start && preferredPos >= endB ? start - preferredPos : 0\n start -= move\n endA = start + (endA - endB)\n endB = start\n }\n return {start, endA, endB}\n}\n","import {Slice, Fragment, DOMParser, DOMSerializer} from \"prosemirror-model\"\n\nexport function serializeForClipboard(view, slice) {\n let context = [], {content, openStart, openEnd} = slice\n while (openStart > 1 && openEnd > 1 && content.childCount == 1 && content.firstChild.childCount == 1) {\n openStart--\n openEnd--\n let node = content.firstChild\n context.push(node.type.name, node.type.hasRequiredAttrs() ? node.attrs : null)\n content = node.content\n }\n\n let serializer = view.someProp(\"clipboardSerializer\") || DOMSerializer.fromSchema(view.state.schema)\n let doc = detachedDoc(), wrap = doc.createElement(\"div\")\n wrap.appendChild(serializer.serializeFragment(content, {document: doc}))\n\n let firstChild = wrap.firstChild, needsWrap\n while (firstChild && firstChild.nodeType == 1 && (needsWrap = wrapMap[firstChild.nodeName.toLowerCase()])) {\n for (let i = needsWrap.length - 1; i >= 0; i--) {\n let wrapper = doc.createElement(needsWrap[i])\n while (wrap.firstChild) wrapper.appendChild(wrap.firstChild)\n wrap.appendChild(wrapper)\n }\n firstChild = wrap.firstChild\n }\n\n if (firstChild && firstChild.nodeType == 1)\n firstChild.setAttribute(\"data-pm-slice\", `${openStart} ${openEnd} ${JSON.stringify(context)}`)\n\n let text = view.someProp(\"clipboardTextSerializer\", f => f(slice)) ||\n slice.content.textBetween(0, slice.content.size, \"\\n\\n\")\n\n return {dom: wrap, text}\n}\n\n// : (EditorView, string, string, ?bool, ResolvedPos) → ?Slice\n// Read a slice of content from the clipboard (or drop data).\nexport function parseFromClipboard(view, text, html, plainText, $context) {\n let dom, inCode = $context.parent.type.spec.code, slice\n if (!html && !text) return null\n let asText = text && (plainText || inCode || !html)\n if (asText) {\n view.someProp(\"transformPastedText\", f => { text = f(text) })\n if (inCode) return new Slice(Fragment.from(view.state.schema.text(text)), 0, 0)\n let parsed = view.someProp(\"clipboardTextParser\", f => f(text, $context))\n if (parsed) {\n slice = parsed\n } else {\n dom = document.createElement(\"div\")\n text.trim().split(/(?:\\r\\n?|\\n)+/).forEach(block => {\n dom.appendChild(document.createElement(\"p\")).textContent = block\n })\n }\n } else {\n view.someProp(\"transformPastedHTML\", f => { html = f(html) })\n dom = readHTML(html)\n }\n\n let contextNode = dom && dom.querySelector(\"[data-pm-slice]\")\n let sliceData = contextNode && /^(\\d+) (\\d+) (.*)/.exec(contextNode.getAttribute(\"data-pm-slice\"))\n if (!slice) {\n let parser = view.someProp(\"clipboardParser\") || view.someProp(\"domParser\") || DOMParser.fromSchema(view.state.schema)\n slice = parser.parseSlice(dom, {preserveWhitespace: !!(asText || sliceData), context: $context})\n }\n if (sliceData)\n slice = addContext(closeSlice(slice, +sliceData[1], +sliceData[2]), sliceData[3])\n else // HTML wasn't created by ProseMirror. Make sure top-level siblings are coherent\n slice = Slice.maxOpen(normalizeSiblings(slice.content, $context), false)\n\n view.someProp(\"transformPasted\", f => { slice = f(slice) })\n return slice\n}\n\n// Takes a slice parsed with parseSlice, which means there hasn't been\n// any content-expression checking done on the top nodes, tries to\n// find a parent node in the current context that might fit the nodes,\n// and if successful, rebuilds the slice so that it fits into that parent.\n//\n// This addresses the problem that Transform.replace expects a\n// coherent slice, and will fail to place a set of siblings that don't\n// fit anywhere in the schema.\nfunction normalizeSiblings(fragment, $context) {\n if (fragment.childCount < 2) return fragment\n for (let d = $context.depth; d >= 0; d--) {\n let parent = $context.node(d)\n let match = parent.contentMatchAt($context.index(d))\n let lastWrap, result = []\n fragment.forEach(node => {\n if (!result) return\n let wrap = match.findWrapping(node.type), inLast\n if (!wrap) return result = null\n if (inLast = result.length && lastWrap.length && addToSibling(wrap, lastWrap, node, result[result.length - 1], 0)) {\n result[result.length - 1] = inLast\n } else {\n if (result.length) result[result.length - 1] = closeRight(result[result.length - 1], lastWrap.length)\n let wrapped = withWrappers(node, wrap)\n result.push(wrapped)\n match = match.matchType(wrapped.type, wrapped.attrs)\n lastWrap = wrap\n }\n })\n if (result) return Fragment.from(result)\n }\n return fragment\n}\n\nfunction withWrappers(node, wrap, from = 0) {\n for (let i = wrap.length - 1; i >= from; i--)\n node = wrap[i].create(null, Fragment.from(node))\n return node\n}\n\n// Used to group adjacent nodes wrapped in similar parents by\n// normalizeSiblings into the same parent node\nfunction addToSibling(wrap, lastWrap, node, sibling, depth) {\n if (depth < wrap.length && depth < lastWrap.length && wrap[depth] == lastWrap[depth]) {\n let inner = addToSibling(wrap, lastWrap, node, sibling.lastChild, depth + 1)\n if (inner) return sibling.copy(sibling.content.replaceChild(sibling.childCount - 1, inner))\n let match = sibling.contentMatchAt(sibling.childCount)\n if (match.matchType(depth == wrap.length - 1 ? node.type : wrap[depth + 1]))\n return sibling.copy(sibling.content.append(Fragment.from(withWrappers(node, wrap, depth + 1))))\n }\n}\n\nfunction closeRight(node, depth) {\n if (depth == 0) return node\n let fragment = node.content.replaceChild(node.childCount - 1, closeRight(node.lastChild, depth - 1))\n let fill = node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true)\n return node.copy(fragment.append(fill))\n}\n\nfunction closeRange(fragment, side, from, to, depth, openEnd) {\n let node = side < 0 ? fragment.firstChild : fragment.lastChild, inner = node.content\n if (depth < to - 1) inner = closeRange(inner, side, from, to, depth + 1, openEnd)\n if (depth >= from)\n inner = side < 0 ? node.contentMatchAt(0).fillBefore(inner, fragment.childCount > 1 || openEnd <= depth).append(inner)\n : inner.append(node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true))\n return fragment.replaceChild(side < 0 ? 0 : fragment.childCount - 1, node.copy(inner))\n}\n\nfunction closeSlice(slice, openStart, openEnd) {\n if (openStart < slice.openStart)\n slice = new Slice(closeRange(slice.content, -1, openStart, slice.openStart, 0, slice.openEnd), openStart, slice.openEnd)\n if (openEnd < slice.openEnd)\n slice = new Slice(closeRange(slice.content, 1, openEnd, slice.openEnd, 0, 0), slice.openStart, openEnd)\n return slice\n}\n\n// Trick from jQuery -- some elements must be wrapped in other\n// elements for innerHTML to work. I.e. if you do `div.innerHTML =\n// \"..\"` the table cells are ignored.\nconst wrapMap = {thead: [\"table\"], colgroup: [\"table\"], col: [\"table\", \"colgroup\"],\n tr: [\"table\", \"tbody\"], td: [\"table\", \"tbody\", \"tr\"], th: [\"table\", \"tbody\", \"tr\"]}\n\nlet _detachedDoc = null\nfunction detachedDoc() {\n return _detachedDoc || (_detachedDoc = document.implementation.createHTMLDocument(\"title\"))\n}\n\nfunction readHTML(html) {\n let metas = /(\\s*]*>)*/.exec(html)\n if (metas) html = html.slice(metas[0].length)\n let elt = detachedDoc().createElement(\"div\")\n let firstTag = /(?:]*>)*<([a-z][^>\\s]+)/i.exec(html), wrap, depth = 0\n if (wrap = firstTag && wrapMap[firstTag[1].toLowerCase()]) {\n html = wrap.map(n => \"<\" + n + \">\").join(\"\") + html + wrap.map(n => \"\").reverse().join(\"\")\n depth = wrap.length\n }\n elt.innerHTML = html\n for (let i = 0; i < depth; i++) elt = elt.firstChild\n return elt\n}\n\nfunction addContext(slice, context) {\n if (!slice.size) return slice\n let schema = slice.content.firstChild.type.schema, array\n try { array = JSON.parse(context) }\n catch(e) { return slice }\n let {content, openStart, openEnd} = slice\n for (let i = array.length - 2; i >= 0; i -= 2) {\n let type = schema.nodes[array[i]]\n if (!type || type.hasRequiredAttrs()) break\n content = Fragment.from(type.create(array[i + 1], content))\n openStart++; openEnd++\n }\n return new Slice(content, openStart, openEnd)\n}\n","import browser from \"./browser\"\nimport {domIndex, isEquivalentPosition} from \"./dom\"\nimport {hasFocusAndSelection, hasSelection, selectionToDOM} from \"./selection\"\n\nconst observeOptions = {\n childList: true,\n characterData: true,\n characterDataOldValue: true,\n attributes: true,\n attributeOldValue: true,\n subtree: true\n}\n// IE11 has very broken mutation observers, so we also listen to DOMCharacterDataModified\nconst useCharData = browser.ie && browser.ie_version <= 11\n\nclass SelectionState {\n constructor() {\n this.anchorNode = this.anchorOffset = this.focusNode = this.focusOffset = null\n }\n\n set(sel) {\n this.anchorNode = sel.anchorNode; this.anchorOffset = sel.anchorOffset\n this.focusNode = sel.focusNode; this.focusOffset = sel.focusOffset\n }\n\n eq(sel) {\n return sel.anchorNode == this.anchorNode && sel.anchorOffset == this.anchorOffset &&\n sel.focusNode == this.focusNode && sel.focusOffset == this.focusOffset\n }\n}\n\nexport class DOMObserver {\n constructor(view, handleDOMChange) {\n this.view = view\n this.handleDOMChange = handleDOMChange\n this.queue = []\n this.flushingSoon = false\n this.observer = window.MutationObserver &&\n new window.MutationObserver(mutations => {\n for (let i = 0; i < mutations.length; i++) this.queue.push(mutations[i])\n // IE11 will sometimes (on backspacing out a single character\n // text node after a BR node) call the observer callback\n // before actually updating the DOM, which will cause\n // ProseMirror to miss the change (see #930)\n if (browser.ie && browser.ie_version <= 11 && mutations.some(\n m => m.type == \"childList\" && m.removedNodes.length ||\n m.type == \"characterData\" && m.oldValue.length > m.target.nodeValue.length))\n this.flushSoon()\n else\n this.flush()\n })\n this.currentSelection = new SelectionState\n if (useCharData) {\n this.onCharData = e => {\n this.queue.push({target: e.target, type: \"characterData\", oldValue: e.prevValue})\n this.flushSoon()\n }\n }\n this.onSelectionChange = this.onSelectionChange.bind(this)\n this.suppressingSelectionUpdates = false\n }\n\n flushSoon() {\n if (!this.flushingSoon) {\n this.flushingSoon = true\n window.setTimeout(() => { this.flushingSoon = false; this.flush() }, 20)\n }\n }\n\n start() {\n if (this.observer)\n this.observer.observe(this.view.dom, observeOptions)\n if (useCharData)\n this.view.dom.addEventListener(\"DOMCharacterDataModified\", this.onCharData)\n this.connectSelection()\n }\n\n stop() {\n if (this.observer) {\n let take = this.observer.takeRecords()\n if (take.length) {\n for (let i = 0; i < take.length; i++) this.queue.push(take[i])\n window.setTimeout(() => this.flush(), 20)\n }\n this.observer.disconnect()\n }\n if (useCharData) this.view.dom.removeEventListener(\"DOMCharacterDataModified\", this.onCharData)\n this.disconnectSelection()\n }\n\n connectSelection() {\n this.view.dom.ownerDocument.addEventListener(\"selectionchange\", this.onSelectionChange)\n }\n\n disconnectSelection() {\n this.view.dom.ownerDocument.removeEventListener(\"selectionchange\", this.onSelectionChange)\n }\n\n suppressSelectionUpdates() {\n this.suppressingSelectionUpdates = true\n setTimeout(() => this.suppressingSelectionUpdates = false, 50)\n }\n\n onSelectionChange() {\n if (!hasFocusAndSelection(this.view)) return\n if (this.suppressingSelectionUpdates) return selectionToDOM(this.view)\n // Deletions on IE11 fire their events in the wrong order, giving\n // us a selection change event before the DOM changes are\n // reported.\n if (browser.ie && browser.ie_version <= 11 && !this.view.state.selection.empty) {\n let sel = this.view.root.getSelection()\n // Selection.isCollapsed isn't reliable on IE\n if (sel.focusNode && isEquivalentPosition(sel.focusNode, sel.focusOffset, sel.anchorNode, sel.anchorOffset))\n return this.flushSoon()\n }\n this.flush()\n }\n\n setCurSelection() {\n this.currentSelection.set(this.view.root.getSelection())\n }\n\n ignoreSelectionChange(sel) {\n if (sel.rangeCount == 0) return true\n let container = sel.getRangeAt(0).commonAncestorContainer\n let desc = this.view.docView.nearestDesc(container)\n return desc && desc.ignoreMutation({type: \"selection\", target: container.nodeType == 3 ? container.parentNode : container})\n }\n\n flush() {\n if (!this.view.docView || this.flushingSoon) return\n let mutations = this.observer ? this.observer.takeRecords() : []\n if (this.queue.length) {\n mutations = this.queue.concat(mutations)\n this.queue.length = 0\n }\n\n let sel = this.view.root.getSelection()\n let newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasSelection(this.view) && !this.ignoreSelectionChange(sel)\n\n let from = -1, to = -1, typeOver = false, added = []\n if (this.view.editable) {\n for (let i = 0; i < mutations.length; i++) {\n let result = this.registerMutation(mutations[i], added)\n if (result) {\n from = from < 0 ? result.from : Math.min(result.from, from)\n to = to < 0 ? result.to : Math.max(result.to, to)\n if (result.typeOver && !this.view.composing) typeOver = true\n }\n }\n }\n\n if (browser.gecko && added.length > 1) {\n let brs = added.filter(n => n.nodeName == \"BR\")\n if (brs.length == 2) {\n let [a, b] = brs\n if (a.parentNode && a.parentNode.parentNode == b.parentNode) b.remove()\n else a.remove()\n }\n }\n\n if (from > -1 || newSel) {\n if (from > -1) {\n this.view.docView.markDirty(from, to)\n checkCSS(this.view)\n }\n this.handleDOMChange(from, to, typeOver)\n if (this.view.docView.dirty) this.view.updateState(this.view.state)\n else if (!this.currentSelection.eq(sel)) selectionToDOM(this.view)\n }\n }\n\n registerMutation(mut, added) {\n // Ignore mutations inside nodes that were already noted as inserted\n if (added.indexOf(mut.target) > -1) return null\n let desc = this.view.docView.nearestDesc(mut.target)\n if (mut.type == \"attributes\" &&\n (desc == this.view.docView || mut.attributeName == \"contenteditable\" ||\n // Firefox sometimes fires spurious events for null/empty styles\n (mut.attributeName == \"style\" && !mut.oldValue && !mut.target.getAttribute(\"style\"))))\n return null\n if (!desc || desc.ignoreMutation(mut)) return null\n\n if (mut.type == \"childList\") {\n let prev = mut.previousSibling, next = mut.nextSibling\n if (browser.ie && browser.ie_version <= 11 && mut.addedNodes.length) {\n // IE11 gives us incorrect next/prev siblings for some\n // insertions, so if there are added nodes, recompute those\n for (let i = 0; i < mut.addedNodes.length; i++) {\n let {previousSibling, nextSibling} = mut.addedNodes[i]\n if (!previousSibling || Array.prototype.indexOf.call(mut.addedNodes, previousSibling) < 0) prev = previousSibling\n if (!nextSibling || Array.prototype.indexOf.call(mut.addedNodes, nextSibling) < 0) next = nextSibling\n }\n }\n let fromOffset = prev && prev.parentNode == mut.target\n ? domIndex(prev) + 1 : 0\n let from = desc.localPosFromDOM(mut.target, fromOffset, -1)\n let toOffset = next && next.parentNode == mut.target\n ? domIndex(next) : mut.target.childNodes.length\n for (let i = 0; i < mut.addedNodes.length; i++) added.push(mut.addedNodes[i])\n let to = desc.localPosFromDOM(mut.target, toOffset, 1)\n return {from, to}\n } else if (mut.type == \"attributes\") {\n return {from: desc.posAtStart - desc.border, to: desc.posAtEnd + desc.border}\n } else { // \"characterData\"\n return {\n from: desc.posAtStart,\n to: desc.posAtEnd,\n // An event was generated for a text change that didn't change\n // any text. Mark the dom change to fall back to assuming the\n // selection was typed over with an identical value if it can't\n // find another change.\n typeOver: mut.target.nodeValue == mut.oldValue\n }\n }\n }\n}\n\nlet cssChecked = false\n\nfunction checkCSS(view) {\n if (cssChecked) return\n cssChecked = true\n if (getComputedStyle(view.dom).whiteSpace == \"normal\")\n console[\"warn\"](\"ProseMirror expects the CSS white-space property to be set, preferably to 'pre-wrap'. It is recommended to load style/prosemirror.css from the prosemirror-view package.\")\n}\n","import {Selection, NodeSelection, TextSelection} from \"prosemirror-state\"\nimport {dropPoint} from \"prosemirror-transform\"\nimport {Slice} from \"prosemirror-model\"\n\nimport browser from \"./browser\"\nimport {captureKeyDown} from \"./capturekeys\"\nimport {readDOMChange} from \"./domchange\"\nimport {parseFromClipboard, serializeForClipboard} from \"./clipboard\"\nimport {DOMObserver} from \"./domobserver\"\nimport {selectionBetween} from \"./selection\"\nimport {keyEvent} from \"./dom\"\n\n// A collection of DOM events that occur within the editor, and callback functions\n// to invoke when the event fires.\nconst handlers = {}, editHandlers = {}\n\nexport function initInput(view) {\n view.shiftKey = false\n view.mouseDown = null\n view.lastKeyCode = null\n view.lastKeyCodeTime = 0\n view.lastClick = {time: 0, x: 0, y: 0, type: \"\"}\n view.lastSelectionOrigin = null\n view.lastSelectionTime = 0\n\n view.composing = false\n view.composingTimeout = null\n view.compositionNodes = []\n view.compositionEndedAt = -2e8\n\n view.domObserver = new DOMObserver(view, (from, to, typeOver) => readDOMChange(view, from, to, typeOver))\n view.domObserver.start()\n // Used by hacks like the beforeinput handler to check whether anything happened in the DOM\n view.domChangeCount = 0\n\n view.eventHandlers = Object.create(null)\n for (let event in handlers) {\n let handler = handlers[event]\n view.dom.addEventListener(event, view.eventHandlers[event] = event => {\n if (eventBelongsToView(view, event) && !runCustomHandler(view, event) &&\n (view.editable || !(event.type in editHandlers)))\n handler(view, event)\n })\n }\n // On Safari, for reasons beyond my understanding, adding an input\n // event handler makes an issue where the composition vanishes when\n // you press enter go away.\n if (browser.safari) view.dom.addEventListener(\"input\", () => null)\n\n ensureListeners(view)\n}\n\nfunction setSelectionOrigin(view, origin) {\n view.lastSelectionOrigin = origin\n view.lastSelectionTime = Date.now()\n}\n\nexport function destroyInput(view) {\n view.domObserver.stop()\n for (let type in view.eventHandlers)\n view.dom.removeEventListener(type, view.eventHandlers[type])\n clearTimeout(view.composingTimeout)\n}\n\nexport function ensureListeners(view) {\n view.someProp(\"handleDOMEvents\", currentHandlers => {\n for (let type in currentHandlers) if (!view.eventHandlers[type])\n view.dom.addEventListener(type, view.eventHandlers[type] = event => runCustomHandler(view, event))\n })\n}\n\nfunction runCustomHandler(view, event) {\n return view.someProp(\"handleDOMEvents\", handlers => {\n let handler = handlers[event.type]\n return handler ? handler(view, event) || event.defaultPrevented : false\n })\n}\n\nfunction eventBelongsToView(view, event) {\n if (!event.bubbles) return true\n if (event.defaultPrevented) return false\n for (let node = event.target; node != view.dom; node = node.parentNode)\n if (!node || node.nodeType == 11 ||\n (node.pmViewDesc && node.pmViewDesc.stopEvent(event)))\n return false\n return true\n}\n\nexport function dispatchEvent(view, event) {\n if (!runCustomHandler(view, event) && handlers[event.type] &&\n (view.editable || !(event.type in editHandlers)))\n handlers[event.type](view, event)\n}\n\neditHandlers.keydown = (view, event) => {\n view.shiftKey = event.keyCode == 16 || event.shiftKey\n if (inOrNearComposition(view, event)) return\n view.lastKeyCode = event.keyCode\n view.lastKeyCodeTime = Date.now()\n if (view.someProp(\"handleKeyDown\", f => f(view, event)) || captureKeyDown(view, event))\n event.preventDefault()\n else\n setSelectionOrigin(view, \"key\")\n}\n\neditHandlers.keyup = (view, e) => {\n if (e.keyCode == 16) view.shiftKey = false\n}\n\neditHandlers.keypress = (view, event) => {\n if (inOrNearComposition(view, event) || !event.charCode ||\n event.ctrlKey && !event.altKey || browser.mac && event.metaKey) return\n\n if (view.someProp(\"handleKeyPress\", f => f(view, event))) {\n event.preventDefault()\n return\n }\n\n let sel = view.state.selection\n if (!(sel instanceof TextSelection) || !sel.$from.sameParent(sel.$to)) {\n let text = String.fromCharCode(event.charCode)\n if (!view.someProp(\"handleTextInput\", f => f(view, sel.$from.pos, sel.$to.pos, text)))\n view.dispatch(view.state.tr.insertText(text).scrollIntoView())\n event.preventDefault()\n }\n}\n\nfunction eventCoords(event) { return {left: event.clientX, top: event.clientY} }\n\nfunction isNear(event, click) {\n let dx = click.x - event.clientX, dy = click.y - event.clientY\n return dx * dx + dy * dy < 100\n}\n\nfunction runHandlerOnContext(view, propName, pos, inside, event) {\n if (inside == -1) return false\n let $pos = view.state.doc.resolve(inside)\n for (let i = $pos.depth + 1; i > 0; i--) {\n if (view.someProp(propName, f => i > $pos.depth ? f(view, pos, $pos.nodeAfter, $pos.before(i), event, true)\n : f(view, pos, $pos.node(i), $pos.before(i), event, false)))\n return true\n }\n return false\n}\n\nfunction updateSelection(view, selection, origin) {\n if (!view.focused) view.focus()\n let tr = view.state.tr.setSelection(selection)\n if (origin == \"pointer\") tr.setMeta(\"pointer\", true)\n view.dispatch(tr)\n}\n\nfunction selectClickedLeaf(view, inside) {\n if (inside == -1) return false\n let $pos = view.state.doc.resolve(inside), node = $pos.nodeAfter\n if (node && node.isAtom && NodeSelection.isSelectable(node)) {\n updateSelection(view, new NodeSelection($pos), \"pointer\")\n return true\n }\n return false\n}\n\nfunction selectClickedNode(view, inside) {\n if (inside == -1) return false\n let sel = view.state.selection, selectedNode, selectAt\n if (sel instanceof NodeSelection) selectedNode = sel.node\n\n let $pos = view.state.doc.resolve(inside)\n for (let i = $pos.depth + 1; i > 0; i--) {\n let node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i)\n if (NodeSelection.isSelectable(node)) {\n if (selectedNode && sel.$from.depth > 0 &&\n i >= sel.$from.depth && $pos.before(sel.$from.depth + 1) == sel.$from.pos)\n selectAt = $pos.before(sel.$from.depth)\n else\n selectAt = $pos.before(i)\n break\n }\n }\n\n if (selectAt != null) {\n updateSelection(view, NodeSelection.create(view.state.doc, selectAt), \"pointer\")\n return true\n } else {\n return false\n }\n}\n\nfunction handleSingleClick(view, pos, inside, event, selectNode) {\n return runHandlerOnContext(view, \"handleClickOn\", pos, inside, event) ||\n view.someProp(\"handleClick\", f => f(view, pos, event)) ||\n (selectNode ? selectClickedNode(view, inside) : selectClickedLeaf(view, inside))\n}\n\nfunction handleDoubleClick(view, pos, inside, event) {\n return runHandlerOnContext(view, \"handleDoubleClickOn\", pos, inside, event) ||\n view.someProp(\"handleDoubleClick\", f => f(view, pos, event))\n}\n\nfunction handleTripleClick(view, pos, inside, event) {\n return runHandlerOnContext(view, \"handleTripleClickOn\", pos, inside, event) ||\n view.someProp(\"handleTripleClick\", f => f(view, pos, event)) ||\n defaultTripleClick(view, inside)\n}\n\nfunction defaultTripleClick(view, inside) {\n let doc = view.state.doc\n if (inside == -1) {\n if (doc.inlineContent) {\n updateSelection(view, TextSelection.create(doc, 0, doc.content.size), \"pointer\")\n return true\n }\n return false\n }\n\n let $pos = doc.resolve(inside)\n for (let i = $pos.depth + 1; i > 0; i--) {\n let node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i)\n let nodePos = $pos.before(i)\n if (node.inlineContent)\n updateSelection(view, TextSelection.create(doc, nodePos + 1, nodePos + 1 + node.content.size), \"pointer\")\n else if (NodeSelection.isSelectable(node))\n updateSelection(view, NodeSelection.create(doc, nodePos), \"pointer\")\n else\n continue\n return true\n }\n}\n\nfunction forceDOMFlush(view) {\n return endComposition(view)\n}\n\nconst selectNodeModifier = browser.mac ? \"metaKey\" : \"ctrlKey\"\n\nhandlers.mousedown = (view, event) => {\n view.shiftKey = event.shiftKey\n let flushed = forceDOMFlush(view)\n let now = Date.now(), type = \"singleClick\"\n if (now - view.lastClick.time < 500 && isNear(event, view.lastClick) && !event[selectNodeModifier]) {\n if (view.lastClick.type == \"singleClick\") type = \"doubleClick\"\n else if (view.lastClick.type == \"doubleClick\") type = \"tripleClick\"\n }\n view.lastClick = {time: now, x: event.clientX, y: event.clientY, type}\n\n let pos = view.posAtCoords(eventCoords(event))\n if (!pos) return\n\n if (type == \"singleClick\")\n view.mouseDown = new MouseDown(view, pos, event, flushed)\n else if ((type == \"doubleClick\" ? handleDoubleClick : handleTripleClick)(view, pos.pos, pos.inside, event))\n event.preventDefault()\n else\n setSelectionOrigin(view, \"pointer\")\n}\n\nclass MouseDown {\n constructor(view, pos, event, flushed) {\n this.view = view\n this.startDoc = view.state.doc\n this.pos = pos\n this.event = event\n this.flushed = flushed\n this.selectNode = event[selectNodeModifier]\n this.allowDefault = event.shiftKey\n\n let targetNode, targetPos\n if (pos.inside > -1) {\n targetNode = view.state.doc.nodeAt(pos.inside)\n targetPos = pos.inside\n } else {\n let $pos = view.state.doc.resolve(pos.pos)\n targetNode = $pos.parent\n targetPos = $pos.depth ? $pos.before() : 0\n }\n\n this.mightDrag = null\n\n const target = flushed ? null : event.target\n const targetDesc = target ? view.docView.nearestDesc(target, true) : null\n this.target = targetDesc ? targetDesc.dom : null\n\n if (targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false ||\n view.state.selection instanceof NodeSelection && targetPos == view.state.selection.from)\n this.mightDrag = {node: targetNode,\n pos: targetPos,\n addAttr: this.target && !this.target.draggable,\n setUneditable: this.target && browser.gecko && !this.target.hasAttribute(\"contentEditable\")}\n\n if (this.target && this.mightDrag && (this.mightDrag.addAttr || this.mightDrag.setUneditable)) {\n this.view.domObserver.stop()\n if (this.mightDrag.addAttr) this.target.draggable = true\n if (this.mightDrag.setUneditable)\n setTimeout(() => this.target.setAttribute(\"contentEditable\", \"false\"), 20)\n this.view.domObserver.start()\n }\n\n view.root.addEventListener(\"mouseup\", this.up = this.up.bind(this))\n view.root.addEventListener(\"mousemove\", this.move = this.move.bind(this))\n setSelectionOrigin(view, \"pointer\")\n }\n\n done() {\n this.view.root.removeEventListener(\"mouseup\", this.up)\n this.view.root.removeEventListener(\"mousemove\", this.move)\n if (this.mightDrag && this.target) {\n this.view.domObserver.stop()\n if (this.mightDrag.addAttr) this.target.draggable = false\n if (this.mightDrag.setUneditable) this.target.removeAttribute(\"contentEditable\")\n this.view.domObserver.start()\n }\n this.view.mouseDown = null\n }\n\n up(event) {\n this.done()\n\n if (!this.view.dom.contains(event.target.nodeType == 3 ? event.target.parentNode : event.target))\n return\n\n let pos = this.pos\n if (this.view.state.doc != this.startDoc) pos = this.view.posAtCoords(eventCoords(event))\n\n if (this.allowDefault || !pos) {\n setSelectionOrigin(this.view, \"pointer\")\n } else if (handleSingleClick(this.view, pos.pos, pos.inside, event, this.selectNode)) {\n event.preventDefault()\n } else if (this.flushed ||\n // Chrome will sometimes treat a node selection as a\n // cursor, but still report that the node is selected\n // when asked through getSelection. You'll then get a\n // situation where clicking at the point where that\n // (hidden) cursor is doesn't change the selection, and\n // thus doesn't get a reaction from ProseMirror. This\n // works around that.\n (browser.chrome && !(this.view.state.selection instanceof TextSelection) &&\n (pos.pos == this.view.state.selection.from || pos.pos == this.view.state.selection.to))) {\n updateSelection(this.view, Selection.near(this.view.state.doc.resolve(pos.pos)), \"pointer\")\n event.preventDefault()\n } else {\n setSelectionOrigin(this.view, \"pointer\")\n }\n }\n\n move(event) {\n if (!this.allowDefault && (Math.abs(this.event.x - event.clientX) > 4 ||\n Math.abs(this.event.y - event.clientY) > 4))\n this.allowDefault = true\n setSelectionOrigin(this.view, \"pointer\")\n }\n}\n\nhandlers.touchdown = view => {\n forceDOMFlush(view)\n setSelectionOrigin(view, \"pointer\")\n}\n\nhandlers.contextmenu = view => forceDOMFlush(view)\n\nfunction inOrNearComposition(view, event) {\n if (view.composing) return true\n // See https://www.stum.de/2016/06/24/handling-ime-events-in-javascript/.\n // On Japanese input method editors (IMEs), the Enter key is used to confirm character\n // selection. On Safari, when Enter is pressed, compositionend and keydown events are\n // emitted. The keydown event triggers newline insertion, which we don't want.\n // This method returns true if the keydown event should be ignored.\n // We only ignore it once, as pressing Enter a second time *should* insert a newline.\n // Furthermore, the keydown event timestamp must be close to the compositionEndedAt timestamp.\n // This guards against the case where compositionend is triggered without the keyboard\n // (e.g. character confirmation may be done with the mouse), and keydown is triggered\n // afterwards- we wouldn't want to ignore the keydown event in this case.\n if (browser.safari && Math.abs(event.timeStamp - view.compositionEndedAt) < 500) {\n view.compositionEndedAt = -2e8\n return true\n }\n return false\n}\n\n// Drop active composition after 5 seconds of inactivity on Android\nconst timeoutComposition = browser.android ? 5000 : -1\n\neditHandlers.compositionstart = editHandlers.compositionupdate = view => {\n if (!view.composing) {\n view.domObserver.flush()\n let {state} = view, $pos = state.selection.$from\n if (state.selection.empty &&\n (state.storedMarks || (!$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some(m => m.type.spec.inclusive === false)))) {\n // Need to wrap the cursor in mark nodes different from the ones in the DOM context\n view.markCursor = view.state.storedMarks || $pos.marks()\n endComposition(view, true)\n view.markCursor = null\n } else {\n endComposition(view)\n // In firefox, if the cursor is after but outside a marked node,\n // the inserted text won't inherit the marks. So this moves it\n // inside if necessary.\n if (browser.gecko && state.selection.empty && $pos.parentOffset && !$pos.textOffset && $pos.nodeBefore.marks.length) {\n let sel = view.root.getSelection()\n for (let node = sel.focusNode, offset = sel.focusOffset; node && node.nodeType == 1 && offset != 0;) {\n let before = offset < 0 ? node.lastChild : node.childNodes[offset - 1]\n if (before.nodeType == 3) {\n sel.collapse(before, before.nodeValue.length)\n break\n } else {\n node = before\n offset = -1\n }\n }\n }\n }\n view.composing = true\n }\n scheduleComposeEnd(view, timeoutComposition)\n}\n\neditHandlers.compositionend = (view, event) => {\n if (view.composing) {\n view.composing = false\n view.compositionEndedAt = event.timeStamp\n scheduleComposeEnd(view, 20)\n }\n}\n\nfunction scheduleComposeEnd(view, delay) {\n clearTimeout(view.composingTimeout)\n if (delay > -1) view.composingTimeout = setTimeout(() => endComposition(view), delay)\n}\n\nexport function endComposition(view, forceUpdate) {\n view.composing = false\n while (view.compositionNodes.length > 0) view.compositionNodes.pop().markParentsDirty()\n if (forceUpdate || view.docView.dirty) {\n view.updateState(view.state)\n return true\n }\n return false\n}\n\nfunction captureCopy(view, dom) {\n // The extra wrapper is somehow necessary on IE/Edge to prevent the\n // content from being mangled when it is put onto the clipboard\n let doc = view.dom.ownerDocument\n let wrap = doc.body.appendChild(doc.createElement(\"div\"))\n wrap.appendChild(dom)\n wrap.style.cssText = \"position: fixed; left: -10000px; top: 10px\"\n let sel = getSelection(), range = doc.createRange()\n range.selectNodeContents(dom)\n // Done because IE will fire a selectionchange moving the selection\n // to its start when removeAllRanges is called and the editor still\n // has focus (which will mess up the editor's selection state).\n view.dom.blur()\n sel.removeAllRanges()\n sel.addRange(range)\n setTimeout(() => {\n doc.body.removeChild(wrap)\n view.focus()\n }, 50)\n}\n\n// This is very crude, but unfortunately both these browsers _pretend_\n// that they have a clipboard API—all the objects and methods are\n// there, they just don't work, and they are hard to test.\nconst brokenClipboardAPI = (browser.ie && browser.ie_version < 15) ||\n (browser.ios && browser.webkit_version < 604)\n\nhandlers.copy = editHandlers.cut = (view, e) => {\n let sel = view.state.selection, cut = e.type == \"cut\"\n if (sel.empty) return\n\n // IE and Edge's clipboard interface is completely broken\n let data = brokenClipboardAPI ? null : e.clipboardData\n let slice = sel.content(), {dom, text} = serializeForClipboard(view, slice)\n if (data) {\n e.preventDefault()\n data.clearData()\n data.setData(\"text/html\", dom.innerHTML)\n data.setData(\"text/plain\", text)\n } else {\n captureCopy(view, dom)\n }\n if (cut) view.dispatch(view.state.tr.deleteSelection().scrollIntoView().setMeta(\"uiEvent\", \"cut\"))\n}\n\nfunction sliceSingleNode(slice) {\n return slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1 ? slice.content.firstChild : null\n}\n\nfunction capturePaste(view, e) {\n let doc = view.dom.ownerDocument\n let plainText = view.shiftKey || view.state.selection.$from.parent.type.spec.code\n let target = doc.body.appendChild(doc.createElement(plainText ? \"textarea\" : \"div\"))\n if (!plainText) target.contentEditable = \"true\"\n target.style.cssText = \"position: fixed; left: -10000px; top: 10px\"\n target.focus()\n setTimeout(() => {\n view.focus()\n doc.body.removeChild(target)\n if (plainText) doPaste(view, target.value, null, e)\n else doPaste(view, target.textContent, target.innerHTML, e)\n }, 50)\n}\n\nfunction doPaste(view, text, html, e) {\n let slice = parseFromClipboard(view, text, html, view.shiftKey, view.state.selection.$from)\n if (view.someProp(\"handlePaste\", f => f(view, e, slice || Slice.empty)) || !slice) return\n\n let singleNode = sliceSingleNode(slice)\n let tr = singleNode ? view.state.tr.replaceSelectionWith(singleNode, view.shiftKey) : view.state.tr.replaceSelection(slice)\n view.dispatch(tr.scrollIntoView().setMeta(\"paste\", true).setMeta(\"uiEvent\", \"paste\"))\n}\n\neditHandlers.paste = (view, e) => {\n let data = brokenClipboardAPI ? null : e.clipboardData\n let html = data && data.getData(\"text/html\"), text = data && data.getData(\"text/plain\")\n if (data && (html || text || data.files.length)) {\n doPaste(view, text, html, e)\n e.preventDefault()\n } else {\n capturePaste(view, e)\n }\n}\n\nclass Dragging {\n constructor(slice, move) {\n this.slice = slice\n this.move = move\n }\n}\n\nconst dragCopyModifier = browser.mac ? \"altKey\" : \"ctrlKey\"\n\nhandlers.dragstart = (view, e) => {\n let mouseDown = view.mouseDown\n if (mouseDown) mouseDown.done()\n if (!e.dataTransfer) return\n\n let sel = view.state.selection\n let pos = sel.empty ? null : view.posAtCoords(eventCoords(e))\n if (pos && pos.pos >= sel.from && pos.pos <= (sel instanceof NodeSelection ? sel.to - 1: sel.to)) {\n // In selection\n } else if (mouseDown && mouseDown.mightDrag) {\n view.dispatch(view.state.tr.setSelection(NodeSelection.create(view.state.doc, mouseDown.mightDrag.pos)))\n } else if (e.target && e.target.nodeType == 1) {\n let desc = view.docView.nearestDesc(e.target, true)\n if (!desc || !desc.node.type.spec.draggable || desc == view.docView) return\n view.dispatch(view.state.tr.setSelection(NodeSelection.create(view.state.doc, desc.posBefore)))\n }\n let slice = view.state.selection.content(), {dom, text} = serializeForClipboard(view, slice)\n e.dataTransfer.clearData()\n e.dataTransfer.setData(brokenClipboardAPI ? \"Text\" : \"text/html\", dom.innerHTML)\n if (!brokenClipboardAPI) e.dataTransfer.setData(\"text/plain\", text)\n view.dragging = new Dragging(slice, !e[dragCopyModifier])\n}\n\nhandlers.dragend = view => {\n window.setTimeout(() => view.dragging = null, 50)\n}\n\neditHandlers.dragover = editHandlers.dragenter = (_, e) => e.preventDefault()\n\neditHandlers.drop = (view, e) => {\n let dragging = view.dragging\n view.dragging = null\n\n if (!e.dataTransfer) return\n\n let eventPos = view.posAtCoords(eventCoords(e))\n if (!eventPos) return\n let $mouse = view.state.doc.resolve(eventPos.pos)\n if (!$mouse) return\n let slice = dragging && dragging.slice ||\n parseFromClipboard(view, e.dataTransfer.getData(brokenClipboardAPI ? \"Text\" : \"text/plain\"),\n brokenClipboardAPI ? null : e.dataTransfer.getData(\"text/html\"), false, $mouse)\n if (!slice) return\n\n e.preventDefault()\n if (view.someProp(\"handleDrop\", f => f(view, e, slice, dragging && dragging.move))) return\n let insertPos = slice ? dropPoint(view.state.doc, $mouse.pos, slice) : $mouse.pos\n if (insertPos == null) insertPos = $mouse.pos\n\n let tr = view.state.tr\n if (dragging && dragging.move) tr.deleteSelection()\n\n let pos = tr.mapping.map(insertPos)\n let isNode = slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1\n let beforeInsert = tr.doc\n if (isNode)\n tr.replaceRangeWith(pos, pos, slice.content.firstChild)\n else\n tr.replaceRange(pos, pos, slice)\n if (tr.doc.eq(beforeInsert)) return\n\n let $pos = tr.doc.resolve(pos)\n if (isNode && NodeSelection.isSelectable(slice.content.firstChild) &&\n $pos.nodeAfter && $pos.nodeAfter.sameMarkup(slice.content.firstChild))\n tr.setSelection(new NodeSelection($pos))\n else\n tr.setSelection(selectionBetween(view, $pos, tr.doc.resolve(tr.mapping.map(insertPos))))\n view.focus()\n view.dispatch(tr.setMeta(\"uiEvent\", \"drop\"))\n}\n\nhandlers.focus = view => {\n if (!view.focused) {\n view.domObserver.stop()\n view.dom.classList.add(\"ProseMirror-focused\")\n view.domObserver.start()\n view.focused = true\n }\n}\n\nhandlers.blur = view => {\n if (view.focused) {\n view.domObserver.stop()\n view.dom.classList.remove(\"ProseMirror-focused\")\n view.domObserver.start()\n view.domObserver.currentSelection.set({})\n view.focused = false\n }\n}\n\nhandlers.beforeinput = (view, event) => {\n // We should probably do more with beforeinput events, but support\n // is so spotty that I'm still waiting to see where they are going.\n\n // Very specific hack to deal with backspace sometimes failing on\n // Chrome Android when after an uneditable node.\n if (browser.chrome && browser.android && event.inputType == \"deleteContentBackward\") {\n let {domChangeCount} = view\n setTimeout(() => {\n if (view.domChangeCount != domChangeCount) return // Event already had some effect\n // This bug tends to close the virtual keyboard, so we refocus\n view.dom.blur()\n view.focus()\n if (view.someProp(\"handleKeyDown\", f => f(view, keyEvent(8, \"Backspace\")))) return\n let {$cursor} = view.state.selection\n // Crude approximation of backspace behavior when no command handled it\n if ($cursor && $cursor.pos > 0) view.dispatch(view.state.tr.delete($cursor.pos - 1, $cursor.pos).scrollIntoView())\n }, 50)\n }\n}\n\n// Make sure all handlers get registered\nfor (let prop in editHandlers) handlers[prop] = editHandlers[prop]\n","function compareObjs(a, b) {\n if (a == b) return true\n for (let p in a) if (a[p] !== b[p]) return false\n for (let p in b) if (!(p in a)) return false\n return true\n}\n\nclass WidgetType {\n constructor(toDOM, spec) {\n this.spec = spec || noSpec\n this.side = this.spec.side || 0\n this.toDOM = toDOM\n }\n\n map(mapping, span, offset, oldOffset) {\n let {pos, deleted} = mapping.mapResult(span.from + oldOffset, this.side < 0 ? -1 : 1)\n return deleted ? null : new Decoration(pos - offset, pos - offset, this)\n }\n\n valid() { return true }\n\n eq(other) {\n return this == other ||\n (other instanceof WidgetType &&\n (this.spec.key && this.spec.key == other.spec.key ||\n this.toDOM == other.toDOM && compareObjs(this.spec, other.spec)))\n }\n}\n\nclass InlineType {\n constructor(attrs, spec) {\n this.spec = spec || noSpec\n this.attrs = attrs\n }\n\n map(mapping, span, offset, oldOffset) {\n let from = mapping.map(span.from + oldOffset, this.spec.inclusiveStart ? -1 : 1) - offset\n let to = mapping.map(span.to + oldOffset, this.spec.inclusiveEnd ? 1 : -1) - offset\n return from >= to ? null : new Decoration(from, to, this)\n }\n\n valid(_, span) { return span.from < span.to }\n\n eq(other) {\n return this == other ||\n (other instanceof InlineType && compareObjs(this.attrs, other.attrs) &&\n compareObjs(this.spec, other.spec))\n }\n\n static is(span) { return span.type instanceof InlineType }\n}\n\nclass NodeType {\n constructor(attrs, spec) {\n this.spec = spec || noSpec\n this.attrs = attrs\n }\n\n map(mapping, span, offset, oldOffset) {\n let from = mapping.mapResult(span.from + oldOffset, 1)\n if (from.deleted) return null\n let to = mapping.mapResult(span.to + oldOffset, -1)\n if (to.deleted || to.pos <= from.pos) return null\n return new Decoration(from.pos - offset, to.pos - offset, this)\n }\n\n valid(node, span) {\n let {index, offset} = node.content.findIndex(span.from)\n return offset == span.from && offset + node.child(index).nodeSize == span.to\n }\n\n eq(other) {\n return this == other ||\n (other instanceof NodeType && compareObjs(this.attrs, other.attrs) &&\n compareObjs(this.spec, other.spec))\n }\n}\n\n// ::- Decoration objects can be provided to the view through the\n// [`decorations` prop](#view.EditorProps.decorations). They come in\n// several variants—see the static members of this class for details.\nexport class Decoration {\n constructor(from, to, type) {\n // :: number\n // The start position of the decoration.\n this.from = from\n // :: number\n // The end position. Will be the same as `from` for [widget\n // decorations](#view.Decoration^widget).\n this.to = to\n this.type = type\n }\n\n copy(from, to) {\n return new Decoration(from, to, this.type)\n }\n\n eq(other) {\n return this.type.eq(other.type) && this.from == other.from && this.to == other.to\n }\n\n map(mapping, offset, oldOffset) {\n return this.type.map(mapping, this, offset, oldOffset)\n }\n\n // :: (number, union<(view: EditorView, getPos: () → number) → dom.Node, dom.Node>, ?Object) → Decoration\n // Creates a widget decoration, which is a DOM node that's shown in\n // the document at the given position. It is recommended that you\n // delay rendering the widget by passing a function that will be\n // called when the widget is actually drawn in a view, but you can\n // also directly pass a DOM node. `getPos` can be used to find the\n // widget's current document position.\n //\n // spec::- These options are supported:\n //\n // side:: ?number\n // Controls which side of the document position this widget is\n // associated with. When negative, it is drawn before a cursor\n // at its position, and content inserted at that position ends\n // up after the widget. When zero (the default) or positive, the\n // widget is drawn after the cursor and content inserted there\n // ends up before the widget.\n //\n // When there are multiple widgets at a given position, their\n // `side` values determine the order in which they appear. Those\n // with lower values appear first. The ordering of widgets with\n // the same `side` value is unspecified.\n //\n // When `marks` is null, `side` also determines the marks that\n // the widget is wrapped in—those of the node before when\n // negative, those of the node after when positive.\n //\n // marks:: ?[Mark]\n // The precise set of marks to draw around the widget.\n //\n // stopEvent:: ?(event: dom.Event) → bool\n // Can be used to control which DOM events, when they bubble out\n // of this widget, the editor view should ignore.\n //\n // key:: ?string\n // When comparing decorations of this type (in order to decide\n // whether it needs to be redrawn), ProseMirror will by default\n // compare the widget DOM node by identity. If you pass a key,\n // that key will be compared instead, which can be useful when\n // you generate decorations on the fly and don't want to store\n // and reuse DOM nodes. Make sure that any widgets with the same\n // key are interchangeable—if widgets differ in, for example,\n // the behavior of some event handler, they should get\n // different keys.\n static widget(pos, toDOM, spec) {\n return new Decoration(pos, pos, new WidgetType(toDOM, spec))\n }\n\n // :: (number, number, DecorationAttrs, ?Object) → Decoration\n // Creates an inline decoration, which adds the given attributes to\n // each inline node between `from` and `to`.\n //\n // spec::- These options are recognized:\n //\n // inclusiveStart:: ?bool\n // Determines how the left side of the decoration is\n // [mapped](#transform.Position_Mapping) when content is\n // inserted directly at that position. By default, the decoration\n // won't include the new content, but you can set this to `true`\n // to make it inclusive.\n //\n // inclusiveEnd:: ?bool\n // Determines how the right side of the decoration is mapped.\n // See\n // [`inclusiveStart`](#view.Decoration^inline^spec.inclusiveStart).\n static inline(from, to, attrs, spec) {\n return new Decoration(from, to, new InlineType(attrs, spec))\n }\n\n // :: (number, number, DecorationAttrs, ?Object) → Decoration\n // Creates a node decoration. `from` and `to` should point precisely\n // before and after a node in the document. That node, and only that\n // node, will receive the given attributes.\n //\n // spec::-\n //\n // Optional information to store with the decoration. It\n // is also used when comparing decorators for equality.\n static node(from, to, attrs, spec) {\n return new Decoration(from, to, new NodeType(attrs, spec))\n }\n\n // :: Object\n // The spec provided when creating this decoration. Can be useful\n // if you've stored extra information in that object.\n get spec() { return this.type.spec }\n}\n\n// DecorationAttrs:: interface\n// A set of attributes to add to a decorated node. Most properties\n// simply directly correspond to DOM attributes of the same name,\n// which will be set to the property's value. These are exceptions:\n//\n// class:: ?string\n// A CSS class name or a space-separated set of class names to be\n// _added_ to the classes that the node already had.\n//\n// style:: ?string\n// A string of CSS to be _added_ to the node's existing `style` property.\n//\n// nodeName:: ?string\n// When non-null, the target node is wrapped in a DOM element of\n// this type (and the other attributes are applied to this element).\n\nconst none = [], noSpec = {}\n\n// ::- A collection of [decorations](#view.Decoration), organized in\n// such a way that the drawing algorithm can efficiently use and\n// compare them. This is a persistent data structure—it is not\n// modified, updates create a new value.\nexport class DecorationSet {\n constructor(local, children) {\n this.local = local && local.length ? local : none\n this.children = children && children.length ? children : none\n }\n\n // :: (Node, [Decoration]) → DecorationSet\n // Create a set of decorations, using the structure of the given\n // document.\n static create(doc, decorations) {\n return decorations.length ? buildTree(decorations, doc, 0, noSpec) : empty\n }\n\n // :: (?number, ?number, ?(spec: Object) → bool) → [Decoration]\n // Find all decorations in this set which touch the given range\n // (including decorations that start or end directly at the\n // boundaries) and match the given predicate on their spec. When\n // `start` and `end` are omitted, all decorations in the set are\n // considered. When `predicate` isn't given, all decorations are\n // assumed to match.\n find(start, end, predicate) {\n let result = []\n this.findInner(start == null ? 0 : start, end == null ? 1e9 : end, result, 0, predicate)\n return result\n }\n\n findInner(start, end, result, offset, predicate) {\n for (let i = 0; i < this.local.length; i++) {\n let span = this.local[i]\n if (span.from <= end && span.to >= start && (!predicate || predicate(span.spec)))\n result.push(span.copy(span.from + offset, span.to + offset))\n }\n for (let i = 0; i < this.children.length; i += 3) {\n if (this.children[i] < end && this.children[i + 1] > start) {\n let childOff = this.children[i] + 1\n this.children[i + 2].findInner(start - childOff, end - childOff, result, offset + childOff, predicate)\n }\n }\n }\n\n // :: (Mapping, Node, ?Object) → DecorationSet\n // Map the set of decorations in response to a change in the\n // document.\n //\n // options::- An optional set of options.\n //\n // onRemove:: ?(decorationSpec: Object)\n // When given, this function will be called for each decoration\n // that gets dropped as a result of the mapping, passing the\n // spec of that decoration.\n map(mapping, doc, options) {\n if (this == empty || mapping.maps.length == 0) return this\n return this.mapInner(mapping, doc, 0, 0, options || noSpec)\n }\n\n mapInner(mapping, node, offset, oldOffset, options) {\n let newLocal\n for (let i = 0; i < this.local.length; i++) {\n let mapped = this.local[i].map(mapping, offset, oldOffset)\n if (mapped && mapped.type.valid(node, mapped)) (newLocal || (newLocal = [])).push(mapped)\n else if (options.onRemove) options.onRemove(this.local[i].spec)\n }\n\n if (this.children.length)\n return mapChildren(this.children, newLocal, mapping, node, offset, oldOffset, options)\n else\n return newLocal ? new DecorationSet(newLocal.sort(byPos)) : empty\n }\n\n // :: (Node, [Decoration]) → DecorationSet\n // Add the given array of decorations to the ones in the set,\n // producing a new set. Needs access to the current document to\n // create the appropriate tree structure.\n add(doc, decorations) {\n if (!decorations.length) return this\n if (this == empty) return DecorationSet.create(doc, decorations)\n return this.addInner(doc, decorations, 0)\n }\n\n addInner(doc, decorations, offset) {\n let children, childIndex = 0\n doc.forEach((childNode, childOffset) => {\n let baseOffset = childOffset + offset, found\n if (!(found = takeSpansForNode(decorations, childNode, baseOffset))) return\n\n if (!children) children = this.children.slice()\n while (childIndex < children.length && children[childIndex] < childOffset) childIndex += 3\n if (children[childIndex] == childOffset)\n children[childIndex + 2] = children[childIndex + 2].addInner(childNode, found, baseOffset + 1)\n else\n children.splice(childIndex, 0, childOffset, childOffset + childNode.nodeSize, buildTree(found, childNode, baseOffset + 1, noSpec))\n childIndex += 3\n })\n\n let local = moveSpans(childIndex ? withoutNulls(decorations) : decorations, -offset)\n return new DecorationSet(local.length ? this.local.concat(local).sort(byPos) : this.local,\n children || this.children)\n }\n\n // :: ([Decoration]) → DecorationSet\n // Create a new set that contains the decorations in this set, minus\n // the ones in the given array.\n remove(decorations) {\n if (decorations.length == 0 || this == empty) return this\n return this.removeInner(decorations, 0)\n }\n\n removeInner(decorations, offset) {\n let children = this.children, local = this.local\n for (let i = 0; i < children.length; i += 3) {\n let found, from = children[i] + offset, to = children[i + 1] + offset\n for (let j = 0, span; j < decorations.length; j++) if (span = decorations[j]) {\n if (span.from > from && span.to < to) {\n decorations[j] = null\n ;(found || (found = [])).push(span)\n }\n }\n if (!found) continue\n if (children == this.children) children = this.children.slice()\n let removed = children[i + 2].removeInner(found, from + 1)\n if (removed != empty) {\n children[i + 2] = removed\n } else {\n children.splice(i, 3)\n i -= 3\n }\n }\n if (local.length) for (let i = 0, span; i < decorations.length; i++) if (span = decorations[i]) {\n for (let j = 0; j < local.length; j++) if (local[j].type.eq(span.type)) {\n if (local == this.local) local = this.local.slice()\n local.splice(j--, 1)\n }\n }\n if (children == this.children && local == this.local) return this\n return local.length || children.length ? new DecorationSet(local, children) : empty\n }\n\n forChild(offset, node) {\n if (this == empty) return this\n if (node.isLeaf) return DecorationSet.empty\n\n let child, local\n for (let i = 0; i < this.children.length; i += 3) if (this.children[i] >= offset) {\n if (this.children[i] == offset) child = this.children[i + 2]\n break\n }\n let start = offset + 1, end = start + node.content.size\n for (let i = 0; i < this.local.length; i++) {\n let dec = this.local[i]\n if (dec.from < end && dec.to > start && (dec.type instanceof InlineType)) {\n let from = Math.max(start, dec.from) - start, to = Math.min(end, dec.to) - start\n if (from < to) (local || (local = [])).push(dec.copy(from, to))\n }\n }\n if (local) {\n let localSet = new DecorationSet(local.sort(byPos))\n return child ? new DecorationGroup([localSet, child]) : localSet\n }\n return child || empty\n }\n\n eq(other) {\n if (this == other) return true\n if (!(other instanceof DecorationSet) ||\n this.local.length != other.local.length ||\n this.children.length != other.children.length) return false\n for (let i = 0; i < this.local.length; i++)\n if (!this.local[i].eq(other.local[i])) return false\n for (let i = 0; i < this.children.length; i += 3)\n if (this.children[i] != other.children[i] ||\n this.children[i + 1] != other.children[i + 1] ||\n !this.children[i + 2].eq(other.children[i + 2])) return false\n return true\n }\n\n locals(node) {\n return removeOverlap(this.localsInner(node))\n }\n\n localsInner(node) {\n if (this == empty) return none\n if (node.inlineContent || !this.local.some(InlineType.is)) return this.local\n let result = []\n for (let i = 0; i < this.local.length; i++) {\n if (!(this.local[i].type instanceof InlineType))\n result.push(this.local[i])\n }\n return result\n }\n}\n\nconst empty = new DecorationSet()\n\n// :: DecorationSet\n// The empty set of decorations.\nDecorationSet.empty = empty\n\nDecorationSet.removeOverlap = removeOverlap\n\n// :- An abstraction that allows the code dealing with decorations to\n// treat multiple DecorationSet objects as if it were a single object\n// with (a subset of) the same interface.\nclass DecorationGroup {\n constructor(members) {\n this.members = members\n }\n\n forChild(offset, child) {\n if (child.isLeaf) return DecorationSet.empty\n let found = []\n for (let i = 0; i < this.members.length; i++) {\n let result = this.members[i].forChild(offset, child)\n if (result == empty) continue\n if (result instanceof DecorationGroup) found = found.concat(result.members)\n else found.push(result)\n }\n return DecorationGroup.from(found)\n }\n\n eq(other) {\n if (!(other instanceof DecorationGroup) ||\n other.members.length != this.members.length) return false\n for (let i = 0; i < this.members.length; i++)\n if (!this.members[i].eq(other.members[i])) return false\n return true\n }\n\n locals(node) {\n let result, sorted = true\n for (let i = 0; i < this.members.length; i++) {\n let locals = this.members[i].localsInner(node)\n if (!locals.length) continue\n if (!result) {\n result = locals\n } else {\n if (sorted) {\n result = result.slice()\n sorted = false\n }\n for (let j = 0; j < locals.length; j++) result.push(locals[j])\n }\n }\n return result ? removeOverlap(sorted ? result : result.sort(byPos)) : none\n }\n\n // : ([DecorationSet]) → union\n // Create a group for the given array of decoration sets, or return\n // a single set when possible.\n static from(members) {\n switch (members.length) {\n case 0: return empty\n case 1: return members[0]\n default: return new DecorationGroup(members)\n }\n }\n}\n\nfunction mapChildren(oldChildren, newLocal, mapping, node, offset, oldOffset, options) {\n let children = oldChildren.slice()\n\n // Mark the children that are directly touched by changes, and\n // move those that are after the changes.\n let shift = (oldStart, oldEnd, newStart, newEnd) => {\n for (let i = 0; i < children.length; i += 3) {\n let end = children[i + 1], dSize\n if (end == -1 || oldStart > end + oldOffset) continue\n if (oldEnd >= children[i] + oldOffset) {\n children[i + 1] = -1\n } else if (dSize = (newEnd - newStart) - (oldEnd - oldStart) + (oldOffset - offset)) {\n children[i] += dSize\n children[i + 1] += dSize\n }\n }\n }\n for (let i = 0; i < mapping.maps.length; i++) mapping.maps[i].forEach(shift)\n\n // Find the child nodes that still correspond to a single node,\n // recursively call mapInner on them and update their positions.\n let mustRebuild = false\n for (let i = 0; i < children.length; i += 3) if (children[i + 1] == -1) { // Touched nodes\n let from = mapping.map(children[i] + oldOffset), fromLocal = from - offset\n if (fromLocal < 0 || fromLocal >= node.content.size) {\n mustRebuild = true\n continue\n }\n // Must read oldChildren because children was tagged with -1\n let to = mapping.map(oldChildren[i + 1] + oldOffset, -1), toLocal = to - offset\n let {index, offset: childOffset} = node.content.findIndex(fromLocal)\n let childNode = node.maybeChild(index)\n if (childNode && childOffset == fromLocal && childOffset + childNode.nodeSize == toLocal) {\n let mapped = children[i + 2].mapInner(mapping, childNode, from + 1, children[i] + oldOffset + 1, options)\n if (mapped != empty) {\n children[i] = fromLocal\n children[i + 1] = toLocal\n children[i + 2] = mapped\n } else {\n children[i + 1] = -2\n mustRebuild = true\n }\n } else {\n mustRebuild = true\n }\n }\n\n // Remaining children must be collected and rebuilt into the appropriate structure\n if (mustRebuild) {\n let decorations = mapAndGatherRemainingDecorations(children, oldChildren, newLocal || [], mapping,\n offset, oldOffset, options)\n let built = buildTree(decorations, node, 0, options)\n newLocal = built.local\n for (let i = 0; i < children.length; i += 3) if (children[i + 1] < 0) {\n children.splice(i, 3)\n i -= 3\n }\n for (let i = 0, j = 0; i < built.children.length; i += 3) {\n let from = built.children[i]\n while (j < children.length && children[j] < from) j += 3\n children.splice(j, 0, built.children[i], built.children[i + 1], built.children[i + 2])\n }\n }\n\n return new DecorationSet(newLocal && newLocal.sort(byPos), children)\n}\n\nfunction moveSpans(spans, offset) {\n if (!offset || !spans.length) return spans\n let result = []\n for (let i = 0; i < spans.length; i++) {\n let span = spans[i]\n result.push(new Decoration(span.from + offset, span.to + offset, span.type))\n }\n return result\n}\n\nfunction mapAndGatherRemainingDecorations(children, oldChildren, decorations, mapping, offset, oldOffset, options) {\n // Gather all decorations from the remaining marked children\n function gather(set, oldOffset) {\n for (let i = 0; i < set.local.length; i++) {\n let mapped = set.local[i].map(mapping, offset, oldOffset)\n if (mapped) decorations.push(mapped)\n else if (options.onRemove) options.onRemove(set.local[i].spec)\n }\n for (let i = 0; i < set.children.length; i += 3)\n gather(set.children[i + 2], set.children[i] + oldOffset + 1)\n }\n for (let i = 0; i < children.length; i += 3) if (children[i + 1] == -1)\n gather(children[i + 2], oldChildren[i] + oldOffset + 1)\n\n return decorations\n}\n\nfunction takeSpansForNode(spans, node, offset) {\n if (node.isLeaf) return null\n let end = offset + node.nodeSize, found = null\n for (let i = 0, span; i < spans.length; i++) {\n if ((span = spans[i]) && span.from > offset && span.to < end) {\n ;(found || (found = [])).push(span)\n spans[i] = null\n }\n }\n return found\n}\n\nfunction withoutNulls(array) {\n let result = []\n for (let i = 0; i < array.length; i++)\n if (array[i] != null) result.push(array[i])\n return result\n}\n\n// : ([Decoration], Node, number) → DecorationSet\n// Build up a tree that corresponds to a set of decorations. `offset`\n// is a base offset that should be subtractet from the `from` and `to`\n// positions in the spans (so that we don't have to allocate new spans\n// for recursive calls).\nfunction buildTree(spans, node, offset, options) {\n let children = [], hasNulls = false\n node.forEach((childNode, localStart) => {\n let found = takeSpansForNode(spans, childNode, localStart + offset)\n if (found) {\n hasNulls = true\n let subtree = buildTree(found, childNode, offset + localStart + 1, options)\n if (subtree != empty)\n children.push(localStart, localStart + childNode.nodeSize, subtree)\n }\n })\n let locals = moveSpans(hasNulls ? withoutNulls(spans) : spans, -offset).sort(byPos)\n for (let i = 0; i < locals.length; i++) if (!locals[i].type.valid(node, locals[i])) {\n if (options.onRemove) options.onRemove(locals[i].spec)\n locals.splice(i--, 1)\n }\n return locals.length || children.length ? new DecorationSet(locals, children) : empty\n}\n\n// : (Decoration, Decoration) → number\n// Used to sort decorations so that ones with a low start position\n// come first, and within a set with the same start position, those\n// with an smaller end position come first.\nfunction byPos(a, b) {\n return a.from - b.from || a.to - b.to\n}\n\n// : ([Decoration]) → [Decoration]\n// Scan a sorted array of decorations for partially overlapping spans,\n// and split those so that only fully overlapping spans are left (to\n// make subsequent rendering easier). Will return the input array if\n// no partially overlapping spans are found (the common case).\nfunction removeOverlap(spans) {\n let working = spans\n for (let i = 0; i < working.length - 1; i++) {\n let span = working[i]\n if (span.from != span.to) for (let j = i + 1; j < working.length; j++) {\n let next = working[j]\n if (next.from == span.from) {\n if (next.to != span.to) {\n if (working == spans) working = spans.slice()\n // Followed by a partially overlapping larger span. Split that\n // span.\n working[j] = next.copy(next.from, span.to)\n insertAhead(working, j + 1, next.copy(span.to, next.to))\n }\n continue\n } else {\n if (next.from < span.to) {\n if (working == spans) working = spans.slice()\n // The end of this one overlaps with a subsequent span. Split\n // this one.\n working[i] = span.copy(span.from, next.from)\n insertAhead(working, j, span.copy(next.from, span.to))\n }\n break\n }\n }\n }\n return working\n}\n\nfunction insertAhead(array, i, deco) {\n while (i < array.length && byPos(deco, array[i]) > 0) i++\n array.splice(i, 0, deco)\n}\n\n// : (EditorView) → union\n// Get the decorations associated with the current props of a view.\nexport function viewDecorations(view) {\n let found = []\n view.someProp(\"decorations\", f => {\n let result = f(view.state)\n if (result && result != empty) found.push(result)\n })\n if (view.cursorWrapper)\n found.push(DecorationSet.create(view.state.doc, [view.cursorWrapper.deco]))\n return DecorationGroup.from(found)\n}\n","import {NodeSelection} from \"prosemirror-state\"\n\nimport {scrollRectIntoView, posAtCoords, coordsAtPos, endOfTextblock, storeScrollPos,\n resetScrollPos, focusPreventScroll} from \"./domcoords\"\nimport {docViewDesc} from \"./viewdesc\"\nimport {initInput, destroyInput, dispatchEvent, ensureListeners} from \"./input\"\nimport {selectionToDOM, anchorInRightPlace, syncNodeSelection} from \"./selection\"\nimport {Decoration, viewDecorations} from \"./decoration\"\nimport browser from \"./browser\"\n\nexport {Decoration, DecorationSet} from \"./decoration\"\n\n// Exported for testing\nexport {serializeForClipboard as __serializeForClipboard, parseFromClipboard as __parseFromClipboard} from \"./clipboard\"\nexport {endComposition as __endComposition} from \"./input\"\n\n// ::- An editor view manages the DOM structure that represents an\n// editable document. Its state and behavior are determined by its\n// [props](#view.DirectEditorProps).\nexport class EditorView {\n // :: (?union, DirectEditorProps)\n // Create a view. `place` may be a DOM node that the editor should\n // be appended to, a function that will place it into the document,\n // or an object whose `mount` property holds the node to use as the\n // document container. If it is `null`, the editor will not be added\n // to the document.\n constructor(place, props) {\n this._props = props\n // :: EditorState\n // The view's current [state](#state.EditorState).\n this.state = props.state\n\n this.dispatch = this.dispatch.bind(this)\n\n this._root = null\n this.focused = false\n\n // :: dom.Element\n // An editable DOM node containing the document. (You probably\n // should not directly interfere with its content.)\n this.dom = (place && place.mount) || document.createElement(\"div\")\n if (place) {\n if (place.appendChild) place.appendChild(this.dom)\n else if (place.apply) place(this.dom)\n else if (place.mount) this.mounted = true\n }\n\n // :: bool\n // Indicates whether the editor is currently [editable](#view.EditorProps.editable).\n this.editable = getEditable(this)\n this.markCursor = null\n this.cursorWrapper = null\n updateCursorWrapper(this)\n this.nodeViews = buildNodeViews(this)\n this.docView = docViewDesc(this.state.doc, computeDocDeco(this), viewDecorations(this), this.dom, this)\n\n this.lastSelectedViewDesc = null\n // :: ?{slice: Slice, move: bool}\n // When editor content is being dragged, this object contains\n // information about the dragged slice and whether it is being\n // copied or moved. At any other time, it is null.\n this.dragging = null\n\n initInput(this)\n\n this.pluginViews = []\n this.updatePluginViews()\n }\n\n // composing:: boolean\n // Holds `true` when a\n // [composition](https://developer.mozilla.org/en-US/docs/Mozilla/IME_handling_guide)\n // is active.\n\n // :: DirectEditorProps\n // The view's current [props](#view.EditorProps).\n get props() {\n if (this._props.state != this.state) {\n let prev = this._props\n this._props = {}\n for (let name in prev) this._props[name] = prev[name]\n this._props.state = this.state\n }\n return this._props\n }\n\n // :: (DirectEditorProps)\n // Update the view's props. Will immediately cause an update to\n // the DOM.\n update(props) {\n if (props.handleDOMEvents != this._props.handleDOMEvents) ensureListeners(this)\n this._props = props\n this.updateStateInner(props.state, true)\n }\n\n // :: (DirectEditorProps)\n // Update the view by updating existing props object with the object\n // given as argument. Equivalent to `view.update(Object.assign({},\n // view.props, props))`.\n setProps(props) {\n let updated = {}\n for (let name in this._props) updated[name] = this._props[name]\n updated.state = this.state\n for (let name in props) updated[name] = props[name]\n this.update(updated)\n }\n\n // :: (EditorState)\n // Update the editor's `state` prop, without touching any of the\n // other props.\n updateState(state) {\n this.updateStateInner(state, this.state.plugins != state.plugins)\n }\n\n updateStateInner(state, reconfigured) {\n let prev = this.state, redraw = false\n this.state = state\n if (reconfigured) {\n let nodeViews = buildNodeViews(this)\n if (changedNodeViews(nodeViews, this.nodeViews)) {\n this.nodeViews = nodeViews\n redraw = true\n }\n ensureListeners(this)\n }\n\n this.editable = getEditable(this)\n updateCursorWrapper(this)\n let innerDeco = viewDecorations(this), outerDeco = computeDocDeco(this)\n\n let scroll = reconfigured ? \"reset\"\n : state.scrollToSelection > prev.scrollToSelection ? \"to selection\" : \"preserve\"\n let updateDoc = redraw || !this.docView.matchesNode(state.doc, outerDeco, innerDeco)\n let updateSel = updateDoc || !state.selection.eq(prev.selection)\n let oldScrollPos = scroll == \"preserve\" && updateSel && this.dom.style.overflowAnchor == null && storeScrollPos(this)\n\n if (updateSel) {\n this.domObserver.stop()\n // Work around an issue in Chrome, IE, and Edge where changing\n // the DOM around an active selection puts it into a broken\n // state where the thing the user sees differs from the\n // selection reported by the Selection object (#710, #973,\n // #1011, #1013).\n let forceSelUpdate = updateDoc && (browser.ie || browser.chrome) &&\n !prev.selection.empty && !state.selection.empty && selectionContextChanged(prev.selection, state.selection)\n if (updateDoc) {\n if (redraw || !this.docView.update(state.doc, outerDeco, innerDeco, this)) {\n this.docView.destroy()\n this.docView = docViewDesc(state.doc, outerDeco, innerDeco, this.dom, this)\n }\n }\n // Work around for an issue where an update arriving right between\n // a DOM selection change and the \"selectionchange\" event for it\n // can cause a spurious DOM selection update, disrupting mouse\n // drag selection.\n if (forceSelUpdate ||\n !(this.mouseDown && this.domObserver.currentSelection.eq(this.root.getSelection()) && anchorInRightPlace(this))) {\n selectionToDOM(this, forceSelUpdate)\n } else {\n syncNodeSelection(this, state.selection)\n this.domObserver.setCurSelection()\n }\n this.domObserver.start()\n }\n\n this.updatePluginViews(prev)\n\n if (scroll == \"reset\") {\n this.dom.scrollTop = 0\n } else if (scroll == \"to selection\") {\n let startDOM = this.root.getSelection().focusNode\n if (this.someProp(\"handleScrollToSelection\", f => f(this)))\n {} // Handled\n else if (state.selection instanceof NodeSelection)\n scrollRectIntoView(this, this.docView.domAfterPos(state.selection.from).getBoundingClientRect(), startDOM)\n else\n scrollRectIntoView(this, this.coordsAtPos(state.selection.head), startDOM)\n } else if (oldScrollPos) {\n resetScrollPos(oldScrollPos)\n }\n }\n\n destroyPluginViews() {\n let view\n while (view = this.pluginViews.pop()) if (view.destroy) view.destroy()\n }\n\n updatePluginViews(prevState) {\n if (!prevState || prevState.plugins != this.state.plugins) {\n this.destroyPluginViews()\n for (let i = 0; i < this.state.plugins.length; i++) {\n let plugin = this.state.plugins[i]\n if (plugin.spec.view) this.pluginViews.push(plugin.spec.view(this))\n }\n } else {\n for (let i = 0; i < this.pluginViews.length; i++) {\n let pluginView = this.pluginViews[i]\n if (pluginView.update) pluginView.update(this, prevState)\n }\n }\n }\n\n // :: (string, ?(prop: *) → *) → *\n // Goes over the values of a prop, first those provided directly,\n // then those from plugins (in order), and calls `f` every time a\n // non-undefined value is found. When `f` returns a truthy value,\n // that is immediately returned. When `f` isn't provided, it is\n // treated as the identity function (the prop value is returned\n // directly).\n someProp(propName, f) {\n let prop = this._props && this._props[propName], value\n if (prop != null && (value = f ? f(prop) : prop)) return value\n let plugins = this.state.plugins\n if (plugins) for (let i = 0; i < plugins.length; i++) {\n let prop = plugins[i].props[propName]\n if (prop != null && (value = f ? f(prop) : prop)) return value\n }\n }\n\n // :: () → bool\n // Query whether the view has focus.\n hasFocus() {\n return this.root.activeElement == this.dom\n }\n\n // :: ()\n // Focus the editor.\n focus() {\n this.domObserver.stop()\n if (this.editable) focusPreventScroll(this.dom)\n selectionToDOM(this)\n this.domObserver.start()\n }\n\n // :: union\n // Get the document root in which the editor exists. This will\n // usually be the top-level `document`, but might be a [shadow\n // DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Shadow_DOM)\n // root if the editor is inside one.\n get root() {\n let cached = this._root\n if (cached == null) for (let search = this.dom.parentNode; search; search = search.parentNode) {\n if (search.nodeType == 9 || (search.nodeType == 11 && search.host)) {\n if (!search.getSelection) Object.getPrototypeOf(search).getSelection = () => document.getSelection()\n return this._root = search\n }\n }\n return cached || document\n }\n\n // :: ({left: number, top: number}) → ?{pos: number, inside: number}\n // Given a pair of viewport coordinates, return the document\n // position that corresponds to them. May return null if the given\n // coordinates aren't inside of the editor. When an object is\n // returned, its `pos` property is the position nearest to the\n // coordinates, and its `inside` property holds the position of the\n // inner node that the position falls inside of, or -1 if it is at\n // the top level, not in any node.\n posAtCoords(coords) {\n return posAtCoords(this, coords)\n }\n\n // :: (number) → {left: number, right: number, top: number, bottom: number}\n // Returns the viewport rectangle at a given document position. `left`\n // and `right` will be the same number, as this returns a flat\n // cursor-ish rectangle.\n coordsAtPos(pos) {\n return coordsAtPos(this, pos)\n }\n\n // :: (number) → {node: dom.Node, offset: number}\n // Find the DOM position that corresponds to the given document\n // position. Note that you should **not** mutate the editor's\n // internal DOM, only inspect it (and even that is usually not\n // necessary).\n domAtPos(pos) {\n return this.docView.domFromPos(pos)\n }\n\n // :: (number) → ?dom.Node\n // Find the DOM node that represents the document node after the\n // given position. May return `null` when the position doesn't point\n // in front of a node or if the node is inside an opaque node view.\n //\n // This is intended to be able to call things like\n // `getBoundingClientRect` on that DOM node. Do **not** mutate the\n // editor DOM directly, or add styling this way, since that will be\n // immediately overriden by the editor as it redraws the node.\n nodeDOM(pos) {\n let desc = this.docView.descAt(pos)\n return desc ? desc.nodeDOM : null\n }\n\n // :: (dom.Node, number, ?number) → number\n // Find the document position that corresponds to a given DOM\n // position. (Whenever possible, it is preferable to inspect the\n // document structure directly, rather than poking around in the\n // DOM, but sometimes—for example when interpreting an event\n // target—you don't have a choice.)\n //\n // The `bias` parameter can be used to influence which side of a DOM\n // node to use when the position is inside a leaf node.\n posAtDOM(node, offset, bias = -1) {\n let pos = this.docView.posFromDOM(node, offset, bias)\n if (pos == null) throw new RangeError(\"DOM position not inside the editor\")\n return pos\n }\n\n // :: (union<\"up\", \"down\", \"left\", \"right\", \"forward\", \"backward\">, ?EditorState) → bool\n // Find out whether the selection is at the end of a textblock when\n // moving in a given direction. When, for example, given `\"left\"`,\n // it will return true if moving left from the current cursor\n // position would leave that position's parent textblock. Will apply\n // to the view's current state by default, but it is possible to\n // pass a different state.\n endOfTextblock(dir, state) {\n return endOfTextblock(this, state || this.state, dir)\n }\n\n // :: ()\n // Removes the editor from the DOM and destroys all [node\n // views](#view.NodeView).\n destroy() {\n if (!this.docView) return\n destroyInput(this)\n this.destroyPluginViews()\n if (this.mounted) {\n this.docView.update(this.state.doc, [], viewDecorations(this), this)\n this.dom.textContent = \"\"\n } else if (this.dom.parentNode) {\n this.dom.parentNode.removeChild(this.dom)\n }\n this.docView.destroy()\n this.docView = null\n }\n\n // Used for testing.\n dispatchEvent(event) {\n return dispatchEvent(this, event)\n }\n\n // :: (Transaction)\n // Dispatch a transaction. Will call\n // [`dispatchTransaction`](#view.DirectEditorProps.dispatchTransaction)\n // when given, and otherwise defaults to applying the transaction to\n // the current state and calling\n // [`updateState`](#view.EditorView.updateState) with the result.\n // This method is bound to the view instance, so that it can be\n // easily passed around.\n dispatch(tr) {\n let dispatchTransaction = this._props.dispatchTransaction\n if (dispatchTransaction) dispatchTransaction.call(this, tr)\n else this.updateState(this.state.apply(tr))\n }\n}\n\nfunction computeDocDeco(view) {\n let attrs = Object.create(null)\n attrs.class = \"ProseMirror\"\n attrs.contenteditable = String(view.editable)\n\n view.someProp(\"attributes\", value => {\n if (typeof value == \"function\") value = value(view.state)\n if (value) for (let attr in value) {\n if (attr == \"class\")\n attrs.class += \" \" + value[attr]\n else if (!attrs[attr] && attr != \"contenteditable\" && attr != \"nodeName\")\n attrs[attr] = String(value[attr])\n }\n })\n\n return [Decoration.node(0, view.state.doc.content.size, attrs)]\n}\n\nfunction updateCursorWrapper(view) {\n let {$head, $anchor, visible} = view.state.selection\n if (view.markCursor) {\n let dom = document.createElement(\"img\")\n dom.setAttribute(\"mark-placeholder\", \"true\")\n view.cursorWrapper = {dom, deco: Decoration.widget($head.pos, dom, {raw: true, marks: view.markCursor})}\n } else if (visible || $head.pos != $anchor.pos) {\n view.cursorWrapper = null\n } else {\n let dom\n if (!view.cursorWrapper || view.cursorWrapper.dom.childNodes.length) {\n dom = document.createElement(\"div\")\n dom.style.position = \"absolute\"\n dom.style.left = \"-100000px\"\n } else if (view.cursorWrapper.deco.pos != $head.pos) {\n dom = view.cursorWrapper.dom\n }\n if (dom)\n view.cursorWrapper = {dom, deco: Decoration.widget($head.pos, dom, {raw: true})}\n }\n}\n\nfunction getEditable(view) {\n return !view.someProp(\"editable\", value => value(view.state) === false)\n}\n\nfunction selectionContextChanged(sel1, sel2) {\n let depth = Math.min(sel1.$anchor.sharedDepth(sel1.head), sel2.$anchor.sharedDepth(sel2.head))\n return sel1.$anchor.node(depth) != sel2.$anchor.node(depth)\n}\n\nfunction buildNodeViews(view) {\n let result = {}\n view.someProp(\"nodeViews\", obj => {\n for (let prop in obj) if (!Object.prototype.hasOwnProperty.call(result, prop))\n result[prop] = obj[prop]\n })\n return result\n}\n\nfunction changedNodeViews(a, b) {\n let nA = 0, nB = 0\n for (let prop in a) {\n if (a[prop] != b[prop]) return true\n nA++\n }\n for (let _ in b) nB++\n return nA != nB\n}\n\n// EditorProps:: interface\n//\n// Props are configuration values that can be passed to an editor view\n// or included in a plugin. This interface lists the supported props.\n//\n// The various event-handling functions may all return `true` to\n// indicate that they handled the given event. The view will then take\n// care to call `preventDefault` on the event, except with\n// `handleDOMEvents`, where the handler itself is responsible for that.\n//\n// How a prop is resolved depends on the prop. Handler functions are\n// called one at a time, starting with the base props and then\n// searching through the plugins (in order of appearance) until one of\n// them returns true. For some props, the first plugin that yields a\n// value gets precedence.\n//\n// handleDOMEvents:: ?Object<(view: EditorView, event: dom.Event) → bool>\n// Can be an object mapping DOM event type names to functions that\n// handle them. Such functions will be called before any handling\n// ProseMirror does of events fired on the editable DOM element.\n// Contrary to the other event handling props, when returning true\n// from such a function, you are responsible for calling\n// `preventDefault` yourself (or not, if you want to allow the\n// default behavior).\n//\n// handleKeyDown:: ?(view: EditorView, event: dom.KeyboardEvent) → bool\n// Called when the editor receives a `keydown` event.\n//\n// handleKeyPress:: ?(view: EditorView, event: dom.KeyboardEvent) → bool\n// Handler for `keypress` events.\n//\n// handleTextInput:: ?(view: EditorView, from: number, to: number, text: string) → bool\n// Whenever the user directly input text, this handler is called\n// before the input is applied. If it returns `true`, the default\n// behavior of actually inserting the text is suppressed.\n//\n// handleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool\n// Called for each node around a click, from the inside out. The\n// `direct` flag will be true for the inner node.\n//\n// handleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool\n// Called when the editor is clicked, after `handleClickOn` handlers\n// have been called.\n//\n// handleDoubleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool\n// Called for each node around a double click.\n//\n// handleDoubleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool\n// Called when the editor is double-clicked, after `handleDoubleClickOn`.\n//\n// handleTripleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool\n// Called for each node around a triple click.\n//\n// handleTripleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool\n// Called when the editor is triple-clicked, after `handleTripleClickOn`.\n//\n// handlePaste:: ?(view: EditorView, event: dom.Event, slice: Slice) → bool\n// Can be used to override the behavior of pasting. `slice` is the\n// pasted content parsed by the editor, but you can directly access\n// the event to get at the raw content.\n//\n// handleDrop:: ?(view: EditorView, event: dom.Event, slice: Slice, moved: bool) → bool\n// Called when something is dropped on the editor. `moved` will be\n// true if this drop moves from the current selection (which should\n// thus be deleted).\n//\n// handleScrollToSelection:: ?(view: EditorView) → bool\n// Called when the view, after updating its state, tries to scroll\n// the selection into view. A handler function may return false to\n// indicate that it did not handle the scrolling and further\n// handlers or the default behavior should be tried.\n//\n// createSelectionBetween:: ?(view: EditorView, anchor: ResolvedPos, head: ResolvedPos) → ?Selection\n// Can be used to override the way a selection is created when\n// reading a DOM selection between the given anchor and head.\n//\n// domParser:: ?DOMParser\n// The [parser](#model.DOMParser) to use when reading editor changes\n// from the DOM. Defaults to calling\n// [`DOMParser.fromSchema`](#model.DOMParser^fromSchema) on the\n// editor's schema.\n//\n// transformPastedHTML:: ?(html: string) → string\n// Can be used to transform pasted HTML text, _before_ it is parsed,\n// for example to clean it up.\n//\n// clipboardParser:: ?DOMParser\n// The [parser](#model.DOMParser) to use when reading content from\n// the clipboard. When not given, the value of the\n// [`domParser`](#view.EditorProps.domParser) prop is used.\n//\n// transformPastedText:: ?(text: string) → string\n// Transform pasted plain text.\n//\n// clipboardTextParser:: ?(text: string, $context: ResolvedPos) → Slice\n// A function to parse text from the clipboard into a document\n// slice. Called after\n// [`transformPastedText`](#view.EditorProps.transformPastedText).\n// The default behavior is to split the text into lines, wrap them\n// in `

    ` tags, and call\n// [`clipboardParser`](#view.EditorProps.clipboardParser) on it.\n//\n// transformPasted:: ?(Slice) → Slice\n// Can be used to transform pasted content before it is applied to\n// the document.\n//\n// nodeViews:: ?Object<(node: Node, view: EditorView, getPos: () → number, decorations: [Decoration]) → NodeView>\n// Allows you to pass custom rendering and behavior logic for nodes\n// and marks. Should map node and mark names to constructor\n// functions that produce a [`NodeView`](#view.NodeView) object\n// implementing the node's display behavior. For nodes, the third\n// argument `getPos` is a function that can be called to get the\n// node's current position, which can be useful when creating\n// transactions to update it. For marks, the third argument is a\n// boolean that indicates whether the mark's content is inline.\n//\n// `decorations` is an array of node or inline decorations that are\n// active around the node. They are automatically drawn in the\n// normal way, and you will usually just want to ignore this, but\n// they can also be used as a way to provide context information to\n// the node view without adding it to the document itself.\n//\n// clipboardSerializer:: ?DOMSerializer\n// The DOM serializer to use when putting content onto the\n// clipboard. If not given, the result of\n// [`DOMSerializer.fromSchema`](#model.DOMSerializer^fromSchema)\n// will be used.\n//\n// clipboardTextSerializer:: ?(Slice) → string\n// A function that will be called to get the text for the current\n// selection when copying text to the clipboard. By default, the\n// editor will use [`textBetween`](#model.Node.textBetween) on the\n// selected range.\n//\n// decorations:: ?(state: EditorState) → ?DecorationSet\n// A set of [document decorations](#view.Decoration) to show in the\n// view.\n//\n// editable:: ?(state: EditorState) → bool\n// When this returns false, the content of the view is not directly\n// editable.\n//\n// attributes:: ?union, (EditorState) → ?Object>\n// Control the DOM attributes of the editable element. May be either\n// an object or a function going from an editor state to an object.\n// By default, the element will get a class `\"ProseMirror\"`, and\n// will have its `contentEditable` attribute determined by the\n// [`editable` prop](#view.EditorProps.editable). Additional classes\n// provided here will be added to the class. For other attributes,\n// the value provided first (as in\n// [`someProp`](#view.EditorView.someProp)) will be used.\n//\n// scrollThreshold:: ?union\n// Determines the distance (in pixels) between the cursor and the\n// end of the visible viewport at which point, when scrolling the\n// cursor into view, scrolling takes place. Defaults to 0.\n//\n// scrollMargin:: ?union\n// Determines the extra space (in pixels) that is left above or\n// below the cursor when it is scrolled into view. Defaults to 5.\n\n// DirectEditorProps:: interface extends EditorProps\n//\n// The props object given directly to the editor view supports two\n// fields that can't be used in plugins:\n//\n// state:: EditorState\n// The current state of the editor.\n//\n// dispatchTransaction:: ?(tr: Transaction)\n// The callback over which to send transactions (state updates)\n// produced by the view. If you specify this, you probably want to\n// make sure this ends up calling the view's\n// [`updateState`](#view.EditorView.updateState) method with a new\n// state that has the transaction\n// [applied](#state.EditorState.apply). The callback will be bound to have\n// the view instance as its `this` binding.\n"],"names":["const","let","browser","pos","box","rect","target","desc","search","j","super","DOMSerializer","this","Fragment","Mark","TextSelection","name","i","child","Selection","NodeSelection","next","DOMParser","anchor","tr","sel","move","Slice","d","result","dropPoint","p","prototypeAccessors","span","from","prop","dom"],"mappings":"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"} \ No newline at end of file diff --git a/packages/tiptap/node_modules/prosemirror-view/package.json b/packages/tiptap/node_modules/prosemirror-view/package.json new file mode 100644 index 0000000000..87cdc8cbdc --- /dev/null +++ b/packages/tiptap/node_modules/prosemirror-view/package.json @@ -0,0 +1,40 @@ +{ + "name": "prosemirror-view", + "version": "1.13.7", + "description": "ProseMirror's view component", + "main": "dist/index.js", + "module": "dist/index.es.js", + "style": "style/prosemirror.css", + "license": "MIT", + "maintainers": [ + { + "name": "Marijn Haverbeke", + "email": "marijnh@gmail.com", + "web": "http://marijnhaverbeke.nl" + } + ], + "repository": { + "type": "git", + "url": "git://github.com/prosemirror/prosemirror-view.git" + }, + "dependencies": { + "prosemirror-model": "^1.1.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.1.0" + }, + "devDependencies": { + "ist": "^1.0.0", + "mocha": "^3.0.2", + "moduleserve": "^0.7.0", + "prosemirror-test-builder": "^1.0.0", + "rollup": "^1.26.3", + "@rollup/plugin-buble": "^0.20.0" + }, + "scripts": { + "test": "FIXME autorun browser tests", + "test-server": "node test/link-mocha-css.js && moduleserve test --port 8090", + "build": "rollup -c", + "watch": "rollup -c -w", + "prepare": "npm run build" + } +} diff --git a/packages/tiptap/node_modules/prosemirror-view/rollup.config.js b/packages/tiptap/node_modules/prosemirror-view/rollup.config.js new file mode 100644 index 0000000000..156b12a278 --- /dev/null +++ b/packages/tiptap/node_modules/prosemirror-view/rollup.config.js @@ -0,0 +1,14 @@ +module.exports = { + input: './src/index.js', + output: [{ + file: 'dist/index.js', + format: 'cjs', + sourcemap: true + }, { + file: 'dist/index.es.js', + format: 'es', + sourcemap: true + }], + plugins: [require('@rollup/plugin-buble')()], + external(id) { return !/^[\.\/]/.test(id) } +} diff --git a/packages/tiptap/node_modules/prosemirror-view/src/README.md b/packages/tiptap/node_modules/prosemirror-view/src/README.md new file mode 100644 index 0000000000..1503890d36 --- /dev/null +++ b/packages/tiptap/node_modules/prosemirror-view/src/README.md @@ -0,0 +1,26 @@ +ProseMirror's view module displays a given [editor +state](#state.EditorState) in the DOM, and handles user events. + +Make sure you load `style/prosemirror.css` as a stylesheet when using +this module. + +@EditorView + +### Props + +@EditorProps + +@DirectEditorProps + +@NodeView + +### Decorations + +Decorations make it possible to influence the way the document is +drawn, without actually changing the document. + +@Decoration + +@DecorationAttrs + +@DecorationSet diff --git a/packages/tiptap/node_modules/prosemirror-view/src/browser.js b/packages/tiptap/node_modules/prosemirror-view/src/browser.js new file mode 100644 index 0000000000..0cfcbf20a7 --- /dev/null +++ b/packages/tiptap/node_modules/prosemirror-view/src/browser.js @@ -0,0 +1,22 @@ +const result = {} +export default result + +if (typeof navigator != "undefined" && typeof document != "undefined") { + const ie_edge = /Edge\/(\d+)/.exec(navigator.userAgent) + const ie_upto10 = /MSIE \d/.test(navigator.userAgent) + const ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent) + + result.mac = /Mac/.test(navigator.platform) + let ie = result.ie = !!(ie_upto10 || ie_11up || ie_edge) + result.ie_version = ie_upto10 ? document.documentMode || 6 : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : null + result.gecko = !ie && /gecko\/(\d+)/i.test(navigator.userAgent) + result.gecko_version = result.gecko && +(/Firefox\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1] + let chrome = !ie && /Chrome\/(\d+)/.exec(navigator.userAgent) + result.chrome = !!chrome + result.chrome_version = chrome && +chrome[1] + result.ios = !ie && /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent) + result.android = /Android \d/.test(navigator.userAgent) + result.webkit = !ie && 'WebkitAppearance' in document.documentElement.style + result.safari = /Apple Computer/.test(navigator.vendor) + result.webkit_version = result.webkit && +(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1] +} diff --git a/packages/tiptap/node_modules/prosemirror-view/src/capturekeys.js b/packages/tiptap/node_modules/prosemirror-view/src/capturekeys.js new file mode 100644 index 0000000000..2e70e76b5e --- /dev/null +++ b/packages/tiptap/node_modules/prosemirror-view/src/capturekeys.js @@ -0,0 +1,262 @@ +import {Selection, NodeSelection, TextSelection} from "prosemirror-state" +import browser from "./browser" +import {domIndex, selectionCollapsed} from "./dom" + +function moveSelectionBlock(state, dir) { + let {$anchor, $head} = state.selection + let $side = dir > 0 ? $anchor.max($head) : $anchor.min($head) + let $start = !$side.parent.inlineContent ? $side : $side.depth ? state.doc.resolve(dir > 0 ? $side.after() : $side.before()) : null + return $start && Selection.findFrom($start, dir) +} + +function apply(view, sel) { + view.dispatch(view.state.tr.setSelection(sel).scrollIntoView()) + return true +} + +function selectHorizontally(view, dir, mods) { + let sel = view.state.selection + if (sel instanceof TextSelection) { + if (!sel.empty || mods.indexOf("s") > -1) { + return false + } else if (view.endOfTextblock(dir > 0 ? "right" : "left")) { + let next = moveSelectionBlock(view.state, dir) + if (next && (next instanceof NodeSelection)) return apply(view, next) + return false + } else { + let $head = sel.$head, node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter, desc + if (!node || node.isText) return false + let nodePos = dir < 0 ? $head.pos - node.nodeSize : $head.pos + if (!(node.isAtom || (desc = view.docView.descAt(nodePos)) && !desc.contentDOM)) return false + if (NodeSelection.isSelectable(node)) { + return apply(view, new NodeSelection(dir < 0 ? view.state.doc.resolve($head.pos - node.nodeSize) : $head)) + } else if (browser.webkit) { + // Chrome and Safari will introduce extra pointless cursor + // positions around inline uneditable nodes, so we have to + // take over and move the cursor past them (#937) + return apply(view, new TextSelection(view.state.doc.resolve(dir < 0 ? nodePos : nodePos + node.nodeSize))) + } else { + return false + } + } + } else if (sel instanceof NodeSelection && sel.node.isInline) { + return apply(view, new TextSelection(dir > 0 ? sel.$to : sel.$from)) + } else { + let next = moveSelectionBlock(view.state, dir) + if (next) return apply(view, next) + return false + } +} + +function nodeLen(node) { + return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length +} + +function isIgnorable(dom) { + let desc = dom.pmViewDesc + return desc && desc.size == 0 && (dom.nextSibling || dom.nodeName != "BR") +} + +// Make sure the cursor isn't directly after one or more ignored +// nodes, which will confuse the browser's cursor motion logic. +function skipIgnoredNodesLeft(view) { + let sel = view.root.getSelection() + let node = sel.focusNode, offset = sel.focusOffset + if (!node) return + let moveNode, moveOffset, force = false + // Gecko will do odd things when the selection is directly in front + // of a non-editable node, so in that case, move it into the next + // node if possible. Issue prosemirror/prosemirror#832. + if (browser.gecko && node.nodeType == 1 && offset < nodeLen(node) && isIgnorable(node.childNodes[offset])) force = true + for (;;) { + if (offset > 0) { + if (node.nodeType != 1) { + break + } else { + let before = node.childNodes[offset - 1] + if (isIgnorable(before)) { + moveNode = node + moveOffset = --offset + } else if (before.nodeType == 3) { + node = before + offset = node.nodeValue.length + } else break + } + } else if (isBlockNode(node)) { + break + } else { + let prev = node.previousSibling + while (prev && isIgnorable(prev)) { + moveNode = node.parentNode + moveOffset = domIndex(prev) + prev = prev.previousSibling + } + if (!prev) { + node = node.parentNode + if (node == view.dom) break + offset = 0 + } else { + node = prev + offset = nodeLen(node) + } + } + } + if (force) setSelFocus(view, sel, node, offset) + else if (moveNode) setSelFocus(view, sel, moveNode, moveOffset) +} + +// Make sure the cursor isn't directly before one or more ignored +// nodes. +function skipIgnoredNodesRight(view) { + let sel = view.root.getSelection() + let node = sel.focusNode, offset = sel.focusOffset + if (!node) return + let len = nodeLen(node) + let moveNode, moveOffset + for (;;) { + if (offset < len) { + if (node.nodeType != 1) break + let after = node.childNodes[offset] + if (isIgnorable(after)) { + moveNode = node + moveOffset = ++offset + } + else break + } else if (isBlockNode(node)) { + break + } else { + let next = node.nextSibling + while (next && isIgnorable(next)) { + moveNode = next.parentNode + moveOffset = domIndex(next) + 1 + next = next.nextSibling + } + if (!next) { + node = node.parentNode + if (node == view.dom) break + offset = len = 0 + } else { + node = next + offset = 0 + len = nodeLen(node) + } + } + } + if (moveNode) setSelFocus(view, sel, moveNode, moveOffset) +} + +function isBlockNode(dom) { + let desc = dom.pmViewDesc + return desc && desc.node && desc.node.isBlock +} + +function setSelFocus(view, sel, node, offset) { + if (selectionCollapsed(sel)) { + let range = document.createRange() + range.setEnd(node, offset) + range.setStart(node, offset) + sel.removeAllRanges() + sel.addRange(range) + } else if (sel.extend) { + sel.extend(node, offset) + } + view.domObserver.setCurSelection() +} + +// : (EditorState, number) +// Check whether vertical selection motion would involve node +// selections. If so, apply it (if not, the result is left to the +// browser) +function selectVertically(view, dir, mods) { + let sel = view.state.selection + if (sel instanceof TextSelection && !sel.empty || mods.indexOf("s") > -1) return false + let {$from, $to} = sel + + if (!$from.parent.inlineContent || view.endOfTextblock(dir < 0 ? "up" : "down")) { + let next = moveSelectionBlock(view.state, dir) + if (next && (next instanceof NodeSelection)) + return apply(view, next) + } + if (!$from.parent.inlineContent) { + let beyond = Selection.findFrom(dir < 0 ? $from : $to, dir) + return beyond ? apply(view, beyond) : true + } + return false +} + +function stopNativeHorizontalDelete(view, dir) { + if (!(view.state.selection instanceof TextSelection)) return true + let {$head, $anchor, empty} = view.state.selection + if (!$head.sameParent($anchor)) return true + if (!empty) return false + if (view.endOfTextblock(dir > 0 ? "forward" : "backward")) return true + let nextNode = !$head.textOffset && (dir < 0 ? $head.nodeBefore : $head.nodeAfter) + if (nextNode && !nextNode.isText) { + let tr = view.state.tr + if (dir < 0) tr.delete($head.pos - nextNode.nodeSize, $head.pos) + else tr.delete($head.pos, $head.pos + nextNode.nodeSize) + view.dispatch(tr) + return true + } + return false +} + +function switchEditable(view, node, state) { + view.domObserver.stop() + node.contentEditable = state + view.domObserver.start() +} + +// Issue #867 / https://bugs.chromium.org/p/chromium/issues/detail?id=903821 +// In which Chrome does really wrong things when the down arrow is +// pressed when the cursor is directly at the start of a textblock and +// has an uneditable node after it +function chromeDownArrowBug(view) { + if (!browser.chrome || view.state.selection.$head.parentOffset > 0) return + let {focusNode, focusOffset} = view.root.getSelection() + if (focusNode && focusNode.nodeType == 1 && focusOffset == 0 && + focusNode.firstChild && focusNode.firstChild.contentEditable == "false") { + let child = focusNode.firstChild + switchEditable(view, child, true) + setTimeout(() => switchEditable(view, child, false), 20) + } +} + +// A backdrop key mapping used to make sure we always suppress keys +// that have a dangerous default effect, even if the commands they are +// bound to return false, and to make sure that cursor-motion keys +// find a cursor (as opposed to a node selection) when pressed. For +// cursor-motion keys, the code in the handlers also takes care of +// block selections. + +function getMods(event) { + let result = "" + if (event.ctrlKey) result += "c" + if (event.metaKey) result += "m" + if (event.altKey) result += "a" + if (event.shiftKey) result += "s" + return result +} + +export function captureKeyDown(view, event) { + let code = event.keyCode, mods = getMods(event) + if (code == 8 || (browser.mac && code == 72 && mods == "c")) { // Backspace, Ctrl-h on Mac + return stopNativeHorizontalDelete(view, -1) || skipIgnoredNodesLeft(view) + } else if (code == 46 || (browser.mac && code == 68 && mods == "c")) { // Delete, Ctrl-d on Mac + return stopNativeHorizontalDelete(view, 1) || skipIgnoredNodesRight(view) + } else if (code == 13 || code == 27) { // Enter, Esc + return true + } else if (code == 37) { // Left arrow + return selectHorizontally(view, -1, mods) || skipIgnoredNodesLeft(view) + } else if (code == 39) { // Right arrow + return selectHorizontally(view, 1, mods) || skipIgnoredNodesRight(view) + } else if (code == 38) { // Up arrow + return selectVertically(view, -1, mods) || skipIgnoredNodesLeft(view) + } else if (code == 40) { // Down arrow + return chromeDownArrowBug(view) || selectVertically(view, 1, mods) || skipIgnoredNodesRight(view) + } else if (mods == (browser.mac ? "m" : "c") && + (code == 66 || code == 73 || code == 89 || code == 90)) { // Mod-[biyz] + return true + } + return false +} diff --git a/packages/tiptap/node_modules/prosemirror-view/src/clipboard.js b/packages/tiptap/node_modules/prosemirror-view/src/clipboard.js new file mode 100644 index 0000000000..b13e091a7e --- /dev/null +++ b/packages/tiptap/node_modules/prosemirror-view/src/clipboard.js @@ -0,0 +1,187 @@ +import {Slice, Fragment, DOMParser, DOMSerializer} from "prosemirror-model" + +export function serializeForClipboard(view, slice) { + let context = [], {content, openStart, openEnd} = slice + while (openStart > 1 && openEnd > 1 && content.childCount == 1 && content.firstChild.childCount == 1) { + openStart-- + openEnd-- + let node = content.firstChild + context.push(node.type.name, node.type.hasRequiredAttrs() ? node.attrs : null) + content = node.content + } + + let serializer = view.someProp("clipboardSerializer") || DOMSerializer.fromSchema(view.state.schema) + let doc = detachedDoc(), wrap = doc.createElement("div") + wrap.appendChild(serializer.serializeFragment(content, {document: doc})) + + let firstChild = wrap.firstChild, needsWrap + while (firstChild && firstChild.nodeType == 1 && (needsWrap = wrapMap[firstChild.nodeName.toLowerCase()])) { + for (let i = needsWrap.length - 1; i >= 0; i--) { + let wrapper = doc.createElement(needsWrap[i]) + while (wrap.firstChild) wrapper.appendChild(wrap.firstChild) + wrap.appendChild(wrapper) + } + firstChild = wrap.firstChild + } + + if (firstChild && firstChild.nodeType == 1) + firstChild.setAttribute("data-pm-slice", `${openStart} ${openEnd} ${JSON.stringify(context)}`) + + let text = view.someProp("clipboardTextSerializer", f => f(slice)) || + slice.content.textBetween(0, slice.content.size, "\n\n") + + return {dom: wrap, text} +} + +// : (EditorView, string, string, ?bool, ResolvedPos) → ?Slice +// Read a slice of content from the clipboard (or drop data). +export function parseFromClipboard(view, text, html, plainText, $context) { + let dom, inCode = $context.parent.type.spec.code, slice + if (!html && !text) return null + let asText = text && (plainText || inCode || !html) + if (asText) { + view.someProp("transformPastedText", f => { text = f(text) }) + if (inCode) return new Slice(Fragment.from(view.state.schema.text(text)), 0, 0) + let parsed = view.someProp("clipboardTextParser", f => f(text, $context)) + if (parsed) { + slice = parsed + } else { + dom = document.createElement("div") + text.trim().split(/(?:\r\n?|\n)+/).forEach(block => { + dom.appendChild(document.createElement("p")).textContent = block + }) + } + } else { + view.someProp("transformPastedHTML", f => { html = f(html) }) + dom = readHTML(html) + } + + let contextNode = dom && dom.querySelector("[data-pm-slice]") + let sliceData = contextNode && /^(\d+) (\d+) (.*)/.exec(contextNode.getAttribute("data-pm-slice")) + if (!slice) { + let parser = view.someProp("clipboardParser") || view.someProp("domParser") || DOMParser.fromSchema(view.state.schema) + slice = parser.parseSlice(dom, {preserveWhitespace: !!(asText || sliceData), context: $context}) + } + if (sliceData) + slice = addContext(closeSlice(slice, +sliceData[1], +sliceData[2]), sliceData[3]) + else // HTML wasn't created by ProseMirror. Make sure top-level siblings are coherent + slice = Slice.maxOpen(normalizeSiblings(slice.content, $context), false) + + view.someProp("transformPasted", f => { slice = f(slice) }) + return slice +} + +// Takes a slice parsed with parseSlice, which means there hasn't been +// any content-expression checking done on the top nodes, tries to +// find a parent node in the current context that might fit the nodes, +// and if successful, rebuilds the slice so that it fits into that parent. +// +// This addresses the problem that Transform.replace expects a +// coherent slice, and will fail to place a set of siblings that don't +// fit anywhere in the schema. +function normalizeSiblings(fragment, $context) { + if (fragment.childCount < 2) return fragment + for (let d = $context.depth; d >= 0; d--) { + let parent = $context.node(d) + let match = parent.contentMatchAt($context.index(d)) + let lastWrap, result = [] + fragment.forEach(node => { + if (!result) return + let wrap = match.findWrapping(node.type), inLast + if (!wrap) return result = null + if (inLast = result.length && lastWrap.length && addToSibling(wrap, lastWrap, node, result[result.length - 1], 0)) { + result[result.length - 1] = inLast + } else { + if (result.length) result[result.length - 1] = closeRight(result[result.length - 1], lastWrap.length) + let wrapped = withWrappers(node, wrap) + result.push(wrapped) + match = match.matchType(wrapped.type, wrapped.attrs) + lastWrap = wrap + } + }) + if (result) return Fragment.from(result) + } + return fragment +} + +function withWrappers(node, wrap, from = 0) { + for (let i = wrap.length - 1; i >= from; i--) + node = wrap[i].create(null, Fragment.from(node)) + return node +} + +// Used to group adjacent nodes wrapped in similar parents by +// normalizeSiblings into the same parent node +function addToSibling(wrap, lastWrap, node, sibling, depth) { + if (depth < wrap.length && depth < lastWrap.length && wrap[depth] == lastWrap[depth]) { + let inner = addToSibling(wrap, lastWrap, node, sibling.lastChild, depth + 1) + if (inner) return sibling.copy(sibling.content.replaceChild(sibling.childCount - 1, inner)) + let match = sibling.contentMatchAt(sibling.childCount) + if (match.matchType(depth == wrap.length - 1 ? node.type : wrap[depth + 1])) + return sibling.copy(sibling.content.append(Fragment.from(withWrappers(node, wrap, depth + 1)))) + } +} + +function closeRight(node, depth) { + if (depth == 0) return node + let fragment = node.content.replaceChild(node.childCount - 1, closeRight(node.lastChild, depth - 1)) + let fill = node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true) + return node.copy(fragment.append(fill)) +} + +function closeRange(fragment, side, from, to, depth, openEnd) { + let node = side < 0 ? fragment.firstChild : fragment.lastChild, inner = node.content + if (depth < to - 1) inner = closeRange(inner, side, from, to, depth + 1, openEnd) + if (depth >= from) + inner = side < 0 ? node.contentMatchAt(0).fillBefore(inner, fragment.childCount > 1 || openEnd <= depth).append(inner) + : inner.append(node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true)) + return fragment.replaceChild(side < 0 ? 0 : fragment.childCount - 1, node.copy(inner)) +} + +function closeSlice(slice, openStart, openEnd) { + if (openStart < slice.openStart) + slice = new Slice(closeRange(slice.content, -1, openStart, slice.openStart, 0, slice.openEnd), openStart, slice.openEnd) + if (openEnd < slice.openEnd) + slice = new Slice(closeRange(slice.content, 1, openEnd, slice.openEnd, 0, 0), slice.openStart, openEnd) + return slice +} + +// Trick from jQuery -- some elements must be wrapped in other +// elements for innerHTML to work. I.e. if you do `div.innerHTML = +// ".."` the table cells are ignored. +const wrapMap = {thead: ["table"], colgroup: ["table"], col: ["table", "colgroup"], + tr: ["table", "tbody"], td: ["table", "tbody", "tr"], th: ["table", "tbody", "tr"]} + +let _detachedDoc = null +function detachedDoc() { + return _detachedDoc || (_detachedDoc = document.implementation.createHTMLDocument("title")) +} + +function readHTML(html) { + let metas = /(\s*]*>)*/.exec(html) + if (metas) html = html.slice(metas[0].length) + let elt = detachedDoc().createElement("div") + let firstTag = /(?:]*>)*<([a-z][^>\s]+)/i.exec(html), wrap, depth = 0 + if (wrap = firstTag && wrapMap[firstTag[1].toLowerCase()]) { + html = wrap.map(n => "<" + n + ">").join("") + html + wrap.map(n => "").reverse().join("") + depth = wrap.length + } + elt.innerHTML = html + for (let i = 0; i < depth; i++) elt = elt.firstChild + return elt +} + +function addContext(slice, context) { + if (!slice.size) return slice + let schema = slice.content.firstChild.type.schema, array + try { array = JSON.parse(context) } + catch(e) { return slice } + let {content, openStart, openEnd} = slice + for (let i = array.length - 2; i >= 0; i -= 2) { + let type = schema.nodes[array[i]] + if (!type || type.hasRequiredAttrs()) break + content = Fragment.from(type.create(array[i + 1], content)) + openStart++; openEnd++ + } + return new Slice(content, openStart, openEnd) +} diff --git a/packages/tiptap/node_modules/prosemirror-view/src/decoration.js b/packages/tiptap/node_modules/prosemirror-view/src/decoration.js new file mode 100644 index 0000000000..2c5796aa25 --- /dev/null +++ b/packages/tiptap/node_modules/prosemirror-view/src/decoration.js @@ -0,0 +1,669 @@ +function compareObjs(a, b) { + if (a == b) return true + for (let p in a) if (a[p] !== b[p]) return false + for (let p in b) if (!(p in a)) return false + return true +} + +class WidgetType { + constructor(toDOM, spec) { + this.spec = spec || noSpec + this.side = this.spec.side || 0 + this.toDOM = toDOM + } + + map(mapping, span, offset, oldOffset) { + let {pos, deleted} = mapping.mapResult(span.from + oldOffset, this.side < 0 ? -1 : 1) + return deleted ? null : new Decoration(pos - offset, pos - offset, this) + } + + valid() { return true } + + eq(other) { + return this == other || + (other instanceof WidgetType && + (this.spec.key && this.spec.key == other.spec.key || + this.toDOM == other.toDOM && compareObjs(this.spec, other.spec))) + } +} + +class InlineType { + constructor(attrs, spec) { + this.spec = spec || noSpec + this.attrs = attrs + } + + map(mapping, span, offset, oldOffset) { + let from = mapping.map(span.from + oldOffset, this.spec.inclusiveStart ? -1 : 1) - offset + let to = mapping.map(span.to + oldOffset, this.spec.inclusiveEnd ? 1 : -1) - offset + return from >= to ? null : new Decoration(from, to, this) + } + + valid(_, span) { return span.from < span.to } + + eq(other) { + return this == other || + (other instanceof InlineType && compareObjs(this.attrs, other.attrs) && + compareObjs(this.spec, other.spec)) + } + + static is(span) { return span.type instanceof InlineType } +} + +class NodeType { + constructor(attrs, spec) { + this.spec = spec || noSpec + this.attrs = attrs + } + + map(mapping, span, offset, oldOffset) { + let from = mapping.mapResult(span.from + oldOffset, 1) + if (from.deleted) return null + let to = mapping.mapResult(span.to + oldOffset, -1) + if (to.deleted || to.pos <= from.pos) return null + return new Decoration(from.pos - offset, to.pos - offset, this) + } + + valid(node, span) { + let {index, offset} = node.content.findIndex(span.from) + return offset == span.from && offset + node.child(index).nodeSize == span.to + } + + eq(other) { + return this == other || + (other instanceof NodeType && compareObjs(this.attrs, other.attrs) && + compareObjs(this.spec, other.spec)) + } +} + +// ::- Decoration objects can be provided to the view through the +// [`decorations` prop](#view.EditorProps.decorations). They come in +// several variants—see the static members of this class for details. +export class Decoration { + constructor(from, to, type) { + // :: number + // The start position of the decoration. + this.from = from + // :: number + // The end position. Will be the same as `from` for [widget + // decorations](#view.Decoration^widget). + this.to = to + this.type = type + } + + copy(from, to) { + return new Decoration(from, to, this.type) + } + + eq(other) { + return this.type.eq(other.type) && this.from == other.from && this.to == other.to + } + + map(mapping, offset, oldOffset) { + return this.type.map(mapping, this, offset, oldOffset) + } + + // :: (number, union<(view: EditorView, getPos: () → number) → dom.Node, dom.Node>, ?Object) → Decoration + // Creates a widget decoration, which is a DOM node that's shown in + // the document at the given position. It is recommended that you + // delay rendering the widget by passing a function that will be + // called when the widget is actually drawn in a view, but you can + // also directly pass a DOM node. `getPos` can be used to find the + // widget's current document position. + // + // spec::- These options are supported: + // + // side:: ?number + // Controls which side of the document position this widget is + // associated with. When negative, it is drawn before a cursor + // at its position, and content inserted at that position ends + // up after the widget. When zero (the default) or positive, the + // widget is drawn after the cursor and content inserted there + // ends up before the widget. + // + // When there are multiple widgets at a given position, their + // `side` values determine the order in which they appear. Those + // with lower values appear first. The ordering of widgets with + // the same `side` value is unspecified. + // + // When `marks` is null, `side` also determines the marks that + // the widget is wrapped in—those of the node before when + // negative, those of the node after when positive. + // + // marks:: ?[Mark] + // The precise set of marks to draw around the widget. + // + // stopEvent:: ?(event: dom.Event) → bool + // Can be used to control which DOM events, when they bubble out + // of this widget, the editor view should ignore. + // + // key:: ?string + // When comparing decorations of this type (in order to decide + // whether it needs to be redrawn), ProseMirror will by default + // compare the widget DOM node by identity. If you pass a key, + // that key will be compared instead, which can be useful when + // you generate decorations on the fly and don't want to store + // and reuse DOM nodes. Make sure that any widgets with the same + // key are interchangeable—if widgets differ in, for example, + // the behavior of some event handler, they should get + // different keys. + static widget(pos, toDOM, spec) { + return new Decoration(pos, pos, new WidgetType(toDOM, spec)) + } + + // :: (number, number, DecorationAttrs, ?Object) → Decoration + // Creates an inline decoration, which adds the given attributes to + // each inline node between `from` and `to`. + // + // spec::- These options are recognized: + // + // inclusiveStart:: ?bool + // Determines how the left side of the decoration is + // [mapped](#transform.Position_Mapping) when content is + // inserted directly at that position. By default, the decoration + // won't include the new content, but you can set this to `true` + // to make it inclusive. + // + // inclusiveEnd:: ?bool + // Determines how the right side of the decoration is mapped. + // See + // [`inclusiveStart`](#view.Decoration^inline^spec.inclusiveStart). + static inline(from, to, attrs, spec) { + return new Decoration(from, to, new InlineType(attrs, spec)) + } + + // :: (number, number, DecorationAttrs, ?Object) → Decoration + // Creates a node decoration. `from` and `to` should point precisely + // before and after a node in the document. That node, and only that + // node, will receive the given attributes. + // + // spec::- + // + // Optional information to store with the decoration. It + // is also used when comparing decorators for equality. + static node(from, to, attrs, spec) { + return new Decoration(from, to, new NodeType(attrs, spec)) + } + + // :: Object + // The spec provided when creating this decoration. Can be useful + // if you've stored extra information in that object. + get spec() { return this.type.spec } +} + +// DecorationAttrs:: interface +// A set of attributes to add to a decorated node. Most properties +// simply directly correspond to DOM attributes of the same name, +// which will be set to the property's value. These are exceptions: +// +// class:: ?string +// A CSS class name or a space-separated set of class names to be +// _added_ to the classes that the node already had. +// +// style:: ?string +// A string of CSS to be _added_ to the node's existing `style` property. +// +// nodeName:: ?string +// When non-null, the target node is wrapped in a DOM element of +// this type (and the other attributes are applied to this element). + +const none = [], noSpec = {} + +// ::- A collection of [decorations](#view.Decoration), organized in +// such a way that the drawing algorithm can efficiently use and +// compare them. This is a persistent data structure—it is not +// modified, updates create a new value. +export class DecorationSet { + constructor(local, children) { + this.local = local && local.length ? local : none + this.children = children && children.length ? children : none + } + + // :: (Node, [Decoration]) → DecorationSet + // Create a set of decorations, using the structure of the given + // document. + static create(doc, decorations) { + return decorations.length ? buildTree(decorations, doc, 0, noSpec) : empty + } + + // :: (?number, ?number, ?(spec: Object) → bool) → [Decoration] + // Find all decorations in this set which touch the given range + // (including decorations that start or end directly at the + // boundaries) and match the given predicate on their spec. When + // `start` and `end` are omitted, all decorations in the set are + // considered. When `predicate` isn't given, all decorations are + // assumed to match. + find(start, end, predicate) { + let result = [] + this.findInner(start == null ? 0 : start, end == null ? 1e9 : end, result, 0, predicate) + return result + } + + findInner(start, end, result, offset, predicate) { + for (let i = 0; i < this.local.length; i++) { + let span = this.local[i] + if (span.from <= end && span.to >= start && (!predicate || predicate(span.spec))) + result.push(span.copy(span.from + offset, span.to + offset)) + } + for (let i = 0; i < this.children.length; i += 3) { + if (this.children[i] < end && this.children[i + 1] > start) { + let childOff = this.children[i] + 1 + this.children[i + 2].findInner(start - childOff, end - childOff, result, offset + childOff, predicate) + } + } + } + + // :: (Mapping, Node, ?Object) → DecorationSet + // Map the set of decorations in response to a change in the + // document. + // + // options::- An optional set of options. + // + // onRemove:: ?(decorationSpec: Object) + // When given, this function will be called for each decoration + // that gets dropped as a result of the mapping, passing the + // spec of that decoration. + map(mapping, doc, options) { + if (this == empty || mapping.maps.length == 0) return this + return this.mapInner(mapping, doc, 0, 0, options || noSpec) + } + + mapInner(mapping, node, offset, oldOffset, options) { + let newLocal + for (let i = 0; i < this.local.length; i++) { + let mapped = this.local[i].map(mapping, offset, oldOffset) + if (mapped && mapped.type.valid(node, mapped)) (newLocal || (newLocal = [])).push(mapped) + else if (options.onRemove) options.onRemove(this.local[i].spec) + } + + if (this.children.length) + return mapChildren(this.children, newLocal, mapping, node, offset, oldOffset, options) + else + return newLocal ? new DecorationSet(newLocal.sort(byPos)) : empty + } + + // :: (Node, [Decoration]) → DecorationSet + // Add the given array of decorations to the ones in the set, + // producing a new set. Needs access to the current document to + // create the appropriate tree structure. + add(doc, decorations) { + if (!decorations.length) return this + if (this == empty) return DecorationSet.create(doc, decorations) + return this.addInner(doc, decorations, 0) + } + + addInner(doc, decorations, offset) { + let children, childIndex = 0 + doc.forEach((childNode, childOffset) => { + let baseOffset = childOffset + offset, found + if (!(found = takeSpansForNode(decorations, childNode, baseOffset))) return + + if (!children) children = this.children.slice() + while (childIndex < children.length && children[childIndex] < childOffset) childIndex += 3 + if (children[childIndex] == childOffset) + children[childIndex + 2] = children[childIndex + 2].addInner(childNode, found, baseOffset + 1) + else + children.splice(childIndex, 0, childOffset, childOffset + childNode.nodeSize, buildTree(found, childNode, baseOffset + 1, noSpec)) + childIndex += 3 + }) + + let local = moveSpans(childIndex ? withoutNulls(decorations) : decorations, -offset) + return new DecorationSet(local.length ? this.local.concat(local).sort(byPos) : this.local, + children || this.children) + } + + // :: ([Decoration]) → DecorationSet + // Create a new set that contains the decorations in this set, minus + // the ones in the given array. + remove(decorations) { + if (decorations.length == 0 || this == empty) return this + return this.removeInner(decorations, 0) + } + + removeInner(decorations, offset) { + let children = this.children, local = this.local + for (let i = 0; i < children.length; i += 3) { + let found, from = children[i] + offset, to = children[i + 1] + offset + for (let j = 0, span; j < decorations.length; j++) if (span = decorations[j]) { + if (span.from > from && span.to < to) { + decorations[j] = null + ;(found || (found = [])).push(span) + } + } + if (!found) continue + if (children == this.children) children = this.children.slice() + let removed = children[i + 2].removeInner(found, from + 1) + if (removed != empty) { + children[i + 2] = removed + } else { + children.splice(i, 3) + i -= 3 + } + } + if (local.length) for (let i = 0, span; i < decorations.length; i++) if (span = decorations[i]) { + for (let j = 0; j < local.length; j++) if (local[j].type.eq(span.type)) { + if (local == this.local) local = this.local.slice() + local.splice(j--, 1) + } + } + if (children == this.children && local == this.local) return this + return local.length || children.length ? new DecorationSet(local, children) : empty + } + + forChild(offset, node) { + if (this == empty) return this + if (node.isLeaf) return DecorationSet.empty + + let child, local + for (let i = 0; i < this.children.length; i += 3) if (this.children[i] >= offset) { + if (this.children[i] == offset) child = this.children[i + 2] + break + } + let start = offset + 1, end = start + node.content.size + for (let i = 0; i < this.local.length; i++) { + let dec = this.local[i] + if (dec.from < end && dec.to > start && (dec.type instanceof InlineType)) { + let from = Math.max(start, dec.from) - start, to = Math.min(end, dec.to) - start + if (from < to) (local || (local = [])).push(dec.copy(from, to)) + } + } + if (local) { + let localSet = new DecorationSet(local.sort(byPos)) + return child ? new DecorationGroup([localSet, child]) : localSet + } + return child || empty + } + + eq(other) { + if (this == other) return true + if (!(other instanceof DecorationSet) || + this.local.length != other.local.length || + this.children.length != other.children.length) return false + for (let i = 0; i < this.local.length; i++) + if (!this.local[i].eq(other.local[i])) return false + for (let i = 0; i < this.children.length; i += 3) + if (this.children[i] != other.children[i] || + this.children[i + 1] != other.children[i + 1] || + !this.children[i + 2].eq(other.children[i + 2])) return false + return true + } + + locals(node) { + return removeOverlap(this.localsInner(node)) + } + + localsInner(node) { + if (this == empty) return none + if (node.inlineContent || !this.local.some(InlineType.is)) return this.local + let result = [] + for (let i = 0; i < this.local.length; i++) { + if (!(this.local[i].type instanceof InlineType)) + result.push(this.local[i]) + } + return result + } +} + +const empty = new DecorationSet() + +// :: DecorationSet +// The empty set of decorations. +DecorationSet.empty = empty + +DecorationSet.removeOverlap = removeOverlap + +// :- An abstraction that allows the code dealing with decorations to +// treat multiple DecorationSet objects as if it were a single object +// with (a subset of) the same interface. +class DecorationGroup { + constructor(members) { + this.members = members + } + + forChild(offset, child) { + if (child.isLeaf) return DecorationSet.empty + let found = [] + for (let i = 0; i < this.members.length; i++) { + let result = this.members[i].forChild(offset, child) + if (result == empty) continue + if (result instanceof DecorationGroup) found = found.concat(result.members) + else found.push(result) + } + return DecorationGroup.from(found) + } + + eq(other) { + if (!(other instanceof DecorationGroup) || + other.members.length != this.members.length) return false + for (let i = 0; i < this.members.length; i++) + if (!this.members[i].eq(other.members[i])) return false + return true + } + + locals(node) { + let result, sorted = true + for (let i = 0; i < this.members.length; i++) { + let locals = this.members[i].localsInner(node) + if (!locals.length) continue + if (!result) { + result = locals + } else { + if (sorted) { + result = result.slice() + sorted = false + } + for (let j = 0; j < locals.length; j++) result.push(locals[j]) + } + } + return result ? removeOverlap(sorted ? result : result.sort(byPos)) : none + } + + // : ([DecorationSet]) → union + // Create a group for the given array of decoration sets, or return + // a single set when possible. + static from(members) { + switch (members.length) { + case 0: return empty + case 1: return members[0] + default: return new DecorationGroup(members) + } + } +} + +function mapChildren(oldChildren, newLocal, mapping, node, offset, oldOffset, options) { + let children = oldChildren.slice() + + // Mark the children that are directly touched by changes, and + // move those that are after the changes. + let shift = (oldStart, oldEnd, newStart, newEnd) => { + for (let i = 0; i < children.length; i += 3) { + let end = children[i + 1], dSize + if (end == -1 || oldStart > end + oldOffset) continue + if (oldEnd >= children[i] + oldOffset) { + children[i + 1] = -1 + } else if (dSize = (newEnd - newStart) - (oldEnd - oldStart) + (oldOffset - offset)) { + children[i] += dSize + children[i + 1] += dSize + } + } + } + for (let i = 0; i < mapping.maps.length; i++) mapping.maps[i].forEach(shift) + + // Find the child nodes that still correspond to a single node, + // recursively call mapInner on them and update their positions. + let mustRebuild = false + for (let i = 0; i < children.length; i += 3) if (children[i + 1] == -1) { // Touched nodes + let from = mapping.map(children[i] + oldOffset), fromLocal = from - offset + if (fromLocal < 0 || fromLocal >= node.content.size) { + mustRebuild = true + continue + } + // Must read oldChildren because children was tagged with -1 + let to = mapping.map(oldChildren[i + 1] + oldOffset, -1), toLocal = to - offset + let {index, offset: childOffset} = node.content.findIndex(fromLocal) + let childNode = node.maybeChild(index) + if (childNode && childOffset == fromLocal && childOffset + childNode.nodeSize == toLocal) { + let mapped = children[i + 2].mapInner(mapping, childNode, from + 1, children[i] + oldOffset + 1, options) + if (mapped != empty) { + children[i] = fromLocal + children[i + 1] = toLocal + children[i + 2] = mapped + } else { + children[i + 1] = -2 + mustRebuild = true + } + } else { + mustRebuild = true + } + } + + // Remaining children must be collected and rebuilt into the appropriate structure + if (mustRebuild) { + let decorations = mapAndGatherRemainingDecorations(children, oldChildren, newLocal || [], mapping, + offset, oldOffset, options) + let built = buildTree(decorations, node, 0, options) + newLocal = built.local + for (let i = 0; i < children.length; i += 3) if (children[i + 1] < 0) { + children.splice(i, 3) + i -= 3 + } + for (let i = 0, j = 0; i < built.children.length; i += 3) { + let from = built.children[i] + while (j < children.length && children[j] < from) j += 3 + children.splice(j, 0, built.children[i], built.children[i + 1], built.children[i + 2]) + } + } + + return new DecorationSet(newLocal && newLocal.sort(byPos), children) +} + +function moveSpans(spans, offset) { + if (!offset || !spans.length) return spans + let result = [] + for (let i = 0; i < spans.length; i++) { + let span = spans[i] + result.push(new Decoration(span.from + offset, span.to + offset, span.type)) + } + return result +} + +function mapAndGatherRemainingDecorations(children, oldChildren, decorations, mapping, offset, oldOffset, options) { + // Gather all decorations from the remaining marked children + function gather(set, oldOffset) { + for (let i = 0; i < set.local.length; i++) { + let mapped = set.local[i].map(mapping, offset, oldOffset) + if (mapped) decorations.push(mapped) + else if (options.onRemove) options.onRemove(set.local[i].spec) + } + for (let i = 0; i < set.children.length; i += 3) + gather(set.children[i + 2], set.children[i] + oldOffset + 1) + } + for (let i = 0; i < children.length; i += 3) if (children[i + 1] == -1) + gather(children[i + 2], oldChildren[i] + oldOffset + 1) + + return decorations +} + +function takeSpansForNode(spans, node, offset) { + if (node.isLeaf) return null + let end = offset + node.nodeSize, found = null + for (let i = 0, span; i < spans.length; i++) { + if ((span = spans[i]) && span.from > offset && span.to < end) { + ;(found || (found = [])).push(span) + spans[i] = null + } + } + return found +} + +function withoutNulls(array) { + let result = [] + for (let i = 0; i < array.length; i++) + if (array[i] != null) result.push(array[i]) + return result +} + +// : ([Decoration], Node, number) → DecorationSet +// Build up a tree that corresponds to a set of decorations. `offset` +// is a base offset that should be subtractet from the `from` and `to` +// positions in the spans (so that we don't have to allocate new spans +// for recursive calls). +function buildTree(spans, node, offset, options) { + let children = [], hasNulls = false + node.forEach((childNode, localStart) => { + let found = takeSpansForNode(spans, childNode, localStart + offset) + if (found) { + hasNulls = true + let subtree = buildTree(found, childNode, offset + localStart + 1, options) + if (subtree != empty) + children.push(localStart, localStart + childNode.nodeSize, subtree) + } + }) + let locals = moveSpans(hasNulls ? withoutNulls(spans) : spans, -offset).sort(byPos) + for (let i = 0; i < locals.length; i++) if (!locals[i].type.valid(node, locals[i])) { + if (options.onRemove) options.onRemove(locals[i].spec) + locals.splice(i--, 1) + } + return locals.length || children.length ? new DecorationSet(locals, children) : empty +} + +// : (Decoration, Decoration) → number +// Used to sort decorations so that ones with a low start position +// come first, and within a set with the same start position, those +// with an smaller end position come first. +function byPos(a, b) { + return a.from - b.from || a.to - b.to +} + +// : ([Decoration]) → [Decoration] +// Scan a sorted array of decorations for partially overlapping spans, +// and split those so that only fully overlapping spans are left (to +// make subsequent rendering easier). Will return the input array if +// no partially overlapping spans are found (the common case). +function removeOverlap(spans) { + let working = spans + for (let i = 0; i < working.length - 1; i++) { + let span = working[i] + if (span.from != span.to) for (let j = i + 1; j < working.length; j++) { + let next = working[j] + if (next.from == span.from) { + if (next.to != span.to) { + if (working == spans) working = spans.slice() + // Followed by a partially overlapping larger span. Split that + // span. + working[j] = next.copy(next.from, span.to) + insertAhead(working, j + 1, next.copy(span.to, next.to)) + } + continue + } else { + if (next.from < span.to) { + if (working == spans) working = spans.slice() + // The end of this one overlaps with a subsequent span. Split + // this one. + working[i] = span.copy(span.from, next.from) + insertAhead(working, j, span.copy(next.from, span.to)) + } + break + } + } + } + return working +} + +function insertAhead(array, i, deco) { + while (i < array.length && byPos(deco, array[i]) > 0) i++ + array.splice(i, 0, deco) +} + +// : (EditorView) → union +// Get the decorations associated with the current props of a view. +export function viewDecorations(view) { + let found = [] + view.someProp("decorations", f => { + let result = f(view.state) + if (result && result != empty) found.push(result) + }) + if (view.cursorWrapper) + found.push(DecorationSet.create(view.state.doc, [view.cursorWrapper.deco])) + return DecorationGroup.from(found) +} diff --git a/packages/tiptap/node_modules/prosemirror-view/src/dom.js b/packages/tiptap/node_modules/prosemirror-view/src/dom.js new file mode 100644 index 0000000000..728f3b883f --- /dev/null +++ b/packages/tiptap/node_modules/prosemirror-view/src/dom.js @@ -0,0 +1,75 @@ +import browser from "./browser" + +export const domIndex = function(node) { + for (var index = 0;; index++) { + node = node.previousSibling + if (!node) return index + } +} + +export const parentNode = function(node) { + let parent = node.parentNode + return parent && parent.nodeType == 11 ? parent.host : parent +} + +export const textRange = function(node, from, to) { + let range = document.createRange() + range.setEnd(node, to == null ? node.nodeValue.length : to) + range.setStart(node, from || 0) + return range +} + +// Scans forward and backward through DOM positions equivalent to the +// given one to see if the two are in the same place (i.e. after a +// text node vs at the end of that text node) +export const isEquivalentPosition = function(node, off, targetNode, targetOff) { + return targetNode && (scanFor(node, off, targetNode, targetOff, -1) || + scanFor(node, off, targetNode, targetOff, 1)) +} + +const atomElements = /^(img|br|input|textarea|hr)$/i + +function scanFor(node, off, targetNode, targetOff, dir) { + for (;;) { + if (node == targetNode && off == targetOff) return true + if (off == (dir < 0 ? 0 : nodeSize(node))) { + let parent = node.parentNode + if (parent.nodeType != 1 || hasBlockDesc(node) || atomElements.test(node.nodeName) || node.contentEditable == "false") + return false + off = domIndex(node) + (dir < 0 ? 0 : 1) + node = parent + } else if (node.nodeType == 1) { + node = node.childNodes[off + (dir < 0 ? -1 : 0)] + off = dir < 0 ? nodeSize(node) : 0 + } else { + return false + } + } +} + +export function nodeSize(node) { + return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length +} + +function hasBlockDesc(dom) { + let desc + for (let cur = dom; cur; cur = cur.parentNode) if (desc = cur.pmViewDesc) break + return desc && desc.node && desc.node.isBlock && (desc.dom == dom || desc.contentDOM == dom) +} + +// Work around Chrome issue https://bugs.chromium.org/p/chromium/issues/detail?id=447523 +// (isCollapsed inappropriately returns true in shadow dom) +export const selectionCollapsed = function(domSel) { + let collapsed = domSel.isCollapsed + if (collapsed && browser.chrome && domSel.rangeCount && !domSel.getRangeAt(0).collapsed) + collapsed = false + return collapsed +} + +export function keyEvent(keyCode, key) { + let event = document.createEvent("Event") + event.initEvent("keydown", true, true) + event.keyCode = keyCode + event.key = event.code = key + return event +} diff --git a/packages/tiptap/node_modules/prosemirror-view/src/domchange.js b/packages/tiptap/node_modules/prosemirror-view/src/domchange.js new file mode 100644 index 0000000000..e1c3af7431 --- /dev/null +++ b/packages/tiptap/node_modules/prosemirror-view/src/domchange.js @@ -0,0 +1,301 @@ +import {Fragment, DOMParser} from "prosemirror-model" +import {Selection, TextSelection} from "prosemirror-state" + +import {selectionBetween, selectionFromDOM, selectionToDOM} from "./selection" +import {selectionCollapsed, keyEvent} from "./dom" +import browser from "./browser" + +// Note that all referencing and parsing is done with the +// start-of-operation selection and document, since that's the one +// that the DOM represents. If any changes came in in the meantime, +// the modification is mapped over those before it is applied, in +// readDOMChange. + +function parseBetween(view, from_, to_) { + let {node: parent, fromOffset, toOffset, from, to} = view.docView.parseRange(from_, to_) + + let domSel = view.root.getSelection(), find = null, anchor = domSel.anchorNode + if (anchor && view.dom.contains(anchor.nodeType == 1 ? anchor : anchor.parentNode)) { + find = [{node: anchor, offset: domSel.anchorOffset}] + if (!selectionCollapsed(domSel)) + find.push({node: domSel.focusNode, offset: domSel.focusOffset}) + } + // Work around issue in Chrome where backspacing sometimes replaces + // the deleted content with a random BR node (issues #799, #831) + if (browser.chrome && view.lastKeyCode === 8) { + for (let off = toOffset; off > fromOffset; off--) { + let node = parent.childNodes[off - 1], desc = node.pmViewDesc + if (node.nodeType == "BR" && !desc) { toOffset = off; break } + if (!desc || desc.size) break + } + } + let startDoc = view.state.doc + let parser = view.someProp("domParser") || DOMParser.fromSchema(view.state.schema) + let $from = startDoc.resolve(from) + + let sel = null, doc = parser.parse(parent, { + topNode: $from.parent, + topMatch: $from.parent.contentMatchAt($from.index()), + topOpen: true, + from: fromOffset, + to: toOffset, + preserveWhitespace: $from.parent.type.spec.code ? "full" : true, + editableContent: true, + findPositions: find, + ruleFromNode, + context: $from + }) + if (find && find[0].pos != null) { + let anchor = find[0].pos, head = find[1] && find[1].pos + if (head == null) head = anchor + sel = {anchor: anchor + from, head: head + from} + } + return {doc, sel, from, to} +} + +function ruleFromNode(dom) { + let desc = dom.pmViewDesc + if (desc) { + return desc.parseRule() + } else if (dom.nodeName == "BR" && dom.parentNode) { + // Safari replaces the list item or table cell with a BR + // directly in the list node (?!) if you delete the last + // character in a list item or table cell (#708, #862) + if (browser.safari && /^(ul|ol)$/i.test(dom.parentNode.nodeName)) { + let skip = document.createElement("div") + skip.appendChild(document.createElement("li")) + return {skip} + } else if (dom.parentNode.lastChild == dom || browser.safari && /^(tr|table)$/i.test(dom.parentNode.nodeName)) { + return {ignore: true} + } + } else if (dom.nodeName == "IMG" && dom.getAttribute("mark-placeholder")) { + return {ignore: true} + } +} + +export function readDOMChange(view, from, to, typeOver) { + if (from < 0) { + let origin = view.lastSelectionTime > Date.now() - 50 ? view.lastSelectionOrigin : null + let newSel = selectionFromDOM(view, origin) + if (!view.state.selection.eq(newSel)) { + let tr = view.state.tr.setSelection(newSel) + if (origin == "pointer") tr.setMeta("pointer", true) + else if (origin == "key") tr.scrollIntoView() + view.dispatch(tr) + } + return + } + + let $before = view.state.doc.resolve(from) + let shared = $before.sharedDepth(to) + from = $before.before(shared + 1) + to = view.state.doc.resolve(to).after(shared + 1) + + let sel = view.state.selection + let parse = parseBetween(view, from, to) + + let doc = view.state.doc, compare = doc.slice(parse.from, parse.to) + let preferredPos, preferredSide + // Prefer anchoring to end when Backspace is pressed + if (view.lastKeyCode === 8 && Date.now() - 100 < view.lastKeyCodeTime) { + preferredPos = view.state.selection.to + preferredSide = "end" + } else { + preferredPos = view.state.selection.from + preferredSide = "start" + } + view.lastKeyCode = null + + let change = findDiff(compare.content, parse.doc.content, parse.from, preferredPos, preferredSide) + if (!change) { + if (typeOver && sel instanceof TextSelection && !sel.empty && sel.$head.sameParent(sel.$anchor) && + !view.composing && !(parse.sel && parse.sel.anchor != parse.sel.head)) { + change = {start: sel.from, endA: sel.to, endB: sel.to} + } else { + if (parse.sel) { + let sel = resolveSelection(view, view.state.doc, parse.sel) + if (sel && !sel.eq(view.state.selection)) view.dispatch(view.state.tr.setSelection(sel)) + } + return + } + } + view.domChangeCount++ + // Handle the case where overwriting a selection by typing matches + // the start or end of the selected content, creating a change + // that's smaller than what was actually overwritten. + if (view.state.selection.from < view.state.selection.to && + change.start == change.endB && + view.state.selection instanceof TextSelection) { + if (change.start > view.state.selection.from && change.start <= view.state.selection.from + 2) { + change.start = view.state.selection.from + } else if (change.endA < view.state.selection.to && change.endA >= view.state.selection.to - 2) { + change.endB += (view.state.selection.to - change.endA) + change.endA = view.state.selection.to + } + } + + // IE11 will insert a non-breaking space _ahead_ of the space after + // the cursor space when adding a space before another space. When + // that happened, adjust the change to cover the space instead. + if (browser.ie && browser.ie_version <= 11 && change.endB == change.start + 1 && + change.endA == change.start && change.start > parse.from && + parse.doc.textBetween(change.start - parse.from - 1, change.start - parse.from + 1) == " \u00a0") { + change.start-- + change.endA-- + change.endB-- + } + + let $from = parse.doc.resolveNoCache(change.start - parse.from) + let $to = parse.doc.resolveNoCache(change.endB - parse.from) + let nextSel + // If this looks like the effect of pressing Enter, just dispatch an + // Enter key instead. + if (!$from.sameParent($to) && $from.pos < parse.doc.content.size && + (nextSel = Selection.findFrom(parse.doc.resolve($from.pos + 1), 1, true)) && + nextSel.head == $to.pos && + view.someProp("handleKeyDown", f => f(view, keyEvent(13, "Enter")))) + return + // Same for backspace + if (view.state.selection.anchor > change.start && + looksLikeJoin(doc, change.start, change.endA, $from, $to) && + view.someProp("handleKeyDown", f => f(view, keyEvent(8, "Backspace")))) { + if (browser.android && browser.chrome) view.domObserver.suppressSelectionUpdates() // #820 + return + } + + let chFrom = change.start, chTo = change.endA + + let tr, storedMarks, markChange, $from1 + if ($from.sameParent($to) && $from.parent.inlineContent) { + if ($from.pos == $to.pos) { // Deletion + // IE11 sometimes weirdly moves the DOM selection around after + // backspacing out the first element in a textblock + if (browser.ie && browser.ie_version <= 11 && $from.parentOffset == 0) { + view.domObserver.suppressSelectionUpdates() + setTimeout(() => selectionToDOM(view), 20) + } + tr = view.state.tr.delete(chFrom, chTo) + storedMarks = doc.resolve(change.start).marksAcross(doc.resolve(change.endA)) + } else if ( // Adding or removing a mark + change.endA == change.endB && ($from1 = doc.resolve(change.start)) && + (markChange = isMarkChange($from.parent.content.cut($from.parentOffset, $to.parentOffset), + $from1.parent.content.cut($from1.parentOffset, change.endA - $from1.start()))) + ) { + tr = view.state.tr + if (markChange.type == "add") tr.addMark(chFrom, chTo, markChange.mark) + else tr.removeMark(chFrom, chTo, markChange.mark) + } else if ($from.parent.child($from.index()).isText && $from.index() == $to.index() - ($to.textOffset ? 0 : 1)) { + // Both positions in the same text node -- simply insert text + let text = $from.parent.textBetween($from.parentOffset, $to.parentOffset) + if (view.someProp("handleTextInput", f => f(view, chFrom, chTo, text))) return + tr = view.state.tr.insertText(text, chFrom, chTo) + } + } + + if (!tr) + tr = view.state.tr.replace(chFrom, chTo, parse.doc.slice(change.start - parse.from, change.endB - parse.from)) + if (parse.sel) { + let sel = resolveSelection(view, tr.doc, parse.sel) + // Chrome Android will sometimes, during composition, report the + // selection in the wrong place. If it looks like that is + // happening, don't update the selection. + // Edge just doesn't move the cursor forward when you start typing + // in an empty block or between br nodes. + if (sel && !(browser.chrome && browser.android && view.composing && sel.empty && sel.head == chFrom || + browser.ie && sel.empty && sel.head == chFrom)) + tr.setSelection(sel) + } + if (storedMarks) tr.ensureMarks(storedMarks) + view.dispatch(tr.scrollIntoView()) +} + +function resolveSelection(view, doc, parsedSel) { + if (Math.max(parsedSel.anchor, parsedSel.head) > doc.content.size) return null + return selectionBetween(view, doc.resolve(parsedSel.anchor), doc.resolve(parsedSel.head)) +} + +// : (Fragment, Fragment) → ?{mark: Mark, type: string} +// Given two same-length, non-empty fragments of inline content, +// determine whether the first could be created from the second by +// removing or adding a single mark type. +function isMarkChange(cur, prev) { + let curMarks = cur.firstChild.marks, prevMarks = prev.firstChild.marks + let added = curMarks, removed = prevMarks, type, mark, update + for (let i = 0; i < prevMarks.length; i++) added = prevMarks[i].removeFromSet(added) + for (let i = 0; i < curMarks.length; i++) removed = curMarks[i].removeFromSet(removed) + if (added.length == 1 && removed.length == 0) { + mark = added[0] + type = "add" + update = node => node.mark(mark.addToSet(node.marks)) + } else if (added.length == 0 && removed.length == 1) { + mark = removed[0] + type = "remove" + update = node => node.mark(mark.removeFromSet(node.marks)) + } else { + return null + } + let updated = [] + for (let i = 0; i < prev.childCount; i++) updated.push(update(prev.child(i))) + if (Fragment.from(updated).eq(cur)) return {mark, type} +} + +function looksLikeJoin(old, start, end, $newStart, $newEnd) { + if (!$newStart.parent.isTextblock || + // The content must have shrunk + end - start <= $newEnd.pos - $newStart.pos || + // newEnd must point directly at or after the end of the block that newStart points into + skipClosingAndOpening($newStart, true, false) < $newEnd.pos) + return false + + let $start = old.resolve(start) + // Start must be at the end of a block + if ($start.parentOffset < $start.parent.content.size || !$start.parent.isTextblock) + return false + let $next = old.resolve(skipClosingAndOpening($start, true, true)) + // The next textblock must start before end and end near it + if (!$next.parent.isTextblock || $next.pos > end || + skipClosingAndOpening($next, true, false) < end) + return false + + // The fragments after the join point must match + return $newStart.parent.content.cut($newStart.parentOffset).eq($next.parent.content) +} + +function skipClosingAndOpening($pos, fromEnd, mayOpen) { + let depth = $pos.depth, end = fromEnd ? $pos.end() : $pos.pos + while (depth > 0 && (fromEnd || $pos.indexAfter(depth) == $pos.node(depth).childCount)) { + depth-- + end++ + fromEnd = false + } + if (mayOpen) { + let next = $pos.node(depth).maybeChild($pos.indexAfter(depth)) + while (next && !next.isLeaf) { + next = next.firstChild + end++ + } + } + return end +} + +function findDiff(a, b, pos, preferredPos, preferredSide) { + let start = a.findDiffStart(b, pos) + if (start == null) return null + let {a: endA, b: endB} = a.findDiffEnd(b, pos + a.size, pos + b.size) + if (preferredSide == "end") { + let adjust = Math.max(0, start - Math.min(endA, endB)) + preferredPos -= endA + adjust - start + } + if (endA < start && a.size < b.size) { + let move = preferredPos <= start && preferredPos >= endA ? start - preferredPos : 0 + start -= move + endB = start + (endB - endA) + endA = start + } else if (endB < start) { + let move = preferredPos <= start && preferredPos >= endB ? start - preferredPos : 0 + start -= move + endA = start + (endA - endB) + endB = start + } + return {start, endA, endB} +} diff --git a/packages/tiptap/node_modules/prosemirror-view/src/domcoords.js b/packages/tiptap/node_modules/prosemirror-view/src/domcoords.js new file mode 100644 index 0000000000..6ead2ef7c0 --- /dev/null +++ b/packages/tiptap/node_modules/prosemirror-view/src/domcoords.js @@ -0,0 +1,434 @@ +import {nodeSize, textRange, parentNode} from "./dom" +import browser from "./browser" + +function windowRect(win) { + return {left: 0, right: win.innerWidth, + top: 0, bottom: win.innerHeight} +} + +function getSide(value, side) { + return typeof value == "number" ? value : value[side] +} + +export function scrollRectIntoView(view, rect, startDOM) { + let scrollThreshold = view.someProp("scrollThreshold") || 0, scrollMargin = view.someProp("scrollMargin") || 5 + let doc = view.dom.ownerDocument, win = doc.defaultView + for (let parent = startDOM || view.dom;; parent = parentNode(parent)) { + if (!parent) break + if (parent.nodeType != 1) continue + let atTop = parent == doc.body || parent.nodeType != 1 + let bounding = atTop ? windowRect(win) : parent.getBoundingClientRect() + let moveX = 0, moveY = 0 + if (rect.top < bounding.top + getSide(scrollThreshold, "top")) + moveY = -(bounding.top - rect.top + getSide(scrollMargin, "top")) + else if (rect.bottom > bounding.bottom - getSide(scrollThreshold, "bottom")) + moveY = rect.bottom - bounding.bottom + getSide(scrollMargin, "bottom") + if (rect.left < bounding.left + getSide(scrollThreshold, "left")) + moveX = -(bounding.left - rect.left + getSide(scrollMargin, "left")) + else if (rect.right > bounding.right - getSide(scrollThreshold, "right")) + moveX = rect.right - bounding.right + getSide(scrollMargin, "right") + if (moveX || moveY) { + if (atTop) { + win.scrollBy(moveX, moveY) + } else { + if (moveY) parent.scrollTop += moveY + if (moveX) parent.scrollLeft += moveX + } + } + if (atTop) break + } +} + +// Store the scroll position of the editor's parent nodes, along with +// the top position of an element near the top of the editor, which +// will be used to make sure the visible viewport remains stable even +// when the size of the content above changes. +export function storeScrollPos(view) { + let rect = view.dom.getBoundingClientRect(), startY = Math.max(0, rect.top) + let refDOM, refTop + for (let x = (rect.left + rect.right) / 2, y = startY + 1; + y < Math.min(innerHeight, rect.bottom); y += 5) { + let dom = view.root.elementFromPoint(x, y) + if (dom == view.dom || !view.dom.contains(dom)) continue + let localRect = dom.getBoundingClientRect() + if (localRect.top >= startY - 20) { + refDOM = dom + refTop = localRect.top + break + } + } + return {refDOM, refTop, stack: scrollStack(view.dom)} +} + +function scrollStack(dom) { + let stack = [], doc = dom.ownerDocument + for (; dom; dom = parentNode(dom)) { + stack.push({dom, top: dom.scrollTop, left: dom.scrollLeft}) + if (dom == doc) break + } + return stack +} + +// Reset the scroll position of the editor's parent nodes to that what +// it was before, when storeScrollPos was called. +export function resetScrollPos({refDOM, refTop, stack}) { + let newRefTop = refDOM ? refDOM.getBoundingClientRect().top : 0 + restoreScrollStack(stack, newRefTop == 0 ? 0 : newRefTop - refTop) +} + +function restoreScrollStack(stack, dTop) { + for (let i = 0; i < stack.length; i++) { + let {dom, top, left} = stack[i] + if (dom.scrollTop != top + dTop) dom.scrollTop = top + dTop + if (dom.scrollLeft != left) dom.scrollLeft = left + } +} + +let preventScrollSupported = null +// Feature-detects support for .focus({preventScroll: true}), and uses +// a fallback kludge when not supported. +export function focusPreventScroll(dom) { + if (dom.setActive) return dom.setActive() // in IE + if (preventScrollSupported) return dom.focus(preventScrollSupported) + + let stored = scrollStack(dom) + dom.focus(preventScrollSupported == null ? { + get preventScroll() { + preventScrollSupported = {preventScroll: true} + return true + } + } : undefined) + if (!preventScrollSupported) { + preventScrollSupported = false + restoreScrollStack(stored, 0) + } +} + +function findOffsetInNode(node, coords) { + let closest, dxClosest = 2e8, coordsClosest, offset = 0 + let rowBot = coords.top, rowTop = coords.top + for (let child = node.firstChild, childIndex = 0; child; child = child.nextSibling, childIndex++) { + let rects + if (child.nodeType == 1) rects = child.getClientRects() + else if (child.nodeType == 3) rects = textRange(child).getClientRects() + else continue + + for (let i = 0; i < rects.length; i++) { + let rect = rects[i] + if (rect.top <= rowBot && rect.bottom >= rowTop) { + rowBot = Math.max(rect.bottom, rowBot) + rowTop = Math.min(rect.top, rowTop) + let dx = rect.left > coords.left ? rect.left - coords.left + : rect.right < coords.left ? coords.left - rect.right : 0 + if (dx < dxClosest) { + closest = child + dxClosest = dx + coordsClosest = dx && closest.nodeType == 3 ? {left: rect.right < coords.left ? rect.right : rect.left, top: coords.top} : coords + if (child.nodeType == 1 && dx) + offset = childIndex + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0) + continue + } + } + if (!closest && (coords.left >= rect.right && coords.top >= rect.top || + coords.left >= rect.left && coords.top >= rect.bottom)) + offset = childIndex + 1 + } + } + if (closest && closest.nodeType == 3) return findOffsetInText(closest, coordsClosest) + if (!closest || (dxClosest && closest.nodeType == 1)) return {node, offset} + return findOffsetInNode(closest, coordsClosest) +} + +function findOffsetInText(node, coords) { + let len = node.nodeValue.length + let range = document.createRange() + for (let i = 0; i < len; i++) { + range.setEnd(node, i + 1) + range.setStart(node, i) + let rect = singleRect(range, 1) + if (rect.top == rect.bottom) continue + if (inRect(coords, rect)) + return {node, offset: i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0)} + } + return {node, offset: 0} +} + +function inRect(coords, rect) { + return coords.left >= rect.left - 1 && coords.left <= rect.right + 1&& + coords.top >= rect.top - 1 && coords.top <= rect.bottom + 1 +} + +function targetKludge(dom, coords) { + let parent = dom.parentNode + if (parent && /^li$/i.test(parent.nodeName) && coords.left < dom.getBoundingClientRect().left) + return parent + return dom +} + +function posFromElement(view, elt, coords) { + let {node, offset} = findOffsetInNode(elt, coords), bias = -1 + if (node.nodeType == 1 && !node.firstChild) { + let rect = node.getBoundingClientRect() + bias = rect.left != rect.right && coords.left > (rect.left + rect.right) / 2 ? 1 : -1 + } + return view.docView.posFromDOM(node, offset, bias) +} + +function posFromCaret(view, node, offset, coords) { + // Browser (in caretPosition/RangeFromPoint) will agressively + // normalize towards nearby inline nodes. Since we are interested in + // positions between block nodes too, we first walk up the hierarchy + // of nodes to see if there are block nodes that the coordinates + // fall outside of. If so, we take the position before/after that + // block. If not, we call `posFromDOM` on the raw node/offset. + let outside = -1 + for (let cur = node;;) { + if (cur == view.dom) break + let desc = view.docView.nearestDesc(cur, true) + if (!desc) return null + if (desc.node.isBlock && desc.parent) { + let rect = desc.dom.getBoundingClientRect() + if (rect.left > coords.left || rect.top > coords.top) outside = desc.posBefore + else if (rect.right < coords.left || rect.bottom < coords.top) outside = desc.posAfter + else break + } + cur = desc.dom.parentNode + } + return outside > -1 ? outside : view.docView.posFromDOM(node, offset) +} + +function elementFromPoint(element, coords, box) { + let len = element.childNodes.length + if (len && box.top < box.bottom) { + for (let startI = Math.max(0, Math.min(len - 1, Math.floor(len * (coords.top - box.top) / (box.bottom - box.top)) - 2)), i = startI;;) { + let child = element.childNodes[i] + if (child.nodeType == 1) { + let rects = child.getClientRects() + for (let j = 0; j < rects.length; j++) { + let rect = rects[j] + if (inRect(coords, rect)) return elementFromPoint(child, coords, rect) + } + } + if ((i = (i + 1) % len) == startI) break + } + } + return element +} + +// Given an x,y position on the editor, get the position in the document. +export function posAtCoords(view, coords) { + let root = view.root, node, offset + if (root.caretPositionFromPoint) { + try { // Firefox throws for this call in hard-to-predict circumstances (#994) + let pos = root.caretPositionFromPoint(coords.left, coords.top) + if (pos) ({offsetNode: node, offset} = pos) + } catch (_) {} + } + if (!node && root.caretRangeFromPoint) { + let range = root.caretRangeFromPoint(coords.left, coords.top) + if (range) ({startContainer: node, startOffset: offset} = range) + } + + let elt = root.elementFromPoint(coords.left, coords.top + 1), pos + if (!elt || !view.dom.contains(elt.nodeType != 1 ? elt.parentNode : elt)) { + let box = view.dom.getBoundingClientRect() + if (!inRect(coords, box)) return null + elt = elementFromPoint(view.dom, coords, box) + if (!elt) return null + } + elt = targetKludge(elt, coords) + if (node) { + if (browser.gecko && node.nodeType == 1) { + // Firefox will sometimes return offsets into nodes, which + // have no actual children, from caretPositionFromPoint (#953) + offset = Math.min(offset, node.childNodes.length) + // It'll also move the returned position before image nodes, + // even if those are behind it. + if (offset < node.childNodes.length) { + let next = node.childNodes[offset], box + if (next.nodeName == "IMG" && (box = next.getBoundingClientRect()).right <= coords.left && + box.bottom > coords.top) + offset++ + } + } + // Suspiciously specific kludge to work around caret*FromPoint + // never returning a position at the end of the document + if (node == view.dom && offset == node.childNodes.length - 1 && node.lastChild.nodeType == 1 && + coords.top > node.lastChild.getBoundingClientRect().bottom) + pos = view.state.doc.content.size + // Ignore positions directly after a BR, since caret*FromPoint + // 'round up' positions that would be more accurately placed + // before the BR node. + else if (offset == 0 || node.nodeType != 1 || node.childNodes[offset - 1].nodeName != "BR") + pos = posFromCaret(view, node, offset, coords) + } + if (pos == null) pos = posFromElement(view, elt, coords) + + let desc = view.docView.nearestDesc(elt, true) + return {pos, inside: desc ? desc.posAtStart - desc.border : -1} +} + +function singleRect(object, bias) { + let rects = object.getClientRects() + return !rects.length ? object.getBoundingClientRect() : rects[bias < 0 ? 0 : rects.length - 1] +} + +// : (EditorView, number) → {left: number, top: number, right: number, bottom: number} +// Given a position in the document model, get a bounding box of the +// character at that position, relative to the window. +export function coordsAtPos(view, pos) { + let {node, offset} = view.docView.domFromPos(pos) + + // These browsers support querying empty text ranges + if (node.nodeType == 3 && (browser.chrome || browser.gecko)) { + let rect = singleRect(textRange(node, offset, offset), 0) + // Firefox returns bad results (the position before the space) + // when querying a position directly after line-broken + // whitespace. Detect this situation and and kludge around it + if (browser.gecko && offset && /\s/.test(node.nodeValue[offset - 1]) && offset < node.nodeValue.length) { + let rectBefore = singleRect(textRange(node, offset - 1, offset - 1), -1) + if (Math.abs(rectBefore.left - rect.left) < 1 && rectBefore.top == rect.top) { + let rectAfter = singleRect(textRange(node, offset, offset + 1), -1) + return flattenV(rectAfter, rectAfter.left < rectBefore.left) + } + } + return rect + } + + if (node.nodeType == 1 && !view.state.doc.resolve(pos).parent.inlineContent) { + // Return a horizontal line in block context + let top = true, rect + if (offset < node.childNodes.length) { + let after = node.childNodes[offset] + if (after.nodeType == 1) rect = after.getBoundingClientRect() + } + if (!rect && offset) { + let before = node.childNodes[offset - 1] + if (before.nodeType == 1) { rect = before.getBoundingClientRect(); top = false } + } + return flattenH(rect || node.getBoundingClientRect(), top) + } + + // Not Firefox/Chrome, or not in a text node, so we have to use + // actual element/character rectangles to get a solution (this part + // is not very bidi-safe) + // + // Try the left side first, fall back to the right one if that + // doesn't work. + for (let dir = -1; dir < 2; dir += 2) { + if (dir < 0 && offset) { + let prev, target = node.nodeType == 3 ? textRange(node, offset - 1, offset) + : (prev = node.childNodes[offset - 1]).nodeType == 3 ? textRange(prev) + : prev.nodeType == 1 && prev.nodeName != "BR" ? prev : null // BR nodes tend to only return the rectangle before them + if (target) { + let rect = singleRect(target, 1) + if (rect.top < rect.bottom) return flattenV(rect, false) + } + } else if (dir > 0 && offset < nodeSize(node)) { + let next, target = node.nodeType == 3 ? textRange(node, offset, offset + 1) + : (next = node.childNodes[offset]).nodeType == 3 ? textRange(next) + : next.nodeType == 1 ? next : null + if (target) { + let rect = singleRect(target, -1) + if (rect.top < rect.bottom) return flattenV(rect, true) + } + } + } + // All else failed, just try to get a rectangle for the target node + return flattenV(singleRect(node.nodeType == 3 ? textRange(node) : node, 0), false) +} + +function flattenV(rect, left) { + if (rect.width == 0) return rect + let x = left ? rect.left : rect.right + return {top: rect.top, bottom: rect.bottom, left: x, right: x} +} + +function flattenH(rect, top) { + if (rect.height == 0) return rect + let y = top ? rect.top : rect.bottom + return {top: y, bottom: y, left: rect.left, right: rect.right} +} + +function withFlushedState(view, state, f) { + let viewState = view.state, active = view.root.activeElement + if (viewState != state) view.updateState(state) + if (active != view.dom) view.focus() + try { + return f() + } finally { + if (viewState != state) view.updateState(viewState) + if (active != view.dom) active.focus() + } +} + +// : (EditorView, number, number) +// Whether vertical position motion in a given direction +// from a position would leave a text block. +function endOfTextblockVertical(view, state, dir) { + let sel = state.selection + let $pos = dir == "up" ? sel.$anchor.min(sel.$head) : sel.$anchor.max(sel.$head) + return withFlushedState(view, state, () => { + let {node: dom} = view.docView.domFromPos($pos.pos) + for (;;) { + let nearest = view.docView.nearestDesc(dom, true) + if (!nearest) break + if (nearest.node.isBlock) { dom = nearest.dom; break } + dom = nearest.dom.parentNode + } + let coords = coordsAtPos(view, $pos.pos) + for (let child = dom.firstChild; child; child = child.nextSibling) { + let boxes + if (child.nodeType == 1) boxes = child.getClientRects() + else if (child.nodeType == 3) boxes = textRange(child, 0, child.nodeValue.length).getClientRects() + else continue + for (let i = 0; i < boxes.length; i++) { + let box = boxes[i] + if (box.bottom > box.top && (dir == "up" ? box.bottom < coords.top + 1 : box.top > coords.bottom - 1)) + return false + } + } + return true + }) +} + +const maybeRTL = /[\u0590-\u08ac]/ + +function endOfTextblockHorizontal(view, state, dir) { + let {$head} = state.selection + if (!$head.parent.isTextblock) return false + let offset = $head.parentOffset, atStart = !offset, atEnd = offset == $head.parent.content.size + let sel = getSelection() + // If the textblock is all LTR, or the browser doesn't support + // Selection.modify (Edge), fall back to a primitive approach + if (!maybeRTL.test($head.parent.textContent) || !sel.modify) + return dir == "left" || dir == "backward" ? atStart : atEnd + + return withFlushedState(view, state, () => { + // This is a huge hack, but appears to be the best we can + // currently do: use `Selection.modify` to move the selection by + // one character, and see if that moves the cursor out of the + // textblock (or doesn't move it at all, when at the start/end of + // the document). + let oldRange = sel.getRangeAt(0), oldNode = sel.focusNode, oldOff = sel.focusOffset + let oldBidiLevel = sel.caretBidiLevel // Only for Firefox + sel.modify("move", dir, "character") + let parentDOM = $head.depth ? view.docView.domAfterPos($head.before()) : view.dom + let result = !parentDOM.contains(sel.focusNode.nodeType == 1 ? sel.focusNode : sel.focusNode.parentNode) || + (oldNode == sel.focusNode && oldOff == sel.focusOffset) + // Restore the previous selection + sel.removeAllRanges() + sel.addRange(oldRange) + if (oldBidiLevel != null) sel.caretBidiLevel = oldBidiLevel + return result + }) +} + +let cachedState = null, cachedDir = null, cachedResult = false +export function endOfTextblock(view, state, dir) { + if (cachedState == state && cachedDir == dir) return cachedResult + cachedState = state; cachedDir = dir + return cachedResult = dir == "up" || dir == "down" + ? endOfTextblockVertical(view, state, dir) + : endOfTextblockHorizontal(view, state, dir) +} diff --git a/packages/tiptap/node_modules/prosemirror-view/src/domobserver.js b/packages/tiptap/node_modules/prosemirror-view/src/domobserver.js new file mode 100644 index 0000000000..038eea1326 --- /dev/null +++ b/packages/tiptap/node_modules/prosemirror-view/src/domobserver.js @@ -0,0 +1,226 @@ +import browser from "./browser" +import {domIndex, isEquivalentPosition} from "./dom" +import {hasFocusAndSelection, hasSelection, selectionToDOM} from "./selection" + +const observeOptions = { + childList: true, + characterData: true, + characterDataOldValue: true, + attributes: true, + attributeOldValue: true, + subtree: true +} +// IE11 has very broken mutation observers, so we also listen to DOMCharacterDataModified +const useCharData = browser.ie && browser.ie_version <= 11 + +class SelectionState { + constructor() { + this.anchorNode = this.anchorOffset = this.focusNode = this.focusOffset = null + } + + set(sel) { + this.anchorNode = sel.anchorNode; this.anchorOffset = sel.anchorOffset + this.focusNode = sel.focusNode; this.focusOffset = sel.focusOffset + } + + eq(sel) { + return sel.anchorNode == this.anchorNode && sel.anchorOffset == this.anchorOffset && + sel.focusNode == this.focusNode && sel.focusOffset == this.focusOffset + } +} + +export class DOMObserver { + constructor(view, handleDOMChange) { + this.view = view + this.handleDOMChange = handleDOMChange + this.queue = [] + this.flushingSoon = false + this.observer = window.MutationObserver && + new window.MutationObserver(mutations => { + for (let i = 0; i < mutations.length; i++) this.queue.push(mutations[i]) + // IE11 will sometimes (on backspacing out a single character + // text node after a BR node) call the observer callback + // before actually updating the DOM, which will cause + // ProseMirror to miss the change (see #930) + if (browser.ie && browser.ie_version <= 11 && mutations.some( + m => m.type == "childList" && m.removedNodes.length || + m.type == "characterData" && m.oldValue.length > m.target.nodeValue.length)) + this.flushSoon() + else + this.flush() + }) + this.currentSelection = new SelectionState + if (useCharData) { + this.onCharData = e => { + this.queue.push({target: e.target, type: "characterData", oldValue: e.prevValue}) + this.flushSoon() + } + } + this.onSelectionChange = this.onSelectionChange.bind(this) + this.suppressingSelectionUpdates = false + } + + flushSoon() { + if (!this.flushingSoon) { + this.flushingSoon = true + window.setTimeout(() => { this.flushingSoon = false; this.flush() }, 20) + } + } + + start() { + if (this.observer) + this.observer.observe(this.view.dom, observeOptions) + if (useCharData) + this.view.dom.addEventListener("DOMCharacterDataModified", this.onCharData) + this.connectSelection() + } + + stop() { + if (this.observer) { + let take = this.observer.takeRecords() + if (take.length) { + for (let i = 0; i < take.length; i++) this.queue.push(take[i]) + window.setTimeout(() => this.flush(), 20) + } + this.observer.disconnect() + } + if (useCharData) this.view.dom.removeEventListener("DOMCharacterDataModified", this.onCharData) + this.disconnectSelection() + } + + connectSelection() { + this.view.dom.ownerDocument.addEventListener("selectionchange", this.onSelectionChange) + } + + disconnectSelection() { + this.view.dom.ownerDocument.removeEventListener("selectionchange", this.onSelectionChange) + } + + suppressSelectionUpdates() { + this.suppressingSelectionUpdates = true + setTimeout(() => this.suppressingSelectionUpdates = false, 50) + } + + onSelectionChange() { + if (!hasFocusAndSelection(this.view)) return + if (this.suppressingSelectionUpdates) return selectionToDOM(this.view) + // Deletions on IE11 fire their events in the wrong order, giving + // us a selection change event before the DOM changes are + // reported. + if (browser.ie && browser.ie_version <= 11 && !this.view.state.selection.empty) { + let sel = this.view.root.getSelection() + // Selection.isCollapsed isn't reliable on IE + if (sel.focusNode && isEquivalentPosition(sel.focusNode, sel.focusOffset, sel.anchorNode, sel.anchorOffset)) + return this.flushSoon() + } + this.flush() + } + + setCurSelection() { + this.currentSelection.set(this.view.root.getSelection()) + } + + ignoreSelectionChange(sel) { + if (sel.rangeCount == 0) return true + let container = sel.getRangeAt(0).commonAncestorContainer + let desc = this.view.docView.nearestDesc(container) + return desc && desc.ignoreMutation({type: "selection", target: container.nodeType == 3 ? container.parentNode : container}) + } + + flush() { + if (!this.view.docView || this.flushingSoon) return + let mutations = this.observer ? this.observer.takeRecords() : [] + if (this.queue.length) { + mutations = this.queue.concat(mutations) + this.queue.length = 0 + } + + let sel = this.view.root.getSelection() + let newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasSelection(this.view) && !this.ignoreSelectionChange(sel) + + let from = -1, to = -1, typeOver = false, added = [] + if (this.view.editable) { + for (let i = 0; i < mutations.length; i++) { + let result = this.registerMutation(mutations[i], added) + if (result) { + from = from < 0 ? result.from : Math.min(result.from, from) + to = to < 0 ? result.to : Math.max(result.to, to) + if (result.typeOver && !this.view.composing) typeOver = true + } + } + } + + if (browser.gecko && added.length > 1) { + let brs = added.filter(n => n.nodeName == "BR") + if (brs.length == 2) { + let [a, b] = brs + if (a.parentNode && a.parentNode.parentNode == b.parentNode) b.remove() + else a.remove() + } + } + + if (from > -1 || newSel) { + if (from > -1) { + this.view.docView.markDirty(from, to) + checkCSS(this.view) + } + this.handleDOMChange(from, to, typeOver) + if (this.view.docView.dirty) this.view.updateState(this.view.state) + else if (!this.currentSelection.eq(sel)) selectionToDOM(this.view) + } + } + + registerMutation(mut, added) { + // Ignore mutations inside nodes that were already noted as inserted + if (added.indexOf(mut.target) > -1) return null + let desc = this.view.docView.nearestDesc(mut.target) + if (mut.type == "attributes" && + (desc == this.view.docView || mut.attributeName == "contenteditable" || + // Firefox sometimes fires spurious events for null/empty styles + (mut.attributeName == "style" && !mut.oldValue && !mut.target.getAttribute("style")))) + return null + if (!desc || desc.ignoreMutation(mut)) return null + + if (mut.type == "childList") { + let prev = mut.previousSibling, next = mut.nextSibling + if (browser.ie && browser.ie_version <= 11 && mut.addedNodes.length) { + // IE11 gives us incorrect next/prev siblings for some + // insertions, so if there are added nodes, recompute those + for (let i = 0; i < mut.addedNodes.length; i++) { + let {previousSibling, nextSibling} = mut.addedNodes[i] + if (!previousSibling || Array.prototype.indexOf.call(mut.addedNodes, previousSibling) < 0) prev = previousSibling + if (!nextSibling || Array.prototype.indexOf.call(mut.addedNodes, nextSibling) < 0) next = nextSibling + } + } + let fromOffset = prev && prev.parentNode == mut.target + ? domIndex(prev) + 1 : 0 + let from = desc.localPosFromDOM(mut.target, fromOffset, -1) + let toOffset = next && next.parentNode == mut.target + ? domIndex(next) : mut.target.childNodes.length + for (let i = 0; i < mut.addedNodes.length; i++) added.push(mut.addedNodes[i]) + let to = desc.localPosFromDOM(mut.target, toOffset, 1) + return {from, to} + } else if (mut.type == "attributes") { + return {from: desc.posAtStart - desc.border, to: desc.posAtEnd + desc.border} + } else { // "characterData" + return { + from: desc.posAtStart, + to: desc.posAtEnd, + // An event was generated for a text change that didn't change + // any text. Mark the dom change to fall back to assuming the + // selection was typed over with an identical value if it can't + // find another change. + typeOver: mut.target.nodeValue == mut.oldValue + } + } + } +} + +let cssChecked = false + +function checkCSS(view) { + if (cssChecked) return + cssChecked = true + if (getComputedStyle(view.dom).whiteSpace == "normal") + console["warn"]("ProseMirror expects the CSS white-space property to be set, preferably to 'pre-wrap'. It is recommended to load style/prosemirror.css from the prosemirror-view package.") +} diff --git a/packages/tiptap/node_modules/prosemirror-view/src/index.js b/packages/tiptap/node_modules/prosemirror-view/src/index.js new file mode 100644 index 0000000000..d879514fac --- /dev/null +++ b/packages/tiptap/node_modules/prosemirror-view/src/index.js @@ -0,0 +1,601 @@ +import {NodeSelection} from "prosemirror-state" + +import {scrollRectIntoView, posAtCoords, coordsAtPos, endOfTextblock, storeScrollPos, + resetScrollPos, focusPreventScroll} from "./domcoords" +import {docViewDesc} from "./viewdesc" +import {initInput, destroyInput, dispatchEvent, ensureListeners} from "./input" +import {selectionToDOM, anchorInRightPlace, syncNodeSelection} from "./selection" +import {Decoration, viewDecorations} from "./decoration" +import browser from "./browser" + +export {Decoration, DecorationSet} from "./decoration" + +// Exported for testing +export {serializeForClipboard as __serializeForClipboard, parseFromClipboard as __parseFromClipboard} from "./clipboard" +export {endComposition as __endComposition} from "./input" + +// ::- An editor view manages the DOM structure that represents an +// editable document. Its state and behavior are determined by its +// [props](#view.DirectEditorProps). +export class EditorView { + // :: (?union, DirectEditorProps) + // Create a view. `place` may be a DOM node that the editor should + // be appended to, a function that will place it into the document, + // or an object whose `mount` property holds the node to use as the + // document container. If it is `null`, the editor will not be added + // to the document. + constructor(place, props) { + this._props = props + // :: EditorState + // The view's current [state](#state.EditorState). + this.state = props.state + + this.dispatch = this.dispatch.bind(this) + + this._root = null + this.focused = false + + // :: dom.Element + // An editable DOM node containing the document. (You probably + // should not directly interfere with its content.) + this.dom = (place && place.mount) || document.createElement("div") + if (place) { + if (place.appendChild) place.appendChild(this.dom) + else if (place.apply) place(this.dom) + else if (place.mount) this.mounted = true + } + + // :: bool + // Indicates whether the editor is currently [editable](#view.EditorProps.editable). + this.editable = getEditable(this) + this.markCursor = null + this.cursorWrapper = null + updateCursorWrapper(this) + this.nodeViews = buildNodeViews(this) + this.docView = docViewDesc(this.state.doc, computeDocDeco(this), viewDecorations(this), this.dom, this) + + this.lastSelectedViewDesc = null + // :: ?{slice: Slice, move: bool} + // When editor content is being dragged, this object contains + // information about the dragged slice and whether it is being + // copied or moved. At any other time, it is null. + this.dragging = null + + initInput(this) + + this.pluginViews = [] + this.updatePluginViews() + } + + // composing:: boolean + // Holds `true` when a + // [composition](https://developer.mozilla.org/en-US/docs/Mozilla/IME_handling_guide) + // is active. + + // :: DirectEditorProps + // The view's current [props](#view.EditorProps). + get props() { + if (this._props.state != this.state) { + let prev = this._props + this._props = {} + for (let name in prev) this._props[name] = prev[name] + this._props.state = this.state + } + return this._props + } + + // :: (DirectEditorProps) + // Update the view's props. Will immediately cause an update to + // the DOM. + update(props) { + if (props.handleDOMEvents != this._props.handleDOMEvents) ensureListeners(this) + this._props = props + this.updateStateInner(props.state, true) + } + + // :: (DirectEditorProps) + // Update the view by updating existing props object with the object + // given as argument. Equivalent to `view.update(Object.assign({}, + // view.props, props))`. + setProps(props) { + let updated = {} + for (let name in this._props) updated[name] = this._props[name] + updated.state = this.state + for (let name in props) updated[name] = props[name] + this.update(updated) + } + + // :: (EditorState) + // Update the editor's `state` prop, without touching any of the + // other props. + updateState(state) { + this.updateStateInner(state, this.state.plugins != state.plugins) + } + + updateStateInner(state, reconfigured) { + let prev = this.state, redraw = false + this.state = state + if (reconfigured) { + let nodeViews = buildNodeViews(this) + if (changedNodeViews(nodeViews, this.nodeViews)) { + this.nodeViews = nodeViews + redraw = true + } + ensureListeners(this) + } + + this.editable = getEditable(this) + updateCursorWrapper(this) + let innerDeco = viewDecorations(this), outerDeco = computeDocDeco(this) + + let scroll = reconfigured ? "reset" + : state.scrollToSelection > prev.scrollToSelection ? "to selection" : "preserve" + let updateDoc = redraw || !this.docView.matchesNode(state.doc, outerDeco, innerDeco) + let updateSel = updateDoc || !state.selection.eq(prev.selection) + let oldScrollPos = scroll == "preserve" && updateSel && this.dom.style.overflowAnchor == null && storeScrollPos(this) + + if (updateSel) { + this.domObserver.stop() + // Work around an issue in Chrome, IE, and Edge where changing + // the DOM around an active selection puts it into a broken + // state where the thing the user sees differs from the + // selection reported by the Selection object (#710, #973, + // #1011, #1013). + let forceSelUpdate = updateDoc && (browser.ie || browser.chrome) && + !prev.selection.empty && !state.selection.empty && selectionContextChanged(prev.selection, state.selection) + if (updateDoc) { + if (redraw || !this.docView.update(state.doc, outerDeco, innerDeco, this)) { + this.docView.destroy() + this.docView = docViewDesc(state.doc, outerDeco, innerDeco, this.dom, this) + } + } + // Work around for an issue where an update arriving right between + // a DOM selection change and the "selectionchange" event for it + // can cause a spurious DOM selection update, disrupting mouse + // drag selection. + if (forceSelUpdate || + !(this.mouseDown && this.domObserver.currentSelection.eq(this.root.getSelection()) && anchorInRightPlace(this))) { + selectionToDOM(this, forceSelUpdate) + } else { + syncNodeSelection(this, state.selection) + this.domObserver.setCurSelection() + } + this.domObserver.start() + } + + this.updatePluginViews(prev) + + if (scroll == "reset") { + this.dom.scrollTop = 0 + } else if (scroll == "to selection") { + let startDOM = this.root.getSelection().focusNode + if (this.someProp("handleScrollToSelection", f => f(this))) + {} // Handled + else if (state.selection instanceof NodeSelection) + scrollRectIntoView(this, this.docView.domAfterPos(state.selection.from).getBoundingClientRect(), startDOM) + else + scrollRectIntoView(this, this.coordsAtPos(state.selection.head), startDOM) + } else if (oldScrollPos) { + resetScrollPos(oldScrollPos) + } + } + + destroyPluginViews() { + let view + while (view = this.pluginViews.pop()) if (view.destroy) view.destroy() + } + + updatePluginViews(prevState) { + if (!prevState || prevState.plugins != this.state.plugins) { + this.destroyPluginViews() + for (let i = 0; i < this.state.plugins.length; i++) { + let plugin = this.state.plugins[i] + if (plugin.spec.view) this.pluginViews.push(plugin.spec.view(this)) + } + } else { + for (let i = 0; i < this.pluginViews.length; i++) { + let pluginView = this.pluginViews[i] + if (pluginView.update) pluginView.update(this, prevState) + } + } + } + + // :: (string, ?(prop: *) → *) → * + // Goes over the values of a prop, first those provided directly, + // then those from plugins (in order), and calls `f` every time a + // non-undefined value is found. When `f` returns a truthy value, + // that is immediately returned. When `f` isn't provided, it is + // treated as the identity function (the prop value is returned + // directly). + someProp(propName, f) { + let prop = this._props && this._props[propName], value + if (prop != null && (value = f ? f(prop) : prop)) return value + let plugins = this.state.plugins + if (plugins) for (let i = 0; i < plugins.length; i++) { + let prop = plugins[i].props[propName] + if (prop != null && (value = f ? f(prop) : prop)) return value + } + } + + // :: () → bool + // Query whether the view has focus. + hasFocus() { + return this.root.activeElement == this.dom + } + + // :: () + // Focus the editor. + focus() { + this.domObserver.stop() + if (this.editable) focusPreventScroll(this.dom) + selectionToDOM(this) + this.domObserver.start() + } + + // :: union + // Get the document root in which the editor exists. This will + // usually be the top-level `document`, but might be a [shadow + // DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Shadow_DOM) + // root if the editor is inside one. + get root() { + let cached = this._root + if (cached == null) for (let search = this.dom.parentNode; search; search = search.parentNode) { + if (search.nodeType == 9 || (search.nodeType == 11 && search.host)) { + if (!search.getSelection) Object.getPrototypeOf(search).getSelection = () => document.getSelection() + return this._root = search + } + } + return cached || document + } + + // :: ({left: number, top: number}) → ?{pos: number, inside: number} + // Given a pair of viewport coordinates, return the document + // position that corresponds to them. May return null if the given + // coordinates aren't inside of the editor. When an object is + // returned, its `pos` property is the position nearest to the + // coordinates, and its `inside` property holds the position of the + // inner node that the position falls inside of, or -1 if it is at + // the top level, not in any node. + posAtCoords(coords) { + return posAtCoords(this, coords) + } + + // :: (number) → {left: number, right: number, top: number, bottom: number} + // Returns the viewport rectangle at a given document position. `left` + // and `right` will be the same number, as this returns a flat + // cursor-ish rectangle. + coordsAtPos(pos) { + return coordsAtPos(this, pos) + } + + // :: (number) → {node: dom.Node, offset: number} + // Find the DOM position that corresponds to the given document + // position. Note that you should **not** mutate the editor's + // internal DOM, only inspect it (and even that is usually not + // necessary). + domAtPos(pos) { + return this.docView.domFromPos(pos) + } + + // :: (number) → ?dom.Node + // Find the DOM node that represents the document node after the + // given position. May return `null` when the position doesn't point + // in front of a node or if the node is inside an opaque node view. + // + // This is intended to be able to call things like + // `getBoundingClientRect` on that DOM node. Do **not** mutate the + // editor DOM directly, or add styling this way, since that will be + // immediately overriden by the editor as it redraws the node. + nodeDOM(pos) { + let desc = this.docView.descAt(pos) + return desc ? desc.nodeDOM : null + } + + // :: (dom.Node, number, ?number) → number + // Find the document position that corresponds to a given DOM + // position. (Whenever possible, it is preferable to inspect the + // document structure directly, rather than poking around in the + // DOM, but sometimes—for example when interpreting an event + // target—you don't have a choice.) + // + // The `bias` parameter can be used to influence which side of a DOM + // node to use when the position is inside a leaf node. + posAtDOM(node, offset, bias = -1) { + let pos = this.docView.posFromDOM(node, offset, bias) + if (pos == null) throw new RangeError("DOM position not inside the editor") + return pos + } + + // :: (union<"up", "down", "left", "right", "forward", "backward">, ?EditorState) → bool + // Find out whether the selection is at the end of a textblock when + // moving in a given direction. When, for example, given `"left"`, + // it will return true if moving left from the current cursor + // position would leave that position's parent textblock. Will apply + // to the view's current state by default, but it is possible to + // pass a different state. + endOfTextblock(dir, state) { + return endOfTextblock(this, state || this.state, dir) + } + + // :: () + // Removes the editor from the DOM and destroys all [node + // views](#view.NodeView). + destroy() { + if (!this.docView) return + destroyInput(this) + this.destroyPluginViews() + if (this.mounted) { + this.docView.update(this.state.doc, [], viewDecorations(this), this) + this.dom.textContent = "" + } else if (this.dom.parentNode) { + this.dom.parentNode.removeChild(this.dom) + } + this.docView.destroy() + this.docView = null + } + + // Used for testing. + dispatchEvent(event) { + return dispatchEvent(this, event) + } + + // :: (Transaction) + // Dispatch a transaction. Will call + // [`dispatchTransaction`](#view.DirectEditorProps.dispatchTransaction) + // when given, and otherwise defaults to applying the transaction to + // the current state and calling + // [`updateState`](#view.EditorView.updateState) with the result. + // This method is bound to the view instance, so that it can be + // easily passed around. + dispatch(tr) { + let dispatchTransaction = this._props.dispatchTransaction + if (dispatchTransaction) dispatchTransaction.call(this, tr) + else this.updateState(this.state.apply(tr)) + } +} + +function computeDocDeco(view) { + let attrs = Object.create(null) + attrs.class = "ProseMirror" + attrs.contenteditable = String(view.editable) + + view.someProp("attributes", value => { + if (typeof value == "function") value = value(view.state) + if (value) for (let attr in value) { + if (attr == "class") + attrs.class += " " + value[attr] + else if (!attrs[attr] && attr != "contenteditable" && attr != "nodeName") + attrs[attr] = String(value[attr]) + } + }) + + return [Decoration.node(0, view.state.doc.content.size, attrs)] +} + +function updateCursorWrapper(view) { + let {$head, $anchor, visible} = view.state.selection + if (view.markCursor) { + let dom = document.createElement("img") + dom.setAttribute("mark-placeholder", "true") + view.cursorWrapper = {dom, deco: Decoration.widget($head.pos, dom, {raw: true, marks: view.markCursor})} + } else if (visible || $head.pos != $anchor.pos) { + view.cursorWrapper = null + } else { + let dom + if (!view.cursorWrapper || view.cursorWrapper.dom.childNodes.length) { + dom = document.createElement("div") + dom.style.position = "absolute" + dom.style.left = "-100000px" + } else if (view.cursorWrapper.deco.pos != $head.pos) { + dom = view.cursorWrapper.dom + } + if (dom) + view.cursorWrapper = {dom, deco: Decoration.widget($head.pos, dom, {raw: true})} + } +} + +function getEditable(view) { + return !view.someProp("editable", value => value(view.state) === false) +} + +function selectionContextChanged(sel1, sel2) { + let depth = Math.min(sel1.$anchor.sharedDepth(sel1.head), sel2.$anchor.sharedDepth(sel2.head)) + return sel1.$anchor.node(depth) != sel2.$anchor.node(depth) +} + +function buildNodeViews(view) { + let result = {} + view.someProp("nodeViews", obj => { + for (let prop in obj) if (!Object.prototype.hasOwnProperty.call(result, prop)) + result[prop] = obj[prop] + }) + return result +} + +function changedNodeViews(a, b) { + let nA = 0, nB = 0 + for (let prop in a) { + if (a[prop] != b[prop]) return true + nA++ + } + for (let _ in b) nB++ + return nA != nB +} + +// EditorProps:: interface +// +// Props are configuration values that can be passed to an editor view +// or included in a plugin. This interface lists the supported props. +// +// The various event-handling functions may all return `true` to +// indicate that they handled the given event. The view will then take +// care to call `preventDefault` on the event, except with +// `handleDOMEvents`, where the handler itself is responsible for that. +// +// How a prop is resolved depends on the prop. Handler functions are +// called one at a time, starting with the base props and then +// searching through the plugins (in order of appearance) until one of +// them returns true. For some props, the first plugin that yields a +// value gets precedence. +// +// handleDOMEvents:: ?Object<(view: EditorView, event: dom.Event) → bool> +// Can be an object mapping DOM event type names to functions that +// handle them. Such functions will be called before any handling +// ProseMirror does of events fired on the editable DOM element. +// Contrary to the other event handling props, when returning true +// from such a function, you are responsible for calling +// `preventDefault` yourself (or not, if you want to allow the +// default behavior). +// +// handleKeyDown:: ?(view: EditorView, event: dom.KeyboardEvent) → bool +// Called when the editor receives a `keydown` event. +// +// handleKeyPress:: ?(view: EditorView, event: dom.KeyboardEvent) → bool +// Handler for `keypress` events. +// +// handleTextInput:: ?(view: EditorView, from: number, to: number, text: string) → bool +// Whenever the user directly input text, this handler is called +// before the input is applied. If it returns `true`, the default +// behavior of actually inserting the text is suppressed. +// +// handleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool +// Called for each node around a click, from the inside out. The +// `direct` flag will be true for the inner node. +// +// handleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool +// Called when the editor is clicked, after `handleClickOn` handlers +// have been called. +// +// handleDoubleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool +// Called for each node around a double click. +// +// handleDoubleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool +// Called when the editor is double-clicked, after `handleDoubleClickOn`. +// +// handleTripleClickOn:: ?(view: EditorView, pos: number, node: Node, nodePos: number, event: dom.MouseEvent, direct: bool) → bool +// Called for each node around a triple click. +// +// handleTripleClick:: ?(view: EditorView, pos: number, event: dom.MouseEvent) → bool +// Called when the editor is triple-clicked, after `handleTripleClickOn`. +// +// handlePaste:: ?(view: EditorView, event: dom.Event, slice: Slice) → bool +// Can be used to override the behavior of pasting. `slice` is the +// pasted content parsed by the editor, but you can directly access +// the event to get at the raw content. +// +// handleDrop:: ?(view: EditorView, event: dom.Event, slice: Slice, moved: bool) → bool +// Called when something is dropped on the editor. `moved` will be +// true if this drop moves from the current selection (which should +// thus be deleted). +// +// handleScrollToSelection:: ?(view: EditorView) → bool +// Called when the view, after updating its state, tries to scroll +// the selection into view. A handler function may return false to +// indicate that it did not handle the scrolling and further +// handlers or the default behavior should be tried. +// +// createSelectionBetween:: ?(view: EditorView, anchor: ResolvedPos, head: ResolvedPos) → ?Selection +// Can be used to override the way a selection is created when +// reading a DOM selection between the given anchor and head. +// +// domParser:: ?DOMParser +// The [parser](#model.DOMParser) to use when reading editor changes +// from the DOM. Defaults to calling +// [`DOMParser.fromSchema`](#model.DOMParser^fromSchema) on the +// editor's schema. +// +// transformPastedHTML:: ?(html: string) → string +// Can be used to transform pasted HTML text, _before_ it is parsed, +// for example to clean it up. +// +// clipboardParser:: ?DOMParser +// The [parser](#model.DOMParser) to use when reading content from +// the clipboard. When not given, the value of the +// [`domParser`](#view.EditorProps.domParser) prop is used. +// +// transformPastedText:: ?(text: string) → string +// Transform pasted plain text. +// +// clipboardTextParser:: ?(text: string, $context: ResolvedPos) → Slice +// A function to parse text from the clipboard into a document +// slice. Called after +// [`transformPastedText`](#view.EditorProps.transformPastedText). +// The default behavior is to split the text into lines, wrap them +// in `

    ` tags, and call +// [`clipboardParser`](#view.EditorProps.clipboardParser) on it. +// +// transformPasted:: ?(Slice) → Slice +// Can be used to transform pasted content before it is applied to +// the document. +// +// nodeViews:: ?Object<(node: Node, view: EditorView, getPos: () → number, decorations: [Decoration]) → NodeView> +// Allows you to pass custom rendering and behavior logic for nodes +// and marks. Should map node and mark names to constructor +// functions that produce a [`NodeView`](#view.NodeView) object +// implementing the node's display behavior. For nodes, the third +// argument `getPos` is a function that can be called to get the +// node's current position, which can be useful when creating +// transactions to update it. For marks, the third argument is a +// boolean that indicates whether the mark's content is inline. +// +// `decorations` is an array of node or inline decorations that are +// active around the node. They are automatically drawn in the +// normal way, and you will usually just want to ignore this, but +// they can also be used as a way to provide context information to +// the node view without adding it to the document itself. +// +// clipboardSerializer:: ?DOMSerializer +// The DOM serializer to use when putting content onto the +// clipboard. If not given, the result of +// [`DOMSerializer.fromSchema`](#model.DOMSerializer^fromSchema) +// will be used. +// +// clipboardTextSerializer:: ?(Slice) → string +// A function that will be called to get the text for the current +// selection when copying text to the clipboard. By default, the +// editor will use [`textBetween`](#model.Node.textBetween) on the +// selected range. +// +// decorations:: ?(state: EditorState) → ?DecorationSet +// A set of [document decorations](#view.Decoration) to show in the +// view. +// +// editable:: ?(state: EditorState) → bool +// When this returns false, the content of the view is not directly +// editable. +// +// attributes:: ?union, (EditorState) → ?Object> +// Control the DOM attributes of the editable element. May be either +// an object or a function going from an editor state to an object. +// By default, the element will get a class `"ProseMirror"`, and +// will have its `contentEditable` attribute determined by the +// [`editable` prop](#view.EditorProps.editable). Additional classes +// provided here will be added to the class. For other attributes, +// the value provided first (as in +// [`someProp`](#view.EditorView.someProp)) will be used. +// +// scrollThreshold:: ?union +// Determines the distance (in pixels) between the cursor and the +// end of the visible viewport at which point, when scrolling the +// cursor into view, scrolling takes place. Defaults to 0. +// +// scrollMargin:: ?union +// Determines the extra space (in pixels) that is left above or +// below the cursor when it is scrolled into view. Defaults to 5. + +// DirectEditorProps:: interface extends EditorProps +// +// The props object given directly to the editor view supports two +// fields that can't be used in plugins: +// +// state:: EditorState +// The current state of the editor. +// +// dispatchTransaction:: ?(tr: Transaction) +// The callback over which to send transactions (state updates) +// produced by the view. If you specify this, you probably want to +// make sure this ends up calling the view's +// [`updateState`](#view.EditorView.updateState) method with a new +// state that has the transaction +// [applied](#state.EditorState.apply). The callback will be bound to have +// the view instance as its `this` binding. diff --git a/packages/tiptap/node_modules/prosemirror-view/src/input.js b/packages/tiptap/node_modules/prosemirror-view/src/input.js new file mode 100644 index 0000000000..a0e80460d1 --- /dev/null +++ b/packages/tiptap/node_modules/prosemirror-view/src/input.js @@ -0,0 +1,644 @@ +import {Selection, NodeSelection, TextSelection} from "prosemirror-state" +import {dropPoint} from "prosemirror-transform" +import {Slice} from "prosemirror-model" + +import browser from "./browser" +import {captureKeyDown} from "./capturekeys" +import {readDOMChange} from "./domchange" +import {parseFromClipboard, serializeForClipboard} from "./clipboard" +import {DOMObserver} from "./domobserver" +import {selectionBetween} from "./selection" +import {keyEvent} from "./dom" + +// A collection of DOM events that occur within the editor, and callback functions +// to invoke when the event fires. +const handlers = {}, editHandlers = {} + +export function initInput(view) { + view.shiftKey = false + view.mouseDown = null + view.lastKeyCode = null + view.lastKeyCodeTime = 0 + view.lastClick = {time: 0, x: 0, y: 0, type: ""} + view.lastSelectionOrigin = null + view.lastSelectionTime = 0 + + view.composing = false + view.composingTimeout = null + view.compositionNodes = [] + view.compositionEndedAt = -2e8 + + view.domObserver = new DOMObserver(view, (from, to, typeOver) => readDOMChange(view, from, to, typeOver)) + view.domObserver.start() + // Used by hacks like the beforeinput handler to check whether anything happened in the DOM + view.domChangeCount = 0 + + view.eventHandlers = Object.create(null) + for (let event in handlers) { + let handler = handlers[event] + view.dom.addEventListener(event, view.eventHandlers[event] = event => { + if (eventBelongsToView(view, event) && !runCustomHandler(view, event) && + (view.editable || !(event.type in editHandlers))) + handler(view, event) + }) + } + // On Safari, for reasons beyond my understanding, adding an input + // event handler makes an issue where the composition vanishes when + // you press enter go away. + if (browser.safari) view.dom.addEventListener("input", () => null) + + ensureListeners(view) +} + +function setSelectionOrigin(view, origin) { + view.lastSelectionOrigin = origin + view.lastSelectionTime = Date.now() +} + +export function destroyInput(view) { + view.domObserver.stop() + for (let type in view.eventHandlers) + view.dom.removeEventListener(type, view.eventHandlers[type]) + clearTimeout(view.composingTimeout) +} + +export function ensureListeners(view) { + view.someProp("handleDOMEvents", currentHandlers => { + for (let type in currentHandlers) if (!view.eventHandlers[type]) + view.dom.addEventListener(type, view.eventHandlers[type] = event => runCustomHandler(view, event)) + }) +} + +function runCustomHandler(view, event) { + return view.someProp("handleDOMEvents", handlers => { + let handler = handlers[event.type] + return handler ? handler(view, event) || event.defaultPrevented : false + }) +} + +function eventBelongsToView(view, event) { + if (!event.bubbles) return true + if (event.defaultPrevented) return false + for (let node = event.target; node != view.dom; node = node.parentNode) + if (!node || node.nodeType == 11 || + (node.pmViewDesc && node.pmViewDesc.stopEvent(event))) + return false + return true +} + +export function dispatchEvent(view, event) { + if (!runCustomHandler(view, event) && handlers[event.type] && + (view.editable || !(event.type in editHandlers))) + handlers[event.type](view, event) +} + +editHandlers.keydown = (view, event) => { + view.shiftKey = event.keyCode == 16 || event.shiftKey + if (inOrNearComposition(view, event)) return + view.lastKeyCode = event.keyCode + view.lastKeyCodeTime = Date.now() + if (view.someProp("handleKeyDown", f => f(view, event)) || captureKeyDown(view, event)) + event.preventDefault() + else + setSelectionOrigin(view, "key") +} + +editHandlers.keyup = (view, e) => { + if (e.keyCode == 16) view.shiftKey = false +} + +editHandlers.keypress = (view, event) => { + if (inOrNearComposition(view, event) || !event.charCode || + event.ctrlKey && !event.altKey || browser.mac && event.metaKey) return + + if (view.someProp("handleKeyPress", f => f(view, event))) { + event.preventDefault() + return + } + + let sel = view.state.selection + if (!(sel instanceof TextSelection) || !sel.$from.sameParent(sel.$to)) { + let text = String.fromCharCode(event.charCode) + if (!view.someProp("handleTextInput", f => f(view, sel.$from.pos, sel.$to.pos, text))) + view.dispatch(view.state.tr.insertText(text).scrollIntoView()) + event.preventDefault() + } +} + +function eventCoords(event) { return {left: event.clientX, top: event.clientY} } + +function isNear(event, click) { + let dx = click.x - event.clientX, dy = click.y - event.clientY + return dx * dx + dy * dy < 100 +} + +function runHandlerOnContext(view, propName, pos, inside, event) { + if (inside == -1) return false + let $pos = view.state.doc.resolve(inside) + for (let i = $pos.depth + 1; i > 0; i--) { + if (view.someProp(propName, f => i > $pos.depth ? f(view, pos, $pos.nodeAfter, $pos.before(i), event, true) + : f(view, pos, $pos.node(i), $pos.before(i), event, false))) + return true + } + return false +} + +function updateSelection(view, selection, origin) { + if (!view.focused) view.focus() + let tr = view.state.tr.setSelection(selection) + if (origin == "pointer") tr.setMeta("pointer", true) + view.dispatch(tr) +} + +function selectClickedLeaf(view, inside) { + if (inside == -1) return false + let $pos = view.state.doc.resolve(inside), node = $pos.nodeAfter + if (node && node.isAtom && NodeSelection.isSelectable(node)) { + updateSelection(view, new NodeSelection($pos), "pointer") + return true + } + return false +} + +function selectClickedNode(view, inside) { + if (inside == -1) return false + let sel = view.state.selection, selectedNode, selectAt + if (sel instanceof NodeSelection) selectedNode = sel.node + + let $pos = view.state.doc.resolve(inside) + for (let i = $pos.depth + 1; i > 0; i--) { + let node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i) + if (NodeSelection.isSelectable(node)) { + if (selectedNode && sel.$from.depth > 0 && + i >= sel.$from.depth && $pos.before(sel.$from.depth + 1) == sel.$from.pos) + selectAt = $pos.before(sel.$from.depth) + else + selectAt = $pos.before(i) + break + } + } + + if (selectAt != null) { + updateSelection(view, NodeSelection.create(view.state.doc, selectAt), "pointer") + return true + } else { + return false + } +} + +function handleSingleClick(view, pos, inside, event, selectNode) { + return runHandlerOnContext(view, "handleClickOn", pos, inside, event) || + view.someProp("handleClick", f => f(view, pos, event)) || + (selectNode ? selectClickedNode(view, inside) : selectClickedLeaf(view, inside)) +} + +function handleDoubleClick(view, pos, inside, event) { + return runHandlerOnContext(view, "handleDoubleClickOn", pos, inside, event) || + view.someProp("handleDoubleClick", f => f(view, pos, event)) +} + +function handleTripleClick(view, pos, inside, event) { + return runHandlerOnContext(view, "handleTripleClickOn", pos, inside, event) || + view.someProp("handleTripleClick", f => f(view, pos, event)) || + defaultTripleClick(view, inside) +} + +function defaultTripleClick(view, inside) { + let doc = view.state.doc + if (inside == -1) { + if (doc.inlineContent) { + updateSelection(view, TextSelection.create(doc, 0, doc.content.size), "pointer") + return true + } + return false + } + + let $pos = doc.resolve(inside) + for (let i = $pos.depth + 1; i > 0; i--) { + let node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i) + let nodePos = $pos.before(i) + if (node.inlineContent) + updateSelection(view, TextSelection.create(doc, nodePos + 1, nodePos + 1 + node.content.size), "pointer") + else if (NodeSelection.isSelectable(node)) + updateSelection(view, NodeSelection.create(doc, nodePos), "pointer") + else + continue + return true + } +} + +function forceDOMFlush(view) { + return endComposition(view) +} + +const selectNodeModifier = browser.mac ? "metaKey" : "ctrlKey" + +handlers.mousedown = (view, event) => { + view.shiftKey = event.shiftKey + let flushed = forceDOMFlush(view) + let now = Date.now(), type = "singleClick" + if (now - view.lastClick.time < 500 && isNear(event, view.lastClick) && !event[selectNodeModifier]) { + if (view.lastClick.type == "singleClick") type = "doubleClick" + else if (view.lastClick.type == "doubleClick") type = "tripleClick" + } + view.lastClick = {time: now, x: event.clientX, y: event.clientY, type} + + let pos = view.posAtCoords(eventCoords(event)) + if (!pos) return + + if (type == "singleClick") + view.mouseDown = new MouseDown(view, pos, event, flushed) + else if ((type == "doubleClick" ? handleDoubleClick : handleTripleClick)(view, pos.pos, pos.inside, event)) + event.preventDefault() + else + setSelectionOrigin(view, "pointer") +} + +class MouseDown { + constructor(view, pos, event, flushed) { + this.view = view + this.startDoc = view.state.doc + this.pos = pos + this.event = event + this.flushed = flushed + this.selectNode = event[selectNodeModifier] + this.allowDefault = event.shiftKey + + let targetNode, targetPos + if (pos.inside > -1) { + targetNode = view.state.doc.nodeAt(pos.inside) + targetPos = pos.inside + } else { + let $pos = view.state.doc.resolve(pos.pos) + targetNode = $pos.parent + targetPos = $pos.depth ? $pos.before() : 0 + } + + this.mightDrag = null + + const target = flushed ? null : event.target + const targetDesc = target ? view.docView.nearestDesc(target, true) : null + this.target = targetDesc ? targetDesc.dom : null + + if (targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false || + view.state.selection instanceof NodeSelection && targetPos == view.state.selection.from) + this.mightDrag = {node: targetNode, + pos: targetPos, + addAttr: this.target && !this.target.draggable, + setUneditable: this.target && browser.gecko && !this.target.hasAttribute("contentEditable")} + + if (this.target && this.mightDrag && (this.mightDrag.addAttr || this.mightDrag.setUneditable)) { + this.view.domObserver.stop() + if (this.mightDrag.addAttr) this.target.draggable = true + if (this.mightDrag.setUneditable) + setTimeout(() => this.target.setAttribute("contentEditable", "false"), 20) + this.view.domObserver.start() + } + + view.root.addEventListener("mouseup", this.up = this.up.bind(this)) + view.root.addEventListener("mousemove", this.move = this.move.bind(this)) + setSelectionOrigin(view, "pointer") + } + + done() { + this.view.root.removeEventListener("mouseup", this.up) + this.view.root.removeEventListener("mousemove", this.move) + if (this.mightDrag && this.target) { + this.view.domObserver.stop() + if (this.mightDrag.addAttr) this.target.draggable = false + if (this.mightDrag.setUneditable) this.target.removeAttribute("contentEditable") + this.view.domObserver.start() + } + this.view.mouseDown = null + } + + up(event) { + this.done() + + if (!this.view.dom.contains(event.target.nodeType == 3 ? event.target.parentNode : event.target)) + return + + let pos = this.pos + if (this.view.state.doc != this.startDoc) pos = this.view.posAtCoords(eventCoords(event)) + + if (this.allowDefault || !pos) { + setSelectionOrigin(this.view, "pointer") + } else if (handleSingleClick(this.view, pos.pos, pos.inside, event, this.selectNode)) { + event.preventDefault() + } else if (this.flushed || + // Chrome will sometimes treat a node selection as a + // cursor, but still report that the node is selected + // when asked through getSelection. You'll then get a + // situation where clicking at the point where that + // (hidden) cursor is doesn't change the selection, and + // thus doesn't get a reaction from ProseMirror. This + // works around that. + (browser.chrome && !(this.view.state.selection instanceof TextSelection) && + (pos.pos == this.view.state.selection.from || pos.pos == this.view.state.selection.to))) { + updateSelection(this.view, Selection.near(this.view.state.doc.resolve(pos.pos)), "pointer") + event.preventDefault() + } else { + setSelectionOrigin(this.view, "pointer") + } + } + + move(event) { + if (!this.allowDefault && (Math.abs(this.event.x - event.clientX) > 4 || + Math.abs(this.event.y - event.clientY) > 4)) + this.allowDefault = true + setSelectionOrigin(this.view, "pointer") + } +} + +handlers.touchdown = view => { + forceDOMFlush(view) + setSelectionOrigin(view, "pointer") +} + +handlers.contextmenu = view => forceDOMFlush(view) + +function inOrNearComposition(view, event) { + if (view.composing) return true + // See https://www.stum.de/2016/06/24/handling-ime-events-in-javascript/. + // On Japanese input method editors (IMEs), the Enter key is used to confirm character + // selection. On Safari, when Enter is pressed, compositionend and keydown events are + // emitted. The keydown event triggers newline insertion, which we don't want. + // This method returns true if the keydown event should be ignored. + // We only ignore it once, as pressing Enter a second time *should* insert a newline. + // Furthermore, the keydown event timestamp must be close to the compositionEndedAt timestamp. + // This guards against the case where compositionend is triggered without the keyboard + // (e.g. character confirmation may be done with the mouse), and keydown is triggered + // afterwards- we wouldn't want to ignore the keydown event in this case. + if (browser.safari && Math.abs(event.timeStamp - view.compositionEndedAt) < 500) { + view.compositionEndedAt = -2e8 + return true + } + return false +} + +// Drop active composition after 5 seconds of inactivity on Android +const timeoutComposition = browser.android ? 5000 : -1 + +editHandlers.compositionstart = editHandlers.compositionupdate = view => { + if (!view.composing) { + view.domObserver.flush() + let {state} = view, $pos = state.selection.$from + if (state.selection.empty && + (state.storedMarks || (!$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some(m => m.type.spec.inclusive === false)))) { + // Need to wrap the cursor in mark nodes different from the ones in the DOM context + view.markCursor = view.state.storedMarks || $pos.marks() + endComposition(view, true) + view.markCursor = null + } else { + endComposition(view) + // In firefox, if the cursor is after but outside a marked node, + // the inserted text won't inherit the marks. So this moves it + // inside if necessary. + if (browser.gecko && state.selection.empty && $pos.parentOffset && !$pos.textOffset && $pos.nodeBefore.marks.length) { + let sel = view.root.getSelection() + for (let node = sel.focusNode, offset = sel.focusOffset; node && node.nodeType == 1 && offset != 0;) { + let before = offset < 0 ? node.lastChild : node.childNodes[offset - 1] + if (before.nodeType == 3) { + sel.collapse(before, before.nodeValue.length) + break + } else { + node = before + offset = -1 + } + } + } + } + view.composing = true + } + scheduleComposeEnd(view, timeoutComposition) +} + +editHandlers.compositionend = (view, event) => { + if (view.composing) { + view.composing = false + view.compositionEndedAt = event.timeStamp + scheduleComposeEnd(view, 20) + } +} + +function scheduleComposeEnd(view, delay) { + clearTimeout(view.composingTimeout) + if (delay > -1) view.composingTimeout = setTimeout(() => endComposition(view), delay) +} + +export function endComposition(view, forceUpdate) { + view.composing = false + while (view.compositionNodes.length > 0) view.compositionNodes.pop().markParentsDirty() + if (forceUpdate || view.docView.dirty) { + view.updateState(view.state) + return true + } + return false +} + +function captureCopy(view, dom) { + // The extra wrapper is somehow necessary on IE/Edge to prevent the + // content from being mangled when it is put onto the clipboard + let doc = view.dom.ownerDocument + let wrap = doc.body.appendChild(doc.createElement("div")) + wrap.appendChild(dom) + wrap.style.cssText = "position: fixed; left: -10000px; top: 10px" + let sel = getSelection(), range = doc.createRange() + range.selectNodeContents(dom) + // Done because IE will fire a selectionchange moving the selection + // to its start when removeAllRanges is called and the editor still + // has focus (which will mess up the editor's selection state). + view.dom.blur() + sel.removeAllRanges() + sel.addRange(range) + setTimeout(() => { + doc.body.removeChild(wrap) + view.focus() + }, 50) +} + +// This is very crude, but unfortunately both these browsers _pretend_ +// that they have a clipboard API—all the objects and methods are +// there, they just don't work, and they are hard to test. +const brokenClipboardAPI = (browser.ie && browser.ie_version < 15) || + (browser.ios && browser.webkit_version < 604) + +handlers.copy = editHandlers.cut = (view, e) => { + let sel = view.state.selection, cut = e.type == "cut" + if (sel.empty) return + + // IE and Edge's clipboard interface is completely broken + let data = brokenClipboardAPI ? null : e.clipboardData + let slice = sel.content(), {dom, text} = serializeForClipboard(view, slice) + if (data) { + e.preventDefault() + data.clearData() + data.setData("text/html", dom.innerHTML) + data.setData("text/plain", text) + } else { + captureCopy(view, dom) + } + if (cut) view.dispatch(view.state.tr.deleteSelection().scrollIntoView().setMeta("uiEvent", "cut")) +} + +function sliceSingleNode(slice) { + return slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1 ? slice.content.firstChild : null +} + +function capturePaste(view, e) { + let doc = view.dom.ownerDocument + let plainText = view.shiftKey || view.state.selection.$from.parent.type.spec.code + let target = doc.body.appendChild(doc.createElement(plainText ? "textarea" : "div")) + if (!plainText) target.contentEditable = "true" + target.style.cssText = "position: fixed; left: -10000px; top: 10px" + target.focus() + setTimeout(() => { + view.focus() + doc.body.removeChild(target) + if (plainText) doPaste(view, target.value, null, e) + else doPaste(view, target.textContent, target.innerHTML, e) + }, 50) +} + +function doPaste(view, text, html, e) { + let slice = parseFromClipboard(view, text, html, view.shiftKey, view.state.selection.$from) + if (view.someProp("handlePaste", f => f(view, e, slice || Slice.empty)) || !slice) return + + let singleNode = sliceSingleNode(slice) + let tr = singleNode ? view.state.tr.replaceSelectionWith(singleNode, view.shiftKey) : view.state.tr.replaceSelection(slice) + view.dispatch(tr.scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste")) +} + +editHandlers.paste = (view, e) => { + let data = brokenClipboardAPI ? null : e.clipboardData + let html = data && data.getData("text/html"), text = data && data.getData("text/plain") + if (data && (html || text || data.files.length)) { + doPaste(view, text, html, e) + e.preventDefault() + } else { + capturePaste(view, e) + } +} + +class Dragging { + constructor(slice, move) { + this.slice = slice + this.move = move + } +} + +const dragCopyModifier = browser.mac ? "altKey" : "ctrlKey" + +handlers.dragstart = (view, e) => { + let mouseDown = view.mouseDown + if (mouseDown) mouseDown.done() + if (!e.dataTransfer) return + + let sel = view.state.selection + let pos = sel.empty ? null : view.posAtCoords(eventCoords(e)) + if (pos && pos.pos >= sel.from && pos.pos <= (sel instanceof NodeSelection ? sel.to - 1: sel.to)) { + // In selection + } else if (mouseDown && mouseDown.mightDrag) { + view.dispatch(view.state.tr.setSelection(NodeSelection.create(view.state.doc, mouseDown.mightDrag.pos))) + } else if (e.target && e.target.nodeType == 1) { + let desc = view.docView.nearestDesc(e.target, true) + if (!desc || !desc.node.type.spec.draggable || desc == view.docView) return + view.dispatch(view.state.tr.setSelection(NodeSelection.create(view.state.doc, desc.posBefore))) + } + let slice = view.state.selection.content(), {dom, text} = serializeForClipboard(view, slice) + e.dataTransfer.clearData() + e.dataTransfer.setData(brokenClipboardAPI ? "Text" : "text/html", dom.innerHTML) + if (!brokenClipboardAPI) e.dataTransfer.setData("text/plain", text) + view.dragging = new Dragging(slice, !e[dragCopyModifier]) +} + +handlers.dragend = view => { + window.setTimeout(() => view.dragging = null, 50) +} + +editHandlers.dragover = editHandlers.dragenter = (_, e) => e.preventDefault() + +editHandlers.drop = (view, e) => { + let dragging = view.dragging + view.dragging = null + + if (!e.dataTransfer) return + + let eventPos = view.posAtCoords(eventCoords(e)) + if (!eventPos) return + let $mouse = view.state.doc.resolve(eventPos.pos) + if (!$mouse) return + let slice = dragging && dragging.slice || + parseFromClipboard(view, e.dataTransfer.getData(brokenClipboardAPI ? "Text" : "text/plain"), + brokenClipboardAPI ? null : e.dataTransfer.getData("text/html"), false, $mouse) + if (!slice) return + + e.preventDefault() + if (view.someProp("handleDrop", f => f(view, e, slice, dragging && dragging.move))) return + let insertPos = slice ? dropPoint(view.state.doc, $mouse.pos, slice) : $mouse.pos + if (insertPos == null) insertPos = $mouse.pos + + let tr = view.state.tr + if (dragging && dragging.move) tr.deleteSelection() + + let pos = tr.mapping.map(insertPos) + let isNode = slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1 + let beforeInsert = tr.doc + if (isNode) + tr.replaceRangeWith(pos, pos, slice.content.firstChild) + else + tr.replaceRange(pos, pos, slice) + if (tr.doc.eq(beforeInsert)) return + + let $pos = tr.doc.resolve(pos) + if (isNode && NodeSelection.isSelectable(slice.content.firstChild) && + $pos.nodeAfter && $pos.nodeAfter.sameMarkup(slice.content.firstChild)) + tr.setSelection(new NodeSelection($pos)) + else + tr.setSelection(selectionBetween(view, $pos, tr.doc.resolve(tr.mapping.map(insertPos)))) + view.focus() + view.dispatch(tr.setMeta("uiEvent", "drop")) +} + +handlers.focus = view => { + if (!view.focused) { + view.domObserver.stop() + view.dom.classList.add("ProseMirror-focused") + view.domObserver.start() + view.focused = true + } +} + +handlers.blur = view => { + if (view.focused) { + view.domObserver.stop() + view.dom.classList.remove("ProseMirror-focused") + view.domObserver.start() + view.domObserver.currentSelection.set({}) + view.focused = false + } +} + +handlers.beforeinput = (view, event) => { + // We should probably do more with beforeinput events, but support + // is so spotty that I'm still waiting to see where they are going. + + // Very specific hack to deal with backspace sometimes failing on + // Chrome Android when after an uneditable node. + if (browser.chrome && browser.android && event.inputType == "deleteContentBackward") { + let {domChangeCount} = view + setTimeout(() => { + if (view.domChangeCount != domChangeCount) return // Event already had some effect + // This bug tends to close the virtual keyboard, so we refocus + view.dom.blur() + view.focus() + if (view.someProp("handleKeyDown", f => f(view, keyEvent(8, "Backspace")))) return + let {$cursor} = view.state.selection + // Crude approximation of backspace behavior when no command handled it + if ($cursor && $cursor.pos > 0) view.dispatch(view.state.tr.delete($cursor.pos - 1, $cursor.pos).scrollIntoView()) + }, 50) + } +} + +// Make sure all handlers get registered +for (let prop in editHandlers) handlers[prop] = editHandlers[prop] diff --git a/packages/tiptap/node_modules/prosemirror-view/src/selection.js b/packages/tiptap/node_modules/prosemirror-view/src/selection.js new file mode 100644 index 0000000000..97d73bb21d --- /dev/null +++ b/packages/tiptap/node_modules/prosemirror-view/src/selection.js @@ -0,0 +1,167 @@ +import {TextSelection, NodeSelection} from "prosemirror-state" + +import browser from "./browser" +import {selectionCollapsed, isEquivalentPosition, domIndex} from "./dom" + +export function selectionFromDOM(view, origin) { + let domSel = view.root.getSelection(), doc = view.state.doc + let nearestDesc = view.docView.nearestDesc(domSel.focusNode), inWidget = nearestDesc && nearestDesc.size == 0 + let head = view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset) + let $head = doc.resolve(head), $anchor, selection + if (selectionCollapsed(domSel)) { + $anchor = $head + while (nearestDesc && !nearestDesc.node) nearestDesc = nearestDesc.parent + if (nearestDesc && nearestDesc.node.isAtom && NodeSelection.isSelectable(nearestDesc.node) && nearestDesc.parent) { + let pos = nearestDesc.posBefore + selection = new NodeSelection(head == pos ? $head : doc.resolve(pos)) + } + } else { + $anchor = doc.resolve(view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset)) + } + + if (!selection) { + let bias = origin == "pointer" || (view.state.selection.head < $head.pos && !inWidget) ? 1 : -1 + selection = selectionBetween(view, $anchor, $head, bias) + } + return selection +} + +export function selectionToDOM(view, force) { + let sel = view.state.selection + syncNodeSelection(view, sel) + + if (view.editable ? !view.hasFocus() : !(hasSelection(view) && document.activeElement.contains(view.dom))) return + + view.domObserver.disconnectSelection() + + if (view.cursorWrapper) { + selectCursorWrapper(view) + } else { + let {anchor, head} = sel, resetEditableFrom, resetEditableTo + if (brokenSelectBetweenUneditable && !(sel instanceof TextSelection)) { + if (!sel.$from.parent.inlineContent) + resetEditableFrom = temporarilyEditableNear(view, sel.from) + if (!sel.empty && !sel.$from.parent.inlineContent) + resetEditableTo = temporarilyEditableNear(view, sel.to) + } + view.docView.setSelection(anchor, head, view.root, force) + if (brokenSelectBetweenUneditable) { + if (resetEditableFrom) resetEditableFrom.contentEditable = "false" + if (resetEditableTo) resetEditableTo.contentEditable = "false" + } + if (sel.visible) { + view.dom.classList.remove("ProseMirror-hideselection") + } else if (anchor != head) { + view.dom.classList.add("ProseMirror-hideselection") + if ("onselectionchange" in document) removeClassOnSelectionChange(view) + } + } + + view.domObserver.setCurSelection() + view.domObserver.connectSelection() +} + +// Kludge to work around Webkit not allowing a selection to start/end +// between non-editable block nodes. We briefly make something +// editable, set the selection, then set it uneditable again. + +const brokenSelectBetweenUneditable = browser.safari || browser.chrome && browser.chrome_version < 63 + +function temporarilyEditableNear(view, pos) { + let {node, offset} = view.docView.domFromPos(pos) + let after = offset < node.childNodes.length ? node.childNodes[offset] : null + let before = offset ? node.childNodes[offset - 1] : null + if ((!after || after.contentEditable == "false") && (!before || before.contentEditable == "false")) { + if (after) { + after.contentEditable = "true" + return after + } else if (before) { + before.contentEditable = "true" + return before + } + } +} + +function removeClassOnSelectionChange(view) { + let doc = view.dom.ownerDocument + doc.removeEventListener("selectionchange", view.hideSelectionGuard) + let domSel = view.root.getSelection() + let node = domSel.anchorNode, offset = domSel.anchorOffset + doc.addEventListener("selectionchange", view.hideSelectionGuard = () => { + if (domSel.anchorNode != node || domSel.anchorOffset != offset) { + doc.removeEventListener("selectionchange", view.hideSelectionGuard) + view.dom.classList.remove("ProseMirror-hideselection") + } + }) +} + +function selectCursorWrapper(view) { + let domSel = view.root.getSelection(), range = document.createRange() + let node = view.cursorWrapper.dom, img = node.nodeName == "IMG" + if (img) range.setEnd(node.parentNode, domIndex(node) + 1) + else range.setEnd(node, 0) + range.collapse(false) + domSel.removeAllRanges() + domSel.addRange(range) + // Kludge to kill 'control selection' in IE11 when selecting an + // invisible cursor wrapper, since that would result in those weird + // resize handles and a selection that considers the absolutely + // positioned wrapper, rather than the root editable node, the + // focused element. + if (!img && !view.state.selection.visible && browser.ie && browser.ie_version <= 11) { + node.disabled = true + node.disabled = false + } +} + +export function syncNodeSelection(view, sel) { + if (sel instanceof NodeSelection) { + let desc = view.docView.descAt(sel.from) + if (desc != view.lastSelectedViewDesc) { + clearNodeSelection(view) + if (desc) desc.selectNode() + view.lastSelectedViewDesc = desc + } + } else { + clearNodeSelection(view) + } +} + +// Clear all DOM statefulness of the last node selection. +function clearNodeSelection(view) { + if (view.lastSelectedViewDesc) { + if (view.lastSelectedViewDesc.parent) + view.lastSelectedViewDesc.deselectNode() + view.lastSelectedViewDesc = null + } +} + +export function selectionBetween(view, $anchor, $head, bias) { + return view.someProp("createSelectionBetween", f => f(view, $anchor, $head)) + || TextSelection.between($anchor, $head, bias) +} + +export function hasFocusAndSelection(view) { + if (view.editable && view.root.activeElement != view.dom) return false + return hasSelection(view) +} + +export function hasSelection(view) { + let sel = view.root.getSelection() + if (!sel.anchorNode) return false + try { + // Firefox will raise 'permission denied' errors when accessing + // properties of `sel.anchorNode` when it's in a generated CSS + // element. + return view.dom.contains(sel.anchorNode.nodeType == 3 ? sel.anchorNode.parentNode : sel.anchorNode) && + (view.editable || view.dom.contains(sel.focusNode.nodeType == 3 ? sel.focusNode.parentNode : sel.focusNode)) + } catch(_) { + return false + } +} + +export function anchorInRightPlace(view) { + let anchorDOM = view.docView.domFromPos(view.state.selection.anchor) + let domSel = view.root.getSelection() + return isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset) +} diff --git a/packages/tiptap/node_modules/prosemirror-view/src/viewdesc.js b/packages/tiptap/node_modules/prosemirror-view/src/viewdesc.js new file mode 100644 index 0000000000..ad75372727 --- /dev/null +++ b/packages/tiptap/node_modules/prosemirror-view/src/viewdesc.js @@ -0,0 +1,1285 @@ +import {DOMSerializer, Fragment, Mark} from "prosemirror-model" +import {TextSelection} from "prosemirror-state" + +import {domIndex, isEquivalentPosition, nodeSize} from "./dom" +import browser from "./browser" + +// NodeView:: interface +// +// By default, document nodes are rendered using the result of the +// [`toDOM`](#model.NodeSpec.toDOM) method of their spec, and managed +// entirely by the editor. For some use cases, such as embedded +// node-specific editing interfaces, you want more control over +// the behavior of a node's in-editor representation, and need to +// [define](#view.EditorProps.nodeViews) a custom node view. +// +// Objects returned as node views must conform to this interface. +// +// dom:: ?dom.Node +// The outer DOM node that represents the document node. When not +// given, the default strategy is used to create a DOM node. +// +// contentDOM:: ?dom.Node +// The DOM node that should hold the node's content. Only meaningful +// if the node view also defines a `dom` property and if its node +// type is not a leaf node type. When this is present, ProseMirror +// will take care of rendering the node's children into it. When it +// is not present, the node view itself is responsible for rendering +// (or deciding not to render) its child nodes. +// +// update:: ?(node: Node, decorations: [Decoration]) → bool +// When given, this will be called when the view is updating itself. +// It will be given a node (possibly of a different type), and an +// array of active decorations (which are automatically drawn, and +// the node view may ignore if it isn't interested in them), and +// should return true if it was able to update to that node, and +// false otherwise. If the node view has a `contentDOM` property (or +// no `dom` property), updating its child nodes will be handled by +// ProseMirror. +// +// selectNode:: ?() +// Can be used to override the way the node's selected status (as a +// node selection) is displayed. +// +// deselectNode:: ?() +// When defining a `selectNode` method, you should also provide a +// `deselectNode` method to remove the effect again. +// +// setSelection:: ?(anchor: number, head: number, root: dom.Document) +// This will be called to handle setting the selection inside the +// node. The `anchor` and `head` positions are relative to the start +// of the node. By default, a DOM selection will be created between +// the DOM positions corresponding to those positions, but if you +// override it you can do something else. +// +// stopEvent:: ?(event: dom.Event) → bool +// Can be used to prevent the editor view from trying to handle some +// or all DOM events that bubble up from the node view. Events for +// which this returns true are not handled by the editor. +// +// ignoreMutation:: ?(dom.MutationRecord) → bool +// Called when a DOM +// [mutation](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) +// or a selection change happens within the view. When the change is +// a selection change, the record will have a `type` property of +// `"selection"` (which doesn't occur for native mutation records). +// Return false if the editor should re-read the selection or +// re-parse the range around the mutation, true if it can safely be +// ignored. +// +// destroy:: ?() +// Called when the node view is removed from the editor or the whole +// editor is destroyed. + +// View descriptions are data structures that describe the DOM that is +// used to represent the editor's content. They are used for: +// +// - Incremental redrawing when the document changes +// +// - Figuring out what part of the document a given DOM position +// corresponds to +// +// - Wiring in custom implementations of the editing interface for a +// given node +// +// They form a doubly-linked mutable tree, starting at `view.docView`. + +const NOT_DIRTY = 0, CHILD_DIRTY = 1, CONTENT_DIRTY = 2, NODE_DIRTY = 3 + +// Superclass for the various kinds of descriptions. Defines their +// basic structure and shared methods. +class ViewDesc { + // : (?ViewDesc, [ViewDesc], dom.Node, ?dom.Node) + constructor(parent, children, dom, contentDOM) { + this.parent = parent + this.children = children + this.dom = dom + // An expando property on the DOM node provides a link back to its + // description. + dom.pmViewDesc = this + // This is the node that holds the child views. It may be null for + // descs that don't have children. + this.contentDOM = contentDOM + this.dirty = NOT_DIRTY + } + + // Used to check whether a given description corresponds to a + // widget/mark/node. + matchesWidget() { return false } + matchesMark() { return false } + matchesNode() { return false } + matchesHack() { return false } + + get beforePosition() { return false } + + // : () → ?ParseRule + // When parsing in-editor content (in domchange.js), we allow + // descriptions to determine the parse rules that should be used to + // parse them. + parseRule() { return null } + + // : (dom.Event) → bool + // Used by the editor's event handler to ignore events that come + // from certain descs. + stopEvent() { return false } + + // The size of the content represented by this desc. + get size() { + let size = 0 + for (let i = 0; i < this.children.length; i++) size += this.children[i].size + return size + } + + // For block nodes, this represents the space taken up by their + // start/end tokens. + get border() { return 0 } + + destroy() { + this.parent = null + if (this.dom.pmViewDesc == this) this.dom.pmViewDesc = null + for (let i = 0; i < this.children.length; i++) + this.children[i].destroy() + } + + posBeforeChild(child) { + for (let i = 0, pos = this.posAtStart; i < this.children.length; i++) { + let cur = this.children[i] + if (cur == child) return pos + pos += cur.size + } + } + + get posBefore() { + return this.parent.posBeforeChild(this) + } + + get posAtStart() { + return this.parent ? this.parent.posBeforeChild(this) + this.border : 0 + } + + get posAfter() { + return this.posBefore + this.size + } + + get posAtEnd() { + return this.posAtStart + this.size - 2 * this.border + } + + // : (dom.Node, number, ?number) → number + localPosFromDOM(dom, offset, bias) { + // If the DOM position is in the content, use the child desc after + // it to figure out a position. + if (this.contentDOM && this.contentDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode)) { + if (bias < 0) { + let domBefore, desc + if (dom == this.contentDOM) { + domBefore = dom.childNodes[offset - 1] + } else { + while (dom.parentNode != this.contentDOM) dom = dom.parentNode + domBefore = dom.previousSibling + } + while (domBefore && !((desc = domBefore.pmViewDesc) && desc.parent == this)) domBefore = domBefore.previousSibling + return domBefore ? this.posBeforeChild(desc) + desc.size : this.posAtStart + } else { + let domAfter, desc + if (dom == this.contentDOM) { + domAfter = dom.childNodes[offset] + } else { + while (dom.parentNode != this.contentDOM) dom = dom.parentNode + domAfter = dom.nextSibling + } + while (domAfter && !((desc = domAfter.pmViewDesc) && desc.parent == this)) domAfter = domAfter.nextSibling + return domAfter ? this.posBeforeChild(desc) : this.posAtEnd + } + } + // Otherwise, use various heuristics, falling back on the bias + // parameter, to determine whether to return the position at the + // start or at the end of this view desc. + let atEnd + if (this.contentDOM && this.contentDOM != this.dom && this.dom.contains(this.contentDOM)) { + atEnd = dom.compareDocumentPosition(this.contentDOM) & 2 + } else if (this.dom.firstChild) { + if (offset == 0) for (let search = dom;; search = search.parentNode) { + if (search == this.dom) { atEnd = false; break } + if (search.parentNode.firstChild != search) break + } + if (atEnd == null && offset == dom.childNodes.length) for (let search = dom;; search = search.parentNode) { + if (search == this.dom) { atEnd = true; break } + if (search.parentNode.lastChild != search) break + } + } + return (atEnd == null ? bias > 0 : atEnd) ? this.posAtEnd : this.posAtStart + } + + // Scan up the dom finding the first desc that is a descendant of + // this one. + nearestDesc(dom, onlyNodes) { + for (let first = true, cur = dom; cur; cur = cur.parentNode) { + let desc = this.getDesc(cur) + if (desc && (!onlyNodes || desc.node)) { + // If dom is outside of this desc's nodeDOM, don't count it. + if (first && desc.nodeDOM && !(desc.nodeDOM.nodeType == 1 ? desc.nodeDOM.contains(dom) : desc.nodeDOM == dom)) first = false + else return desc + } + } + } + + getDesc(dom) { + let desc = dom.pmViewDesc + for (let cur = desc; cur; cur = cur.parent) if (cur == this) return desc + } + + posFromDOM(dom, offset, bias) { + for (let scan = dom;; scan = scan.parentNode) { + let desc = this.getDesc(scan) + if (desc) return desc.localPosFromDOM(dom, offset, bias) + } + } + + // : (number) → ?NodeViewDesc + // Find the desc for the node after the given pos, if any. (When a + // parent node overrode rendering, there might not be one.) + descAt(pos) { + for (let i = 0, offset = 0; i < this.children.length; i++) { + let child = this.children[i], end = offset + child.size + if (offset == pos && end != offset) { + while (!child.border && child.children.length) child = child.children[0] + return child + } + if (pos < end) return child.descAt(pos - offset - child.border) + offset = end + } + } + + // : (number) → {node: dom.Node, offset: number} + domFromPos(pos) { + if (!this.contentDOM) return {node: this.dom, offset: 0} + for (let offset = 0, i = 0;; i++) { + if (offset == pos) { + while (i < this.children.length && (this.children[i].beforePosition || this.children[i].dom.parentNode != this.contentDOM)) i++ + return {node: this.contentDOM, + offset: i == this.children.length ? this.contentDOM.childNodes.length : domIndex(this.children[i].dom)} + } + if (i == this.children.length) throw new Error("Invalid position " + pos) + let child = this.children[i], end = offset + child.size + if (pos < end) return child.domFromPos(pos - offset - child.border) + offset = end + } + } + + // Used to find a DOM range in a single parent for a given changed + // range. + parseRange(from, to, base = 0) { + if (this.children.length == 0) + return {node: this.contentDOM, from, to, fromOffset: 0, toOffset: this.contentDOM.childNodes.length} + + let fromOffset = -1, toOffset = -1 + for (let offset = base, i = 0;; i++) { + let child = this.children[i], end = offset + child.size + if (fromOffset == -1 && from <= end) { + let childBase = offset + child.border + // FIXME maybe descend mark views to parse a narrower range? + if (from >= childBase && to <= end - child.border && child.node && + child.contentDOM && this.contentDOM.contains(child.contentDOM)) + return child.parseRange(from, to, childBase) + + from = offset + for (let j = i; j > 0; j--) { + let prev = this.children[j - 1] + if (prev.size && prev.dom.parentNode == this.contentDOM && !prev.emptyChildAt(1)) { + fromOffset = domIndex(prev.dom) + 1 + break + } + from -= prev.size + } + if (fromOffset == -1) fromOffset = 0 + } + if (fromOffset > -1 && to <= end) { + to = end + for (let j = i + 1; j < this.children.length; j++) { + let next = this.children[j] + if (next.size && next.dom.parentNode == this.contentDOM && !next.emptyChildAt(-1)) { + toOffset = domIndex(next.dom) + break + } + to += next.size + } + if (toOffset == -1) toOffset = this.contentDOM.childNodes.length + break + } + offset = end + } + return {node: this.contentDOM, from, to, fromOffset, toOffset} + } + + emptyChildAt(side) { + if (this.border || !this.contentDOM || !this.children.length) return false + let child = this.children[side < 0 ? 0 : this.children.length - 1] + return child.size == 0 || child.emptyChildAt(side) + } + + // : (number) → dom.Node + domAfterPos(pos) { + let {node, offset} = this.domFromPos(pos) + if (node.nodeType != 1 || offset == node.childNodes.length) + throw new RangeError("No node after pos " + pos) + return node.childNodes[offset] + } + + // : (number, number, dom.Document) + // View descs are responsible for setting any selection that falls + // entirely inside of them, so that custom implementations can do + // custom things with the selection. Note that this falls apart when + // a selection starts in such a node and ends in another, in which + // case we just use whatever domFromPos produces as a best effort. + setSelection(anchor, head, root, force) { + // If the selection falls entirely in a child, give it to that child + let from = Math.min(anchor, head), to = Math.max(anchor, head) + for (let i = 0, offset = 0; i < this.children.length; i++) { + let child = this.children[i], end = offset + child.size + if (from > offset && to < end) + return child.setSelection(anchor - offset - child.border, head - offset - child.border, root, force) + offset = end + } + + let anchorDOM = this.domFromPos(anchor), headDOM = this.domFromPos(head) + let domSel = root.getSelection(), range = document.createRange() + if (!force && + isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset) && + isEquivalentPosition(headDOM.node, headDOM.offset, domSel.focusNode, domSel.focusOffset)) + return + + // Selection.extend can be used to create an 'inverted' selection + // (one where the focus is before the anchor), but not all + // browsers support it yet. + if (domSel.extend) { + range.setEnd(anchorDOM.node, anchorDOM.offset) + range.collapse(false) + } else { + if (anchor > head) { let tmp = anchorDOM; anchorDOM = headDOM; headDOM = tmp } + range.setEnd(headDOM.node, headDOM.offset) + range.setStart(anchorDOM.node, anchorDOM.offset) + } + domSel.removeAllRanges() + domSel.addRange(range) + if (domSel.extend) + domSel.extend(headDOM.node, headDOM.offset) + } + + // : (dom.MutationRecord) → bool + ignoreMutation(_mutation) { + return !this.contentDOM + } + + get contentLost() { + return this.contentDOM && this.contentDOM != this.dom && !this.dom.contains(this.contentDOM) + } + + // Remove a subtree of the element tree that has been touched + // by a DOM change, so that the next update will redraw it. + markDirty(from, to) { + for (let offset = 0, i = 0; i < this.children.length; i++) { + let child = this.children[i], end = offset + child.size + if (offset == end ? from <= end && to >= offset : from < end && to > offset) { + let startInside = offset + child.border, endInside = end - child.border + if (from >= startInside && to <= endInside) { + this.dirty = from == offset || to == end ? CONTENT_DIRTY : CHILD_DIRTY + if (from == startInside && to == endInside && + (child.contentLost || child.dom.parentNode != this.contentDOM)) child.dirty = NODE_DIRTY + else child.markDirty(from - startInside, to - startInside) + return + } else { + child.dirty = NODE_DIRTY + } + } + offset = end + } + this.dirty = CONTENT_DIRTY + } + + markParentsDirty() { + let level = 1 + for (let node = this.parent; node; node = node.parent) { + let dirty = level == 1 ? CONTENT_DIRTY : CHILD_DIRTY + if (node.dirty < dirty) node.dirty = dirty + } + } +} + +// Reused array to avoid allocating fresh arrays for things that will +// stay empty anyway. +const nothing = [] + +// A widget desc represents a widget decoration, which is a DOM node +// drawn between the document nodes. +class WidgetViewDesc extends ViewDesc { + // : (ViewDesc, Decoration) + constructor(parent, widget, view, pos) { + let self, dom = widget.type.toDOM + if (typeof dom == "function") dom = dom(view, () => { + if (!self) return pos + if (self.parent) return self.parent.posBeforeChild(self) + }) + if (!widget.type.spec.raw) { + if (dom.nodeType != 1) { + let wrap = document.createElement("span") + wrap.appendChild(dom) + dom = wrap + } + dom.contentEditable = false + dom.classList.add("ProseMirror-widget") + } + super(parent, nothing, dom, null) + this.widget = widget + self = this + } + + get beforePosition() { + return this.widget.type.side < 0 + } + + matchesWidget(widget) { + return this.dirty == NOT_DIRTY && widget.type.eq(this.widget.type) + } + + parseRule() { return {ignore: true} } + + stopEvent(event) { + let stop = this.widget.spec.stopEvent + return stop ? stop(event) : false + } +} + +class CompositionViewDesc extends ViewDesc { + constructor(parent, dom, textDOM, text) { + super(parent, nothing, dom, null) + this.textDOM = textDOM + this.text = text + } + + get size() { return this.text.length } + + localPosFromDOM(dom, offset) { + if (dom != this.textDOM) return this.posAtStart + (offset ? this.size : 0) + return this.posAtStart + offset + } + + domFromPos(pos) { + return {node: this.textDOM, offset: pos} + } + + ignoreMutation(mut) { + return mut.type === 'characterData' && mut.target.nodeValue == mut.oldValue + } +} + +// A mark desc represents a mark. May have multiple children, +// depending on how the mark is split. Note that marks are drawn using +// a fixed nesting order, for simplicity and predictability, so in +// some cases they will be split more often than would appear +// necessary. +class MarkViewDesc extends ViewDesc { + // : (ViewDesc, Mark, dom.Node) + constructor(parent, mark, dom, contentDOM) { + super(parent, [], dom, contentDOM) + this.mark = mark + } + + static create(parent, mark, inline, view) { + let custom = view.nodeViews[mark.type.name] + let spec = custom && custom(mark, view, inline) + if (!spec || !spec.dom) + spec = DOMSerializer.renderSpec(document, mark.type.spec.toDOM(mark, inline)) + return new MarkViewDesc(parent, mark, spec.dom, spec.contentDOM || spec.dom) + } + + parseRule() { return {mark: this.mark.type.name, attrs: this.mark.attrs, contentElement: this.contentDOM} } + + matchesMark(mark) { return this.dirty != NODE_DIRTY && this.mark.eq(mark) } + + markDirty(from, to) { + super.markDirty(from, to) + // Move dirty info to nearest node view + if (this.dirty != NOT_DIRTY) { + let parent = this.parent + while (!parent.node) parent = parent.parent + if (parent.dirty < this.dirty) parent.dirty = this.dirty + this.dirty = NOT_DIRTY + } + } + + slice(from, to, view) { + let copy = MarkViewDesc.create(this.parent, this.mark, true, view) + let nodes = this.children, size = this.size + if (to < size) nodes = replaceNodes(nodes, to, size, view) + if (from > 0) nodes = replaceNodes(nodes, 0, from, view) + for (let i = 0; i < nodes.length; i++) nodes[i].parent = copy + copy.children = nodes + return copy + } +} + +// Node view descs are the main, most common type of view desc, and +// correspond to an actual node in the document. Unlike mark descs, +// they populate their child array themselves. +class NodeViewDesc extends ViewDesc { + // : (?ViewDesc, Node, [Decoration], DecorationSet, dom.Node, ?dom.Node, EditorView) + constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos) { + super(parent, node.isLeaf ? nothing : [], dom, contentDOM) + this.nodeDOM = nodeDOM + this.node = node + this.outerDeco = outerDeco + this.innerDeco = innerDeco + if (contentDOM) this.updateChildren(view, pos) + } + + // By default, a node is rendered using the `toDOM` method from the + // node type spec. But client code can use the `nodeViews` spec to + // supply a custom node view, which can influence various aspects of + // the way the node works. + // + // (Using subclassing for this was intentionally decided against, + // since it'd require exposing a whole slew of finnicky + // implementation details to the user code that they probably will + // never need.) + static create(parent, node, outerDeco, innerDeco, view, pos) { + let custom = view.nodeViews[node.type.name], descObj + let spec = custom && custom(node, view, () => { + // (This is a function that allows the custom view to find its + // own position) + if (!descObj) return pos + if (descObj.parent) return descObj.parent.posBeforeChild(descObj) + }, outerDeco) + + let dom = spec && spec.dom, contentDOM = spec && spec.contentDOM + if (node.isText) { + if (!dom) dom = document.createTextNode(node.text) + else if (dom.nodeType != 3) throw new RangeError("Text must be rendered as a DOM text node") + } else if (!dom) { + ;({dom, contentDOM} = DOMSerializer.renderSpec(document, node.type.spec.toDOM(node))) + } + if (!contentDOM && !node.isText && dom.nodeName != "BR") { // Chrome gets confused by
    + if (!dom.hasAttribute("contenteditable")) dom.contentEditable = false + if (node.type.spec.draggable) dom.draggable = true + } + + let nodeDOM = dom + dom = applyOuterDeco(dom, outerDeco, node) + + if (spec) + return descObj = new CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, + spec, view, pos + 1) + else if (node.isText) + return new TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM, view) + else + return new NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos + 1) + } + + parseRule() { + // Experimental kludge to allow opt-in re-parsing of nodes + if (this.node.type.spec.reparseInView) return null + // FIXME the assumption that this can always return the current + // attrs means that if the user somehow manages to change the + // attrs in the dom, that won't be picked up. Not entirely sure + // whether this is a problem + let rule = {node: this.node.type.name, attrs: this.node.attrs} + if (this.node.type.spec.code) rule.preserveWhitespace = "full" + if (this.contentDOM && !this.contentLost) rule.contentElement = this.contentDOM + else rule.getContent = () => this.contentDOM ? Fragment.empty : this.node.content + return rule + } + + matchesNode(node, outerDeco, innerDeco) { + return this.dirty == NOT_DIRTY && node.eq(this.node) && + sameOuterDeco(outerDeco, this.outerDeco) && innerDeco.eq(this.innerDeco) + } + + get size() { return this.node.nodeSize } + + get border() { return this.node.isLeaf ? 0 : 1 } + + // Syncs `this.children` to match `this.node.content` and the local + // decorations, possibly introducing nesting for marks. Then, in a + // separate step, syncs the DOM inside `this.contentDOM` to + // `this.children`. + updateChildren(view, pos) { + let inline = this.node.inlineContent, off = pos + let composition = inline && view.composing && this.localCompositionNode(view, pos) + let updater = new ViewTreeUpdater(this, composition && composition.node) + iterDeco(this.node, this.innerDeco, (widget, i) => { + if (widget.spec.marks) + updater.syncToMarks(widget.spec.marks, inline, view) + else if (widget.type.side >= 0) + updater.syncToMarks(i == this.node.childCount ? Mark.none : this.node.child(i).marks, inline, view) + // If the next node is a desc matching this widget, reuse it, + // otherwise insert the widget as a new view desc. + updater.placeWidget(widget, view, off) + }, (child, outerDeco, innerDeco, i) => { + // Make sure the wrapping mark descs match the node's marks. + updater.syncToMarks(child.marks, inline, view) + // Either find an existing desc that exactly matches this node, + // and drop the descs before it. + updater.findNodeMatch(child, outerDeco, innerDeco, i) || + // Or try updating the next desc to reflect this node. + updater.updateNextNode(child, outerDeco, innerDeco, view, i) || + // Or just add it as a new desc. + updater.addNode(child, outerDeco, innerDeco, view, off) + off += child.nodeSize + }) + // Drop all remaining descs after the current position. + updater.syncToMarks(nothing, inline, view) + if (this.node.isTextblock) updater.addTextblockHacks() + updater.destroyRest() + + // Sync the DOM if anything changed + if (updater.changed || this.dirty == CONTENT_DIRTY) { + // May have to protect focused DOM from being changed if a composition is active + if (composition) this.protectLocalComposition(view, composition) + this.renderChildren() + } + } + + renderChildren() { + renderDescs(this.contentDOM, this.children, NodeViewDesc.is) + if (browser.ios) iosHacks(this.dom) + } + + localCompositionNode(view, pos) { + // Only do something if both the selection and a focused text node + // are inside of this node, and the node isn't already part of a + // view that's a child of this view + let {from, to} = view.state.selection + if (!(view.state.selection instanceof TextSelection) || from < pos || to > pos + this.node.content.size) return + let sel = view.root.getSelection() + let textNode = nearbyTextNode(sel.focusNode, sel.focusOffset) + if (!textNode || !this.dom.contains(textNode.parentNode)) return + + // Find the text in the focused node in the node, stop if it's not + // there (may have been modified through other means, in which + // case it should overwritten) + let text = textNode.nodeValue + let textPos = findTextInFragment(this.node.content, text, from - pos, to - pos) + + return textPos < 0 ? null : {node: textNode, pos: textPos, text} + } + + protectLocalComposition(view, {node, pos, text}) { + // The node is already part of a local view desc, leave it there + if (this.getDesc(node)) return + + // Create a composition view for the orphaned nodes + let topNode = node + for (;; topNode = topNode.parentNode) { + if (topNode.parentNode == this.contentDOM) break + while (topNode.previousSibling) topNode.parentNode.removeChild(topNode.previousSibling) + while (topNode.nextSibling) topNode.parentNode.removeChild(topNode.nextSibling) + if (topNode.pmViewDesc) topNode.pmViewDesc = null + } + let desc = new CompositionViewDesc(this, topNode, node, text) + view.compositionNodes.push(desc) + + // Patch up this.children to contain the composition view + this.children = replaceNodes(this.children, pos, pos + text.length, view, desc) + } + + // : (Node, [Decoration], DecorationSet, EditorView) → bool + // If this desc be updated to match the given node decoration, + // do so and return true. + update(node, outerDeco, innerDeco, view) { + if (this.dirty == NODE_DIRTY || + !node.sameMarkup(this.node)) return false + this.updateInner(node, outerDeco, innerDeco, view) + return true + } + + updateInner(node, outerDeco, innerDeco, view) { + this.updateOuterDeco(outerDeco) + this.node = node + this.innerDeco = innerDeco + if (this.contentDOM) this.updateChildren(view, this.posAtStart) + this.dirty = NOT_DIRTY + } + + updateOuterDeco(outerDeco) { + if (sameOuterDeco(outerDeco, this.outerDeco)) return + let needsWrap = this.nodeDOM.nodeType != 1 + let oldDOM = this.dom + this.dom = patchOuterDeco(this.dom, this.nodeDOM, + computeOuterDeco(this.outerDeco, this.node, needsWrap), + computeOuterDeco(outerDeco, this.node, needsWrap)) + if (this.dom != oldDOM) { + oldDOM.pmViewDesc = null + this.dom.pmViewDesc = this + } + this.outerDeco = outerDeco + } + + // Mark this node as being the selected node. + selectNode() { + this.nodeDOM.classList.add("ProseMirror-selectednode") + if (this.contentDOM || !this.node.type.spec.draggable) this.dom.draggable = true + } + + // Remove selected node marking from this node. + deselectNode() { + this.nodeDOM.classList.remove("ProseMirror-selectednode") + if (this.contentDOM || !this.node.type.spec.draggable) this.dom.draggable = false + } +} + +// Create a view desc for the top-level document node, to be exported +// and used by the view class. +export function docViewDesc(doc, outerDeco, innerDeco, dom, view) { + applyOuterDeco(dom, outerDeco, doc) + return new NodeViewDesc(null, doc, outerDeco, innerDeco, dom, dom, dom, view, 0) +} + +class TextViewDesc extends NodeViewDesc { + constructor(parent, node, outerDeco, innerDeco, dom, nodeDOM, view) { + super(parent, node, outerDeco, innerDeco, dom, null, nodeDOM, view) + } + + parseRule() { + return {skip: this.nodeDOM.parentNode || true} + } + + update(node, outerDeco) { + if (this.dirty == NODE_DIRTY || (this.dirty != NOT_DIRTY && !this.inParent()) || + !node.sameMarkup(this.node)) return false + this.updateOuterDeco(outerDeco) + if ((this.dirty != NOT_DIRTY || node.text != this.node.text) && node.text != this.nodeDOM.nodeValue) + this.nodeDOM.nodeValue = node.text + this.node = node + this.dirty = NOT_DIRTY + return true + } + + inParent() { + let parentDOM = this.parent.contentDOM + for (let n = this.nodeDOM; n; n = n.parentNode) if (n == parentDOM) return true + return false + } + + domFromPos(pos) { + return {node: this.nodeDOM, offset: pos} + } + + localPosFromDOM(dom, offset, bias) { + if (dom == this.nodeDOM) return this.posAtStart + Math.min(offset, this.node.text.length) + return super.localPosFromDOM(dom, offset, bias) + } + + ignoreMutation(mutation) { + return mutation.type != "characterData" && mutation.type != "selection" + } + + slice(from, to, view) { + let node = this.node.cut(from, to), dom = document.createTextNode(node.text) + return new TextViewDesc(this.parent, node, this.outerDeco, this.innerDeco, dom, dom, view) + } +} + +// A dummy desc used to tag trailing BR or span nodes created to work +// around contentEditable terribleness. +class BRHackViewDesc extends ViewDesc { + parseRule() { return {ignore: true} } + matchesHack() { return this.dirty == NOT_DIRTY } +} + +// A separate subclass is used for customized node views, so that the +// extra checks only have to be made for nodes that are actually +// customized. +class CustomNodeViewDesc extends NodeViewDesc { + // : (?ViewDesc, Node, [Decoration], DecorationSet, dom.Node, ?dom.Node, NodeView, EditorView) + constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, spec, view, pos) { + super(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos) + this.spec = spec + } + + // A custom `update` method gets to decide whether the update goes + // through. If it does, and there's a `contentDOM` node, our logic + // updates the children. + update(node, outerDeco, innerDeco, view) { + if (this.dirty == NODE_DIRTY) return false + if (this.spec.update) { + let result = this.spec.update(node, outerDeco) + if (result) this.updateInner(node, outerDeco, innerDeco, view) + return result + } else if (!this.contentDOM && !node.isLeaf) { + return false + } else { + return super.update(node, outerDeco, innerDeco, view) + } + } + + selectNode() { + this.spec.selectNode ? this.spec.selectNode() : super.selectNode() + } + + deselectNode() { + this.spec.deselectNode ? this.spec.deselectNode() : super.deselectNode() + } + + setSelection(anchor, head, root, force) { + this.spec.setSelection ? this.spec.setSelection(anchor, head, root) + : super.setSelection(anchor, head, root, force) + } + + destroy() { + if (this.spec.destroy) this.spec.destroy() + super.destroy() + } + + stopEvent(event) { + return this.spec.stopEvent ? this.spec.stopEvent(event) : false + } + + ignoreMutation(mutation) { + return this.spec.ignoreMutation ? this.spec.ignoreMutation(mutation) : super.ignoreMutation(mutation) + } +} + +// : (dom.Node, [ViewDesc]) +// Sync the content of the given DOM node with the nodes associated +// with the given array of view descs, recursing into mark descs +// because this should sync the subtree for a whole node at a time. +function renderDescs(parentDOM, descs) { + let dom = parentDOM.firstChild + for (let i = 0; i < descs.length; i++) { + let desc = descs[i], childDOM = desc.dom + if (childDOM.parentNode == parentDOM) { + while (childDOM != dom) dom = rm(dom) + dom = dom.nextSibling + } else { + parentDOM.insertBefore(childDOM, dom) + } + if (desc instanceof MarkViewDesc) { + let pos = dom ? dom.previousSibling : parentDOM.lastChild + renderDescs(desc.contentDOM, desc.children) + dom = pos ? pos.nextSibling : parentDOM.firstChild + } + } + while (dom) dom = rm(dom) +} + +function OuterDecoLevel(nodeName) { + if (nodeName) this.nodeName = nodeName +} +OuterDecoLevel.prototype = Object.create(null) + +const noDeco = [new OuterDecoLevel] + +function computeOuterDeco(outerDeco, node, needsWrap) { + if (outerDeco.length == 0) return noDeco + + let top = needsWrap ? noDeco[0] : new OuterDecoLevel, result = [top] + + for (let i = 0; i < outerDeco.length; i++) { + let attrs = outerDeco[i].type.attrs, cur = top + if (!attrs) continue + if (attrs.nodeName) + result.push(cur = new OuterDecoLevel(attrs.nodeName)) + + for (let name in attrs) { + let val = attrs[name] + if (val == null) continue + if (needsWrap && result.length == 1) + result.push(cur = top = new OuterDecoLevel(node.isInline ? "span" : "div")) + if (name == "class") cur.class = (cur.class ? cur.class + " " : "") + val + else if (name == "style") cur.style = (cur.style ? cur.style + ";" : "") + val + else if (name != "nodeName") cur[name] = val + } + } + + return result +} + +function patchOuterDeco(outerDOM, nodeDOM, prevComputed, curComputed) { + // Shortcut for trivial case + if (prevComputed == noDeco && curComputed == noDeco) return nodeDOM + + let curDOM = nodeDOM + for (let i = 0; i < curComputed.length; i++) { + let deco = curComputed[i], prev = prevComputed[i] + if (i) { + let parent + if (prev && prev.nodeName == deco.nodeName && curDOM != outerDOM && + (parent = curDOM.parentNode) && parent.tagName.toLowerCase() == deco.nodeName) { + curDOM = parent + } else { + parent = document.createElement(deco.nodeName) + parent.appendChild(curDOM) + prev = noDeco[0] + curDOM = parent + } + } + patchAttributes(curDOM, prev || noDeco[0], deco) + } + return curDOM +} + +function patchAttributes(dom, prev, cur) { + for (let name in prev) + if (name != "class" && name != "style" && name != "nodeName" && !(name in cur)) + dom.removeAttribute(name) + for (let name in cur) + if (name != "class" && name != "style" && name != "nodeName" && cur[name] != prev[name]) + dom.setAttribute(name, cur[name]) + if (prev.class != cur.class) { + let prevList = prev.class ? prev.class.split(" ") : nothing + let curList = cur.class ? cur.class.split(" ") : nothing + for (let i = 0; i < prevList.length; i++) if (curList.indexOf(prevList[i]) == -1) + dom.classList.remove(prevList[i]) + for (let i = 0; i < curList.length; i++) if (prevList.indexOf(curList[i]) == -1) + dom.classList.add(curList[i]) + } + if (prev.style != cur.style) { + if (prev.style) { + let prop = /\s*([\w\-\xa1-\uffff]+)\s*:(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*'|\(.*?\)|[^;])*/g, m + while (m = prop.exec(prev.style)) + dom.style.removeProperty(m[1]) + } + if (cur.style) + dom.style.cssText += cur.style + } +} + +function applyOuterDeco(dom, deco, node) { + return patchOuterDeco(dom, dom, noDeco, computeOuterDeco(deco, node, dom.nodeType != 1)) +} + +// : ([Decoration], [Decoration]) → bool +function sameOuterDeco(a, b) { + if (a.length != b.length) return false + for (let i = 0; i < a.length; i++) if (!a[i].type.eq(b[i].type)) return false + return true +} + +// Remove a DOM node and return its next sibling. +function rm(dom) { + let next = dom.nextSibling + dom.parentNode.removeChild(dom) + return next +} + +// Helper class for incrementally updating a tree of mark descs and +// the widget and node descs inside of them. +class ViewTreeUpdater { + // : (NodeViewDesc) + constructor(top, lockedNode) { + this.top = top + this.lock = lockedNode + // Index into `this.top`'s child array, represents the current + // update position. + this.index = 0 + // When entering a mark, the current top and index are pushed + // onto this. + this.stack = [] + // Tracks whether anything was changed + this.changed = false + + let pre = preMatch(top.node.content, top.children) + this.preMatched = pre.nodes + this.preMatchOffset = pre.offset + } + + getPreMatch(index) { + return index >= this.preMatchOffset ? this.preMatched[index - this.preMatchOffset] : null + } + + // Destroy and remove the children between the given indices in + // `this.top`. + destroyBetween(start, end) { + if (start == end) return + for (let i = start; i < end; i++) this.top.children[i].destroy() + this.top.children.splice(start, end - start) + this.changed = true + } + + // Destroy all remaining children in `this.top`. + destroyRest() { + this.destroyBetween(this.index, this.top.children.length) + } + + // : ([Mark], EditorView) + // Sync the current stack of mark descs with the given array of + // marks, reusing existing mark descs when possible. + syncToMarks(marks, inline, view) { + let keep = 0, depth = this.stack.length >> 1 + let maxKeep = Math.min(depth, marks.length) + while (keep < maxKeep && + (keep == depth - 1 ? this.top : this.stack[(keep + 1) << 1]).matchesMark(marks[keep]) && marks[keep].type.spec.spanning !== false) + keep++ + + while (keep < depth) { + this.destroyRest() + this.top.dirty = NOT_DIRTY + this.index = this.stack.pop() + this.top = this.stack.pop() + depth-- + } + while (depth < marks.length) { + this.stack.push(this.top, this.index + 1) + let found = -1 + for (let i = this.index; i < Math.min(this.index + 3, this.top.children.length); i++) { + if (this.top.children[i].matchesMark(marks[depth])) { found = i; break } + } + if (found > -1) { + if (found > this.index) { + this.changed = true + this.destroyBetween(this.index, found) + } + this.top = this.top.children[this.index] + } else { + let markDesc = MarkViewDesc.create(this.top, marks[depth], inline, view) + this.top.children.splice(this.index, 0, markDesc) + this.top = markDesc + this.changed = true + } + this.index = 0 + depth++ + } + } + + // : (Node, [Decoration], DecorationSet) → bool + // Try to find a node desc matching the given data. Skip over it and + // return true when successful. + findNodeMatch(node, outerDeco, innerDeco, index) { + let found = -1, preMatch = index < 0 ? undefined : this.getPreMatch(index), children = this.top.children + if (preMatch && preMatch.matchesNode(node, outerDeco, innerDeco)) { + found = children.indexOf(preMatch) + } else { + for (let i = this.index, e = Math.min(children.length, i + 5); i < e; i++) { + let child = children[i] + if (child.matchesNode(node, outerDeco, innerDeco) && this.preMatched.indexOf(child) < 0) { + found = i + break + } + } + } + if (found < 0) return false + this.destroyBetween(this.index, found) + this.index++ + return true + } + + // : (Node, [Decoration], DecorationSet, EditorView, Fragment, number) → bool + // Try to update the next node, if any, to the given data. Checks + // pre-matches to avoid overwriting nodes that could still be used. + updateNextNode(node, outerDeco, innerDeco, view, index) { + if (this.index == this.top.children.length) return false + let next = this.top.children[this.index] + if (next instanceof NodeViewDesc) { + let preMatch = this.preMatched.indexOf(next) + if (preMatch > -1 && preMatch + this.preMatchOffset != index) return false + let nextDOM = next.dom + + // Can't update if nextDOM is or contains this.lock, except if + // it's a text node whose content already matches the new text + // and whose decorations match the new ones. + let locked = this.lock && (nextDOM == this.lock || nextDOM.nodeType == 1 && nextDOM.contains(this.lock.parentNode)) && + !(node.isText && next.node && next.node.isText && next.nodeDOM.nodeValue == node.text && + next.dirty != NODE_DIRTY && sameOuterDeco(outerDeco, next.outerDeco)) + if (!locked && next.update(node, outerDeco, innerDeco, view)) { + if (next.dom != nextDOM) this.changed = true + this.index++ + return true + } + } + return false + } + + // : (Node, [Decoration], DecorationSet, EditorView) + // Insert the node as a newly created node desc. + addNode(node, outerDeco, innerDeco, view, pos) { + this.top.children.splice(this.index++, 0, NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos)) + this.changed = true + } + + placeWidget(widget, view, pos) { + if (this.index < this.top.children.length && this.top.children[this.index].matchesWidget(widget)) { + this.index++ + } else { + let desc = new WidgetViewDesc(this.top, widget, view, pos) + this.top.children.splice(this.index++, 0, desc) + this.changed = true + } + } + + // Make sure a textblock looks and behaves correctly in + // contentEditable. + addTextblockHacks() { + let lastChild = this.top.children[this.index - 1] + while (lastChild instanceof MarkViewDesc) lastChild = lastChild.children[lastChild.children.length - 1] + + if (!lastChild || // Empty textblock + !(lastChild instanceof TextViewDesc) || + /\n$/.test(lastChild.node.text)) { + if (this.index < this.top.children.length && this.top.children[this.index].matchesHack()) { + this.index++ + } else { + let dom = document.createElement("br") + this.top.children.splice(this.index++, 0, new BRHackViewDesc(this.top, nothing, dom, null)) + this.changed = true + } + } + } +} + +// : (Fragment, [ViewDesc]) → [ViewDesc] +// Iterate from the end of the fragment and array of descs to find +// directly matching ones, in order to avoid overeagerly reusing +// those for other nodes. Returns an array whose positions correspond +// to node positions in the fragment, and whose elements are either +// descs matched to the child at that index, or empty. +function preMatch(frag, descs) { + let result = [], end = frag.childCount + for (let i = descs.length - 1; end > 0 && i >= 0; i--) { + let desc = descs[i], node = desc.node + if (!node) continue + if (node != frag.child(end - 1)) break + result.push(desc) + --end + } + return {nodes: result.reverse(), offset: end} +} + +function compareSide(a, b) { return a.type.side - b.type.side } + +// : (ViewDesc, DecorationSet, (Decoration, number), (Node, [Decoration], DecorationSet, number)) +// This function abstracts iterating over the nodes and decorations in +// a fragment. Calls `onNode` for each node, with its local and child +// decorations. Splits text nodes when there is a decoration starting +// or ending inside of them. Calls `onWidget` for each widget. +function iterDeco(parent, deco, onWidget, onNode) { + let locals = deco.locals(parent), offset = 0 + // Simple, cheap variant for when there are no local decorations + if (locals.length == 0) { + for (let i = 0; i < parent.childCount; i++) { + let child = parent.child(i) + onNode(child, locals, deco.forChild(offset, child), i) + offset += child.nodeSize + } + return + } + + let decoIndex = 0, active = [], restNode = null + for (let parentIndex = 0;;) { + if (decoIndex < locals.length && locals[decoIndex].to == offset) { + let widget = locals[decoIndex++], widgets + while (decoIndex < locals.length && locals[decoIndex].to == offset) + (widgets || (widgets = [widget])).push(locals[decoIndex++]) + if (widgets) { + widgets.sort(compareSide) + for (let i = 0; i < widgets.length; i++) onWidget(widgets[i], parentIndex) + } else { + onWidget(widget, parentIndex) + } + } + + let child, index + if (restNode) { + index = -1 + child = restNode + restNode = null + } else if (parentIndex < parent.childCount) { + index = parentIndex + child = parent.child(parentIndex++) + } else { + break + } + + for (let i = 0; i < active.length; i++) if (active[i].to <= offset) active.splice(i--, 1) + while (decoIndex < locals.length && locals[decoIndex].from == offset) active.push(locals[decoIndex++]) + + let end = offset + child.nodeSize + if (child.isText) { + let cutAt = end + if (decoIndex < locals.length && locals[decoIndex].from < cutAt) cutAt = locals[decoIndex].from + for (let i = 0; i < active.length; i++) if (active[i].to < cutAt) cutAt = active[i].to + if (cutAt < end) { + restNode = child.cut(cutAt - offset) + child = child.cut(0, cutAt - offset) + end = cutAt + index = -1 + } + } + + onNode(child, active.length ? active.slice() : nothing, deco.forChild(offset, child), index) + offset = end + } +} + +// List markers in Mobile Safari will mysteriously disappear +// sometimes. This works around that. +function iosHacks(dom) { + if (dom.nodeName == "UL" || dom.nodeName == "OL") { + let oldCSS = dom.style.cssText + dom.style.cssText = oldCSS + "; list-style: square !important" + window.getComputedStyle(dom).listStyle + dom.style.cssText = oldCSS + } +} + +function nearbyTextNode(node, offset) { + for (;;) { + if (node.nodeType == 3) return node + if (node.nodeType == 1 && offset > 0) { + if (node.childNodes.length > offset && node.childNodes[offset].nodeType == 3) + return node.childNodes[offset] + node = node.childNodes[offset - 1] + offset = nodeSize(node) + } else if (node.nodeType == 1 && offset < node.childNodes.length) { + node = node.childNodes[offset] + offset = 0 + } else { + return null + } + } +} + +// Find a piece of text in an inline fragment, overlapping from-to +function findTextInFragment(frag, text, from, to) { + for (let str = "", i = 0, childPos = 0; i < frag.childCount; i++) { + let child = frag.child(i), end = childPos + child.nodeSize + if (child.isText) { + str += child.text + if (end >= to) { + let strStart = end - str.length, found = str.lastIndexOf(text) + while (found > -1 && strStart + found > from) found = str.lastIndexOf(text, found - 1) + if (found > -1 && strStart + found + text.length >= to) { + return strStart + found + } else if (end > to) { + break + } + } + } else { + str = "" + } + childPos = end + } + return -1 +} + +// Replace range from-to in an array of view descs with replacement +// (may be null to just delete). This goes very much against the grain +// of the rest of this code, which tends to create nodes with the +// right shape in one go, rather than messing with them after +// creation, but is necessary in the composition hack. +function replaceNodes(nodes, from, to, view, replacement) { + let result = [] + for (let i = 0, off = 0; i < nodes.length; i++) { + let child = nodes[i], start = off, end = off += child.size + if (start >= to || end <= from) { + result.push(child) + } else { + if (start < from) result.push(child.slice(0, from - start, view)) + if (replacement) { + result.push(replacement) + replacement = null + } + if (end > to) result.push(child.slice(to - start, child.size, view)) + } + } + return result +} diff --git a/packages/tiptap/node_modules/prosemirror-view/style/prosemirror.css b/packages/tiptap/node_modules/prosemirror-view/style/prosemirror.css new file mode 100644 index 0000000000..6d4fb54ebb --- /dev/null +++ b/packages/tiptap/node_modules/prosemirror-view/style/prosemirror.css @@ -0,0 +1,43 @@ +.ProseMirror { + position: relative; +} + +.ProseMirror { + word-wrap: break-word; + white-space: pre-wrap; + white-space: break-spaces; + -webkit-font-variant-ligatures: none; + font-variant-ligatures: none; + font-feature-settings: "liga" 0; /* the above doesn't seem to work in Edge */ +} + +.ProseMirror pre { + white-space: pre-wrap; +} + +.ProseMirror li { + position: relative; +} + +.ProseMirror-hideselection *::selection { background: transparent; } +.ProseMirror-hideselection *::-moz-selection { background: transparent; } +.ProseMirror-hideselection { caret-color: transparent; } + +.ProseMirror-selectednode { + outline: 2px solid #8cf; +} + +/* Make sure li selections wrap around markers */ + +li.ProseMirror-selectednode { + outline: none; +} + +li.ProseMirror-selectednode:after { + content: ""; + position: absolute; + left: -32px; + right: -2px; top: -2px; bottom: -2px; + border: 2px solid #8cf; + pointer-events: none; +}