diff --git a/.gitignore b/.gitignore index 5c496db9..2e4e8d35 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,11 @@ # Compiled code -# /dist/* +/dist/* # We need to check in the package.json for /dist/cjs so that # consumers know to treat it as cjs -# !/dist/cjs -# /dist/cjs/* -# !/dist/cjs/package.json +!/dist/cjs +/dist/cjs/* +!/dist/cjs/package.json # Yarn PnP artifacts .pnp.* diff --git a/dist/cjs/browser.js b/dist/cjs/browser.js deleted file mode 100644 index b28da86d..00000000 --- a/dist/cjs/browser.js +++ /dev/null @@ -1,51 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "browser", { - enumerable: true, - get: ()=>browser -}); -const nav = typeof navigator != "undefined" ? navigator : null; -const doc = typeof document != "undefined" ? document : null; -const agent = nav && nav.userAgent || ""; -const ie_edge = /Edge\/(\d+)/.exec(agent); -const ie_upto10 = /MSIE \d/.exec(agent); -const ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(agent); -const ie = !!(ie_upto10 || ie_11up || ie_edge); -const ie_version = ie_upto10 ? document.documentMode : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : 0; -const gecko = !ie && /gecko\/(\d+)/i.test(agent); -const gecko_version = gecko && +(/Firefox\/(\d+)/.exec(agent) || [ - 0, - 0 -])[1]; -const _chrome = !ie && /Chrome\/(\d+)/.exec(agent); -const chrome = !!_chrome; -// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -const chrome_version = _chrome ? +_chrome[1] : 0; -const safari = !ie && !!nav && /Apple Computer/.test(nav.vendor); -// Is true for both iOS and iPadOS for convenience -const ios = safari && (/Mobile\/\w+/.test(agent) || !!nav && nav.maxTouchPoints > 2); -const mac = ios || (nav ? /Mac/.test(nav.platform) : false); -const windows = nav ? /Win/.test(nav.platform) : false; -const android = /Android \d/.test(agent); -const webkit = !!doc && "webkitFontSmoothing" in doc.documentElement.style; -const webkit_version = webkit ? +(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent) || [ - 0, - 0 -])[1] : 0; -const browser = { - ie, - ie_version, - gecko, - gecko_version, - chrome, - chrome_version, - safari, - ios, - mac, - windows, - android, - webkit, - webkit_version -}; diff --git a/dist/cjs/components/ChildNodeViews.js b/dist/cjs/components/ChildNodeViews.js deleted file mode 100644 index 98005eea..00000000 --- a/dist/cjs/components/ChildNodeViews.js +++ /dev/null @@ -1,325 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -function _export(target, all) { - for(var name in all)Object.defineProperty(target, name, { - enumerable: true, - get: all[name] - }); -} -_export(exports, { - wrapInDeco: ()=>wrapInDeco, - ChildNodeViews: ()=>ChildNodeViews -}); -const _dedupe = /*#__PURE__*/ _interopRequireDefault(require("classnames/dedupe")); -const _react = /*#__PURE__*/ _interopRequireWildcard(require("react")); -const _childDescriptorsContextJs = require("../contexts/ChildDescriptorsContext.js"); -const _editorContextJs = require("../contexts/EditorContext.js"); -const _iterDecoJs = require("../decorations/iterDeco.js"); -const _useEditorStateJs = require("../hooks/useEditorState.js"); -const _useReactKeysJs = require("../hooks/useReactKeys.js"); -const _markViewJs = require("./MarkView.js"); -const _nativeWidgetViewJs = require("./NativeWidgetView.js"); -const _nodeViewJs = require("./NodeView.js"); -const _separatorHackViewJs = require("./SeparatorHackView.js"); -const _textNodeViewJs = require("./TextNodeView.js"); -const _trailingHackViewJs = require("./TrailingHackView.js"); -const _widgetViewJs = require("./WidgetView.js"); -function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { - default: obj - }; -} -function _getRequireWildcardCache(nodeInterop) { - if (typeof WeakMap !== "function") return null; - var cacheBabelInterop = new WeakMap(); - var cacheNodeInterop = new WeakMap(); - return (_getRequireWildcardCache = function(nodeInterop) { - return nodeInterop ? cacheNodeInterop : cacheBabelInterop; - })(nodeInterop); -} -function _interopRequireWildcard(obj, nodeInterop) { - if (!nodeInterop && obj && obj.__esModule) { - return obj; - } - if (obj === null || typeof obj !== "object" && typeof obj !== "function") { - return { - default: obj - }; - } - var cache = _getRequireWildcardCache(nodeInterop); - if (cache && cache.has(obj)) { - return cache.get(obj); - } - var newObj = {}; - var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; - for(var key in obj){ - if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { - var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; - if (desc && (desc.get || desc.set)) { - Object.defineProperty(newObj, key, desc); - } else { - newObj[key] = obj[key]; - } - } - } - newObj.default = obj; - if (cache) { - cache.set(obj, newObj); - } - return newObj; -} -function cssToStyles(css) { - const cssJson = `{"${css.replace(/;? *$/, "").replace(/;+ */g, '","').replace(/: */g, '":"')}"}`; - const obj = JSON.parse(cssJson); - return Object.keys(obj).reduce((acc, key)=>{ - const camelCased = key.startsWith("--") ? key : key.replace(/-[a-z]/g, (g)=>g[1]?.toUpperCase() ?? ""); - return { - ...acc, - [camelCased]: obj[key] - }; - }, {}); -} -function wrapInDeco(reactNode, deco) { - const { nodeName , class: className , style: css , contenteditable: contentEditable , spellcheck: spellCheck , ...attrs } = deco.type.attrs; - // We auto-wrap text nodes in spans so that we can apply attributes - // and styles, but we want to avoid double-wrapping the same - // text node - if (nodeName || typeof reactNode === "string") { - return /*#__PURE__*/ (0, _react.createElement)(nodeName ?? "span", { - className, - contentEditable, - spellCheck, - style: css && cssToStyles(css), - ...attrs - }, reactNode); - } - return /*#__PURE__*/ (0, _react.cloneElement)(reactNode, { - className: (0, _dedupe.default)(reactNode.props.className, className), - contentEditable, - spellCheck, - style: { - ...reactNode.props.style, - ...css && cssToStyles(css) - }, - ...attrs - }); -} -function InlineView(param) { - let { innerPos , childViews } = param; - const { view } = (0, _react.useContext)(_editorContextJs.EditorContext); - const editorState = (0, _useEditorStateJs.useEditorState)(); - const reactKeys = (0, _useReactKeysJs.useReactKeys)(); - const partitioned = childViews.reduce((acc, child)=>{ - const lastPartition = acc[acc.length - 1]; - if (!lastPartition) { - return [ - [ - child - ] - ]; - } - const lastChild = lastPartition[lastPartition.length - 1]; - if (!lastChild) { - return [ - ...acc.slice(0, acc.length), - [ - child - ] - ]; - } - if (!child.marks.length && !lastChild.marks.length || child.marks.length && lastChild.marks.length && // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - child.marks[0]?.eq(lastChild.marks[0])) { - return [ - ...acc.slice(0, acc.length - 1), - [ - ...lastPartition.slice(0, lastPartition.length), - child - ] - ]; - } - return [ - ...acc, - [ - child - ] - ]; - }, []); - return /*#__PURE__*/ _react.default.createElement(_react.default.Fragment, null, partitioned.map((childViews)=>{ - const firstChild = childViews[0]; - if (!firstChild) return null; - const firstMark = firstChild.marks[0]; - if (!firstMark) { - return childViews.map((child)=>{ - const childPos = innerPos + child.offset; - const childElement = child.type === "widget" ? /*#__PURE__*/ _react.default.createElement(_widgetViewJs.WidgetView, { - widget: child.widget, - pos: childPos - }) : child.type === "native-widget" ? /*#__PURE__*/ _react.default.createElement(_nativeWidgetViewJs.NativeWidgetView, { - widget: child.widget, - pos: childPos - }) : child.node.isText ? /*#__PURE__*/ _react.default.createElement(_childDescriptorsContextJs.ChildDescriptorsContext.Consumer, null, (siblingDescriptors)=>/*#__PURE__*/ _react.default.createElement(_textNodeViewJs.TextNodeView, { - view: view, - node: child.node, - pos: childPos, - siblingDescriptors: siblingDescriptors, - decorations: child.outerDeco - })) : /*#__PURE__*/ _react.default.createElement(_nodeViewJs.NodeView, { - node: child.node, - pos: childPos, - outerDeco: child.outerDeco, - innerDeco: child.innerDeco - }); - return /*#__PURE__*/ (0, _react.cloneElement)(childElement, { - key: createKey(editorState?.doc, innerPos, child, reactKeys?.posToKey) - }); - }); - } - return /*#__PURE__*/ _react.default.createElement(_markViewJs.MarkView, { - key: createKey(editorState?.doc, innerPos, firstChild, reactKeys?.posToKey), - mark: firstMark - }, /*#__PURE__*/ _react.default.createElement(InlineView, { - key: createKey(editorState?.doc, innerPos, firstChild, reactKeys?.posToKey), - innerPos: innerPos, - childViews: childViews.map((child)=>({ - ...child, - marks: child.marks.slice(1) - })) - })); - })); -} -function createKey(doc, innerPos, child, posToKey) { - const pos = innerPos + child.offset; - const key = posToKey?.get(pos); - if (child.type === "widget" || child.type === "native-widget") { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - if (child.widget.type.spec.key) // eslint-disable-next-line @typescript-eslint/no-explicit-any - return child.widget.type.spec.key; - // eslint-disable-next-line no-console - console.warn(`Widget at position ${pos} doesn't have a key specified. This has negative performance implications.`); - return `${key}-${child.index}`; - } - if (key) return key; - if (!doc) return pos; - const parentPos = doc.resolve(pos).start() - 1; - const parentKey = posToKey?.get(parentPos); - if (parentKey) return `${parentKey}-${child.offset}`; - return pos; -} -function adjustWidgetMarksForward(children) { - const lastChild = children[children.length - 1]; - if (lastChild?.type !== "widget" && lastChild?.type !== "native-widget" || // Using internal Decoration property, "type" - // eslint-disable-next-line @typescript-eslint/no-explicit-any - lastChild.widget.type.side >= 0) return; - let lastNodeChild = null; - for(let i = children.length - 2; i >= 0; i--){ - const child = children[i]; - if (child?.type === "node") { - lastNodeChild = child; - break; - } - } - if (!lastNodeChild || !lastNodeChild.node.isInline) return; - const marksToSpread = lastNodeChild.marks; - lastChild.marks = lastChild.marks.reduce((acc, mark)=>mark.addToSet(acc), marksToSpread); -} -function adjustWidgetMarksBack(children) { - const lastChild = children[children.length - 1]; - if (lastChild?.type !== "node" || !lastChild.node.isInline) return; - const marksToSpread = lastChild.marks; - for(let i = children.length - 2; i >= 0; i--){ - const child = children[i]; - if (child?.type !== "widget" && child?.type !== "native-widget" || // Using internal Decoration property, "type" - // eslint-disable-next-line @typescript-eslint/no-explicit-any - child.widget.type.side < 0) break; - child.marks = child.marks.reduce((acc, mark)=>mark.addToSet(acc), marksToSpread); - } -} -function createChildElements(children, innerPos, doc, posToKey) { - if (!children.length) return []; - if (children.every((child)=>child.type !== "node" || child.node.isInline)) { - return [ - /*#__PURE__*/ _react.default.createElement(InlineView, { - key: createKey(doc, innerPos, // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - children[0], posToKey), - childViews: children, - innerPos: innerPos - }) - ]; - } - return children.map((child)=>{ - if (child.type === "node") { - const pos = innerPos + child.offset; - const key = posToKey?.get(pos) ?? pos; - return /*#__PURE__*/ _react.default.createElement(_nodeViewJs.NodeView, { - key: key, - outerDeco: child.outerDeco, - node: child.node, - innerDeco: child.innerDeco, - pos: pos - }); - } else { - return /*#__PURE__*/ _react.default.createElement(InlineView, { - key: createKey(doc, innerPos, // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - child, posToKey), - childViews: [ - child - ], - innerPos: innerPos - }); - } - }); -} -function ChildNodeViews(param) { - let { pos , node , innerDecorations } = param; - const editorState = (0, _useEditorStateJs.useEditorState)(); - const reactKeys = (0, _useReactKeysJs.useReactKeys)(); - if (!node) return null; - const innerPos = pos + 1; - const children = []; - (0, _iterDecoJs.iterDeco)(node, innerDecorations, (widget, isNative, offset, index)=>{ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const widgetMarks = widget.type.spec.marks ?? []; - if (isNative) { - children.push({ - type: "native-widget", - widget: widget, - marks: widgetMarks, - offset, - index - }); - } else { - children.push({ - type: "widget", - widget: widget, - marks: widgetMarks, - offset, - index - }); - } - adjustWidgetMarksForward(children); - }, (childNode, outerDeco, innerDeco, offset)=>{ - children.push({ - type: "node", - node: childNode, - marks: childNode.marks, - innerDeco, - outerDeco, - offset - }); - adjustWidgetMarksBack(children); - }); - const childElements = createChildElements(children, innerPos, editorState?.doc, reactKeys?.posToKey); - const lastChild = children[children.length - 1]; - if (!lastChild || lastChild.type !== "node" || lastChild.node.isInline && !lastChild.node.isText || // RegExp.test actually handles undefined just fine - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - /\n$/.test(lastChild.node.text)) { - childElements.push(/*#__PURE__*/ _react.default.createElement(_separatorHackViewJs.SeparatorHackView, { - key: "trailing-hack-img" - }), /*#__PURE__*/ _react.default.createElement(_trailingHackViewJs.TrailingHackView, { - key: "trailing-hack-br" - })); - } - return /*#__PURE__*/ _react.default.createElement(_react.default.Fragment, null, childElements); -} diff --git a/dist/cjs/components/CursorWrapper.js b/dist/cjs/components/CursorWrapper.js deleted file mode 100644 index e3f796a1..00000000 --- a/dist/cjs/components/CursorWrapper.js +++ /dev/null @@ -1,100 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "CursorWrapper", { - enumerable: true, - get: ()=>CursorWrapper -}); -const _react = /*#__PURE__*/ _interopRequireWildcard(require("react")); -const _domJs = require("../dom.js"); -const _useEditorEffectJs = require("../hooks/useEditorEffect.js"); -function _extends() { - _extends = Object.assign || function(target) { - for(var i = 1; i < arguments.length; i++){ - var source = arguments[i]; - for(var key in source){ - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; - return _extends.apply(this, arguments); -} -function _getRequireWildcardCache(nodeInterop) { - if (typeof WeakMap !== "function") return null; - var cacheBabelInterop = new WeakMap(); - var cacheNodeInterop = new WeakMap(); - return (_getRequireWildcardCache = function(nodeInterop) { - return nodeInterop ? cacheNodeInterop : cacheBabelInterop; - })(nodeInterop); -} -function _interopRequireWildcard(obj, nodeInterop) { - if (!nodeInterop && obj && obj.__esModule) { - return obj; - } - if (obj === null || typeof obj !== "object" && typeof obj !== "function") { - return { - default: obj - }; - } - var cache = _getRequireWildcardCache(nodeInterop); - if (cache && cache.has(obj)) { - return cache.get(obj); - } - var newObj = {}; - var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; - for(var key in obj){ - if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { - var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; - if (desc && (desc.get || desc.set)) { - Object.defineProperty(newObj, key, desc); - } else { - newObj[key] = obj[key]; - } - } - } - newObj.default = obj; - if (cache) { - cache.set(obj, newObj); - } - return newObj; -} -const CursorWrapper = /*#__PURE__*/ (0, _react.forwardRef)(function CursorWrapper(param, ref) { - let { widget , pos , ...props } = param; - const [shouldRender, setShouldRender] = (0, _react.useState)(true); - const innerRef = (0, _react.useRef)(null); - (0, _react.useImperativeHandle)(ref, ()=>{ - return innerRef.current; - }, []); - (0, _useEditorEffectJs.useEditorEffect)((view)=>{ - if (!view || !innerRef.current) return; - // @ts-expect-error Internal property - domObserver - view.domObserver.disconnectSelection(); - // @ts-expect-error Internal property - domSelection - const domSel = view.domSelection(); - const range = document.createRange(); - const node = innerRef.current; - const img = node.nodeName == "IMG"; - if (img && node.parentNode) { - range.setEnd(node.parentNode, (0, _domJs.domIndex)(node) + 1); - } else { - range.setEnd(node, 0); - } - range.collapse(false); - domSel.removeAllRanges(); - domSel.addRange(range); - setShouldRender(false); - // @ts-expect-error Internal property - domObserver - view.domObserver.connectSelection(); - }, []); - return shouldRender ? /*#__PURE__*/ _react.default.createElement("img", _extends({ - ref: innerRef, - className: "ProseMirror-separator", - // eslint-disable-next-line react/no-unknown-property - "mark-placeholder": "true", - alt: "" - }, props)) : null; -}); diff --git a/dist/cjs/components/DocNodeView.js b/dist/cjs/components/DocNodeView.js deleted file mode 100644 index 145eac22..00000000 --- a/dist/cjs/components/DocNodeView.js +++ /dev/null @@ -1,87 +0,0 @@ -// TODO: I must be missing something, but I do not know why -// this linting rule is only broken in this file -/* eslint-disable react/prop-types */ "use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "DocNodeView", { - enumerable: true, - get: ()=>DocNodeView -}); -const _react = /*#__PURE__*/ _interopRequireWildcard(require("react")); -const _childDescriptorsContextJs = require("../contexts/ChildDescriptorsContext.js"); -const _useNodeViewDescriptorJs = require("../hooks/useNodeViewDescriptor.js"); -const _childNodeViewsJs = require("./ChildNodeViews.js"); -function _getRequireWildcardCache(nodeInterop) { - if (typeof WeakMap !== "function") return null; - var cacheBabelInterop = new WeakMap(); - var cacheNodeInterop = new WeakMap(); - return (_getRequireWildcardCache = function(nodeInterop) { - return nodeInterop ? cacheNodeInterop : cacheBabelInterop; - })(nodeInterop); -} -function _interopRequireWildcard(obj, nodeInterop) { - if (!nodeInterop && obj && obj.__esModule) { - return obj; - } - if (obj === null || typeof obj !== "object" && typeof obj !== "function") { - return { - default: obj - }; - } - var cache = _getRequireWildcardCache(nodeInterop); - if (cache && cache.has(obj)) { - return cache.get(obj); - } - var newObj = {}; - var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; - for(var key in obj){ - if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { - var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; - if (desc && (desc.get || desc.set)) { - Object.defineProperty(newObj, key, desc); - } else { - newObj[key] = obj[key]; - } - } - } - newObj.default = obj; - if (cache) { - cache.set(obj, newObj); - } - return newObj; -} -const DocNodeView = /*#__PURE__*/ (0, _react.forwardRef)(function DocNodeView(param, ref) { - let { className , node , innerDeco , outerDeco , as , viewDesc } = param; - const innerRef = (0, _react.useRef)(null); - (0, _react.useImperativeHandle)(ref, ()=>{ - return innerRef.current; - }, []); - const childDescriptors = (0, _useNodeViewDescriptorJs.useNodeViewDescriptor)(node, innerRef, innerRef, innerDeco, outerDeco, viewDesc); - const props = { - ref: innerRef, - className, - suppressContentEditableWarning: true - }; - const element = as ? /*#__PURE__*/ (0, _react.cloneElement)(as, props, /*#__PURE__*/ _react.default.createElement(_childDescriptorsContextJs.ChildDescriptorsContext.Provider, { - value: childDescriptors - }, /*#__PURE__*/ _react.default.createElement(_childNodeViewsJs.ChildNodeViews, { - pos: -1, - node: node, - innerDecorations: innerDeco - }))) : /*#__PURE__*/ (0, _react.createElement)("div", props, /*#__PURE__*/ _react.default.createElement(_childDescriptorsContextJs.ChildDescriptorsContext.Provider, { - value: childDescriptors - }, /*#__PURE__*/ _react.default.createElement(_childNodeViewsJs.ChildNodeViews, { - pos: -1, - node: node, - innerDecorations: innerDeco - }))); - if (!node) return element; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const nodeDecorations = outerDeco.filter((deco)=>!deco.inline); - if (!nodeDecorations.length) { - return element; - } - const wrapped = nodeDecorations.reduce(_childNodeViewsJs.wrapInDeco, element); - return wrapped; -}); diff --git a/dist/cjs/components/LayoutGroup.js b/dist/cjs/components/LayoutGroup.js deleted file mode 100644 index bb0f9417..00000000 --- a/dist/cjs/components/LayoutGroup.js +++ /dev/null @@ -1,107 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "LayoutGroup", { - enumerable: true, - get: ()=>LayoutGroup -}); -const _react = /*#__PURE__*/ _interopRequireWildcard(require("react")); -const _layoutGroupContextJs = require("../contexts/LayoutGroupContext.js"); -const _useForceUpdateJs = require("../hooks/useForceUpdate.js"); -function _getRequireWildcardCache(nodeInterop) { - if (typeof WeakMap !== "function") return null; - var cacheBabelInterop = new WeakMap(); - var cacheNodeInterop = new WeakMap(); - return (_getRequireWildcardCache = function(nodeInterop) { - return nodeInterop ? cacheNodeInterop : cacheBabelInterop; - })(nodeInterop); -} -function _interopRequireWildcard(obj, nodeInterop) { - if (!nodeInterop && obj && obj.__esModule) { - return obj; - } - if (obj === null || typeof obj !== "object" && typeof obj !== "function") { - return { - default: obj - }; - } - var cache = _getRequireWildcardCache(nodeInterop); - if (cache && cache.has(obj)) { - return cache.get(obj); - } - var newObj = {}; - var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; - for(var key in obj){ - if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { - var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; - if (desc && (desc.get || desc.set)) { - Object.defineProperty(newObj, key, desc); - } else { - newObj[key] = obj[key]; - } - } - } - newObj.default = obj; - if (cache) { - cache.set(obj, newObj); - } - return newObj; -} -function LayoutGroup(param) { - let { children } = param; - const createQueue = (0, _react.useRef)(new Set()).current; - const destroyQueue = (0, _react.useRef)(new Set()).current; - const isMounted = (0, _react.useRef)(false); - const forceUpdate = (0, _useForceUpdateJs.useForceUpdate)(); - const isUpdatePending = (0, _react.useRef)(true); - const ensureFlush = (0, _react.useCallback)(()=>{ - if (!isUpdatePending.current) { - forceUpdate(); - isUpdatePending.current = true; - } - }, [ - forceUpdate - ]); - const register = (0, _react.useCallback)((effect)=>{ - let destroy; - const create = ()=>{ - destroy = effect(); - }; - createQueue.add(create); - ensureFlush(); - return ()=>{ - createQueue.delete(create); - if (destroy) { - if (isMounted.current) { - destroyQueue.add(destroy); - ensureFlush(); - } else { - destroy(); - } - } - }; - }, [ - createQueue, - destroyQueue, - ensureFlush - ]); - (0, _react.useLayoutEffect)(()=>{ - isUpdatePending.current = false; - createQueue.forEach((create)=>create()); - createQueue.clear(); - return ()=>{ - destroyQueue.forEach((destroy)=>destroy()); - destroyQueue.clear(); - }; - }); - (0, _react.useLayoutEffect)(()=>{ - isMounted.current = true; - return ()=>{ - isMounted.current = false; - }; - }, []); - return /*#__PURE__*/ _react.default.createElement(_layoutGroupContextJs.LayoutGroupContext.Provider, { - value: register - }, children); -} diff --git a/dist/cjs/components/MarkView.js b/dist/cjs/components/MarkView.js deleted file mode 100644 index 1cdb5c84..00000000 --- a/dist/cjs/components/MarkView.js +++ /dev/null @@ -1,77 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "MarkView", { - enumerable: true, - get: ()=>MarkView -}); -const _react = /*#__PURE__*/ _interopRequireWildcard(require("react")); -const _childDescriptorsContextJs = require("../contexts/ChildDescriptorsContext.js"); -const _viewdescJs = require("../viewdesc.js"); -const _outputSpecJs = require("./OutputSpec.js"); -function _getRequireWildcardCache(nodeInterop) { - if (typeof WeakMap !== "function") return null; - var cacheBabelInterop = new WeakMap(); - var cacheNodeInterop = new WeakMap(); - return (_getRequireWildcardCache = function(nodeInterop) { - return nodeInterop ? cacheNodeInterop : cacheBabelInterop; - })(nodeInterop); -} -function _interopRequireWildcard(obj, nodeInterop) { - if (!nodeInterop && obj && obj.__esModule) { - return obj; - } - if (obj === null || typeof obj !== "object" && typeof obj !== "function") { - return { - default: obj - }; - } - var cache = _getRequireWildcardCache(nodeInterop); - if (cache && cache.has(obj)) { - return cache.get(obj); - } - var newObj = {}; - var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; - for(var key in obj){ - if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { - var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; - if (desc && (desc.get || desc.set)) { - Object.defineProperty(newObj, key, desc); - } else { - newObj[key] = obj[key]; - } - } - } - newObj.default = obj; - if (cache) { - cache.set(obj, newObj); - } - return newObj; -} -const MarkView = /*#__PURE__*/ (0, _react.forwardRef)(function MarkView(param, ref) { - let { mark , children } = param; - const siblingDescriptors = (0, _react.useContext)(_childDescriptorsContextJs.ChildDescriptorsContext); - const childDescriptors = []; - const domRef = (0, _react.useRef)(null); - (0, _react.useImperativeHandle)(ref, ()=>{ - return domRef.current; - }, []); - const outputSpec = mark.type.spec.toDOM?.(mark, true); - if (!outputSpec) throw new Error(`Mark spec for ${mark.type.name} is missing toDOM`); - (0, _react.useLayoutEffect)(()=>{ - if (!domRef.current) return; - const firstChildDesc = childDescriptors[0]; - const desc = new _viewdescJs.MarkViewDesc(undefined, childDescriptors, mark, domRef.current, firstChildDesc?.dom.parentElement ?? domRef.current); - siblingDescriptors.push(desc); - for (const childDesc of childDescriptors){ - childDesc.parent = desc; - } - }); - return /*#__PURE__*/ _react.default.createElement(_outputSpecJs.OutputSpec, { - ref: domRef, - outputSpec: outputSpec - }, /*#__PURE__*/ _react.default.createElement(_childDescriptorsContextJs.ChildDescriptorsContext.Provider, { - value: childDescriptors - }, children)); -}); diff --git a/dist/cjs/components/NativeWidgetView.js b/dist/cjs/components/NativeWidgetView.js deleted file mode 100644 index b551d240..00000000 --- a/dist/cjs/components/NativeWidgetView.js +++ /dev/null @@ -1,84 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "NativeWidgetView", { - enumerable: true, - get: ()=>NativeWidgetView -}); -const _react = /*#__PURE__*/ _interopRequireWildcard(require("react")); -const _childDescriptorsContextJs = require("../contexts/ChildDescriptorsContext.js"); -const _useEditorEffectJs = require("../hooks/useEditorEffect.js"); -const _viewdescJs = require("../viewdesc.js"); -function _getRequireWildcardCache(nodeInterop) { - if (typeof WeakMap !== "function") return null; - var cacheBabelInterop = new WeakMap(); - var cacheNodeInterop = new WeakMap(); - return (_getRequireWildcardCache = function(nodeInterop) { - return nodeInterop ? cacheNodeInterop : cacheBabelInterop; - })(nodeInterop); -} -function _interopRequireWildcard(obj, nodeInterop) { - if (!nodeInterop && obj && obj.__esModule) { - return obj; - } - if (obj === null || typeof obj !== "object" && typeof obj !== "function") { - return { - default: obj - }; - } - var cache = _getRequireWildcardCache(nodeInterop); - if (cache && cache.has(obj)) { - return cache.get(obj); - } - var newObj = {}; - var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; - for(var key in obj){ - if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { - var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; - if (desc && (desc.get || desc.set)) { - Object.defineProperty(newObj, key, desc); - } else { - newObj[key] = obj[key]; - } - } - } - newObj.default = obj; - if (cache) { - cache.set(obj, newObj); - } - return newObj; -} -function NativeWidgetView(param) { - let { widget , pos } = param; - const siblingDescriptors = (0, _react.useContext)(_childDescriptorsContextJs.ChildDescriptorsContext); - const rootDomRef = (0, _react.useRef)(null); - const posRef = (0, _react.useRef)(pos); - posRef.current = pos; - (0, _useEditorEffectJs.useEditorEffect)((view)=>{ - if (!rootDomRef.current) return; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const toDOM = widget.type.toDOM; - let dom = typeof toDOM === "function" ? toDOM(view, ()=>posRef.current) : toDOM; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - if (!widget.type.spec.raw) { - if (dom.nodeType != 1) { - const wrap = document.createElement("span"); - wrap.appendChild(dom); - dom = wrap; - } - dom.contentEditable = "false"; - dom.classList.add("ProseMirror-widget"); - } - if (rootDomRef.current.firstElementChild === dom) return; - rootDomRef.current.replaceChildren(dom); - }); - (0, _react.useLayoutEffect)(()=>{ - if (!rootDomRef.current) return; - const desc = new _viewdescJs.WidgetViewDesc(undefined, widget, rootDomRef.current); - siblingDescriptors.push(desc); - }); - return /*#__PURE__*/ _react.default.createElement("span", { - ref: rootDomRef - }); -} diff --git a/dist/cjs/components/NodeView.js b/dist/cjs/components/NodeView.js deleted file mode 100644 index af8a6097..00000000 --- a/dist/cjs/components/NodeView.js +++ /dev/null @@ -1,190 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "NodeView", { - enumerable: true, - get: ()=>NodeView -}); -const _prosemirrorState = require("prosemirror-state"); -const _react = /*#__PURE__*/ _interopRequireWildcard(require("react")); -const _reactDom = require("react-dom"); -const _childDescriptorsContextJs = require("../contexts/ChildDescriptorsContext.js"); -const _editorContextJs = require("../contexts/EditorContext.js"); -const _nodeViewContextJs = require("../contexts/NodeViewContext.js"); -const _useEditorStateJs = require("../hooks/useEditorState.js"); -const _useNodeViewDescriptorJs = require("../hooks/useNodeViewDescriptor.js"); -const _childNodeViewsJs = require("./ChildNodeViews.js"); -const _markViewJs = require("./MarkView.js"); -const _outputSpecJs = require("./OutputSpec.js"); -function _extends() { - _extends = Object.assign || function(target) { - for(var i = 1; i < arguments.length; i++){ - var source = arguments[i]; - for(var key in source){ - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; - return _extends.apply(this, arguments); -} -function _getRequireWildcardCache(nodeInterop) { - if (typeof WeakMap !== "function") return null; - var cacheBabelInterop = new WeakMap(); - var cacheNodeInterop = new WeakMap(); - return (_getRequireWildcardCache = function(nodeInterop) { - return nodeInterop ? cacheNodeInterop : cacheBabelInterop; - })(nodeInterop); -} -function _interopRequireWildcard(obj, nodeInterop) { - if (!nodeInterop && obj && obj.__esModule) { - return obj; - } - if (obj === null || typeof obj !== "object" && typeof obj !== "function") { - return { - default: obj - }; - } - var cache = _getRequireWildcardCache(nodeInterop); - if (cache && cache.has(obj)) { - return cache.get(obj); - } - var newObj = {}; - var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; - for(var key in obj){ - if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { - var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; - if (desc && (desc.get || desc.set)) { - Object.defineProperty(newObj, key, desc); - } else { - newObj[key] = obj[key]; - } - } - } - newObj.default = obj; - if (cache) { - cache.set(obj, newObj); - } - return newObj; -} -function NodeView(param) { - let { outerDeco , pos , node , innerDeco , ...props } = param; - const domRef = (0, _react.useRef)(null); - const nodeDomRef = (0, _react.useRef)(null); - const contentDomRef = (0, _react.useRef)(null); - // this is ill-conceived; should revisit - const initialNode = (0, _react.useRef)(node); - const initialOuterDeco = (0, _react.useRef)(outerDeco); - const initialInnerDeco = (0, _react.useRef)(innerDeco); - const posRef = (0, _react.useRef)(pos); - posRef.current = pos; - const customNodeViewRootRef = (0, _react.useRef)(null); - const customNodeViewRef = (0, _react.useRef)(null); - const state = (0, _useEditorStateJs.useEditorState)(); - const { nodeViews } = (0, _react.useContext)(_nodeViewContextJs.NodeViewContext); - const { view } = (0, _react.useContext)(_editorContextJs.EditorContext); - let element = null; - const Component = nodeViews[node.type.name]; - // TODO: Would be great to pull all of the custom node view stuff into - // a hook - const customNodeView = view?.someProp("nodeViews")?.[node.type.name]; - (0, _react.useLayoutEffect)(()=>{ - if (!customNodeViewRef.current || !customNodeViewRootRef.current) return; - const { dom } = customNodeViewRef.current; - nodeDomRef.current = customNodeViewRootRef.current; - customNodeViewRootRef.current.appendChild(dom); - return ()=>{ - customNodeViewRef.current?.destroy?.(); - }; - }, []); - (0, _react.useLayoutEffect)(()=>{ - if (!customNodeView || !customNodeViewRef.current) return; - const { destroy , update } = customNodeViewRef.current; - const updated = update?.call(customNodeViewRef.current, node, outerDeco, innerDeco) ?? true; - if (updated) return; - destroy?.call(customNodeViewRef.current); - if (!customNodeView || !customNodeViewRootRef.current) return; - initialNode.current = node; - initialOuterDeco.current = outerDeco; - initialInnerDeco.current = innerDeco; - customNodeViewRef.current = customNodeView(initialNode.current, view, ()=>posRef.current, initialOuterDeco.current, initialInnerDeco.current); - const { dom } = customNodeViewRef.current; - nodeDomRef.current = customNodeViewRootRef.current; - customNodeViewRootRef.current.appendChild(dom); - }, [ - customNodeView, - view, - innerDeco, - node, - outerDeco - ]); - const childDescriptors = (0, _useNodeViewDescriptorJs.useNodeViewDescriptor)(node, domRef, nodeDomRef, innerDeco, outerDeco, undefined, contentDomRef); - if (Component) { - element = /*#__PURE__*/ _react.default.createElement(Component, _extends({}, props, { - ref: nodeDomRef, - nodeProps: { - node: node, - pos: pos, - decorations: outerDeco, - innerDecorations: innerDeco, - isSelected: state?.selection instanceof _prosemirrorState.NodeSelection && state.selection.node === node - } - }), /*#__PURE__*/ _react.default.createElement(_childNodeViewsJs.ChildNodeViews, { - pos: pos, - node: node, - innerDecorations: innerDeco - })); - } else if (customNodeView) { - if (!customNodeViewRef.current) { - customNodeViewRef.current = customNodeView(initialNode.current, view, ()=>posRef.current, initialOuterDeco.current, initialInnerDeco.current); - } - const { contentDOM } = customNodeViewRef.current; - contentDomRef.current = contentDOM ?? null; - element = /*#__PURE__*/ (0, _react.createElement)(node.isInline ? "span" : "div", { - ref: customNodeViewRootRef, - contentEditable: !!contentDOM, - suppressContentEditableWarning: true - }, contentDOM && /*#__PURE__*/ (0, _reactDom.createPortal)(/*#__PURE__*/ _react.default.createElement(_childNodeViewsJs.ChildNodeViews, { - pos: pos, - node: node, - innerDecorations: innerDeco - }), contentDOM)); - } else { - const outputSpec = node.type.spec.toDOM?.(node); - if (outputSpec) { - element = /*#__PURE__*/ _react.default.createElement(_outputSpecJs.OutputSpec, _extends({}, props, { - ref: nodeDomRef, - outputSpec: outputSpec - }), /*#__PURE__*/ _react.default.createElement(_childNodeViewsJs.ChildNodeViews, { - pos: pos, - node: node, - innerDecorations: innerDeco - })); - } - } - if (!element) { - throw new Error(`Node spec for ${node.type.name} is missing toDOM`); - } - const decoratedElement = /*#__PURE__*/ (0, _react.cloneElement)(outerDeco.reduce(_childNodeViewsJs.wrapInDeco, element), // eslint-disable-next-line @typescript-eslint/no-explicit-any - outerDeco.some((d)=>d.type.attrs.nodeName) ? { - ref: domRef - } : // we've already passed the domRef to the NodeView component - // as a prop - undefined); - // TODO: Should we only be wrapping non-inline elements? Inline elements have - // already been wrapped in ChildNodeViews/InlineView? - const markedElement = node.marks.reduce((element, mark)=>/*#__PURE__*/ _react.default.createElement(_markViewJs.MarkView, { - mark: mark - }, element), decoratedElement); - return /*#__PURE__*/ _react.default.createElement(_childDescriptorsContextJs.ChildDescriptorsContext.Provider, { - value: childDescriptors - }, /*#__PURE__*/ (0, _react.cloneElement)(markedElement, node.marks.length || // eslint-disable-next-line @typescript-eslint/no-explicit-any - outerDeco.some((d)=>d.type.attrs.nodeName) ? { - ref: domRef - } : // we've already passed the domRef to the NodeView component - // as a prop - undefined)); -} diff --git a/dist/cjs/components/NodeViewComponentProps.js b/dist/cjs/components/NodeViewComponentProps.js deleted file mode 100644 index b62a6d55..00000000 --- a/dist/cjs/components/NodeViewComponentProps.js +++ /dev/null @@ -1,4 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); diff --git a/dist/cjs/components/OutputSpec.js b/dist/cjs/components/OutputSpec.js deleted file mode 100644 index 2b351990..00000000 --- a/dist/cjs/components/OutputSpec.js +++ /dev/null @@ -1,87 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "OutputSpec", { - enumerable: true, - get: ()=>ForwardedOutputSpec -}); -const _react = /*#__PURE__*/ _interopRequireWildcard(require("react")); -function _getRequireWildcardCache(nodeInterop) { - if (typeof WeakMap !== "function") return null; - var cacheBabelInterop = new WeakMap(); - var cacheNodeInterop = new WeakMap(); - return (_getRequireWildcardCache = function(nodeInterop) { - return nodeInterop ? cacheNodeInterop : cacheBabelInterop; - })(nodeInterop); -} -function _interopRequireWildcard(obj, nodeInterop) { - if (!nodeInterop && obj && obj.__esModule) { - return obj; - } - if (obj === null || typeof obj !== "object" && typeof obj !== "function") { - return { - default: obj - }; - } - var cache = _getRequireWildcardCache(nodeInterop); - if (cache && cache.has(obj)) { - return cache.get(obj); - } - var newObj = {}; - var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; - for(var key in obj){ - if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { - var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; - if (desc && (desc.get || desc.set)) { - Object.defineProperty(newObj, key, desc); - } else { - newObj[key] = obj[key]; - } - } - } - newObj.default = obj; - if (cache) { - cache.set(obj, newObj); - } - return newObj; -} -const ForwardedOutputSpec = /*#__PURE__*/ (0, _react.forwardRef)(function OutputSpec(param, ref) { - let { outputSpec , children , ...initialProps } = param; - if (typeof outputSpec === "string") { - return /*#__PURE__*/ _react.default.createElement(_react.default.Fragment, null, outputSpec); - } - if (!Array.isArray(outputSpec)) { - throw new Error("@nytimes/react-prosemirror only supports strings and arrays in toDOM"); - } - const tagSpec = outputSpec[0]; - const tagName = tagSpec.replace(" ", ":"); - const attrs = outputSpec[1]; - const props = { - ...initialProps, - ref - }; - let start = 1; - if (attrs && typeof attrs === "object" && attrs.nodeType == null && !Array.isArray(attrs)) { - start = 2; - for(const name in attrs)if (attrs[name] != null) { - const attrName = name === "class" ? "className" : name.replace(" ", ":"); - props[attrName] = attrs[name]; - } - } - const content = []; - for(let i = start; i < outputSpec.length; i++){ - const child = outputSpec[i]; - if (child === 0) { - if (i < outputSpec.length - 1 || i > start) { - throw new RangeError("Content hole must be the only child of its parent node"); - } - return /*#__PURE__*/ (0, _react.createElement)(tagName, props, children); - } - content.push(/*#__PURE__*/ _react.default.createElement(ForwardedOutputSpec, { - ref: undefined, - outputSpec: child - }, children)); - } - return /*#__PURE__*/ (0, _react.createElement)(tagName, props, ...content); -}); diff --git a/dist/cjs/components/ProseMirror.js b/dist/cjs/components/ProseMirror.js deleted file mode 100644 index 740995a1..00000000 --- a/dist/cjs/components/ProseMirror.js +++ /dev/null @@ -1,84 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "ProseMirror", { - enumerable: true, - get: ()=>ProseMirror -}); -const _prosemirrorView = require("prosemirror-view"); -const _react = /*#__PURE__*/ _interopRequireWildcard(require("react")); -const _editorContextJs = require("../contexts/EditorContext.js"); -const _nodeViewContextJs = require("../contexts/NodeViewContext.js"); -const _computeDocDecoJs = require("../decorations/computeDocDeco.js"); -const _viewDecorationsJs = require("../decorations/viewDecorations.js"); -const _useEditorJs = require("../hooks/useEditor.js"); -const _usePendingViewEffectsJs = require("../hooks/usePendingViewEffects.js"); -const _layoutGroupJs = require("./LayoutGroup.js"); -const _proseMirrorDocJs = require("./ProseMirrorDoc.js"); -function _getRequireWildcardCache(nodeInterop) { - if (typeof WeakMap !== "function") return null; - var cacheBabelInterop = new WeakMap(); - var cacheNodeInterop = new WeakMap(); - return (_getRequireWildcardCache = function(nodeInterop) { - return nodeInterop ? cacheNodeInterop : cacheBabelInterop; - })(nodeInterop); -} -function _interopRequireWildcard(obj, nodeInterop) { - if (!nodeInterop && obj && obj.__esModule) { - return obj; - } - if (obj === null || typeof obj !== "object" && typeof obj !== "function") { - return { - default: obj - }; - } - var cache = _getRequireWildcardCache(nodeInterop); - if (cache && cache.has(obj)) { - return cache.get(obj); - } - var newObj = {}; - var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; - for(var key in obj){ - if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { - var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; - if (desc && (desc.get || desc.set)) { - Object.defineProperty(newObj, key, desc); - } else { - newObj[key] = obj[key]; - } - } - } - newObj.default = obj; - if (cache) { - cache.set(obj, newObj); - } - return newObj; -} -function ProseMirror(param) { - let { className , children , nodeViews ={} , customNodeViews , ...props } = param; - const [mount, setMount] = (0, _react.useState)(null); - const editor = (0, _useEditorJs.useEditor)(mount, { - ...props, - nodeViews: customNodeViews - }); - (0, _usePendingViewEffectsJs.usePendingViewEffects)(editor.view); - const innerDecos = editor.view ? (0, _viewDecorationsJs.viewDecorations)(editor.view, editor.cursorWrapper) : _prosemirrorView.DecorationSet.empty; - const outerDecos = editor.view ? (0, _computeDocDecoJs.computeDocDeco)(editor.view) : []; - return /*#__PURE__*/ _react.default.createElement(_layoutGroupJs.LayoutGroup, null, /*#__PURE__*/ _react.default.createElement(_editorContextJs.EditorContext.Provider, { - value: editor - }, /*#__PURE__*/ _react.default.createElement(_nodeViewContextJs.NodeViewContext.Provider, { - value: { - nodeViews - } - }, /*#__PURE__*/ _react.default.createElement(_proseMirrorDocJs.DocNodeViewContext.Provider, { - value: { - className: className, - setMount: setMount, - node: editor.view?.state.doc, - innerDeco: innerDecos, - outerDeco: outerDecos, - viewDesc: editor.docViewDescRef.current - } - }, children)))); -} diff --git a/dist/cjs/components/ProseMirrorDoc.js b/dist/cjs/components/ProseMirrorDoc.js deleted file mode 100644 index 25741ca1..00000000 --- a/dist/cjs/components/ProseMirrorDoc.js +++ /dev/null @@ -1,90 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -function _export(target, all) { - for(var name in all)Object.defineProperty(target, name, { - enumerable: true, - get: all[name] - }); -} -_export(exports, { - DocNodeViewContext: ()=>DocNodeViewContext, - ProseMirrorDoc: ()=>ForwardedProseMirrorDoc -}); -const _react = /*#__PURE__*/ _interopRequireWildcard(require("react")); -const _childDescriptorsContextJs = require("../contexts/ChildDescriptorsContext.js"); -const _docNodeViewJs = require("./DocNodeView.js"); -function _extends() { - _extends = Object.assign || function(target) { - for(var i = 1; i < arguments.length; i++){ - var source = arguments[i]; - for(var key in source){ - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; - return _extends.apply(this, arguments); -} -function _getRequireWildcardCache(nodeInterop) { - if (typeof WeakMap !== "function") return null; - var cacheBabelInterop = new WeakMap(); - var cacheNodeInterop = new WeakMap(); - return (_getRequireWildcardCache = function(nodeInterop) { - return nodeInterop ? cacheNodeInterop : cacheBabelInterop; - })(nodeInterop); -} -function _interopRequireWildcard(obj, nodeInterop) { - if (!nodeInterop && obj && obj.__esModule) { - return obj; - } - if (obj === null || typeof obj !== "object" && typeof obj !== "function") { - return { - default: obj - }; - } - var cache = _getRequireWildcardCache(nodeInterop); - if (cache && cache.has(obj)) { - return cache.get(obj); - } - var newObj = {}; - var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; - for(var key in obj){ - if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { - var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; - if (desc && (desc.get || desc.set)) { - Object.defineProperty(newObj, key, desc); - } else { - newObj[key] = obj[key]; - } - } - } - newObj.default = obj; - if (cache) { - cache.set(obj, newObj); - } - return newObj; -} -const DocNodeViewContext = /*#__PURE__*/ (0, _react.createContext)(null); -function ProseMirrorDoc(param, ref) { - let { as } = param; - const innerRef = (0, _react.useRef)(null); - const { setMount , ...docProps } = (0, _react.useContext)(DocNodeViewContext); - (0, _react.useImperativeHandle)(ref, ()=>{ - return innerRef.current; - }, []); - return /*#__PURE__*/ _react.default.createElement(_childDescriptorsContextJs.ChildDescriptorsContext.Provider, { - value: [] - }, /*#__PURE__*/ _react.default.createElement(_docNodeViewJs.DocNodeView, _extends({ - ref: (el)=>{ - innerRef.current = el; - setMount(el); - } - }, docProps, { - as: as - }))); -} -const ForwardedProseMirrorDoc = /*#__PURE__*/ (0, _react.forwardRef)(ProseMirrorDoc); diff --git a/dist/cjs/components/SeparatorHackView.js b/dist/cjs/components/SeparatorHackView.js deleted file mode 100644 index def986c2..00000000 --- a/dist/cjs/components/SeparatorHackView.js +++ /dev/null @@ -1,73 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "SeparatorHackView", { - enumerable: true, - get: ()=>SeparatorHackView -}); -const _react = /*#__PURE__*/ _interopRequireWildcard(require("react")); -const _browserJs = require("../browser.js"); -const _childDescriptorsContextJs = require("../contexts/ChildDescriptorsContext.js"); -const _viewdescJs = require("../viewdesc.js"); -function _getRequireWildcardCache(nodeInterop) { - if (typeof WeakMap !== "function") return null; - var cacheBabelInterop = new WeakMap(); - var cacheNodeInterop = new WeakMap(); - return (_getRequireWildcardCache = function(nodeInterop) { - return nodeInterop ? cacheNodeInterop : cacheBabelInterop; - })(nodeInterop); -} -function _interopRequireWildcard(obj, nodeInterop) { - if (!nodeInterop && obj && obj.__esModule) { - return obj; - } - if (obj === null || typeof obj !== "object" && typeof obj !== "function") { - return { - default: obj - }; - } - var cache = _getRequireWildcardCache(nodeInterop); - if (cache && cache.has(obj)) { - return cache.get(obj); - } - var newObj = {}; - var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; - for(var key in obj){ - if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { - var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; - if (desc && (desc.get || desc.set)) { - Object.defineProperty(newObj, key, desc); - } else { - newObj[key] = obj[key]; - } - } - } - newObj.default = obj; - if (cache) { - cache.set(obj, newObj); - } - return newObj; -} -function SeparatorHackView() { - const siblingDescriptors = (0, _react.useContext)(_childDescriptorsContextJs.ChildDescriptorsContext); - const ref = (0, _react.useRef)(null); - const [shouldRender, setShouldRender] = (0, _react.useState)(false); - // There's no risk of an infinite loop here, because - // we call setShouldRender conditionally - // eslint-disable-next-line react-hooks/exhaustive-deps - (0, _react.useLayoutEffect)(()=>{ - const lastSibling = siblingDescriptors[siblingDescriptors.length - 1]; - if ((_browserJs.browser.safari || _browserJs.browser.chrome) && (lastSibling?.dom)?.contentEditable == "false") { - setShouldRender(true); - return; - } - if (!ref.current) return; - const desc = new _viewdescJs.TrailingHackViewDesc(undefined, [], ref.current, null); - siblingDescriptors.push(desc); - }); - return shouldRender ? /*#__PURE__*/ _react.default.createElement("img", { - ref: ref, - className: "ProseMirror-separator" - }) : null; -} diff --git a/dist/cjs/components/TextNodeView.js b/dist/cjs/components/TextNodeView.js deleted file mode 100644 index 07e15f1b..00000000 --- a/dist/cjs/components/TextNodeView.js +++ /dev/null @@ -1,57 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "TextNodeView", { - enumerable: true, - get: ()=>TextNodeView -}); -const _prosemirrorView = require("prosemirror-view"); -const _react = require("react"); -const _reactDom = require("react-dom"); -const _viewdescJs = require("../viewdesc.js"); -const _childNodeViewsJs = require("./ChildNodeViews.js"); -let TextNodeView = class TextNodeView extends _react.Component { - updateEffect() { - const { decorations , siblingDescriptors , node } = this.props; - // There simply is no other way to ref a text node - // eslint-disable-next-line react/no-find-dom-node - const dom = (0, _reactDom.findDOMNode)(this); - // We only need to explicitly create a CompositionViewDesc - // when a composition was started that produces a new text node. - // Otherwise we just rely on re-rendering the renderRef - if (!dom) { - return; - } - let textNode = dom; - while(textNode.firstChild){ - textNode = textNode.firstChild; - } - if (!this.viewDescRef || this.viewDescRef instanceof _viewdescJs.CompositionViewDesc) { - this.viewDescRef = new _viewdescJs.TextViewDesc(undefined, [], node, decorations, _prosemirrorView.DecorationSet.empty, dom, textNode); - } else { - this.viewDescRef.parent = undefined; - this.viewDescRef.children = []; - this.viewDescRef.node = node; - this.viewDescRef.outerDeco = decorations; - this.viewDescRef.innerDeco = _prosemirrorView.DecorationSet.empty; - this.viewDescRef.dom = dom; - this.viewDescRef.nodeDOM = textNode; - } - siblingDescriptors.push(this.viewDescRef); - } - componentDidMount() { - this.updateEffect(); - } - componentDidUpdate() { - this.updateEffect(); - } - render() { - const { node , decorations } = this.props; - return decorations.reduce(_childNodeViewsJs.wrapInDeco, node.text); - } - constructor(...args){ - super(...args); - this.viewDescRef = null; - } -}; diff --git a/dist/cjs/components/TrailingHackView.js b/dist/cjs/components/TrailingHackView.js deleted file mode 100644 index 1792ab4c..00000000 --- a/dist/cjs/components/TrailingHackView.js +++ /dev/null @@ -1,63 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "TrailingHackView", { - enumerable: true, - get: ()=>TrailingHackView -}); -const _react = /*#__PURE__*/ _interopRequireWildcard(require("react")); -const _childDescriptorsContextJs = require("../contexts/ChildDescriptorsContext.js"); -const _viewdescJs = require("../viewdesc.js"); -function _getRequireWildcardCache(nodeInterop) { - if (typeof WeakMap !== "function") return null; - var cacheBabelInterop = new WeakMap(); - var cacheNodeInterop = new WeakMap(); - return (_getRequireWildcardCache = function(nodeInterop) { - return nodeInterop ? cacheNodeInterop : cacheBabelInterop; - })(nodeInterop); -} -function _interopRequireWildcard(obj, nodeInterop) { - if (!nodeInterop && obj && obj.__esModule) { - return obj; - } - if (obj === null || typeof obj !== "object" && typeof obj !== "function") { - return { - default: obj - }; - } - var cache = _getRequireWildcardCache(nodeInterop); - if (cache && cache.has(obj)) { - return cache.get(obj); - } - var newObj = {}; - var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; - for(var key in obj){ - if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { - var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; - if (desc && (desc.get || desc.set)) { - Object.defineProperty(newObj, key, desc); - } else { - newObj[key] = obj[key]; - } - } - } - newObj.default = obj; - if (cache) { - cache.set(obj, newObj); - } - return newObj; -} -function TrailingHackView() { - const siblingDescriptors = (0, _react.useContext)(_childDescriptorsContextJs.ChildDescriptorsContext); - const ref = (0, _react.useRef)(null); - (0, _react.useLayoutEffect)(()=>{ - if (!ref.current) return; - const desc = new _viewdescJs.TrailingHackViewDesc(undefined, [], ref.current, null); - siblingDescriptors.push(desc); - }); - return /*#__PURE__*/ _react.default.createElement("br", { - ref: ref, - className: "ProseMirror-trailingBreak" - }); -} diff --git a/dist/cjs/components/WidgetView.js b/dist/cjs/components/WidgetView.js deleted file mode 100644 index d99b4709..00000000 --- a/dist/cjs/components/WidgetView.js +++ /dev/null @@ -1,67 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "WidgetView", { - enumerable: true, - get: ()=>WidgetView -}); -const _react = /*#__PURE__*/ _interopRequireWildcard(require("react")); -const _childDescriptorsContextJs = require("../contexts/ChildDescriptorsContext.js"); -const _viewdescJs = require("../viewdesc.js"); -function _getRequireWildcardCache(nodeInterop) { - if (typeof WeakMap !== "function") return null; - var cacheBabelInterop = new WeakMap(); - var cacheNodeInterop = new WeakMap(); - return (_getRequireWildcardCache = function(nodeInterop) { - return nodeInterop ? cacheNodeInterop : cacheBabelInterop; - })(nodeInterop); -} -function _interopRequireWildcard(obj, nodeInterop) { - if (!nodeInterop && obj && obj.__esModule) { - return obj; - } - if (obj === null || typeof obj !== "object" && typeof obj !== "function") { - return { - default: obj - }; - } - var cache = _getRequireWildcardCache(nodeInterop); - if (cache && cache.has(obj)) { - return cache.get(obj); - } - var newObj = {}; - var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; - for(var key in obj){ - if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { - var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; - if (desc && (desc.get || desc.set)) { - Object.defineProperty(newObj, key, desc); - } else { - newObj[key] = obj[key]; - } - } - } - newObj.default = obj; - if (cache) { - cache.set(obj, newObj); - } - return newObj; -} -function WidgetView(param) { - let { widget , pos } = param; - const siblingDescriptors = (0, _react.useContext)(_childDescriptorsContextJs.ChildDescriptorsContext); - const domRef = (0, _react.useRef)(null); - (0, _react.useLayoutEffect)(()=>{ - if (!domRef.current) return; - const desc = new _viewdescJs.WidgetViewDesc(undefined, widget, domRef.current); - siblingDescriptors.push(desc); - }); - const { Component } = widget.type; - return Component && /*#__PURE__*/ _react.default.createElement(Component, { - ref: domRef, - widget: widget, - pos: pos, - contentEditable: false - }); -} diff --git a/dist/cjs/components/WidgetViewComponentProps.js b/dist/cjs/components/WidgetViewComponentProps.js deleted file mode 100644 index b62a6d55..00000000 --- a/dist/cjs/components/WidgetViewComponentProps.js +++ /dev/null @@ -1,4 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); diff --git a/dist/cjs/components/__tests__/ProseMirror.composition.js b/dist/cjs/components/__tests__/ProseMirror.composition.js deleted file mode 100644 index 19bd0051..00000000 --- a/dist/cjs/components/__tests__/ProseMirror.composition.js +++ /dev/null @@ -1,414 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-non-null-assertion */ "use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -const _globals = require("@jest/globals"); -const _react = require("@testing-library/react"); -const _prosemirrorState = require("prosemirror-state"); -const _prosemirrorTestBuilder = require("prosemirror-test-builder"); -const _prosemirrorView = require("prosemirror-view"); -const _editorViewTestHelpersJs = require("../../testing/editorViewTestHelpers.js"); -const _setupProseMirrorViewJs = require("../../testing/setupProseMirrorView.js"); -function endComposition(view, forceUpdate) { - (0, _react.act)(()=>{ - (0, _prosemirrorView["__endComposition"])(view, forceUpdate); - }); -} -function event(pm, type) { - (0, _react.act)(()=>{ - pm.dom.dispatchEvent(new CompositionEvent(type)); - }); -} -function edit(node) { - let text = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "", from = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : node.nodeValue.length, to = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : from; - const val = node.nodeValue; - node.nodeValue = val.slice(0, from) + text + val.slice(to); - document.getSelection().collapse(node, from + text.length); - return node; -} -function hasCompositionNode(_pm) { - let { focusNode } = document.getSelection(); - while(focusNode && !focusNode.pmViewDesc)focusNode = focusNode.parentNode; - return focusNode && focusNode.pmViewDesc.constructor.name == "CompositionViewDesc"; -} -function compose(pm, start, update) { - let options = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : {}; - event(pm, "compositionstart"); - (0, _globals.expect)(pm.composing).toBeTruthy(); - let node; - const sel = document.getSelection(); - for(let i = -1; i < update.length; i++){ - if (i < 0) node = start(); - else update[i](node); - const { focusNode , focusOffset } = sel; - (0, _react.act)(()=>{ - pm.domObserver.flush(); - }); - if (options.cancel && i == update.length - 1) { - (0, _globals.expect)(hasCompositionNode(pm)).toBeFalsy(); - } else { - (0, _globals.expect)(node.parentNode && pm.dom.contains(node.parentNode)).toBeTruthy(); - (0, _globals.expect)(sel.focusNode).toBe(focusNode); - (0, _globals.expect)(sel.focusOffset).toBe(focusOffset); - } - } - event(pm, "compositionend"); - if (options.end) { - options.end(node); - pm.domObserver.flush(); - } - endComposition(pm); - (0, _globals.expect)(pm.composing).toBeFalsy(); - (0, _globals.expect)(hasCompositionNode(pm)).toBeFalsy(); -} -function wordDeco(state) { - const re = /[^\s]+/g, deco = []; - state.doc.descendants((node, pos)=>{ - if (node.isText) for(let m; m = re.exec(node.text);)deco.push(_prosemirrorView.Decoration.inline(pos + m.index, pos + m.index + m[0].length, { - class: "word" - })); - }); - return _prosemirrorView.DecorationSet.create(state.doc, deco); -} -const wordHighlighter = new _prosemirrorState.Plugin({ - props: { - decorations: wordDeco - } -}); -// const Widget = forwardRef(function Widget( -// { widget, pos, ...props }: WidgetViewComponentProps, -// ref: Ref -// ) { -// return ( -// -// × -// -// ); -// }); -// function widgets(positions: number[], sides: number[]) { -// return new Plugin({ -// state: { -// init(state) { -// const deco = positions.map((p, i) => -// widget(p, Widget, { side: sides[i] }) -// ); -// return DecorationSet.create(state.doc!, deco); -// }, -// apply(tr, deco) { -// return deco.map(tr.mapping, tr.doc); -// }, -// }, -// props: { -// decorations(this: Plugin, state) { -// return this.getState(state); -// }, -// }, -// }); -// } -function insertComposition(dom) { - _react.fireEvent.keyDown(dom, { - key: "Dead", - code: "Quote" - }); - _react.fireEvent.compositionStart(dom); - _react.fireEvent.compositionUpdate(dom, { - data: "\xb4" - }); - (0, _react.fireEvent)(dom, new InputEvent("beforeinput", { - isComposing: true, - inputType: "insertCompositionText", - data: "\xb4" - })); - _react.fireEvent.input(dom, { - isComposing: true, - inputType: "insertCompositionText", - data: "\xb4" - }); - _react.fireEvent.keyUp(dom, { - key: "\xb4", - code: "Quote", - isComposing: true - }); - _react.fireEvent.keyDown(dom, { - key: "\xe9", - code: "KeyE", - isComposing: true - }); - _react.fireEvent.compositionUpdate(dom, { - data: "\xe9" - }); - (0, _react.fireEvent)(dom, new InputEvent("beforeinput", { - isComposing: true, - inputType: "insertCompositionText", - data: "\xe9" - })); - _react.fireEvent.compositionEnd(dom, { - inputType: "insertCompositionText", - data: "\xe9" - }); - _react.fireEvent.input(dom, { - isComposing: true, - inputType: "insertCompositionText", - data: "\xe9" - }); - _react.fireEvent.keyUp(dom, { - key: "e", - code: "KeyE" - }); -} -describe("EditorView composition", ()=>{ - beforeAll(()=>{ - (0, _setupProseMirrorViewJs.setupProseMirrorView)(); - }); - it("supports composition in an empty block", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("")) - }); - insertComposition(view.dom); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("\xe9"))); - }); - it("supports composition at end of block", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")) - }); - insertComposition(view.dom); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo\xe9"))); - }); - it("supports composition at start of block in a new node", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")) - }); - insertComposition(view.dom); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("\xe9foo"))); - }); - it("supports composition inside existing text", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")) - }); - insertComposition(view.dom); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("f\xe9oo"))); - }); - // TODO: Deal with Android style compositions - // eslint-disable-next-line jest/no-disabled-tests - it.skip("can deal with Android-style newline-after-composition", ()=>{ - const { view: pm } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("abcdef")) - }); - compose(pm, ()=>edit((0, _editorViewTestHelpersJs.findTextNode)(pm.dom, "abcdef")), [ - (n)=>edit(n, "x", 3), - (n)=>edit(n, "y", 4) - ], { - end: (n)=>{ - const line = pm.dom.appendChild(document.createElement("div")); - line.textContent = "def"; - n.nodeValue = "abcxy"; - document.getSelection().collapse(line, 0); - } - }); - (0, _globals.expect)(pm.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("abcxy"), (0, _prosemirrorTestBuilder.p)("def"))); - }); - it("handles replacement of existing words", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one two three")) - }); - insertComposition(view.dom); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one \xe9 three"))); - }); - it("handles composition inside marks", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one ", (0, _prosemirrorTestBuilder.em)("two"))) - }); - insertComposition(view.dom); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one ", (0, _prosemirrorTestBuilder.em)("two\xe9")))); - }); - it("handles composition in a mark that has multiple children", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one ", (0, _prosemirrorTestBuilder.em)("two", (0, _prosemirrorTestBuilder.strong)(" three")))) - }); - insertComposition(view.dom); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one ", (0, _prosemirrorTestBuilder.em)("two\xe9", (0, _prosemirrorTestBuilder.strong)(" three"))))); - }); - // This passes, but I think it shouldn't; it doesn't seem to work - // in the demo - it.skip("supports composition in a cursor wrapper", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("")) - }); - view.dispatch(view.state.tr.addStoredMark(_prosemirrorTestBuilder.schema.marks.em.create())); - insertComposition(view.dom); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)((0, _prosemirrorTestBuilder.em)("\xe9")))); - }); - // it("handles composition in a multi-child mark with a cursor wrapper", () => { - // const { view: pm } = requireFocus( - // tempEditor({ doc: doc(p("one ", em("two", strong(" three")))) }) - // ); - // pm.dispatch(pm.state.tr.addStoredMark(schema.marks.code.create())); - // const emNode = pm.dom.querySelector("em")!; - // compose( - // pm, - // () => - // edit( - // emNode.insertBefore( - // document.createTextNode(""), - // emNode.querySelector("strong") - // ), - // "o" - // ), - // [(n) => edit(n, "o"), (n) => edit(n, "w")], - // { node: true } - // ); - // ist( - // pm.state.doc, - // doc(p("one ", em("two", code("oow"), strong(" three")))), - // eq - // ); - // }); - // TODO: This also passes but does not actually work in the - // demo :( - it.skip("doesn't get interrupted by changes in decorations", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo ...")), - plugins: [ - wordHighlighter - ] - }); - insertComposition(view.dom); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo \xe9"))); - }); -// it("works inside highlighted text", () => { -// const { view: pm } = requireFocus( -// tempEditor({ doc: doc(p("one two")), plugins: [wordHighlighter] }) -// ); -// compose(pm, () => edit(findTextNode(pm.dom, "one")!, "x"), [ -// (n) => edit(n, "y"), -// (n) => edit(n, "."), -// ]); -// ist(pm.state.doc, doc(p("onexy. two")), eq); -// }); -// it("can handle compositions spanning multiple nodes", () => { -// const { view: pm } = requireFocus( -// tempEditor({ doc: doc(p("one two")), plugins: [wordHighlighter] }) -// ); -// compose( -// pm, -// () => edit(findTextNode(pm.dom, "two")!, "a"), -// [(n) => edit(n, "b"), (n) => edit(n, "c")], -// { -// end: (n: Text) => { -// n.parentNode!.previousSibling!.remove(); -// n.parentNode!.previousSibling!.remove(); -// return edit(n, "xyzone ", 0); -// }, -// } -// ); -// ist(pm.state.doc, doc(p("xyzone twoabc")), eq); -// }); -// it("doesn't overwrite widgets next to the composition", () => { -// const { view: pm } = requireFocus( -// tempEditor({ doc: doc(p("")), plugins: [widgets([1, 1], [-1, 1])] }) -// ); -// compose( -// pm, -// () => { -// const p = pm.dom.firstChild!; -// return edit(p.insertBefore(document.createTextNode("a"), p.lastChild)); -// }, -// [(n) => edit(n, "b", 0, 1)], -// { -// end: () => { -// ist(pm.dom.querySelectorAll("var").length, 2); -// }, -// } -// ); -// ist(pm.state.doc, doc(p("b")), eq); -// }); -// it("cancels composition when a change fully overlaps with it", () => { -// const { view: pm } = requireFocus( -// tempEditor({ doc: doc(p("one"), p("two"), p("three")) }) -// ); -// compose( -// pm, -// () => edit(findTextNode(pm.dom, "two")!, "x"), -// [() => pm.dispatch(pm.state.tr.insertText("---", 3, 13))], -// { cancel: true } -// ); -// ist(pm.state.doc, doc(p("on---hree")), eq); -// }); -// it("cancels composition when a change partially overlaps with it", () => { -// const { view: pm } = requireFocus( -// tempEditor({ doc: doc(p("one"), p("two"), p("three")) }) -// ); -// compose( -// pm, -// () => edit(findTextNode(pm.dom, "two")!, "x", 0), -// [() => pm.dispatch(pm.state.tr.insertText("---", 7, 15))], -// { cancel: true } -// ); -// ist(pm.state.doc, doc(p("one"), p("x---ee")), eq); -// }); -// it("cancels composition when a change happens inside of it", () => { -// const { view: pm } = requireFocus( -// tempEditor({ doc: doc(p("one"), p("two"), p("three")) }) -// ); -// compose( -// pm, -// () => edit(findTextNode(pm.dom, "two")!, "x", 0), -// [() => pm.dispatch(pm.state.tr.insertText("!", 7, 8))], -// { cancel: true } -// ); -// ist(pm.state.doc, doc(p("one"), p("x!wo"), p("three")), eq); -// }); -// it("doesn't cancel composition when a change happens elsewhere", () => { -// const { view: pm } = requireFocus( -// tempEditor({ doc: doc(p("one"), p("two"), p("three")) }) -// ); -// compose(pm, () => edit(findTextNode(pm.dom, "two")!, "x", 0), [ -// (n) => edit(n, "y", 1), -// () => pm.dispatch(pm.state.tr.insertText("!", 2, 3)), -// (n) => edit(n, "z", 2), -// ]); -// ist(pm.state.doc, doc(p("o!e"), p("xyztwo"), p("three")), eq); -// }); -// it("handles compositions rapidly following each other", () => { -// const { view: pm } = tempEditor({ doc: doc(p("one"), p("two")) }); -// event(pm, "compositionstart"); -// const one = findTextNode(pm.dom, "one")!; -// edit(one, "!"); -// (pm as any).domObserver.flush(); -// event(pm, "compositionend"); -// one.nodeValue = "one!!"; -// const L2 = pm.dom.lastChild; -// event(pm, "compositionstart"); -// const two = findTextNode(pm.dom, "two")!; -// ist(pm.dom.lastChild, L2); -// edit(two, "."); -// (pm as any).domObserver.flush(); -// ist(document.getSelection()!.focusNode, two); -// ist(document.getSelection()!.focusOffset, 4); -// ist(pm.composing); -// event(pm, "compositionend"); -// (pm as any).domObserver.flush(); -// ist(pm.state.doc, doc(p("one!!"), p("two.")), eq); -// }); -// function crossParagraph(first = false) { -// const { view: pm } = requireFocus( -// tempEditor({ doc: doc(p("one two"), p("three"), p("four five")) }) -// ); -// compose( -// pm, -// () => { -// for (let i = 0; i < 2; i++) -// pm.dom.removeChild(first ? pm.dom.lastChild! : pm.dom.firstChild!); -// const target = pm.dom.firstChild!.firstChild as Text; -// target.nodeValue = "one A five"; -// document.getSelection()!.collapse(target, 4); -// return target; -// }, -// [(n) => edit(n, "B", 4, 5), (n) => edit(n, "C", 4, 5)] -// ); -// ist(pm.state.doc, doc(p("one C five")), eq); -// } -// it("can handle cross-paragraph compositions", () => crossParagraph(true)); -// it("can handle cross-paragraph compositions (keeping the last paragraph)", () => -// crossParagraph(false)); -}); diff --git a/dist/cjs/components/__tests__/ProseMirror.domchange.test.js b/dist/cjs/components/__tests__/ProseMirror.domchange.test.js deleted file mode 100644 index 64d134e2..00000000 --- a/dist/cjs/components/__tests__/ProseMirror.domchange.test.js +++ /dev/null @@ -1,555 +0,0 @@ -/** - * @fileoverview - * This file tests that prosemirror-view's DOMObserver works correctly - * in conjunction with React ProseMirror. - * - * @important - * DOMObserver relies on a MutationObserver. The MutationObserver callback - * seems to get queued as a microtask; it will not run until after all - * synchronous code in a test has completed. This is why we manually call - * flush(view) in each test to ensure that the mutation records have been - * flushed. - * - * HOWEVER! If you use an awaited statement after changing the DOM, the - * MutationObserver WILL run. This means that a sequence of DOM changes - * that you want to be staged and detected as a single change may be - * detected and processed in multiple separate phases, which can lead to - * unexpected results. Unsure that you only have synchronous code between - * your first DOM change and your eventual call to flush(view) to avoid this. - */ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-non-null-assertion */ "use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -const _globals = require("@jest/globals"); -const _react = require("@testing-library/react"); -const _userEvent = /*#__PURE__*/ _interopRequireDefault(require("@testing-library/user-event")); -const _prosemirrorState = require("prosemirror-state"); -const _prosemirrorTestBuilder = require("prosemirror-test-builder"); -const _editorViewTestHelpersJs = require("../../testing/editorViewTestHelpers.js"); -const _setupProseMirrorViewJs = require("../../testing/setupProseMirrorView.js"); -function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { - default: obj - }; -} -const img = (0, _prosemirrorTestBuilder.img)({ - src: "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" -}); -function flush(view) { - (0, _react.act)(()=>{ - view.domObserver.flush(); - }); -} -function setSel(aNode, aOff, fNode) { - let fOff = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : 0; - const r = document.createRange(); - const s = window.getSelection(); - r.setEnd(fNode || aNode, fNode ? fOff : aOff); - r.setStart(aNode, aOff); - s.removeAllRanges(); - s.addRange(r); -} -describe("DOM change", ()=>{ - beforeAll(()=>{ - (0, _setupProseMirrorViewJs.setupProseMirrorView)(); - }); - it("notices when text is added", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("hello")) - }); - (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "hello").nodeValue = "heLllo"; - flush(view); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("heLllo"))); - }); - it("notices when text is removed", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("hello")) - }); - (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "hello").nodeValue = "heo"; - flush(view); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("heo"))); - }); - it("handles ambiguous changes", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("hello")) - }); - (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "hello").nodeValue = "helo"; - flush(view); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("helo"))); - }); - it("respects stored marks", async ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("hello")) - }); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.addStoredMark(view.state.schema.marks.em.create())); - }); - (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "hello").nodeValue = "helloo"; - flush(view); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("hello", (0, _prosemirrorTestBuilder.em)("o")))); - }); - it("can add a node", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("hello")) - }); - const txt = (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "hello"); - txt.parentNode.appendChild(document.createTextNode("!")); - flush(view); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("hello!"))); - }); - it("can remove a text node", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("hello")) - }); - const txt = (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "hello"); - txt.parentNode.removeChild(txt); - flush(view); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)())); - }); - it("can add a paragraph", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("hello")) - }); - view.dom.insertBefore(document.createElement("p"), view.dom.firstChild).appendChild(document.createTextNode("hey")); - flush(view); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("hey"), (0, _prosemirrorTestBuilder.p)("hello"))); - }); - it("supports duplicating a paragraph", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("hello")) - }); - view.dom.insertBefore(document.createElement("p"), view.dom.firstChild).appendChild(document.createTextNode("hello")); - flush(view); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("hello"), (0, _prosemirrorTestBuilder.p)("hello"))); - }); - it("support inserting repeated text", async ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("hello")) - }); - (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "hello").nodeValue = "helhello"; - flush(view); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("helhello"))); - }); - it("detects an enter press", async ()=>{ - let enterPressed = false; - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.blockquote)((0, _prosemirrorTestBuilder.p)("foo"), (0, _prosemirrorTestBuilder.p)(""))), - handleKeyDown: (_, event)=>{ - if (event.key === "Enter") return enterPressed = true; - return false; - } - }); - const bq = view.dom.querySelector("blockquote"); - bq.appendChild(document.createElement("p")); - flush(view); - (0, _globals.expect)(enterPressed).toBeTruthy(); - }); - it("detects a simple backspace press", async ()=>{ - let backspacePressed = false; - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.blockquote)((0, _prosemirrorTestBuilder.p)("foo"), (0, _prosemirrorTestBuilder.p)("bar"))), - handleKeyDown: (_, event)=>{ - if (event.key === "Backspace") return backspacePressed = true; - return false; - } - }); - const user = _userEvent.default.setup(); - await (0, _react.act)(async ()=>{ - await user.type(view.dom.firstElementChild, "{Backspace}"); - }); - (0, _globals.expect)(backspacePressed).toBeTruthy(); - }); - // TODO: This causes React to throw an error, because we're - // removing a DOM node that React was responsible for. - // I'm not sure why this only fails in the test environment - // (deletes work just fine in the browser). - // eslint-disable-next-line jest/no-disabled-tests - it.skip("doesn't route delete as backspace", ()=>{ - let backspacePressed = false; - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo"), (0, _prosemirrorTestBuilder.p)("bar")), - handleKeyDown: (_view, event)=>{ - if (event.key === "Backspace") return backspacePressed = true; - return false; - } - }); - (0, _react.act)(()=>{ - view.dom.removeChild(view.dom.lastChild); - view.dom.firstChild.textContent = "foobar"; - flush(view); - }); - (0, _globals.expect)(backspacePressed).toBeFalsy(); - }); - it("correctly adjusts the selection", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("abc")) - }); - const textNode = (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "abc"); - (0, _react.act)(()=>{ - textNode.nodeValue = "abcd"; - setSel(textNode, 3); - flush(view); - }); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("abcd"))); - (0, _globals.expect)(view.state.selection.anchor).toBe(4); - (0, _globals.expect)(view.state.selection.head).toBe(4); - }); - it("handles a deep split of nodes", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.blockquote)((0, _prosemirrorTestBuilder.p)("abcd"))) - }); - const quote = view.dom.querySelector("blockquote"); - const text1 = quote.firstChild.firstChild; - const quote2 = view.dom.appendChild(quote.cloneNode(true)); - const text2 = quote2.firstChild.firstChild; - text1.nodeValue = "abx"; - text2.nodeValue = "cd"; - setSel(text2.parentNode, 0); - flush(view); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.blockquote)((0, _prosemirrorTestBuilder.p)("abx")), (0, _prosemirrorTestBuilder.blockquote)((0, _prosemirrorTestBuilder.p)("cd")))); - (0, _globals.expect)(view.state.selection.anchor).toBe(9); - }); - it("can delete the third instance of a character", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo xxx bar")) - }); - const textNode = (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "foo xxx bar"); - textNode.nodeValue = "foo xx bar"; - flush(view); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo xx bar"))); - }); - it("can read a simple composition", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("hello")) - }); - const textNode = (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "hello"); - textNode.nodeValue = "hellox"; - flush(view); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("hellox"))); - }); - it("can delete text in markup", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("a", (0, _prosemirrorTestBuilder.em)("b", img, (0, _prosemirrorTestBuilder.strong)("cd")), "e")) - }); - const textNode = (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "cd"); - textNode.nodeValue = "c"; - flush(view); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("a", (0, _prosemirrorTestBuilder.em)("b", img, (0, _prosemirrorTestBuilder.strong)("c")), "e"))); - }); - it("recognizes typing inside markup", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("a", (0, _prosemirrorTestBuilder.em)("b", img, (0, _prosemirrorTestBuilder.strong)("cd")), "e")) - }); - const textNode = (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "cd"); - textNode.nodeValue = "cdxy"; - flush(view); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("a", (0, _prosemirrorTestBuilder.em)("b", img, (0, _prosemirrorTestBuilder.strong)("cdxy")), "e"))); - }); - it("resolves ambiguous text input", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")) - }); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.addStoredMark(view.state.schema.marks.strong.create())); - }); - const textNode = (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "foo"); - textNode.nodeValue = "fooo"; - flush(view); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("fo", (0, _prosemirrorTestBuilder.strong)("o"), "o"))); - }); - it("does not repaint a text node when it's typed into", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")) - }); - const textNode = (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "foo"); - textNode.nodeValue = "fojo"; - let mutated = false; - const observer = new MutationObserver(()=>mutated = true); - observer.observe(view.dom, { - subtree: true, - characterData: true, - childList: true - }); - flush(view); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("fojo"))); - (0, _globals.expect)(mutated).toBeFalsy(); - observer.disconnect(); - }); - it("understands text typed into an empty paragraph", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("")) - }); - const paragraph = view.dom.querySelector("p"); - paragraph.replaceChildren("i"); - flush(view); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("i"))); - }); - it("doesn't treat a placeholder BR as real content", async ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("i")) - }); - const paragraph = await _react.screen.findByText("i"); - paragraph.replaceChildren(document.createElement("br")); - flush(view); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)())); - }); - // TODO: Figure out why this doesn't work. Seems like React isn't - // re-rendering after flushing a mutation that doesn't lead to a state - // update. - // eslint-disable-next-line jest/no-disabled-tests - it.skip("fixes text changes when input is ignored", async ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo", (0, _prosemirrorTestBuilder.br)(), "bar")), - dispatchTransaction () { - // ignore transaction - } - }); - const paragraph = await _react.screen.findByText((text)=>text.startsWith("foo")); - paragraph.replaceChild(document.createElement("img"), paragraph.lastChild); - flush(view); - (0, _globals.expect)(view.dom.textContent).toBe("foobar"); - }); - it("aborts when an incompatible state is set", ()=>{ - const { view , rerender } = (0, _editorViewTestHelpersJs.tempEditor)({ - state: _prosemirrorState.EditorState.create({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("abcde")) - }) - }); - const textNode = (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "abcde"); - textNode.nodeValue = "xabcde"; - view.dispatchEvent({ - type: "input" - }); - rerender({ - state: _prosemirrorState.EditorState.create({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("uvw")) - }) - }); - flush(view); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("uvw"))); - }); - // TODO: This causes React to throw an error, because we're - // removing a DOM node that React was responsible for. - // I'm not sure what would cause this actual behavior in real - // life, but if we can replicate it, it would be good to get - // it working. - // eslint-disable-next-line jest/no-disabled-tests - it.skip("recognizes a mark change as such", async ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one")), - dispatchTransaction (tr) { - (0, _globals.expect)(tr.steps).toHaveLength(1); - (0, _globals.expect)(tr.steps[0].toJSON().stepType).toBe("addMark"); - view.updateState(view.state.apply(tr)); - } - }); - const paragraph = await _react.screen.findByText("one"); - const newChild = document.createElement("b"); - newChild.appendChild(document.createTextNode("one")); - paragraph.replaceChildren(newChild); - flush(view); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)((0, _prosemirrorTestBuilder.strong)("one")))); - }); - it("preserves marks on deletion", async ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one", (0, _prosemirrorTestBuilder.em)("x"))) - }); - const emBlock = await _react.screen.findByText("x"); - emBlock.replaceChildren(); - view.dispatchEvent({ - type: "input" - }); - (0, _react.act)(()=>{ - flush(view); - view.dispatch(view.state.tr.insertText("y")); - }); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one", (0, _prosemirrorTestBuilder.em)("y")))); - }); - it("works when a node's contentDOM is deleted", async ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one"), (0, _prosemirrorTestBuilder.pre)("two")) - }); - const codeBlock = await _react.screen.findByText("two"); - (0, _react.act)(()=>{ - codeBlock.replaceChildren(); - view.dispatchEvent({ - type: "input" - }); - flush(view); - }); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one"), (0, _prosemirrorTestBuilder.pre)())); - (0, _globals.expect)(view.state.selection.head).toBe(6); - }); - it("doesn't redraw content with marks when typing in front", async ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo", (0, _prosemirrorTestBuilder.em)("bar"), (0, _prosemirrorTestBuilder.strong)("baz"))) - }); - const bar = await _react.screen.findByText("bar"); - const foo = await _react.screen.findByText("foo"); - foo.firstChild.nodeValue = "froo"; - flush(view); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("froo", (0, _prosemirrorTestBuilder.em)("bar"), (0, _prosemirrorTestBuilder.strong)("baz")))); - (0, _globals.expect)(bar).toBeTruthy(); - (0, _globals.expect)(view.dom.contains(bar)).toBeTruthy(); - (0, _globals.expect)(foo).toBeTruthy(); - (0, _globals.expect)(view.dom.contains(foo)).toBeTruthy(); - }); - it("doesn't redraw content with marks when typing inside mark", async ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo", (0, _prosemirrorTestBuilder.em)("bar"), (0, _prosemirrorTestBuilder.strong)("baz"))) - }); - const bar = await _react.screen.findByText("bar"); - const foo = await _react.screen.findByText("foo"); - bar.firstChild.nodeValue = "baar"; - flush(view); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo", (0, _prosemirrorTestBuilder.em)("baar"), (0, _prosemirrorTestBuilder.strong)("baz")))); - (0, _globals.expect)(bar).toBeTruthy(); - (0, _globals.expect)(view.dom.contains(bar)).toBeTruthy(); - (0, _globals.expect)(foo).toBeTruthy(); - (0, _globals.expect)(view.dom.contains(foo)).toBeTruthy(); - }); - it("maps input to coordsAtPos through pending changes", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")) - }); - (0, _react.act)(()=>{ - view.dispatchEvent({ - type: "input" - }); - view.dispatch(view.state.tr.insertText("more text")); - }); - (0, _globals.expect)(view.coordsAtPos(13)).toBeTruthy(); - }); - it("notices text added to a cursor wrapper at the start of a mark", async ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)((0, _prosemirrorTestBuilder.strong)((0, _prosemirrorTestBuilder.a)("foo"), "bar"))) - }); - const textNode = (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "foo"); - textNode.nodeValue = "fooxy"; - flush(view); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)((0, _prosemirrorTestBuilder.strong)((0, _prosemirrorTestBuilder.a)("foo"), "xybar")))); - }); - it("removes cursor wrapper text when the wrapper otherwise remains valid", async ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)((0, _prosemirrorTestBuilder.a)((0, _prosemirrorTestBuilder.strong)("foo"), "bar"))) - }); - const textNode = (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "foo"); - textNode.nodeValue = "fooq"; - flush(view); - (0, _globals.expect)(view.state.doc).toEqualNode((0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)((0, _prosemirrorTestBuilder.a)((0, _prosemirrorTestBuilder.strong)("fooq"), "bar")))); - const found = _react.screen.queryByText("\uFEFFq"); - (0, _globals.expect)(found).toBeNull(); - }); - it("doesn't confuse backspace with delete", async ()=>{ - let steps; - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("aa")), - dispatchTransaction (tr) { - steps = tr.steps; - view.updateState(view.state.apply(tr)); - } - }); - view.input.lastKeyCode = 8; - view.input.lastKeyCodeTime = Date.now(); - const textNode = (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "aa"); - textNode.nodeValue = "a"; - flush(view); - (0, _globals.expect)(steps).toHaveLength(1); - (0, _globals.expect)(steps[0].from).toBe(1); - (0, _globals.expect)(steps[0].to).toBe(2); - }); - it("can disambiguate a multiple-character backspace event", async ()=>{ - let steps; - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foofoo")), - dispatchTransaction (tr) { - steps = tr.steps; - view.updateState(view.state.apply(tr)); - } - }); - view.input.lastKeyCode = 8; - view.input.lastKeyCodeTime = Date.now(); - const textNode = (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "foofoo"); - textNode.nodeValue = "foo"; - flush(view); - (0, _globals.expect)(steps).toHaveLength(1); - (0, _globals.expect)(steps[0].from).toBe(1); - (0, _globals.expect)(steps[0].to).toBe(4); - }); - it("doesn't confuse delete with backspace", async ()=>{ - let steps; - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("aa")), - dispatchTransaction (tr) { - steps = tr.steps; - view.updateState(view.state.apply(tr)); - } - }); - const textNode = (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "aa"); - textNode.nodeValue = "a"; - flush(view); - (0, _globals.expect)(steps).toHaveLength(1); - (0, _globals.expect)(steps[0].from).toBe(2); - (0, _globals.expect)(steps[0].to).toBe(3); - }); - it("doesn't confuse delete with backspace for multi-character deletions", async ()=>{ - let steps; - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one foofoo three")), - dispatchTransaction (tr) { - steps = tr.steps; - view.updateState(view.state.apply(tr)); - } - }); - const textNode = (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "one foofoo three"); - textNode.nodeValue = "one foo three"; - flush(view); - (0, _globals.expect)(steps).toHaveLength(1); - (0, _globals.expect)(steps[0].from).toBe(8); - (0, _globals.expect)(steps[0].to).toBe(11); - }); - it("creates a correct step for an ambiguous selection-deletion", async ()=>{ - let steps; - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("lalala")), - dispatchTransaction (tr) { - steps = tr.steps; - view.updateState(view.state.apply(tr)); - } - }); - view.input.lastKeyCode = 8; - view.input.lastKeyCodeTime = Date.now(); - const textNode = (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "lalala"); - textNode.nodeValue = "lala"; - flush(view); - (0, _globals.expect)(steps).toHaveLength(1); - (0, _globals.expect)(steps[0].from).toBe(3); - (0, _globals.expect)(steps[0].to).toBe(5); - }); - it("creates a step that covers the entire selection for partially-matching replacement", async ()=>{ - let steps; - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one two three")), - dispatchTransaction (tr) { - steps = tr.steps; - view.updateState(view.state.apply(tr)); - } - }); - const textNode = (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "one two three"); - textNode.nodeValue = "one t three"; - flush(view); - (0, _globals.expect)(steps).toHaveLength(1); - (0, _globals.expect)(steps[0].from).toBe(5); - (0, _globals.expect)(steps[0].to).toBe(8); - (0, _globals.expect)(steps[0].slice.content.toString()).toBe('<"t">'); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.setSelection(_prosemirrorState.TextSelection.create(view.state.doc, 7, 12))); - }); - textNode.nodeValue = "one t e"; - flush(view); - (0, _globals.expect)(steps).toHaveLength(1); - (0, _globals.expect)(steps[0].from).toBe(7); - (0, _globals.expect)(steps[0].to).toBe(12); - (0, _globals.expect)(steps[0].slice.content.toString()).toBe('<"e">'); - }); -}); diff --git a/dist/cjs/components/__tests__/ProseMirror.draw-decoration.test.js b/dist/cjs/components/__tests__/ProseMirror.draw-decoration.test.js deleted file mode 100644 index b4f4b7ae..00000000 --- a/dist/cjs/components/__tests__/ProseMirror.draw-decoration.test.js +++ /dev/null @@ -1,1054 +0,0 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ // TODO: figure out whether it's possible to support native -// widgets. Right now, I'm not sure how we'd do it without -// wrapping them in another element, which would re-introduce -// all of the issues we had before with node views. -// -// For now, we've updated the factory in this file to use -// our React widgets. -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -const _react = require("@testing-library/react"); -const _prosemirrorModel = require("prosemirror-model"); -const _prosemirrorState = require("prosemirror-state"); -const _prosemirrorTestBuilder = require("prosemirror-test-builder"); -const _prosemirrorView = require("prosemirror-view"); -const _react1 = /*#__PURE__*/ _interopRequireWildcard(require("react")); -const _reactWidgetTypeJs = require("../../decorations/ReactWidgetType.js"); -const _useEditorEffectJs = require("../../hooks/useEditorEffect.js"); -const _editorViewTestHelpersJs = require("../../testing/editorViewTestHelpers.js"); -function _extends() { - _extends = Object.assign || function(target) { - for(var i = 1; i < arguments.length; i++){ - var source = arguments[i]; - for(var key in source){ - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; - return _extends.apply(this, arguments); -} -function _getRequireWildcardCache(nodeInterop) { - if (typeof WeakMap !== "function") return null; - var cacheBabelInterop = new WeakMap(); - var cacheNodeInterop = new WeakMap(); - return (_getRequireWildcardCache = function(nodeInterop) { - return nodeInterop ? cacheNodeInterop : cacheBabelInterop; - })(nodeInterop); -} -function _interopRequireWildcard(obj, nodeInterop) { - if (!nodeInterop && obj && obj.__esModule) { - return obj; - } - if (obj === null || typeof obj !== "object" && typeof obj !== "function") { - return { - default: obj - }; - } - var cache = _getRequireWildcardCache(nodeInterop); - if (cache && cache.has(obj)) { - return cache.get(obj); - } - var newObj = {}; - var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; - for(var key in obj){ - if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { - var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; - if (desc && (desc.get || desc.set)) { - Object.defineProperty(newObj, key, desc); - } else { - newObj[key] = obj[key]; - } - } - } - newObj.default = obj; - if (cache) { - cache.set(obj, newObj); - } - return newObj; -} -const Widget = /*#__PURE__*/ (0, _react1.forwardRef)(function Widget(props, ref) { - return /*#__PURE__*/ _react1.default.createElement("button", _extends({ - ref: ref - }, props), "ω"); -}); -function make(str) { - if (typeof str != "string") return str; - const match = /^(\d+)(?:-(\d+))?-(.+)$/.exec(str); - if (match[3] == "widget") { - return (0, _reactWidgetTypeJs.widget)(+match[1], Widget, { - key: str - }); - } - return _prosemirrorView.Decoration.inline(+match[1], +match[2], { - class: match[3] - }); -} -function decoPlugin(decos) { - return new _prosemirrorState.Plugin({ - state: { - init (config) { - return config.doc ? _prosemirrorView.DecorationSet.create(config.doc, decos.map(make)) : _prosemirrorView.DecorationSet.empty; - }, - apply (tr, set, state) { - if (tr.docChanged) { - if (set === _prosemirrorView.DecorationSet.empty) { - set = _prosemirrorView.DecorationSet.create(tr.doc, decos.map(make)); - } - set = set.map(tr.mapping, tr.doc); - } - const change = tr.getMeta("updateDecorations"); - if (change) { - if (change.remove) set = set.remove(change.remove); - if (change.add) set = set.add(state.doc, change.add); - } - return set; - } - }, - props: { - decorations (state) { - return this.getState(state); - } - } - }); -} -function updateDeco(view, add, remove) { - view.dispatch(view.state.tr.setMeta("updateDecorations", { - add, - remove - })); -} -describe("Decoration drawing", ()=>{ - it("draws inline decorations", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foobar")), - plugins: [ - decoPlugin([ - "2-5-foo" - ]) - ] - }); - const found = view.dom.querySelector(".foo"); - expect(found).not.toBeNull(); - expect(found.textContent).toBe("oob"); - }); - it("draws wrapping decorations", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")), - plugins: [ - decoPlugin([ - _prosemirrorView.Decoration.inline(1, 5, { - nodeName: "i" - }) - ]) - ] - }); - const found = view.dom.querySelector("i"); - expect(found && found.innerHTML).toBe("foo"); - }); - it("draws node decorations", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo"), (0, _prosemirrorTestBuilder.p)("bar")), - plugins: [ - decoPlugin([ - _prosemirrorView.Decoration.node(5, 10, { - class: "cls" - }) - ]) - ] - }); - const found = view.dom.querySelectorAll(".cls"); - expect(found).toHaveLength(1); - expect(found[0].nodeName).toBe("P"); - expect(found[0].previousSibling.nodeName).toBe("P"); - }); - it("can update multi-level wrapping decorations", ()=>{ - const d2 = _prosemirrorView.Decoration.inline(1, 5, { - nodeName: "i", - class: "b" - }); - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("hello")), - plugins: [ - decoPlugin([ - _prosemirrorView.Decoration.inline(1, 5, { - nodeName: "i", - class: "a" - }), - d2 - ]) - ] - }); - expect(view.dom.querySelectorAll("i")).toHaveLength(2); - (0, _react.act)(()=>{ - updateDeco(view, [ - _prosemirrorView.Decoration.inline(1, 5, { - nodeName: "i", - class: "c" - }) - ], [ - d2 - ]); - }); - const iNodes = view.dom.querySelectorAll("i"); - expect(iNodes).toHaveLength(2); - expect(Array.prototype.map.call(iNodes, (n)=>n.className).sort().join()).toBe("a,c"); - }); - it("draws overlapping inline decorations", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("abcdef")), - plugins: [ - decoPlugin([ - "3-5-foo", - "4-6-bar", - "1-7-baz" - ]) - ] - }); - const baz = view.dom.querySelectorAll(".baz"); - expect(baz).toHaveLength(5); - expect(Array.prototype.map.call(baz, (x)=>x.textContent).join("-")).toBe("ab-c-d-e-f"); - function classes(n) { - return n.className.split(" ").sort().join(" "); - } - expect(classes(baz[1])).toBe("baz foo"); - expect(classes(baz[2])).toBe("bar baz foo"); - expect(classes(baz[3])).toBe("bar baz"); - }); - it("draws multiple widgets", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foobar")), - plugins: [ - decoPlugin([ - "1-widget", - "4-widget", - "7-widget" - ]) - ] - }); - const found = view.dom.querySelectorAll("button"); - expect(found).toHaveLength(3); - expect(found[0].nextSibling.textContent).toBe("foo"); - expect(found[1].nextSibling.textContent).toBe("bar"); - expect(found[2].previousSibling.textContent).toBe("bar"); - }); - it("orders widgets by their side option", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foobar")), - plugins: [ - decoPlugin([ - (0, _reactWidgetTypeJs.widget)(4, /*#__PURE__*/ (0, _react1.forwardRef)(function B(props, ref) { - return /*#__PURE__*/ _react1.default.createElement("span", _extends({ - ref: ref - }, props), "B"); - }), { - key: "widget-b" - }), - (0, _reactWidgetTypeJs.widget)(4, /*#__PURE__*/ (0, _react1.forwardRef)(function A(props, ref) { - return /*#__PURE__*/ _react1.default.createElement("span", _extends({ - ref: ref - }, props), "A"); - }), { - side: -100, - key: "widget-a" - }), - (0, _reactWidgetTypeJs.widget)(4, /*#__PURE__*/ (0, _react1.forwardRef)(function C(props, ref) { - return /*#__PURE__*/ _react1.default.createElement("span", _extends({ - ref: ref - }, props), "C"); - }), { - side: 2, - key: "widget-c" - }) - ]) - ] - }); - expect(view.dom.textContent).toBe("fooABCbar"); - }); - it("draws a widget in an empty node", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)()), - plugins: [ - decoPlugin([ - "1-widget" - ]) - ] - }); - expect(view.dom.querySelectorAll("button")).toHaveLength(1); - }); - it("draws widgets on node boundaries", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo", (0, _prosemirrorTestBuilder.em)("bar"))), - plugins: [ - decoPlugin([ - "4-widget" - ]) - ] - }); - expect(view.dom.querySelectorAll("button")).toHaveLength(1); - }); - it("draws decorations from multiple plugins", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo", (0, _prosemirrorTestBuilder.em)("bar"))), - plugins: [ - decoPlugin([ - "2-widget" - ]), - decoPlugin([ - "6-widget" - ]) - ] - }); - expect(view.dom.querySelectorAll("button")).toHaveLength(2); - }); - it("calls widget destroy methods", ()=>{ - let destroyed = false; - const DestroyableWidget = /*#__PURE__*/ (0, _react1.forwardRef)(function DestroyableWidget(props, ref) { - (0, _react1.useEffect)(()=>{ - destroyed = true; - }); - return /*#__PURE__*/ _react1.default.createElement("button", _extends({ - ref: ref - }, props)); - }); - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("abc")), - plugins: [ - decoPlugin([ - (0, _reactWidgetTypeJs.widget)(2, DestroyableWidget, { - key: "destroyable-widget" - }) - ]) - ] - }); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.delete(1, 4)); - }); - expect(destroyed).toBeTruthy(); - }); - it("draws inline decorations spanning multiple parents", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("long first ", (0, _prosemirrorTestBuilder.em)("p"), "aragraph"), (0, _prosemirrorTestBuilder.p)("two")), - plugins: [ - decoPlugin([ - "7-25-foo" - ]) - ] - }); - const foos = view.dom.querySelectorAll(".foo"); - expect(foos).toHaveLength(4); - expect(foos[0].textContent).toBe("irst "); - expect(foos[1].textContent).toBe("p"); - expect(foos[2].textContent).toBe("aragraph"); - expect(foos[3].textContent).toBe("tw"); - }); - it("draws inline decorations across empty paragraphs", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("first"), (0, _prosemirrorTestBuilder.p)(), (0, _prosemirrorTestBuilder.p)("second")), - plugins: [ - decoPlugin([ - "3-12-foo" - ]) - ] - }); - const foos = view.dom.querySelectorAll(".foo"); - expect(foos).toHaveLength(2); - expect(foos[0].textContent).toBe("rst"); - expect(foos[1].textContent).toBe("se"); - }); - it("can handle inline decorations ending at the start or end of a node", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)(), (0, _prosemirrorTestBuilder.p)()), - plugins: [ - decoPlugin([ - "1-3-foo" - ]) - ] - }); - expect(view.dom.querySelector(".foo")).toBeNull(); - }); - it("can draw decorations with multiple classes", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")), - plugins: [ - decoPlugin([ - "1-4-foo bar" - ]) - ] - }); - expect(view.dom.querySelectorAll(".foo")).toHaveLength(1); - expect(view.dom.querySelectorAll(".bar")).toHaveLength(1); - }); - it("supports overlapping inline decorations", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foobar")), - plugins: [ - decoPlugin([ - "1-3-foo", - "2-5-bar" - ]) - ] - }); - const foos = view.dom.querySelectorAll(".foo"); - const bars = view.dom.querySelectorAll(".bar"); - expect(foos).toHaveLength(2); - expect(bars).toHaveLength(2); - expect(foos[0].textContent).toBe("f"); - expect(foos[1].textContent).toBe("o"); - expect(bars[0].textContent).toBe("o"); - expect(bars[1].textContent).toBe("ob"); - }); - it("doesn't redraw when irrelevant decorations change", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo"), (0, _prosemirrorTestBuilder.p)("baz")), - plugins: [ - decoPlugin([ - "7-8-foo" - ]) - ] - }); - const para2 = view.dom.lastChild; - (0, _react.act)(()=>{ - updateDeco(view, [ - make("2-3-bar") - ]); - }); - expect(view.dom.lastChild).toBe(para2); - expect(view.dom.querySelector(".bar")).not.toBeNull(); - }); - it("doesn't redraw when irrelevant content changes", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo"), (0, _prosemirrorTestBuilder.p)("baz")), - plugins: [ - decoPlugin([ - "7-8-foo" - ]) - ] - }); - const para2 = view.dom.lastChild; - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.delete(2, 3)); - view.dispatch(view.state.tr.delete(2, 3)); - }); - expect(view.dom.lastChild).toBe(para2); - }); - it("can add a widget on a node boundary", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo", (0, _prosemirrorTestBuilder.em)("bar"))), - plugins: [ - decoPlugin([]) - ] - }); - (0, _react.act)(()=>{ - updateDeco(view, [ - make("4-widget") - ]); - }); - expect(view.dom.querySelectorAll("button")).toHaveLength(1); - }); - it("can remove a widget on a node boundary", ()=>{ - const dec = make("4-widget"); - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo", (0, _prosemirrorTestBuilder.em)("bar"))), - plugins: [ - decoPlugin([ - dec - ]) - ] - }); - (0, _react.act)(()=>{ - updateDeco(view, null, [ - dec - ]); - }); - expect(view.dom.querySelector("button")).toBeNull(); - }); - it("can remove the class from a text node", ()=>{ - const dec = make("1-4-foo"); - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("abc")), - plugins: [ - decoPlugin([ - dec - ]) - ] - }); - expect(view.dom.querySelector(".foo")).not.toBeNull(); - (0, _react.act)(()=>{ - updateDeco(view, null, [ - dec - ]); - }); - expect(view.dom.querySelector(".foo")).toBeNull(); - }); - it("can remove the class from part of a text node", ()=>{ - const dec = make("2-4-foo"); - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("abcd")), - plugins: [ - decoPlugin([ - dec - ]) - ] - }); - expect(view.dom.querySelector(".foo")).not.toBeNull(); - (0, _react.act)(()=>{ - updateDeco(view, null, [ - dec - ]); - }); - expect(view.dom.querySelector(".foo")).toBeNull(); - expect(view.dom.firstChild.innerHTML).toBe("abcd"); - }); - it("can change the class for part of a text node", ()=>{ - const dec = make("2-4-foo"); - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("abcd")), - plugins: [ - decoPlugin([ - dec - ]) - ] - }); - expect(view.dom.querySelector(".foo")).not.toBeNull(); - (0, _react.act)(()=>{ - updateDeco(view, [ - make("2-4-bar") - ], [ - dec - ]); - }); - expect(view.dom.querySelector(".foo")).toBeNull(); - expect(view.dom.querySelector(".bar")).not.toBeNull(); - }); - it("draws a widget added in the middle of a text node", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")), - plugins: [ - decoPlugin([]) - ] - }); - (0, _react.act)(()=>{ - updateDeco(view, [ - make("3-widget") - ]); - }); - expect(view.dom.firstChild.textContent).toBe("foωo"); - }); - it("can update a text node around a widget", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("bar")), - plugins: [ - decoPlugin([ - "3-widget" - ]) - ] - }); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.delete(1, 2)); - }); - expect(view.dom.querySelectorAll("button")).toHaveLength(1); - expect(view.dom.firstChild.textContent).toBe("aωr"); - }); - it("can update a text node with an inline decoration", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("bar")), - plugins: [ - decoPlugin([ - "1-3-foo" - ]) - ] - }); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.delete(1, 2)); - }); - const foo = view.dom.querySelector(".foo"); - expect(foo).not.toBeNull(); - expect(foo.textContent).toBe("a"); - expect(foo.nextSibling.textContent).toBe("r"); - }); - it("correctly redraws a partially decorated node when a widget is added", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one", (0, _prosemirrorTestBuilder.em)("two"))), - plugins: [ - decoPlugin([ - "1-6-foo" - ]) - ] - }); - (0, _react.act)(()=>{ - updateDeco(view, [ - make("6-widget") - ]); - }); - const foos = view.dom.querySelectorAll(".foo"); - expect(foos).toHaveLength(2); - expect(foos[0].textContent).toBe("one"); - expect(foos[1].textContent).toBe("tw"); - }); - it("correctly redraws when skipping split text node", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")), - plugins: [ - decoPlugin([ - "3-widget", - "3-4-foo" - ]) - ] - }); - (0, _react.act)(()=>{ - updateDeco(view, [ - make("4-widget") - ]); - }); - expect(view.dom.querySelectorAll("button")).toHaveLength(2); - }); - it("drops removed node decorations from the view", ()=>{ - const deco = _prosemirrorView.Decoration.node(1, 6, { - class: "cls" - }); - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.blockquote)((0, _prosemirrorTestBuilder.p)("foo"), (0, _prosemirrorTestBuilder.p)("bar"))), - plugins: [ - decoPlugin([ - deco - ]) - ] - }); - (0, _react.act)(()=>{ - updateDeco(view, null, [ - deco - ]); - }); - expect(view.dom.querySelector(".cls")).toBeNull(); - }); - it("can update a node's attributes without replacing the node", ()=>{ - const deco = _prosemirrorView.Decoration.node(0, 5, { - title: "title", - class: "foo" - }); - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")), - plugins: [ - decoPlugin([ - deco - ]) - ] - }); - const para = view.dom.querySelector("p"); - (0, _react.act)(()=>{ - updateDeco(view, [ - _prosemirrorView.Decoration.node(0, 5, { - class: "foo bar" - }) - ], [ - deco - ]); - }); - expect(view.dom.querySelector("p")).toBe(para); - expect(para.className).toBe("foo bar"); - expect(para.title).toBeFalsy(); - }); - it("can add and remove CSS custom properties from a node", ()=>{ - const deco = _prosemirrorView.Decoration.node(0, 5, { - style: "--my-custom-property:36px" - }); - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")), - plugins: [ - decoPlugin([ - deco - ]) - ] - }); - expect(view.dom.querySelector("p").style.getPropertyValue("--my-custom-property")).toBe("36px"); - (0, _react.act)(()=>{ - updateDeco(view, null, [ - deco - ]); - }); - expect(view.dom.querySelector("p").style.getPropertyValue("--my-custom-property")).toBe(""); - }); - it("updates decorated nodes even if a widget is added before them", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("a"), (0, _prosemirrorTestBuilder.p)("b")), - plugins: [ - decoPlugin([]) - ] - }); - const lastP = view.dom.querySelectorAll("p")[1]; - (0, _react.act)(()=>{ - updateDeco(view, [ - make("3-widget"), - _prosemirrorView.Decoration.node(3, 6, { - style: "color: red" - }) - ]); - }); - expect(lastP.style.color).toBe("red"); - }); - it("doesn't redraw nodes when a widget before them is replaced", ()=>{ - const w0 = make("3-widget"); - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.h1)("a"), (0, _prosemirrorTestBuilder.p)("b")), - plugins: [ - decoPlugin([ - w0 - ]) - ] - }); - const initialP = view.dom.querySelector("p"); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.setMeta("updateDecorations", { - add: [ - make("3-widget") - ], - remove: [ - w0 - ] - }).insertText("c", 5)); - }); - expect(view.dom.querySelector("p")).toBe(initialP); - }); - it("can add and remove inline style", ()=>{ - const deco = _prosemirrorView.Decoration.inline(1, 6, { - style: "color: rgba(0,10,200,.4); text-decoration: underline" - }); - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("al", (0, _prosemirrorTestBuilder.img)(), "lo")), - plugins: [ - decoPlugin([ - deco - ]) - ] - }); - expect(view.dom.querySelector("img").style.color).toMatch(/rgba/); - expect(view.dom.querySelector("img").previousSibling.style.textDecoration).toBe("underline"); - (0, _react.act)(()=>{ - updateDeco(view, null, [ - deco - ]); - }); - expect(view.dom.querySelector("img").style.color).toBe(""); - expect(view.dom.querySelector("img").style.textDecoration).toBe(""); - }); - it("passes decorations to a node view", ()=>{ - let current = ""; - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo"), (0, _prosemirrorTestBuilder.hr)()), - plugins: [ - decoPlugin([]) - ], - nodeViews: { - horizontal_rule: /*#__PURE__*/ (0, _react1.forwardRef)(function HR(props, ref) { - current = props.nodeProps.decorations.map((d)=>d.spec.name).join(); - return /*#__PURE__*/ _react1.default.createElement("hr", { - ref: ref - }); - }) - } - }); - const a = _prosemirrorView.Decoration.node(5, 6, {}, { - name: "a" - }); - (0, _react.act)(()=>{ - updateDeco(view, [ - a - ], []); - }); - expect(current).toBe("a"); - (0, _react.act)(()=>{ - updateDeco(view, [ - _prosemirrorView.Decoration.node(5, 6, {}, { - name: "b" - }), - _prosemirrorView.Decoration.node(5, 6, {}, { - name: "c" - }) - ], [ - a - ]); - }); - expect(current).toBe("b,c"); - }); - it("draws the specified marks around a widget", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foobar")), - plugins: [ - decoPlugin([ - (0, _reactWidgetTypeJs.widget)(4, /*#__PURE__*/ (0, _react1.forwardRef)(function Img(props, ref) { - return /*#__PURE__*/ _react1.default.createElement("img", _extends({}, props, { - ref: ref - })); - }), { - marks: [ - _prosemirrorTestBuilder.schema.mark("em") - ], - key: "img-widget" - }) - ]) - ] - }); - expect(view.dom.querySelector("em img")).not.toBeNull(); - }); - it("draws widgets inside the marks for their side", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)((0, _prosemirrorTestBuilder.em)("foo"), (0, _prosemirrorTestBuilder.strong)("bar"))), - plugins: [ - decoPlugin([ - (0, _reactWidgetTypeJs.widget)(4, /*#__PURE__*/ (0, _react1.forwardRef)(function Img(props, ref) { - return /*#__PURE__*/ _react1.default.createElement("img", _extends({}, props, { - ref: ref - })); - }), { - side: -1, - key: "img-widget" - }) - ]), - decoPlugin([ - (0, _reactWidgetTypeJs.widget)(4, /*#__PURE__*/ (0, _react1.forwardRef)(function BR(props, ref) { - return /*#__PURE__*/ _react1.default.createElement("br", _extends({}, props, { - ref: ref - })); - }), { - key: "br-widget" - }) - ]), - decoPlugin([ - (0, _reactWidgetTypeJs.widget)(7, /*#__PURE__*/ (0, _react1.forwardRef)(function Span(props, ref) { - return /*#__PURE__*/ _react1.default.createElement("span", _extends({}, props, { - ref: ref - })); - }), { - side: 1, - key: "span-widget" - }) - ]) - ] - }); - expect(view.dom.querySelector("em img")).not.toBeNull(); - expect(view.dom.querySelector("strong img")).toBeNull(); - expect(view.dom.querySelector("strong br")).not.toBeNull(); - expect(view.dom.querySelector("em br")).toBeNull(); - expect(view.dom.querySelector("strong span")).toBeNull(); - }); - it("draws decorations inside node views", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")), - nodeViews: { - paragraph: /*#__PURE__*/ (0, _react1.forwardRef)(function Paragraph(param, ref) { - let { nodeProps , children , ...props } = param; - return /*#__PURE__*/ _react1.default.createElement("p", _extends({ - ref: ref - }, props), children); - }) - }, - plugins: [ - decoPlugin([ - (0, _reactWidgetTypeJs.widget)(2, /*#__PURE__*/ (0, _react1.forwardRef)(function Img(props, ref) { - return /*#__PURE__*/ _react1.default.createElement("img", _extends({}, props, { - ref: ref - })); - }), { - key: "img-widget" - }) - ]) - ] - }); - expect(view.dom.querySelector("img")).not.toBeNull(); - }); - it("can delay widget drawing to render time", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("hi")), - decorations (state) { - return _prosemirrorView.DecorationSet.create(state.doc, [ - (0, _reactWidgetTypeJs.widget)(3, /*#__PURE__*/ (0, _react1.forwardRef)(function Span(props, ref) { - (0, _useEditorEffectJs.useEditorEffect)((view)=>{ - expect(view?.state).toBe(state); - }); - return /*#__PURE__*/ _react1.default.createElement("span", _extends({}, props, { - ref: ref - }), "!"); - }), { - key: "span-widget" - }) - ]); - } - }); - expect(view.dom.textContent).toBe("hi!"); - }); - it("supports widgets querying their own position", ()=>{ - (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("hi")), - decorations (state) { - return _prosemirrorView.DecorationSet.create(state.doc, [ - (0, _reactWidgetTypeJs.widget)(3, /*#__PURE__*/ (0, _react1.forwardRef)(function Widget(param, ref) { - let { pos , ...props } = param; - expect(pos).toBe(3); - return /*#__PURE__*/ _react1.default.createElement("button", _extends({ - ref: ref - }, props), "ω"); - }), { - key: "button-widget" - }) - ]); - } - }); - }); - it("doesn't redraw widgets with matching keys", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("hi")), - decorations (state) { - return _prosemirrorView.DecorationSet.create(state.doc, [ - (0, _reactWidgetTypeJs.widget)(2, Widget, { - key: "myButton" - }) - ]); - } - }); - const widgetDOM = view.dom.querySelector("button"); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.insertText("!", 2, 2)); - }); - expect(view.dom.querySelector("button")).toBe(widgetDOM); - }); - it("doesn't redraw widgets with identical specs", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("hi")), - decorations (state) { - return _prosemirrorView.DecorationSet.create(state.doc, [ - (0, _reactWidgetTypeJs.widget)(2, Widget, { - side: 1, - key: "widget" - }) - ]); - } - }); - const widgetDOM = view.dom.querySelector("button"); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.insertText("!", 2, 2)); - }); - expect(view.dom.querySelector("button")).toBe(widgetDOM); - }); - it("doesn't get confused by split text nodes", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("abab")), - decorations (state) { - return state.selection.from <= 1 ? null : _prosemirrorView.DecorationSet.create(view.state.doc, [ - _prosemirrorView.Decoration.inline(1, 2, { - class: "foo" - }), - _prosemirrorView.Decoration.inline(3, 4, { - class: "foo" - }) - ]); - } - }); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.setSelection(_prosemirrorState.TextSelection.create(view.state.doc, 5))); - }); - expect(view.dom.textContent).toBe("abab"); - }); - it("only draws inline decorations on the innermost level", ()=>{ - const s = new _prosemirrorModel.Schema({ - nodes: { - doc: { - content: "(text | thing)*" - }, - text: {}, - thing: { - inline: true, - content: "text*", - toDOM: ()=>[ - "strong", - 0 - ], - parseDOM: [ - { - tag: "strong" - } - ] - } - } - }); - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: s.node("doc", null, [ - s.text("abc"), - s.node("thing", null, [ - s.text("def") - ]), - s.text("ghi") - ]), - decorations: (s)=>_prosemirrorView.DecorationSet.create(s.doc, [ - _prosemirrorView.Decoration.inline(1, 10, { - class: "dec" - }) - ]) - }); - const styled = view.dom.querySelectorAll(".dec"); - expect(styled).toHaveLength(3); - expect(Array.prototype.map.call(styled, (n)=>n.textContent).join()).toBe("bc,def,gh"); - expect(styled[1].parentNode.nodeName).toBe("STRONG"); - }); - it("can handle nodeName decoration overlapping with classes", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one two three")), - plugins: [ - decoPlugin([ - _prosemirrorView.Decoration.inline(2, 13, { - class: "foo" - }), - _prosemirrorView.Decoration.inline(5, 8, { - nodeName: "em" - }) - ]) - ] - }); - expect(view.dom.firstChild.innerHTML).toBe('one two three'); - }); - it("can handle combining decorations from parent editors in child editors", ()=>{ - let decosFromFirstEditor; - let { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one two three")), - plugins: [ - decoPlugin([ - _prosemirrorView.Decoration.inline(2, 13, { - class: "foo" - }) - ]), - decoPlugin([ - _prosemirrorView.Decoration.inline(2, 13, { - class: "bar" - }) - ]) - ], - nodeViews: { - paragraph: /*#__PURE__*/ (0, _react1.forwardRef)(function Paragraph(param, ref) { - let { nodeProps , children , ...props } = param; - decosFromFirstEditor = nodeProps.innerDecorations; - return /*#__PURE__*/ _react1.default.createElement("p", _extends({ - ref: ref - }, props), children); - }) - } - }); - ({ view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one two three")), - plugins: [ - decoPlugin([ - _prosemirrorView.Decoration.inline(1, 12, { - class: "baz" - }) - ]) - ], - decorations: ()=>decosFromFirstEditor - })); - expect(view.dom.querySelectorAll(".foo")).toHaveLength(1); - expect(view.dom.querySelectorAll(".bar")).toHaveLength(1); - expect(view.dom.querySelectorAll(".baz")).toHaveLength(1); - }); -}); diff --git a/dist/cjs/components/__tests__/ProseMirror.draw.test.js b/dist/cjs/components/__tests__/ProseMirror.draw.test.js deleted file mode 100644 index fe8b3120..00000000 --- a/dist/cjs/components/__tests__/ProseMirror.draw.test.js +++ /dev/null @@ -1,344 +0,0 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ "use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -const _react = require("@testing-library/react"); -const _prosemirrorModel = require("prosemirror-model"); -const _prosemirrorState = require("prosemirror-state"); -const _prosemirrorTestBuilder = require("prosemirror-test-builder"); -const _react1 = /*#__PURE__*/ _interopRequireWildcard(require("react")); -const _editorViewTestHelpersJs = require("../../testing/editorViewTestHelpers.js"); -function _getRequireWildcardCache(nodeInterop) { - if (typeof WeakMap !== "function") return null; - var cacheBabelInterop = new WeakMap(); - var cacheNodeInterop = new WeakMap(); - return (_getRequireWildcardCache = function(nodeInterop) { - return nodeInterop ? cacheNodeInterop : cacheBabelInterop; - })(nodeInterop); -} -function _interopRequireWildcard(obj, nodeInterop) { - if (!nodeInterop && obj && obj.__esModule) { - return obj; - } - if (obj === null || typeof obj !== "object" && typeof obj !== "function") { - return { - default: obj - }; - } - var cache = _getRequireWildcardCache(nodeInterop); - if (cache && cache.has(obj)) { - return cache.get(obj); - } - var newObj = {}; - var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; - for(var key in obj){ - if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { - var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; - if (desc && (desc.get || desc.set)) { - Object.defineProperty(newObj, key, desc); - } else { - newObj[key] = obj[key]; - } - } - } - newObj.default = obj; - if (cache) { - cache.set(obj, newObj); - } - return newObj; -} -describe("EditorView draw", ()=>{ - it("updates the DOM", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")) - }); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.insertText("bar")); - }); - expect(view.dom.textContent).toBe("barfoo"); - }); - it("doesn't redraw nodes after changes", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.h1)("foo"), (0, _prosemirrorTestBuilder.p)("bar")) - }); - const oldP = view.dom.querySelector("p"); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.insertText("!")); - }); - expect(view.dom.querySelector("p")).toBe(oldP); - }); - it("doesn't redraw nodes before changes", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo"), (0, _prosemirrorTestBuilder.h1)("bar")) - }); - const oldP = view.dom.querySelector("p"); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.insertText("!", 2)); - }); - expect(view.dom.querySelector("p")).toBe(oldP); - }); - it("doesn't redraw nodes between changes", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo"), (0, _prosemirrorTestBuilder.h1)("bar"), (0, _prosemirrorTestBuilder.pre)("baz")) - }); - const oldP = view.dom.querySelector("p"); - const oldPre = view.dom.querySelector("pre"); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.insertText("!", 2)); - }); - expect(view.dom.querySelector("p")).toBe(oldP); - expect(view.dom.querySelector("pre")).toBe(oldPre); - }); - it("doesn't redraw siblings of a split node", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo"), (0, _prosemirrorTestBuilder.h1)("bar"), (0, _prosemirrorTestBuilder.pre)("baz")) - }); - const oldP = view.dom.querySelector("p"); - const oldPre = view.dom.querySelector("pre"); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.split(8)); - }); - expect(view.dom.querySelector("p")).toBe(oldP); - expect(view.dom.querySelector("pre")).toBe(oldPre); - }); - it("doesn't redraw siblings of a joined node", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo"), (0, _prosemirrorTestBuilder.h1)("bar"), (0, _prosemirrorTestBuilder.h1)("x"), (0, _prosemirrorTestBuilder.pre)("baz")) - }); - const oldP = view.dom.querySelector("p"); - const oldPre = view.dom.querySelector("pre"); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.join(10)); - }); - expect(view.dom.querySelector("p")).toBe(oldP); - expect(view.dom.querySelector("pre")).toBe(oldPre); - }); - it("doesn't redraw after a big deletion", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)(), (0, _prosemirrorTestBuilder.p)(), (0, _prosemirrorTestBuilder.p)(), (0, _prosemirrorTestBuilder.p)(), (0, _prosemirrorTestBuilder.p)(), (0, _prosemirrorTestBuilder.p)(), (0, _prosemirrorTestBuilder.p)(), (0, _prosemirrorTestBuilder.p)(), (0, _prosemirrorTestBuilder.h1)("!"), (0, _prosemirrorTestBuilder.p)(), (0, _prosemirrorTestBuilder.p)()) - }); - const oldH = view.dom.querySelector("h1"); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.delete(2, 14)); - }); - expect(view.dom.querySelector("h1")).toBe(oldH); - }); - it("adds classes from the attributes prop", ()=>{ - const { view , rerender } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)()), - attributes: { - class: "foo bar" - } - }); - expect(view.dom.classList.contains("foo")).toBeTruthy(); - expect(view.dom.classList.contains("bar")).toBeTruthy(); - expect(view.dom.classList.contains("ProseMirror")).toBeTruthy(); - (0, _react.act)(()=>{ - rerender({ - attributes: { - class: "baz" - } - }); - }); - expect(!view.dom.classList.contains("foo")).toBeTruthy(); - expect(view.dom.classList.contains("baz")).toBeTruthy(); - }); - it("adds style from the attributes prop", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)()), - attributes: { - style: "border: 1px solid red;" - }, - plugins: [ - new _prosemirrorState.Plugin({ - props: { - attributes: { - style: "background: red;" - } - } - }), - new _prosemirrorState.Plugin({ - props: { - attributes: { - style: "color: red;" - } - } - }) - ] - }); - expect(view.dom.style.border).toBe("1px solid red"); - expect(view.dom.style.backgroundColor).toBe("red"); - expect(view.dom.style.color).toBe("red"); - }); - it("can set other attributes", ()=>{ - const { view , rerender } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)()), - attributes: { - spellcheck: "false", - "aria-label": "hello" - } - }); - expect(view.dom.getAttribute("spellcheck")).toBe("false"); - expect(view.dom.getAttribute("aria-label")).toBe("hello"); - (0, _react.act)(()=>{ - rerender({ - attributes: { - style: "background-color: yellow" - } - }); - }); - expect(view.dom.hasAttribute("aria-label")).toBe(false); - expect(view.dom.style.backgroundColor).toBe("yellow"); - }); - it("can't set the contenteditable attribute", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)()), - attributes: { - contenteditable: "false" - } - }); - expect(view.dom.getAttribute("contenteditable")).toBe("true"); - }); - it("understands the editable prop", ()=>{ - const { view , rerender } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)()), - editable: ()=>false - }); - expect(view.dom.getAttribute("contenteditable")).toBe("false"); - rerender({ - editable: ()=>true - }); - expect(view.dom.getAttribute("contenteditable")).toBe("true"); - }); - it("doesn't redraw following paragraphs when a paragraph is split", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("abcde"), (0, _prosemirrorTestBuilder.p)("fg")) - }); - const lastPara = view.dom.lastChild; - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.split(3)); - }); - expect(view.dom.lastChild).toBe(lastPara); - }); - it("doesn't greedily match nodes that have another match", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("a"), (0, _prosemirrorTestBuilder.p)("b"), (0, _prosemirrorTestBuilder.p)()) - }); - const secondPara = view.dom.querySelectorAll("p")[1]; - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.split(2)); - }); - expect(view.dom.querySelectorAll("p")[2]).toBe(secondPara); - }); - it("creates and destroys plugin views", ()=>{ - const events = []; - let PluginView = class PluginView { - update() { - events.push("update"); - } - destroy() { - events.push("destroy"); - } - }; - const plugin = new _prosemirrorState.Plugin({ - view () { - events.push("create"); - return new PluginView(); - } - }); - const { view , unmount } = (0, _editorViewTestHelpersJs.tempEditor)({ - plugins: [ - plugin - ] - }); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.insertText("u")); - }); - unmount(); - expect(events.join(" ")).toBe("create update destroy"); - }); - it("redraws changed node views", ()=>{ - const { view , rerender } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo"), (0, _prosemirrorTestBuilder.hr)()) - }); - expect(view.dom.querySelector("hr")).toBeTruthy(); - rerender({ - nodeViews: { - horizontal_rule: /*#__PURE__*/ (0, _react1.forwardRef)(function Var(props, ref) { - return /*#__PURE__*/ _react1.default.createElement("var", { - ref: ref - }, props.children); - }) - } - }); - expect(!view.dom.querySelector("hr")).toBeTruthy(); - expect(view.dom.querySelector("var")).toBeTruthy(); - }); - it("doesn't get confused by merged nodes", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)((0, _prosemirrorTestBuilder.strong)("one"), " two ", (0, _prosemirrorTestBuilder.strong)("three"))) - }); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.removeMark(1, 4, _prosemirrorTestBuilder.schema.marks.strong)); - }); - expect(view.dom.querySelectorAll("strong")).toHaveLength(1); - }); - it("doesn't redraw too much when marks are present", ()=>{ - const s = new _prosemirrorModel.Schema({ - nodes: { - doc: { - content: "paragraph+", - marks: "m" - }, - text: { - group: "inline" - }, - paragraph: _prosemirrorTestBuilder.schema.spec.nodes.get("paragraph") - }, - marks: { - m: { - toDOM: ()=>[ - "div", - { - class: "m" - }, - 0 - ], - parseDOM: [ - { - tag: "div.m" - } - ] - } - } - }); - const paragraphs = []; - for(let i = 1; i <= 10; i++)paragraphs.push(s.node("paragraph", null, [ - s.text("para " + i) - ], [ - s.mark("m") - ])); - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - // @ts-expect-error this is fine - doc: s.node("doc", null, paragraphs) - }); - const initialChildren = Array.from(view.dom.querySelectorAll("p")); - const newParagraphs = []; - for(let i = -6; i < 0; i++)newParagraphs.push(s.node("paragraph", null, [ - s.text("para " + i) - ], [ - s.mark("m") - ])); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.replaceWith(0, 8, newParagraphs)); - }); - const currentChildren = Array.from(view.dom.querySelectorAll("p")); - let sameAtEnd = 0; - while(sameAtEnd < currentChildren.length && sameAtEnd < initialChildren.length && currentChildren[currentChildren.length - sameAtEnd - 1] == initialChildren[initialChildren.length - sameAtEnd - 1])sameAtEnd++; - // $$FORK: Our node stability isn't _quite_ as robust - // as prosemirror-view's. The node adjacent to the one - // that was replaced also gets repainted. - // expect(sameAtEnd).toBe(9); - expect(sameAtEnd).toBe(8); - }); -}); diff --git a/dist/cjs/components/__tests__/ProseMirror.node-view.test.js b/dist/cjs/components/__tests__/ProseMirror.node-view.test.js deleted file mode 100644 index 253fe67c..00000000 --- a/dist/cjs/components/__tests__/ProseMirror.node-view.test.js +++ /dev/null @@ -1,559 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-non-null-assertion */ "use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -const _react = require("@testing-library/react"); -const _prosemirrorState = require("prosemirror-state"); -const _prosemirrorTestBuilder = require("prosemirror-test-builder"); -const _prosemirrorView = require("prosemirror-view"); -const _react1 = /*#__PURE__*/ _interopRequireWildcard(require("react")); -const _editorViewTestHelpersJs = require("../../testing/editorViewTestHelpers.js"); -function _extends() { - _extends = Object.assign || function(target) { - for(var i = 1; i < arguments.length; i++){ - var source = arguments[i]; - for(var key in source){ - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; - return _extends.apply(this, arguments); -} -function _getRequireWildcardCache(nodeInterop) { - if (typeof WeakMap !== "function") return null; - var cacheBabelInterop = new WeakMap(); - var cacheNodeInterop = new WeakMap(); - return (_getRequireWildcardCache = function(nodeInterop) { - return nodeInterop ? cacheNodeInterop : cacheBabelInterop; - })(nodeInterop); -} -function _interopRequireWildcard(obj, nodeInterop) { - if (!nodeInterop && obj && obj.__esModule) { - return obj; - } - if (obj === null || typeof obj !== "object" && typeof obj !== "function") { - return { - default: obj - }; - } - var cache = _getRequireWildcardCache(nodeInterop); - if (cache && cache.has(obj)) { - return cache.get(obj); - } - var newObj = {}; - var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; - for(var key in obj){ - if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { - var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; - if (desc && (desc.get || desc.set)) { - Object.defineProperty(newObj, key, desc); - } else { - newObj[key] = obj[key]; - } - } - } - newObj.default = obj; - if (cache) { - cache.set(obj, newObj); - } - return newObj; -} -describe("React-based node views prop", ()=>{ - it("can replace a node's representation", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo", (0, _prosemirrorTestBuilder.br)())), - nodeViews: { - hard_break: /*#__PURE__*/ (0, _react1.forwardRef)(function Var(props, ref) { - return /*#__PURE__*/ _react1.default.createElement("var", { - ref: ref - }, props.children); - }) - } - }); - expect(view.dom.querySelector("var")).not.toBeNull(); - }); - it("can override drawing of a node's content", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")), - nodeViews: { - paragraph: /*#__PURE__*/ (0, _react1.forwardRef)(function Paragraph(props, ref) { - return /*#__PURE__*/ _react1.default.createElement("p", { - ref: ref - }, props.nodeProps.node.textContent.toUpperCase()); - }) - } - }); - expect(view.dom.querySelector("p").textContent).toBe("FOO"); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.insertText("a")); - }); - expect(view.dom.querySelector("p").textContent).toBe("AFOO"); - }); - // React makes this more or less trivial; the render - // method of the component _is_ the update (and create) - // method - // eslint-disable-next-line jest/no-disabled-tests - it.skip("can register its own update method", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")), - nodeViews: { - paragraph: /*#__PURE__*/ (0, _react1.forwardRef)(function Paragraph(props, ref) { - return /*#__PURE__*/ _react1.default.createElement("p", { - ref: ref - }, props.nodeProps.node.textContent.toUpperCase()); - }) - } - }); - const para = view.dom.querySelector("p"); - view.dispatch(view.state.tr.insertText("a")); - expect(view.dom.querySelector("p")).toBe(para); - expect(para.textContent).toBe("AFOO"); - }); - it("allows decoration updates for node views with an update method", ()=>{ - const { view , rerender } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")), - nodeViews: { - paragraph: /*#__PURE__*/ (0, _react1.forwardRef)(function Paragraph(param, ref) { - let { children , nodeProps , ...props } = param; - return /*#__PURE__*/ _react1.default.createElement("p", _extends({ - ref: ref - }, props), children); - }) - } - }); - rerender({ - decorations (state) { - return _prosemirrorView.DecorationSet.create(state.doc, [ - _prosemirrorView.Decoration.inline(2, 3, { - someattr: "ok" - }), - _prosemirrorView.Decoration.node(0, 5, { - otherattr: "ok" - }) - ]); - } - }); - expect(view.dom.querySelector("[someattr]")).not.toBeNull(); - expect(view.dom.querySelector("[otherattr]")).not.toBeNull(); - }); - it("can provide a contentDOM property", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")), - nodeViews: { - paragraph: /*#__PURE__*/ (0, _react1.forwardRef)(function Paragraph(props, ref) { - return(// ContentDOM is inferred from where props.children is rendered - /*#__PURE__*/ _react1.default.createElement("p", { - ref: ref - }, props.children)); - }) - } - }); - const para = view.dom.querySelector("p"); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.insertText("a")); - }); - expect(view.dom.querySelector("p")).toBe(para); - expect(para.textContent).toBe("afoo"); - }); - it("has its destroy method called", ()=>{ - let destroyed = false; - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo", (0, _prosemirrorTestBuilder.br)())), - nodeViews: { - hard_break: /*#__PURE__*/ (0, _react1.forwardRef)(function BR(_props, ref) { - // React implements "destroy methods" with effect - // hooks - (0, _react1.useEffect)(()=>{ - return ()=>{ - destroyed = true; - }; - }, []); - return /*#__PURE__*/ _react1.default.createElement("br", { - ref: ref - }); - }) - } - }); - expect(destroyed).toBeFalsy(); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.delete(3, 5)); - }); - expect(destroyed).toBeTruthy(); - }); - it("can query its own position", ()=>{ - let pos; - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.blockquote)((0, _prosemirrorTestBuilder.p)("abc"), (0, _prosemirrorTestBuilder.p)("foo", (0, _prosemirrorTestBuilder.br)()))), - nodeViews: { - hard_break: /*#__PURE__*/ (0, _react1.forwardRef)(function BR(props, ref) { - pos = props.nodeProps.pos; - return /*#__PURE__*/ _react1.default.createElement("br", { - ref: ref - }); - }) - } - }); - expect(pos).toBe(10); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.insertText("a")); - }); - expect(pos).toBe(11); - }); - it("has access to outer decorations", ()=>{ - const plugin = new _prosemirrorState.Plugin({ - state: { - init () { - return null; - }, - apply (tr, prev) { - return tr.getMeta("setDeco") || prev; - } - }, - props: { - decorations (state) { - const deco = this.getState(state); - return deco && _prosemirrorView.DecorationSet.create(state.doc, [ - _prosemirrorView.Decoration.inline(0, state.doc.content.size, {}, { - name: deco - }) - ]); - } - } - }); - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo", (0, _prosemirrorTestBuilder.br)())), - plugins: [ - plugin - ], - nodeViews: { - hard_break: /*#__PURE__*/ (0, _react1.forwardRef)(function Var(props, ref) { - return /*#__PURE__*/ _react1.default.createElement("var", { - ref: ref - }, props.nodeProps.decorations.length ? props.nodeProps.decorations[0].spec.name : "[]"); - }) - } - }); - expect(view.dom.querySelector("var").textContent).toBe("[]"); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.setMeta("setDeco", "foo")); - }); - expect(view.dom.querySelector("var").textContent).toBe("foo"); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.setMeta("setDeco", "bar")); - }); - expect(view.dom.querySelector("var").textContent).toBe("bar"); - }); - it("provides access to inner decorations in the constructor", ()=>{ - (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")), - nodeViews: { - paragraph: /*#__PURE__*/ (0, _react1.forwardRef)(function Paragraph(props, ref) { - expect(props.nodeProps.innerDecorations.find().map((d)=>`${d.from}-${d.to}`).join()).toBe("1-2"); - return /*#__PURE__*/ _react1.default.createElement("p", { - ref: ref - }, props.children); - }) - }, - decorations (state) { - return _prosemirrorView.DecorationSet.create(state.doc, [ - _prosemirrorView.Decoration.inline(2, 3, { - someattr: "ok" - }), - _prosemirrorView.Decoration.node(0, 5, { - otherattr: "ok" - }) - ]); - } - }); - }); - it("provides access to inner decorations in the update method", ()=>{ - let innerDecos = []; - const { rerender } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")), - nodeViews: { - paragraph: /*#__PURE__*/ (0, _react1.forwardRef)(function Paragraph(props, ref) { - innerDecos = props.nodeProps.innerDecorations.find().map((d)=>`${d.from}-${d.to}`); - return /*#__PURE__*/ _react1.default.createElement("p", { - ref: ref - }, props.children); - }) - } - }); - rerender({ - decorations (state) { - return _prosemirrorView.DecorationSet.create(state.doc, [ - _prosemirrorView.Decoration.inline(2, 3, { - someattr: "ok" - }), - _prosemirrorView.Decoration.node(0, 5, { - otherattr: "ok" - }) - ]); - } - }); - expect(innerDecos.join()).toBe("1-2"); - }); -}); -describe("Classic node views prop", ()=>{ - it("can replace a node's representation", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo", (0, _prosemirrorTestBuilder.br)())), - customNodeViews: { - hard_break () { - return { - dom: document.createElement("var") - }; - } - } - }); - expect(view.dom.querySelector("var")).not.toBeNull(); - }); - it("can override drawing of a node's content", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")), - customNodeViews: { - paragraph (node) { - const dom = document.createElement("p"); - dom.textContent = node.textContent.toUpperCase(); - return { - dom - }; - } - } - }); - expect(view.dom.querySelector("p").textContent).toBe("FOO"); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.insertText("a")); - }); - // TODO: Fix this. I think that ProseMirror's behavior is to - // call the constructor again in this scenario. - expect(view.dom.querySelector("p").textContent).toBe("AFOO"); - }); - it("can register its own update method", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")), - customNodeViews: { - paragraph (node) { - const dom = document.createElement("p"); - dom.textContent = node.textContent.toUpperCase(); - return { - dom, - update (node) { - dom.textContent = node.textContent.toUpperCase(); - return true; - } - }; - } - } - }); - const para = view.dom.querySelector("p"); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.insertText("a")); - }); - expect(view.dom.querySelector("p")).toBe(para); - expect(para.textContent).toBe("AFOO"); - }); - it("allows decoration updates for node views with an update method", ()=>{ - const { view , rerender } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")), - customNodeViews: { - paragraph (node) { - const dom = document.createElement("p"); - return { - dom, - contentDOM: dom, - update (node_) { - return node.sameMarkup(node_); - } - }; - } - } - }); - rerender({ - decorations (state) { - return _prosemirrorView.DecorationSet.create(state.doc, [ - _prosemirrorView.Decoration.inline(2, 3, { - someattr: "ok" - }), - _prosemirrorView.Decoration.node(0, 5, { - otherattr: "ok" - }) - ]); - } - }); - expect(view.dom.querySelector("[someattr]")).not.toBeNull(); - expect(view.dom.querySelector("[otherattr]")).not.toBeNull(); - }); - it("can provide a contentDOM property", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")), - customNodeViews: { - paragraph () { - const dom = document.createElement("p"); - return { - dom, - contentDOM: dom - }; - } - } - }); - const para = view.dom.querySelector("p"); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.insertText("a")); - }); - expect(view.dom.querySelector("p")).toBe(para); - expect(para.textContent).toBe("afoo"); - }); - it("has its destroy method called", ()=>{ - let destroyed = false; - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo", (0, _prosemirrorTestBuilder.br)())), - customNodeViews: { - hard_break () { - return { - dom: document.createElement("br"), - destroy: ()=>destroyed = true - }; - } - } - }); - expect(destroyed).toBeFalsy(); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.delete(3, 5)); - }); - expect(destroyed).toBeTruthy(); - }); - it("can query its own position", ()=>{ - let get; - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.blockquote)((0, _prosemirrorTestBuilder.p)("abc"), (0, _prosemirrorTestBuilder.p)("foo", (0, _prosemirrorTestBuilder.br)()))), - customNodeViews: { - hard_break (_n, _v, getPos) { - expect(getPos()).toBe(10); - get = getPos; - return { - dom: document.createElement("br") - }; - } - } - }); - expect(get()).toBe(10); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.insertText("a")); - }); - expect(get()).toBe(11); - }); - it("has access to outer decorations", ()=>{ - const plugin = new _prosemirrorState.Plugin({ - state: { - init () { - return null; - }, - apply (tr, prev) { - return tr.getMeta("setDeco") || prev; - } - }, - props: { - decorations (state) { - const deco = this.getState(state); - return deco && _prosemirrorView.DecorationSet.create(state.doc, [ - _prosemirrorView.Decoration.inline(0, state.doc.content.size, {}, { - name: deco - }) - ]); - } - } - }); - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo", (0, _prosemirrorTestBuilder.br)())), - plugins: [ - plugin - ], - customNodeViews: { - hard_break (_n, _v, _p, deco) { - const dom = document.createElement("var"); - function update(deco) { - dom.textContent = deco.length ? deco[0].spec.name : "[]"; - } - update(deco); - return { - dom, - update (_, deco) { - update(deco); - return true; - } - }; - } - } - }); - expect(view.dom.querySelector("var").textContent).toBe("[]"); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.setMeta("setDeco", "foo")); - }); - expect(view.dom.querySelector("var").textContent).toBe("foo"); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.setMeta("setDeco", "bar")); - }); - expect(view.dom.querySelector("var").textContent).toBe("bar"); - }); - it("provides access to inner decorations in the constructor", ()=>{ - (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")), - customNodeViews: { - paragraph (_node, _v, _pos, _outer, innerDeco) { - const dom = document.createElement("p"); - expect(innerDeco.find().map((d)=>`${d.from}-${d.to}`).join()).toBe("1-2"); - return { - dom, - contentDOM: dom - }; - } - }, - decorations (state) { - return _prosemirrorView.DecorationSet.create(state.doc, [ - _prosemirrorView.Decoration.inline(2, 3, { - someattr: "ok" - }), - _prosemirrorView.Decoration.node(0, 5, { - otherattr: "ok" - }) - ]); - } - }); - }); - it("provides access to inner decorations in the update method", ()=>{ - let innerDecos = []; - const { rerender } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")), - customNodeViews: { - paragraph (node) { - const dom = document.createElement("p"); - return { - dom, - contentDOM: dom, - update (node_, _, innerDecoSet) { - innerDecos = innerDecoSet.find().map((d)=>`${d.from}-${d.to}`); - return node.sameMarkup(node_); - } - }; - } - } - }); - rerender({ - decorations (state) { - return _prosemirrorView.DecorationSet.create(state.doc, [ - _prosemirrorView.Decoration.inline(2, 3, { - someattr: "ok" - }), - _prosemirrorView.Decoration.node(0, 5, { - otherattr: "ok" - }) - ]); - } - }); - expect(innerDecos.join()).toBe("1-2"); - }); -}); diff --git a/dist/cjs/components/__tests__/ProseMirror.selection.test.js b/dist/cjs/components/__tests__/ProseMirror.selection.test.js deleted file mode 100644 index 4694aad6..00000000 --- a/dist/cjs/components/__tests__/ProseMirror.selection.test.js +++ /dev/null @@ -1,447 +0,0 @@ -/* eslint-disable jest/no-disabled-tests */ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-non-null-assertion */ "use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -const _react = require("@testing-library/react"); -const _prosemirrorState = require("prosemirror-state"); -const _prosemirrorTestBuilder = require("prosemirror-test-builder"); -const _prosemirrorView = require("prosemirror-view"); -const _editorViewTestHelpersJs = require("../../testing/editorViewTestHelpers.js"); -const _setupProseMirrorViewJs = require("../../testing/setupProseMirrorView.js"); -const img = (0, _prosemirrorTestBuilder.img)({ - src: "data:image/gif;base64,R0lGODlhBQAFAIABAAAAAP///yH5BAEKAAEALAAAAAAFAAUAAAIEjI+pWAA7" -}); -function allPositions(doc) { - const found = []; - function scan(node, start) { - if (node.isTextblock) { - for(let i = 0; i <= node.content.size; i++)found.push(start + i); - } else { - node.forEach((child, offset)=>scan(child, start + offset + 1)); - } - } - scan(doc, 0); - return found; -} -function setDOMSel(node, offset) { - const range = document.createRange(); - range.setEnd(node, offset); - range.setStart(node, offset); - const sel = window.getSelection(); - sel.removeAllRanges(); - sel.addRange(range); -} -function getSel() { - const sel = window.getSelection(); - let node = sel.focusNode, offset = sel.focusOffset; - while(node && node.nodeType != 3){ - const after = offset < node.childNodes.length && node.childNodes[offset]; - const before = offset > 0 && node.childNodes[offset - 1]; - if (after) { - node = after; - offset = 0; - } else if (before) { - node = before; - offset = node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length; - } else break; - } - return { - node: node, - offset: offset - }; -} -function setSel(view, sel) { - const selection = typeof sel == "number" ? _prosemirrorState.Selection.near(view.state.doc.resolve(sel)) : sel; - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.setSelection(selection)); - }); -} -function event(code) { - const event = document.createEvent("Event"); - event.initEvent("keydown", true, true); - event.keyCode = code; - return event; -} -const LEFT = 37, RIGHT = 39, UP = 38, DOWN = 40; -describe("EditorView", ()=>{ - beforeAll(()=>{ - (0, _setupProseMirrorViewJs.setupProseMirrorView)(); - }); - it("can read the DOM selection", async ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one"), (0, _prosemirrorTestBuilder.hr)(), (0, _prosemirrorTestBuilder.blockquote)((0, _prosemirrorTestBuilder.p)("two"))) - }); - function test(node, offset, expected) { - setDOMSel(node, offset); - view.dom.focus(); - (0, _react.act)(()=>{ - view.domObserver.flush(); - }); - const sel = view.state.selection; - expect(sel.head == null ? sel.from : sel.head).toBe(expected); - } - const one = await (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "one"); - const two = await (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "two"); - test(one, 0, 1); - test(one, 1, 2); - test(one, 3, 4); - // TODO: Not sure why this is broken - // test(one.parentNode!, 0, 1); - test(one.parentNode, 1, 4); - test(two, 0, 8); - test(two, 3, 11); - test(two.parentNode, 1, 11); - test(view.dom, 1, 4); - test(view.dom, 2, 8); - test(view.dom, 3, 11); - }); - it("syncs the DOM selection with the editor selection", async ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one"), (0, _prosemirrorTestBuilder.hr)(), (0, _prosemirrorTestBuilder.blockquote)((0, _prosemirrorTestBuilder.p)("two"))) - }); - function test(pos, node, offset) { - setSel(view, pos); - const sel = getSel(); - expect(sel.node).toBe(node); - expect(sel.offset).toBe(offset); - } - const one = await (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "one"); - const two = await (0, _editorViewTestHelpersJs.findTextNode)(view.dom, "two"); - view.focus(); - test(1, one, 0); - test(2, one, 1); - test(4, one, 3); - test(8, two, 0); - test(10, two, 2); - }); - // Jest-dom doesn't actually provide a working getClientRects - // implementation, so this test doesn't work. - // TODO: should we consider running these with puppeteer for - // better test accuracy? - it.skip("returns sensible screen coordinates", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one"), (0, _prosemirrorTestBuilder.p)("two")) - }); - const p00 = view.coordsAtPos(1); - const p01 = view.coordsAtPos(2); - const p03 = view.coordsAtPos(4); - const p10 = view.coordsAtPos(6); - const p13 = view.coordsAtPos(9); - expect(p00.bottom).toBeGreaterThan(p00.top); - expect(p13.bottom).toBeGreaterThan(p13.top); - expect(p00.top).toEqual(p01.top); - expect(p01.top).toEqual(p03.top); - expect(p00.bottom).toEqual(p03.bottom); - expect(p10.top).toEqual(p13.top); - expect(p01.left).toBeGreaterThan(p00.left); - expect(p03.left).toBeGreaterThan(p01.left); - expect(p10.top).toBeGreaterThan(p00.top); - expect(p13.left).toBeGreaterThan(p10.left); - }); - it.skip("returns proper coordinates in code blocks", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.code_block)("a\nb\n")) - }), p = []; - for(let i = 1; i <= 5; i++)p.push(view.coordsAtPos(i)); - const [p0, p1, p2, p3, p4] = p; - expect(p0.top).toBe(p1.top); - expect(p0.left).toBeLessThan(p1.left); - expect(p2.top).toBeGreaterThan(p1.top); - expect(p2.top).toBe(p3.top); - expect(p2.left).toBeLessThan(p3.left); - expect(p2.left).toBe(p0.left); - expect(p4.top).toBeGreaterThan(p3.top); - // This one shows a small (0.01 pixel) difference in Firefox for - // some reason. - expect(Math.round(p4.left)).toBe(Math.round(p2.left)); - }); - it.skip("produces sensible screen coordinates in corner cases", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one", (0, _prosemirrorTestBuilder.em)("two", (0, _prosemirrorTestBuilder.strong)("three"), img), (0, _prosemirrorTestBuilder.br)(), (0, _prosemirrorTestBuilder.code)("foo")), (0, _prosemirrorTestBuilder.p)()) - }); - return new Promise((ok)=>{ - setTimeout(()=>{ - allPositions(view.state.doc).forEach((pos)=>{ - const coords = view.coordsAtPos(pos); - const found = view.posAtCoords({ - top: coords.top + 1, - left: coords.left - }).pos; - expect(found).toBe(pos); - setSel(view, pos); - }); - ok(null); - }, 20); - }); - }); - it.skip("doesn't return zero-height rectangles after leaves", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)(img)) - }); - const coords = view.coordsAtPos(2, 1); - expect(coords.bottom - coords.top).toBeGreaterThan(5); - }); - it.skip("produces horizontal rectangles for positions between blocks", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("ha"), (0, _prosemirrorTestBuilder.hr)(), (0, _prosemirrorTestBuilder.blockquote)((0, _prosemirrorTestBuilder.p)("ba"))) - }); - const a = view.coordsAtPos(0); - expect(a.top).toBe(a.bottom); - expect(a.top).toBe(view.dom.firstChild.getBoundingClientRect().top); - expect(a.left).toBeLessThan(a.right); - const b = view.coordsAtPos(4); - expect(b.top).toBe(b.bottom); - expect(b.top).toBeGreaterThan(a.top); - expect(b.left).toBeLessThan(b.right); - const c = view.coordsAtPos(5); - expect(c.top).toBe(c.bottom); - expect(c.top).toBeGreaterThan(b.top); - const d = view.coordsAtPos(6); - expect(d.top).toBe(d.bottom); - expect(d.left).toBeLessThan(d.right); - expect(d.top).toBeLessThan(view.dom.getBoundingClientRect().bottom); - }); - it.skip("produces sensible screen coordinates around line breaks", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one two three four five-six-seven-eight")) - }); - function afterSpace(pos) { - return pos > 0 && view.state.doc.textBetween(pos - 1, pos) == " "; - } - view.dom.style.width = "4em"; - let prevBefore; - let prevAfter; - allPositions(view.state.doc).forEach((pos)=>{ - const coords = view.coordsAtPos(pos, 1); - if (prevAfter) // eslint-disable-next-line jest/no-conditional-expect - expect(prevAfter.top < coords.top || prevAfter.top == coords.top && prevAfter.left < coords.left).toBeTruthy(); - prevAfter = coords; - const found = view.posAtCoords({ - top: coords.top + 1, - left: coords.left - }).pos; - expect(found).toBe(pos); - const coordsBefore = view.coordsAtPos(pos, -1); - if (prevBefore) // eslint-disable-next-line jest/no-conditional-expect - expect(prevBefore.top < coordsBefore.top || prevBefore.top == coordsBefore.top && (prevBefore.left < coordsBefore.left || afterSpace(pos) && prevBefore.left == coordsBefore.left)).toBeTruthy(); - prevBefore = coordsBefore; - }); - }); - it.skip("can find coordinates on node boundaries", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one ", (0, _prosemirrorTestBuilder.em)("two"), " ", (0, _prosemirrorTestBuilder.em)((0, _prosemirrorTestBuilder.strong)("three")))) - }); - let prev; - allPositions(view.state.doc).forEach((pos)=>{ - const coords = view.coordsAtPos(pos, 1); - if (prev) // eslint-disable-next-line jest/no-conditional-expect - expect(prev.top < coords.top || Math.abs(prev.top - coords.top) < 4 && prev.left < coords.left).toBeTruthy(); - prev = coords; - }); - }); - it.skip("finds proper coordinates in RTL text", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("مرآة نثرية")) - }); - view.dom.style.direction = "rtl"; - let prev; - allPositions(view.state.doc).forEach((pos)=>{ - const coords = view.coordsAtPos(pos, 1); - if (prev) // eslint-disable-next-line jest/no-conditional-expect - expect(prev.top < coords.top || Math.abs(prev.top - coords.top) < 4 && prev.left > coords.left).toBeTruthy(); - prev = coords; - }); - }); - it.skip("can go back and forth between screen coordsa and document positions", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one"), (0, _prosemirrorTestBuilder.blockquote)((0, _prosemirrorTestBuilder.p)("two"), (0, _prosemirrorTestBuilder.p)("three"))) - }); - [ - 1, - 2, - 4, - 7, - 14, - 15 - ].forEach((pos)=>{ - const coords = view.coordsAtPos(pos); - const found = view.posAtCoords({ - top: coords.top + 1, - left: coords.left - }).pos; - expect(found).toBe(pos); - }); - }); - it.skip("returns correct screen coordinates for wrapped lines", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({}); - const top = view.coordsAtPos(1); - let pos = 1, end; - for(let i = 0; i < 100; i++){ - view.dispatch(view.state.tr.insertText("a bc de fg h")); - pos += 12; - end = view.coordsAtPos(pos); - if (end.bottom > top.bottom + 4) break; - } - expect(view.posAtCoords({ - left: end.left + 50, - top: end.top + 5 - }).pos).toBe(pos); - }); - it("makes arrow motion go through selectable inline nodes", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo", img, "bar")) - }); - (0, _react.act)(()=>{ - view.dispatchEvent(event(RIGHT)); - }); - expect(view.state.selection.from).toBe(4); - (0, _react.act)(()=>{ - view.dispatchEvent(event(RIGHT)); - }); - expect(view.state.selection.head).toBe(5); - expect(view.state.selection.anchor).toBe(5); - (0, _react.act)(()=>{ - view.dispatchEvent(event(LEFT)); - }); - expect(view.state.selection.from).toBe(4); - (0, _react.act)(()=>{ - view.dispatchEvent(event(LEFT)); - }); - expect(view.state.selection.head).toBe(4); - expect(view.state.selection.anchor).toBe(4); - }); - it("makes arrow motion go through selectable block nodes", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("hello"), (0, _prosemirrorTestBuilder.hr)(), (0, _prosemirrorTestBuilder.ul)((0, _prosemirrorTestBuilder.li)((0, _prosemirrorTestBuilder.p)("there")))) - }); - (0, _react.act)(()=>{ - view.dispatchEvent(event(DOWN)); - }); - expect(view.state.selection.from).toBe(7); - setSel(view, 11); - (0, _react.act)(()=>{ - view.dispatchEvent(event(UP)); - }); - expect(view.state.selection.from).toBe(7); - }); - it("supports arrow motion through adjacent blocks", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.blockquote)((0, _prosemirrorTestBuilder.p)("hello")), (0, _prosemirrorTestBuilder.hr)(), (0, _prosemirrorTestBuilder.hr)(), (0, _prosemirrorTestBuilder.p)("there")) - }); - (0, _react.act)(()=>{ - view.dispatchEvent(event(DOWN)); - }); - expect(view.state.selection.from).toBe(9); - (0, _react.act)(()=>{ - view.dispatchEvent(event(DOWN)); - }); - expect(view.state.selection.from).toBe(10); - setSel(view, 14); - (0, _react.act)(()=>{ - view.dispatchEvent(event(UP)); - }); - expect(view.state.selection.from).toBe(10); - (0, _react.act)(()=>{ - view.dispatchEvent(event(UP)); - }); - expect(view.state.selection.from).toBe(9); - }); - it("support horizontal motion through blocks", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo"), (0, _prosemirrorTestBuilder.hr)(), (0, _prosemirrorTestBuilder.hr)(), (0, _prosemirrorTestBuilder.p)("bar")) - }); - (0, _react.act)(()=>{ - view.dispatchEvent(event(RIGHT)); - }); - expect(view.state.selection.from).toBe(5); - (0, _react.act)(()=>{ - view.dispatchEvent(event(RIGHT)); - }); - expect(view.state.selection.from).toBe(6); - (0, _react.act)(()=>{ - view.dispatchEvent(event(RIGHT)); - }); - expect(view.state.selection.head).toBe(8); - (0, _react.act)(()=>{ - view.dispatchEvent(event(LEFT)); - }); - expect(view.state.selection.from).toBe(6); - (0, _react.act)(()=>{ - view.dispatchEvent(event(LEFT)); - }); - expect(view.state.selection.from).toBe(5); - (0, _react.act)(()=>{ - view.dispatchEvent(event(LEFT)); - }); - expect(view.state.selection.head).toBe(4); - }); - it("allows moving directly from an inline node to a block node", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo", img), (0, _prosemirrorTestBuilder.hr)(), (0, _prosemirrorTestBuilder.p)(img, "bar")) - }); - setSel(view, _prosemirrorState.NodeSelection.create(view.state.doc, 4)); - (0, _react.act)(()=>{ - view.dispatchEvent(event(DOWN)); - }); - expect(view.state.selection.from).toBe(6); - setSel(view, _prosemirrorState.NodeSelection.create(view.state.doc, 8)); - (0, _react.act)(()=>{ - view.dispatchEvent(event(UP)); - }); - expect(view.state.selection.from).toBe(6); - }); - it("updates the selection even if the DOM parameters look unchanged", ()=>{ - const { view , rerender } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foobar")) - }); - view.focus(); - const decos = _prosemirrorView.DecorationSet.create(view.state.doc, [ - _prosemirrorView.Decoration.inline(1, 4, { - color: "green" - }) - ]); - rerender({ - decorations () { - return decos; - } - }); - rerender({ - decorations: undefined - }); - rerender({ - decorations () { - return decos; - } - }); - const range = document.createRange(); - range.setEnd(document.getSelection().anchorNode, document.getSelection().anchorOffset); - range.setStart(view.dom, 0); - expect(range.toString()).toBe("foobar"); - }); - it("sets selection even if Selection.extend throws DOMException", ()=>{ - const originalExtend = window.Selection.prototype.extend; - window.Selection.prototype.extend = ()=>{ - // declare global: DOMException - throw new DOMException("failed"); - }; - try { - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo", img), (0, _prosemirrorTestBuilder.hr)(), (0, _prosemirrorTestBuilder.p)(img, "bar")) - }); - setSel(view, _prosemirrorState.NodeSelection.create(view.state.doc, 4)); - (0, _react.act)(()=>{ - view.dispatchEvent(event(DOWN)); - }); - expect(view.state.selection.from).toBe(6); - } finally{ - window.Selection.prototype.extend = originalExtend; - } - }); - it("doesn't put the cursor after BR hack nodes", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)()) - }); - view.focus(); - expect(getSelection().focusOffset).toBe(0); - }); -}); diff --git a/dist/cjs/components/__tests__/ProseMirror.test.js b/dist/cjs/components/__tests__/ProseMirror.test.js deleted file mode 100644 index 6e415dd6..00000000 --- a/dist/cjs/components/__tests__/ProseMirror.test.js +++ /dev/null @@ -1,101 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-non-null-assertion */ "use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -const _globals = require("@jest/globals"); -const _react = require("@testing-library/react"); -const _prosemirrorTestBuilder = require("prosemirror-test-builder"); -const _editorViewTestHelpersJs = require("../../testing/editorViewTestHelpers.js"); -const _setupProseMirrorViewJs = require("../../testing/setupProseMirrorView.js"); -describe("EditorView", ()=>{ - beforeAll(()=>{ - (0, _setupProseMirrorViewJs.setupProseMirrorView)(); - }); - it("reflects the current state in .props", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)()) - }); - (0, _globals.expect)(view.state).toBe(view.props.state); - }); - it("calls handleScrollToSelection when appropriate", ()=>{ - let scrolled = 0; - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)()), - handleScrollToSelection: ()=>{ - scrolled++; - return false; - } - }); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.scrollIntoView()); - }); - (0, _globals.expect)(scrolled).toBe(1); - }); - it("can be queried for the DOM position at a doc position", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.ul)((0, _prosemirrorTestBuilder.li)((0, _prosemirrorTestBuilder.p)((0, _prosemirrorTestBuilder.strong)("foo"))))) - }); - const inText = view.domAtPos(4); - (0, _globals.expect)(inText.offset).toBe(1); - (0, _globals.expect)(inText.node.nodeValue).toBe("foo"); - const beforeLI = view.domAtPos(1); - (0, _globals.expect)(beforeLI.offset).toBe(0); - (0, _globals.expect)(beforeLI.node.nodeName).toBe("UL"); - const afterP = view.domAtPos(7); - (0, _globals.expect)(afterP.offset).toBe(1); - (0, _globals.expect)(afterP.node.nodeName).toBe("LI"); - }); - it("can bias DOM position queries to enter nodes", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)((0, _prosemirrorTestBuilder.em)((0, _prosemirrorTestBuilder.strong)("a"), "b"), "c")) - }); - function get(pos, bias) { - const r = view.domAtPos(pos, bias); - return (r.node.nodeType == 1 ? r.node.nodeName : r.node.nodeValue) + "@" + r.offset; - } - (0, _globals.expect)(get(1, 0)).toBe("P@0"); - (0, _globals.expect)(get(1, -1)).toBe("P@0"); - (0, _globals.expect)(get(1, 1)).toBe("a@0"); - (0, _globals.expect)(get(2, -1)).toBe("a@1"); - (0, _globals.expect)(get(2, 0)).toBe("EM@1"); - (0, _globals.expect)(get(2, 1)).toBe("b@0"); - (0, _globals.expect)(get(3, -1)).toBe("b@1"); - (0, _globals.expect)(get(3, 0)).toBe("P@1"); - (0, _globals.expect)(get(3, 1)).toBe("c@0"); - (0, _globals.expect)(get(4, -1)).toBe("c@1"); - (0, _globals.expect)(get(4, 0)).toBe("P@2"); - (0, _globals.expect)(get(4, 1)).toBe("P@2"); - }); - it("can be queried for a node's DOM representation", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo"), (0, _prosemirrorTestBuilder.hr)()) - }); - (0, _globals.expect)(view.nodeDOM(0).nodeName).toBe("P"); - (0, _globals.expect)(view.nodeDOM(5).nodeName).toBe("HR"); - (0, _globals.expect)(view.nodeDOM(3)).toBeNull(); - }); - it("can map DOM positions to doc positions", ()=>{ - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo"), (0, _prosemirrorTestBuilder.hr)()) - }); - (0, _globals.expect)(view.posAtDOM(view.dom.firstChild.firstChild, 2)).toBe(3); - (0, _globals.expect)(view.posAtDOM(view.dom, 1)).toBe(5); - (0, _globals.expect)(view.posAtDOM(view.dom, 2)).toBe(6); - (0, _globals.expect)(view.posAtDOM(view.dom.lastChild, 0, -1)).toBe(5); - (0, _globals.expect)(view.posAtDOM(view.dom.lastChild, 0, 1)).toBe(6); - }); - it("binds this to itself in dispatchTransaction prop", ()=>{ - let thisBinding; - const { view } = (0, _editorViewTestHelpersJs.tempEditor)({ - doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo"), (0, _prosemirrorTestBuilder.hr)()), - dispatchTransaction () { - // eslint-disable-next-line @typescript-eslint/no-this-alias - thisBinding = this; - } - }); - (0, _react.act)(()=>{ - view.dispatch(view.state.tr.insertText("x")); - }); - (0, _globals.expect)(view).toBe(thisBinding); - }); -}); diff --git a/dist/cjs/contexts/ChildDescriptorsContext.js b/dist/cjs/contexts/ChildDescriptorsContext.js deleted file mode 100644 index d17b81bc..00000000 --- a/dist/cjs/contexts/ChildDescriptorsContext.js +++ /dev/null @@ -1,10 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "ChildDescriptorsContext", { - enumerable: true, - get: ()=>ChildDescriptorsContext -}); -const _react = require("react"); -const ChildDescriptorsContext = (0, _react.createContext)([]); diff --git a/dist/cjs/contexts/EditorContext.js b/dist/cjs/contexts/EditorContext.js deleted file mode 100644 index c8cc3019..00000000 --- a/dist/cjs/contexts/EditorContext.js +++ /dev/null @@ -1,10 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "EditorContext", { - enumerable: true, - get: ()=>EditorContext -}); -const _react = require("react"); -const EditorContext = (0, _react.createContext)(null); diff --git a/dist/cjs/contexts/LayoutGroupContext.js b/dist/cjs/contexts/LayoutGroupContext.js deleted file mode 100644 index ec12c4a2..00000000 --- a/dist/cjs/contexts/LayoutGroupContext.js +++ /dev/null @@ -1,10 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "LayoutGroupContext", { - enumerable: true, - get: ()=>LayoutGroupContext -}); -const _react = require("react"); -const LayoutGroupContext = /*#__PURE__*/ (0, _react.createContext)(null); diff --git a/dist/cjs/contexts/NodeViewContext.js b/dist/cjs/contexts/NodeViewContext.js deleted file mode 100644 index c8a74d8c..00000000 --- a/dist/cjs/contexts/NodeViewContext.js +++ /dev/null @@ -1,10 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "NodeViewContext", { - enumerable: true, - get: ()=>NodeViewContext -}); -const _react = require("react"); -const NodeViewContext = /*#__PURE__*/ (0, _react.createContext)(null); diff --git a/dist/cjs/contexts/__tests__/DeferredLayoutEffects.test.js b/dist/cjs/contexts/__tests__/DeferredLayoutEffects.test.js deleted file mode 100644 index c9ffd5b8..00000000 --- a/dist/cjs/contexts/__tests__/DeferredLayoutEffects.test.js +++ /dev/null @@ -1,141 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -const _react = require("@testing-library/react"); -const _react1 = /*#__PURE__*/ _interopRequireWildcard(require("react")); -const _layoutGroupJs = require("../../components/LayoutGroup.js"); -const _useLayoutGroupEffectJs = require("../../hooks/useLayoutGroupEffect.js"); -function _getRequireWildcardCache(nodeInterop) { - if (typeof WeakMap !== "function") return null; - var cacheBabelInterop = new WeakMap(); - var cacheNodeInterop = new WeakMap(); - return (_getRequireWildcardCache = function(nodeInterop) { - return nodeInterop ? cacheNodeInterop : cacheBabelInterop; - })(nodeInterop); -} -function _interopRequireWildcard(obj, nodeInterop) { - if (!nodeInterop && obj && obj.__esModule) { - return obj; - } - if (obj === null || typeof obj !== "object" && typeof obj !== "function") { - return { - default: obj - }; - } - var cache = _getRequireWildcardCache(nodeInterop); - if (cache && cache.has(obj)) { - return cache.get(obj); - } - var newObj = {}; - var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; - for(var key in obj){ - if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { - var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; - if (desc && (desc.get || desc.set)) { - Object.defineProperty(newObj, key, desc); - } else { - newObj[key] = obj[key]; - } - } - } - newObj.default = obj; - if (cache) { - cache.set(obj, newObj); - } - return newObj; -} -describe("DeferredLayoutEffects", ()=>{ - jest.useFakeTimers("modern"); - it("registers multiple effects and runs them", ()=>{ - function Parent() { - return /*#__PURE__*/ _react1.default.createElement(_layoutGroupJs.LayoutGroup, null, /*#__PURE__*/ _react1.default.createElement(Child, null)); - } - function Child() { - const [double, setDouble] = (0, _react1.useState)(1); - (0, _react1.useLayoutEffect)(()=>{ - if (double === 2) { - setTimeout(()=>{ - setDouble((d)=>d * 2.5); - }, 500); - } - if (double === 20) { - setDouble((d)=>d * 2.5); - } - }, [ - double - ]); - (0, _useLayoutGroupEffectJs.useLayoutGroupEffect)(()=>{ - const timeout = setTimeout(()=>{ - setDouble((d)=>d * 2); - }, 1000); - return ()=>{ - clearTimeout(timeout); - }; - }, [ - double - ]); - return /*#__PURE__*/ _react1.default.createElement("div", null, /*#__PURE__*/ _react1.default.createElement("div", { - "data-testid": "double" - }, double)); - } - // The component mounts ... - // ... the initial value should be 1 - // ... there should be one timeout scheduled by the deferred effect - (0, _react.render)(/*#__PURE__*/ _react1.default.createElement(Parent, null)); - expect(_react.screen.getByTestId("double").innerHTML).toBe("1"); - // This block assert that deferred effects run. - // -------------------------------------------- - // 1000 milliseconds go by ... - // ... the timeout set by the deferred effect should run - // ... the timeout should double the new value to 2 - // ... the immediate effect should set a timeout - // ... the deferred effect should set a timeout - (0, _react.act)(()=>{ - jest.advanceTimersByTime(1000); - }); - expect(_react.screen.getByTestId("double").innerHTML).toBe("2"); - // The next three blocks assert that cleanup of deferred effects run. - // ------------------------------------------------------------------ - // 500 milliseconds go by ... - // ... the timeout set by the immediate effect should run - // ... the timeout should set the value to 5 - // ... the old deferred effect should cancel its timeout - // ... the new deferred effect should set a new timeout - (0, _react.act)(()=>{ - jest.advanceTimersByTime(500); - }); - expect(_react.screen.getByTestId("double").innerHTML).toBe("5"); - // ... 500 more milliseconds go by ... - // ... the canceled timeout should not run - // ... the rescheduled timoeut should not yet run - (0, _react.act)(()=>{ - jest.advanceTimersByTime(500); - }); - expect(_react.screen.getByTestId("double").innerHTML).toBe("5"); - // ... 500 more milliseconds go by ... - // ... the rescheduled timeout should run - // ... the timeout should double the value to 10 - // ... the deferred effect should set a new timeout - (0, _react.act)(()=>{ - jest.advanceTimersByTime(500); - }); - expect(_react.screen.getByTestId("double").innerHTML).toBe("10"); - // The next block asserts that cancelation of deferred effects works. - // ------------------------------------------------------------------ - // 1000 milliseconds go by ... - // ... the timeout set by the deferred effect should run - // ... the timeout should double the value to 20 - // ... the immediate effect should then set the value to 50 - // ... the deferred effect from the first render should not run - // ... the deferred effect from the second render should run - // ... the deferred effect that does run should set a new timeout - (0, _react.act)(()=>{ - jest.advanceTimersByTime(1000); - }); - // For this assertion, we need to clear a timer from the React scheduler. - jest.advanceTimersByTime(1); - expect(_react.screen.getByTestId("double").innerHTML).toBe("50"); - expect(jest.getTimerCount()).toBe(1); - }); -}); diff --git a/dist/cjs/decorations/ReactWidgetType.js b/dist/cjs/decorations/ReactWidgetType.js deleted file mode 100644 index 44d2846d..00000000 --- a/dist/cjs/decorations/ReactWidgetType.js +++ /dev/null @@ -1,51 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -function _export(target, all) { - for(var name in all)Object.defineProperty(target, name, { - enumerable: true, - get: all[name] - }); -} -_export(exports, { - ReactWidgetType: ()=>ReactWidgetType, - widget: ()=>widget -}); -const _prosemirrorView = require("prosemirror-view"); -function compareObjs(a, b) { - if (a == b) return true; - for(const p in a)if (a[p] !== b[p]) return false; - for(const p in b)if (!(p in a)) return false; - return true; -} -const noSpec = { - side: 0 -}; -let ReactWidgetType = class ReactWidgetType { - map(mapping, span, offset, oldOffset) { - const { pos , deleted } = mapping.mapResult(span.from + oldOffset, this.side < 0 ? -1 : 1); - // @ts-expect-error The Decoration constructor is private/internal, but - // we need to use it for our custom widget implementation here. - return deleted ? null : new _prosemirrorView.Decoration(pos - offset, pos - offset, this); - } - valid() { - return true; - } - eq(other) { - return this == other || other instanceof ReactWidgetType && (this.spec.key && this.spec.key == other.spec.key || this.Component == other.Component && compareObjs(this.spec, other.spec)); - } - destroy() { - // Can be implemented with React effect hooks - } - constructor(Component, spec){ - this.Component = Component; - this.spec = spec ?? noSpec; - this.side = this.spec.side ?? 0; - } -}; -function widget(pos, component, spec) { - // @ts-expect-error The Decoration constructor is private/internal, but - // we need to use it for our custom widget implementation here. - return new _prosemirrorView.Decoration(pos, pos, new ReactWidgetType(component, spec)); -} diff --git a/dist/cjs/decorations/computeDocDeco.js b/dist/cjs/decorations/computeDocDeco.js deleted file mode 100644 index 581025c8..00000000 --- a/dist/cjs/decorations/computeDocDeco.js +++ /dev/null @@ -1,26 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "computeDocDeco", { - enumerable: true, - get: ()=>computeDocDeco -}); -const _prosemirrorView = require("prosemirror-view"); -function computeDocDeco(view) { - const 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(const attr in value){ - if (attr == "class") attrs.class += " " + value[attr]; - else if (attr == "style") attrs.style = (attrs.style ? attrs.style + ";" : "") + value[attr]; - else if (!attrs[attr] && attr != "contenteditable" && attr != "nodeName") attrs[attr] = String(value[attr]); - } - }); - if (!attrs.translate) attrs.translate = "no"; - return [ - _prosemirrorView.Decoration.node(0, view.state.doc.content.size, attrs) - ]; -} diff --git a/dist/cjs/decorations/internalTypes.js b/dist/cjs/decorations/internalTypes.js deleted file mode 100644 index b62a6d55..00000000 --- a/dist/cjs/decorations/internalTypes.js +++ /dev/null @@ -1,4 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); diff --git a/dist/cjs/decorations/iterDeco.js b/dist/cjs/decorations/iterDeco.js deleted file mode 100644 index 36e9a783..00000000 --- a/dist/cjs/decorations/iterDeco.js +++ /dev/null @@ -1,77 +0,0 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ "use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "iterDeco", { - enumerable: true, - get: ()=>iterDeco -}); -const _reactWidgetTypeJs = require("./ReactWidgetType.js"); -function compareSide(a, b) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - return a.type.side - b.type.side; -} -function iterDeco(parent, deco, // Callbacks have been slightly modified to pass -// the offset, so that we can pass the position as -// a prop to components -onWidget, onNode) { - const locals = deco.locals(parent); - let offset = 0; - // Simple, cheap variant for when there are no local decorations - if (locals.length == 0) { - for(let i = 0; i < parent.childCount; i++){ - const child = parent.child(i); - onNode(child, locals, deco.forChild(offset, child), offset, i); - offset += child.nodeSize; - } - return; - } - let decoIndex = 0; - const active = []; - let restNode = null; - for(let parentIndex = 0;;){ - if (decoIndex < locals.length && locals[decoIndex].to == offset) { - const widget = locals[decoIndex++]; - let 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], // eslint-disable-next-line @typescript-eslint/no-explicit-any - !(widgets[i].type instanceof _reactWidgetTypeJs.ReactWidgetType), offset, parentIndex + i, !!restNode); - } else { - onWidget(widget, // eslint-disable-next-line @typescript-eslint/no-explicit-any - !(widget.type instanceof _reactWidgetTypeJs.ReactWidgetType), offset, parentIndex, !!restNode); - } - } - 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 && locals[decoIndex].to > 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; - } - } - const outerDeco = child.isInline && !child.isLeaf ? active.filter((d)=>!d.inline) : active.slice(); - onNode(child, outerDeco, deco.forChild(offset, child), offset, index); - offset = end; - } -} diff --git a/dist/cjs/decorations/viewDecorations.js b/dist/cjs/decorations/viewDecorations.js deleted file mode 100644 index c2b87af3..00000000 --- a/dist/cjs/decorations/viewDecorations.js +++ /dev/null @@ -1,133 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "viewDecorations", { - enumerable: true, - get: ()=>viewDecorations -}); -const _prosemirrorView = require("prosemirror-view"); -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const none = [], noSpec = {}; -const empty = _prosemirrorView.DecorationSet.empty; -// 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. -let DecorationGroup = class DecorationGroup { - map(mapping, doc) { - const mappedDecos = this.members.map((member)=>member.map(mapping, doc, noSpec)); - return DecorationGroup.from(mappedDecos); - } - forChild(offset, child) { - if (child.isLeaf) return _prosemirrorView.DecorationSet.empty; - let found = []; - for(let i = 0; i < this.members.length; i++){ - const 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++){ - const locals = this.members[i].localsInner(node); - if (!locals.length) continue; - if (!result) { - result = locals; - } else { - if (sorted) { - result = result.slice(); - sorted = false; - } - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - for(let j = 0; j < locals.length; j++)result.push(locals[j]); - } - } - return result ? removeOverlap(sorted ? result : result.sort(byPos)) : none; - } - // 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: - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - return members[0]; - default: - return new DecorationGroup(members.every((m)=>m instanceof _prosemirrorView.DecorationSet) ? members : members.reduce((r, m)=>r.concat(m instanceof _prosemirrorView.DecorationSet ? m : m.members), [])); - } - } - constructor(members){ - this.members = members; - } -}; -// 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; -} -// 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++){ - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const span = working[i]; - if (span.from != span.to) for(let j = i + 1; j < working.length; j++){ - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const 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) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - while(i < array.length && byPos(deco, array[i]) > 0)i++; - array.splice(i, 0, deco); -} -function viewDecorations(view, cursorWrapper) { - const found = []; - view.someProp("decorations", (f)=>{ - const result = f(view.state); - if (result && result != empty) found.push(result); - }); - // We don't have access to types for view.cursorWrapper here - // eslint-disable-next-line @typescript-eslint/no-explicit-any - if (cursorWrapper) { - found.push(// eslint-disable-next-line @typescript-eslint/no-explicit-any - _prosemirrorView.DecorationSet.create(view.state.doc, [ - cursorWrapper - ])); - } - return DecorationGroup.from(found); -} diff --git a/dist/cjs/dom.js b/dist/cjs/dom.js deleted file mode 100644 index 6cc817ee..00000000 --- a/dist/cjs/dom.js +++ /dev/null @@ -1,117 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -function _export(target, all) { - for(var name in all)Object.defineProperty(target, name, { - enumerable: true, - get: all[name] - }); -} -_export(exports, { - domIndex: ()=>domIndex, - parentNode: ()=>parentNode, - textRange: ()=>textRange, - isEquivalentPosition: ()=>isEquivalentPosition, - nodeSize: ()=>nodeSize, - isOnEdge: ()=>isOnEdge, - hasBlockDesc: ()=>hasBlockDesc, - selectionCollapsed: ()=>selectionCollapsed, - keyEvent: ()=>keyEvent, - deepActiveElement: ()=>deepActiveElement, - caretFromPoint: ()=>caretFromPoint -}); -const domIndex = function(node) { - for(let index = 0;; index++){ - node = node.previousSibling; - if (!node) return index; - } -}; -const parentNode = function(node) { - const parent = node.assignedSlot || node.parentNode; - return parent && parent.nodeType == 11 ? parent.host : parent; -}; -let reusedRange = null; -const textRange = function(node, from, to) { - const range = reusedRange || (reusedRange = document.createRange()); - range.setEnd(node, to == null ? node.nodeValue.length : to); - range.setStart(node, from || 0); - return range; -}; -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))) { - const parent = node.parentNode; - if (!parent || 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)]; - if (node.contentEditable == "false") return false; - off = dir < 0 ? nodeSize(node) : 0; - } else { - return false; - } - } -} -function nodeSize(node) { - return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length; -} -function isOnEdge(node, offset, parent) { - for(let atStart = offset == 0, atEnd = offset == nodeSize(node); atStart || atEnd;){ - if (node == parent) return true; - const index = domIndex(node); - node = node.parentNode; - if (!node) return false; - atStart = atStart && index == 0; - atEnd = atEnd && index == nodeSize(node); - } - return false; -} -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); -} -const selectionCollapsed = function(domSel) { - return domSel.focusNode && isEquivalentPosition(domSel.focusNode, domSel.focusOffset, domSel.anchorNode, domSel.anchorOffset); -}; -function keyEvent(keyCode, key) { - const event = document.createEvent("Event"); - event.initEvent("keydown", true, true); - event.keyCode = keyCode; - event.key = event.code = key; - return event; -} -function deepActiveElement(doc) { - let elt = doc.activeElement; - while(elt && elt.shadowRoot)elt = elt.shadowRoot.activeElement; - return elt; -} -function caretFromPoint(doc, x, y) { - if (doc.caretPositionFromPoint) { - try { - // Firefox throws for this call in hard-to-predict circumstances (#994) - const pos = doc.caretPositionFromPoint(x, y); - if (pos) return { - node: pos.offsetNode, - offset: pos.offset - }; - } catch (_) { - // pass - } - } - if (doc.caretRangeFromPoint) { - const range = doc.caretRangeFromPoint(x, y); - if (range) return { - node: range.startContainer, - offset: range.startOffset - }; - } - return; -} diff --git a/dist/cjs/hooks/__tests__/useEditorViewLayoutEffect.test.js b/dist/cjs/hooks/__tests__/useEditorViewLayoutEffect.test.js deleted file mode 100644 index 844fc1e6..00000000 --- a/dist/cjs/hooks/__tests__/useEditorViewLayoutEffect.test.js +++ /dev/null @@ -1,107 +0,0 @@ -/* eslint-disable @typescript-eslint/no-empty-function */ "use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -const _react = require("@testing-library/react"); -const _react1 = /*#__PURE__*/ _interopRequireDefault(require("react")); -const _layoutGroupJs = require("../../components/LayoutGroup.js"); -const _editorContextJs = require("../../contexts/EditorContext.js"); -const _useEditorEffectJs = require("../useEditorEffect.js"); -function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { - default: obj - }; -} -function TestComponent(param) { - let { effect , dependencies =[] } = param; - (0, _useEditorEffectJs.useEditorEffect)(effect, [ - effect, - ...dependencies - ]); - return null; -} -describe("useEditorViewLayoutEffect", ()=>{ - it("should run the effect", ()=>{ - const effect = jest.fn(); - const editorView = {}; - const editorState = {}; - const registerEventListener = ()=>{}; - const unregisterEventListener = ()=>{}; - (0, _react.render)(/*#__PURE__*/ _react1.default.createElement(_layoutGroupJs.LayoutGroup, null, /*#__PURE__*/ _react1.default.createElement(_editorContextJs.EditorContext.Provider, { - value: { - view: editorView, - state: editorState, - registerEventListener, - unregisterEventListener - } - }, /*#__PURE__*/ _react1.default.createElement(TestComponent, { - effect: effect - })))); - expect(effect).toHaveBeenCalled(); - expect(effect).toHaveBeenCalledWith(editorView); - }); - it("should not re-run the effect if no dependencies change", ()=>{ - const effect = jest.fn(); - const editorView = {}; - const editorState = {}; - const registerEventListener = ()=>{}; - const unregisterEventListener = ()=>{}; - const { rerender } = (0, _react.render)(/*#__PURE__*/ _react1.default.createElement(_layoutGroupJs.LayoutGroup, null, /*#__PURE__*/ _react1.default.createElement(_editorContextJs.EditorContext.Provider, { - value: { - view: editorView, - state: editorState, - registerEventListener, - unregisterEventListener - } - }, /*#__PURE__*/ _react1.default.createElement(TestComponent, { - effect: effect, - dependencies: [] - })))); - rerender(/*#__PURE__*/ _react1.default.createElement(_layoutGroupJs.LayoutGroup, null, /*#__PURE__*/ _react1.default.createElement(_editorContextJs.EditorContext.Provider, { - value: { - view: editorView, - state: editorState, - registerEventListener, - unregisterEventListener - } - }, /*#__PURE__*/ _react1.default.createElement(TestComponent, { - effect: effect, - dependencies: [] - })))); - expect(effect).toHaveBeenCalledTimes(1); - }); - it("should re-run the effect if dependencies change", ()=>{ - const effect = jest.fn(); - const editorView = {}; - const editorState = {}; - const registerEventListener = ()=>{}; - const unregisterEventListener = ()=>{}; - const { rerender } = (0, _react.render)(/*#__PURE__*/ _react1.default.createElement(_layoutGroupJs.LayoutGroup, null, /*#__PURE__*/ _react1.default.createElement(_editorContextJs.EditorContext.Provider, { - value: { - view: editorView, - state: editorState, - registerEventListener, - unregisterEventListener - } - }, /*#__PURE__*/ _react1.default.createElement(TestComponent, { - effect: effect, - dependencies: [ - "one" - ] - })))); - rerender(/*#__PURE__*/ _react1.default.createElement(_layoutGroupJs.LayoutGroup, null, /*#__PURE__*/ _react1.default.createElement(_editorContextJs.EditorContext.Provider, { - value: { - view: editorView, - state: editorState, - registerEventListener, - unregisterEventListener - } - }, /*#__PURE__*/ _react1.default.createElement(TestComponent, { - effect: effect, - dependencies: [ - "two" - ] - })))); - expect(effect).toHaveBeenCalledTimes(2); - }); -}); diff --git a/dist/cjs/hooks/useBeforeInput.js b/dist/cjs/hooks/useBeforeInput.js deleted file mode 100644 index 1ab6955a..00000000 --- a/dist/cjs/hooks/useBeforeInput.js +++ /dev/null @@ -1,198 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "useBeforeInput", { - enumerable: true, - get: ()=>useBeforeInput -}); -const _react = require("react"); -const _reactKeysJs = require("../plugins/reactKeys.js"); -const SPACE = /\s/; -const PUNCTUATION = /[\u0021-\u0023\u0025-\u002A\u002C-\u002F\u003A\u003B\u003F\u0040\u005B-\u005D\u005F\u007B\u007D\u00A1\u00A7\u00AB\u00B6\u00B7\u00BB\u00BF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0AF0\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E3B\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/; -const CHAMELEON = /['\u2018\u2019]/; -const isWordCharacter = function(doc, pos) { - let checkDir = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : -1; - const $pos = doc.resolve(pos); - // The position is at the beginning of a node - if ($pos.parentOffset === 0) return false; - const char = doc.textBetween(pos + checkDir, pos, null, " "); - if (SPACE.test(char)) { - return false; - } - // Chameleons count as word characters as long as they're in a word, so - // recurse to see if the next one is a word character or not. - if (CHAMELEON.test(char)) { - if (isWordCharacter(doc, pos - 1)) { - return true; - } - } - if (PUNCTUATION.test(char)) { - return false; - } - return true; -}; -function insertText(view, eventData) { - let options = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {}; - if (eventData === null) return false; - const from = view.state.selection.from ?? options.from; - const to = view.state.selection.to ?? options.to; - if (view.someProp("handleTextInput")?.(view, from, to, eventData)) { - return true; - } - const { tr } = view.state; - tr.insertText(eventData, from, to); - for (const mark of view.state.storedMarks ?? []){ - tr.addMark(from, to, mark); - } - if (options.bust) { - const parentPos = view.state.doc.resolve(from).before(); - const parentKey = _reactKeysJs.reactKeysPluginKey.getState(view.state)?.posToKey.get(parentPos); - tr.setMeta(_reactKeysJs.reactKeysPluginKey, { - type: "bustKey", - payload: { - key: parentKey - } - }); - } - view.dispatch(tr); - return true; -} -function findWordBoundaryBackward(doc, start) { - let pos = start; - while(!isWordCharacter(doc, pos)){ - pos--; - } - while(isWordCharacter(doc, pos)){ - pos--; - } - return pos; -} -function findWordBoundaryForward(doc, start) { - let pos = start; - while(!isWordCharacter(doc, pos, 1)){ - pos++; - } - while(isWordCharacter(doc, pos, 1)){ - pos++; - } - return pos; -} -function useBeforeInput(view) { - const compositionTextRef = (0, _react.useRef)(null); - const compositionMarks = (0, _react.useRef)(null); - (0, _react.useEffect)(()=>{ - if (!view) return; - function onCompositionStart() { - // @ts-expect-error Internal property (domObserver) - view?.domObserver.stop(); - compositionMarks.current = view?.state.storedMarks ?? null; - } - function onCompositionEnd() { - if (!view) return; - if (compositionTextRef.current === null) return; - insertText(view, compositionTextRef.current, { - bust: true, - marks: compositionMarks.current - }); - // @ts-expect-error Internal property (domObserver) - view.domObserver.start(); - compositionTextRef.current = null; - } - function onBeforeInput(event) { - if (!view) return; - event.preventDefault(); - switch(event.inputType){ - case "insertCompositionText": - { - if (event.data === null) return; - compositionTextRef.current = event.data; - break; - } - case "insertReplacementText": - { - const ranges = event.getTargetRanges(); - event.dataTransfer?.items[0]?.getAsString((data)=>{ - for (const range of ranges){ - // @ts-expect-error Internal property (docView) - const from = view.docView.posFromDOM(range.startContainer, range.startOffset, 1); - // @ts-expect-error Internal property (docView) - const to = view.docView.posFromDOM(range.endContainer, range.endOffset, 1); - insertText(view, data, { - from, - to - }); - } - }); - break; - } - case "insertText": - { - insertText(view, event.data); - break; - } - case "deleteWordBackward": - { - const { tr , doc , selection } = view.state; - const from = selection.empty ? findWordBoundaryBackward(view.state.doc, selection.from) : selection.from; - const to = selection.to; - const storedMarks = doc.resolve(from).marksAcross(doc.resolve(to)); - tr.delete(from, to).setStoredMarks(storedMarks); - view.dispatch(tr); - break; - } - case "deleteWordForward": - { - const { tr , doc , selection } = view.state; - const from = selection.empty ? findWordBoundaryForward(view.state.doc, selection.from) : selection.from; - const to = selection.to; - const storedMarks = doc.resolve(from).marksAcross(doc.resolve(to)); - tr.delete(from, to).setStoredMarks(storedMarks); - view.dispatch(tr); - break; - } - case "deleteContentBackward": - { - const { tr , doc , selection } = view.state; - const from = selection.empty ? selection.from - 1 : selection.from; - const to = selection.to; - const storedMarks = doc.resolve(from).marksAcross(doc.resolve(to)); - tr.delete(from, to).setStoredMarks(storedMarks); - view.dispatch(tr); - break; - } - case "deleteContentForward": - { - const { tr , doc , selection } = view.state; - const from = selection.from; - const to = selection.empty ? selection.to + 1 : selection.to; - const storedMarks = doc.resolve(from).marksAcross(doc.resolve(to)); - tr.delete(from, to).setStoredMarks(storedMarks); - break; - } - case "deleteContent": - { - const { tr , doc , selection } = view.state; - const storedMarks = doc.resolve(selection.from).marksAcross(doc.resolve(selection.to)); - tr.delete(selection.from, selection.to).setStoredMarks(storedMarks); - view.dispatch(tr); - break; - } - default: - { - break; - } - } - } - view.dom.addEventListener("beforeinput", onBeforeInput); - view.dom.addEventListener("compositionend", onCompositionEnd); - view.dom.addEventListener("compositionstart", onCompositionStart); - return ()=>{ - view.dom.removeEventListener("compositionstart", onCompositionStart); - view.dom.removeEventListener("compositionend", onCompositionEnd); - view.dom.removeEventListener("beforeinput", onBeforeInput); - }; - }, [ - view - ]); -} diff --git a/dist/cjs/hooks/useComponentEventListeners.js b/dist/cjs/hooks/useComponentEventListeners.js deleted file mode 100644 index 904abf4c..00000000 --- a/dist/cjs/hooks/useComponentEventListeners.js +++ /dev/null @@ -1,37 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "useComponentEventListeners", { - enumerable: true, - get: ()=>useComponentEventListeners -}); -const _react = require("react"); -const _componentEventListenersJs = require("../plugins/componentEventListeners.js"); -function useComponentEventListeners() { - const [registry, setRegistry] = (0, _react.useState)(new Map()); - const registerEventListener = (0, _react.useCallback)((eventType, handler)=>{ - const handlers = registry.get(eventType) ?? []; - handlers.unshift(handler); - if (!registry.has(eventType)) { - registry.set(eventType, handlers); - setRegistry(new Map(registry)); - } - }, [ - registry - ]); - const unregisterEventListener = (0, _react.useCallback)((eventType, handler)=>{ - const handlers = registry.get(eventType); - handlers?.splice(handlers.indexOf(handler), 1); - }, [ - registry - ]); - const componentEventListenersPlugin = (0, _react.useMemo)(()=>(0, _componentEventListenersJs.componentEventListeners)(registry), [ - registry - ]); - return { - registerEventListener, - unregisterEventListener, - componentEventListenersPlugin - }; -} diff --git a/dist/cjs/hooks/useEditor.js b/dist/cjs/hooks/useEditor.js deleted file mode 100644 index 32d5ac5c..00000000 --- a/dist/cjs/hooks/useEditor.js +++ /dev/null @@ -1,188 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -function _export(target, all) { - for(var name in all)Object.defineProperty(target, name, { - enumerable: true, - get: all[name] - }); -} -_export(exports, { - ReactEditorView: ()=>ReactEditorView, - useEditor: ()=>useEditor -}); -const _prosemirrorModel = require("prosemirror-model"); -const _prosemirrorState = require("prosemirror-state"); -const _prosemirrorView = require("prosemirror-view"); -const _react = require("react"); -const _reactDom = require("react-dom"); -const _beforeInputPluginJs = require("../plugins/beforeInputPlugin.js"); -const _selectionDOMObserverJs = require("../selection/SelectionDOMObserver.js"); -const _viewdescJs = require("../viewdesc.js"); -const _useComponentEventListenersJs = require("./useComponentEventListeners.js"); -const _useForceUpdateJs = require("./useForceUpdate.js"); -let ReactEditorView = class ReactEditorView extends _prosemirrorView.EditorView { - /** - * Like setProps, but without executing any side effects. - * Safe to use in a component render method. - */ pureSetProps(props) { - // this.oldProps = this.props; - this._props = { - ...this._props, - ...props - }; - this.state = this._props.state; - } - /** - * Triggers any side effects that have been queued by previous - * calls to pureSetProps. - */ runPendingEffects() { - const newProps = this.props; - this._props = this.oldProps; - this.state = this._props.state; - this.update(newProps); - } - update(props) { - super.update(props); - // Ensure that side effects aren't re-triggered until - // pureSetProps is called again - this.oldProps = props; - } - updatePluginViews() { - if (this.shouldUpdatePluginViews) { - // @ts-expect-error We're making use of knowledge of internal methods here - super.updatePluginViews(); - } - } - constructor(place, props){ - // Call the superclass constructor with an empty - // document and limited props. We'll set everything - // else ourselves. - super(place, { - state: _prosemirrorState.EditorState.create({ - schema: props.state.schema, - plugins: props.state.plugins - }), - plugins: props.plugins - }); - this.shouldUpdatePluginViews = false; - this.shouldUpdatePluginViews = true; - this._props = props; - this.oldProps = { - state: props.state - }; - this.state = props.state; - // @ts-expect-error We're making use of knowledge of internal attributes here - this.domObserver.stop(); - // @ts-expect-error We're making use of knowledge of internal attributes here - this.domObserver = new _selectionDOMObserverJs.SelectionDOMObserver(this); - // @ts-expect-error We're making use of knowledge of internal attributes here - this.domObserver.start(); - // updateCursorWrapper(this); - // Destroy the DOM created by the default - // ProseMirror ViewDesc implementation; we - // have a NodeViewDesc from React instead. - // @ts-expect-error We're making use of knowledge of internal attributes here - this.docView.dom.replaceChildren(); - // @ts-expect-error We're making use of knowledge of internal attributes here - this.docView = props.docView; - } -}; -const EMPTY_SCHEMA = new _prosemirrorModel.Schema({ - nodes: { - doc: { - content: "text*" - }, - text: { - inline: true - } - } -}); -const EMPTY_STATE = _prosemirrorState.EditorState.create({ - schema: EMPTY_SCHEMA -}); -let didWarnValueDefaultValue = false; -function useEditor(mount, options) { - if (process.env.NODE_ENV !== "production") { - if (options.defaultState !== undefined && options.state !== undefined && !didWarnValueDefaultValue) { - console.error("A component contains a ProseMirror editor with both value and defaultValue props. " + "ProseMirror editors must be either controlled or uncontrolled " + "(specify either the state prop, or the defaultState prop, but not both). " + "Decide between using a controlled or uncontrolled ProseMirror editor " + "and remove one of these props. More info: " + "https://reactjs.org/link/controlled-components"); - didWarnValueDefaultValue = true; - } - } - const [view, setView] = (0, _react.useState)(null); - const [cursorWrapper, _setCursorWrapper] = (0, _react.useState)(null); - const forceUpdate = (0, _useForceUpdateJs.useForceUpdate)(); - const defaultState = options.defaultState ?? EMPTY_STATE; - const [_state, setState] = (0, _react.useState)(defaultState); - const state = options.state ?? _state; - const { componentEventListenersPlugin , registerEventListener , unregisterEventListener } = (0, _useComponentEventListenersJs.useComponentEventListeners)(); - const setCursorWrapper = (0, _react.useCallback)((deco)=>{ - (0, _reactDom.flushSync)(()=>{ - _setCursorWrapper(deco); - }); - }, []); - const plugins = (0, _react.useMemo)(()=>[ - ...options.plugins ?? [], - componentEventListenersPlugin, - (0, _beforeInputPluginJs.beforeInputPlugin)(setCursorWrapper) - ], [ - options.plugins, - componentEventListenersPlugin, - setCursorWrapper - ]); - function dispatchTransaction(tr) { - (0, _reactDom.flushSync)(()=>{ - if (!options.state) { - setState((s)=>s.apply(tr)); - } - if (options.dispatchTransaction) { - options.dispatchTransaction.call(this, tr); - } - }); - } - const tempDom = document.createElement("div"); - const docViewDescRef = (0, _react.useRef)(new _viewdescJs.NodeViewDesc(undefined, [], state.doc, [], _prosemirrorView.DecorationSet.empty, tempDom, null, tempDom)); - const directEditorProps = { - ...options, - state, - plugins, - dispatchTransaction, - docView: docViewDescRef.current - }; - // This rule is concerned about infinite updates due to the - // call to setView. These calls are deliberately conditional, - // so this is not a concern. - // eslint-disable-next-line react-hooks/exhaustive-deps - (0, _react.useLayoutEffect)(()=>{ - if (view && view.dom !== mount) { - setView(null); - } - if (!mount) { - return; - } - if (!view) { - const newView = new ReactEditorView({ - mount - }, directEditorProps); - setView(newView); - newView.dom.addEventListener("compositionend", forceUpdate); - return; - } - }); - view?.pureSetProps(directEditorProps); - return (0, _react.useMemo)(()=>({ - view: view, - state: state, - registerEventListener, - unregisterEventListener, - cursorWrapper, - docViewDescRef - }), [ - view, - state, - registerEventListener, - unregisterEventListener, - cursorWrapper - ]); -} diff --git a/dist/cjs/hooks/useEditorEffect.js b/dist/cjs/hooks/useEditorEffect.js deleted file mode 100644 index 8f41c2b0..00000000 --- a/dist/cjs/hooks/useEditorEffect.js +++ /dev/null @@ -1,33 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "useEditorEffect", { - enumerable: true, - get: ()=>useEditorEffect -}); -const _react = require("react"); -const _editorContextJs = require("../contexts/EditorContext.js"); -const _useLayoutGroupEffectJs = require("./useLayoutGroupEffect.js"); -function useEditorEffect(effect, dependencies) { - const { view } = (0, _react.useContext)(_editorContextJs.EditorContext); - // The rules of hooks want `effect` to be included in the - // dependency list, but dependency issues for `effect` will - // be caught by the linter at the call-site for - // `useEditorViewLayoutEffect`. - // Note: we specifically don't want to re-run the effect - // every time it changes, because it will most likely - // be defined inline and run on every re-render. - (0, _useLayoutGroupEffectJs.useLayoutGroupEffect)(()=>{ - if (view) { - return effect(view); - } - }, // The rules of hooks want to be able to statically - // verify the dependencies for the effect, but this will - // have already happened at the call-site. - // eslint-disable-next-line react-hooks/exhaustive-deps - dependencies && [ - view, - ...dependencies - ]); -} diff --git a/dist/cjs/hooks/useEditorEventCallback.js b/dist/cjs/hooks/useEditorEventCallback.js deleted file mode 100644 index 1601b3bf..00000000 --- a/dist/cjs/hooks/useEditorEventCallback.js +++ /dev/null @@ -1,31 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "useEditorEventCallback", { - enumerable: true, - get: ()=>useEditorEventCallback -}); -const _react = require("react"); -const _editorContextJs = require("../contexts/EditorContext.js"); -const _useEditorEffectJs = require("./useEditorEffect.js"); -function useEditorEventCallback(callback) { - const ref = (0, _react.useRef)(callback); - const { view } = (0, _react.useContext)(_editorContextJs.EditorContext); - (0, _useEditorEffectJs.useEditorEffect)(()=>{ - ref.current = callback; - }, [ - callback - ]); - return (0, _react.useCallback)(function() { - for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){ - args[_key] = arguments[_key]; - } - if (view) { - return ref.current(view, ...args); - } - return; - }, [ - view - ]); -} diff --git a/dist/cjs/hooks/useEditorEventListener.js b/dist/cjs/hooks/useEditorEventListener.js deleted file mode 100644 index df914b9d..00000000 --- a/dist/cjs/hooks/useEditorEventListener.js +++ /dev/null @@ -1,32 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "useEditorEventListener", { - enumerable: true, - get: ()=>useEditorEventListener -}); -const _react = require("react"); -const _editorContextJs = require("../contexts/EditorContext.js"); -const _useEditorEffectJs = require("./useEditorEffect.js"); -function useEditorEventListener(eventType, handler) { - const { registerEventListener , unregisterEventListener } = (0, _react.useContext)(_editorContextJs.EditorContext); - const ref = (0, _react.useRef)(handler); - (0, _useEditorEffectJs.useEditorEffect)(()=>{ - ref.current = handler; - }, [ - handler - ]); - const eventHandler = (0, _react.useCallback)(function(view, event) { - return ref.current.call(this, view, event); - }, []); - (0, _useEditorEffectJs.useEditorEffect)(()=>{ - registerEventListener(eventType, eventHandler); - return ()=>unregisterEventListener(eventType, eventHandler); - }, [ - eventHandler, - eventType, - registerEventListener, - unregisterEventListener - ]); -} diff --git a/dist/cjs/hooks/useEditorState.js b/dist/cjs/hooks/useEditorState.js deleted file mode 100644 index e2445358..00000000 --- a/dist/cjs/hooks/useEditorState.js +++ /dev/null @@ -1,14 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "useEditorState", { - enumerable: true, - get: ()=>useEditorState -}); -const _react = require("react"); -const _editorContextJs = require("../contexts/EditorContext.js"); -function useEditorState() { - const { state: editorState } = (0, _react.useContext)(_editorContextJs.EditorContext); - return editorState; -} diff --git a/dist/cjs/hooks/useForceUpdate.js b/dist/cjs/hooks/useForceUpdate.js deleted file mode 100644 index 0a3209d0..00000000 --- a/dist/cjs/hooks/useForceUpdate.js +++ /dev/null @@ -1,13 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "useForceUpdate", { - enumerable: true, - get: ()=>useForceUpdate -}); -const _react = require("react"); -function useForceUpdate() { - const [, forceUpdate] = (0, _react.useReducer)((x)=>x + 1, 0); - return forceUpdate; -} diff --git a/dist/cjs/hooks/useLayoutGroupEffect.js b/dist/cjs/hooks/useLayoutGroupEffect.js deleted file mode 100644 index 2fc67ff7..00000000 --- a/dist/cjs/hooks/useLayoutGroupEffect.js +++ /dev/null @@ -1,17 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "useLayoutGroupEffect", { - enumerable: true, - get: ()=>useLayoutGroupEffect -}); -const _react = require("react"); -const _layoutGroupContextJs = require("../contexts/LayoutGroupContext.js"); -function useLayoutGroupEffect(effect, deps) { - const register = (0, _react.useContext)(_layoutGroupContextJs.LayoutGroupContext); - // The rule for hooks wants to statically verify the deps, - // but the dependencies are up to the caller, not this implementation. - // eslint-disable-next-line react-hooks/exhaustive-deps - (0, _react.useLayoutEffect)(()=>register(effect), deps); -} diff --git a/dist/cjs/hooks/useNodeViewDescriptor.js b/dist/cjs/hooks/useNodeViewDescriptor.js deleted file mode 100644 index ac3dce86..00000000 --- a/dist/cjs/hooks/useNodeViewDescriptor.js +++ /dev/null @@ -1,43 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "useNodeViewDescriptor", { - enumerable: true, - get: ()=>useNodeViewDescriptor -}); -const _react = require("react"); -const _childDescriptorsContextJs = require("../contexts/ChildDescriptorsContext.js"); -const _viewdescJs = require("../viewdesc.js"); -function useNodeViewDescriptor(node, domRef, nodeDomRef, innerDecorations, outerDecorations, viewDesc, contentDOMRef) { - const nodeViewDescRef = (0, _react.useRef)(viewDesc); - const siblingDescriptors = (0, _react.useContext)(_childDescriptorsContextJs.ChildDescriptorsContext); - const childDescriptors = []; - (0, _react.useLayoutEffect)(()=>{ - if (!node || !nodeDomRef.current) return; - const firstChildDesc = childDescriptors[0]; - if (!nodeViewDescRef.current) { - nodeViewDescRef.current = new _viewdescJs.NodeViewDesc(undefined, childDescriptors, node, outerDecorations, innerDecorations, domRef?.current ?? nodeDomRef.current, firstChildDesc?.dom.parentElement ?? null, nodeDomRef.current); - } else { - nodeViewDescRef.current.parent = undefined; - nodeViewDescRef.current.children = childDescriptors; - nodeViewDescRef.current.node = node; - nodeViewDescRef.current.outerDeco = outerDecorations; - nodeViewDescRef.current.innerDeco = innerDecorations; - nodeViewDescRef.current.dom = domRef?.current ?? nodeDomRef.current; - // @ts-expect-error We have our own ViewDesc implementations - nodeViewDescRef.current.dom.pmViewDesc = nodeViewDescRef.current; - nodeViewDescRef.current.contentDOM = // If there's already a contentDOM, we can just - // keep it; it won't have changed. This is especially - // important during compositions, where the - // firstChildDesc might not have a correct dom node set yet. - contentDOMRef?.current ?? nodeViewDescRef.current.contentDOM ?? firstChildDesc?.dom.parentElement ?? null; - nodeViewDescRef.current.nodeDOM = nodeDomRef.current; - } - siblingDescriptors.push(nodeViewDescRef.current); - for (const childDesc of childDescriptors){ - childDesc.parent = nodeViewDescRef.current; - } - }); - return childDescriptors; -} diff --git a/dist/cjs/hooks/usePendingViewEffects.js b/dist/cjs/hooks/usePendingViewEffects.js deleted file mode 100644 index 8568404c..00000000 --- a/dist/cjs/hooks/usePendingViewEffects.js +++ /dev/null @@ -1,19 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "usePendingViewEffects", { - enumerable: true, - get: ()=>usePendingViewEffects -}); -const _react = require("react"); -function usePendingViewEffects(view) { - (0, _react.useLayoutEffect)(()=>{ - // @ts-expect-error Internal property - domObserver - view?.domObserver.selectionToDOM(); - view?.runPendingEffects(); - }, [ - view, - view?.props - ]); -} diff --git a/dist/cjs/hooks/useReactKeys.js b/dist/cjs/hooks/useReactKeys.js deleted file mode 100644 index 4ab4543c..00000000 --- a/dist/cjs/hooks/useReactKeys.js +++ /dev/null @@ -1,14 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "useReactKeys", { - enumerable: true, - get: ()=>useReactKeys -}); -const _reactKeysJs = require("../plugins/reactKeys.js"); -const _useEditorStateJs = require("./useEditorState.js"); -function useReactKeys() { - const state = (0, _useEditorStateJs.useEditorState)(); - return state && _reactKeysJs.reactKeysPluginKey.getState(state); -} diff --git a/dist/cjs/index.js b/dist/cjs/index.js deleted file mode 100644 index 57af5960..00000000 --- a/dist/cjs/index.js +++ /dev/null @@ -1,29 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -function _export(target, all) { - for(var name in all)Object.defineProperty(target, name, { - enumerable: true, - get: all[name] - }); -} -_export(exports, { - ProseMirror: ()=>_proseMirrorJs.ProseMirror, - ProseMirrorDoc: ()=>_proseMirrorDocJs.ProseMirrorDoc, - useEditorEffect: ()=>_useEditorEffectJs.useEditorEffect, - useEditorEventCallback: ()=>_useEditorEventCallbackJs.useEditorEventCallback, - useEditorEventListener: ()=>_useEditorEventListenerJs.useEditorEventListener, - useEditorState: ()=>_useEditorStateJs.useEditorState, - reactKeys: ()=>_reactKeysJs.reactKeys, - widget: ()=>_reactWidgetTypeJs.widget -}); -const _proseMirrorJs = require("./components/ProseMirror.js"); -const _proseMirrorDocJs = require("./components/ProseMirrorDoc.js"); -const _useEditorEffectJs = require("./hooks/useEditorEffect.js"); -const _useEditorEventCallbackJs = require("./hooks/useEditorEventCallback.js"); -const _useEditorEventListenerJs = require("./hooks/useEditorEventListener.js"); -const _useEditorStateJs = require("./hooks/useEditorState.js"); -const _reactKeysJs = require("./plugins/reactKeys.js"); -const _reactWidgetTypeJs = require("./decorations/ReactWidgetType.js"); -"use client"; diff --git a/dist/cjs/plugins/__tests__/reactKeys.test.js b/dist/cjs/plugins/__tests__/reactKeys.test.js deleted file mode 100644 index 4b225892..00000000 --- a/dist/cjs/plugins/__tests__/reactKeys.test.js +++ /dev/null @@ -1,81 +0,0 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ "use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -const _prosemirrorModel = require("prosemirror-model"); -const _prosemirrorState = require("prosemirror-state"); -const _reactKeysJs = require("../reactKeys.js"); -const schema = new _prosemirrorModel.Schema({ - nodes: { - doc: { - content: "block+" - }, - paragraph: { - group: "block", - content: "inline*" - }, - list: { - group: "block", - content: "list_item+" - }, - list_item: { - content: "inline*" - }, - text: { - group: "inline" - } - } -}); -describe("reactNodeViewPlugin", ()=>{ - it("should create a unique key for each node", ()=>{ - const editorState = _prosemirrorState.EditorState.create({ - doc: schema.topNodeType.create(null, [ - schema.nodes.paragraph.create(), - schema.nodes.paragraph.create(), - schema.nodes.paragraph.create() - ]), - plugins: [ - (0, _reactKeysJs.reactKeys)() - ] - }); - const pluginState = _reactKeysJs.reactKeysPluginKey.getState(editorState); - expect(pluginState.posToKey.size).toBe(3); - }); - it("should maintain key stability when possible", ()=>{ - const initialEditorState = _prosemirrorState.EditorState.create({ - doc: schema.topNodeType.create(null, [ - schema.nodes.paragraph.create({}, schema.text("Hello")), - schema.nodes.paragraph.create(), - schema.nodes.paragraph.create() - ]), - plugins: [ - (0, _reactKeysJs.reactKeys)() - ] - }); - const initialPluginState = _reactKeysJs.reactKeysPluginKey.getState(initialEditorState); - const nextEditorState = initialEditorState.apply(initialEditorState.tr.insertText(", world!", 6)); - const nextPluginState = _reactKeysJs.reactKeysPluginKey.getState(nextEditorState); - expect(Array.from(initialPluginState.keyToPos.keys())).toEqual(Array.from(nextPluginState.keyToPos.keys())); - }); - it("should create unique keys for new nodes", ()=>{ - const initialEditorState = _prosemirrorState.EditorState.create({ - doc: schema.topNodeType.create(null, [ - schema.nodes.paragraph.create(), - schema.nodes.paragraph.create(), - schema.nodes.paragraph.create() - ]), - plugins: [ - (0, _reactKeysJs.reactKeys)() - ] - }); - const initialPluginState = _reactKeysJs.reactKeysPluginKey.getState(initialEditorState); - const nextEditorState = initialEditorState.apply(initialEditorState.tr.insert(0, schema.nodes.list.createAndFill())); - const nextPluginState = _reactKeysJs.reactKeysPluginKey.getState(nextEditorState); - // Adds new keys for new nodes - expect(nextPluginState.keyToPos.size).toBe(5); - // Maintains keys for previous nodes that are still there - Array.from(initialPluginState.keyToPos.keys()).forEach((key)=>{ - expect(Array.from(nextPluginState.keyToPos.keys())).toContain(key); - }); - }); -}); diff --git a/dist/cjs/plugins/beforeInputPlugin.js b/dist/cjs/plugins/beforeInputPlugin.js deleted file mode 100644 index 9b99ed99..00000000 --- a/dist/cjs/plugins/beforeInputPlugin.js +++ /dev/null @@ -1,216 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "beforeInputPlugin", { - enumerable: true, - get: ()=>beforeInputPlugin -}); -const _prosemirrorState = require("prosemirror-state"); -const _cursorWrapperJs = require("../components/CursorWrapper.js"); -const _reactWidgetTypeJs = require("../decorations/ReactWidgetType.js"); -const _reactKeysJs = require("./reactKeys.js"); -const SPACE = /\s/; -const PUNCTUATION = /[\u0021-\u0023\u0025-\u002A\u002C-\u002F\u003A\u003B\u003F\u0040\u005B-\u005D\u005F\u007B\u007D\u00A1\u00A7\u00AB\u00B6\u00B7\u00BB\u00BF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0AF0\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E3B\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/; -const CHAMELEON = /['\u2018\u2019]/; -const isWordCharacter = function(doc, pos) { - let checkDir = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : -1; - const $pos = doc.resolve(pos); - // The position is at the beginning of a node - if ($pos.parentOffset === 0) return false; - const char = doc.textBetween(pos + checkDir, pos, null, " "); - if (SPACE.test(char)) { - return false; - } - // Chameleons count as word characters as long as they're in a word, so - // recurse to see if the next one is a word character or not. - if (CHAMELEON.test(char)) { - if (isWordCharacter(doc, pos - 1)) { - return true; - } - } - if (PUNCTUATION.test(char)) { - return false; - } - return true; -}; -function insertText(view, eventData) { - let options = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {}; - if (eventData === null) return false; - const from = options.from ?? view.state.selection.from; - const to = options.to ?? view.state.selection.to; - if (view.someProp("handleTextInput")?.(view, from, to, eventData)) { - return true; - } - const { tr } = view.state; - if (options.marks) tr.ensureMarks(options.marks); - tr.insertText(eventData, from, to); - if (options.bust) { - const $from = view.state.doc.resolve(from); - const sharedAncestorDepth = $from.sharedDepth(to); - const sharedAncestorPos = $from.start(sharedAncestorDepth); - const parentKey = _reactKeysJs.reactKeysPluginKey.getState(view.state)?.posToKey.get(sharedAncestorPos - 1); - tr.setMeta(_reactKeysJs.reactKeysPluginKey, { - type: "bustKey", - payload: { - key: parentKey - } - }); - } - view.dispatch(tr); - return true; -} -function findWordBoundaryBackward(doc, start) { - let pos = start; - while(!isWordCharacter(doc, pos)){ - pos--; - } - while(isWordCharacter(doc, pos)){ - pos--; - } - return pos; -} -function findWordBoundaryForward(doc, start) { - let pos = start; - while(!isWordCharacter(doc, pos, 1)){ - pos++; - } - while(isWordCharacter(doc, pos, 1)){ - pos++; - } - return pos; -} -function beforeInputPlugin(setCursorWrapper) { - let compositionText = null; - let compositionMarks = null; - return new _prosemirrorState.Plugin({ - props: { - handleDOMEvents: { - compositionstart (view) { - const { state } = view; - view.dispatch(state.tr.deleteSelection()); - const $pos = state.selection.$from; - if (state.selection.empty && (state.storedMarks || !$pos.textOffset && $pos.parentOffset && $pos.nodeBefore?.marks.some((m)=>m.type.spec.inclusive === false))) { - setCursorWrapper((0, _reactWidgetTypeJs.widget)(state.selection.from, _cursorWrapperJs.CursorWrapper, { - key: "cursor-wrapper", - marks: state.storedMarks ?? $pos.marks() - })); - } - compositionMarks = state.storedMarks ?? $pos.marks(); - // @ts-expect-error Internal property - input - view.input.composing = true; - return true; - }, - compositionupdate () { - return true; - }, - compositionend (view) { - // @ts-expect-error Internal property - input - view.input.composing = false; - if (compositionText === null) return; - insertText(view, compositionText, { - // TODO: Rather than busting the reactKey cache here, - // which is pretty blunt and doesn't work for - // multi-node replacements, we should attempt to - // snapshot the selected DOM during compositionstart - // and restore it before we end the composition. - // This should allow React to successfully clean up - // and insert the newly composed text, without requiring - // any remounts - bust: true, - marks: compositionMarks - }); - compositionText = null; - compositionMarks = null; - setCursorWrapper(null); - return true; - }, - beforeinput (view, event) { - event.preventDefault(); - switch(event.inputType){ - case "insertCompositionText": - { - if (event.data === null) break; - compositionText = event.data; - break; - } - case "insertReplacementText": - { - const ranges = event.getTargetRanges(); - event.dataTransfer?.items[0]?.getAsString((data)=>{ - for (const range of ranges){ - // @ts-expect-error Internal property - docView - const from = view.docView.posFromDOM(range.startContainer, range.startOffset, 1); - // @ts-expect-error Internal property - docView - const to = view.docView.posFromDOM(range.endContainer, range.endOffset, 1); - insertText(view, data, { - from, - to - }); - } - }); - break; - } - case "insertText": - { - insertText(view, event.data); - break; - } - case "deleteWordBackward": - { - const { tr , doc , selection } = view.state; - const from = selection.empty ? findWordBoundaryBackward(view.state.doc, selection.from) : selection.from; - const to = selection.to; - const storedMarks = doc.resolve(from).marksAcross(doc.resolve(to)); - tr.delete(from, to).setStoredMarks(storedMarks); - view.dispatch(tr); - break; - } - case "deleteWordForward": - { - const { tr , doc , selection } = view.state; - const from = selection.empty ? findWordBoundaryForward(view.state.doc, selection.from) : selection.from; - const to = selection.to; - const storedMarks = doc.resolve(from).marksAcross(doc.resolve(to)); - tr.delete(from, to).setStoredMarks(storedMarks); - view.dispatch(tr); - break; - } - case "deleteContentBackward": - { - const { tr , doc , selection } = view.state; - const from = selection.empty ? selection.from - 1 : selection.from; - const to = selection.to; - const storedMarks = doc.resolve(from).marksAcross(doc.resolve(to)); - tr.delete(from, to).setStoredMarks(storedMarks); - view.dispatch(tr); - break; - } - case "deleteContentForward": - { - const { tr , doc , selection } = view.state; - const from = selection.from; - const to = selection.empty ? selection.to + 1 : selection.to; - const storedMarks = doc.resolve(from).marksAcross(doc.resolve(to)); - tr.delete(from, to).setStoredMarks(storedMarks); - break; - } - case "deleteContent": - { - const { tr , doc , selection } = view.state; - const storedMarks = doc.resolve(selection.from).marksAcross(doc.resolve(selection.to)); - tr.delete(selection.from, selection.to).setStoredMarks(storedMarks); - view.dispatch(tr); - break; - } - default: - { - break; - } - } - return true; - } - } - } - }); -} diff --git a/dist/cjs/plugins/componentEventListeners.js b/dist/cjs/plugins/componentEventListeners.js deleted file mode 100644 index 810cc94b..00000000 --- a/dist/cjs/plugins/componentEventListeners.js +++ /dev/null @@ -1,33 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "componentEventListeners", { - enumerable: true, - get: ()=>componentEventListeners -}); -const _prosemirrorState = require("prosemirror-state"); -const _reactDom = require("react-dom"); -function componentEventListeners(eventHandlerRegistry) { - const domEventHandlers = {}; - for (const [eventType, handlers] of eventHandlerRegistry.entries()){ - function handleEvent(view, event) { - for (const handler of handlers){ - let handled = false; - (0, _reactDom.unstable_batchedUpdates)(()=>{ - handled = !!handler.call(this, view, event); - }); - if (handled || event.defaultPrevented) return true; - } - return false; - } - domEventHandlers[eventType] = handleEvent; - } - const plugin = new _prosemirrorState.Plugin({ - key: new _prosemirrorState.PluginKey("@nytimes/react-prosemirror/componentEventListeners"), - props: { - handleDOMEvents: domEventHandlers - } - }); - return plugin; -} diff --git a/dist/cjs/plugins/componentEventListenersPlugin.js b/dist/cjs/plugins/componentEventListenersPlugin.js deleted file mode 100644 index 183e45f5..00000000 --- a/dist/cjs/plugins/componentEventListenersPlugin.js +++ /dev/null @@ -1,33 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "createComponentEventListenersPlugin", { - enumerable: true, - get: ()=>createComponentEventListenersPlugin -}); -const _prosemirrorState = require("prosemirror-state"); -const _reactDom = require("react-dom"); -function createComponentEventListenersPlugin(eventHandlerRegistry) { - const domEventHandlers = {}; - for (const [eventType, handlers] of eventHandlerRegistry.entries()){ - function handleEvent(view, event) { - for (const handler of handlers){ - let handled = false; - (0, _reactDom.unstable_batchedUpdates)(()=>{ - handled = !!handler.call(this, view, event); - }); - if (handled || event.defaultPrevented) return true; - } - return false; - } - domEventHandlers[eventType] = handleEvent; - } - const plugin = new _prosemirrorState.Plugin({ - key: new _prosemirrorState.PluginKey("componentEventListeners"), - props: { - handleDOMEvents: domEventHandlers - } - }); - return plugin; -} diff --git a/dist/cjs/plugins/reactKeys.js b/dist/cjs/plugins/reactKeys.js deleted file mode 100644 index 26bb9f0b..00000000 --- a/dist/cjs/plugins/reactKeys.js +++ /dev/null @@ -1,89 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -function _export(target, all) { - for(var name in all)Object.defineProperty(target, name, { - enumerable: true, - get: all[name] - }); -} -_export(exports, { - createNodeKey: ()=>createNodeKey, - reactKeysPluginKey: ()=>reactKeysPluginKey, - reactKeys: ()=>reactKeys -}); -const _prosemirrorState = require("prosemirror-state"); -function createNodeKey() { - const key = Math.floor(Math.random() * 0xffffff).toString(16); - return key; -} -const reactKeysPluginKey = new _prosemirrorState.PluginKey("@nytimes/react-prosemirror/reactKeys"); -function reactKeys() { - let composing = false; - return new _prosemirrorState.Plugin({ - key: reactKeysPluginKey, - state: { - init (_, state) { - const next = { - posToKey: new Map(), - keyToPos: new Map() - }; - state.doc.descendants((_, pos)=>{ - const key = createNodeKey(); - next.posToKey.set(pos, key); - next.keyToPos.set(key, pos); - return true; - }); - return next; - }, - /** - * Keeps node keys (mostly) stable across transactions. - * - * To accomplish this, we map each node position backwards - * through the transaction to identify its previous position, - * and thereby retrieve its previous key. - */ apply (tr, value, _, newState) { - if (!tr.docChanged || composing) return value; - const meta = tr.getMeta(reactKeysPluginKey); - const keyToBust = meta?.type === "bustKey" && meta.payload.key; - const next = { - posToKey: new Map(), - keyToPos: new Map() - }; - const posToKeyEntries = Array.from(value.posToKey.entries()).sort((param, param1)=>{ - let [a] = param, [b] = param1; - return a - b; - }); - for (const [pos, key] of posToKeyEntries){ - const { pos: newPos , deleted } = tr.mapping.mapResult(pos); - if (deleted) continue; - let newKey = key; - if (keyToBust === key) { - newKey = createNodeKey(); - } - next.posToKey.set(newPos, newKey); - next.keyToPos.set(newKey, newPos); - } - newState.doc.descendants((_, pos)=>{ - if (next.posToKey.has(pos)) return true; - const key = createNodeKey(); - next.posToKey.set(pos, key); - next.keyToPos.set(key, pos); - return true; - }); - return next; - } - }, - props: { - handleDOMEvents: { - compositionstart: ()=>{ - composing = true; - }, - compositionend: ()=>{ - composing = false; - } - } - } - }); -} diff --git a/dist/cjs/selection/SelectionDOMObserver.js b/dist/cjs/selection/SelectionDOMObserver.js deleted file mode 100644 index d034294a..00000000 --- a/dist/cjs/selection/SelectionDOMObserver.js +++ /dev/null @@ -1,172 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "SelectionDOMObserver", { - enumerable: true, - get: ()=>SelectionDOMObserver -}); -const _prosemirrorState = require("prosemirror-state"); -const _browserJs = require("../browser.js"); -const _domJs = require("../dom.js"); -const _hasFocusAndSelectionJs = require("./hasFocusAndSelection.js"); -const _selectionFromDOMJs = require("./selectionFromDOM.js"); -const _selectionToDOMJs = require("./selectionToDOM.js"); -let SelectionState = class SelectionState { - set(sel) { - this.anchorNode = sel.anchorNode; - this.anchorOffset = sel.anchorOffset; - this.focusNode = sel.focusNode; - this.focusOffset = sel.focusOffset; - } - clear() { - this.anchorNode = this.focusNode = null; - } - eq(sel) { - return sel.anchorNode == this.anchorNode && sel.anchorOffset == this.anchorOffset && sel.focusNode == this.focusNode && sel.focusOffset == this.focusOffset; - } - constructor(){ - this.anchorNode = null; - this.anchorOffset = 0; - this.focusNode = null; - this.focusOffset = 0; - } -}; -let SelectionDOMObserver = class SelectionDOMObserver { - connectSelection() { - // TODO: Unclear whether this is safe. Without it, - // the DOMObserver will be triggered by its own selection - // updates - // setTimeout(() => - this.view.dom.ownerDocument.addEventListener("selectionchange", this.onSelectionChange); - // ); - } - disconnectSelection() { - this.view.dom.ownerDocument.removeEventListener("selectionchange", this.onSelectionChange); - } - stop() { - this.disconnectSelection(); - } - start() { - this.connectSelection(); - } - suppressSelectionUpdates() { - this.suppressingSelectionUpdates = true; - setTimeout(()=>this.suppressingSelectionUpdates = false, 50); - } - setCurSelection() { - // @ts-expect-error Internal method - this.currentSelection.set(this.view.domSelectionRange()); - } - ignoreSelectionChange(sel) { - if (!sel.focusNode) return true; - const ancestors = new Set(); - let container; - for(let scan = sel.focusNode; scan; scan = (0, _domJs.parentNode)(scan))ancestors.add(scan); - for(let scan = sel.anchorNode; scan; scan = (0, _domJs.parentNode)(scan))if (ancestors.has(scan)) { - container = scan; - break; - } - // @ts-expect-error Internal property (docView) - const desc = container && this.view.docView.nearestDesc(container); - if (desc && desc.ignoreMutation({ - type: "selection", - target: container?.nodeType == 3 ? container?.parentNode : container - })) { - this.setCurSelection(); - return true; - } - return; - } - registerMutation() { - // pass - } - flushSoon() { - if (this.flushingSoon < 0) this.flushingSoon = window.setTimeout(()=>{ - this.flushingSoon = -1; - this.flush(); - }, 20); - } - updateSelection() { - const { view } = this; - const compositionID = // @ts-expect-error Internal property (input) - view.input.compositionPendingChanges || // @ts-expect-error Internal property (input) - (view.composing ? view.input.compositionID : 0); - // @ts-expect-error Internal property (input) - view.input.compositionPendingChanges = 0; - const origin = // @ts-expect-error Internal property (input) - view.input.lastSelectionTime > Date.now() - 50 ? view.input.lastSelectionOrigin : null; - const newSel = (0, _selectionFromDOMJs.selectionFromDOM)(view, origin); - if (newSel && !view.state.selection.eq(newSel)) { - const tr = view.state.tr.setSelection(newSel); - if (origin == "pointer") tr.setMeta("pointer", true); - else if (origin == "key") tr.scrollIntoView(); - if (compositionID) tr.setMeta("composition", compositionID); - view.dispatch(tr); - } - } - selectionToDOM() { - const { view } = this; - (0, _selectionToDOMJs.selectionToDOM)(view); - // @ts-expect-error Internal property (domSelectionRange) - const sel = view.domSelectionRange(); - this.currentSelection.set(sel); - } - flush() { - const { view } = this; - // @ts-expect-error Internal property (docView) - if (!view.docView || this.flushingSoon > -1) return; - // @ts-expect-error Internal property (domSelectionRange) - const sel = view.domSelectionRange(); - const newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && (0, _hasFocusAndSelectionJs.hasFocusAndSelection)(view) && !this.ignoreSelectionChange(sel); - let readSel = null; - // If it looks like the browser has reset the selection to the - // start of the document after focus, restore the selection from - // the state - if (newSel && // @ts-expect-error Internal property (input) - view.input.lastFocus > Date.now() - 200 && // @ts-expect-error Internal property (input) - Math.max(view.input.lastTouch, view.input.lastClick.time) < Date.now() - 300 && (0, _domJs.selectionCollapsed)(sel) && (readSel = (0, _selectionFromDOMJs.selectionFromDOM)(view)) && readSel.eq(_prosemirrorState.Selection.near(view.state.doc.resolve(0), 1))) { - // @ts-expect-error Internal property (input) - view.input.lastFocus = 0; - (0, _selectionToDOMJs.selectionToDOM)(view); - this.currentSelection.set(sel); - // @ts-expect-error Internal property (scrollToSelection) - view.scrollToSelection(); - } else if (newSel) { - this.updateSelection(); - if (!this.currentSelection.eq(sel)) (0, _selectionToDOMJs.selectionToDOM)(view); - this.currentSelection.set(sel); - } - } - forceFlush() { - if (this.flushingSoon > -1) { - window.clearTimeout(this.flushingSoon); - this.flushingSoon = -1; - this.flush(); - } - } - onSelectionChange() { - if (!(0, _hasFocusAndSelectionJs.hasFocusAndSelection)(this.view)) return; - if (this.view.composing) return; - if (this.suppressingSelectionUpdates) return (0, _selectionToDOMJs.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 (_browserJs.browser.ie && _browserJs.browser.ie_version <= 11 && !this.view.state.selection.empty) { - // @ts-expect-error Internal method - const sel = this.view.domSelectionRange(); - // Selection.isCollapsed isn't reliable on IE - if (sel.focusNode && (0, _selectionToDOMJs.isEquivalentPosition)(sel.focusNode, sel.focusOffset, // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - sel.anchorNode, sel.anchorOffset)) return this.flushSoon(); - } - this.flush(); - } - constructor(view){ - this.view = view; - this.flushingSoon = -1; - this.currentSelection = new SelectionState(); - this.suppressingSelectionUpdates = false; - this.view = view; - this.onSelectionChange = this.onSelectionChange.bind(this); - } -}; diff --git a/dist/cjs/selection/hasFocusAndSelection.js b/dist/cjs/selection/hasFocusAndSelection.js deleted file mode 100644 index ccadbee1..00000000 --- a/dist/cjs/selection/hasFocusAndSelection.js +++ /dev/null @@ -1,31 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -function _export(target, all) { - for(var name in all)Object.defineProperty(target, name, { - enumerable: true, - get: all[name] - }); -} -_export(exports, { - hasFocusAndSelection: ()=>hasFocusAndSelection, - hasSelection: ()=>hasSelection -}); -function hasFocusAndSelection(view) { - if (view.editable && !view.hasFocus()) return false; - return hasSelection(view); -} -function hasSelection(view) { - // @ts-expect-error Internal method - const sel = view.domSelectionRange(); - 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; - } -} diff --git a/dist/cjs/selection/selectionFromDOM.js b/dist/cjs/selection/selectionFromDOM.js deleted file mode 100644 index 03619426..00000000 --- a/dist/cjs/selection/selectionFromDOM.js +++ /dev/null @@ -1,53 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -function _export(target, all) { - for(var name in all)Object.defineProperty(target, name, { - enumerable: true, - get: all[name] - }); -} -_export(exports, { - selectionBetween: ()=>selectionBetween, - selectionFromDOM: ()=>selectionFromDOM -}); -const _prosemirrorState = require("prosemirror-state"); -const _domJs = require("../dom.js"); -function selectionBetween(view, $anchor, $head, bias) { - return view.someProp("createSelectionBetween", (f)=>f(view, $anchor, $head)) || _prosemirrorState.TextSelection.between($anchor, $head, bias); -} -function selectionFromDOM(view) { - let origin = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : null; - // @ts-expect-error Internal method - const domSel = view.domSelectionRange(), doc = view.state.doc; - if (!domSel.focusNode) return null; - // @ts-expect-error Internel property - let nearestDesc = view.docView.nearestDesc(domSel.focusNode); - const inWidget = nearestDesc && nearestDesc.size == 0; - // @ts-expect-error Internel property - const head = view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset, 1); - if (head < 0) return null; - const $head = doc.resolve(head); - let $anchor, selection; - if ((0, _domJs.selectionCollapsed)(domSel)) { - $anchor = $head; - while(nearestDesc && !nearestDesc.node)nearestDesc = nearestDesc.parent; - const nearestDescNode = nearestDesc.node; - if (nearestDesc && nearestDescNode.isAtom && _prosemirrorState.NodeSelection.isSelectable(nearestDescNode) && nearestDesc.parent && !(nearestDescNode.isInline && (0, _domJs.isOnEdge)(domSel.focusNode, domSel.focusOffset, nearestDesc.dom))) { - const pos = nearestDesc.posBefore; - selection = new _prosemirrorState.NodeSelection(head == pos ? $head : doc.resolve(pos)); - } - } else { - // @ts-expect-error Internal property - const anchor = view.docView.posFromDOM(// eslint-disable-next-line @typescript-eslint/no-non-null-assertion - domSel.anchorNode, domSel.anchorOffset, 1); - if (anchor < 0) return null; - $anchor = doc.resolve(anchor); - } - if (!selection) { - const bias = origin == "pointer" || view.state.selection.head < $head.pos && !inWidget ? 1 : -1; - selection = selectionBetween(view, $anchor, $head, bias); - } - return selection; -} diff --git a/dist/cjs/selection/selectionToDOM.js b/dist/cjs/selection/selectionToDOM.js deleted file mode 100644 index 3d4e68db..00000000 --- a/dist/cjs/selection/selectionToDOM.js +++ /dev/null @@ -1,211 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -function _export(target, all) { - for(var name in all)Object.defineProperty(target, name, { - enumerable: true, - get: all[name] - }); -} -_export(exports, { - isEquivalentPosition: ()=>isEquivalentPosition, - hasBlockDesc: ()=>hasBlockDesc, - domIndex: ()=>domIndex, - nodeSize: ()=>nodeSize, - syncNodeSelection: ()=>syncNodeSelection, - hasSelection: ()=>hasSelection, - selectionToDOM: ()=>selectionToDOM -}); -const _prosemirrorState = require("prosemirror-state"); -const _browserJs = require("../browser.js"); -const isEquivalentPosition = function(node, off, targetNode, targetOff) { - return targetNode && (scanFor(node, off, targetNode, targetOff, -1) || scanFor(node, off, targetNode, targetOff, 1)); -}; -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); -} -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))) { - const parent = node.parentNode; - if (!parent || 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) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - node = node.childNodes[off + (dir < 0 ? -1 : 0)]; - if (node.contentEditable == "false") return false; - off = dir < 0 ? nodeSize(node) : 0; - } else { - return false; - } - } -} -const domIndex = function(node) { - let n = node; - for(let index = 0;; index++){ - n = n.previousSibling; - if (!n) return index; - } -}; -function nodeSize(node) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length; -} -function syncNodeSelection(view, sel) { - const v = view; - if (sel instanceof _prosemirrorState.NodeSelection) { - const desc = v.docView.descAt(sel.from); - if (desc != v.lastSelectedViewDesc) { - clearNodeSelection(v); - if (desc) desc.selectNode(); - v.lastSelectedViewDesc = desc; - } - } else { - clearNodeSelection(v); - } -} -// Clear all DOM statefulness of the last node selection. -function clearNodeSelection(view) { - const v = view; - if (v.lastSelectedViewDesc) { - if (v.lastSelectedViewDesc.parent) v.lastSelectedViewDesc.deselectNode(); - v.lastSelectedViewDesc = undefined; - } -} -function hasSelection(view) { - const v = view; - const sel = v.domSelectionRange(); - 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 v.dom.contains(sel.anchorNode.nodeType == 3 ? sel.anchorNode.parentNode : sel.anchorNode) && (v.editable || v.dom.contains(// eslint-disable-next-line @typescript-eslint/no-non-null-assertion - sel.focusNode.nodeType == 3 ? sel.focusNode.parentNode : sel.focusNode)); - } catch (_) { - return false; - } -} -function editorOwnsSelection(view) { - return view.editable ? view.hasFocus() : hasSelection(view) && document.activeElement && document.activeElement.contains(view.dom); -} -function selectCursorWrapper(view) { - const v = view; - const domSel = v.domSelection(), range = document.createRange(); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const node = v.cursorWrapper.dom, img = node.nodeName == "IMG"; - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - 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 && !v.state.selection.visible && _browserJs.browser.ie && _browserJs.browser.ie_version <= 11) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - node.disabled = true; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - node.disabled = false; - } -} -function temporarilyEditableNear(view, pos) { - const v = view; - const { node , offset } = v.docView.domFromPos(pos, 0); - const after = offset < node.childNodes.length ? node.childNodes[offset] : null; - const before = offset ? node.childNodes[offset - 1] : null; - if (_browserJs.browser.safari && after && after.contentEditable == "false") return setEditable(after); - if ((!after || after.contentEditable == "false") && (!before || before.contentEditable == "false")) { - if (after) return setEditable(after); - else if (before) return setEditable(before); - } - return; -} -function setEditable(element) { - element.contentEditable = "true"; - if (_browserJs.browser.safari && element.draggable) { - element.draggable = false; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - element.wasDraggable = true; - } - return element; -} -function resetEditable(element) { - element.contentEditable = "false"; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - if (element.wasDraggable) { - element.draggable = true; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - element.wasDraggable = null; - } -} -function removeClassOnSelectionChange(view) { - const v = view; - const doc = v.dom.ownerDocument; - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - doc.removeEventListener("selectionchange", v.input.hideSelectionGuard); - const domSel = v.domSelectionRange(); - const node = domSel.anchorNode, offset = domSel.anchorOffset; - doc.addEventListener("selectionchange", v.input.hideSelectionGuard = ()=>{ - if (domSel.anchorNode != node || domSel.anchorOffset != offset) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - doc.removeEventListener("selectionchange", v.input.hideSelectionGuard); - setTimeout(()=>{ - if (!editorOwnsSelection(v) || v.state.selection.visible) v.dom.classList.remove("ProseMirror-hideselection"); - }, 20); - } - }); -} -const brokenSelectBetweenUneditable = _browserJs.browser.safari || _browserJs.browser.chrome && _browserJs.browser.chrome_version < 63; -function selectionToDOM(view) { - let force = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : false; - const v = view; - const sel = v.state.selection; - syncNodeSelection(v, sel); - if (!editorOwnsSelection(v)) return; - // The delayed drag selection causes issues with Cell Selections - // in Safari. And the drag selection delay is to workarond issues - // which only present in Chrome. - if (!force && v.input.mouseDown && v.input.mouseDown.allowDefault && _browserJs.browser.chrome) { - const domSel = v.domSelectionRange(), curSel = v.domObserver.currentSelection; - if (domSel.anchorNode && curSel.anchorNode && isEquivalentPosition(domSel.anchorNode, domSel.anchorOffset, curSel.anchorNode, curSel.anchorOffset)) { - v.input.mouseDown.delayedSelectionSync = true; - v.domObserver.setCurSelection(); - return; - } - } - v.domObserver.disconnectSelection(); - if (v.cursorWrapper) { - selectCursorWrapper(v); - } else { - const { anchor , head } = sel; - let resetEditableFrom; - let resetEditableTo; - if (brokenSelectBetweenUneditable && !(sel instanceof _prosemirrorState.TextSelection)) { - if (!sel.$from.parent.inlineContent) resetEditableFrom = temporarilyEditableNear(v, sel.from); - if (!sel.empty && !sel.$from.parent.inlineContent) resetEditableTo = temporarilyEditableNear(v, sel.to); - } - v.docView.setSelection(anchor, head, v.root, force); - if (brokenSelectBetweenUneditable) { - if (resetEditableFrom) resetEditable(resetEditableFrom); - if (resetEditableTo) resetEditable(resetEditableTo); - } - if (sel.visible) { - v.dom.classList.remove("ProseMirror-hideselection"); - } else { - v.dom.classList.add("ProseMirror-hideselection"); - if ("onselectionchange" in document) removeClassOnSelectionChange(v); - } - } - v.domObserver.setCurSelection(); - v.domObserver.connectSelection(); -} diff --git a/dist/cjs/testing/editorViewTestHelpers.js b/dist/cjs/testing/editorViewTestHelpers.js deleted file mode 100644 index cbd3bc99..00000000 --- a/dist/cjs/testing/editorViewTestHelpers.js +++ /dev/null @@ -1,114 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ "use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -function _export(target, all) { - for(var name in all)Object.defineProperty(target, name, { - enumerable: true, - get: all[name] - }); -} -_export(exports, { - tempEditor: ()=>tempEditor, - findTextNode: ()=>findTextNode -}); -const _globals = require("@jest/globals"); -const _react = require("@testing-library/react"); -const _prosemirrorModel = require("prosemirror-model"); -const _prosemirrorState = require("prosemirror-state"); -const _prosemirrorTestBuilder = require("prosemirror-test-builder"); -const _react1 = /*#__PURE__*/ _interopRequireDefault(require("react")); -const _proseMirrorJs = require("../components/ProseMirror.js"); -const _proseMirrorDocJs = require("../components/ProseMirrorDoc.js"); -const _useEditorEffectJs = require("../hooks/useEditorEffect.js"); -const _reactKeysJs = require("../plugins/reactKeys.js"); -function _extends() { - _extends = Object.assign || function(target) { - for(var i = 1; i < arguments.length; i++){ - var source = arguments[i]; - for(var key in source){ - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; - return _extends.apply(this, arguments); -} -function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { - default: obj - }; -} -const toEqualNode = function(actual, expected) { - if (!(actual instanceof _prosemirrorModel.Node && expected instanceof _prosemirrorModel.Node)) { - throw new Error("Must be comparing nodes"); - } - const pass = (0, _prosemirrorTestBuilder.eq)(actual, expected); - return { - message: ()=>// `this` context will have correct typings - `expected ${this.utils.printReceived(actual)} ${pass ? "not " : ""}to equal ${this.utils.printExpected(expected)}`, - pass - }; -}; -_globals.expect.extend({ - toEqualNode -}); -function tempEditor(param) { - let { doc: startDoc , selection , plugins , state: stateProp , ...props } = param; - startDoc = startDoc ?? (0, _prosemirrorTestBuilder.doc)(); - const state = stateProp ?? _prosemirrorState.EditorState.create({ - doc: startDoc, - schema: _prosemirrorTestBuilder.schema, - selection: selection ?? startDoc.tag?.a ? _prosemirrorState.TextSelection.create(startDoc, startDoc.tag.a, startDoc.tag?.b) : undefined, - plugins: [ - ...plugins ?? [], - (0, _reactKeysJs.reactKeys)() - ] - }); - let view; - function Test() { - (0, _useEditorEffectJs.useEditorEffect)((v)=>{ - view = v; - }); - return null; - } - const { rerender , unmount } = (0, _react.render)(/*#__PURE__*/ _react1.default.createElement(_proseMirrorJs.ProseMirror, _extends({}, stateProp ? { - state: stateProp - } : { - defaultState: state - }, props), /*#__PURE__*/ _react1.default.createElement(Test, null), /*#__PURE__*/ _react1.default.createElement(_proseMirrorDocJs.ProseMirrorDoc, null))); - function rerenderEditor(param) { - let { state: newStateProp , ...newProps } = param; - rerender(/*#__PURE__*/ _react1.default.createElement(_proseMirrorJs.ProseMirror, _extends({}, newStateProp && stateProp ? { - state: newStateProp - } : { - defaultState: state - }, { - ...props, - ...newProps - }), /*#__PURE__*/ _react1.default.createElement(Test, null), /*#__PURE__*/ _react1.default.createElement(_proseMirrorDocJs.ProseMirrorDoc, null))); - } - return { - rerender: rerenderEditor, - unmount, - view - }; -} -function findTextNodeInner(node, text) { - if (node.nodeType == 3) { - if (node.nodeValue == text) return node; - } else if (node.nodeType == 1) { - for(let ch = node.firstChild; ch; ch = ch.nextSibling){ - const found = findTextNodeInner(ch, text); - if (found) return found; - } - } - return undefined; -} -function findTextNode(node, text) { - const found = findTextNodeInner(node, text); - if (found) return found; - throw new Error("Unable to find matching text node"); -} diff --git a/dist/cjs/testing/setupProseMirrorView.js b/dist/cjs/testing/setupProseMirrorView.js deleted file mode 100644 index 2d645ef6..00000000 --- a/dist/cjs/testing/setupProseMirrorView.js +++ /dev/null @@ -1,90 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -function _export(target, all) { - for(var name in all)Object.defineProperty(target, name, { - enumerable: true, - get: all[name] - }); -} -_export(exports, { - setupProseMirrorView: ()=>setupProseMirrorView, - teardownProseMirrorView: ()=>teardownProseMirrorView -}); -let oldElementFromPoint; -let oldGetClientRects; -let oldGetBoundingClientRect; -const mockElementFromPoint = ()=>globalThis.document.body; -const mockGetBoundingClientRect = ()=>{ - return { - bottom: 0, - height: 0, - left: 0, - right: 0, - top: 0, - width: 0, - x: 0, - y: 0, - toJSON () { - return { - bottom: 0, - height: 0, - left: 0, - right: 0, - top: 0, - width: 0, - x: 0, - y: 0 - }; - } - }; -}; -const mockGetClientRects = ()=>{ - const list = [ - { - bottom: 0, - height: 0, - left: 0, - right: 0, - top: 0, - width: 0, - x: 0, - y: 0, - toJSON () { - return { - bottom: 0, - height: 0, - left: 0, - right: 0, - top: 0, - width: 0, - x: 0, - y: 0 - }; - } - } - ]; - const domRectList = Object.assign(list, { - item (index) { - return list[index] ?? null; - } - }); - return domRectList; -}; -function setupProseMirrorView() { - oldElementFromPoint = Document.prototype.elementFromPoint; - Document.prototype.elementFromPoint = mockElementFromPoint; - oldGetClientRects = Range.prototype.getClientRects; - Range.prototype.getClientRects = mockGetClientRects; - oldGetBoundingClientRect = Range.prototype.getBoundingClientRect; - Range.prototype.getBoundingClientRect = mockGetBoundingClientRect; -} -function teardownProseMirrorView() { - // @ts-expect-error jsdom actually doesn't implement these, so they might be undefined - Document.prototype.elementFromPoint = oldElementFromPoint; - // @ts-expect-error jsdom actually doesn't implement these, so they might be undefined - Range.prototype.getClientRects = oldGetClientRects; - // @ts-expect-error jsdom actually doesn't implement these, so they might be undefined - Range.prototype.getBoundingClientRect = oldGetBoundingClientRect; -} diff --git a/dist/cjs/viewdesc.js b/dist/cjs/viewdesc.js deleted file mode 100644 index 3c6aa5f9..00000000 --- a/dist/cjs/viewdesc.js +++ /dev/null @@ -1,649 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-non-null-assertion */ "use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -function _export(target, all) { - for(var name in all)Object.defineProperty(target, name, { - enumerable: true, - get: all[name] - }); -} -_export(exports, { - ViewDesc: ()=>ViewDesc, - WidgetViewDesc: ()=>WidgetViewDesc, - CompositionViewDesc: ()=>CompositionViewDesc, - MarkViewDesc: ()=>MarkViewDesc, - NodeViewDesc: ()=>NodeViewDesc, - TextViewDesc: ()=>TextViewDesc, - TrailingHackViewDesc: ()=>TrailingHackViewDesc -}); -const _prosemirrorModel = require("prosemirror-model"); -const _browserJs = require("./browser.js"); -const _selectionToDOMJs = require("./selection/selectionToDOM.js"); -// 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; -let ViewDesc = class ViewDesc { - // Used to check whether a given description corresponds to a - // widget/mark/node. - matchesWidget(_widget) { - return false; - } - matchesMark(_mark) { - return false; - } - matchesNode(_node, _outerDeco, _innerDeco) { - return false; - } - // @ts-expect-error ... - matchesHack(nodeName) { - return false; - } - // 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; - } - // Used by the editor's event handler to ignore events that come - // from certain descs. - // @ts-expect-error ... - stopEvent(event) { - 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++)// @ts-expect-error ... - 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() { - // pass - } - posBeforeChild(child) { - for(let i = 0, pos = this.posAtStart;; i++){ - const cur = this.children[i]; - if (cur == child) return pos; - // @ts-expect-error ... - 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; - } - 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 (dom == this.dom && this.contentDOM) { - atEnd = offset > (0, _selectionToDOMJs.domIndex)(this.contentDOM); - } else 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.previousSibling) break; - } - if (atEnd == null && offset == dom.childNodes.length) for(let search = dom;; search = search.parentNode){ - if (search == this.dom) { - atEnd = true; - break; - } - if (search.nextSibling) break; - } - } - return (atEnd == null ? bias > 0 : atEnd) ? this.posAtEnd : this.posAtStart; - } - nearestDesc(dom) { - let onlyNodes = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : false; - for(let first = true, cur = dom; cur; cur = cur.parentNode){ - const desc = this.getDesc(cur); - let nodeDOM; - if (desc && (!onlyNodes || desc.node)) { - // If dom is outside of this desc's nodeDOM, don't count it. - if (first && (nodeDOM = desc.nodeDOM) && !(nodeDOM.nodeType == 1 ? nodeDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode) : nodeDOM == dom)) first = false; - else return desc; - } - } - return; - } - getDesc(dom) { - const desc = dom.pmViewDesc; - for(let cur = desc; cur; cur = cur.parent)if (cur == this) return desc; - return; - } - posFromDOM(dom, offset, bias) { - for(let scan = dom; scan; scan = scan.parentNode){ - const desc = this.getDesc(scan); - if (desc) return desc.localPosFromDOM(dom, offset, bias); - } - return -1; - } - // 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]; - const 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; - } - return; - } - domFromPos(pos, side) { - if (!this.contentDOM) return { - node: this.dom, - offset: 0, - atom: pos + 1 - }; - // First find the position in the child array - let i = 0, offset = 0; - for(let curPos = 0; i < this.children.length; i++){ - const child = this.children[i], end = curPos + child.size; - if (end > pos || child instanceof TrailingHackViewDesc) { - offset = pos - curPos; - break; - } - curPos = end; - } - // If this points into the middle of a child, call through - if (offset) return this.children[i].domFromPos(offset - this.children[i].border, side); - // Go back if there were any zero-length widgets with side >= 0 before this point - for(let prev; i && !(prev = this.children[i - 1]).size && prev instanceof WidgetViewDesc && prev.side >= 0; i--){ - // ... - } - // Scan towards the first useable node - if (side <= 0) { - let prev, enter = true; - for(;; i--, enter = false){ - prev = i ? this.children[i - 1] : null; - if (!prev || prev.dom.parentNode == this.contentDOM) break; - } - if (prev && side && enter && !prev.border && !prev.domAtom) return prev.domFromPos(prev.size, side); - return { - node: this.contentDOM, - offset: prev ? (0, _selectionToDOMJs.domIndex)(prev.dom) + 1 : 0 - }; - } else { - let next, enter = true; - for(;; i++, enter = false){ - next = i < this.children.length ? this.children[i] : null; - if (!next || next.dom.parentNode == this.contentDOM) break; - } - if (next && enter && !next.border && !next.domAtom) return next.domFromPos(0, side); - return { - node: this.contentDOM, - offset: next ? (0, _selectionToDOMJs.domIndex)(next.dom) : this.contentDOM.childNodes.length - }; - } - } - // Used to find a DOM range in a single parent for a given changed - // range. - parseRange(from, to) { - let base = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : 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++){ - const child = this.children[i], end = offset + child.size; - if (fromOffset == -1 && from <= end) { - const 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--){ - const prev = this.children[j - 1]; - if (prev.size && prev.dom.parentNode == this.contentDOM && !prev.emptyChildAt(1)) { - fromOffset = (0, _selectionToDOMJs.domIndex)(prev.dom) + 1; - break; - } - from -= prev.size; - } - if (fromOffset == -1) fromOffset = 0; - } - if (fromOffset > -1 && (end > to || i == this.children.length - 1)) { - to = end; - for(let j = i + 1; j < this.children.length; j++){ - const next = this.children[j]; - if (next.size && next.dom.parentNode == this.contentDOM && !next.emptyChildAt(-1)) { - toOffset = (0, _selectionToDOMJs.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; - const child = this.children[side < 0 ? 0 : this.children.length - 1]; - // @ts-expect-error ... - return child.size == 0 || child.emptyChildAt(side); - } - domAfterPos(pos) { - const { node , offset } = this.domFromPos(pos, 0); - if (node.nodeType != 1 || offset == node.childNodes.length) throw new RangeError("No node after pos " + pos); - // @ts-expect-error ... - return node.childNodes[offset]; - } - // 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) { - let force = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : false; - // If the selection falls entirely in a child, give it to that child - const from = Math.min(anchor, head), to = Math.max(anchor, head); - for(let i = 0, offset = 0; i < this.children.length; i++){ - const 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, anchor ? -1 : 1); - let headDOM = head == anchor ? anchorDOM : this.domFromPos(head, head ? -1 : 1); - const domSel = root.getSelection(); - let brKludge = false; - // On Firefox, using Selection.collapse to put the cursor after a - // BR node for some reason doesn't always work (#1073). On Safari, - // the cursor sometimes inexplicable visually lags behind its - // reported position in such situations (#1092). - if ((_browserJs.browser.gecko || _browserJs.browser.safari) && anchor == head) { - const { node , offset } = anchorDOM; - if (node.nodeType == 3) { - brKludge = !!(offset && node.nodeValue?.[offset - 1] == "\n"); - // Issue #1128 - if (brKludge && offset == node.nodeValue.length) { - for(let scan = node, after; scan; scan = scan.parentNode){ - if (after = scan.nextSibling) { - if (after.nodeName == "BR") anchorDOM = headDOM = { - node: after.parentNode, - offset: (0, _selectionToDOMJs.domIndex)(after) + 1 - }; - break; - } - const desc = scan.pmViewDesc; - if (desc && desc.node && desc.node.isBlock) break; - } - } - } else { - const prev = node.childNodes[offset - 1]; - // @ts-expect-error ... - brKludge = prev && (prev.nodeName == "BR" || prev.contentEditable == "false"); - } - } - // Firefox can act strangely when the selection is in front of an - // uneditable node. See #1163 and https://bugzilla.mozilla.org/show_bug.cgi?id=1709536 - if (_browserJs.browser.gecko && domSel.focusNode && domSel.focusNode != headDOM.node && domSel.focusNode.nodeType == 1) { - const after = domSel.focusNode.childNodes[domSel.focusOffset]; - if (after && after.contentEditable == "false") force = true; - } - if (!(force || brKludge && _browserJs.browser.safari) && (0, _selectionToDOMJs.isEquivalentPosition)(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset) && (0, _selectionToDOMJs.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. - let domSelExtended = false; - if ((domSel.extend || anchor == head) && !brKludge) { - domSel.collapse(anchorDOM.node, anchorDOM.offset); - try { - if (anchor != head) domSel.extend(headDOM.node, headDOM.offset); - domSelExtended = true; - } catch (_) { - // In some cases with Chrome the selection is empty after calling - // collapse, even when it should be valid. This appears to be a bug, but - // it is difficult to isolate. If this happens fallback to the old path - // without using extend. - // Similarly, this could crash on Safari if the editor is hidden, and - // there was no selection. - } - } - if (!domSelExtended) { - if (anchor > head) { - const tmp = anchorDOM; - anchorDOM = headDOM; - headDOM = tmp; - } - const range = document.createRange(); - range.setEnd(headDOM.node, headDOM.offset); - range.setStart(anchorDOM.node, anchorDOM.offset); - domSel.removeAllRanges(); - domSel.addRange(range); - } - } - ignoreMutation(mutation) { - return !this.contentDOM && mutation.type != "selection"; - } - 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++){ - const child = this.children[i], end = offset + child.size; - if (offset == end ? from <= end && to >= offset : from < end && to > offset) { - const 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 = child.dom == child.contentDOM && child.dom.parentNode == this.contentDOM && !child.children.length ? CONTENT_DIRTY : NODE_DIRTY; - } - } - offset = end; - } - this.dirty = CONTENT_DIRTY; - } - markParentsDirty() { - let level = 1; - for(let node = this.parent; node; node = node.parent, level++){ - const dirty = level == 1 ? CONTENT_DIRTY : CHILD_DIRTY; - if (node.dirty < dirty) node.dirty = dirty; - } - } - get domAtom() { - return false; - } - get ignoreForCoords() { - return false; - } - constructor(parent, children, dom, contentDOM){ - this.parent = parent; - this.children = children; - this.dom = dom; - this.contentDOM = contentDOM; - this.dirty = NOT_DIRTY; - // An expando property on the DOM node provides a link back to its - // description. - // @ts-expect-error We're using custom view implementations here but - // we match the API so this is relatively safe. - dom.pmViewDesc = this; - } -}; -let WidgetViewDesc = class WidgetViewDesc extends ViewDesc { - matchesWidget(widget) { - return this.dirty == NOT_DIRTY && widget.type.eq(this.widget.type); - } - parseRule() { - return { - ignore: true - }; - } - stopEvent(event) { - const stop = this.widget.spec.stopEvent; - return stop ? stop(event) : false; - } - ignoreMutation(mutation) { - return mutation.type != "selection" || this.widget.spec.ignoreSelection; - } - get domAtom() { - return true; - } - get side() { - return this.widget.type.side; - } - constructor(parent, widget, dom){ - super(parent, [], dom, null); - this.widget = widget; - this.widget = widget; - } -}; -let CompositionViewDesc = class CompositionViewDesc extends ViewDesc { - 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; - } - constructor(parent, dom, textDOM, text){ - super(parent, [], dom, null); - this.textDOM = textDOM; - this.text = text; - } -}; -let MarkViewDesc = class MarkViewDesc extends ViewDesc { - parseRule() { - if (this.dirty & NODE_DIRTY || this.mark.type.spec.reparseInView) return null; - 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; - } - } - constructor(parent, children, mark, dom, contentDOM){ - super(parent, children, dom, contentDOM); - this.mark = mark; - } -}; -let NodeViewDesc = class NodeViewDesc extends ViewDesc { - updateOuterDeco() { - // pass - } - 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 - const rule = { - node: this.node.type.name, - attrs: this.node.attrs - }; - if (this.node.type.whitespace == "pre") rule.preserveWhitespace = "full"; - if (!this.contentDOM) { - rule.getContent = ()=>this.node.content; - } else if (!this.contentLost) { - rule.contentElement = this.contentDOM; - } else { - // Chrome likes to randomly recreate parent nodes when - // backspacing things. When that happens, this tries to find the - // new parent. - for(let i = this.children.length - 1; i >= 0; i--){ - const child = this.children[i]; - // @ts-expect-error ... - if (this.dom.contains(child.dom.parentNode)) { - // @ts-expect-error ... - rule.contentElement = child.dom.parentNode; - break; - } - } - if (!rule.contentElement) rule.getContent = ()=>_prosemirrorModel.Fragment.empty; - } - 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; - } - // If this desc must be updated to match the given node decoration, - // do so and return true. - update(_node, _outerDeco, _innerDeco, _view) { - return true; - } - // Mark this node as being the selected node. - selectNode() { - if (this.nodeDOM.nodeType == 1) 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() { - if (this.nodeDOM.nodeType == 1) this.nodeDOM.classList.remove("ProseMirror-selectednode"); - if (this.contentDOM || !this.node.type.spec.draggable) this.dom.removeAttribute("draggable"); - } - get domAtom() { - return this.node.isAtom; - } - constructor(parent, children, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM){ - super(parent, children, dom, contentDOM); - this.node = node; - this.outerDeco = outerDeco; - this.innerDeco = innerDeco; - this.nodeDOM = nodeDOM; - } -}; -let TextViewDesc = class TextViewDesc extends NodeViewDesc { - parseRule() { - let skip = this.nodeDOM.parentNode; - while(skip && skip != this.dom && !skip.pmIsDeco)skip = skip.parentNode; - return { - skip: skip || true - }; - } - update(_node, _outerDeco, _innerDeco, _view) { - return true; - } - inParent() { - const 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"; - } - markDirty(from, to) { - super.markDirty(from, to); - if (this.dom != this.nodeDOM && (from == 0 || to == this.nodeDOM.nodeValue.length)) this.dirty = NODE_DIRTY; - } - get domAtom() { - return false; - } - constructor(parent, children, node, outerDeco, innerDeco, dom, nodeDOM){ - super(parent, children, node, outerDeco, innerDeco, dom, null, nodeDOM); - } -}; -let TrailingHackViewDesc = class TrailingHackViewDesc extends ViewDesc { - parseRule() { - return { - ignore: true - }; - } - matchesHack(nodeName) { - return this.dirty == NOT_DIRTY && this.dom.nodeName == nodeName; - } - get domAtom() { - return true; - } - get ignoreForCoords() { - return this.dom.nodeName == "IMG"; - } -}; -function sameOuterDeco(a, b) { - if (a.length != b.length) return false; - // @ts-expect-error ... - for(let i = 0; i < a.length; i++)if (!a[i].type.eq(b[i].type)) return false; - return true; -} diff --git a/dist/esm/browser.js b/dist/esm/browser.js deleted file mode 100644 index 2bf09d4a..00000000 --- a/dist/esm/browser.js +++ /dev/null @@ -1,43 +0,0 @@ -const nav = typeof navigator != "undefined" ? navigator : null; -const doc = typeof document != "undefined" ? document : null; -const agent = nav && nav.userAgent || ""; -const ie_edge = /Edge\/(\d+)/.exec(agent); -const ie_upto10 = /MSIE \d/.exec(agent); -const ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(agent); -const ie = !!(ie_upto10 || ie_11up || ie_edge); -const ie_version = ie_upto10 ? document.documentMode : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : 0; -const gecko = !ie && /gecko\/(\d+)/i.test(agent); -const gecko_version = gecko && +(/Firefox\/(\d+)/.exec(agent) || [ - 0, - 0 -])[1]; -const _chrome = !ie && /Chrome\/(\d+)/.exec(agent); -const chrome = !!_chrome; -// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -const chrome_version = _chrome ? +_chrome[1] : 0; -const safari = !ie && !!nav && /Apple Computer/.test(nav.vendor); -// Is true for both iOS and iPadOS for convenience -const ios = safari && (/Mobile\/\w+/.test(agent) || !!nav && nav.maxTouchPoints > 2); -const mac = ios || (nav ? /Mac/.test(nav.platform) : false); -const windows = nav ? /Win/.test(nav.platform) : false; -const android = /Android \d/.test(agent); -const webkit = !!doc && "webkitFontSmoothing" in doc.documentElement.style; -const webkit_version = webkit ? +(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent) || [ - 0, - 0 -])[1] : 0; -export const browser = { - ie, - ie_version, - gecko, - gecko_version, - chrome, - chrome_version, - safari, - ios, - mac, - windows, - android, - webkit, - webkit_version -}; diff --git a/dist/esm/components/ChildNodeViews.js b/dist/esm/components/ChildNodeViews.js deleted file mode 100644 index 3fd0ce29..00000000 --- a/dist/esm/components/ChildNodeViews.js +++ /dev/null @@ -1,267 +0,0 @@ -import classnames from "classnames/dedupe"; -import React, { cloneElement, createElement, useContext } from "react"; -import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js"; -import { EditorContext } from "../contexts/EditorContext.js"; -import { iterDeco } from "../decorations/iterDeco.js"; -import { useEditorState } from "../hooks/useEditorState.js"; -import { useReactKeys } from "../hooks/useReactKeys.js"; -import { MarkView } from "./MarkView.js"; -import { NativeWidgetView } from "./NativeWidgetView.js"; -import { NodeView } from "./NodeView.js"; -import { SeparatorHackView } from "./SeparatorHackView.js"; -import { TextNodeView } from "./TextNodeView.js"; -import { TrailingHackView } from "./TrailingHackView.js"; -import { WidgetView } from "./WidgetView.js"; -function cssToStyles(css) { - const cssJson = `{"${css.replace(/;? *$/, "").replace(/;+ */g, '","').replace(/: */g, '":"')}"}`; - const obj = JSON.parse(cssJson); - return Object.keys(obj).reduce((acc, key)=>{ - const camelCased = key.startsWith("--") ? key : key.replace(/-[a-z]/g, (g)=>g[1]?.toUpperCase() ?? ""); - return { - ...acc, - [camelCased]: obj[key] - }; - }, {}); -} -export function wrapInDeco(reactNode, deco) { - const { nodeName , class: className , style: css , contenteditable: contentEditable , spellcheck: spellCheck , ...attrs } = deco.type.attrs; - // We auto-wrap text nodes in spans so that we can apply attributes - // and styles, but we want to avoid double-wrapping the same - // text node - if (nodeName || typeof reactNode === "string") { - return /*#__PURE__*/ createElement(nodeName ?? "span", { - className, - contentEditable, - spellCheck, - style: css && cssToStyles(css), - ...attrs - }, reactNode); - } - return /*#__PURE__*/ cloneElement(reactNode, { - className: classnames(reactNode.props.className, className), - contentEditable, - spellCheck, - style: { - ...reactNode.props.style, - ...css && cssToStyles(css) - }, - ...attrs - }); -} -function InlineView(param) { - let { innerPos , childViews } = param; - const { view } = useContext(EditorContext); - const editorState = useEditorState(); - const reactKeys = useReactKeys(); - const partitioned = childViews.reduce((acc, child)=>{ - const lastPartition = acc[acc.length - 1]; - if (!lastPartition) { - return [ - [ - child - ] - ]; - } - const lastChild = lastPartition[lastPartition.length - 1]; - if (!lastChild) { - return [ - ...acc.slice(0, acc.length), - [ - child - ] - ]; - } - if (!child.marks.length && !lastChild.marks.length || child.marks.length && lastChild.marks.length && // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - child.marks[0]?.eq(lastChild.marks[0])) { - return [ - ...acc.slice(0, acc.length - 1), - [ - ...lastPartition.slice(0, lastPartition.length), - child - ] - ]; - } - return [ - ...acc, - [ - child - ] - ]; - }, []); - return /*#__PURE__*/ React.createElement(React.Fragment, null, partitioned.map((childViews)=>{ - const firstChild = childViews[0]; - if (!firstChild) return null; - const firstMark = firstChild.marks[0]; - if (!firstMark) { - return childViews.map((child)=>{ - const childPos = innerPos + child.offset; - const childElement = child.type === "widget" ? /*#__PURE__*/ React.createElement(WidgetView, { - widget: child.widget, - pos: childPos - }) : child.type === "native-widget" ? /*#__PURE__*/ React.createElement(NativeWidgetView, { - widget: child.widget, - pos: childPos - }) : child.node.isText ? /*#__PURE__*/ React.createElement(ChildDescriptorsContext.Consumer, null, (siblingDescriptors)=>/*#__PURE__*/ React.createElement(TextNodeView, { - view: view, - node: child.node, - pos: childPos, - siblingDescriptors: siblingDescriptors, - decorations: child.outerDeco - })) : /*#__PURE__*/ React.createElement(NodeView, { - node: child.node, - pos: childPos, - outerDeco: child.outerDeco, - innerDeco: child.innerDeco - }); - return /*#__PURE__*/ cloneElement(childElement, { - key: createKey(editorState?.doc, innerPos, child, reactKeys?.posToKey) - }); - }); - } - return /*#__PURE__*/ React.createElement(MarkView, { - key: createKey(editorState?.doc, innerPos, firstChild, reactKeys?.posToKey), - mark: firstMark - }, /*#__PURE__*/ React.createElement(InlineView, { - key: createKey(editorState?.doc, innerPos, firstChild, reactKeys?.posToKey), - innerPos: innerPos, - childViews: childViews.map((child)=>({ - ...child, - marks: child.marks.slice(1) - })) - })); - })); -} -function createKey(doc, innerPos, child, posToKey) { - const pos = innerPos + child.offset; - const key = posToKey?.get(pos); - if (child.type === "widget" || child.type === "native-widget") { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - if (child.widget.type.spec.key) // eslint-disable-next-line @typescript-eslint/no-explicit-any - return child.widget.type.spec.key; - // eslint-disable-next-line no-console - console.warn(`Widget at position ${pos} doesn't have a key specified. This has negative performance implications.`); - return `${key}-${child.index}`; - } - if (key) return key; - if (!doc) return pos; - const parentPos = doc.resolve(pos).start() - 1; - const parentKey = posToKey?.get(parentPos); - if (parentKey) return `${parentKey}-${child.offset}`; - return pos; -} -function adjustWidgetMarksForward(children) { - const lastChild = children[children.length - 1]; - if (lastChild?.type !== "widget" && lastChild?.type !== "native-widget" || // Using internal Decoration property, "type" - // eslint-disable-next-line @typescript-eslint/no-explicit-any - lastChild.widget.type.side >= 0) return; - let lastNodeChild = null; - for(let i = children.length - 2; i >= 0; i--){ - const child = children[i]; - if (child?.type === "node") { - lastNodeChild = child; - break; - } - } - if (!lastNodeChild || !lastNodeChild.node.isInline) return; - const marksToSpread = lastNodeChild.marks; - lastChild.marks = lastChild.marks.reduce((acc, mark)=>mark.addToSet(acc), marksToSpread); -} -function adjustWidgetMarksBack(children) { - const lastChild = children[children.length - 1]; - if (lastChild?.type !== "node" || !lastChild.node.isInline) return; - const marksToSpread = lastChild.marks; - for(let i = children.length - 2; i >= 0; i--){ - const child = children[i]; - if (child?.type !== "widget" && child?.type !== "native-widget" || // Using internal Decoration property, "type" - // eslint-disable-next-line @typescript-eslint/no-explicit-any - child.widget.type.side < 0) break; - child.marks = child.marks.reduce((acc, mark)=>mark.addToSet(acc), marksToSpread); - } -} -function createChildElements(children, innerPos, doc, posToKey) { - if (!children.length) return []; - if (children.every((child)=>child.type !== "node" || child.node.isInline)) { - return [ - /*#__PURE__*/ React.createElement(InlineView, { - key: createKey(doc, innerPos, // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - children[0], posToKey), - childViews: children, - innerPos: innerPos - }) - ]; - } - return children.map((child)=>{ - if (child.type === "node") { - const pos = innerPos + child.offset; - const key = posToKey?.get(pos) ?? pos; - return /*#__PURE__*/ React.createElement(NodeView, { - key: key, - outerDeco: child.outerDeco, - node: child.node, - innerDeco: child.innerDeco, - pos: pos - }); - } else { - return /*#__PURE__*/ React.createElement(InlineView, { - key: createKey(doc, innerPos, // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - child, posToKey), - childViews: [ - child - ], - innerPos: innerPos - }); - } - }); -} -export function ChildNodeViews(param) { - let { pos , node , innerDecorations } = param; - const editorState = useEditorState(); - const reactKeys = useReactKeys(); - if (!node) return null; - const innerPos = pos + 1; - const children = []; - iterDeco(node, innerDecorations, (widget, isNative, offset, index)=>{ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const widgetMarks = widget.type.spec.marks ?? []; - if (isNative) { - children.push({ - type: "native-widget", - widget: widget, - marks: widgetMarks, - offset, - index - }); - } else { - children.push({ - type: "widget", - widget: widget, - marks: widgetMarks, - offset, - index - }); - } - adjustWidgetMarksForward(children); - }, (childNode, outerDeco, innerDeco, offset)=>{ - children.push({ - type: "node", - node: childNode, - marks: childNode.marks, - innerDeco, - outerDeco, - offset - }); - adjustWidgetMarksBack(children); - }); - const childElements = createChildElements(children, innerPos, editorState?.doc, reactKeys?.posToKey); - const lastChild = children[children.length - 1]; - if (!lastChild || lastChild.type !== "node" || lastChild.node.isInline && !lastChild.node.isText || // RegExp.test actually handles undefined just fine - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - /\n$/.test(lastChild.node.text)) { - childElements.push(/*#__PURE__*/ React.createElement(SeparatorHackView, { - key: "trailing-hack-img" - }), /*#__PURE__*/ React.createElement(TrailingHackView, { - key: "trailing-hack-br" - })); - } - return /*#__PURE__*/ React.createElement(React.Fragment, null, childElements); -} diff --git a/dist/esm/components/CursorWrapper.js b/dist/esm/components/CursorWrapper.js deleted file mode 100644 index 80922669..00000000 --- a/dist/esm/components/CursorWrapper.js +++ /dev/null @@ -1,53 +0,0 @@ -function _extends() { - _extends = Object.assign || function(target) { - for(var i = 1; i < arguments.length; i++){ - var source = arguments[i]; - for(var key in source){ - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; - return _extends.apply(this, arguments); -} -import React, { forwardRef, useImperativeHandle, useRef, useState } from "react"; -import { domIndex } from "../dom.js"; -import { useEditorEffect } from "../hooks/useEditorEffect.js"; -export const CursorWrapper = /*#__PURE__*/ forwardRef(function CursorWrapper(param, ref) { - let { widget , pos , ...props } = param; - const [shouldRender, setShouldRender] = useState(true); - const innerRef = useRef(null); - useImperativeHandle(ref, ()=>{ - return innerRef.current; - }, []); - useEditorEffect((view)=>{ - if (!view || !innerRef.current) return; - // @ts-expect-error Internal property - domObserver - view.domObserver.disconnectSelection(); - // @ts-expect-error Internal property - domSelection - const domSel = view.domSelection(); - const range = document.createRange(); - const node = innerRef.current; - const img = node.nodeName == "IMG"; - if (img && node.parentNode) { - range.setEnd(node.parentNode, domIndex(node) + 1); - } else { - range.setEnd(node, 0); - } - range.collapse(false); - domSel.removeAllRanges(); - domSel.addRange(range); - setShouldRender(false); - // @ts-expect-error Internal property - domObserver - view.domObserver.connectSelection(); - }, []); - return shouldRender ? /*#__PURE__*/ React.createElement("img", _extends({ - ref: innerRef, - className: "ProseMirror-separator", - // eslint-disable-next-line react/no-unknown-property - "mark-placeholder": "true", - alt: "" - }, props)) : null; -}); diff --git a/dist/esm/components/DocNodeView.js b/dist/esm/components/DocNodeView.js deleted file mode 100644 index b74441c5..00000000 --- a/dist/esm/components/DocNodeView.js +++ /dev/null @@ -1,40 +0,0 @@ -// TODO: I must be missing something, but I do not know why -// this linting rule is only broken in this file -/* eslint-disable react/prop-types */ import React, { cloneElement, createElement, forwardRef, useImperativeHandle, useRef } from "react"; -import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js"; -import { useNodeViewDescriptor } from "../hooks/useNodeViewDescriptor.js"; -import { ChildNodeViews, wrapInDeco } from "./ChildNodeViews.js"; -export const DocNodeView = /*#__PURE__*/ forwardRef(function DocNodeView(param, ref) { - let { className , node , innerDeco , outerDeco , as , viewDesc } = param; - const innerRef = useRef(null); - useImperativeHandle(ref, ()=>{ - return innerRef.current; - }, []); - const childDescriptors = useNodeViewDescriptor(node, innerRef, innerRef, innerDeco, outerDeco, viewDesc); - const props = { - ref: innerRef, - className, - suppressContentEditableWarning: true - }; - const element = as ? /*#__PURE__*/ cloneElement(as, props, /*#__PURE__*/ React.createElement(ChildDescriptorsContext.Provider, { - value: childDescriptors - }, /*#__PURE__*/ React.createElement(ChildNodeViews, { - pos: -1, - node: node, - innerDecorations: innerDeco - }))) : /*#__PURE__*/ createElement("div", props, /*#__PURE__*/ React.createElement(ChildDescriptorsContext.Provider, { - value: childDescriptors - }, /*#__PURE__*/ React.createElement(ChildNodeViews, { - pos: -1, - node: node, - innerDecorations: innerDeco - }))); - if (!node) return element; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const nodeDecorations = outerDeco.filter((deco)=>!deco.inline); - if (!nodeDecorations.length) { - return element; - } - const wrapped = nodeDecorations.reduce(wrapInDeco, element); - return wrapped; -}); diff --git a/dist/esm/components/LayoutGroup.js b/dist/esm/components/LayoutGroup.js deleted file mode 100644 index ef7307a1..00000000 --- a/dist/esm/components/LayoutGroup.js +++ /dev/null @@ -1,66 +0,0 @@ -import React, { useCallback, useLayoutEffect, useRef } from "react"; -import { LayoutGroupContext } from "../contexts/LayoutGroupContext.js"; -import { useForceUpdate } from "../hooks/useForceUpdate.js"; -/** - * Provides a boundary for grouping layout effects. - * - * Descendant components can invoke the `useLayoutGroupEffect` hook to register - * effects that run after all descendants within the group have processed their - * regular layout effects. - */ export function LayoutGroup(param) { - let { children } = param; - const createQueue = useRef(new Set()).current; - const destroyQueue = useRef(new Set()).current; - const isMounted = useRef(false); - const forceUpdate = useForceUpdate(); - const isUpdatePending = useRef(true); - const ensureFlush = useCallback(()=>{ - if (!isUpdatePending.current) { - forceUpdate(); - isUpdatePending.current = true; - } - }, [ - forceUpdate - ]); - const register = useCallback((effect)=>{ - let destroy; - const create = ()=>{ - destroy = effect(); - }; - createQueue.add(create); - ensureFlush(); - return ()=>{ - createQueue.delete(create); - if (destroy) { - if (isMounted.current) { - destroyQueue.add(destroy); - ensureFlush(); - } else { - destroy(); - } - } - }; - }, [ - createQueue, - destroyQueue, - ensureFlush - ]); - useLayoutEffect(()=>{ - isUpdatePending.current = false; - createQueue.forEach((create)=>create()); - createQueue.clear(); - return ()=>{ - destroyQueue.forEach((destroy)=>destroy()); - destroyQueue.clear(); - }; - }); - useLayoutEffect(()=>{ - isMounted.current = true; - return ()=>{ - isMounted.current = false; - }; - }, []); - return /*#__PURE__*/ React.createElement(LayoutGroupContext.Provider, { - value: register - }, children); -} diff --git a/dist/esm/components/MarkView.js b/dist/esm/components/MarkView.js deleted file mode 100644 index 36dead8d..00000000 --- a/dist/esm/components/MarkView.js +++ /dev/null @@ -1,30 +0,0 @@ -import React, { forwardRef, useContext, useImperativeHandle, useLayoutEffect, useRef } from "react"; -import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js"; -import { MarkViewDesc } from "../viewdesc.js"; -import { OutputSpec } from "./OutputSpec.js"; -export const MarkView = /*#__PURE__*/ forwardRef(function MarkView(param, ref) { - let { mark , children } = param; - const siblingDescriptors = useContext(ChildDescriptorsContext); - const childDescriptors = []; - const domRef = useRef(null); - useImperativeHandle(ref, ()=>{ - return domRef.current; - }, []); - const outputSpec = mark.type.spec.toDOM?.(mark, true); - if (!outputSpec) throw new Error(`Mark spec for ${mark.type.name} is missing toDOM`); - useLayoutEffect(()=>{ - if (!domRef.current) return; - const firstChildDesc = childDescriptors[0]; - const desc = new MarkViewDesc(undefined, childDescriptors, mark, domRef.current, firstChildDesc?.dom.parentElement ?? domRef.current); - siblingDescriptors.push(desc); - for (const childDesc of childDescriptors){ - childDesc.parent = desc; - } - }); - return /*#__PURE__*/ React.createElement(OutputSpec, { - ref: domRef, - outputSpec: outputSpec - }, /*#__PURE__*/ React.createElement(ChildDescriptorsContext.Provider, { - value: childDescriptors - }, children)); -}); diff --git a/dist/esm/components/NativeWidgetView.js b/dist/esm/components/NativeWidgetView.js deleted file mode 100644 index 55d4f43c..00000000 --- a/dist/esm/components/NativeWidgetView.js +++ /dev/null @@ -1,37 +0,0 @@ -import React, { useContext, useLayoutEffect, useRef } from "react"; -import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js"; -import { useEditorEffect } from "../hooks/useEditorEffect.js"; -import { WidgetViewDesc } from "../viewdesc.js"; -export function NativeWidgetView(param) { - let { widget , pos } = param; - const siblingDescriptors = useContext(ChildDescriptorsContext); - const rootDomRef = useRef(null); - const posRef = useRef(pos); - posRef.current = pos; - useEditorEffect((view)=>{ - if (!rootDomRef.current) return; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const toDOM = widget.type.toDOM; - let dom = typeof toDOM === "function" ? toDOM(view, ()=>posRef.current) : toDOM; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - if (!widget.type.spec.raw) { - if (dom.nodeType != 1) { - const wrap = document.createElement("span"); - wrap.appendChild(dom); - dom = wrap; - } - dom.contentEditable = "false"; - dom.classList.add("ProseMirror-widget"); - } - if (rootDomRef.current.firstElementChild === dom) return; - rootDomRef.current.replaceChildren(dom); - }); - useLayoutEffect(()=>{ - if (!rootDomRef.current) return; - const desc = new WidgetViewDesc(undefined, widget, rootDomRef.current); - siblingDescriptors.push(desc); - }); - return /*#__PURE__*/ React.createElement("span", { - ref: rootDomRef - }); -} diff --git a/dist/esm/components/NodeView.js b/dist/esm/components/NodeView.js deleted file mode 100644 index 3cf3b0c1..00000000 --- a/dist/esm/components/NodeView.js +++ /dev/null @@ -1,143 +0,0 @@ -function _extends() { - _extends = Object.assign || function(target) { - for(var i = 1; i < arguments.length; i++){ - var source = arguments[i]; - for(var key in source){ - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; - return _extends.apply(this, arguments); -} -import { NodeSelection } from "prosemirror-state"; -import React, { cloneElement, createElement, useContext, useLayoutEffect, useRef } from "react"; -import { createPortal } from "react-dom"; -import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js"; -import { EditorContext } from "../contexts/EditorContext.js"; -import { NodeViewContext } from "../contexts/NodeViewContext.js"; -import { useEditorState } from "../hooks/useEditorState.js"; -import { useNodeViewDescriptor } from "../hooks/useNodeViewDescriptor.js"; -import { ChildNodeViews, wrapInDeco } from "./ChildNodeViews.js"; -import { MarkView } from "./MarkView.js"; -import { OutputSpec } from "./OutputSpec.js"; -export function NodeView(param) { - let { outerDeco , pos , node , innerDeco , ...props } = param; - const domRef = useRef(null); - const nodeDomRef = useRef(null); - const contentDomRef = useRef(null); - // this is ill-conceived; should revisit - const initialNode = useRef(node); - const initialOuterDeco = useRef(outerDeco); - const initialInnerDeco = useRef(innerDeco); - const posRef = useRef(pos); - posRef.current = pos; - const customNodeViewRootRef = useRef(null); - const customNodeViewRef = useRef(null); - const state = useEditorState(); - const { nodeViews } = useContext(NodeViewContext); - const { view } = useContext(EditorContext); - let element = null; - const Component = nodeViews[node.type.name]; - // TODO: Would be great to pull all of the custom node view stuff into - // a hook - const customNodeView = view?.someProp("nodeViews")?.[node.type.name]; - useLayoutEffect(()=>{ - if (!customNodeViewRef.current || !customNodeViewRootRef.current) return; - const { dom } = customNodeViewRef.current; - nodeDomRef.current = customNodeViewRootRef.current; - customNodeViewRootRef.current.appendChild(dom); - return ()=>{ - customNodeViewRef.current?.destroy?.(); - }; - }, []); - useLayoutEffect(()=>{ - if (!customNodeView || !customNodeViewRef.current) return; - const { destroy , update } = customNodeViewRef.current; - const updated = update?.call(customNodeViewRef.current, node, outerDeco, innerDeco) ?? true; - if (updated) return; - destroy?.call(customNodeViewRef.current); - if (!customNodeView || !customNodeViewRootRef.current) return; - initialNode.current = node; - initialOuterDeco.current = outerDeco; - initialInnerDeco.current = innerDeco; - customNodeViewRef.current = customNodeView(initialNode.current, view, ()=>posRef.current, initialOuterDeco.current, initialInnerDeco.current); - const { dom } = customNodeViewRef.current; - nodeDomRef.current = customNodeViewRootRef.current; - customNodeViewRootRef.current.appendChild(dom); - }, [ - customNodeView, - view, - innerDeco, - node, - outerDeco - ]); - const childDescriptors = useNodeViewDescriptor(node, domRef, nodeDomRef, innerDeco, outerDeco, undefined, contentDomRef); - if (Component) { - element = /*#__PURE__*/ React.createElement(Component, _extends({}, props, { - ref: nodeDomRef, - nodeProps: { - node: node, - pos: pos, - decorations: outerDeco, - innerDecorations: innerDeco, - isSelected: state?.selection instanceof NodeSelection && state.selection.node === node - } - }), /*#__PURE__*/ React.createElement(ChildNodeViews, { - pos: pos, - node: node, - innerDecorations: innerDeco - })); - } else if (customNodeView) { - if (!customNodeViewRef.current) { - customNodeViewRef.current = customNodeView(initialNode.current, view, ()=>posRef.current, initialOuterDeco.current, initialInnerDeco.current); - } - const { contentDOM } = customNodeViewRef.current; - contentDomRef.current = contentDOM ?? null; - element = /*#__PURE__*/ createElement(node.isInline ? "span" : "div", { - ref: customNodeViewRootRef, - contentEditable: !!contentDOM, - suppressContentEditableWarning: true - }, contentDOM && /*#__PURE__*/ createPortal(/*#__PURE__*/ React.createElement(ChildNodeViews, { - pos: pos, - node: node, - innerDecorations: innerDeco - }), contentDOM)); - } else { - const outputSpec = node.type.spec.toDOM?.(node); - if (outputSpec) { - element = /*#__PURE__*/ React.createElement(OutputSpec, _extends({}, props, { - ref: nodeDomRef, - outputSpec: outputSpec - }), /*#__PURE__*/ React.createElement(ChildNodeViews, { - pos: pos, - node: node, - innerDecorations: innerDeco - })); - } - } - if (!element) { - throw new Error(`Node spec for ${node.type.name} is missing toDOM`); - } - const decoratedElement = /*#__PURE__*/ cloneElement(outerDeco.reduce(wrapInDeco, element), // eslint-disable-next-line @typescript-eslint/no-explicit-any - outerDeco.some((d)=>d.type.attrs.nodeName) ? { - ref: domRef - } : // we've already passed the domRef to the NodeView component - // as a prop - undefined); - // TODO: Should we only be wrapping non-inline elements? Inline elements have - // already been wrapped in ChildNodeViews/InlineView? - const markedElement = node.marks.reduce((element, mark)=>/*#__PURE__*/ React.createElement(MarkView, { - mark: mark - }, element), decoratedElement); - return /*#__PURE__*/ React.createElement(ChildDescriptorsContext.Provider, { - value: childDescriptors - }, /*#__PURE__*/ cloneElement(markedElement, node.marks.length || // eslint-disable-next-line @typescript-eslint/no-explicit-any - outerDeco.some((d)=>d.type.attrs.nodeName) ? { - ref: domRef - } : // we've already passed the domRef to the NodeView component - // as a prop - undefined)); -} diff --git a/dist/esm/components/NodeViewComponentProps.js b/dist/esm/components/NodeViewComponentProps.js deleted file mode 100644 index 2234b9ca..00000000 --- a/dist/esm/components/NodeViewComponentProps.js +++ /dev/null @@ -1 +0,0 @@ -export { }; diff --git a/dist/esm/components/OutputSpec.js b/dist/esm/components/OutputSpec.js deleted file mode 100644 index 1cd68714..00000000 --- a/dist/esm/components/OutputSpec.js +++ /dev/null @@ -1,41 +0,0 @@ -import React, { createElement, forwardRef } from "react"; -const ForwardedOutputSpec = /*#__PURE__*/ forwardRef(function OutputSpec(param, ref) { - let { outputSpec , children , ...initialProps } = param; - if (typeof outputSpec === "string") { - return /*#__PURE__*/ React.createElement(React.Fragment, null, outputSpec); - } - if (!Array.isArray(outputSpec)) { - throw new Error("@nytimes/react-prosemirror only supports strings and arrays in toDOM"); - } - const tagSpec = outputSpec[0]; - const tagName = tagSpec.replace(" ", ":"); - const attrs = outputSpec[1]; - const props = { - ...initialProps, - ref - }; - let start = 1; - if (attrs && typeof attrs === "object" && attrs.nodeType == null && !Array.isArray(attrs)) { - start = 2; - for(const name in attrs)if (attrs[name] != null) { - const attrName = name === "class" ? "className" : name.replace(" ", ":"); - props[attrName] = attrs[name]; - } - } - const content = []; - for(let i = start; i < outputSpec.length; i++){ - const child = outputSpec[i]; - if (child === 0) { - if (i < outputSpec.length - 1 || i > start) { - throw new RangeError("Content hole must be the only child of its parent node"); - } - return /*#__PURE__*/ createElement(tagName, props, children); - } - content.push(/*#__PURE__*/ React.createElement(ForwardedOutputSpec, { - ref: undefined, - outputSpec: child - }, children)); - } - return /*#__PURE__*/ createElement(tagName, props, ...content); -}); -export { ForwardedOutputSpec as OutputSpec }; diff --git a/dist/esm/components/ProseMirror.js b/dist/esm/components/ProseMirror.js deleted file mode 100644 index 13c14ef1..00000000 --- a/dist/esm/components/ProseMirror.js +++ /dev/null @@ -1,37 +0,0 @@ -import { DecorationSet } from "prosemirror-view"; -import React, { useState } from "react"; -import { EditorContext } from "../contexts/EditorContext.js"; -import { NodeViewContext } from "../contexts/NodeViewContext.js"; -import { computeDocDeco } from "../decorations/computeDocDeco.js"; -import { viewDecorations } from "../decorations/viewDecorations.js"; -import { useEditor } from "../hooks/useEditor.js"; -import { usePendingViewEffects } from "../hooks/usePendingViewEffects.js"; -import { LayoutGroup } from "./LayoutGroup.js"; -import { DocNodeViewContext } from "./ProseMirrorDoc.js"; -export function ProseMirror(param) { - let { className , children , nodeViews ={} , customNodeViews , ...props } = param; - const [mount, setMount] = useState(null); - const editor = useEditor(mount, { - ...props, - nodeViews: customNodeViews - }); - usePendingViewEffects(editor.view); - const innerDecos = editor.view ? viewDecorations(editor.view, editor.cursorWrapper) : DecorationSet.empty; - const outerDecos = editor.view ? computeDocDeco(editor.view) : []; - return /*#__PURE__*/ React.createElement(LayoutGroup, null, /*#__PURE__*/ React.createElement(EditorContext.Provider, { - value: editor - }, /*#__PURE__*/ React.createElement(NodeViewContext.Provider, { - value: { - nodeViews - } - }, /*#__PURE__*/ React.createElement(DocNodeViewContext.Provider, { - value: { - className: className, - setMount: setMount, - node: editor.view?.state.doc, - innerDeco: innerDecos, - outerDeco: outerDecos, - viewDesc: editor.docViewDescRef.current - } - }, children)))); -} diff --git a/dist/esm/components/ProseMirrorDoc.js b/dist/esm/components/ProseMirrorDoc.js deleted file mode 100644 index 5b2e998e..00000000 --- a/dist/esm/components/ProseMirrorDoc.js +++ /dev/null @@ -1,38 +0,0 @@ -function _extends() { - _extends = Object.assign || function(target) { - for(var i = 1; i < arguments.length; i++){ - var source = arguments[i]; - for(var key in source){ - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; - return _extends.apply(this, arguments); -} -import React, { createContext, forwardRef, useContext, useImperativeHandle, useRef } from "react"; -import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js"; -import { DocNodeView } from "./DocNodeView.js"; -export const DocNodeViewContext = /*#__PURE__*/ createContext(null); -function ProseMirrorDoc(param, ref) { - let { as } = param; - const innerRef = useRef(null); - const { setMount , ...docProps } = useContext(DocNodeViewContext); - useImperativeHandle(ref, ()=>{ - return innerRef.current; - }, []); - return /*#__PURE__*/ React.createElement(ChildDescriptorsContext.Provider, { - value: [] - }, /*#__PURE__*/ React.createElement(DocNodeView, _extends({ - ref: (el)=>{ - innerRef.current = el; - setMount(el); - } - }, docProps, { - as: as - }))); -} -const ForwardedProseMirrorDoc = /*#__PURE__*/ forwardRef(ProseMirrorDoc); -export { ForwardedProseMirrorDoc as ProseMirrorDoc }; diff --git a/dist/esm/components/SeparatorHackView.js b/dist/esm/components/SeparatorHackView.js deleted file mode 100644 index 6987301c..00000000 --- a/dist/esm/components/SeparatorHackView.js +++ /dev/null @@ -1,26 +0,0 @@ -import React, { useContext, useLayoutEffect, useRef, useState } from "react"; -import { browser } from "../browser.js"; -import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js"; -import { TrailingHackViewDesc } from "../viewdesc.js"; -export function SeparatorHackView() { - const siblingDescriptors = useContext(ChildDescriptorsContext); - const ref = useRef(null); - const [shouldRender, setShouldRender] = useState(false); - // There's no risk of an infinite loop here, because - // we call setShouldRender conditionally - // eslint-disable-next-line react-hooks/exhaustive-deps - useLayoutEffect(()=>{ - const lastSibling = siblingDescriptors[siblingDescriptors.length - 1]; - if ((browser.safari || browser.chrome) && (lastSibling?.dom)?.contentEditable == "false") { - setShouldRender(true); - return; - } - if (!ref.current) return; - const desc = new TrailingHackViewDesc(undefined, [], ref.current, null); - siblingDescriptors.push(desc); - }); - return shouldRender ? /*#__PURE__*/ React.createElement("img", { - ref: ref, - className: "ProseMirror-separator" - }) : null; -} diff --git a/dist/esm/components/TextNodeView.js b/dist/esm/components/TextNodeView.js deleted file mode 100644 index ccece7a5..00000000 --- a/dist/esm/components/TextNodeView.js +++ /dev/null @@ -1,49 +0,0 @@ -import { DecorationSet } from "prosemirror-view"; -import { Component } from "react"; -import { findDOMNode } from "react-dom"; -import { CompositionViewDesc, TextViewDesc } from "../viewdesc.js"; -import { wrapInDeco } from "./ChildNodeViews.js"; -export class TextNodeView extends Component { - updateEffect() { - const { decorations , siblingDescriptors , node } = this.props; - // There simply is no other way to ref a text node - // eslint-disable-next-line react/no-find-dom-node - const dom = findDOMNode(this); - // We only need to explicitly create a CompositionViewDesc - // when a composition was started that produces a new text node. - // Otherwise we just rely on re-rendering the renderRef - if (!dom) { - return; - } - let textNode = dom; - while(textNode.firstChild){ - textNode = textNode.firstChild; - } - if (!this.viewDescRef || this.viewDescRef instanceof CompositionViewDesc) { - this.viewDescRef = new TextViewDesc(undefined, [], node, decorations, DecorationSet.empty, dom, textNode); - } else { - this.viewDescRef.parent = undefined; - this.viewDescRef.children = []; - this.viewDescRef.node = node; - this.viewDescRef.outerDeco = decorations; - this.viewDescRef.innerDeco = DecorationSet.empty; - this.viewDescRef.dom = dom; - this.viewDescRef.nodeDOM = textNode; - } - siblingDescriptors.push(this.viewDescRef); - } - componentDidMount() { - this.updateEffect(); - } - componentDidUpdate() { - this.updateEffect(); - } - render() { - const { node , decorations } = this.props; - return decorations.reduce(wrapInDeco, node.text); - } - constructor(...args){ - super(...args); - this.viewDescRef = null; - } -} diff --git a/dist/esm/components/TrailingHackView.js b/dist/esm/components/TrailingHackView.js deleted file mode 100644 index c971b7c8..00000000 --- a/dist/esm/components/TrailingHackView.js +++ /dev/null @@ -1,16 +0,0 @@ -import React, { useContext, useLayoutEffect, useRef } from "react"; -import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js"; -import { TrailingHackViewDesc } from "../viewdesc.js"; -export function TrailingHackView() { - const siblingDescriptors = useContext(ChildDescriptorsContext); - const ref = useRef(null); - useLayoutEffect(()=>{ - if (!ref.current) return; - const desc = new TrailingHackViewDesc(undefined, [], ref.current, null); - siblingDescriptors.push(desc); - }); - return /*#__PURE__*/ React.createElement("br", { - ref: ref, - className: "ProseMirror-trailingBreak" - }); -} diff --git a/dist/esm/components/WidgetView.js b/dist/esm/components/WidgetView.js deleted file mode 100644 index 6871063a..00000000 --- a/dist/esm/components/WidgetView.js +++ /dev/null @@ -1,20 +0,0 @@ -import React, { useContext, useLayoutEffect, useRef } from "react"; -import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js"; -import { WidgetViewDesc } from "../viewdesc.js"; -export function WidgetView(param) { - let { widget , pos } = param; - const siblingDescriptors = useContext(ChildDescriptorsContext); - const domRef = useRef(null); - useLayoutEffect(()=>{ - if (!domRef.current) return; - const desc = new WidgetViewDesc(undefined, widget, domRef.current); - siblingDescriptors.push(desc); - }); - const { Component } = widget.type; - return Component && /*#__PURE__*/ React.createElement(Component, { - ref: domRef, - widget: widget, - pos: pos, - contentEditable: false - }); -} diff --git a/dist/esm/components/WidgetViewComponentProps.js b/dist/esm/components/WidgetViewComponentProps.js deleted file mode 100644 index 2234b9ca..00000000 --- a/dist/esm/components/WidgetViewComponentProps.js +++ /dev/null @@ -1 +0,0 @@ -export { }; diff --git a/dist/esm/components/__tests__/ProseMirror.composition.js b/dist/esm/components/__tests__/ProseMirror.composition.js deleted file mode 100644 index 30901c9e..00000000 --- a/dist/esm/components/__tests__/ProseMirror.composition.js +++ /dev/null @@ -1,411 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-non-null-assertion */ import { expect } from "@jest/globals"; -import { act, fireEvent } from "@testing-library/react"; -import { Plugin } from "prosemirror-state"; -import { doc, em, p, schema, strong } from "prosemirror-test-builder"; -import { Decoration, DecorationSet, // @ts-expect-error This is an internal export -__endComposition } from "prosemirror-view"; -import { findTextNode, tempEditor } from "../../testing/editorViewTestHelpers.js"; -import { setupProseMirrorView } from "../../testing/setupProseMirrorView.js"; -function endComposition(view, forceUpdate) { - act(()=>{ - __endComposition(view, forceUpdate); - }); -} -function event(pm, type) { - act(()=>{ - pm.dom.dispatchEvent(new CompositionEvent(type)); - }); -} -function edit(node) { - let text = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "", from = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : node.nodeValue.length, to = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : from; - const val = node.nodeValue; - node.nodeValue = val.slice(0, from) + text + val.slice(to); - document.getSelection().collapse(node, from + text.length); - return node; -} -function hasCompositionNode(_pm) { - let { focusNode } = document.getSelection(); - while(focusNode && !focusNode.pmViewDesc)focusNode = focusNode.parentNode; - return focusNode && focusNode.pmViewDesc.constructor.name == "CompositionViewDesc"; -} -function compose(pm, start, update) { - let options = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : {}; - event(pm, "compositionstart"); - expect(pm.composing).toBeTruthy(); - let node; - const sel = document.getSelection(); - for(let i = -1; i < update.length; i++){ - if (i < 0) node = start(); - else update[i](node); - const { focusNode , focusOffset } = sel; - act(()=>{ - pm.domObserver.flush(); - }); - if (options.cancel && i == update.length - 1) { - expect(hasCompositionNode(pm)).toBeFalsy(); - } else { - expect(node.parentNode && pm.dom.contains(node.parentNode)).toBeTruthy(); - expect(sel.focusNode).toBe(focusNode); - expect(sel.focusOffset).toBe(focusOffset); - } - } - event(pm, "compositionend"); - if (options.end) { - options.end(node); - pm.domObserver.flush(); - } - endComposition(pm); - expect(pm.composing).toBeFalsy(); - expect(hasCompositionNode(pm)).toBeFalsy(); -} -function wordDeco(state) { - const re = /[^\s]+/g, deco = []; - state.doc.descendants((node, pos)=>{ - if (node.isText) for(let m; m = re.exec(node.text);)deco.push(Decoration.inline(pos + m.index, pos + m.index + m[0].length, { - class: "word" - })); - }); - return DecorationSet.create(state.doc, deco); -} -const wordHighlighter = new Plugin({ - props: { - decorations: wordDeco - } -}); -// const Widget = forwardRef(function Widget( -// { widget, pos, ...props }: WidgetViewComponentProps, -// ref: Ref -// ) { -// return ( -// -// × -// -// ); -// }); -// function widgets(positions: number[], sides: number[]) { -// return new Plugin({ -// state: { -// init(state) { -// const deco = positions.map((p, i) => -// widget(p, Widget, { side: sides[i] }) -// ); -// return DecorationSet.create(state.doc!, deco); -// }, -// apply(tr, deco) { -// return deco.map(tr.mapping, tr.doc); -// }, -// }, -// props: { -// decorations(this: Plugin, state) { -// return this.getState(state); -// }, -// }, -// }); -// } -function insertComposition(dom) { - fireEvent.keyDown(dom, { - key: "Dead", - code: "Quote" - }); - fireEvent.compositionStart(dom); - fireEvent.compositionUpdate(dom, { - data: "\xb4" - }); - fireEvent(dom, new InputEvent("beforeinput", { - isComposing: true, - inputType: "insertCompositionText", - data: "\xb4" - })); - fireEvent.input(dom, { - isComposing: true, - inputType: "insertCompositionText", - data: "\xb4" - }); - fireEvent.keyUp(dom, { - key: "\xb4", - code: "Quote", - isComposing: true - }); - fireEvent.keyDown(dom, { - key: "\xe9", - code: "KeyE", - isComposing: true - }); - fireEvent.compositionUpdate(dom, { - data: "\xe9" - }); - fireEvent(dom, new InputEvent("beforeinput", { - isComposing: true, - inputType: "insertCompositionText", - data: "\xe9" - })); - fireEvent.compositionEnd(dom, { - inputType: "insertCompositionText", - data: "\xe9" - }); - fireEvent.input(dom, { - isComposing: true, - inputType: "insertCompositionText", - data: "\xe9" - }); - fireEvent.keyUp(dom, { - key: "e", - code: "KeyE" - }); -} -describe("EditorView composition", ()=>{ - beforeAll(()=>{ - setupProseMirrorView(); - }); - it("supports composition in an empty block", ()=>{ - const { view } = tempEditor({ - doc: doc(p("")) - }); - insertComposition(view.dom); - expect(view.state.doc).toEqualNode(doc(p("\xe9"))); - }); - it("supports composition at end of block", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo")) - }); - insertComposition(view.dom); - expect(view.state.doc).toEqualNode(doc(p("foo\xe9"))); - }); - it("supports composition at start of block in a new node", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo")) - }); - insertComposition(view.dom); - expect(view.state.doc).toEqualNode(doc(p("\xe9foo"))); - }); - it("supports composition inside existing text", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo")) - }); - insertComposition(view.dom); - expect(view.state.doc).toEqualNode(doc(p("f\xe9oo"))); - }); - // TODO: Deal with Android style compositions - // eslint-disable-next-line jest/no-disabled-tests - it.skip("can deal with Android-style newline-after-composition", ()=>{ - const { view: pm } = tempEditor({ - doc: doc(p("abcdef")) - }); - compose(pm, ()=>edit(findTextNode(pm.dom, "abcdef")), [ - (n)=>edit(n, "x", 3), - (n)=>edit(n, "y", 4) - ], { - end: (n)=>{ - const line = pm.dom.appendChild(document.createElement("div")); - line.textContent = "def"; - n.nodeValue = "abcxy"; - document.getSelection().collapse(line, 0); - } - }); - expect(pm.state.doc).toEqualNode(doc(p("abcxy"), p("def"))); - }); - it("handles replacement of existing words", ()=>{ - const { view } = tempEditor({ - doc: doc(p("one two three")) - }); - insertComposition(view.dom); - expect(view.state.doc).toEqualNode(doc(p("one \xe9 three"))); - }); - it("handles composition inside marks", ()=>{ - const { view } = tempEditor({ - doc: doc(p("one ", em("two"))) - }); - insertComposition(view.dom); - expect(view.state.doc).toEqualNode(doc(p("one ", em("two\xe9")))); - }); - it("handles composition in a mark that has multiple children", ()=>{ - const { view } = tempEditor({ - doc: doc(p("one ", em("two", strong(" three")))) - }); - insertComposition(view.dom); - expect(view.state.doc).toEqualNode(doc(p("one ", em("two\xe9", strong(" three"))))); - }); - // This passes, but I think it shouldn't; it doesn't seem to work - // in the demo - it.skip("supports composition in a cursor wrapper", ()=>{ - const { view } = tempEditor({ - doc: doc(p("")) - }); - view.dispatch(view.state.tr.addStoredMark(schema.marks.em.create())); - insertComposition(view.dom); - expect(view.state.doc).toEqualNode(doc(p(em("\xe9")))); - }); - // it("handles composition in a multi-child mark with a cursor wrapper", () => { - // const { view: pm } = requireFocus( - // tempEditor({ doc: doc(p("one ", em("two", strong(" three")))) }) - // ); - // pm.dispatch(pm.state.tr.addStoredMark(schema.marks.code.create())); - // const emNode = pm.dom.querySelector("em")!; - // compose( - // pm, - // () => - // edit( - // emNode.insertBefore( - // document.createTextNode(""), - // emNode.querySelector("strong") - // ), - // "o" - // ), - // [(n) => edit(n, "o"), (n) => edit(n, "w")], - // { node: true } - // ); - // ist( - // pm.state.doc, - // doc(p("one ", em("two", code("oow"), strong(" three")))), - // eq - // ); - // }); - // TODO: This also passes but does not actually work in the - // demo :( - it.skip("doesn't get interrupted by changes in decorations", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo ...")), - plugins: [ - wordHighlighter - ] - }); - insertComposition(view.dom); - expect(view.state.doc).toEqualNode(doc(p("foo \xe9"))); - }); -// it("works inside highlighted text", () => { -// const { view: pm } = requireFocus( -// tempEditor({ doc: doc(p("one two")), plugins: [wordHighlighter] }) -// ); -// compose(pm, () => edit(findTextNode(pm.dom, "one")!, "x"), [ -// (n) => edit(n, "y"), -// (n) => edit(n, "."), -// ]); -// ist(pm.state.doc, doc(p("onexy. two")), eq); -// }); -// it("can handle compositions spanning multiple nodes", () => { -// const { view: pm } = requireFocus( -// tempEditor({ doc: doc(p("one two")), plugins: [wordHighlighter] }) -// ); -// compose( -// pm, -// () => edit(findTextNode(pm.dom, "two")!, "a"), -// [(n) => edit(n, "b"), (n) => edit(n, "c")], -// { -// end: (n: Text) => { -// n.parentNode!.previousSibling!.remove(); -// n.parentNode!.previousSibling!.remove(); -// return edit(n, "xyzone ", 0); -// }, -// } -// ); -// ist(pm.state.doc, doc(p("xyzone twoabc")), eq); -// }); -// it("doesn't overwrite widgets next to the composition", () => { -// const { view: pm } = requireFocus( -// tempEditor({ doc: doc(p("")), plugins: [widgets([1, 1], [-1, 1])] }) -// ); -// compose( -// pm, -// () => { -// const p = pm.dom.firstChild!; -// return edit(p.insertBefore(document.createTextNode("a"), p.lastChild)); -// }, -// [(n) => edit(n, "b", 0, 1)], -// { -// end: () => { -// ist(pm.dom.querySelectorAll("var").length, 2); -// }, -// } -// ); -// ist(pm.state.doc, doc(p("b")), eq); -// }); -// it("cancels composition when a change fully overlaps with it", () => { -// const { view: pm } = requireFocus( -// tempEditor({ doc: doc(p("one"), p("two"), p("three")) }) -// ); -// compose( -// pm, -// () => edit(findTextNode(pm.dom, "two")!, "x"), -// [() => pm.dispatch(pm.state.tr.insertText("---", 3, 13))], -// { cancel: true } -// ); -// ist(pm.state.doc, doc(p("on---hree")), eq); -// }); -// it("cancels composition when a change partially overlaps with it", () => { -// const { view: pm } = requireFocus( -// tempEditor({ doc: doc(p("one"), p("two"), p("three")) }) -// ); -// compose( -// pm, -// () => edit(findTextNode(pm.dom, "two")!, "x", 0), -// [() => pm.dispatch(pm.state.tr.insertText("---", 7, 15))], -// { cancel: true } -// ); -// ist(pm.state.doc, doc(p("one"), p("x---ee")), eq); -// }); -// it("cancels composition when a change happens inside of it", () => { -// const { view: pm } = requireFocus( -// tempEditor({ doc: doc(p("one"), p("two"), p("three")) }) -// ); -// compose( -// pm, -// () => edit(findTextNode(pm.dom, "two")!, "x", 0), -// [() => pm.dispatch(pm.state.tr.insertText("!", 7, 8))], -// { cancel: true } -// ); -// ist(pm.state.doc, doc(p("one"), p("x!wo"), p("three")), eq); -// }); -// it("doesn't cancel composition when a change happens elsewhere", () => { -// const { view: pm } = requireFocus( -// tempEditor({ doc: doc(p("one"), p("two"), p("three")) }) -// ); -// compose(pm, () => edit(findTextNode(pm.dom, "two")!, "x", 0), [ -// (n) => edit(n, "y", 1), -// () => pm.dispatch(pm.state.tr.insertText("!", 2, 3)), -// (n) => edit(n, "z", 2), -// ]); -// ist(pm.state.doc, doc(p("o!e"), p("xyztwo"), p("three")), eq); -// }); -// it("handles compositions rapidly following each other", () => { -// const { view: pm } = tempEditor({ doc: doc(p("one"), p("two")) }); -// event(pm, "compositionstart"); -// const one = findTextNode(pm.dom, "one")!; -// edit(one, "!"); -// (pm as any).domObserver.flush(); -// event(pm, "compositionend"); -// one.nodeValue = "one!!"; -// const L2 = pm.dom.lastChild; -// event(pm, "compositionstart"); -// const two = findTextNode(pm.dom, "two")!; -// ist(pm.dom.lastChild, L2); -// edit(two, "."); -// (pm as any).domObserver.flush(); -// ist(document.getSelection()!.focusNode, two); -// ist(document.getSelection()!.focusOffset, 4); -// ist(pm.composing); -// event(pm, "compositionend"); -// (pm as any).domObserver.flush(); -// ist(pm.state.doc, doc(p("one!!"), p("two.")), eq); -// }); -// function crossParagraph(first = false) { -// const { view: pm } = requireFocus( -// tempEditor({ doc: doc(p("one two"), p("three"), p("four five")) }) -// ); -// compose( -// pm, -// () => { -// for (let i = 0; i < 2; i++) -// pm.dom.removeChild(first ? pm.dom.lastChild! : pm.dom.firstChild!); -// const target = pm.dom.firstChild!.firstChild as Text; -// target.nodeValue = "one A five"; -// document.getSelection()!.collapse(target, 4); -// return target; -// }, -// [(n) => edit(n, "B", 4, 5), (n) => edit(n, "C", 4, 5)] -// ); -// ist(pm.state.doc, doc(p("one C five")), eq); -// } -// it("can handle cross-paragraph compositions", () => crossParagraph(true)); -// it("can handle cross-paragraph compositions (keeping the last paragraph)", () => -// crossParagraph(false)); -}); diff --git a/dist/esm/components/__tests__/ProseMirror.domchange.test.js b/dist/esm/components/__tests__/ProseMirror.domchange.test.js deleted file mode 100644 index 2c98ab2e..00000000 --- a/dist/esm/components/__tests__/ProseMirror.domchange.test.js +++ /dev/null @@ -1,546 +0,0 @@ -/** - * @fileoverview - * This file tests that prosemirror-view's DOMObserver works correctly - * in conjunction with React ProseMirror. - * - * @important - * DOMObserver relies on a MutationObserver. The MutationObserver callback - * seems to get queued as a microtask; it will not run until after all - * synchronous code in a test has completed. This is why we manually call - * flush(view) in each test to ensure that the mutation records have been - * flushed. - * - * HOWEVER! If you use an awaited statement after changing the DOM, the - * MutationObserver WILL run. This means that a sequence of DOM changes - * that you want to be staged and detected as a single change may be - * detected and processed in multiple separate phases, which can lead to - * unexpected results. Unsure that you only have synchronous code between - * your first DOM change and your eventual call to flush(view) to avoid this. - */ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-non-null-assertion */ import { expect } from "@jest/globals"; -import { act, screen } from "@testing-library/react"; -import userEvent from "@testing-library/user-event"; -import { EditorState, TextSelection } from "prosemirror-state"; -import { a, blockquote, br, doc, em, img as img_, p, pre, strong } from "prosemirror-test-builder"; -import { findTextNode, tempEditor } from "../../testing/editorViewTestHelpers.js"; -import { setupProseMirrorView } from "../../testing/setupProseMirrorView.js"; -const img = img_({ - src: "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" -}); -function flush(view) { - act(()=>{ - view.domObserver.flush(); - }); -} -function setSel(aNode, aOff, fNode) { - let fOff = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : 0; - const r = document.createRange(); - const s = window.getSelection(); - r.setEnd(fNode || aNode, fNode ? fOff : aOff); - r.setStart(aNode, aOff); - s.removeAllRanges(); - s.addRange(r); -} -describe("DOM change", ()=>{ - beforeAll(()=>{ - setupProseMirrorView(); - }); - it("notices when text is added", ()=>{ - const { view } = tempEditor({ - doc: doc(p("hello")) - }); - findTextNode(view.dom, "hello").nodeValue = "heLllo"; - flush(view); - expect(view.state.doc).toEqualNode(doc(p("heLllo"))); - }); - it("notices when text is removed", ()=>{ - const { view } = tempEditor({ - doc: doc(p("hello")) - }); - findTextNode(view.dom, "hello").nodeValue = "heo"; - flush(view); - expect(view.state.doc).toEqualNode(doc(p("heo"))); - }); - it("handles ambiguous changes", ()=>{ - const { view } = tempEditor({ - doc: doc(p("hello")) - }); - findTextNode(view.dom, "hello").nodeValue = "helo"; - flush(view); - expect(view.state.doc).toEqualNode(doc(p("helo"))); - }); - it("respects stored marks", async ()=>{ - const { view } = tempEditor({ - doc: doc(p("hello")) - }); - act(()=>{ - view.dispatch(view.state.tr.addStoredMark(view.state.schema.marks.em.create())); - }); - findTextNode(view.dom, "hello").nodeValue = "helloo"; - flush(view); - expect(view.state.doc).toEqualNode(doc(p("hello", em("o")))); - }); - it("can add a node", ()=>{ - const { view } = tempEditor({ - doc: doc(p("hello")) - }); - const txt = findTextNode(view.dom, "hello"); - txt.parentNode.appendChild(document.createTextNode("!")); - flush(view); - expect(view.state.doc).toEqualNode(doc(p("hello!"))); - }); - it("can remove a text node", ()=>{ - const { view } = tempEditor({ - doc: doc(p("hello")) - }); - const txt = findTextNode(view.dom, "hello"); - txt.parentNode.removeChild(txt); - flush(view); - expect(view.state.doc).toEqualNode(doc(p())); - }); - it("can add a paragraph", ()=>{ - const { view } = tempEditor({ - doc: doc(p("hello")) - }); - view.dom.insertBefore(document.createElement("p"), view.dom.firstChild).appendChild(document.createTextNode("hey")); - flush(view); - expect(view.state.doc).toEqualNode(doc(p("hey"), p("hello"))); - }); - it("supports duplicating a paragraph", ()=>{ - const { view } = tempEditor({ - doc: doc(p("hello")) - }); - view.dom.insertBefore(document.createElement("p"), view.dom.firstChild).appendChild(document.createTextNode("hello")); - flush(view); - expect(view.state.doc).toEqualNode(doc(p("hello"), p("hello"))); - }); - it("support inserting repeated text", async ()=>{ - const { view } = tempEditor({ - doc: doc(p("hello")) - }); - findTextNode(view.dom, "hello").nodeValue = "helhello"; - flush(view); - expect(view.state.doc).toEqualNode(doc(p("helhello"))); - }); - it("detects an enter press", async ()=>{ - let enterPressed = false; - const { view } = tempEditor({ - doc: doc(blockquote(p("foo"), p(""))), - handleKeyDown: (_, event)=>{ - if (event.key === "Enter") return enterPressed = true; - return false; - } - }); - const bq = view.dom.querySelector("blockquote"); - bq.appendChild(document.createElement("p")); - flush(view); - expect(enterPressed).toBeTruthy(); - }); - it("detects a simple backspace press", async ()=>{ - let backspacePressed = false; - const { view } = tempEditor({ - doc: doc(blockquote(p("foo"), p("bar"))), - handleKeyDown: (_, event)=>{ - if (event.key === "Backspace") return backspacePressed = true; - return false; - } - }); - const user = userEvent.setup(); - await act(async ()=>{ - await user.type(view.dom.firstElementChild, "{Backspace}"); - }); - expect(backspacePressed).toBeTruthy(); - }); - // TODO: This causes React to throw an error, because we're - // removing a DOM node that React was responsible for. - // I'm not sure why this only fails in the test environment - // (deletes work just fine in the browser). - // eslint-disable-next-line jest/no-disabled-tests - it.skip("doesn't route delete as backspace", ()=>{ - let backspacePressed = false; - const { view } = tempEditor({ - doc: doc(p("foo"), p("bar")), - handleKeyDown: (_view, event)=>{ - if (event.key === "Backspace") return backspacePressed = true; - return false; - } - }); - act(()=>{ - view.dom.removeChild(view.dom.lastChild); - view.dom.firstChild.textContent = "foobar"; - flush(view); - }); - expect(backspacePressed).toBeFalsy(); - }); - it("correctly adjusts the selection", ()=>{ - const { view } = tempEditor({ - doc: doc(p("abc")) - }); - const textNode = findTextNode(view.dom, "abc"); - act(()=>{ - textNode.nodeValue = "abcd"; - setSel(textNode, 3); - flush(view); - }); - expect(view.state.doc).toEqualNode(doc(p("abcd"))); - expect(view.state.selection.anchor).toBe(4); - expect(view.state.selection.head).toBe(4); - }); - it("handles a deep split of nodes", ()=>{ - const { view } = tempEditor({ - doc: doc(blockquote(p("abcd"))) - }); - const quote = view.dom.querySelector("blockquote"); - const text1 = quote.firstChild.firstChild; - const quote2 = view.dom.appendChild(quote.cloneNode(true)); - const text2 = quote2.firstChild.firstChild; - text1.nodeValue = "abx"; - text2.nodeValue = "cd"; - setSel(text2.parentNode, 0); - flush(view); - expect(view.state.doc).toEqualNode(doc(blockquote(p("abx")), blockquote(p("cd")))); - expect(view.state.selection.anchor).toBe(9); - }); - it("can delete the third instance of a character", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo xxx bar")) - }); - const textNode = findTextNode(view.dom, "foo xxx bar"); - textNode.nodeValue = "foo xx bar"; - flush(view); - expect(view.state.doc).toEqualNode(doc(p("foo xx bar"))); - }); - it("can read a simple composition", ()=>{ - const { view } = tempEditor({ - doc: doc(p("hello")) - }); - const textNode = findTextNode(view.dom, "hello"); - textNode.nodeValue = "hellox"; - flush(view); - expect(view.state.doc).toEqualNode(doc(p("hellox"))); - }); - it("can delete text in markup", ()=>{ - const { view } = tempEditor({ - doc: doc(p("a", em("b", img, strong("cd")), "e")) - }); - const textNode = findTextNode(view.dom, "cd"); - textNode.nodeValue = "c"; - flush(view); - expect(view.state.doc).toEqualNode(doc(p("a", em("b", img, strong("c")), "e"))); - }); - it("recognizes typing inside markup", ()=>{ - const { view } = tempEditor({ - doc: doc(p("a", em("b", img, strong("cd")), "e")) - }); - const textNode = findTextNode(view.dom, "cd"); - textNode.nodeValue = "cdxy"; - flush(view); - expect(view.state.doc).toEqualNode(doc(p("a", em("b", img, strong("cdxy")), "e"))); - }); - it("resolves ambiguous text input", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo")) - }); - act(()=>{ - view.dispatch(view.state.tr.addStoredMark(view.state.schema.marks.strong.create())); - }); - const textNode = findTextNode(view.dom, "foo"); - textNode.nodeValue = "fooo"; - flush(view); - expect(view.state.doc).toEqualNode(doc(p("fo", strong("o"), "o"))); - }); - it("does not repaint a text node when it's typed into", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo")) - }); - const textNode = findTextNode(view.dom, "foo"); - textNode.nodeValue = "fojo"; - let mutated = false; - const observer = new MutationObserver(()=>mutated = true); - observer.observe(view.dom, { - subtree: true, - characterData: true, - childList: true - }); - flush(view); - expect(view.state.doc).toEqualNode(doc(p("fojo"))); - expect(mutated).toBeFalsy(); - observer.disconnect(); - }); - it("understands text typed into an empty paragraph", ()=>{ - const { view } = tempEditor({ - doc: doc(p("")) - }); - const paragraph = view.dom.querySelector("p"); - paragraph.replaceChildren("i"); - flush(view); - expect(view.state.doc).toEqualNode(doc(p("i"))); - }); - it("doesn't treat a placeholder BR as real content", async ()=>{ - const { view } = tempEditor({ - doc: doc(p("i")) - }); - const paragraph = await screen.findByText("i"); - paragraph.replaceChildren(document.createElement("br")); - flush(view); - expect(view.state.doc).toEqualNode(doc(p())); - }); - // TODO: Figure out why this doesn't work. Seems like React isn't - // re-rendering after flushing a mutation that doesn't lead to a state - // update. - // eslint-disable-next-line jest/no-disabled-tests - it.skip("fixes text changes when input is ignored", async ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo", br(), "bar")), - dispatchTransaction () { - // ignore transaction - } - }); - const paragraph = await screen.findByText((text)=>text.startsWith("foo")); - paragraph.replaceChild(document.createElement("img"), paragraph.lastChild); - flush(view); - expect(view.dom.textContent).toBe("foobar"); - }); - it("aborts when an incompatible state is set", ()=>{ - const { view , rerender } = tempEditor({ - state: EditorState.create({ - doc: doc(p("abcde")) - }) - }); - const textNode = findTextNode(view.dom, "abcde"); - textNode.nodeValue = "xabcde"; - view.dispatchEvent({ - type: "input" - }); - rerender({ - state: EditorState.create({ - doc: doc(p("uvw")) - }) - }); - flush(view); - expect(view.state.doc).toEqualNode(doc(p("uvw"))); - }); - // TODO: This causes React to throw an error, because we're - // removing a DOM node that React was responsible for. - // I'm not sure what would cause this actual behavior in real - // life, but if we can replicate it, it would be good to get - // it working. - // eslint-disable-next-line jest/no-disabled-tests - it.skip("recognizes a mark change as such", async ()=>{ - const { view } = tempEditor({ - doc: doc(p("one")), - dispatchTransaction (tr) { - expect(tr.steps).toHaveLength(1); - expect(tr.steps[0].toJSON().stepType).toBe("addMark"); - view.updateState(view.state.apply(tr)); - } - }); - const paragraph = await screen.findByText("one"); - const newChild = document.createElement("b"); - newChild.appendChild(document.createTextNode("one")); - paragraph.replaceChildren(newChild); - flush(view); - expect(view.state.doc).toEqualNode(doc(p(strong("one")))); - }); - it("preserves marks on deletion", async ()=>{ - const { view } = tempEditor({ - doc: doc(p("one", em("x"))) - }); - const emBlock = await screen.findByText("x"); - emBlock.replaceChildren(); - view.dispatchEvent({ - type: "input" - }); - act(()=>{ - flush(view); - view.dispatch(view.state.tr.insertText("y")); - }); - expect(view.state.doc).toEqualNode(doc(p("one", em("y")))); - }); - it("works when a node's contentDOM is deleted", async ()=>{ - const { view } = tempEditor({ - doc: doc(p("one"), pre("two")) - }); - const codeBlock = await screen.findByText("two"); - act(()=>{ - codeBlock.replaceChildren(); - view.dispatchEvent({ - type: "input" - }); - flush(view); - }); - expect(view.state.doc).toEqualNode(doc(p("one"), pre())); - expect(view.state.selection.head).toBe(6); - }); - it("doesn't redraw content with marks when typing in front", async ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo", em("bar"), strong("baz"))) - }); - const bar = await screen.findByText("bar"); - const foo = await screen.findByText("foo"); - foo.firstChild.nodeValue = "froo"; - flush(view); - expect(view.state.doc).toEqualNode(doc(p("froo", em("bar"), strong("baz")))); - expect(bar).toBeTruthy(); - expect(view.dom.contains(bar)).toBeTruthy(); - expect(foo).toBeTruthy(); - expect(view.dom.contains(foo)).toBeTruthy(); - }); - it("doesn't redraw content with marks when typing inside mark", async ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo", em("bar"), strong("baz"))) - }); - const bar = await screen.findByText("bar"); - const foo = await screen.findByText("foo"); - bar.firstChild.nodeValue = "baar"; - flush(view); - expect(view.state.doc).toEqualNode(doc(p("foo", em("baar"), strong("baz")))); - expect(bar).toBeTruthy(); - expect(view.dom.contains(bar)).toBeTruthy(); - expect(foo).toBeTruthy(); - expect(view.dom.contains(foo)).toBeTruthy(); - }); - it("maps input to coordsAtPos through pending changes", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo")) - }); - act(()=>{ - view.dispatchEvent({ - type: "input" - }); - view.dispatch(view.state.tr.insertText("more text")); - }); - expect(view.coordsAtPos(13)).toBeTruthy(); - }); - it("notices text added to a cursor wrapper at the start of a mark", async ()=>{ - const { view } = tempEditor({ - doc: doc(p(strong(a("foo"), "bar"))) - }); - const textNode = findTextNode(view.dom, "foo"); - textNode.nodeValue = "fooxy"; - flush(view); - expect(view.state.doc).toEqualNode(doc(p(strong(a("foo"), "xybar")))); - }); - it("removes cursor wrapper text when the wrapper otherwise remains valid", async ()=>{ - const { view } = tempEditor({ - doc: doc(p(a(strong("foo"), "bar"))) - }); - const textNode = findTextNode(view.dom, "foo"); - textNode.nodeValue = "fooq"; - flush(view); - expect(view.state.doc).toEqualNode(doc(p(a(strong("fooq"), "bar")))); - const found = screen.queryByText("\uFEFFq"); - expect(found).toBeNull(); - }); - it("doesn't confuse backspace with delete", async ()=>{ - let steps; - const { view } = tempEditor({ - doc: doc(p("aa")), - dispatchTransaction (tr) { - steps = tr.steps; - view.updateState(view.state.apply(tr)); - } - }); - view.input.lastKeyCode = 8; - view.input.lastKeyCodeTime = Date.now(); - const textNode = findTextNode(view.dom, "aa"); - textNode.nodeValue = "a"; - flush(view); - expect(steps).toHaveLength(1); - expect(steps[0].from).toBe(1); - expect(steps[0].to).toBe(2); - }); - it("can disambiguate a multiple-character backspace event", async ()=>{ - let steps; - const { view } = tempEditor({ - doc: doc(p("foofoo")), - dispatchTransaction (tr) { - steps = tr.steps; - view.updateState(view.state.apply(tr)); - } - }); - view.input.lastKeyCode = 8; - view.input.lastKeyCodeTime = Date.now(); - const textNode = findTextNode(view.dom, "foofoo"); - textNode.nodeValue = "foo"; - flush(view); - expect(steps).toHaveLength(1); - expect(steps[0].from).toBe(1); - expect(steps[0].to).toBe(4); - }); - it("doesn't confuse delete with backspace", async ()=>{ - let steps; - const { view } = tempEditor({ - doc: doc(p("aa")), - dispatchTransaction (tr) { - steps = tr.steps; - view.updateState(view.state.apply(tr)); - } - }); - const textNode = findTextNode(view.dom, "aa"); - textNode.nodeValue = "a"; - flush(view); - expect(steps).toHaveLength(1); - expect(steps[0].from).toBe(2); - expect(steps[0].to).toBe(3); - }); - it("doesn't confuse delete with backspace for multi-character deletions", async ()=>{ - let steps; - const { view } = tempEditor({ - doc: doc(p("one foofoo three")), - dispatchTransaction (tr) { - steps = tr.steps; - view.updateState(view.state.apply(tr)); - } - }); - const textNode = findTextNode(view.dom, "one foofoo three"); - textNode.nodeValue = "one foo three"; - flush(view); - expect(steps).toHaveLength(1); - expect(steps[0].from).toBe(8); - expect(steps[0].to).toBe(11); - }); - it("creates a correct step for an ambiguous selection-deletion", async ()=>{ - let steps; - const { view } = tempEditor({ - doc: doc(p("lalala")), - dispatchTransaction (tr) { - steps = tr.steps; - view.updateState(view.state.apply(tr)); - } - }); - view.input.lastKeyCode = 8; - view.input.lastKeyCodeTime = Date.now(); - const textNode = findTextNode(view.dom, "lalala"); - textNode.nodeValue = "lala"; - flush(view); - expect(steps).toHaveLength(1); - expect(steps[0].from).toBe(3); - expect(steps[0].to).toBe(5); - }); - it("creates a step that covers the entire selection for partially-matching replacement", async ()=>{ - let steps; - const { view } = tempEditor({ - doc: doc(p("one two three")), - dispatchTransaction (tr) { - steps = tr.steps; - view.updateState(view.state.apply(tr)); - } - }); - const textNode = findTextNode(view.dom, "one two three"); - textNode.nodeValue = "one t three"; - flush(view); - expect(steps).toHaveLength(1); - expect(steps[0].from).toBe(5); - expect(steps[0].to).toBe(8); - expect(steps[0].slice.content.toString()).toBe('<"t">'); - act(()=>{ - view.dispatch(view.state.tr.setSelection(TextSelection.create(view.state.doc, 7, 12))); - }); - textNode.nodeValue = "one t e"; - flush(view); - expect(steps).toHaveLength(1); - expect(steps[0].from).toBe(7); - expect(steps[0].to).toBe(12); - expect(steps[0].slice.content.toString()).toBe('<"e">'); - }); -}); diff --git a/dist/esm/components/__tests__/ProseMirror.draw-decoration.test.js b/dist/esm/components/__tests__/ProseMirror.draw-decoration.test.js deleted file mode 100644 index 59820ff0..00000000 --- a/dist/esm/components/__tests__/ProseMirror.draw-decoration.test.js +++ /dev/null @@ -1,1011 +0,0 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ // TODO: figure out whether it's possible to support native -// widgets. Right now, I'm not sure how we'd do it without -// wrapping them in another element, which would re-introduce -// all of the issues we had before with node views. -// -// For now, we've updated the factory in this file to use -// our React widgets. -function _extends() { - _extends = Object.assign || function(target) { - for(var i = 1; i < arguments.length; i++){ - var source = arguments[i]; - for(var key in source){ - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; - return _extends.apply(this, arguments); -} -import { act } from "@testing-library/react"; -import { Schema } from "prosemirror-model"; -import { Plugin, TextSelection } from "prosemirror-state"; -import { blockquote, doc, em, h1, hr, img, p, schema, strong } from "prosemirror-test-builder"; -import { Decoration, DecorationSet } from "prosemirror-view"; -import React, { forwardRef, useEffect } from "react"; -import { widget } from "../../decorations/ReactWidgetType.js"; -import { useEditorEffect } from "../../hooks/useEditorEffect.js"; -import { tempEditor } from "../../testing/editorViewTestHelpers.js"; -const Widget = /*#__PURE__*/ forwardRef(function Widget(props, ref) { - return /*#__PURE__*/ React.createElement("button", _extends({ - ref: ref - }, props), "ω"); -}); -function make(str) { - if (typeof str != "string") return str; - const match = /^(\d+)(?:-(\d+))?-(.+)$/.exec(str); - if (match[3] == "widget") { - return widget(+match[1], Widget, { - key: str - }); - } - return Decoration.inline(+match[1], +match[2], { - class: match[3] - }); -} -function decoPlugin(decos) { - return new Plugin({ - state: { - init (config) { - return config.doc ? DecorationSet.create(config.doc, decos.map(make)) : DecorationSet.empty; - }, - apply (tr, set, state) { - if (tr.docChanged) { - if (set === DecorationSet.empty) { - set = DecorationSet.create(tr.doc, decos.map(make)); - } - set = set.map(tr.mapping, tr.doc); - } - const change = tr.getMeta("updateDecorations"); - if (change) { - if (change.remove) set = set.remove(change.remove); - if (change.add) set = set.add(state.doc, change.add); - } - return set; - } - }, - props: { - decorations (state) { - return this.getState(state); - } - } - }); -} -function updateDeco(view, add, remove) { - view.dispatch(view.state.tr.setMeta("updateDecorations", { - add, - remove - })); -} -describe("Decoration drawing", ()=>{ - it("draws inline decorations", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foobar")), - plugins: [ - decoPlugin([ - "2-5-foo" - ]) - ] - }); - const found = view.dom.querySelector(".foo"); - expect(found).not.toBeNull(); - expect(found.textContent).toBe("oob"); - }); - it("draws wrapping decorations", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo")), - plugins: [ - decoPlugin([ - Decoration.inline(1, 5, { - nodeName: "i" - }) - ]) - ] - }); - const found = view.dom.querySelector("i"); - expect(found && found.innerHTML).toBe("foo"); - }); - it("draws node decorations", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo"), p("bar")), - plugins: [ - decoPlugin([ - Decoration.node(5, 10, { - class: "cls" - }) - ]) - ] - }); - const found = view.dom.querySelectorAll(".cls"); - expect(found).toHaveLength(1); - expect(found[0].nodeName).toBe("P"); - expect(found[0].previousSibling.nodeName).toBe("P"); - }); - it("can update multi-level wrapping decorations", ()=>{ - const d2 = Decoration.inline(1, 5, { - nodeName: "i", - class: "b" - }); - const { view } = tempEditor({ - doc: doc(p("hello")), - plugins: [ - decoPlugin([ - Decoration.inline(1, 5, { - nodeName: "i", - class: "a" - }), - d2 - ]) - ] - }); - expect(view.dom.querySelectorAll("i")).toHaveLength(2); - act(()=>{ - updateDeco(view, [ - Decoration.inline(1, 5, { - nodeName: "i", - class: "c" - }) - ], [ - d2 - ]); - }); - const iNodes = view.dom.querySelectorAll("i"); - expect(iNodes).toHaveLength(2); - expect(Array.prototype.map.call(iNodes, (n)=>n.className).sort().join()).toBe("a,c"); - }); - it("draws overlapping inline decorations", ()=>{ - const { view } = tempEditor({ - doc: doc(p("abcdef")), - plugins: [ - decoPlugin([ - "3-5-foo", - "4-6-bar", - "1-7-baz" - ]) - ] - }); - const baz = view.dom.querySelectorAll(".baz"); - expect(baz).toHaveLength(5); - expect(Array.prototype.map.call(baz, (x)=>x.textContent).join("-")).toBe("ab-c-d-e-f"); - function classes(n) { - return n.className.split(" ").sort().join(" "); - } - expect(classes(baz[1])).toBe("baz foo"); - expect(classes(baz[2])).toBe("bar baz foo"); - expect(classes(baz[3])).toBe("bar baz"); - }); - it("draws multiple widgets", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foobar")), - plugins: [ - decoPlugin([ - "1-widget", - "4-widget", - "7-widget" - ]) - ] - }); - const found = view.dom.querySelectorAll("button"); - expect(found).toHaveLength(3); - expect(found[0].nextSibling.textContent).toBe("foo"); - expect(found[1].nextSibling.textContent).toBe("bar"); - expect(found[2].previousSibling.textContent).toBe("bar"); - }); - it("orders widgets by their side option", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foobar")), - plugins: [ - decoPlugin([ - widget(4, /*#__PURE__*/ forwardRef(function B(props, ref) { - return /*#__PURE__*/ React.createElement("span", _extends({ - ref: ref - }, props), "B"); - }), { - key: "widget-b" - }), - widget(4, /*#__PURE__*/ forwardRef(function A(props, ref) { - return /*#__PURE__*/ React.createElement("span", _extends({ - ref: ref - }, props), "A"); - }), { - side: -100, - key: "widget-a" - }), - widget(4, /*#__PURE__*/ forwardRef(function C(props, ref) { - return /*#__PURE__*/ React.createElement("span", _extends({ - ref: ref - }, props), "C"); - }), { - side: 2, - key: "widget-c" - }) - ]) - ] - }); - expect(view.dom.textContent).toBe("fooABCbar"); - }); - it("draws a widget in an empty node", ()=>{ - const { view } = tempEditor({ - doc: doc(p()), - plugins: [ - decoPlugin([ - "1-widget" - ]) - ] - }); - expect(view.dom.querySelectorAll("button")).toHaveLength(1); - }); - it("draws widgets on node boundaries", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo", em("bar"))), - plugins: [ - decoPlugin([ - "4-widget" - ]) - ] - }); - expect(view.dom.querySelectorAll("button")).toHaveLength(1); - }); - it("draws decorations from multiple plugins", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo", em("bar"))), - plugins: [ - decoPlugin([ - "2-widget" - ]), - decoPlugin([ - "6-widget" - ]) - ] - }); - expect(view.dom.querySelectorAll("button")).toHaveLength(2); - }); - it("calls widget destroy methods", ()=>{ - let destroyed = false; - const DestroyableWidget = /*#__PURE__*/ forwardRef(function DestroyableWidget(props, ref) { - useEffect(()=>{ - destroyed = true; - }); - return /*#__PURE__*/ React.createElement("button", _extends({ - ref: ref - }, props)); - }); - const { view } = tempEditor({ - doc: doc(p("abc")), - plugins: [ - decoPlugin([ - widget(2, DestroyableWidget, { - key: "destroyable-widget" - }) - ]) - ] - }); - act(()=>{ - view.dispatch(view.state.tr.delete(1, 4)); - }); - expect(destroyed).toBeTruthy(); - }); - it("draws inline decorations spanning multiple parents", ()=>{ - const { view } = tempEditor({ - doc: doc(p("long first ", em("p"), "aragraph"), p("two")), - plugins: [ - decoPlugin([ - "7-25-foo" - ]) - ] - }); - const foos = view.dom.querySelectorAll(".foo"); - expect(foos).toHaveLength(4); - expect(foos[0].textContent).toBe("irst "); - expect(foos[1].textContent).toBe("p"); - expect(foos[2].textContent).toBe("aragraph"); - expect(foos[3].textContent).toBe("tw"); - }); - it("draws inline decorations across empty paragraphs", ()=>{ - const { view } = tempEditor({ - doc: doc(p("first"), p(), p("second")), - plugins: [ - decoPlugin([ - "3-12-foo" - ]) - ] - }); - const foos = view.dom.querySelectorAll(".foo"); - expect(foos).toHaveLength(2); - expect(foos[0].textContent).toBe("rst"); - expect(foos[1].textContent).toBe("se"); - }); - it("can handle inline decorations ending at the start or end of a node", ()=>{ - const { view } = tempEditor({ - doc: doc(p(), p()), - plugins: [ - decoPlugin([ - "1-3-foo" - ]) - ] - }); - expect(view.dom.querySelector(".foo")).toBeNull(); - }); - it("can draw decorations with multiple classes", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo")), - plugins: [ - decoPlugin([ - "1-4-foo bar" - ]) - ] - }); - expect(view.dom.querySelectorAll(".foo")).toHaveLength(1); - expect(view.dom.querySelectorAll(".bar")).toHaveLength(1); - }); - it("supports overlapping inline decorations", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foobar")), - plugins: [ - decoPlugin([ - "1-3-foo", - "2-5-bar" - ]) - ] - }); - const foos = view.dom.querySelectorAll(".foo"); - const bars = view.dom.querySelectorAll(".bar"); - expect(foos).toHaveLength(2); - expect(bars).toHaveLength(2); - expect(foos[0].textContent).toBe("f"); - expect(foos[1].textContent).toBe("o"); - expect(bars[0].textContent).toBe("o"); - expect(bars[1].textContent).toBe("ob"); - }); - it("doesn't redraw when irrelevant decorations change", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo"), p("baz")), - plugins: [ - decoPlugin([ - "7-8-foo" - ]) - ] - }); - const para2 = view.dom.lastChild; - act(()=>{ - updateDeco(view, [ - make("2-3-bar") - ]); - }); - expect(view.dom.lastChild).toBe(para2); - expect(view.dom.querySelector(".bar")).not.toBeNull(); - }); - it("doesn't redraw when irrelevant content changes", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo"), p("baz")), - plugins: [ - decoPlugin([ - "7-8-foo" - ]) - ] - }); - const para2 = view.dom.lastChild; - act(()=>{ - view.dispatch(view.state.tr.delete(2, 3)); - view.dispatch(view.state.tr.delete(2, 3)); - }); - expect(view.dom.lastChild).toBe(para2); - }); - it("can add a widget on a node boundary", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo", em("bar"))), - plugins: [ - decoPlugin([]) - ] - }); - act(()=>{ - updateDeco(view, [ - make("4-widget") - ]); - }); - expect(view.dom.querySelectorAll("button")).toHaveLength(1); - }); - it("can remove a widget on a node boundary", ()=>{ - const dec = make("4-widget"); - const { view } = tempEditor({ - doc: doc(p("foo", em("bar"))), - plugins: [ - decoPlugin([ - dec - ]) - ] - }); - act(()=>{ - updateDeco(view, null, [ - dec - ]); - }); - expect(view.dom.querySelector("button")).toBeNull(); - }); - it("can remove the class from a text node", ()=>{ - const dec = make("1-4-foo"); - const { view } = tempEditor({ - doc: doc(p("abc")), - plugins: [ - decoPlugin([ - dec - ]) - ] - }); - expect(view.dom.querySelector(".foo")).not.toBeNull(); - act(()=>{ - updateDeco(view, null, [ - dec - ]); - }); - expect(view.dom.querySelector(".foo")).toBeNull(); - }); - it("can remove the class from part of a text node", ()=>{ - const dec = make("2-4-foo"); - const { view } = tempEditor({ - doc: doc(p("abcd")), - plugins: [ - decoPlugin([ - dec - ]) - ] - }); - expect(view.dom.querySelector(".foo")).not.toBeNull(); - act(()=>{ - updateDeco(view, null, [ - dec - ]); - }); - expect(view.dom.querySelector(".foo")).toBeNull(); - expect(view.dom.firstChild.innerHTML).toBe("abcd"); - }); - it("can change the class for part of a text node", ()=>{ - const dec = make("2-4-foo"); - const { view } = tempEditor({ - doc: doc(p("abcd")), - plugins: [ - decoPlugin([ - dec - ]) - ] - }); - expect(view.dom.querySelector(".foo")).not.toBeNull(); - act(()=>{ - updateDeco(view, [ - make("2-4-bar") - ], [ - dec - ]); - }); - expect(view.dom.querySelector(".foo")).toBeNull(); - expect(view.dom.querySelector(".bar")).not.toBeNull(); - }); - it("draws a widget added in the middle of a text node", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo")), - plugins: [ - decoPlugin([]) - ] - }); - act(()=>{ - updateDeco(view, [ - make("3-widget") - ]); - }); - expect(view.dom.firstChild.textContent).toBe("foωo"); - }); - it("can update a text node around a widget", ()=>{ - const { view } = tempEditor({ - doc: doc(p("bar")), - plugins: [ - decoPlugin([ - "3-widget" - ]) - ] - }); - act(()=>{ - view.dispatch(view.state.tr.delete(1, 2)); - }); - expect(view.dom.querySelectorAll("button")).toHaveLength(1); - expect(view.dom.firstChild.textContent).toBe("aωr"); - }); - it("can update a text node with an inline decoration", ()=>{ - const { view } = tempEditor({ - doc: doc(p("bar")), - plugins: [ - decoPlugin([ - "1-3-foo" - ]) - ] - }); - act(()=>{ - view.dispatch(view.state.tr.delete(1, 2)); - }); - const foo = view.dom.querySelector(".foo"); - expect(foo).not.toBeNull(); - expect(foo.textContent).toBe("a"); - expect(foo.nextSibling.textContent).toBe("r"); - }); - it("correctly redraws a partially decorated node when a widget is added", ()=>{ - const { view } = tempEditor({ - doc: doc(p("one", em("two"))), - plugins: [ - decoPlugin([ - "1-6-foo" - ]) - ] - }); - act(()=>{ - updateDeco(view, [ - make("6-widget") - ]); - }); - const foos = view.dom.querySelectorAll(".foo"); - expect(foos).toHaveLength(2); - expect(foos[0].textContent).toBe("one"); - expect(foos[1].textContent).toBe("tw"); - }); - it("correctly redraws when skipping split text node", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo")), - plugins: [ - decoPlugin([ - "3-widget", - "3-4-foo" - ]) - ] - }); - act(()=>{ - updateDeco(view, [ - make("4-widget") - ]); - }); - expect(view.dom.querySelectorAll("button")).toHaveLength(2); - }); - it("drops removed node decorations from the view", ()=>{ - const deco = Decoration.node(1, 6, { - class: "cls" - }); - const { view } = tempEditor({ - doc: doc(blockquote(p("foo"), p("bar"))), - plugins: [ - decoPlugin([ - deco - ]) - ] - }); - act(()=>{ - updateDeco(view, null, [ - deco - ]); - }); - expect(view.dom.querySelector(".cls")).toBeNull(); - }); - it("can update a node's attributes without replacing the node", ()=>{ - const deco = Decoration.node(0, 5, { - title: "title", - class: "foo" - }); - const { view } = tempEditor({ - doc: doc(p("foo")), - plugins: [ - decoPlugin([ - deco - ]) - ] - }); - const para = view.dom.querySelector("p"); - act(()=>{ - updateDeco(view, [ - Decoration.node(0, 5, { - class: "foo bar" - }) - ], [ - deco - ]); - }); - expect(view.dom.querySelector("p")).toBe(para); - expect(para.className).toBe("foo bar"); - expect(para.title).toBeFalsy(); - }); - it("can add and remove CSS custom properties from a node", ()=>{ - const deco = Decoration.node(0, 5, { - style: "--my-custom-property:36px" - }); - const { view } = tempEditor({ - doc: doc(p("foo")), - plugins: [ - decoPlugin([ - deco - ]) - ] - }); - expect(view.dom.querySelector("p").style.getPropertyValue("--my-custom-property")).toBe("36px"); - act(()=>{ - updateDeco(view, null, [ - deco - ]); - }); - expect(view.dom.querySelector("p").style.getPropertyValue("--my-custom-property")).toBe(""); - }); - it("updates decorated nodes even if a widget is added before them", ()=>{ - const { view } = tempEditor({ - doc: doc(p("a"), p("b")), - plugins: [ - decoPlugin([]) - ] - }); - const lastP = view.dom.querySelectorAll("p")[1]; - act(()=>{ - updateDeco(view, [ - make("3-widget"), - Decoration.node(3, 6, { - style: "color: red" - }) - ]); - }); - expect(lastP.style.color).toBe("red"); - }); - it("doesn't redraw nodes when a widget before them is replaced", ()=>{ - const w0 = make("3-widget"); - const { view } = tempEditor({ - doc: doc(h1("a"), p("b")), - plugins: [ - decoPlugin([ - w0 - ]) - ] - }); - const initialP = view.dom.querySelector("p"); - act(()=>{ - view.dispatch(view.state.tr.setMeta("updateDecorations", { - add: [ - make("3-widget") - ], - remove: [ - w0 - ] - }).insertText("c", 5)); - }); - expect(view.dom.querySelector("p")).toBe(initialP); - }); - it("can add and remove inline style", ()=>{ - const deco = Decoration.inline(1, 6, { - style: "color: rgba(0,10,200,.4); text-decoration: underline" - }); - const { view } = tempEditor({ - doc: doc(p("al", img(), "lo")), - plugins: [ - decoPlugin([ - deco - ]) - ] - }); - expect(view.dom.querySelector("img").style.color).toMatch(/rgba/); - expect(view.dom.querySelector("img").previousSibling.style.textDecoration).toBe("underline"); - act(()=>{ - updateDeco(view, null, [ - deco - ]); - }); - expect(view.dom.querySelector("img").style.color).toBe(""); - expect(view.dom.querySelector("img").style.textDecoration).toBe(""); - }); - it("passes decorations to a node view", ()=>{ - let current = ""; - const { view } = tempEditor({ - doc: doc(p("foo"), hr()), - plugins: [ - decoPlugin([]) - ], - nodeViews: { - horizontal_rule: /*#__PURE__*/ forwardRef(function HR(props, ref) { - current = props.nodeProps.decorations.map((d)=>d.spec.name).join(); - return /*#__PURE__*/ React.createElement("hr", { - ref: ref - }); - }) - } - }); - const a = Decoration.node(5, 6, {}, { - name: "a" - }); - act(()=>{ - updateDeco(view, [ - a - ], []); - }); - expect(current).toBe("a"); - act(()=>{ - updateDeco(view, [ - Decoration.node(5, 6, {}, { - name: "b" - }), - Decoration.node(5, 6, {}, { - name: "c" - }) - ], [ - a - ]); - }); - expect(current).toBe("b,c"); - }); - it("draws the specified marks around a widget", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foobar")), - plugins: [ - decoPlugin([ - widget(4, /*#__PURE__*/ forwardRef(function Img(props, ref) { - return /*#__PURE__*/ React.createElement("img", _extends({}, props, { - ref: ref - })); - }), { - marks: [ - schema.mark("em") - ], - key: "img-widget" - }) - ]) - ] - }); - expect(view.dom.querySelector("em img")).not.toBeNull(); - }); - it("draws widgets inside the marks for their side", ()=>{ - const { view } = tempEditor({ - doc: doc(p(em("foo"), strong("bar"))), - plugins: [ - decoPlugin([ - widget(4, /*#__PURE__*/ forwardRef(function Img(props, ref) { - return /*#__PURE__*/ React.createElement("img", _extends({}, props, { - ref: ref - })); - }), { - side: -1, - key: "img-widget" - }) - ]), - decoPlugin([ - widget(4, /*#__PURE__*/ forwardRef(function BR(props, ref) { - return /*#__PURE__*/ React.createElement("br", _extends({}, props, { - ref: ref - })); - }), { - key: "br-widget" - }) - ]), - decoPlugin([ - widget(7, /*#__PURE__*/ forwardRef(function Span(props, ref) { - return /*#__PURE__*/ React.createElement("span", _extends({}, props, { - ref: ref - })); - }), { - side: 1, - key: "span-widget" - }) - ]) - ] - }); - expect(view.dom.querySelector("em img")).not.toBeNull(); - expect(view.dom.querySelector("strong img")).toBeNull(); - expect(view.dom.querySelector("strong br")).not.toBeNull(); - expect(view.dom.querySelector("em br")).toBeNull(); - expect(view.dom.querySelector("strong span")).toBeNull(); - }); - it("draws decorations inside node views", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo")), - nodeViews: { - paragraph: /*#__PURE__*/ forwardRef(function Paragraph(param, ref) { - let { nodeProps , children , ...props } = param; - return /*#__PURE__*/ React.createElement("p", _extends({ - ref: ref - }, props), children); - }) - }, - plugins: [ - decoPlugin([ - widget(2, /*#__PURE__*/ forwardRef(function Img(props, ref) { - return /*#__PURE__*/ React.createElement("img", _extends({}, props, { - ref: ref - })); - }), { - key: "img-widget" - }) - ]) - ] - }); - expect(view.dom.querySelector("img")).not.toBeNull(); - }); - it("can delay widget drawing to render time", ()=>{ - const { view } = tempEditor({ - doc: doc(p("hi")), - decorations (state) { - return DecorationSet.create(state.doc, [ - widget(3, /*#__PURE__*/ forwardRef(function Span(props, ref) { - useEditorEffect((view)=>{ - expect(view?.state).toBe(state); - }); - return /*#__PURE__*/ React.createElement("span", _extends({}, props, { - ref: ref - }), "!"); - }), { - key: "span-widget" - }) - ]); - } - }); - expect(view.dom.textContent).toBe("hi!"); - }); - it("supports widgets querying their own position", ()=>{ - tempEditor({ - doc: doc(p("hi")), - decorations (state) { - return DecorationSet.create(state.doc, [ - widget(3, /*#__PURE__*/ forwardRef(function Widget(param, ref) { - let { pos , ...props } = param; - expect(pos).toBe(3); - return /*#__PURE__*/ React.createElement("button", _extends({ - ref: ref - }, props), "ω"); - }), { - key: "button-widget" - }) - ]); - } - }); - }); - it("doesn't redraw widgets with matching keys", ()=>{ - const { view } = tempEditor({ - doc: doc(p("hi")), - decorations (state) { - return DecorationSet.create(state.doc, [ - widget(2, Widget, { - key: "myButton" - }) - ]); - } - }); - const widgetDOM = view.dom.querySelector("button"); - act(()=>{ - view.dispatch(view.state.tr.insertText("!", 2, 2)); - }); - expect(view.dom.querySelector("button")).toBe(widgetDOM); - }); - it("doesn't redraw widgets with identical specs", ()=>{ - const { view } = tempEditor({ - doc: doc(p("hi")), - decorations (state) { - return DecorationSet.create(state.doc, [ - widget(2, Widget, { - side: 1, - key: "widget" - }) - ]); - } - }); - const widgetDOM = view.dom.querySelector("button"); - act(()=>{ - view.dispatch(view.state.tr.insertText("!", 2, 2)); - }); - expect(view.dom.querySelector("button")).toBe(widgetDOM); - }); - it("doesn't get confused by split text nodes", ()=>{ - const { view } = tempEditor({ - doc: doc(p("abab")), - decorations (state) { - return state.selection.from <= 1 ? null : DecorationSet.create(view.state.doc, [ - Decoration.inline(1, 2, { - class: "foo" - }), - Decoration.inline(3, 4, { - class: "foo" - }) - ]); - } - }); - act(()=>{ - view.dispatch(view.state.tr.setSelection(TextSelection.create(view.state.doc, 5))); - }); - expect(view.dom.textContent).toBe("abab"); - }); - it("only draws inline decorations on the innermost level", ()=>{ - const s = new Schema({ - nodes: { - doc: { - content: "(text | thing)*" - }, - text: {}, - thing: { - inline: true, - content: "text*", - toDOM: ()=>[ - "strong", - 0 - ], - parseDOM: [ - { - tag: "strong" - } - ] - } - } - }); - const { view } = tempEditor({ - doc: s.node("doc", null, [ - s.text("abc"), - s.node("thing", null, [ - s.text("def") - ]), - s.text("ghi") - ]), - decorations: (s)=>DecorationSet.create(s.doc, [ - Decoration.inline(1, 10, { - class: "dec" - }) - ]) - }); - const styled = view.dom.querySelectorAll(".dec"); - expect(styled).toHaveLength(3); - expect(Array.prototype.map.call(styled, (n)=>n.textContent).join()).toBe("bc,def,gh"); - expect(styled[1].parentNode.nodeName).toBe("STRONG"); - }); - it("can handle nodeName decoration overlapping with classes", ()=>{ - const { view } = tempEditor({ - doc: doc(p("one two three")), - plugins: [ - decoPlugin([ - Decoration.inline(2, 13, { - class: "foo" - }), - Decoration.inline(5, 8, { - nodeName: "em" - }) - ]) - ] - }); - expect(view.dom.firstChild.innerHTML).toBe('one two three'); - }); - it("can handle combining decorations from parent editors in child editors", ()=>{ - let decosFromFirstEditor; - let { view } = tempEditor({ - doc: doc(p("one two three")), - plugins: [ - decoPlugin([ - Decoration.inline(2, 13, { - class: "foo" - }) - ]), - decoPlugin([ - Decoration.inline(2, 13, { - class: "bar" - }) - ]) - ], - nodeViews: { - paragraph: /*#__PURE__*/ forwardRef(function Paragraph(param, ref) { - let { nodeProps , children , ...props } = param; - decosFromFirstEditor = nodeProps.innerDecorations; - return /*#__PURE__*/ React.createElement("p", _extends({ - ref: ref - }, props), children); - }) - } - }); - ({ view } = tempEditor({ - doc: doc(p("one two three")), - plugins: [ - decoPlugin([ - Decoration.inline(1, 12, { - class: "baz" - }) - ]) - ], - decorations: ()=>decosFromFirstEditor - })); - expect(view.dom.querySelectorAll(".foo")).toHaveLength(1); - expect(view.dom.querySelectorAll(".bar")).toHaveLength(1); - expect(view.dom.querySelectorAll(".baz")).toHaveLength(1); - }); -}); diff --git a/dist/esm/components/__tests__/ProseMirror.draw.test.js b/dist/esm/components/__tests__/ProseMirror.draw.test.js deleted file mode 100644 index e93bfa2b..00000000 --- a/dist/esm/components/__tests__/ProseMirror.draw.test.js +++ /dev/null @@ -1,301 +0,0 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ import { act } from "@testing-library/react"; -import { Schema } from "prosemirror-model"; -import { Plugin } from "prosemirror-state"; -import { doc, h1, hr, p, pre, schema, strong } from "prosemirror-test-builder"; -import React, { forwardRef } from "react"; -import { tempEditor } from "../../testing/editorViewTestHelpers.js"; -describe("EditorView draw", ()=>{ - it("updates the DOM", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo")) - }); - act(()=>{ - view.dispatch(view.state.tr.insertText("bar")); - }); - expect(view.dom.textContent).toBe("barfoo"); - }); - it("doesn't redraw nodes after changes", ()=>{ - const { view } = tempEditor({ - doc: doc(h1("foo"), p("bar")) - }); - const oldP = view.dom.querySelector("p"); - act(()=>{ - view.dispatch(view.state.tr.insertText("!")); - }); - expect(view.dom.querySelector("p")).toBe(oldP); - }); - it("doesn't redraw nodes before changes", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo"), h1("bar")) - }); - const oldP = view.dom.querySelector("p"); - act(()=>{ - view.dispatch(view.state.tr.insertText("!", 2)); - }); - expect(view.dom.querySelector("p")).toBe(oldP); - }); - it("doesn't redraw nodes between changes", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo"), h1("bar"), pre("baz")) - }); - const oldP = view.dom.querySelector("p"); - const oldPre = view.dom.querySelector("pre"); - act(()=>{ - view.dispatch(view.state.tr.insertText("!", 2)); - }); - expect(view.dom.querySelector("p")).toBe(oldP); - expect(view.dom.querySelector("pre")).toBe(oldPre); - }); - it("doesn't redraw siblings of a split node", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo"), h1("bar"), pre("baz")) - }); - const oldP = view.dom.querySelector("p"); - const oldPre = view.dom.querySelector("pre"); - act(()=>{ - view.dispatch(view.state.tr.split(8)); - }); - expect(view.dom.querySelector("p")).toBe(oldP); - expect(view.dom.querySelector("pre")).toBe(oldPre); - }); - it("doesn't redraw siblings of a joined node", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo"), h1("bar"), h1("x"), pre("baz")) - }); - const oldP = view.dom.querySelector("p"); - const oldPre = view.dom.querySelector("pre"); - act(()=>{ - view.dispatch(view.state.tr.join(10)); - }); - expect(view.dom.querySelector("p")).toBe(oldP); - expect(view.dom.querySelector("pre")).toBe(oldPre); - }); - it("doesn't redraw after a big deletion", ()=>{ - const { view } = tempEditor({ - doc: doc(p(), p(), p(), p(), p(), p(), p(), p(), h1("!"), p(), p()) - }); - const oldH = view.dom.querySelector("h1"); - act(()=>{ - view.dispatch(view.state.tr.delete(2, 14)); - }); - expect(view.dom.querySelector("h1")).toBe(oldH); - }); - it("adds classes from the attributes prop", ()=>{ - const { view , rerender } = tempEditor({ - doc: doc(p()), - attributes: { - class: "foo bar" - } - }); - expect(view.dom.classList.contains("foo")).toBeTruthy(); - expect(view.dom.classList.contains("bar")).toBeTruthy(); - expect(view.dom.classList.contains("ProseMirror")).toBeTruthy(); - act(()=>{ - rerender({ - attributes: { - class: "baz" - } - }); - }); - expect(!view.dom.classList.contains("foo")).toBeTruthy(); - expect(view.dom.classList.contains("baz")).toBeTruthy(); - }); - it("adds style from the attributes prop", ()=>{ - const { view } = tempEditor({ - doc: doc(p()), - attributes: { - style: "border: 1px solid red;" - }, - plugins: [ - new Plugin({ - props: { - attributes: { - style: "background: red;" - } - } - }), - new Plugin({ - props: { - attributes: { - style: "color: red;" - } - } - }) - ] - }); - expect(view.dom.style.border).toBe("1px solid red"); - expect(view.dom.style.backgroundColor).toBe("red"); - expect(view.dom.style.color).toBe("red"); - }); - it("can set other attributes", ()=>{ - const { view , rerender } = tempEditor({ - doc: doc(p()), - attributes: { - spellcheck: "false", - "aria-label": "hello" - } - }); - expect(view.dom.getAttribute("spellcheck")).toBe("false"); - expect(view.dom.getAttribute("aria-label")).toBe("hello"); - act(()=>{ - rerender({ - attributes: { - style: "background-color: yellow" - } - }); - }); - expect(view.dom.hasAttribute("aria-label")).toBe(false); - expect(view.dom.style.backgroundColor).toBe("yellow"); - }); - it("can't set the contenteditable attribute", ()=>{ - const { view } = tempEditor({ - doc: doc(p()), - attributes: { - contenteditable: "false" - } - }); - expect(view.dom.getAttribute("contenteditable")).toBe("true"); - }); - it("understands the editable prop", ()=>{ - const { view , rerender } = tempEditor({ - doc: doc(p()), - editable: ()=>false - }); - expect(view.dom.getAttribute("contenteditable")).toBe("false"); - rerender({ - editable: ()=>true - }); - expect(view.dom.getAttribute("contenteditable")).toBe("true"); - }); - it("doesn't redraw following paragraphs when a paragraph is split", ()=>{ - const { view } = tempEditor({ - doc: doc(p("abcde"), p("fg")) - }); - const lastPara = view.dom.lastChild; - act(()=>{ - view.dispatch(view.state.tr.split(3)); - }); - expect(view.dom.lastChild).toBe(lastPara); - }); - it("doesn't greedily match nodes that have another match", ()=>{ - const { view } = tempEditor({ - doc: doc(p("a"), p("b"), p()) - }); - const secondPara = view.dom.querySelectorAll("p")[1]; - act(()=>{ - view.dispatch(view.state.tr.split(2)); - }); - expect(view.dom.querySelectorAll("p")[2]).toBe(secondPara); - }); - it("creates and destroys plugin views", ()=>{ - const events = []; - let PluginView = class PluginView { - update() { - events.push("update"); - } - destroy() { - events.push("destroy"); - } - }; - const plugin = new Plugin({ - view () { - events.push("create"); - return new PluginView(); - } - }); - const { view , unmount } = tempEditor({ - plugins: [ - plugin - ] - }); - act(()=>{ - view.dispatch(view.state.tr.insertText("u")); - }); - unmount(); - expect(events.join(" ")).toBe("create update destroy"); - }); - it("redraws changed node views", ()=>{ - const { view , rerender } = tempEditor({ - doc: doc(p("foo"), hr()) - }); - expect(view.dom.querySelector("hr")).toBeTruthy(); - rerender({ - nodeViews: { - horizontal_rule: /*#__PURE__*/ forwardRef(function Var(props, ref) { - return /*#__PURE__*/ React.createElement("var", { - ref: ref - }, props.children); - }) - } - }); - expect(!view.dom.querySelector("hr")).toBeTruthy(); - expect(view.dom.querySelector("var")).toBeTruthy(); - }); - it("doesn't get confused by merged nodes", ()=>{ - const { view } = tempEditor({ - doc: doc(p(strong("one"), " two ", strong("three"))) - }); - act(()=>{ - view.dispatch(view.state.tr.removeMark(1, 4, schema.marks.strong)); - }); - expect(view.dom.querySelectorAll("strong")).toHaveLength(1); - }); - it("doesn't redraw too much when marks are present", ()=>{ - const s = new Schema({ - nodes: { - doc: { - content: "paragraph+", - marks: "m" - }, - text: { - group: "inline" - }, - paragraph: schema.spec.nodes.get("paragraph") - }, - marks: { - m: { - toDOM: ()=>[ - "div", - { - class: "m" - }, - 0 - ], - parseDOM: [ - { - tag: "div.m" - } - ] - } - } - }); - const paragraphs = []; - for(let i = 1; i <= 10; i++)paragraphs.push(s.node("paragraph", null, [ - s.text("para " + i) - ], [ - s.mark("m") - ])); - const { view } = tempEditor({ - // @ts-expect-error this is fine - doc: s.node("doc", null, paragraphs) - }); - const initialChildren = Array.from(view.dom.querySelectorAll("p")); - const newParagraphs = []; - for(let i = -6; i < 0; i++)newParagraphs.push(s.node("paragraph", null, [ - s.text("para " + i) - ], [ - s.mark("m") - ])); - act(()=>{ - view.dispatch(view.state.tr.replaceWith(0, 8, newParagraphs)); - }); - const currentChildren = Array.from(view.dom.querySelectorAll("p")); - let sameAtEnd = 0; - while(sameAtEnd < currentChildren.length && sameAtEnd < initialChildren.length && currentChildren[currentChildren.length - sameAtEnd - 1] == initialChildren[initialChildren.length - sameAtEnd - 1])sameAtEnd++; - // $$FORK: Our node stability isn't _quite_ as robust - // as prosemirror-view's. The node adjacent to the one - // that was replaced also gets repainted. - // expect(sameAtEnd).toBe(9); - expect(sameAtEnd).toBe(8); - }); -}); diff --git a/dist/esm/components/__tests__/ProseMirror.node-view.test.js b/dist/esm/components/__tests__/ProseMirror.node-view.test.js deleted file mode 100644 index 86e6f646..00000000 --- a/dist/esm/components/__tests__/ProseMirror.node-view.test.js +++ /dev/null @@ -1,516 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-non-null-assertion */ function _extends() { - _extends = Object.assign || function(target) { - for(var i = 1; i < arguments.length; i++){ - var source = arguments[i]; - for(var key in source){ - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; - return _extends.apply(this, arguments); -} -import { act } from "@testing-library/react"; -import { Plugin } from "prosemirror-state"; -import { blockquote, br, doc, p } from "prosemirror-test-builder"; -import { Decoration, DecorationSet } from "prosemirror-view"; -import React, { forwardRef, useEffect } from "react"; -import { tempEditor } from "../../testing/editorViewTestHelpers.js"; -describe("React-based node views prop", ()=>{ - it("can replace a node's representation", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo", br())), - nodeViews: { - hard_break: /*#__PURE__*/ forwardRef(function Var(props, ref) { - return /*#__PURE__*/ React.createElement("var", { - ref: ref - }, props.children); - }) - } - }); - expect(view.dom.querySelector("var")).not.toBeNull(); - }); - it("can override drawing of a node's content", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo")), - nodeViews: { - paragraph: /*#__PURE__*/ forwardRef(function Paragraph(props, ref) { - return /*#__PURE__*/ React.createElement("p", { - ref: ref - }, props.nodeProps.node.textContent.toUpperCase()); - }) - } - }); - expect(view.dom.querySelector("p").textContent).toBe("FOO"); - act(()=>{ - view.dispatch(view.state.tr.insertText("a")); - }); - expect(view.dom.querySelector("p").textContent).toBe("AFOO"); - }); - // React makes this more or less trivial; the render - // method of the component _is_ the update (and create) - // method - // eslint-disable-next-line jest/no-disabled-tests - it.skip("can register its own update method", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo")), - nodeViews: { - paragraph: /*#__PURE__*/ forwardRef(function Paragraph(props, ref) { - return /*#__PURE__*/ React.createElement("p", { - ref: ref - }, props.nodeProps.node.textContent.toUpperCase()); - }) - } - }); - const para = view.dom.querySelector("p"); - view.dispatch(view.state.tr.insertText("a")); - expect(view.dom.querySelector("p")).toBe(para); - expect(para.textContent).toBe("AFOO"); - }); - it("allows decoration updates for node views with an update method", ()=>{ - const { view , rerender } = tempEditor({ - doc: doc(p("foo")), - nodeViews: { - paragraph: /*#__PURE__*/ forwardRef(function Paragraph(param, ref) { - let { children , nodeProps , ...props } = param; - return /*#__PURE__*/ React.createElement("p", _extends({ - ref: ref - }, props), children); - }) - } - }); - rerender({ - decorations (state) { - return DecorationSet.create(state.doc, [ - Decoration.inline(2, 3, { - someattr: "ok" - }), - Decoration.node(0, 5, { - otherattr: "ok" - }) - ]); - } - }); - expect(view.dom.querySelector("[someattr]")).not.toBeNull(); - expect(view.dom.querySelector("[otherattr]")).not.toBeNull(); - }); - it("can provide a contentDOM property", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo")), - nodeViews: { - paragraph: /*#__PURE__*/ forwardRef(function Paragraph(props, ref) { - return(// ContentDOM is inferred from where props.children is rendered - /*#__PURE__*/ React.createElement("p", { - ref: ref - }, props.children)); - }) - } - }); - const para = view.dom.querySelector("p"); - act(()=>{ - view.dispatch(view.state.tr.insertText("a")); - }); - expect(view.dom.querySelector("p")).toBe(para); - expect(para.textContent).toBe("afoo"); - }); - it("has its destroy method called", ()=>{ - let destroyed = false; - const { view } = tempEditor({ - doc: doc(p("foo", br())), - nodeViews: { - hard_break: /*#__PURE__*/ forwardRef(function BR(_props, ref) { - // React implements "destroy methods" with effect - // hooks - useEffect(()=>{ - return ()=>{ - destroyed = true; - }; - }, []); - return /*#__PURE__*/ React.createElement("br", { - ref: ref - }); - }) - } - }); - expect(destroyed).toBeFalsy(); - act(()=>{ - view.dispatch(view.state.tr.delete(3, 5)); - }); - expect(destroyed).toBeTruthy(); - }); - it("can query its own position", ()=>{ - let pos; - const { view } = tempEditor({ - doc: doc(blockquote(p("abc"), p("foo", br()))), - nodeViews: { - hard_break: /*#__PURE__*/ forwardRef(function BR(props, ref) { - pos = props.nodeProps.pos; - return /*#__PURE__*/ React.createElement("br", { - ref: ref - }); - }) - } - }); - expect(pos).toBe(10); - act(()=>{ - view.dispatch(view.state.tr.insertText("a")); - }); - expect(pos).toBe(11); - }); - it("has access to outer decorations", ()=>{ - const plugin = new Plugin({ - state: { - init () { - return null; - }, - apply (tr, prev) { - return tr.getMeta("setDeco") || prev; - } - }, - props: { - decorations (state) { - const deco = this.getState(state); - return deco && DecorationSet.create(state.doc, [ - Decoration.inline(0, state.doc.content.size, {}, { - name: deco - }) - ]); - } - } - }); - const { view } = tempEditor({ - doc: doc(p("foo", br())), - plugins: [ - plugin - ], - nodeViews: { - hard_break: /*#__PURE__*/ forwardRef(function Var(props, ref) { - return /*#__PURE__*/ React.createElement("var", { - ref: ref - }, props.nodeProps.decorations.length ? props.nodeProps.decorations[0].spec.name : "[]"); - }) - } - }); - expect(view.dom.querySelector("var").textContent).toBe("[]"); - act(()=>{ - view.dispatch(view.state.tr.setMeta("setDeco", "foo")); - }); - expect(view.dom.querySelector("var").textContent).toBe("foo"); - act(()=>{ - view.dispatch(view.state.tr.setMeta("setDeco", "bar")); - }); - expect(view.dom.querySelector("var").textContent).toBe("bar"); - }); - it("provides access to inner decorations in the constructor", ()=>{ - tempEditor({ - doc: doc(p("foo")), - nodeViews: { - paragraph: /*#__PURE__*/ forwardRef(function Paragraph(props, ref) { - expect(props.nodeProps.innerDecorations.find().map((d)=>`${d.from}-${d.to}`).join()).toBe("1-2"); - return /*#__PURE__*/ React.createElement("p", { - ref: ref - }, props.children); - }) - }, - decorations (state) { - return DecorationSet.create(state.doc, [ - Decoration.inline(2, 3, { - someattr: "ok" - }), - Decoration.node(0, 5, { - otherattr: "ok" - }) - ]); - } - }); - }); - it("provides access to inner decorations in the update method", ()=>{ - let innerDecos = []; - const { rerender } = tempEditor({ - doc: doc(p("foo")), - nodeViews: { - paragraph: /*#__PURE__*/ forwardRef(function Paragraph(props, ref) { - innerDecos = props.nodeProps.innerDecorations.find().map((d)=>`${d.from}-${d.to}`); - return /*#__PURE__*/ React.createElement("p", { - ref: ref - }, props.children); - }) - } - }); - rerender({ - decorations (state) { - return DecorationSet.create(state.doc, [ - Decoration.inline(2, 3, { - someattr: "ok" - }), - Decoration.node(0, 5, { - otherattr: "ok" - }) - ]); - } - }); - expect(innerDecos.join()).toBe("1-2"); - }); -}); -describe("Classic node views prop", ()=>{ - it("can replace a node's representation", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo", br())), - customNodeViews: { - hard_break () { - return { - dom: document.createElement("var") - }; - } - } - }); - expect(view.dom.querySelector("var")).not.toBeNull(); - }); - it("can override drawing of a node's content", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo")), - customNodeViews: { - paragraph (node) { - const dom = document.createElement("p"); - dom.textContent = node.textContent.toUpperCase(); - return { - dom - }; - } - } - }); - expect(view.dom.querySelector("p").textContent).toBe("FOO"); - act(()=>{ - view.dispatch(view.state.tr.insertText("a")); - }); - // TODO: Fix this. I think that ProseMirror's behavior is to - // call the constructor again in this scenario. - expect(view.dom.querySelector("p").textContent).toBe("AFOO"); - }); - it("can register its own update method", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo")), - customNodeViews: { - paragraph (node) { - const dom = document.createElement("p"); - dom.textContent = node.textContent.toUpperCase(); - return { - dom, - update (node) { - dom.textContent = node.textContent.toUpperCase(); - return true; - } - }; - } - } - }); - const para = view.dom.querySelector("p"); - act(()=>{ - view.dispatch(view.state.tr.insertText("a")); - }); - expect(view.dom.querySelector("p")).toBe(para); - expect(para.textContent).toBe("AFOO"); - }); - it("allows decoration updates for node views with an update method", ()=>{ - const { view , rerender } = tempEditor({ - doc: doc(p("foo")), - customNodeViews: { - paragraph (node) { - const dom = document.createElement("p"); - return { - dom, - contentDOM: dom, - update (node_) { - return node.sameMarkup(node_); - } - }; - } - } - }); - rerender({ - decorations (state) { - return DecorationSet.create(state.doc, [ - Decoration.inline(2, 3, { - someattr: "ok" - }), - Decoration.node(0, 5, { - otherattr: "ok" - }) - ]); - } - }); - expect(view.dom.querySelector("[someattr]")).not.toBeNull(); - expect(view.dom.querySelector("[otherattr]")).not.toBeNull(); - }); - it("can provide a contentDOM property", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo")), - customNodeViews: { - paragraph () { - const dom = document.createElement("p"); - return { - dom, - contentDOM: dom - }; - } - } - }); - const para = view.dom.querySelector("p"); - act(()=>{ - view.dispatch(view.state.tr.insertText("a")); - }); - expect(view.dom.querySelector("p")).toBe(para); - expect(para.textContent).toBe("afoo"); - }); - it("has its destroy method called", ()=>{ - let destroyed = false; - const { view } = tempEditor({ - doc: doc(p("foo", br())), - customNodeViews: { - hard_break () { - return { - dom: document.createElement("br"), - destroy: ()=>destroyed = true - }; - } - } - }); - expect(destroyed).toBeFalsy(); - act(()=>{ - view.dispatch(view.state.tr.delete(3, 5)); - }); - expect(destroyed).toBeTruthy(); - }); - it("can query its own position", ()=>{ - let get; - const { view } = tempEditor({ - doc: doc(blockquote(p("abc"), p("foo", br()))), - customNodeViews: { - hard_break (_n, _v, getPos) { - expect(getPos()).toBe(10); - get = getPos; - return { - dom: document.createElement("br") - }; - } - } - }); - expect(get()).toBe(10); - act(()=>{ - view.dispatch(view.state.tr.insertText("a")); - }); - expect(get()).toBe(11); - }); - it("has access to outer decorations", ()=>{ - const plugin = new Plugin({ - state: { - init () { - return null; - }, - apply (tr, prev) { - return tr.getMeta("setDeco") || prev; - } - }, - props: { - decorations (state) { - const deco = this.getState(state); - return deco && DecorationSet.create(state.doc, [ - Decoration.inline(0, state.doc.content.size, {}, { - name: deco - }) - ]); - } - } - }); - const { view } = tempEditor({ - doc: doc(p("foo", br())), - plugins: [ - plugin - ], - customNodeViews: { - hard_break (_n, _v, _p, deco) { - const dom = document.createElement("var"); - function update(deco) { - dom.textContent = deco.length ? deco[0].spec.name : "[]"; - } - update(deco); - return { - dom, - update (_, deco) { - update(deco); - return true; - } - }; - } - } - }); - expect(view.dom.querySelector("var").textContent).toBe("[]"); - act(()=>{ - view.dispatch(view.state.tr.setMeta("setDeco", "foo")); - }); - expect(view.dom.querySelector("var").textContent).toBe("foo"); - act(()=>{ - view.dispatch(view.state.tr.setMeta("setDeco", "bar")); - }); - expect(view.dom.querySelector("var").textContent).toBe("bar"); - }); - it("provides access to inner decorations in the constructor", ()=>{ - tempEditor({ - doc: doc(p("foo")), - customNodeViews: { - paragraph (_node, _v, _pos, _outer, innerDeco) { - const dom = document.createElement("p"); - expect(innerDeco.find().map((d)=>`${d.from}-${d.to}`).join()).toBe("1-2"); - return { - dom, - contentDOM: dom - }; - } - }, - decorations (state) { - return DecorationSet.create(state.doc, [ - Decoration.inline(2, 3, { - someattr: "ok" - }), - Decoration.node(0, 5, { - otherattr: "ok" - }) - ]); - } - }); - }); - it("provides access to inner decorations in the update method", ()=>{ - let innerDecos = []; - const { rerender } = tempEditor({ - doc: doc(p("foo")), - customNodeViews: { - paragraph (node) { - const dom = document.createElement("p"); - return { - dom, - contentDOM: dom, - update (node_, _, innerDecoSet) { - innerDecos = innerDecoSet.find().map((d)=>`${d.from}-${d.to}`); - return node.sameMarkup(node_); - } - }; - } - } - }); - rerender({ - decorations (state) { - return DecorationSet.create(state.doc, [ - Decoration.inline(2, 3, { - someattr: "ok" - }), - Decoration.node(0, 5, { - otherattr: "ok" - }) - ]); - } - }); - expect(innerDecos.join()).toBe("1-2"); - }); -}); diff --git a/dist/esm/components/__tests__/ProseMirror.selection.test.js b/dist/esm/components/__tests__/ProseMirror.selection.test.js deleted file mode 100644 index ee22154d..00000000 --- a/dist/esm/components/__tests__/ProseMirror.selection.test.js +++ /dev/null @@ -1,443 +0,0 @@ -/* eslint-disable jest/no-disabled-tests */ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-non-null-assertion */ import { act } from "@testing-library/react"; -import { NodeSelection, Selection } from "prosemirror-state"; -import { blockquote, br, code, code_block, doc, em, hr, img as img_, li, p, strong, ul } from "prosemirror-test-builder"; -import { Decoration, DecorationSet } from "prosemirror-view"; -import { findTextNode, tempEditor } from "../../testing/editorViewTestHelpers.js"; -import { setupProseMirrorView } from "../../testing/setupProseMirrorView.js"; -const img = img_({ - src: "data:image/gif;base64,R0lGODlhBQAFAIABAAAAAP///yH5BAEKAAEALAAAAAAFAAUAAAIEjI+pWAA7" -}); -function allPositions(doc) { - const found = []; - function scan(node, start) { - if (node.isTextblock) { - for(let i = 0; i <= node.content.size; i++)found.push(start + i); - } else { - node.forEach((child, offset)=>scan(child, start + offset + 1)); - } - } - scan(doc, 0); - return found; -} -function setDOMSel(node, offset) { - const range = document.createRange(); - range.setEnd(node, offset); - range.setStart(node, offset); - const sel = window.getSelection(); - sel.removeAllRanges(); - sel.addRange(range); -} -function getSel() { - const sel = window.getSelection(); - let node = sel.focusNode, offset = sel.focusOffset; - while(node && node.nodeType != 3){ - const after = offset < node.childNodes.length && node.childNodes[offset]; - const before = offset > 0 && node.childNodes[offset - 1]; - if (after) { - node = after; - offset = 0; - } else if (before) { - node = before; - offset = node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length; - } else break; - } - return { - node: node, - offset: offset - }; -} -function setSel(view, sel) { - const selection = typeof sel == "number" ? Selection.near(view.state.doc.resolve(sel)) : sel; - act(()=>{ - view.dispatch(view.state.tr.setSelection(selection)); - }); -} -function event(code) { - const event = document.createEvent("Event"); - event.initEvent("keydown", true, true); - event.keyCode = code; - return event; -} -const LEFT = 37, RIGHT = 39, UP = 38, DOWN = 40; -describe("EditorView", ()=>{ - beforeAll(()=>{ - setupProseMirrorView(); - }); - it("can read the DOM selection", async ()=>{ - const { view } = tempEditor({ - doc: doc(p("one"), hr(), blockquote(p("two"))) - }); - function test(node, offset, expected) { - setDOMSel(node, offset); - view.dom.focus(); - act(()=>{ - view.domObserver.flush(); - }); - const sel = view.state.selection; - expect(sel.head == null ? sel.from : sel.head).toBe(expected); - } - const one = await findTextNode(view.dom, "one"); - const two = await findTextNode(view.dom, "two"); - test(one, 0, 1); - test(one, 1, 2); - test(one, 3, 4); - // TODO: Not sure why this is broken - // test(one.parentNode!, 0, 1); - test(one.parentNode, 1, 4); - test(two, 0, 8); - test(two, 3, 11); - test(two.parentNode, 1, 11); - test(view.dom, 1, 4); - test(view.dom, 2, 8); - test(view.dom, 3, 11); - }); - it("syncs the DOM selection with the editor selection", async ()=>{ - const { view } = tempEditor({ - doc: doc(p("one"), hr(), blockquote(p("two"))) - }); - function test(pos, node, offset) { - setSel(view, pos); - const sel = getSel(); - expect(sel.node).toBe(node); - expect(sel.offset).toBe(offset); - } - const one = await findTextNode(view.dom, "one"); - const two = await findTextNode(view.dom, "two"); - view.focus(); - test(1, one, 0); - test(2, one, 1); - test(4, one, 3); - test(8, two, 0); - test(10, two, 2); - }); - // Jest-dom doesn't actually provide a working getClientRects - // implementation, so this test doesn't work. - // TODO: should we consider running these with puppeteer for - // better test accuracy? - it.skip("returns sensible screen coordinates", ()=>{ - const { view } = tempEditor({ - doc: doc(p("one"), p("two")) - }); - const p00 = view.coordsAtPos(1); - const p01 = view.coordsAtPos(2); - const p03 = view.coordsAtPos(4); - const p10 = view.coordsAtPos(6); - const p13 = view.coordsAtPos(9); - expect(p00.bottom).toBeGreaterThan(p00.top); - expect(p13.bottom).toBeGreaterThan(p13.top); - expect(p00.top).toEqual(p01.top); - expect(p01.top).toEqual(p03.top); - expect(p00.bottom).toEqual(p03.bottom); - expect(p10.top).toEqual(p13.top); - expect(p01.left).toBeGreaterThan(p00.left); - expect(p03.left).toBeGreaterThan(p01.left); - expect(p10.top).toBeGreaterThan(p00.top); - expect(p13.left).toBeGreaterThan(p10.left); - }); - it.skip("returns proper coordinates in code blocks", ()=>{ - const { view } = tempEditor({ - doc: doc(code_block("a\nb\n")) - }), p = []; - for(let i = 1; i <= 5; i++)p.push(view.coordsAtPos(i)); - const [p0, p1, p2, p3, p4] = p; - expect(p0.top).toBe(p1.top); - expect(p0.left).toBeLessThan(p1.left); - expect(p2.top).toBeGreaterThan(p1.top); - expect(p2.top).toBe(p3.top); - expect(p2.left).toBeLessThan(p3.left); - expect(p2.left).toBe(p0.left); - expect(p4.top).toBeGreaterThan(p3.top); - // This one shows a small (0.01 pixel) difference in Firefox for - // some reason. - expect(Math.round(p4.left)).toBe(Math.round(p2.left)); - }); - it.skip("produces sensible screen coordinates in corner cases", ()=>{ - const { view } = tempEditor({ - doc: doc(p("one", em("two", strong("three"), img), br(), code("foo")), p()) - }); - return new Promise((ok)=>{ - setTimeout(()=>{ - allPositions(view.state.doc).forEach((pos)=>{ - const coords = view.coordsAtPos(pos); - const found = view.posAtCoords({ - top: coords.top + 1, - left: coords.left - }).pos; - expect(found).toBe(pos); - setSel(view, pos); - }); - ok(null); - }, 20); - }); - }); - it.skip("doesn't return zero-height rectangles after leaves", ()=>{ - const { view } = tempEditor({ - doc: doc(p(img)) - }); - const coords = view.coordsAtPos(2, 1); - expect(coords.bottom - coords.top).toBeGreaterThan(5); - }); - it.skip("produces horizontal rectangles for positions between blocks", ()=>{ - const { view } = tempEditor({ - doc: doc(p("ha"), hr(), blockquote(p("ba"))) - }); - const a = view.coordsAtPos(0); - expect(a.top).toBe(a.bottom); - expect(a.top).toBe(view.dom.firstChild.getBoundingClientRect().top); - expect(a.left).toBeLessThan(a.right); - const b = view.coordsAtPos(4); - expect(b.top).toBe(b.bottom); - expect(b.top).toBeGreaterThan(a.top); - expect(b.left).toBeLessThan(b.right); - const c = view.coordsAtPos(5); - expect(c.top).toBe(c.bottom); - expect(c.top).toBeGreaterThan(b.top); - const d = view.coordsAtPos(6); - expect(d.top).toBe(d.bottom); - expect(d.left).toBeLessThan(d.right); - expect(d.top).toBeLessThan(view.dom.getBoundingClientRect().bottom); - }); - it.skip("produces sensible screen coordinates around line breaks", ()=>{ - const { view } = tempEditor({ - doc: doc(p("one two three four five-six-seven-eight")) - }); - function afterSpace(pos) { - return pos > 0 && view.state.doc.textBetween(pos - 1, pos) == " "; - } - view.dom.style.width = "4em"; - let prevBefore; - let prevAfter; - allPositions(view.state.doc).forEach((pos)=>{ - const coords = view.coordsAtPos(pos, 1); - if (prevAfter) // eslint-disable-next-line jest/no-conditional-expect - expect(prevAfter.top < coords.top || prevAfter.top == coords.top && prevAfter.left < coords.left).toBeTruthy(); - prevAfter = coords; - const found = view.posAtCoords({ - top: coords.top + 1, - left: coords.left - }).pos; - expect(found).toBe(pos); - const coordsBefore = view.coordsAtPos(pos, -1); - if (prevBefore) // eslint-disable-next-line jest/no-conditional-expect - expect(prevBefore.top < coordsBefore.top || prevBefore.top == coordsBefore.top && (prevBefore.left < coordsBefore.left || afterSpace(pos) && prevBefore.left == coordsBefore.left)).toBeTruthy(); - prevBefore = coordsBefore; - }); - }); - it.skip("can find coordinates on node boundaries", ()=>{ - const { view } = tempEditor({ - doc: doc(p("one ", em("two"), " ", em(strong("three")))) - }); - let prev; - allPositions(view.state.doc).forEach((pos)=>{ - const coords = view.coordsAtPos(pos, 1); - if (prev) // eslint-disable-next-line jest/no-conditional-expect - expect(prev.top < coords.top || Math.abs(prev.top - coords.top) < 4 && prev.left < coords.left).toBeTruthy(); - prev = coords; - }); - }); - it.skip("finds proper coordinates in RTL text", ()=>{ - const { view } = tempEditor({ - doc: doc(p("مرآة نثرية")) - }); - view.dom.style.direction = "rtl"; - let prev; - allPositions(view.state.doc).forEach((pos)=>{ - const coords = view.coordsAtPos(pos, 1); - if (prev) // eslint-disable-next-line jest/no-conditional-expect - expect(prev.top < coords.top || Math.abs(prev.top - coords.top) < 4 && prev.left > coords.left).toBeTruthy(); - prev = coords; - }); - }); - it.skip("can go back and forth between screen coordsa and document positions", ()=>{ - const { view } = tempEditor({ - doc: doc(p("one"), blockquote(p("two"), p("three"))) - }); - [ - 1, - 2, - 4, - 7, - 14, - 15 - ].forEach((pos)=>{ - const coords = view.coordsAtPos(pos); - const found = view.posAtCoords({ - top: coords.top + 1, - left: coords.left - }).pos; - expect(found).toBe(pos); - }); - }); - it.skip("returns correct screen coordinates for wrapped lines", ()=>{ - const { view } = tempEditor({}); - const top = view.coordsAtPos(1); - let pos = 1, end; - for(let i = 0; i < 100; i++){ - view.dispatch(view.state.tr.insertText("a bc de fg h")); - pos += 12; - end = view.coordsAtPos(pos); - if (end.bottom > top.bottom + 4) break; - } - expect(view.posAtCoords({ - left: end.left + 50, - top: end.top + 5 - }).pos).toBe(pos); - }); - it("makes arrow motion go through selectable inline nodes", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo", img, "bar")) - }); - act(()=>{ - view.dispatchEvent(event(RIGHT)); - }); - expect(view.state.selection.from).toBe(4); - act(()=>{ - view.dispatchEvent(event(RIGHT)); - }); - expect(view.state.selection.head).toBe(5); - expect(view.state.selection.anchor).toBe(5); - act(()=>{ - view.dispatchEvent(event(LEFT)); - }); - expect(view.state.selection.from).toBe(4); - act(()=>{ - view.dispatchEvent(event(LEFT)); - }); - expect(view.state.selection.head).toBe(4); - expect(view.state.selection.anchor).toBe(4); - }); - it("makes arrow motion go through selectable block nodes", ()=>{ - const { view } = tempEditor({ - doc: doc(p("hello"), hr(), ul(li(p("there")))) - }); - act(()=>{ - view.dispatchEvent(event(DOWN)); - }); - expect(view.state.selection.from).toBe(7); - setSel(view, 11); - act(()=>{ - view.dispatchEvent(event(UP)); - }); - expect(view.state.selection.from).toBe(7); - }); - it("supports arrow motion through adjacent blocks", ()=>{ - const { view } = tempEditor({ - doc: doc(blockquote(p("hello")), hr(), hr(), p("there")) - }); - act(()=>{ - view.dispatchEvent(event(DOWN)); - }); - expect(view.state.selection.from).toBe(9); - act(()=>{ - view.dispatchEvent(event(DOWN)); - }); - expect(view.state.selection.from).toBe(10); - setSel(view, 14); - act(()=>{ - view.dispatchEvent(event(UP)); - }); - expect(view.state.selection.from).toBe(10); - act(()=>{ - view.dispatchEvent(event(UP)); - }); - expect(view.state.selection.from).toBe(9); - }); - it("support horizontal motion through blocks", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo"), hr(), hr(), p("bar")) - }); - act(()=>{ - view.dispatchEvent(event(RIGHT)); - }); - expect(view.state.selection.from).toBe(5); - act(()=>{ - view.dispatchEvent(event(RIGHT)); - }); - expect(view.state.selection.from).toBe(6); - act(()=>{ - view.dispatchEvent(event(RIGHT)); - }); - expect(view.state.selection.head).toBe(8); - act(()=>{ - view.dispatchEvent(event(LEFT)); - }); - expect(view.state.selection.from).toBe(6); - act(()=>{ - view.dispatchEvent(event(LEFT)); - }); - expect(view.state.selection.from).toBe(5); - act(()=>{ - view.dispatchEvent(event(LEFT)); - }); - expect(view.state.selection.head).toBe(4); - }); - it("allows moving directly from an inline node to a block node", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo", img), hr(), p(img, "bar")) - }); - setSel(view, NodeSelection.create(view.state.doc, 4)); - act(()=>{ - view.dispatchEvent(event(DOWN)); - }); - expect(view.state.selection.from).toBe(6); - setSel(view, NodeSelection.create(view.state.doc, 8)); - act(()=>{ - view.dispatchEvent(event(UP)); - }); - expect(view.state.selection.from).toBe(6); - }); - it("updates the selection even if the DOM parameters look unchanged", ()=>{ - const { view , rerender } = tempEditor({ - doc: doc(p("foobar")) - }); - view.focus(); - const decos = DecorationSet.create(view.state.doc, [ - Decoration.inline(1, 4, { - color: "green" - }) - ]); - rerender({ - decorations () { - return decos; - } - }); - rerender({ - decorations: undefined - }); - rerender({ - decorations () { - return decos; - } - }); - const range = document.createRange(); - range.setEnd(document.getSelection().anchorNode, document.getSelection().anchorOffset); - range.setStart(view.dom, 0); - expect(range.toString()).toBe("foobar"); - }); - it("sets selection even if Selection.extend throws DOMException", ()=>{ - const originalExtend = window.Selection.prototype.extend; - window.Selection.prototype.extend = ()=>{ - // declare global: DOMException - throw new DOMException("failed"); - }; - try { - const { view } = tempEditor({ - doc: doc(p("foo", img), hr(), p(img, "bar")) - }); - setSel(view, NodeSelection.create(view.state.doc, 4)); - act(()=>{ - view.dispatchEvent(event(DOWN)); - }); - expect(view.state.selection.from).toBe(6); - } finally{ - window.Selection.prototype.extend = originalExtend; - } - }); - it("doesn't put the cursor after BR hack nodes", ()=>{ - const { view } = tempEditor({ - doc: doc(p()) - }); - view.focus(); - expect(getSelection().focusOffset).toBe(0); - }); -}); diff --git a/dist/esm/components/__tests__/ProseMirror.test.js b/dist/esm/components/__tests__/ProseMirror.test.js deleted file mode 100644 index 81276731..00000000 --- a/dist/esm/components/__tests__/ProseMirror.test.js +++ /dev/null @@ -1,97 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-non-null-assertion */ import { expect } from "@jest/globals"; -import { act } from "@testing-library/react"; -import { doc, em, hr, li, p, strong, ul } from "prosemirror-test-builder"; -import { tempEditor } from "../../testing/editorViewTestHelpers.js"; -import { setupProseMirrorView } from "../../testing/setupProseMirrorView.js"; -describe("EditorView", ()=>{ - beforeAll(()=>{ - setupProseMirrorView(); - }); - it("reflects the current state in .props", ()=>{ - const { view } = tempEditor({ - doc: doc(p()) - }); - expect(view.state).toBe(view.props.state); - }); - it("calls handleScrollToSelection when appropriate", ()=>{ - let scrolled = 0; - const { view } = tempEditor({ - doc: doc(p()), - handleScrollToSelection: ()=>{ - scrolled++; - return false; - } - }); - act(()=>{ - view.dispatch(view.state.tr.scrollIntoView()); - }); - expect(scrolled).toBe(1); - }); - it("can be queried for the DOM position at a doc position", ()=>{ - const { view } = tempEditor({ - doc: doc(ul(li(p(strong("foo"))))) - }); - const inText = view.domAtPos(4); - expect(inText.offset).toBe(1); - expect(inText.node.nodeValue).toBe("foo"); - const beforeLI = view.domAtPos(1); - expect(beforeLI.offset).toBe(0); - expect(beforeLI.node.nodeName).toBe("UL"); - const afterP = view.domAtPos(7); - expect(afterP.offset).toBe(1); - expect(afterP.node.nodeName).toBe("LI"); - }); - it("can bias DOM position queries to enter nodes", ()=>{ - const { view } = tempEditor({ - doc: doc(p(em(strong("a"), "b"), "c")) - }); - function get(pos, bias) { - const r = view.domAtPos(pos, bias); - return (r.node.nodeType == 1 ? r.node.nodeName : r.node.nodeValue) + "@" + r.offset; - } - expect(get(1, 0)).toBe("P@0"); - expect(get(1, -1)).toBe("P@0"); - expect(get(1, 1)).toBe("a@0"); - expect(get(2, -1)).toBe("a@1"); - expect(get(2, 0)).toBe("EM@1"); - expect(get(2, 1)).toBe("b@0"); - expect(get(3, -1)).toBe("b@1"); - expect(get(3, 0)).toBe("P@1"); - expect(get(3, 1)).toBe("c@0"); - expect(get(4, -1)).toBe("c@1"); - expect(get(4, 0)).toBe("P@2"); - expect(get(4, 1)).toBe("P@2"); - }); - it("can be queried for a node's DOM representation", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo"), hr()) - }); - expect(view.nodeDOM(0).nodeName).toBe("P"); - expect(view.nodeDOM(5).nodeName).toBe("HR"); - expect(view.nodeDOM(3)).toBeNull(); - }); - it("can map DOM positions to doc positions", ()=>{ - const { view } = tempEditor({ - doc: doc(p("foo"), hr()) - }); - expect(view.posAtDOM(view.dom.firstChild.firstChild, 2)).toBe(3); - expect(view.posAtDOM(view.dom, 1)).toBe(5); - expect(view.posAtDOM(view.dom, 2)).toBe(6); - expect(view.posAtDOM(view.dom.lastChild, 0, -1)).toBe(5); - expect(view.posAtDOM(view.dom.lastChild, 0, 1)).toBe(6); - }); - it("binds this to itself in dispatchTransaction prop", ()=>{ - let thisBinding; - const { view } = tempEditor({ - doc: doc(p("foo"), hr()), - dispatchTransaction () { - // eslint-disable-next-line @typescript-eslint/no-this-alias - thisBinding = this; - } - }); - act(()=>{ - view.dispatch(view.state.tr.insertText("x")); - }); - expect(view).toBe(thisBinding); - }); -}); diff --git a/dist/esm/contexts/ChildDescriptorsContext.js b/dist/esm/contexts/ChildDescriptorsContext.js deleted file mode 100644 index c67f844d..00000000 --- a/dist/esm/contexts/ChildDescriptorsContext.js +++ /dev/null @@ -1,2 +0,0 @@ -import { createContext } from "react"; -export const ChildDescriptorsContext = createContext([]); diff --git a/dist/esm/contexts/EditorContext.js b/dist/esm/contexts/EditorContext.js deleted file mode 100644 index dccd408d..00000000 --- a/dist/esm/contexts/EditorContext.js +++ /dev/null @@ -1,7 +0,0 @@ -import { createContext } from "react"; -/** - * Provides the EditorView, as well as the current - * EditorState. Should not be consumed directly; instead - * see `useEditorState`, `useEditorViewEvent`, and - * `useEditorViewLayoutEffect`. - */ export const EditorContext = createContext(null); diff --git a/dist/esm/contexts/LayoutGroupContext.js b/dist/esm/contexts/LayoutGroupContext.js deleted file mode 100644 index 4c66150f..00000000 --- a/dist/esm/contexts/LayoutGroupContext.js +++ /dev/null @@ -1,2 +0,0 @@ -import { createContext } from "react"; -export const LayoutGroupContext = /*#__PURE__*/ createContext(null); diff --git a/dist/esm/contexts/NodeViewContext.js b/dist/esm/contexts/NodeViewContext.js deleted file mode 100644 index 113b0125..00000000 --- a/dist/esm/contexts/NodeViewContext.js +++ /dev/null @@ -1,2 +0,0 @@ -import { createContext } from "react"; -export const NodeViewContext = /*#__PURE__*/ createContext(null); diff --git a/dist/esm/contexts/__tests__/DeferredLayoutEffects.test.js b/dist/esm/contexts/__tests__/DeferredLayoutEffects.test.js deleted file mode 100644 index 583e991d..00000000 --- a/dist/esm/contexts/__tests__/DeferredLayoutEffects.test.js +++ /dev/null @@ -1,98 +0,0 @@ -import { act, render, screen } from "@testing-library/react"; -import React, { useLayoutEffect, useState } from "react"; -import { LayoutGroup } from "../../components/LayoutGroup.js"; -import { useLayoutGroupEffect } from "../../hooks/useLayoutGroupEffect.js"; -describe("DeferredLayoutEffects", ()=>{ - jest.useFakeTimers("modern"); - it("registers multiple effects and runs them", ()=>{ - function Parent() { - return /*#__PURE__*/ React.createElement(LayoutGroup, null, /*#__PURE__*/ React.createElement(Child, null)); - } - function Child() { - const [double, setDouble] = useState(1); - useLayoutEffect(()=>{ - if (double === 2) { - setTimeout(()=>{ - setDouble((d)=>d * 2.5); - }, 500); - } - if (double === 20) { - setDouble((d)=>d * 2.5); - } - }, [ - double - ]); - useLayoutGroupEffect(()=>{ - const timeout = setTimeout(()=>{ - setDouble((d)=>d * 2); - }, 1000); - return ()=>{ - clearTimeout(timeout); - }; - }, [ - double - ]); - return /*#__PURE__*/ React.createElement("div", null, /*#__PURE__*/ React.createElement("div", { - "data-testid": "double" - }, double)); - } - // The component mounts ... - // ... the initial value should be 1 - // ... there should be one timeout scheduled by the deferred effect - render(/*#__PURE__*/ React.createElement(Parent, null)); - expect(screen.getByTestId("double").innerHTML).toBe("1"); - // This block assert that deferred effects run. - // -------------------------------------------- - // 1000 milliseconds go by ... - // ... the timeout set by the deferred effect should run - // ... the timeout should double the new value to 2 - // ... the immediate effect should set a timeout - // ... the deferred effect should set a timeout - act(()=>{ - jest.advanceTimersByTime(1000); - }); - expect(screen.getByTestId("double").innerHTML).toBe("2"); - // The next three blocks assert that cleanup of deferred effects run. - // ------------------------------------------------------------------ - // 500 milliseconds go by ... - // ... the timeout set by the immediate effect should run - // ... the timeout should set the value to 5 - // ... the old deferred effect should cancel its timeout - // ... the new deferred effect should set a new timeout - act(()=>{ - jest.advanceTimersByTime(500); - }); - expect(screen.getByTestId("double").innerHTML).toBe("5"); - // ... 500 more milliseconds go by ... - // ... the canceled timeout should not run - // ... the rescheduled timoeut should not yet run - act(()=>{ - jest.advanceTimersByTime(500); - }); - expect(screen.getByTestId("double").innerHTML).toBe("5"); - // ... 500 more milliseconds go by ... - // ... the rescheduled timeout should run - // ... the timeout should double the value to 10 - // ... the deferred effect should set a new timeout - act(()=>{ - jest.advanceTimersByTime(500); - }); - expect(screen.getByTestId("double").innerHTML).toBe("10"); - // The next block asserts that cancelation of deferred effects works. - // ------------------------------------------------------------------ - // 1000 milliseconds go by ... - // ... the timeout set by the deferred effect should run - // ... the timeout should double the value to 20 - // ... the immediate effect should then set the value to 50 - // ... the deferred effect from the first render should not run - // ... the deferred effect from the second render should run - // ... the deferred effect that does run should set a new timeout - act(()=>{ - jest.advanceTimersByTime(1000); - }); - // For this assertion, we need to clear a timer from the React scheduler. - jest.advanceTimersByTime(1); - expect(screen.getByTestId("double").innerHTML).toBe("50"); - expect(jest.getTimerCount()).toBe(1); - }); -}); diff --git a/dist/esm/decorations/ReactWidgetType.js b/dist/esm/decorations/ReactWidgetType.js deleted file mode 100644 index 6c9a9363..00000000 --- a/dist/esm/decorations/ReactWidgetType.js +++ /dev/null @@ -1,37 +0,0 @@ -import { Decoration } from "prosemirror-view"; -function compareObjs(a, b) { - if (a == b) return true; - for(const p in a)if (a[p] !== b[p]) return false; - for(const p in b)if (!(p in a)) return false; - return true; -} -const noSpec = { - side: 0 -}; -export class ReactWidgetType { - map(mapping, span, offset, oldOffset) { - const { pos , deleted } = mapping.mapResult(span.from + oldOffset, this.side < 0 ? -1 : 1); - // @ts-expect-error The Decoration constructor is private/internal, but - // we need to use it for our custom widget implementation here. - return deleted ? null : new Decoration(pos - offset, pos - offset, this); - } - valid() { - return true; - } - eq(other) { - return this == other || other instanceof ReactWidgetType && (this.spec.key && this.spec.key == other.spec.key || this.Component == other.Component && compareObjs(this.spec, other.spec)); - } - destroy() { - // Can be implemented with React effect hooks - } - constructor(Component, spec){ - this.Component = Component; - this.spec = spec ?? noSpec; - this.side = this.spec.side ?? 0; - } -} -export function widget(pos, component, spec) { - // @ts-expect-error The Decoration constructor is private/internal, but - // we need to use it for our custom widget implementation here. - return new Decoration(pos, pos, new ReactWidgetType(component, spec)); -} diff --git a/dist/esm/decorations/computeDocDeco.js b/dist/esm/decorations/computeDocDeco.js deleted file mode 100644 index cf7264f6..00000000 --- a/dist/esm/decorations/computeDocDeco.js +++ /dev/null @@ -1,18 +0,0 @@ -import { Decoration } from "prosemirror-view"; -export function computeDocDeco(view) { - const 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(const attr in value){ - if (attr == "class") attrs.class += " " + value[attr]; - else if (attr == "style") attrs.style = (attrs.style ? attrs.style + ";" : "") + value[attr]; - else if (!attrs[attr] && attr != "contenteditable" && attr != "nodeName") attrs[attr] = String(value[attr]); - } - }); - if (!attrs.translate) attrs.translate = "no"; - return [ - Decoration.node(0, view.state.doc.content.size, attrs) - ]; -} diff --git a/dist/esm/decorations/internalTypes.js b/dist/esm/decorations/internalTypes.js deleted file mode 100644 index 2234b9ca..00000000 --- a/dist/esm/decorations/internalTypes.js +++ /dev/null @@ -1 +0,0 @@ -export { }; diff --git a/dist/esm/decorations/iterDeco.js b/dist/esm/decorations/iterDeco.js deleted file mode 100644 index 49af1174..00000000 --- a/dist/esm/decorations/iterDeco.js +++ /dev/null @@ -1,73 +0,0 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ import { ReactWidgetType } from "./ReactWidgetType.js"; -function compareSide(a, b) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - return a.type.side - b.type.side; -} -// 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. -export function iterDeco(parent, deco, // Callbacks have been slightly modified to pass -// the offset, so that we can pass the position as -// a prop to components -onWidget, onNode) { - const locals = deco.locals(parent); - let offset = 0; - // Simple, cheap variant for when there are no local decorations - if (locals.length == 0) { - for(let i = 0; i < parent.childCount; i++){ - const child = parent.child(i); - onNode(child, locals, deco.forChild(offset, child), offset, i); - offset += child.nodeSize; - } - return; - } - let decoIndex = 0; - const active = []; - let restNode = null; - for(let parentIndex = 0;;){ - if (decoIndex < locals.length && locals[decoIndex].to == offset) { - const widget = locals[decoIndex++]; - let 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], // eslint-disable-next-line @typescript-eslint/no-explicit-any - !(widgets[i].type instanceof ReactWidgetType), offset, parentIndex + i, !!restNode); - } else { - onWidget(widget, // eslint-disable-next-line @typescript-eslint/no-explicit-any - !(widget.type instanceof ReactWidgetType), offset, parentIndex, !!restNode); - } - } - 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 && locals[decoIndex].to > 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; - } - } - const outerDeco = child.isInline && !child.isLeaf ? active.filter((d)=>!d.inline) : active.slice(); - onNode(child, outerDeco, deco.forChild(offset, child), offset, index); - offset = end; - } -} diff --git a/dist/esm/decorations/viewDecorations.js b/dist/esm/decorations/viewDecorations.js deleted file mode 100644 index 873e97d2..00000000 --- a/dist/esm/decorations/viewDecorations.js +++ /dev/null @@ -1,125 +0,0 @@ -import { DecorationSet } from "prosemirror-view"; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const none = [], noSpec = {}; -const empty = DecorationSet.empty; -// 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. -let DecorationGroup = class DecorationGroup { - map(mapping, doc) { - const mappedDecos = this.members.map((member)=>member.map(mapping, doc, noSpec)); - return DecorationGroup.from(mappedDecos); - } - forChild(offset, child) { - if (child.isLeaf) return DecorationSet.empty; - let found = []; - for(let i = 0; i < this.members.length; i++){ - const 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++){ - const locals = this.members[i].localsInner(node); - if (!locals.length) continue; - if (!result) { - result = locals; - } else { - if (sorted) { - result = result.slice(); - sorted = false; - } - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - for(let j = 0; j < locals.length; j++)result.push(locals[j]); - } - } - return result ? removeOverlap(sorted ? result : result.sort(byPos)) : none; - } - // 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: - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - return members[0]; - default: - return new DecorationGroup(members.every((m)=>m instanceof DecorationSet) ? members : members.reduce((r, m)=>r.concat(m instanceof DecorationSet ? m : m.members), [])); - } - } - constructor(members){ - this.members = members; - } -}; -// 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; -} -// 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++){ - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const span = working[i]; - if (span.from != span.to) for(let j = i + 1; j < working.length; j++){ - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const 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) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - while(i < array.length && byPos(deco, array[i]) > 0)i++; - array.splice(i, 0, deco); -} -export function viewDecorations(view, cursorWrapper) { - const found = []; - view.someProp("decorations", (f)=>{ - const result = f(view.state); - if (result && result != empty) found.push(result); - }); - // We don't have access to types for view.cursorWrapper here - // eslint-disable-next-line @typescript-eslint/no-explicit-any - if (cursorWrapper) { - found.push(// eslint-disable-next-line @typescript-eslint/no-explicit-any - DecorationSet.create(view.state.doc, [ - cursorWrapper - ])); - } - return DecorationGroup.from(found); -} diff --git a/dist/esm/dom.js b/dist/esm/dom.js deleted file mode 100644 index b350f3de..00000000 --- a/dist/esm/dom.js +++ /dev/null @@ -1,102 +0,0 @@ -export const domIndex = function(node) { - for(let index = 0;; index++){ - node = node.previousSibling; - if (!node) return index; - } -}; -export const parentNode = function(node) { - const parent = node.assignedSlot || node.parentNode; - return parent && parent.nodeType == 11 ? parent.host : parent; -}; -let reusedRange = null; -// Note that this will always return the same range, because DOM range -// objects are every expensive, and keep slowing down subsequent DOM -// updates, for some reason. -export const textRange = function(node, from, to) { - const range = reusedRange || (reusedRange = 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))) { - const parent = node.parentNode; - if (!parent || 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)]; - if (node.contentEditable == "false") return false; - off = dir < 0 ? nodeSize(node) : 0; - } else { - return false; - } - } -} -export function nodeSize(node) { - return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length; -} -export function isOnEdge(node, offset, parent) { - for(let atStart = offset == 0, atEnd = offset == nodeSize(node); atStart || atEnd;){ - if (node == parent) return true; - const index = domIndex(node); - node = node.parentNode; - if (!node) return false; - atStart = atStart && index == 0; - atEnd = atEnd && index == nodeSize(node); - } - return false; -} -export 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) { - return domSel.focusNode && isEquivalentPosition(domSel.focusNode, domSel.focusOffset, domSel.anchorNode, domSel.anchorOffset); -}; -export function keyEvent(keyCode, key) { - const event = document.createEvent("Event"); - event.initEvent("keydown", true, true); - event.keyCode = keyCode; - event.key = event.code = key; - return event; -} -export function deepActiveElement(doc) { - let elt = doc.activeElement; - while(elt && elt.shadowRoot)elt = elt.shadowRoot.activeElement; - return elt; -} -export function caretFromPoint(doc, x, y) { - if (doc.caretPositionFromPoint) { - try { - // Firefox throws for this call in hard-to-predict circumstances (#994) - const pos = doc.caretPositionFromPoint(x, y); - if (pos) return { - node: pos.offsetNode, - offset: pos.offset - }; - } catch (_) { - // pass - } - } - if (doc.caretRangeFromPoint) { - const range = doc.caretRangeFromPoint(x, y); - if (range) return { - node: range.startContainer, - offset: range.startOffset - }; - } - return; -} diff --git a/dist/esm/hooks/__tests__/useEditorViewLayoutEffect.test.js b/dist/esm/hooks/__tests__/useEditorViewLayoutEffect.test.js deleted file mode 100644 index 6591a9af..00000000 --- a/dist/esm/hooks/__tests__/useEditorViewLayoutEffect.test.js +++ /dev/null @@ -1,98 +0,0 @@ -/* eslint-disable @typescript-eslint/no-empty-function */ import { render } from "@testing-library/react"; -import React from "react"; -import { LayoutGroup } from "../../components/LayoutGroup.js"; -import { EditorContext } from "../../contexts/EditorContext.js"; -import { useEditorEffect } from "../useEditorEffect.js"; -function TestComponent(param) { - let { effect , dependencies =[] } = param; - useEditorEffect(effect, [ - effect, - ...dependencies - ]); - return null; -} -describe("useEditorViewLayoutEffect", ()=>{ - it("should run the effect", ()=>{ - const effect = jest.fn(); - const editorView = {}; - const editorState = {}; - const registerEventListener = ()=>{}; - const unregisterEventListener = ()=>{}; - render(/*#__PURE__*/ React.createElement(LayoutGroup, null, /*#__PURE__*/ React.createElement(EditorContext.Provider, { - value: { - view: editorView, - state: editorState, - registerEventListener, - unregisterEventListener - } - }, /*#__PURE__*/ React.createElement(TestComponent, { - effect: effect - })))); - expect(effect).toHaveBeenCalled(); - expect(effect).toHaveBeenCalledWith(editorView); - }); - it("should not re-run the effect if no dependencies change", ()=>{ - const effect = jest.fn(); - const editorView = {}; - const editorState = {}; - const registerEventListener = ()=>{}; - const unregisterEventListener = ()=>{}; - const { rerender } = render(/*#__PURE__*/ React.createElement(LayoutGroup, null, /*#__PURE__*/ React.createElement(EditorContext.Provider, { - value: { - view: editorView, - state: editorState, - registerEventListener, - unregisterEventListener - } - }, /*#__PURE__*/ React.createElement(TestComponent, { - effect: effect, - dependencies: [] - })))); - rerender(/*#__PURE__*/ React.createElement(LayoutGroup, null, /*#__PURE__*/ React.createElement(EditorContext.Provider, { - value: { - view: editorView, - state: editorState, - registerEventListener, - unregisterEventListener - } - }, /*#__PURE__*/ React.createElement(TestComponent, { - effect: effect, - dependencies: [] - })))); - expect(effect).toHaveBeenCalledTimes(1); - }); - it("should re-run the effect if dependencies change", ()=>{ - const effect = jest.fn(); - const editorView = {}; - const editorState = {}; - const registerEventListener = ()=>{}; - const unregisterEventListener = ()=>{}; - const { rerender } = render(/*#__PURE__*/ React.createElement(LayoutGroup, null, /*#__PURE__*/ React.createElement(EditorContext.Provider, { - value: { - view: editorView, - state: editorState, - registerEventListener, - unregisterEventListener - } - }, /*#__PURE__*/ React.createElement(TestComponent, { - effect: effect, - dependencies: [ - "one" - ] - })))); - rerender(/*#__PURE__*/ React.createElement(LayoutGroup, null, /*#__PURE__*/ React.createElement(EditorContext.Provider, { - value: { - view: editorView, - state: editorState, - registerEventListener, - unregisterEventListener - } - }, /*#__PURE__*/ React.createElement(TestComponent, { - effect: effect, - dependencies: [ - "two" - ] - })))); - expect(effect).toHaveBeenCalledTimes(2); - }); -}); diff --git a/dist/esm/hooks/useBeforeInput.js b/dist/esm/hooks/useBeforeInput.js deleted file mode 100644 index 0dbaee0a..00000000 --- a/dist/esm/hooks/useBeforeInput.js +++ /dev/null @@ -1,190 +0,0 @@ -import { useEffect, useRef } from "react"; -import { reactKeysPluginKey } from "../plugins/reactKeys.js"; -const SPACE = /\s/; -const PUNCTUATION = /[\u0021-\u0023\u0025-\u002A\u002C-\u002F\u003A\u003B\u003F\u0040\u005B-\u005D\u005F\u007B\u007D\u00A1\u00A7\u00AB\u00B6\u00B7\u00BB\u00BF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0AF0\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E3B\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/; -const CHAMELEON = /['\u2018\u2019]/; -const isWordCharacter = function(doc, pos) { - let checkDir = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : -1; - const $pos = doc.resolve(pos); - // The position is at the beginning of a node - if ($pos.parentOffset === 0) return false; - const char = doc.textBetween(pos + checkDir, pos, null, " "); - if (SPACE.test(char)) { - return false; - } - // Chameleons count as word characters as long as they're in a word, so - // recurse to see if the next one is a word character or not. - if (CHAMELEON.test(char)) { - if (isWordCharacter(doc, pos - 1)) { - return true; - } - } - if (PUNCTUATION.test(char)) { - return false; - } - return true; -}; -function insertText(view, eventData) { - let options = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {}; - if (eventData === null) return false; - const from = view.state.selection.from ?? options.from; - const to = view.state.selection.to ?? options.to; - if (view.someProp("handleTextInput")?.(view, from, to, eventData)) { - return true; - } - const { tr } = view.state; - tr.insertText(eventData, from, to); - for (const mark of view.state.storedMarks ?? []){ - tr.addMark(from, to, mark); - } - if (options.bust) { - const parentPos = view.state.doc.resolve(from).before(); - const parentKey = reactKeysPluginKey.getState(view.state)?.posToKey.get(parentPos); - tr.setMeta(reactKeysPluginKey, { - type: "bustKey", - payload: { - key: parentKey - } - }); - } - view.dispatch(tr); - return true; -} -function findWordBoundaryBackward(doc, start) { - let pos = start; - while(!isWordCharacter(doc, pos)){ - pos--; - } - while(isWordCharacter(doc, pos)){ - pos--; - } - return pos; -} -function findWordBoundaryForward(doc, start) { - let pos = start; - while(!isWordCharacter(doc, pos, 1)){ - pos++; - } - while(isWordCharacter(doc, pos, 1)){ - pos++; - } - return pos; -} -export function useBeforeInput(view) { - const compositionTextRef = useRef(null); - const compositionMarks = useRef(null); - useEffect(()=>{ - if (!view) return; - function onCompositionStart() { - // @ts-expect-error Internal property (domObserver) - view?.domObserver.stop(); - compositionMarks.current = view?.state.storedMarks ?? null; - } - function onCompositionEnd() { - if (!view) return; - if (compositionTextRef.current === null) return; - insertText(view, compositionTextRef.current, { - bust: true, - marks: compositionMarks.current - }); - // @ts-expect-error Internal property (domObserver) - view.domObserver.start(); - compositionTextRef.current = null; - } - function onBeforeInput(event) { - if (!view) return; - event.preventDefault(); - switch(event.inputType){ - case "insertCompositionText": - { - if (event.data === null) return; - compositionTextRef.current = event.data; - break; - } - case "insertReplacementText": - { - const ranges = event.getTargetRanges(); - event.dataTransfer?.items[0]?.getAsString((data)=>{ - for (const range of ranges){ - // @ts-expect-error Internal property (docView) - const from = view.docView.posFromDOM(range.startContainer, range.startOffset, 1); - // @ts-expect-error Internal property (docView) - const to = view.docView.posFromDOM(range.endContainer, range.endOffset, 1); - insertText(view, data, { - from, - to - }); - } - }); - break; - } - case "insertText": - { - insertText(view, event.data); - break; - } - case "deleteWordBackward": - { - const { tr , doc , selection } = view.state; - const from = selection.empty ? findWordBoundaryBackward(view.state.doc, selection.from) : selection.from; - const to = selection.to; - const storedMarks = doc.resolve(from).marksAcross(doc.resolve(to)); - tr.delete(from, to).setStoredMarks(storedMarks); - view.dispatch(tr); - break; - } - case "deleteWordForward": - { - const { tr , doc , selection } = view.state; - const from = selection.empty ? findWordBoundaryForward(view.state.doc, selection.from) : selection.from; - const to = selection.to; - const storedMarks = doc.resolve(from).marksAcross(doc.resolve(to)); - tr.delete(from, to).setStoredMarks(storedMarks); - view.dispatch(tr); - break; - } - case "deleteContentBackward": - { - const { tr , doc , selection } = view.state; - const from = selection.empty ? selection.from - 1 : selection.from; - const to = selection.to; - const storedMarks = doc.resolve(from).marksAcross(doc.resolve(to)); - tr.delete(from, to).setStoredMarks(storedMarks); - view.dispatch(tr); - break; - } - case "deleteContentForward": - { - const { tr , doc , selection } = view.state; - const from = selection.from; - const to = selection.empty ? selection.to + 1 : selection.to; - const storedMarks = doc.resolve(from).marksAcross(doc.resolve(to)); - tr.delete(from, to).setStoredMarks(storedMarks); - break; - } - case "deleteContent": - { - const { tr , doc , selection } = view.state; - const storedMarks = doc.resolve(selection.from).marksAcross(doc.resolve(selection.to)); - tr.delete(selection.from, selection.to).setStoredMarks(storedMarks); - view.dispatch(tr); - break; - } - default: - { - break; - } - } - } - view.dom.addEventListener("beforeinput", onBeforeInput); - view.dom.addEventListener("compositionend", onCompositionEnd); - view.dom.addEventListener("compositionstart", onCompositionStart); - return ()=>{ - view.dom.removeEventListener("compositionstart", onCompositionStart); - view.dom.removeEventListener("compositionend", onCompositionEnd); - view.dom.removeEventListener("beforeinput", onBeforeInput); - }; - }, [ - view - ]); -} diff --git a/dist/esm/hooks/useComponentEventListeners.js b/dist/esm/hooks/useComponentEventListeners.js deleted file mode 100644 index 40b9d18f..00000000 --- a/dist/esm/hooks/useComponentEventListeners.js +++ /dev/null @@ -1,54 +0,0 @@ -import { useCallback, useMemo, useState } from "react"; -import { componentEventListeners } from "../plugins/componentEventListeners.js"; -/** - * Produces a plugin that can be used with ProseMirror to handle DOM - * events at the EditorView.dom element. - * - * - `reactEventsPlugin` is a ProseMirror plugin for handling DOM events - * at the EditorView.dom element. It should be passed to `useEditorView`, - * along with any other plugins. - * - * - `registerEventListener` and `unregisterEventListener` should be - * passed to `EditorContext.Provider`. - * - * @privateRemarks - * - * This hook uses a combination of mutable and immutable updates to give - * us precise control over when we re-create the ProseMirror plugin. - * - * The plugin has a mutable reference to the set of handlers for each - * event type, but the set of event types is static. This means that we - * need to produce a new ProseMirror plugin whenever a new event type is - * registered. We avoid producing a new ProseMirrer plugin in any other - * scenario to avoid the performance overhead of reconfiguring the plugins - * in the EditorView. - * - * To accomplish this, we shallowly clone the registry whenever a new event - * type is registered. - */ export function useComponentEventListeners() { - const [registry, setRegistry] = useState(new Map()); - const registerEventListener = useCallback((eventType, handler)=>{ - const handlers = registry.get(eventType) ?? []; - handlers.unshift(handler); - if (!registry.has(eventType)) { - registry.set(eventType, handlers); - setRegistry(new Map(registry)); - } - }, [ - registry - ]); - const unregisterEventListener = useCallback((eventType, handler)=>{ - const handlers = registry.get(eventType); - handlers?.splice(handlers.indexOf(handler), 1); - }, [ - registry - ]); - const componentEventListenersPlugin = useMemo(()=>componentEventListeners(registry), [ - registry - ]); - return { - registerEventListener, - unregisterEventListener, - componentEventListenersPlugin - }; -} diff --git a/dist/esm/hooks/useEditor.js b/dist/esm/hooks/useEditor.js deleted file mode 100644 index b4f6594d..00000000 --- a/dist/esm/hooks/useEditor.js +++ /dev/null @@ -1,183 +0,0 @@ -import { Schema } from "prosemirror-model"; -import { EditorState } from "prosemirror-state"; -import { DecorationSet, EditorView } from "prosemirror-view"; -import { useCallback, useLayoutEffect, useMemo, useRef, useState } from "react"; -import { flushSync } from "react-dom"; -import { beforeInputPlugin } from "../plugins/beforeInputPlugin.js"; -import { SelectionDOMObserver } from "../selection/SelectionDOMObserver.js"; -import { NodeViewDesc } from "../viewdesc.js"; -import { useComponentEventListeners } from "./useComponentEventListeners.js"; -import { useForceUpdate } from "./useForceUpdate.js"; -// @ts-expect-error We're making use of knowledge of internal methods here -export class ReactEditorView extends EditorView { - /** - * Like setProps, but without executing any side effects. - * Safe to use in a component render method. - */ pureSetProps(props) { - // this.oldProps = this.props; - this._props = { - ...this._props, - ...props - }; - this.state = this._props.state; - } - /** - * Triggers any side effects that have been queued by previous - * calls to pureSetProps. - */ runPendingEffects() { - const newProps = this.props; - this._props = this.oldProps; - this.state = this._props.state; - this.update(newProps); - } - update(props) { - super.update(props); - // Ensure that side effects aren't re-triggered until - // pureSetProps is called again - this.oldProps = props; - } - updatePluginViews() { - if (this.shouldUpdatePluginViews) { - // @ts-expect-error We're making use of knowledge of internal methods here - super.updatePluginViews(); - } - } - constructor(place, props){ - // Call the superclass constructor with an empty - // document and limited props. We'll set everything - // else ourselves. - super(place, { - state: EditorState.create({ - schema: props.state.schema, - plugins: props.state.plugins - }), - plugins: props.plugins - }); - this.shouldUpdatePluginViews = false; - this.shouldUpdatePluginViews = true; - this._props = props; - this.oldProps = { - state: props.state - }; - this.state = props.state; - // @ts-expect-error We're making use of knowledge of internal attributes here - this.domObserver.stop(); - // @ts-expect-error We're making use of knowledge of internal attributes here - this.domObserver = new SelectionDOMObserver(this); - // @ts-expect-error We're making use of knowledge of internal attributes here - this.domObserver.start(); - // updateCursorWrapper(this); - // Destroy the DOM created by the default - // ProseMirror ViewDesc implementation; we - // have a NodeViewDesc from React instead. - // @ts-expect-error We're making use of knowledge of internal attributes here - this.docView.dom.replaceChildren(); - // @ts-expect-error We're making use of knowledge of internal attributes here - this.docView = props.docView; - } -} -const EMPTY_SCHEMA = new Schema({ - nodes: { - doc: { - content: "text*" - }, - text: { - inline: true - } - } -}); -const EMPTY_STATE = EditorState.create({ - schema: EMPTY_SCHEMA -}); -let didWarnValueDefaultValue = false; -/** - * Creates, mounts, and manages a ProseMirror `EditorView`. - * - * All state and props updates are executed in a layout effect. - * To ensure that the EditorState and EditorView are never out of - * sync, it's important that the EditorView produced by this hook - * is only accessed through the `useEditorViewEvent` and - * `useEditorViewLayoutEffect` hooks. - */ export function useEditor(mount, options) { - if (process.env.NODE_ENV !== "production") { - if (options.defaultState !== undefined && options.state !== undefined && !didWarnValueDefaultValue) { - console.error("A component contains a ProseMirror editor with both value and defaultValue props. " + "ProseMirror editors must be either controlled or uncontrolled " + "(specify either the state prop, or the defaultState prop, but not both). " + "Decide between using a controlled or uncontrolled ProseMirror editor " + "and remove one of these props. More info: " + "https://reactjs.org/link/controlled-components"); - didWarnValueDefaultValue = true; - } - } - const [view, setView] = useState(null); - const [cursorWrapper, _setCursorWrapper] = useState(null); - const forceUpdate = useForceUpdate(); - const defaultState = options.defaultState ?? EMPTY_STATE; - const [_state, setState] = useState(defaultState); - const state = options.state ?? _state; - const { componentEventListenersPlugin , registerEventListener , unregisterEventListener } = useComponentEventListeners(); - const setCursorWrapper = useCallback((deco)=>{ - flushSync(()=>{ - _setCursorWrapper(deco); - }); - }, []); - const plugins = useMemo(()=>[ - ...options.plugins ?? [], - componentEventListenersPlugin, - beforeInputPlugin(setCursorWrapper) - ], [ - options.plugins, - componentEventListenersPlugin, - setCursorWrapper - ]); - function dispatchTransaction(tr) { - flushSync(()=>{ - if (!options.state) { - setState((s)=>s.apply(tr)); - } - if (options.dispatchTransaction) { - options.dispatchTransaction.call(this, tr); - } - }); - } - const tempDom = document.createElement("div"); - const docViewDescRef = useRef(new NodeViewDesc(undefined, [], state.doc, [], DecorationSet.empty, tempDom, null, tempDom)); - const directEditorProps = { - ...options, - state, - plugins, - dispatchTransaction, - docView: docViewDescRef.current - }; - // This rule is concerned about infinite updates due to the - // call to setView. These calls are deliberately conditional, - // so this is not a concern. - // eslint-disable-next-line react-hooks/exhaustive-deps - useLayoutEffect(()=>{ - if (view && view.dom !== mount) { - setView(null); - } - if (!mount) { - return; - } - if (!view) { - const newView = new ReactEditorView({ - mount - }, directEditorProps); - setView(newView); - newView.dom.addEventListener("compositionend", forceUpdate); - return; - } - }); - view?.pureSetProps(directEditorProps); - return useMemo(()=>({ - view: view, - state: state, - registerEventListener, - unregisterEventListener, - cursorWrapper, - docViewDescRef - }), [ - view, - state, - registerEventListener, - unregisterEventListener, - cursorWrapper - ]); -} diff --git a/dist/esm/hooks/useEditorEffect.js b/dist/esm/hooks/useEditorEffect.js deleted file mode 100644 index 75039ed8..00000000 --- a/dist/esm/hooks/useEditorEffect.js +++ /dev/null @@ -1,38 +0,0 @@ -import { useContext } from "react"; -import { EditorContext } from "../contexts/EditorContext.js"; -import { useLayoutGroupEffect } from "./useLayoutGroupEffect.js"; -/** - * Registers a layout effect to run after the EditorView has - * been updated with the latest EditorState and Decorations. - * - * Effects can take an EditorView instance as an argument. - * This hook should be used to execute layout effects that - * depend on the EditorView, such as for positioning DOM - * nodes based on ProseMirror positions. - * - * Layout effects registered with this hook still fire - * synchronously after all DOM mutations, but they do so - * _after_ the EditorView has been updated, even when the - * EditorView lives in an ancestor component. - */ export function useEditorEffect(effect, dependencies) { - const { view } = useContext(EditorContext); - // The rules of hooks want `effect` to be included in the - // dependency list, but dependency issues for `effect` will - // be caught by the linter at the call-site for - // `useEditorViewLayoutEffect`. - // Note: we specifically don't want to re-run the effect - // every time it changes, because it will most likely - // be defined inline and run on every re-render. - useLayoutGroupEffect(()=>{ - if (view) { - return effect(view); - } - }, // The rules of hooks want to be able to statically - // verify the dependencies for the effect, but this will - // have already happened at the call-site. - // eslint-disable-next-line react-hooks/exhaustive-deps - dependencies && [ - view, - ...dependencies - ]); -} diff --git a/dist/esm/hooks/useEditorEventCallback.js b/dist/esm/hooks/useEditorEventCallback.js deleted file mode 100644 index aef95af5..00000000 --- a/dist/esm/hooks/useEditorEventCallback.js +++ /dev/null @@ -1,35 +0,0 @@ -import { useCallback, useContext, useRef } from "react"; -import { EditorContext } from "../contexts/EditorContext.js"; -import { useEditorEffect } from "./useEditorEffect.js"; -/** - * Returns a stable function reference to be used as an - * event handler callback. - * - * The callback will be called with the EditorView instance - * as its first argument. - * - * This hook is dependent on both the - * `EditorViewContext.Provider` and the - * `DeferredLayoutEffectProvider`. It can only be used in a - * component that is mounted as a child of both of these - * providers. - */ export function useEditorEventCallback(callback) { - const ref = useRef(callback); - const { view } = useContext(EditorContext); - useEditorEffect(()=>{ - ref.current = callback; - }, [ - callback - ]); - return useCallback(function() { - for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){ - args[_key] = arguments[_key]; - } - if (view) { - return ref.current(view, ...args); - } - return; - }, [ - view - ]); -} diff --git a/dist/esm/hooks/useEditorEventListener.js b/dist/esm/hooks/useEditorEventListener.js deleted file mode 100644 index 9a9f833a..00000000 --- a/dist/esm/hooks/useEditorEventListener.js +++ /dev/null @@ -1,28 +0,0 @@ -import { useCallback, useContext, useRef } from "react"; -import { EditorContext } from "../contexts/EditorContext.js"; -import { useEditorEffect } from "./useEditorEffect.js"; -/** - * Attaches an event listener at the `EditorView`'s DOM node. See - * [the ProseMirror docs](https://prosemirror.net/docs/ref/#view.EditorProps.handleDOMEvents) - * for more details. - */ export function useEditorEventListener(eventType, handler) { - const { registerEventListener , unregisterEventListener } = useContext(EditorContext); - const ref = useRef(handler); - useEditorEffect(()=>{ - ref.current = handler; - }, [ - handler - ]); - const eventHandler = useCallback(function(view, event) { - return ref.current.call(this, view, event); - }, []); - useEditorEffect(()=>{ - registerEventListener(eventType, eventHandler); - return ()=>unregisterEventListener(eventType, eventHandler); - }, [ - eventHandler, - eventType, - registerEventListener, - unregisterEventListener - ]); -} diff --git a/dist/esm/hooks/useEditorState.js b/dist/esm/hooks/useEditorState.js deleted file mode 100644 index 34fbd40e..00000000 --- a/dist/esm/hooks/useEditorState.js +++ /dev/null @@ -1,8 +0,0 @@ -import { useContext } from "react"; -import { EditorContext } from "../contexts/EditorContext.js"; -/** - * Provides access to the current EditorState value. - */ export function useEditorState() { - const { state: editorState } = useContext(EditorContext); - return editorState; -} diff --git a/dist/esm/hooks/useForceUpdate.js b/dist/esm/hooks/useForceUpdate.js deleted file mode 100644 index 8fbe3114..00000000 --- a/dist/esm/hooks/useForceUpdate.js +++ /dev/null @@ -1,8 +0,0 @@ -import { useReducer } from "react"; -/** - * Provides a function that forces an update of the - * component. - */ export function useForceUpdate() { - const [, forceUpdate] = useReducer((x)=>x + 1, 0); - return forceUpdate; -} diff --git a/dist/esm/hooks/useLayoutGroupEffect.js b/dist/esm/hooks/useLayoutGroupEffect.js deleted file mode 100644 index abe39eac..00000000 --- a/dist/esm/hooks/useLayoutGroupEffect.js +++ /dev/null @@ -1,9 +0,0 @@ -import { useContext, useLayoutEffect } from "react"; -import { LayoutGroupContext } from "../contexts/LayoutGroupContext.js"; -/** Registers a layout effect to run at the nearest `LayoutGroup` boundary. */ export function useLayoutGroupEffect(effect, deps) { - const register = useContext(LayoutGroupContext); - // The rule for hooks wants to statically verify the deps, - // but the dependencies are up to the caller, not this implementation. - // eslint-disable-next-line react-hooks/exhaustive-deps - useLayoutEffect(()=>register(effect), deps); -} diff --git a/dist/esm/hooks/useNodeViewDescriptor.js b/dist/esm/hooks/useNodeViewDescriptor.js deleted file mode 100644 index 277c7723..00000000 --- a/dist/esm/hooks/useNodeViewDescriptor.js +++ /dev/null @@ -1,35 +0,0 @@ -import { useContext, useLayoutEffect, useRef } from "react"; -import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js"; -import { NodeViewDesc } from "../viewdesc.js"; -export function useNodeViewDescriptor(node, domRef, nodeDomRef, innerDecorations, outerDecorations, viewDesc, contentDOMRef) { - const nodeViewDescRef = useRef(viewDesc); - const siblingDescriptors = useContext(ChildDescriptorsContext); - const childDescriptors = []; - useLayoutEffect(()=>{ - if (!node || !nodeDomRef.current) return; - const firstChildDesc = childDescriptors[0]; - if (!nodeViewDescRef.current) { - nodeViewDescRef.current = new NodeViewDesc(undefined, childDescriptors, node, outerDecorations, innerDecorations, domRef?.current ?? nodeDomRef.current, firstChildDesc?.dom.parentElement ?? null, nodeDomRef.current); - } else { - nodeViewDescRef.current.parent = undefined; - nodeViewDescRef.current.children = childDescriptors; - nodeViewDescRef.current.node = node; - nodeViewDescRef.current.outerDeco = outerDecorations; - nodeViewDescRef.current.innerDeco = innerDecorations; - nodeViewDescRef.current.dom = domRef?.current ?? nodeDomRef.current; - // @ts-expect-error We have our own ViewDesc implementations - nodeViewDescRef.current.dom.pmViewDesc = nodeViewDescRef.current; - nodeViewDescRef.current.contentDOM = // If there's already a contentDOM, we can just - // keep it; it won't have changed. This is especially - // important during compositions, where the - // firstChildDesc might not have a correct dom node set yet. - contentDOMRef?.current ?? nodeViewDescRef.current.contentDOM ?? firstChildDesc?.dom.parentElement ?? null; - nodeViewDescRef.current.nodeDOM = nodeDomRef.current; - } - siblingDescriptors.push(nodeViewDescRef.current); - for (const childDesc of childDescriptors){ - childDesc.parent = nodeViewDescRef.current; - } - }); - return childDescriptors; -} diff --git a/dist/esm/hooks/usePendingViewEffects.js b/dist/esm/hooks/usePendingViewEffects.js deleted file mode 100644 index be59ba6b..00000000 --- a/dist/esm/hooks/usePendingViewEffects.js +++ /dev/null @@ -1,11 +0,0 @@ -import { useLayoutEffect } from "react"; -export function usePendingViewEffects(view) { - useLayoutEffect(()=>{ - // @ts-expect-error Internal property - domObserver - view?.domObserver.selectionToDOM(); - view?.runPendingEffects(); - }, [ - view, - view?.props - ]); -} diff --git a/dist/esm/hooks/useReactKeys.js b/dist/esm/hooks/useReactKeys.js deleted file mode 100644 index 435371fe..00000000 --- a/dist/esm/hooks/useReactKeys.js +++ /dev/null @@ -1,6 +0,0 @@ -import { reactKeysPluginKey } from "../plugins/reactKeys.js"; -import { useEditorState } from "./useEditorState.js"; -export function useReactKeys() { - const state = useEditorState(); - return state && reactKeysPluginKey.getState(state); -} diff --git a/dist/esm/index.js b/dist/esm/index.js deleted file mode 100644 index 85823788..00000000 --- a/dist/esm/index.js +++ /dev/null @@ -1,9 +0,0 @@ -"use client"; -export { ProseMirror } from "./components/ProseMirror.js"; -export { ProseMirrorDoc } from "./components/ProseMirrorDoc.js"; -export { useEditorEffect } from "./hooks/useEditorEffect.js"; -export { useEditorEventCallback } from "./hooks/useEditorEventCallback.js"; -export { useEditorEventListener } from "./hooks/useEditorEventListener.js"; -export { useEditorState } from "./hooks/useEditorState.js"; -export { reactKeys } from "./plugins/reactKeys.js"; -export { widget } from "./decorations/ReactWidgetType.js"; diff --git a/dist/esm/plugins/__tests__/reactKeys.test.js b/dist/esm/plugins/__tests__/reactKeys.test.js deleted file mode 100644 index 158737f2..00000000 --- a/dist/esm/plugins/__tests__/reactKeys.test.js +++ /dev/null @@ -1,77 +0,0 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ import { Schema } from "prosemirror-model"; -import { EditorState } from "prosemirror-state"; -import { reactKeys, reactKeysPluginKey } from "../reactKeys.js"; -const schema = new Schema({ - nodes: { - doc: { - content: "block+" - }, - paragraph: { - group: "block", - content: "inline*" - }, - list: { - group: "block", - content: "list_item+" - }, - list_item: { - content: "inline*" - }, - text: { - group: "inline" - } - } -}); -describe("reactNodeViewPlugin", ()=>{ - it("should create a unique key for each node", ()=>{ - const editorState = EditorState.create({ - doc: schema.topNodeType.create(null, [ - schema.nodes.paragraph.create(), - schema.nodes.paragraph.create(), - schema.nodes.paragraph.create() - ]), - plugins: [ - reactKeys() - ] - }); - const pluginState = reactKeysPluginKey.getState(editorState); - expect(pluginState.posToKey.size).toBe(3); - }); - it("should maintain key stability when possible", ()=>{ - const initialEditorState = EditorState.create({ - doc: schema.topNodeType.create(null, [ - schema.nodes.paragraph.create({}, schema.text("Hello")), - schema.nodes.paragraph.create(), - schema.nodes.paragraph.create() - ]), - plugins: [ - reactKeys() - ] - }); - const initialPluginState = reactKeysPluginKey.getState(initialEditorState); - const nextEditorState = initialEditorState.apply(initialEditorState.tr.insertText(", world!", 6)); - const nextPluginState = reactKeysPluginKey.getState(nextEditorState); - expect(Array.from(initialPluginState.keyToPos.keys())).toEqual(Array.from(nextPluginState.keyToPos.keys())); - }); - it("should create unique keys for new nodes", ()=>{ - const initialEditorState = EditorState.create({ - doc: schema.topNodeType.create(null, [ - schema.nodes.paragraph.create(), - schema.nodes.paragraph.create(), - schema.nodes.paragraph.create() - ]), - plugins: [ - reactKeys() - ] - }); - const initialPluginState = reactKeysPluginKey.getState(initialEditorState); - const nextEditorState = initialEditorState.apply(initialEditorState.tr.insert(0, schema.nodes.list.createAndFill())); - const nextPluginState = reactKeysPluginKey.getState(nextEditorState); - // Adds new keys for new nodes - expect(nextPluginState.keyToPos.size).toBe(5); - // Maintains keys for previous nodes that are still there - Array.from(initialPluginState.keyToPos.keys()).forEach((key)=>{ - expect(Array.from(nextPluginState.keyToPos.keys())).toContain(key); - }); - }); -}); diff --git a/dist/esm/plugins/beforeInputPlugin.js b/dist/esm/plugins/beforeInputPlugin.js deleted file mode 100644 index a756661b..00000000 --- a/dist/esm/plugins/beforeInputPlugin.js +++ /dev/null @@ -1,208 +0,0 @@ -import { Plugin } from "prosemirror-state"; -import { CursorWrapper } from "../components/CursorWrapper.js"; -import { widget } from "../decorations/ReactWidgetType.js"; -import { reactKeysPluginKey } from "./reactKeys.js"; -const SPACE = /\s/; -const PUNCTUATION = /[\u0021-\u0023\u0025-\u002A\u002C-\u002F\u003A\u003B\u003F\u0040\u005B-\u005D\u005F\u007B\u007D\u00A1\u00A7\u00AB\u00B6\u00B7\u00BB\u00BF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0AF0\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E3B\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/; -const CHAMELEON = /['\u2018\u2019]/; -const isWordCharacter = function(doc, pos) { - let checkDir = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : -1; - const $pos = doc.resolve(pos); - // The position is at the beginning of a node - if ($pos.parentOffset === 0) return false; - const char = doc.textBetween(pos + checkDir, pos, null, " "); - if (SPACE.test(char)) { - return false; - } - // Chameleons count as word characters as long as they're in a word, so - // recurse to see if the next one is a word character or not. - if (CHAMELEON.test(char)) { - if (isWordCharacter(doc, pos - 1)) { - return true; - } - } - if (PUNCTUATION.test(char)) { - return false; - } - return true; -}; -function insertText(view, eventData) { - let options = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {}; - if (eventData === null) return false; - const from = options.from ?? view.state.selection.from; - const to = options.to ?? view.state.selection.to; - if (view.someProp("handleTextInput")?.(view, from, to, eventData)) { - return true; - } - const { tr } = view.state; - if (options.marks) tr.ensureMarks(options.marks); - tr.insertText(eventData, from, to); - if (options.bust) { - const $from = view.state.doc.resolve(from); - const sharedAncestorDepth = $from.sharedDepth(to); - const sharedAncestorPos = $from.start(sharedAncestorDepth); - const parentKey = reactKeysPluginKey.getState(view.state)?.posToKey.get(sharedAncestorPos - 1); - tr.setMeta(reactKeysPluginKey, { - type: "bustKey", - payload: { - key: parentKey - } - }); - } - view.dispatch(tr); - return true; -} -function findWordBoundaryBackward(doc, start) { - let pos = start; - while(!isWordCharacter(doc, pos)){ - pos--; - } - while(isWordCharacter(doc, pos)){ - pos--; - } - return pos; -} -function findWordBoundaryForward(doc, start) { - let pos = start; - while(!isWordCharacter(doc, pos, 1)){ - pos++; - } - while(isWordCharacter(doc, pos, 1)){ - pos++; - } - return pos; -} -export function beforeInputPlugin(setCursorWrapper) { - let compositionText = null; - let compositionMarks = null; - return new Plugin({ - props: { - handleDOMEvents: { - compositionstart (view) { - const { state } = view; - view.dispatch(state.tr.deleteSelection()); - const $pos = state.selection.$from; - if (state.selection.empty && (state.storedMarks || !$pos.textOffset && $pos.parentOffset && $pos.nodeBefore?.marks.some((m)=>m.type.spec.inclusive === false))) { - setCursorWrapper(widget(state.selection.from, CursorWrapper, { - key: "cursor-wrapper", - marks: state.storedMarks ?? $pos.marks() - })); - } - compositionMarks = state.storedMarks ?? $pos.marks(); - // @ts-expect-error Internal property - input - view.input.composing = true; - return true; - }, - compositionupdate () { - return true; - }, - compositionend (view) { - // @ts-expect-error Internal property - input - view.input.composing = false; - if (compositionText === null) return; - insertText(view, compositionText, { - // TODO: Rather than busting the reactKey cache here, - // which is pretty blunt and doesn't work for - // multi-node replacements, we should attempt to - // snapshot the selected DOM during compositionstart - // and restore it before we end the composition. - // This should allow React to successfully clean up - // and insert the newly composed text, without requiring - // any remounts - bust: true, - marks: compositionMarks - }); - compositionText = null; - compositionMarks = null; - setCursorWrapper(null); - return true; - }, - beforeinput (view, event) { - event.preventDefault(); - switch(event.inputType){ - case "insertCompositionText": - { - if (event.data === null) break; - compositionText = event.data; - break; - } - case "insertReplacementText": - { - const ranges = event.getTargetRanges(); - event.dataTransfer?.items[0]?.getAsString((data)=>{ - for (const range of ranges){ - // @ts-expect-error Internal property - docView - const from = view.docView.posFromDOM(range.startContainer, range.startOffset, 1); - // @ts-expect-error Internal property - docView - const to = view.docView.posFromDOM(range.endContainer, range.endOffset, 1); - insertText(view, data, { - from, - to - }); - } - }); - break; - } - case "insertText": - { - insertText(view, event.data); - break; - } - case "deleteWordBackward": - { - const { tr , doc , selection } = view.state; - const from = selection.empty ? findWordBoundaryBackward(view.state.doc, selection.from) : selection.from; - const to = selection.to; - const storedMarks = doc.resolve(from).marksAcross(doc.resolve(to)); - tr.delete(from, to).setStoredMarks(storedMarks); - view.dispatch(tr); - break; - } - case "deleteWordForward": - { - const { tr , doc , selection } = view.state; - const from = selection.empty ? findWordBoundaryForward(view.state.doc, selection.from) : selection.from; - const to = selection.to; - const storedMarks = doc.resolve(from).marksAcross(doc.resolve(to)); - tr.delete(from, to).setStoredMarks(storedMarks); - view.dispatch(tr); - break; - } - case "deleteContentBackward": - { - const { tr , doc , selection } = view.state; - const from = selection.empty ? selection.from - 1 : selection.from; - const to = selection.to; - const storedMarks = doc.resolve(from).marksAcross(doc.resolve(to)); - tr.delete(from, to).setStoredMarks(storedMarks); - view.dispatch(tr); - break; - } - case "deleteContentForward": - { - const { tr , doc , selection } = view.state; - const from = selection.from; - const to = selection.empty ? selection.to + 1 : selection.to; - const storedMarks = doc.resolve(from).marksAcross(doc.resolve(to)); - tr.delete(from, to).setStoredMarks(storedMarks); - break; - } - case "deleteContent": - { - const { tr , doc , selection } = view.state; - const storedMarks = doc.resolve(selection.from).marksAcross(doc.resolve(selection.to)); - tr.delete(selection.from, selection.to).setStoredMarks(storedMarks); - view.dispatch(tr); - break; - } - default: - { - break; - } - } - return true; - } - } - } - }); -} diff --git a/dist/esm/plugins/componentEventListeners.js b/dist/esm/plugins/componentEventListeners.js deleted file mode 100644 index 4b5f0792..00000000 --- a/dist/esm/plugins/componentEventListeners.js +++ /dev/null @@ -1,25 +0,0 @@ -import { Plugin, PluginKey } from "prosemirror-state"; -import { unstable_batchedUpdates as batch } from "react-dom"; -export function componentEventListeners(eventHandlerRegistry) { - const domEventHandlers = {}; - for (const [eventType, handlers] of eventHandlerRegistry.entries()){ - function handleEvent(view, event) { - for (const handler of handlers){ - let handled = false; - batch(()=>{ - handled = !!handler.call(this, view, event); - }); - if (handled || event.defaultPrevented) return true; - } - return false; - } - domEventHandlers[eventType] = handleEvent; - } - const plugin = new Plugin({ - key: new PluginKey("@nytimes/react-prosemirror/componentEventListeners"), - props: { - handleDOMEvents: domEventHandlers - } - }); - return plugin; -} diff --git a/dist/esm/plugins/componentEventListenersPlugin.js b/dist/esm/plugins/componentEventListenersPlugin.js deleted file mode 100644 index ce80ffc7..00000000 --- a/dist/esm/plugins/componentEventListenersPlugin.js +++ /dev/null @@ -1,25 +0,0 @@ -import { Plugin, PluginKey } from "prosemirror-state"; -import { unstable_batchedUpdates as batch } from "react-dom"; -export function createComponentEventListenersPlugin(eventHandlerRegistry) { - const domEventHandlers = {}; - for (const [eventType, handlers] of eventHandlerRegistry.entries()){ - function handleEvent(view, event) { - for (const handler of handlers){ - let handled = false; - batch(()=>{ - handled = !!handler.call(this, view, event); - }); - if (handled || event.defaultPrevented) return true; - } - return false; - } - domEventHandlers[eventType] = handleEvent; - } - const plugin = new Plugin({ - key: new PluginKey("componentEventListeners"), - props: { - handleDOMEvents: domEventHandlers - } - }); - return plugin; -} diff --git a/dist/esm/plugins/reactKeys.js b/dist/esm/plugins/reactKeys.js deleted file mode 100644 index dceed186..00000000 --- a/dist/esm/plugins/reactKeys.js +++ /dev/null @@ -1,80 +0,0 @@ -import { Plugin, PluginKey } from "prosemirror-state"; -export function createNodeKey() { - const key = Math.floor(Math.random() * 0xffffff).toString(16); - return key; -} -export const reactKeysPluginKey = new PluginKey("@nytimes/react-prosemirror/reactKeys"); -/** - * Tracks a unique key for each (non-text) node in the - * document, identified by its current position. Keys are - * (mostly) stable across transaction applications. The - * key for a given node can be accessed by that node's - * current position in the document, and vice versa. - */ export function reactKeys() { - let composing = false; - return new Plugin({ - key: reactKeysPluginKey, - state: { - init (_, state) { - const next = { - posToKey: new Map(), - keyToPos: new Map() - }; - state.doc.descendants((_, pos)=>{ - const key = createNodeKey(); - next.posToKey.set(pos, key); - next.keyToPos.set(key, pos); - return true; - }); - return next; - }, - /** - * Keeps node keys (mostly) stable across transactions. - * - * To accomplish this, we map each node position backwards - * through the transaction to identify its previous position, - * and thereby retrieve its previous key. - */ apply (tr, value, _, newState) { - if (!tr.docChanged || composing) return value; - const meta = tr.getMeta(reactKeysPluginKey); - const keyToBust = meta?.type === "bustKey" && meta.payload.key; - const next = { - posToKey: new Map(), - keyToPos: new Map() - }; - const posToKeyEntries = Array.from(value.posToKey.entries()).sort((param, param1)=>{ - let [a] = param, [b] = param1; - return a - b; - }); - for (const [pos, key] of posToKeyEntries){ - const { pos: newPos , deleted } = tr.mapping.mapResult(pos); - if (deleted) continue; - let newKey = key; - if (keyToBust === key) { - newKey = createNodeKey(); - } - next.posToKey.set(newPos, newKey); - next.keyToPos.set(newKey, newPos); - } - newState.doc.descendants((_, pos)=>{ - if (next.posToKey.has(pos)) return true; - const key = createNodeKey(); - next.posToKey.set(pos, key); - next.keyToPos.set(key, pos); - return true; - }); - return next; - } - }, - props: { - handleDOMEvents: { - compositionstart: ()=>{ - composing = true; - }, - compositionend: ()=>{ - composing = false; - } - } - } - }); -} diff --git a/dist/esm/selection/SelectionDOMObserver.js b/dist/esm/selection/SelectionDOMObserver.js deleted file mode 100644 index ccd27d1e..00000000 --- a/dist/esm/selection/SelectionDOMObserver.js +++ /dev/null @@ -1,164 +0,0 @@ -import { Selection } from "prosemirror-state"; -import { browser } from "../browser.js"; -import { parentNode, selectionCollapsed } from "../dom.js"; -import { hasFocusAndSelection } from "./hasFocusAndSelection.js"; -import { selectionFromDOM } from "./selectionFromDOM.js"; -import { isEquivalentPosition, selectionToDOM } from "./selectionToDOM.js"; -let SelectionState = class SelectionState { - set(sel) { - this.anchorNode = sel.anchorNode; - this.anchorOffset = sel.anchorOffset; - this.focusNode = sel.focusNode; - this.focusOffset = sel.focusOffset; - } - clear() { - this.anchorNode = this.focusNode = null; - } - eq(sel) { - return sel.anchorNode == this.anchorNode && sel.anchorOffset == this.anchorOffset && sel.focusNode == this.focusNode && sel.focusOffset == this.focusOffset; - } - constructor(){ - this.anchorNode = null; - this.anchorOffset = 0; - this.focusNode = null; - this.focusOffset = 0; - } -}; -export class SelectionDOMObserver { - connectSelection() { - // TODO: Unclear whether this is safe. Without it, - // the DOMObserver will be triggered by its own selection - // updates - // setTimeout(() => - this.view.dom.ownerDocument.addEventListener("selectionchange", this.onSelectionChange); - // ); - } - disconnectSelection() { - this.view.dom.ownerDocument.removeEventListener("selectionchange", this.onSelectionChange); - } - stop() { - this.disconnectSelection(); - } - start() { - this.connectSelection(); - } - suppressSelectionUpdates() { - this.suppressingSelectionUpdates = true; - setTimeout(()=>this.suppressingSelectionUpdates = false, 50); - } - setCurSelection() { - // @ts-expect-error Internal method - this.currentSelection.set(this.view.domSelectionRange()); - } - ignoreSelectionChange(sel) { - if (!sel.focusNode) return true; - const ancestors = new Set(); - let container; - for(let scan = sel.focusNode; scan; scan = parentNode(scan))ancestors.add(scan); - for(let scan = sel.anchorNode; scan; scan = parentNode(scan))if (ancestors.has(scan)) { - container = scan; - break; - } - // @ts-expect-error Internal property (docView) - const desc = container && this.view.docView.nearestDesc(container); - if (desc && desc.ignoreMutation({ - type: "selection", - target: container?.nodeType == 3 ? container?.parentNode : container - })) { - this.setCurSelection(); - return true; - } - return; - } - registerMutation() { - // pass - } - flushSoon() { - if (this.flushingSoon < 0) this.flushingSoon = window.setTimeout(()=>{ - this.flushingSoon = -1; - this.flush(); - }, 20); - } - updateSelection() { - const { view } = this; - const compositionID = // @ts-expect-error Internal property (input) - view.input.compositionPendingChanges || // @ts-expect-error Internal property (input) - (view.composing ? view.input.compositionID : 0); - // @ts-expect-error Internal property (input) - view.input.compositionPendingChanges = 0; - const origin = // @ts-expect-error Internal property (input) - view.input.lastSelectionTime > Date.now() - 50 ? view.input.lastSelectionOrigin : null; - const newSel = selectionFromDOM(view, origin); - if (newSel && !view.state.selection.eq(newSel)) { - const tr = view.state.tr.setSelection(newSel); - if (origin == "pointer") tr.setMeta("pointer", true); - else if (origin == "key") tr.scrollIntoView(); - if (compositionID) tr.setMeta("composition", compositionID); - view.dispatch(tr); - } - } - selectionToDOM() { - const { view } = this; - selectionToDOM(view); - // @ts-expect-error Internal property (domSelectionRange) - const sel = view.domSelectionRange(); - this.currentSelection.set(sel); - } - flush() { - const { view } = this; - // @ts-expect-error Internal property (docView) - if (!view.docView || this.flushingSoon > -1) return; - // @ts-expect-error Internal property (domSelectionRange) - const sel = view.domSelectionRange(); - const newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasFocusAndSelection(view) && !this.ignoreSelectionChange(sel); - let readSel = null; - // If it looks like the browser has reset the selection to the - // start of the document after focus, restore the selection from - // the state - if (newSel && // @ts-expect-error Internal property (input) - view.input.lastFocus > Date.now() - 200 && // @ts-expect-error Internal property (input) - Math.max(view.input.lastTouch, view.input.lastClick.time) < Date.now() - 300 && selectionCollapsed(sel) && (readSel = selectionFromDOM(view)) && readSel.eq(Selection.near(view.state.doc.resolve(0), 1))) { - // @ts-expect-error Internal property (input) - view.input.lastFocus = 0; - selectionToDOM(view); - this.currentSelection.set(sel); - // @ts-expect-error Internal property (scrollToSelection) - view.scrollToSelection(); - } else if (newSel) { - this.updateSelection(); - if (!this.currentSelection.eq(sel)) selectionToDOM(view); - this.currentSelection.set(sel); - } - } - forceFlush() { - if (this.flushingSoon > -1) { - window.clearTimeout(this.flushingSoon); - this.flushingSoon = -1; - this.flush(); - } - } - onSelectionChange() { - if (!hasFocusAndSelection(this.view)) return; - if (this.view.composing) 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) { - // @ts-expect-error Internal method - const sel = this.view.domSelectionRange(); - // Selection.isCollapsed isn't reliable on IE - if (sel.focusNode && isEquivalentPosition(sel.focusNode, sel.focusOffset, // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - sel.anchorNode, sel.anchorOffset)) return this.flushSoon(); - } - this.flush(); - } - constructor(view){ - this.view = view; - this.flushingSoon = -1; - this.currentSelection = new SelectionState(); - this.suppressingSelectionUpdates = false; - this.view = view; - this.onSelectionChange = this.onSelectionChange.bind(this); - } -} diff --git a/dist/esm/selection/hasFocusAndSelection.js b/dist/esm/selection/hasFocusAndSelection.js deleted file mode 100644 index b294c9a3..00000000 --- a/dist/esm/selection/hasFocusAndSelection.js +++ /dev/null @@ -1,17 +0,0 @@ -export function hasFocusAndSelection(view) { - if (view.editable && !view.hasFocus()) return false; - return hasSelection(view); -} -export function hasSelection(view) { - // @ts-expect-error Internal method - const sel = view.domSelectionRange(); - 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; - } -} diff --git a/dist/esm/selection/selectionFromDOM.js b/dist/esm/selection/selectionFromDOM.js deleted file mode 100644 index 51832f8a..00000000 --- a/dist/esm/selection/selectionFromDOM.js +++ /dev/null @@ -1,39 +0,0 @@ -import { NodeSelection, TextSelection } from "prosemirror-state"; -import { isOnEdge, selectionCollapsed } from "../dom.js"; -export function selectionBetween(view, $anchor, $head, bias) { - return view.someProp("createSelectionBetween", (f)=>f(view, $anchor, $head)) || TextSelection.between($anchor, $head, bias); -} -export function selectionFromDOM(view) { - let origin = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : null; - // @ts-expect-error Internal method - const domSel = view.domSelectionRange(), doc = view.state.doc; - if (!domSel.focusNode) return null; - // @ts-expect-error Internel property - let nearestDesc = view.docView.nearestDesc(domSel.focusNode); - const inWidget = nearestDesc && nearestDesc.size == 0; - // @ts-expect-error Internel property - const head = view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset, 1); - if (head < 0) return null; - const $head = doc.resolve(head); - let $anchor, selection; - if (selectionCollapsed(domSel)) { - $anchor = $head; - while(nearestDesc && !nearestDesc.node)nearestDesc = nearestDesc.parent; - const nearestDescNode = nearestDesc.node; - if (nearestDesc && nearestDescNode.isAtom && NodeSelection.isSelectable(nearestDescNode) && nearestDesc.parent && !(nearestDescNode.isInline && isOnEdge(domSel.focusNode, domSel.focusOffset, nearestDesc.dom))) { - const pos = nearestDesc.posBefore; - selection = new NodeSelection(head == pos ? $head : doc.resolve(pos)); - } - } else { - // @ts-expect-error Internal property - const anchor = view.docView.posFromDOM(// eslint-disable-next-line @typescript-eslint/no-non-null-assertion - domSel.anchorNode, domSel.anchorOffset, 1); - if (anchor < 0) return null; - $anchor = doc.resolve(anchor); - } - if (!selection) { - const bias = origin == "pointer" || view.state.selection.head < $head.pos && !inWidget ? 1 : -1; - selection = selectionBetween(view, $anchor, $head, bias); - } - return selection; -} diff --git a/dist/esm/selection/selectionToDOM.js b/dist/esm/selection/selectionToDOM.js deleted file mode 100644 index c104a120..00000000 --- a/dist/esm/selection/selectionToDOM.js +++ /dev/null @@ -1,195 +0,0 @@ -import { NodeSelection, TextSelection } from "prosemirror-state"; -import { browser } from "../browser.js"; -// 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)); -}; -export 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); -} -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))) { - const parent = node.parentNode; - if (!parent || 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) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - node = node.childNodes[off + (dir < 0 ? -1 : 0)]; - if (node.contentEditable == "false") return false; - off = dir < 0 ? nodeSize(node) : 0; - } else { - return false; - } - } -} -export const domIndex = function(node) { - let n = node; - for(let index = 0;; index++){ - n = n.previousSibling; - if (!n) return index; - } -}; -export function nodeSize(node) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length; -} -export function syncNodeSelection(view, sel) { - const v = view; - if (sel instanceof NodeSelection) { - const desc = v.docView.descAt(sel.from); - if (desc != v.lastSelectedViewDesc) { - clearNodeSelection(v); - if (desc) desc.selectNode(); - v.lastSelectedViewDesc = desc; - } - } else { - clearNodeSelection(v); - } -} -// Clear all DOM statefulness of the last node selection. -function clearNodeSelection(view) { - const v = view; - if (v.lastSelectedViewDesc) { - if (v.lastSelectedViewDesc.parent) v.lastSelectedViewDesc.deselectNode(); - v.lastSelectedViewDesc = undefined; - } -} -export function hasSelection(view) { - const v = view; - const sel = v.domSelectionRange(); - 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 v.dom.contains(sel.anchorNode.nodeType == 3 ? sel.anchorNode.parentNode : sel.anchorNode) && (v.editable || v.dom.contains(// eslint-disable-next-line @typescript-eslint/no-non-null-assertion - sel.focusNode.nodeType == 3 ? sel.focusNode.parentNode : sel.focusNode)); - } catch (_) { - return false; - } -} -function editorOwnsSelection(view) { - return view.editable ? view.hasFocus() : hasSelection(view) && document.activeElement && document.activeElement.contains(view.dom); -} -function selectCursorWrapper(view) { - const v = view; - const domSel = v.domSelection(), range = document.createRange(); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const node = v.cursorWrapper.dom, img = node.nodeName == "IMG"; - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - 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 && !v.state.selection.visible && browser.ie && browser.ie_version <= 11) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - node.disabled = true; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - node.disabled = false; - } -} -function temporarilyEditableNear(view, pos) { - const v = view; - const { node , offset } = v.docView.domFromPos(pos, 0); - const after = offset < node.childNodes.length ? node.childNodes[offset] : null; - const before = offset ? node.childNodes[offset - 1] : null; - if (browser.safari && after && after.contentEditable == "false") return setEditable(after); - if ((!after || after.contentEditable == "false") && (!before || before.contentEditable == "false")) { - if (after) return setEditable(after); - else if (before) return setEditable(before); - } - return; -} -function setEditable(element) { - element.contentEditable = "true"; - if (browser.safari && element.draggable) { - element.draggable = false; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - element.wasDraggable = true; - } - return element; -} -function resetEditable(element) { - element.contentEditable = "false"; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - if (element.wasDraggable) { - element.draggable = true; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - element.wasDraggable = null; - } -} -function removeClassOnSelectionChange(view) { - const v = view; - const doc = v.dom.ownerDocument; - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - doc.removeEventListener("selectionchange", v.input.hideSelectionGuard); - const domSel = v.domSelectionRange(); - const node = domSel.anchorNode, offset = domSel.anchorOffset; - doc.addEventListener("selectionchange", v.input.hideSelectionGuard = ()=>{ - if (domSel.anchorNode != node || domSel.anchorOffset != offset) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - doc.removeEventListener("selectionchange", v.input.hideSelectionGuard); - setTimeout(()=>{ - if (!editorOwnsSelection(v) || v.state.selection.visible) v.dom.classList.remove("ProseMirror-hideselection"); - }, 20); - } - }); -} -const brokenSelectBetweenUneditable = browser.safari || browser.chrome && browser.chrome_version < 63; -export function selectionToDOM(view) { - let force = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : false; - const v = view; - const sel = v.state.selection; - syncNodeSelection(v, sel); - if (!editorOwnsSelection(v)) return; - // The delayed drag selection causes issues with Cell Selections - // in Safari. And the drag selection delay is to workarond issues - // which only present in Chrome. - if (!force && v.input.mouseDown && v.input.mouseDown.allowDefault && browser.chrome) { - const domSel = v.domSelectionRange(), curSel = v.domObserver.currentSelection; - if (domSel.anchorNode && curSel.anchorNode && isEquivalentPosition(domSel.anchorNode, domSel.anchorOffset, curSel.anchorNode, curSel.anchorOffset)) { - v.input.mouseDown.delayedSelectionSync = true; - v.domObserver.setCurSelection(); - return; - } - } - v.domObserver.disconnectSelection(); - if (v.cursorWrapper) { - selectCursorWrapper(v); - } else { - const { anchor , head } = sel; - let resetEditableFrom; - let resetEditableTo; - if (brokenSelectBetweenUneditable && !(sel instanceof TextSelection)) { - if (!sel.$from.parent.inlineContent) resetEditableFrom = temporarilyEditableNear(v, sel.from); - if (!sel.empty && !sel.$from.parent.inlineContent) resetEditableTo = temporarilyEditableNear(v, sel.to); - } - v.docView.setSelection(anchor, head, v.root, force); - if (brokenSelectBetweenUneditable) { - if (resetEditableFrom) resetEditable(resetEditableFrom); - if (resetEditableTo) resetEditable(resetEditableTo); - } - if (sel.visible) { - v.dom.classList.remove("ProseMirror-hideselection"); - } else { - v.dom.classList.add("ProseMirror-hideselection"); - if ("onselectionchange" in document) removeClassOnSelectionChange(v); - } - } - v.domObserver.setCurSelection(); - v.domObserver.connectSelection(); -} diff --git a/dist/esm/testing/editorViewTestHelpers.js b/dist/esm/testing/editorViewTestHelpers.js deleted file mode 100644 index 9cc38d75..00000000 --- a/dist/esm/testing/editorViewTestHelpers.js +++ /dev/null @@ -1,95 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ function _extends() { - _extends = Object.assign || function(target) { - for(var i = 1; i < arguments.length; i++){ - var source = arguments[i]; - for(var key in source){ - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; - return _extends.apply(this, arguments); -} -import { expect } from "@jest/globals"; -import { render } from "@testing-library/react"; -import { Node } from "prosemirror-model"; -import { EditorState, TextSelection } from "prosemirror-state"; -import { doc, eq, schema } from "prosemirror-test-builder"; -import React from "react"; -import { ProseMirror } from "../components/ProseMirror.js"; -import { ProseMirrorDoc } from "../components/ProseMirrorDoc.js"; -import { useEditorEffect } from "../hooks/useEditorEffect.js"; -import { reactKeys } from "../plugins/reactKeys.js"; -const toEqualNode = function(actual, expected) { - if (!(actual instanceof Node && expected instanceof Node)) { - throw new Error("Must be comparing nodes"); - } - const pass = eq(actual, expected); - return { - message: ()=>// `this` context will have correct typings - `expected ${this.utils.printReceived(actual)} ${pass ? "not " : ""}to equal ${this.utils.printExpected(expected)}`, - pass - }; -}; -expect.extend({ - toEqualNode -}); -export function tempEditor(param) { - let { doc: startDoc , selection , plugins , state: stateProp , ...props } = param; - startDoc = startDoc ?? doc(); - const state = stateProp ?? EditorState.create({ - doc: startDoc, - schema, - selection: selection ?? startDoc.tag?.a ? TextSelection.create(startDoc, startDoc.tag.a, startDoc.tag?.b) : undefined, - plugins: [ - ...plugins ?? [], - reactKeys() - ] - }); - let view; - function Test() { - useEditorEffect((v)=>{ - view = v; - }); - return null; - } - const { rerender , unmount } = render(/*#__PURE__*/ React.createElement(ProseMirror, _extends({}, stateProp ? { - state: stateProp - } : { - defaultState: state - }, props), /*#__PURE__*/ React.createElement(Test, null), /*#__PURE__*/ React.createElement(ProseMirrorDoc, null))); - function rerenderEditor(param) { - let { state: newStateProp , ...newProps } = param; - rerender(/*#__PURE__*/ React.createElement(ProseMirror, _extends({}, newStateProp && stateProp ? { - state: newStateProp - } : { - defaultState: state - }, { - ...props, - ...newProps - }), /*#__PURE__*/ React.createElement(Test, null), /*#__PURE__*/ React.createElement(ProseMirrorDoc, null))); - } - return { - rerender: rerenderEditor, - unmount, - view - }; -} -function findTextNodeInner(node, text) { - if (node.nodeType == 3) { - if (node.nodeValue == text) return node; - } else if (node.nodeType == 1) { - for(let ch = node.firstChild; ch; ch = ch.nextSibling){ - const found = findTextNodeInner(ch, text); - if (found) return found; - } - } - return undefined; -} -export function findTextNode(node, text) { - const found = findTextNodeInner(node, text); - if (found) return found; - throw new Error("Unable to find matching text node"); -} diff --git a/dist/esm/testing/setupProseMirrorView.js b/dist/esm/testing/setupProseMirrorView.js deleted file mode 100644 index 8bf8e629..00000000 --- a/dist/esm/testing/setupProseMirrorView.js +++ /dev/null @@ -1,76 +0,0 @@ -let oldElementFromPoint; -let oldGetClientRects; -let oldGetBoundingClientRect; -const mockElementFromPoint = ()=>globalThis.document.body; -const mockGetBoundingClientRect = ()=>{ - return { - bottom: 0, - height: 0, - left: 0, - right: 0, - top: 0, - width: 0, - x: 0, - y: 0, - toJSON () { - return { - bottom: 0, - height: 0, - left: 0, - right: 0, - top: 0, - width: 0, - x: 0, - y: 0 - }; - } - }; -}; -const mockGetClientRects = ()=>{ - const list = [ - { - bottom: 0, - height: 0, - left: 0, - right: 0, - top: 0, - width: 0, - x: 0, - y: 0, - toJSON () { - return { - bottom: 0, - height: 0, - left: 0, - right: 0, - top: 0, - width: 0, - x: 0, - y: 0 - }; - } - } - ]; - const domRectList = Object.assign(list, { - item (index) { - return list[index] ?? null; - } - }); - return domRectList; -}; -export function setupProseMirrorView() { - oldElementFromPoint = Document.prototype.elementFromPoint; - Document.prototype.elementFromPoint = mockElementFromPoint; - oldGetClientRects = Range.prototype.getClientRects; - Range.prototype.getClientRects = mockGetClientRects; - oldGetBoundingClientRect = Range.prototype.getBoundingClientRect; - Range.prototype.getBoundingClientRect = mockGetBoundingClientRect; -} -export function teardownProseMirrorView() { - // @ts-expect-error jsdom actually doesn't implement these, so they might be undefined - Document.prototype.elementFromPoint = oldElementFromPoint; - // @ts-expect-error jsdom actually doesn't implement these, so they might be undefined - Range.prototype.getClientRects = oldGetClientRects; - // @ts-expect-error jsdom actually doesn't implement these, so they might be undefined - Range.prototype.getBoundingClientRect = oldGetBoundingClientRect; -} diff --git a/dist/esm/viewdesc.js b/dist/esm/viewdesc.js deleted file mode 100644 index 8869cf26..00000000 --- a/dist/esm/viewdesc.js +++ /dev/null @@ -1,644 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-non-null-assertion */ import { Fragment } from "prosemirror-model"; -import { browser } from "./browser.js"; -import { domIndex, isEquivalentPosition } from "./selection/selectionToDOM.js"; -// 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. -export class ViewDesc { - // Used to check whether a given description corresponds to a - // widget/mark/node. - matchesWidget(_widget) { - return false; - } - matchesMark(_mark) { - return false; - } - matchesNode(_node, _outerDeco, _innerDeco) { - return false; - } - // @ts-expect-error ... - matchesHack(nodeName) { - return false; - } - // 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; - } - // Used by the editor's event handler to ignore events that come - // from certain descs. - // @ts-expect-error ... - stopEvent(event) { - 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++)// @ts-expect-error ... - 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() { - // pass - } - posBeforeChild(child) { - for(let i = 0, pos = this.posAtStart;; i++){ - const cur = this.children[i]; - if (cur == child) return pos; - // @ts-expect-error ... - 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; - } - 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 (dom == this.dom && this.contentDOM) { - atEnd = offset > domIndex(this.contentDOM); - } else 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.previousSibling) break; - } - if (atEnd == null && offset == dom.childNodes.length) for(let search = dom;; search = search.parentNode){ - if (search == this.dom) { - atEnd = true; - break; - } - if (search.nextSibling) break; - } - } - return (atEnd == null ? bias > 0 : atEnd) ? this.posAtEnd : this.posAtStart; - } - nearestDesc(dom) { - let onlyNodes = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : false; - for(let first = true, cur = dom; cur; cur = cur.parentNode){ - const desc = this.getDesc(cur); - let nodeDOM; - if (desc && (!onlyNodes || desc.node)) { - // If dom is outside of this desc's nodeDOM, don't count it. - if (first && (nodeDOM = desc.nodeDOM) && !(nodeDOM.nodeType == 1 ? nodeDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode) : nodeDOM == dom)) first = false; - else return desc; - } - } - return; - } - getDesc(dom) { - const desc = dom.pmViewDesc; - for(let cur = desc; cur; cur = cur.parent)if (cur == this) return desc; - return; - } - posFromDOM(dom, offset, bias) { - for(let scan = dom; scan; scan = scan.parentNode){ - const desc = this.getDesc(scan); - if (desc) return desc.localPosFromDOM(dom, offset, bias); - } - return -1; - } - // 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]; - const 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; - } - return; - } - domFromPos(pos, side) { - if (!this.contentDOM) return { - node: this.dom, - offset: 0, - atom: pos + 1 - }; - // First find the position in the child array - let i = 0, offset = 0; - for(let curPos = 0; i < this.children.length; i++){ - const child = this.children[i], end = curPos + child.size; - if (end > pos || child instanceof TrailingHackViewDesc) { - offset = pos - curPos; - break; - } - curPos = end; - } - // If this points into the middle of a child, call through - if (offset) return this.children[i].domFromPos(offset - this.children[i].border, side); - // Go back if there were any zero-length widgets with side >= 0 before this point - for(let prev; i && !(prev = this.children[i - 1]).size && prev instanceof WidgetViewDesc && prev.side >= 0; i--){ - // ... - } - // Scan towards the first useable node - if (side <= 0) { - let prev, enter = true; - for(;; i--, enter = false){ - prev = i ? this.children[i - 1] : null; - if (!prev || prev.dom.parentNode == this.contentDOM) break; - } - if (prev && side && enter && !prev.border && !prev.domAtom) return prev.domFromPos(prev.size, side); - return { - node: this.contentDOM, - offset: prev ? domIndex(prev.dom) + 1 : 0 - }; - } else { - let next, enter = true; - for(;; i++, enter = false){ - next = i < this.children.length ? this.children[i] : null; - if (!next || next.dom.parentNode == this.contentDOM) break; - } - if (next && enter && !next.border && !next.domAtom) return next.domFromPos(0, side); - return { - node: this.contentDOM, - offset: next ? domIndex(next.dom) : this.contentDOM.childNodes.length - }; - } - } - // Used to find a DOM range in a single parent for a given changed - // range. - parseRange(from, to) { - let base = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : 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++){ - const child = this.children[i], end = offset + child.size; - if (fromOffset == -1 && from <= end) { - const 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--){ - const 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 && (end > to || i == this.children.length - 1)) { - to = end; - for(let j = i + 1; j < this.children.length; j++){ - const 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; - const child = this.children[side < 0 ? 0 : this.children.length - 1]; - // @ts-expect-error ... - return child.size == 0 || child.emptyChildAt(side); - } - domAfterPos(pos) { - const { node , offset } = this.domFromPos(pos, 0); - if (node.nodeType != 1 || offset == node.childNodes.length) throw new RangeError("No node after pos " + pos); - // @ts-expect-error ... - return node.childNodes[offset]; - } - // 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) { - let force = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : false; - // If the selection falls entirely in a child, give it to that child - const from = Math.min(anchor, head), to = Math.max(anchor, head); - for(let i = 0, offset = 0; i < this.children.length; i++){ - const 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, anchor ? -1 : 1); - let headDOM = head == anchor ? anchorDOM : this.domFromPos(head, head ? -1 : 1); - const domSel = root.getSelection(); - let brKludge = false; - // On Firefox, using Selection.collapse to put the cursor after a - // BR node for some reason doesn't always work (#1073). On Safari, - // the cursor sometimes inexplicable visually lags behind its - // reported position in such situations (#1092). - if ((browser.gecko || browser.safari) && anchor == head) { - const { node , offset } = anchorDOM; - if (node.nodeType == 3) { - brKludge = !!(offset && node.nodeValue?.[offset - 1] == "\n"); - // Issue #1128 - if (brKludge && offset == node.nodeValue.length) { - for(let scan = node, after; scan; scan = scan.parentNode){ - if (after = scan.nextSibling) { - if (after.nodeName == "BR") anchorDOM = headDOM = { - node: after.parentNode, - offset: domIndex(after) + 1 - }; - break; - } - const desc = scan.pmViewDesc; - if (desc && desc.node && desc.node.isBlock) break; - } - } - } else { - const prev = node.childNodes[offset - 1]; - // @ts-expect-error ... - brKludge = prev && (prev.nodeName == "BR" || prev.contentEditable == "false"); - } - } - // Firefox can act strangely when the selection is in front of an - // uneditable node. See #1163 and https://bugzilla.mozilla.org/show_bug.cgi?id=1709536 - if (browser.gecko && domSel.focusNode && domSel.focusNode != headDOM.node && domSel.focusNode.nodeType == 1) { - const after = domSel.focusNode.childNodes[domSel.focusOffset]; - if (after && after.contentEditable == "false") force = true; - } - if (!(force || brKludge && browser.safari) && 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. - let domSelExtended = false; - if ((domSel.extend || anchor == head) && !brKludge) { - domSel.collapse(anchorDOM.node, anchorDOM.offset); - try { - if (anchor != head) domSel.extend(headDOM.node, headDOM.offset); - domSelExtended = true; - } catch (_) { - // In some cases with Chrome the selection is empty after calling - // collapse, even when it should be valid. This appears to be a bug, but - // it is difficult to isolate. If this happens fallback to the old path - // without using extend. - // Similarly, this could crash on Safari if the editor is hidden, and - // there was no selection. - } - } - if (!domSelExtended) { - if (anchor > head) { - const tmp = anchorDOM; - anchorDOM = headDOM; - headDOM = tmp; - } - const range = document.createRange(); - range.setEnd(headDOM.node, headDOM.offset); - range.setStart(anchorDOM.node, anchorDOM.offset); - domSel.removeAllRanges(); - domSel.addRange(range); - } - } - ignoreMutation(mutation) { - return !this.contentDOM && mutation.type != "selection"; - } - 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++){ - const child = this.children[i], end = offset + child.size; - if (offset == end ? from <= end && to >= offset : from < end && to > offset) { - const 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 = child.dom == child.contentDOM && child.dom.parentNode == this.contentDOM && !child.children.length ? CONTENT_DIRTY : NODE_DIRTY; - } - } - offset = end; - } - this.dirty = CONTENT_DIRTY; - } - markParentsDirty() { - let level = 1; - for(let node = this.parent; node; node = node.parent, level++){ - const dirty = level == 1 ? CONTENT_DIRTY : CHILD_DIRTY; - if (node.dirty < dirty) node.dirty = dirty; - } - } - get domAtom() { - return false; - } - get ignoreForCoords() { - return false; - } - constructor(parent, children, dom, contentDOM){ - this.parent = parent; - this.children = children; - this.dom = dom; - this.contentDOM = contentDOM; - this.dirty = NOT_DIRTY; - // An expando property on the DOM node provides a link back to its - // description. - // @ts-expect-error We're using custom view implementations here but - // we match the API so this is relatively safe. - dom.pmViewDesc = this; - } -} -// A widget desc represents a widget decoration, which is a DOM node -// drawn between the document nodes. -export class WidgetViewDesc extends ViewDesc { - matchesWidget(widget) { - return this.dirty == NOT_DIRTY && widget.type.eq(this.widget.type); - } - parseRule() { - return { - ignore: true - }; - } - stopEvent(event) { - const stop = this.widget.spec.stopEvent; - return stop ? stop(event) : false; - } - ignoreMutation(mutation) { - return mutation.type != "selection" || this.widget.spec.ignoreSelection; - } - get domAtom() { - return true; - } - get side() { - return this.widget.type.side; - } - constructor(parent, widget, dom){ - super(parent, [], dom, null); - this.widget = widget; - this.widget = widget; - } -} -export class CompositionViewDesc extends ViewDesc { - 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; - } - constructor(parent, dom, textDOM, text){ - super(parent, [], dom, null); - this.textDOM = textDOM; - this.text = text; - } -} -// 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. -export class MarkViewDesc extends ViewDesc { - parseRule() { - if (this.dirty & NODE_DIRTY || this.mark.type.spec.reparseInView) return null; - 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; - } - } - constructor(parent, children, mark, dom, contentDOM){ - super(parent, children, dom, contentDOM); - this.mark = mark; - } -} -// 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. -export class NodeViewDesc extends ViewDesc { - updateOuterDeco() { - // pass - } - 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 - const rule = { - node: this.node.type.name, - attrs: this.node.attrs - }; - if (this.node.type.whitespace == "pre") rule.preserveWhitespace = "full"; - if (!this.contentDOM) { - rule.getContent = ()=>this.node.content; - } else if (!this.contentLost) { - rule.contentElement = this.contentDOM; - } else { - // Chrome likes to randomly recreate parent nodes when - // backspacing things. When that happens, this tries to find the - // new parent. - for(let i = this.children.length - 1; i >= 0; i--){ - const child = this.children[i]; - // @ts-expect-error ... - if (this.dom.contains(child.dom.parentNode)) { - // @ts-expect-error ... - rule.contentElement = child.dom.parentNode; - break; - } - } - if (!rule.contentElement) rule.getContent = ()=>Fragment.empty; - } - 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; - } - // If this desc must be updated to match the given node decoration, - // do so and return true. - update(_node, _outerDeco, _innerDeco, _view) { - return true; - } - // Mark this node as being the selected node. - selectNode() { - if (this.nodeDOM.nodeType == 1) 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() { - if (this.nodeDOM.nodeType == 1) this.nodeDOM.classList.remove("ProseMirror-selectednode"); - if (this.contentDOM || !this.node.type.spec.draggable) this.dom.removeAttribute("draggable"); - } - get domAtom() { - return this.node.isAtom; - } - constructor(parent, children, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM){ - super(parent, children, dom, contentDOM); - this.node = node; - this.outerDeco = outerDeco; - this.innerDeco = innerDeco; - this.nodeDOM = nodeDOM; - } -} -export class TextViewDesc extends NodeViewDesc { - parseRule() { - let skip = this.nodeDOM.parentNode; - while(skip && skip != this.dom && !skip.pmIsDeco)skip = skip.parentNode; - return { - skip: skip || true - }; - } - update(_node, _outerDeco, _innerDeco, _view) { - return true; - } - inParent() { - const 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"; - } - markDirty(from, to) { - super.markDirty(from, to); - if (this.dom != this.nodeDOM && (from == 0 || to == this.nodeDOM.nodeValue.length)) this.dirty = NODE_DIRTY; - } - get domAtom() { - return false; - } - constructor(parent, children, node, outerDeco, innerDeco, dom, nodeDOM){ - super(parent, children, node, outerDeco, innerDeco, dom, null, nodeDOM); - } -} -// A dummy desc used to tag trailing BR or IMG nodes created to work -// around contentEditable terribleness. -export class TrailingHackViewDesc extends ViewDesc { - parseRule() { - return { - ignore: true - }; - } - matchesHack(nodeName) { - return this.dirty == NOT_DIRTY && this.dom.nodeName == nodeName; - } - get domAtom() { - return true; - } - get ignoreForCoords() { - return this.dom.nodeName == "IMG"; - } -} -function sameOuterDeco(a, b) { - if (a.length != b.length) return false; - // @ts-expect-error ... - for(let i = 0; i < a.length; i++)if (!a[i].type.eq(b[i].type)) return false; - return true; -} diff --git a/dist/tsconfig.tsbuildinfo b/dist/tsconfig.tsbuildinfo deleted file mode 100644 index d704d6c8..00000000 --- a/dist/tsconfig.tsbuildinfo +++ /dev/null @@ -1 +0,0 @@ -{"program":{"fileNames":["../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es5.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2015.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2016.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2017.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2018.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2019.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2020.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2021.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2022.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.dom.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2015.core.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2015.collection.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2015.generator.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2015.iterable.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2015.promise.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2015.proxy.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2015.reflect.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2015.symbol.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2016.array.include.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2017.object.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2017.string.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2017.intl.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2018.intl.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2018.promise.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2018.regexp.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2019.array.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2019.object.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2019.string.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2019.symbol.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2019.intl.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2020.bigint.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2020.date.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2020.promise.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2020.string.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2020.intl.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2020.number.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2021.promise.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2021.string.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2021.weakref.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2021.intl.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2022.array.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2022.error.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2022.intl.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2022.object.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2022.sharedmemory.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.es2022.string.d.ts","../.yarn/cache/typescript-patch-72dc6f164f-ab417a2f39.zip/node_modules/typescript/lib/lib.esnext.intl.d.ts","../src/browser.ts","../src/dom.ts","../.yarn/cache/orderedmap-npm-2.1.0-0135fadc5b-af3f2bd3b7.zip/node_modules/orderedmap/dist/index.d.ts","../.yarn/cache/prosemirror-model-npm-1.19.4-4fd32211c8-12c277ed30.zip/node_modules/prosemirror-model/dist/index.d.ts","../.yarn/cache/prosemirror-transform-npm-1.7.1-5f43149b50-0b8ec0953e.zip/node_modules/prosemirror-transform/dist/index.d.ts","../.yarn/cache/prosemirror-state-npm-1.4.3-d6540e44ad-28857d935c.zip/node_modules/prosemirror-state/dist/index.d.ts","../.yarn/cache/prosemirror-view-npm-1.33.1-0b5671f630-fa7de6e3f2.zip/node_modules/prosemirror-view/dist/index.d.ts","../.yarn/cache/@types-react-npm-18.0.28-c6157151cc-e752df9611.zip/node_modules/@types/react/global.d.ts","../.yarn/cache/csstype-npm-3.1.1-3857baf48b-1f7b4f5fdd.zip/node_modules/csstype/index.d.ts","../.yarn/cache/@types-prop-types-npm-15.7.5-2aa48aa177-5b43b8b154.zip/node_modules/@types/prop-types/index.d.ts","../.yarn/cache/@types-scheduler-npm-0.16.2-ba3a7d8c68-b6b4dcfeae.zip/node_modules/@types/scheduler/tracing.d.ts","../.yarn/cache/@types-react-npm-18.0.28-c6157151cc-e752df9611.zip/node_modules/@types/react/index.d.ts","../.yarn/cache/@types-react-npm-18.0.27-931b59df28-600fdbc39a.zip/node_modules/@types/react/global.d.ts","../.yarn/cache/@types-react-npm-18.0.27-931b59df28-600fdbc39a.zip/node_modules/@types/react/index.d.ts","../.yarn/cache/@types-react-dom-npm-18.0.10-97fe360927-ff8282d500.zip/node_modules/@types/react-dom/index.d.ts","../src/plugins/componentEventListeners.ts","../src/contexts/EditorContext.ts","../src/components/NodeViewComponentProps.tsx","../src/contexts/NodeViewContext.tsx","../src/decorations/computeDocDeco.ts","../.yarn/cache/prosemirror-transform-npm-1.8.0-ea3ca0411f-6d16ca4f95.zip/node_modules/prosemirror-transform/dist/index.d.ts","../src/decorations/internalTypes.ts","../src/decorations/viewDecorations.tsx","../src/contexts/LayoutGroupContext.tsx","../src/hooks/useLayoutGroupEffect.ts","../src/hooks/useEditorEffect.ts","../src/decorations/ReactWidgetType.ts","../src/components/WidgetViewComponentProps.ts","../src/components/CursorWrapper.tsx","../src/plugins/reactKeys.ts","../src/plugins/beforeInputPlugin.ts","../src/selection/hasFocusAndSelection.ts","../src/selection/selectionToDOM.ts","../src/viewdesc.ts","../src/selection/selectionFromDOM.ts","../src/selection/SelectionDOMObserver.ts","../src/hooks/useComponentEventListeners.tsx","../src/hooks/useForceUpdate.ts","../src/hooks/useEditor.ts","../src/hooks/usePendingViewEffects.ts","../src/components/LayoutGroup.tsx","../src/contexts/ChildDescriptorsContext.ts","../src/hooks/useNodeViewDescriptor.ts","../.yarn/cache/classnames-npm-2.3.2-d2fdae468d-2c62199789.zip/node_modules/classnames/index.d.ts","../.yarn/cache/classnames-npm-2.3.2-d2fdae468d-2c62199789.zip/node_modules/classnames/dedupe.d.ts","../src/decorations/iterDeco.ts","../src/hooks/useEditorState.ts","../src/hooks/useReactKeys.ts","../src/components/OutputSpec.tsx","../src/components/MarkView.tsx","../src/components/NativeWidgetView.tsx","../src/components/NodeView.tsx","../src/components/SeparatorHackView.tsx","../src/components/TextNodeView.tsx","../src/components/TrailingHackView.tsx","../src/components/WidgetView.tsx","../src/components/ChildNodeViews.tsx","../src/components/DocNodeView.tsx","../src/components/ProseMirrorDoc.tsx","../src/components/ProseMirror.tsx","../src/hooks/useEditorEventCallback.ts","../src/hooks/useEditorEventListener.ts","../src/index.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/assert.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/assert/strict.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/globals.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/async_hooks.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/buffer.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/child_process.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/cluster.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/console.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/constants.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/crypto.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/dgram.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/diagnostics_channel.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/dns.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/dns/promises.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/domain.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/dom-events.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/events.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/fs.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/fs/promises.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/http.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/http2.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/https.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/inspector.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/module.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/net.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/os.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/path.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/perf_hooks.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/process.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/punycode.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/querystring.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/readline.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/readline/promises.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/repl.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/stream.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/stream/promises.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/stream/consumers.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/stream/web.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/string_decoder.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/test.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/timers.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/timers/promises.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/tls.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/trace_events.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/tty.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/url.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/util.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/v8.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/vm.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/wasi.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/worker_threads.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/zlib.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/globals.global.d.ts","../.yarn/cache/@types-node-npm-18.11.19-dd4a5b3ed6-d7cd19fcfc.zip/node_modules/@types/node/index.d.ts","../.yarn/cache/@types-yargs-parser-npm-21.0.0-c8a3b32c52-b2f4c8d12a.zip/node_modules/@types/yargs-parser/index.d.ts","../.yarn/cache/@types-yargs-npm-17.0.22-35cdb1bdeb-0773523fda.zip/node_modules/@types/yargs/index.d.ts","../.yarn/cache/@types-istanbul-lib-coverage-npm-2.0.4-734954bb56-a25d7589ee.zip/node_modules/@types/istanbul-lib-coverage/index.d.ts","../.yarn/cache/chalk-npm-4.1.2-ba8b67ab80-fe75c9d5c7.zip/node_modules/chalk/index.d.ts","../.yarn/cache/@types-istanbul-lib-report-npm-3.0.0-50de3e6b3b-656398b62d.zip/node_modules/@types/istanbul-lib-report/index.d.ts","../.yarn/cache/@types-istanbul-reports-npm-3.0.1-770e825002-f1ad54bc68.zip/node_modules/@types/istanbul-reports/index.d.ts","../.yarn/cache/@sinclair-typebox-npm-0.27.8-23e206d653-00bd7362a3.zip/node_modules/@sinclair/typebox/typebox.d.ts","../.yarn/cache/@jest-schemas-npm-29.6.0-3ca8b9309f-c00511c69c.zip/node_modules/@jest/schemas/build/index.d.ts","../.yarn/cache/@jest-types-npm-29.6.1-b7c765fadd-89fc1ccf71.zip/node_modules/@jest/types/build/index.d.ts","../.yarn/cache/jest-mock-npm-29.6.2-c31cf48c24-0bacb5d584.zip/node_modules/jest-mock/build/index.d.ts","../.yarn/cache/@types-stack-utils-npm-2.0.1-867718ab70-205fdbe332.zip/node_modules/@types/stack-utils/index.d.ts","../.yarn/cache/jest-message-util-npm-29.6.2-8bd7bc632e-e8e3c8d230.zip/node_modules/jest-message-util/build/index.d.ts","../.yarn/cache/@jest-fake-timers-npm-29.6.2-db388f40be-1abcda02f2.zip/node_modules/@jest/fake-timers/build/index.d.ts","../.yarn/cache/@jest-environment-npm-29.6.2-48e8b9de28-c7de0e4c0d.zip/node_modules/@jest/environment/build/index.d.ts","../.yarn/cache/@jest-expect-utils-npm-29.6.2-bafd0077bb-0decf2009a.zip/node_modules/@jest/expect-utils/build/index.d.ts","../.yarn/cache/pretty-format-npm-29.6.2-7f39471065-a0f972a44f.zip/node_modules/pretty-format/build/index.d.ts","../.yarn/cache/jest-diff-npm-29.6.2-caa9c5f644-0effd66a0c.zip/node_modules/jest-diff/build/index.d.ts","../.yarn/cache/jest-matcher-utils-npm-29.6.2-fd1c69812e-3e1b65dd30.zip/node_modules/jest-matcher-utils/build/index.d.ts","../.yarn/cache/expect-npm-29.6.2-d56284fd66-71f7b0c560.zip/node_modules/expect/build/index.d.ts","../.yarn/cache/jest-snapshot-npm-29.6.2-6ed320289f-c1c70a9dbc.zip/node_modules/jest-snapshot/build/index.d.ts","../.yarn/cache/@jest-expect-npm-29.6.2-7910937388-bd2d88a4e7.zip/node_modules/@jest/expect/build/index.d.ts","../.yarn/cache/@jest-globals-npm-29.6.2-c549594aed-aa4a54f19c.zip/node_modules/@jest/globals/build/index.d.ts","../.yarn/cache/@types-aria-query-npm-5.0.1-5c01a56741-69fd7cceb6.zip/node_modules/@types/aria-query/index.d.ts","../.yarn/cache/@testing-library-dom-npm-9.0.0-d257fd1d0b-5381bf9438.zip/node_modules/@testing-library/dom/types/matches.d.ts","../.yarn/cache/@testing-library-dom-npm-9.0.0-d257fd1d0b-5381bf9438.zip/node_modules/@testing-library/dom/types/wait-for.d.ts","../.yarn/cache/@testing-library-dom-npm-9.0.0-d257fd1d0b-5381bf9438.zip/node_modules/@testing-library/dom/types/query-helpers.d.ts","../.yarn/cache/@testing-library-dom-npm-9.0.0-d257fd1d0b-5381bf9438.zip/node_modules/@testing-library/dom/types/queries.d.ts","../.yarn/cache/@testing-library-dom-npm-9.0.0-d257fd1d0b-5381bf9438.zip/node_modules/@testing-library/dom/types/get-queries-for-element.d.ts","../.yarn/cache/pretty-format-npm-27.5.1-cd7d49696f-cf610cffcb.zip/node_modules/pretty-format/build/types.d.ts","../.yarn/cache/pretty-format-npm-27.5.1-cd7d49696f-cf610cffcb.zip/node_modules/pretty-format/build/index.d.ts","../.yarn/cache/@testing-library-dom-npm-9.0.0-d257fd1d0b-5381bf9438.zip/node_modules/@testing-library/dom/types/screen.d.ts","../.yarn/cache/@testing-library-dom-npm-9.0.0-d257fd1d0b-5381bf9438.zip/node_modules/@testing-library/dom/types/wait-for-element-to-be-removed.d.ts","../.yarn/cache/@testing-library-dom-npm-9.0.0-d257fd1d0b-5381bf9438.zip/node_modules/@testing-library/dom/types/get-node-text.d.ts","../.yarn/cache/@testing-library-dom-npm-9.0.0-d257fd1d0b-5381bf9438.zip/node_modules/@testing-library/dom/types/events.d.ts","../.yarn/cache/@testing-library-dom-npm-9.0.0-d257fd1d0b-5381bf9438.zip/node_modules/@testing-library/dom/types/pretty-dom.d.ts","../.yarn/cache/@testing-library-dom-npm-9.0.0-d257fd1d0b-5381bf9438.zip/node_modules/@testing-library/dom/types/role-helpers.d.ts","../.yarn/cache/@testing-library-dom-npm-9.0.0-d257fd1d0b-5381bf9438.zip/node_modules/@testing-library/dom/types/config.d.ts","../.yarn/cache/@testing-library-dom-npm-9.0.0-d257fd1d0b-5381bf9438.zip/node_modules/@testing-library/dom/types/suggestions.d.ts","../.yarn/cache/@testing-library-dom-npm-9.0.0-d257fd1d0b-5381bf9438.zip/node_modules/@testing-library/dom/types/index.d.ts","../.yarn/cache/@types-react-dom-npm-18.0.10-97fe360927-ff8282d500.zip/node_modules/@types/react-dom/test-utils/index.d.ts","../.yarn/__virtual__/@testing-library-react-virtual-05d79fddcf/0/cache/@testing-library-react-npm-14.1.2-ba3e2cab9a-0269903e53.zip/node_modules/@testing-library/react/types/index.d.ts","../.yarn/cache/prosemirror-test-builder-npm-1.1.1-28df3ba262-48c3425709.zip/node_modules/prosemirror-test-builder/dist/index.d.ts","../src/testing/editorViewTestHelpers.tsx","../src/testing/setupProseMirrorView.ts","../src/components/__tests__/ProseMirror.composition.tsx","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/event/types.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/event/dispatchEvent.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/event/focus.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/event/input.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/click/isClickableInput.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/dataTransfer/Blob.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/dataTransfer/DataTransfer.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/dataTransfer/FileList.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/dataTransfer/Clipboard.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/edit/timeValue.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/edit/isContentEditable.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/edit/isEditable.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/edit/maxLength.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/edit/setFiles.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/focus/cursor.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/focus/getActiveElement.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/focus/getTabDestination.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/focus/isFocusable.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/focus/selection.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/focus/selector.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/keyDef/readNextDescriptor.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/misc/cloneEvent.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/misc/findClosest.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/misc/getDocumentFromNode.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/misc/getTreeDiff.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/misc/getWindow.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/misc/isDescendantOrSelf.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/misc/isElementType.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/misc/isVisible.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/misc/isDisabled.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/misc/level.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/misc/wait.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/pointer/cssPointerEvents.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utils/index.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/document/UI.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/document/getValueOrTextContent.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/document/copySelection.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/document/trackValue.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/document/index.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/event/selection/getInputRange.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/event/selection/modifySelection.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/event/selection/moveSelection.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/event/selection/setSelectionPerMouse.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/event/selection/modifySelectionPerMouse.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/event/selection/selectAll.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/event/selection/setSelectionRange.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/event/selection/setSelection.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/event/selection/updateSelectionOnFocus.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/event/selection/index.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/event/index.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/system/pointer/buttons.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/system/pointer/shared.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/system/pointer/index.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/system/index.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/system/keyboard.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/options.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/convenience/click.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/convenience/hover.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/convenience/tab.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/convenience/index.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/keyboard/index.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/clipboard/copy.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/clipboard/cut.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/clipboard/paste.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/clipboard/index.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/pointer/index.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utility/clear.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utility/selectOptions.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utility/type.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utility/upload.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/utility/index.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/setup/api.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/setup/directApi.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/setup/setup.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/setup/index.d.ts","../.yarn/__virtual__/@testing-library-user-event-virtual-8c45542a23/0/cache/@testing-library-user-event-npm-14.4.3-2d1a75355f-852c48ea6d.zip/node_modules/@testing-library/user-event/dist/types/index.d.ts","../src/components/__tests__/ProseMirror.domchange.test.tsx","../src/components/__tests__/ProseMirror.draw-decoration.test.tsx","../src/components/__tests__/ProseMirror.draw.test.tsx","../src/components/__tests__/ProseMirror.node-view.test.tsx","../src/components/__tests__/ProseMirror.selection.test.tsx","../src/components/__tests__/ProseMirror.test.tsx","../src/contexts/__tests__/DeferredLayoutEffects.test.tsx","../src/hooks/useBeforeInput.ts","../src/hooks/__tests__/useEditorViewLayoutEffect.test.tsx","../src/plugins/componentEventListenersPlugin.ts","../src/plugins/__tests__/reactKeys.test.ts","../.yarn/cache/jest-diff-npm-27.5.1-818e549196-8be27c1e1e.zip/node_modules/jest-diff/build/cleanupSemantic.d.ts","../.yarn/cache/jest-diff-npm-27.5.1-818e549196-8be27c1e1e.zip/node_modules/jest-diff/build/types.d.ts","../.yarn/cache/jest-diff-npm-27.5.1-818e549196-8be27c1e1e.zip/node_modules/jest-diff/build/diffLines.d.ts","../.yarn/cache/jest-diff-npm-27.5.1-818e549196-8be27c1e1e.zip/node_modules/jest-diff/build/printDiffs.d.ts","../.yarn/cache/jest-diff-npm-27.5.1-818e549196-8be27c1e1e.zip/node_modules/jest-diff/build/index.d.ts","../.yarn/cache/jest-matcher-utils-npm-27.5.1-0c47b071fb-bb2135fc48.zip/node_modules/jest-matcher-utils/build/index.d.ts","../.yarn/cache/@types-jest-npm-27.5.2-f8ba570ba6-7e11c6826a.zip/node_modules/@types/jest/index.d.ts"],"fileInfos":[{"version":"8730f4bf322026ff5229336391a18bcaa1f94d4f82416c8b2f3954e2ccaae2ba","affectsGlobalScope":true},"dc47c4fa66b9b9890cf076304de2a9c5201e94b740cffdf09f87296d877d71f6","7a387c58583dfca701b6c85e0adaf43fb17d590fb16d5b2dc0a2fbd89f35c467","8a12173c586e95f4433e0c6dc446bc88346be73ffe9ca6eec7aa63c8f3dca7f9","5f4e733ced4e129482ae2186aae29fde948ab7182844c3a5a51dd346182c7b06","4b421cbfb3a38a27c279dec1e9112c3d1da296f77a1a85ddadf7e7a425d45d18","1fc5ab7a764205c68fa10d381b08417795fc73111d6dd16b5b1ed36badb743d9","746d62152361558ea6d6115cf0da4dd10ede041d14882ede3568bce5dc4b4f1f","d11a03592451da2d1065e09e61f4e2a9bf68f780f4f6623c18b57816a9679d17",{"version":"3aafcb693fe5b5c3bd277bd4c3a617b53db474fe498fc5df067c5603b1eebde7","affectsGlobalScope":true},{"version":"adb996790133eb33b33aadb9c09f15c2c575e71fb57a62de8bf74dbf59ec7dfb","affectsGlobalScope":true},{"version":"8cc8c5a3bac513368b0157f3d8b31cfdcfe78b56d3724f30f80ed9715e404af8","affectsGlobalScope":true},{"version":"cdccba9a388c2ee3fd6ad4018c640a471a6c060e96f1232062223063b0a5ac6a","affectsGlobalScope":true},{"version":"c5c05907c02476e4bde6b7e76a79ffcd948aedd14b6a8f56e4674221b0417398","affectsGlobalScope":true},{"version":"5f406584aef28a331c36523df688ca3650288d14f39c5d2e555c95f0d2ff8f6f","affectsGlobalScope":true},{"version":"22f230e544b35349cfb3bd9110b6ef37b41c6d6c43c3314a31bd0d9652fcec72","affectsGlobalScope":true},{"version":"7ea0b55f6b315cf9ac2ad622b0a7813315bb6e97bf4bb3fbf8f8affbca7dc695","affectsGlobalScope":true},{"version":"3013574108c36fd3aaca79764002b3717da09725a36a6fc02eac386593110f93","affectsGlobalScope":true},{"version":"eb26de841c52236d8222f87e9e6a235332e0788af8c87a71e9e210314300410a","affectsGlobalScope":true},{"version":"3be5a1453daa63e031d266bf342f3943603873d890ab8b9ada95e22389389006","affectsGlobalScope":true},{"version":"17bb1fc99591b00515502d264fa55dc8370c45c5298f4a5c2083557dccba5a2a","affectsGlobalScope":true},{"version":"7ce9f0bde3307ca1f944119f6365f2d776d281a393b576a18a2f2893a2d75c98","affectsGlobalScope":true},{"version":"6a6b173e739a6a99629a8594bfb294cc7329bfb7b227f12e1f7c11bc163b8577","affectsGlobalScope":true},{"version":"81cac4cbc92c0c839c70f8ffb94eb61e2d32dc1c3cf6d95844ca099463cf37ea","affectsGlobalScope":true},{"version":"b0124885ef82641903d232172577f2ceb5d3e60aed4da1153bab4221e1f6dd4e","affectsGlobalScope":true},{"version":"0eb85d6c590b0d577919a79e0084fa1744c1beba6fd0d4e951432fa1ede5510a","affectsGlobalScope":true},{"version":"da233fc1c8a377ba9e0bed690a73c290d843c2c3d23a7bd7ec5cd3d7d73ba1e0","affectsGlobalScope":true},{"version":"d154ea5bb7f7f9001ed9153e876b2d5b8f5c2bb9ec02b3ae0d239ec769f1f2ae","affectsGlobalScope":true},{"version":"bb2d3fb05a1d2ffbca947cc7cbc95d23e1d053d6595391bd325deb265a18d36c","affectsGlobalScope":true},{"version":"c80df75850fea5caa2afe43b9949338ce4e2de086f91713e9af1a06f973872b8","affectsGlobalScope":true},{"version":"9d57b2b5d15838ed094aa9ff1299eecef40b190722eb619bac4616657a05f951","affectsGlobalScope":true},{"version":"6c51b5dd26a2c31dbf37f00cfc32b2aa6a92e19c995aefb5b97a3a64f1ac99de","affectsGlobalScope":true},{"version":"6e7997ef61de3132e4d4b2250e75343f487903ddf5370e7ce33cf1b9db9a63ed","affectsGlobalScope":true},{"version":"2ad234885a4240522efccd77de6c7d99eecf9b4de0914adb9a35c0c22433f993","affectsGlobalScope":true},{"version":"5e5e095c4470c8bab227dbbc61374878ecead104c74ab9960d3adcccfee23205","affectsGlobalScope":true},{"version":"09aa50414b80c023553090e2f53827f007a301bc34b0495bfb2c3c08ab9ad1eb","affectsGlobalScope":true},{"version":"d7f680a43f8cd12a6b6122c07c54ba40952b0c8aa140dcfcf32eb9e6cb028596","affectsGlobalScope":true},{"version":"3787b83e297de7c315d55d4a7c546ae28e5f6c0a361b7a1dcec1f1f50a54ef11","affectsGlobalScope":true},{"version":"e7e8e1d368290e9295ef18ca23f405cf40d5456fa9f20db6373a61ca45f75f40","affectsGlobalScope":true},{"version":"faf0221ae0465363c842ce6aa8a0cbda5d9296940a8e26c86e04cc4081eea21e","affectsGlobalScope":true},{"version":"06393d13ea207a1bfe08ec8d7be562549c5e2da8983f2ee074e00002629d1871","affectsGlobalScope":true},{"version":"2768ef564cfc0689a1b76106c421a2909bdff0acbe87da010785adab80efdd5c","affectsGlobalScope":true},{"version":"b248e32ca52e8f5571390a4142558ae4f203ae2f94d5bac38a3084d529ef4e58","affectsGlobalScope":true},{"version":"6c55633c733c8378db65ac3da7a767c3cf2cf3057f0565a9124a16a3a2019e87","affectsGlobalScope":true},{"version":"fb4416144c1bf0323ccbc9afb0ab289c07312214e8820ad17d709498c865a3fe","affectsGlobalScope":true},{"version":"5b0ca94ec819d68d33da516306c15297acec88efeb0ae9e2b39f71dbd9685ef7","affectsGlobalScope":true},{"version":"34c839eaaa6d78c8674ae2c37af2236dee6831b13db7b4ef4df3ec889a04d4f2","affectsGlobalScope":true},{"version":"34478567f8a80171f88f2f30808beb7da15eac0538ae91282dd33dce928d98ed","affectsGlobalScope":true},{"version":"ab7d58e6161a550ff92e5aff755dc37fe896245348332cd5f1e1203479fe0ed1","affectsGlobalScope":true},{"version":"6bda95ea27a59a276e46043b7065b55bd4b316c25e70e29b572958fa77565d43","affectsGlobalScope":true},{"version":"aedb8de1abb2ff1095c153854a6df7deae4a5709c37297f9d6e9948b6806fa66","affectsGlobalScope":true},{"version":"a4da0551fd39b90ca7ce5f68fb55d4dc0c1396d589b612e1902f68ee090aaada","affectsGlobalScope":true},{"version":"11ffe3c281f375fff9ffdde8bbec7669b4dd671905509079f866f2354a788064","affectsGlobalScope":true},{"version":"52d1bb7ab7a3306fd0375c8bff560feed26ed676a5b0457fa8027b563aecb9a4","affectsGlobalScope":true},{"version":"5b5c3e9bcbdad9256a14bd8f74844449cba0bf947f46f6d829c86e049f0a2052","signature":"aebbc63575486ad034a7c43fae3d5a2668cc3593c8934e0a0d6a9e72d0500be8"},{"version":"875c12342c55d3e2d8d114a730dc860693f52d37cdb891063e083117c95718cf","signature":"2751c3a8dfaaf555fb19127ae178d221bb67bdf93bf36e060e95d52dd7e83698"},"3c616cbdf6f11c71a1cadba225121b0733b1c3da2a4855d7247a22bc64ee28cd","254bfaf148e20ebf242ffb8fbc7e4ba81da35bedc7d5a11c3a3e13011dedec0c","1ef7565ffec4456d8a50e72f1cc254f46f2d35e0f34692f9096b11266fdfc6b9","e29c3246bccba476f4285c89ea0c026b6bfdf9e3d15b6edf2d50e7ea1a59ecfb",{"version":"74e1952ef185ac1a6ffcc70e459e29516f7335c8aee60b389df48acfc1a03c68","affectsGlobalScope":true},{"version":"bbdf156fea2fabed31a569445835aeedcc33643d404fcbaa54541f06c109df3f","affectsGlobalScope":true},"1c29793071152b207c01ea1954e343be9a44d85234447b2b236acae9e709a383","6a386ff939f180ae8ef064699d8b7b6e62bc2731a62d7fbf5e02589383838dea","f5a8b384f182b3851cec3596ccc96cb7464f8d3469f48c74bf2befb782a19de5",{"version":"7fb6faf1006c3503d44e4922c8c65772ddc98e92bad7c2ae2d5db123f3e297b3","affectsGlobalScope":true},{"version":"bbdf156fea2fabed31a569445835aeedcc33643d404fcbaa54541f06c109df3f","affectsGlobalScope":true},{"version":"d11a5d3967290ea6be7e6d7667c4673a7626cfaa32cfc68101000d2b218606ab","affectsGlobalScope":true},"e4dd91dd4789a109aab51d8a0569a282369fcda9ba6f2b2297bc61bacfb1a042",{"version":"e5f37dbfe704025bdb85794d974be2f5826824473845878a44aa1a186a9c8140","signature":"b3dc9f1efc355e2871fad138ba7368337463b23c7f497534beb03056e4af4b32"},{"version":"589a8096ca9f83f64a84b44f556410c3bf3b860688314ed7f3b6578bf624cf97","signature":"f638cae381a2fdb7a19734a6154893d82a64c08e2efd32dc83aa8f16f151bd1f"},{"version":"b24bbf608485bb4c04b4b9edffb24bfeee7744c931a58d6b9dbf6d5fe4518262","signature":"0bafc4c271df58ec70712392e8799a26fe6fcc9a1e7c9168e65bcf1977418782"},{"version":"9ed6c2ec2109c03351224547936c83bf265c6b5c268570f115f1dbe061631ccd","signature":"ad4fec76299a49e89432ab06de31eae7a2e71d62518273efdecb8fc2e968240a"},{"version":"479034984d63c0cbe42f9a0c9f75d9967adfdb613930450c670dba33b152cf3b","signature":"e354b4b57e141553624d30c896c117dec62f27a813d76993635c3600a32535f0"},"b05d32c486bb23840ec5623f9604e7cb1a97be6fe512f33fce8561c20e1c68c0",{"version":"045c5917d10b127444cb1f91c11c2a0ae8a33916bfaf62e3306a7a333d8694c9","signature":"2a7e2e1f34ed32b76012ab46ccb8b667a17be319ff581bab5d626fe05395f650"},{"version":"3dd86ab03f079b926383a4363170f0457b9c6a75f6ae582070c20d58eebed4fb","signature":"557c9c62c3da151cd679df08c102de507abfe578917a5db836d5c7199735f6b8"},{"version":"564398bb53c7c06506768bf88b2ebbb094dd71b90a22cf2fd9700beb7cd9c382","signature":"8dd028de430fa7b2c35b74b5b5c24d43b09542fce7fe4e461b291222cdc46171"},{"version":"dc211fd2cac1df57f0ef95c5ef1f65c48f2414a2cffb707c2e5546dd15640a60","signature":"01c1afb666ad23e839d19d712c451ecd053bee665a96bb352bb78df49884149a"},{"version":"bed57f8624b8a1487d260ec75d619effaa351cf0220aec8115d1bd74b7652f02","signature":"4de268d814cdf44767d1e48058071a2fbe94c2849a4f5746520a8e9eb98fbee5"},{"version":"ba080ea03f9691efdb0eeb58520e619ff0bb292287277e0b7fe338344af50fbd","signature":"4e94f55183fa720ca5616b7d67c84b54d0ee9f712dd9d9520beae30bd97c12fa"},{"version":"7416788f64e783f62bad41412f8c22cbd2caf83a07c9b7f30edb0895b059b1cc","signature":"426a520546de14f483e178f510ef382cd965ed34aaa159fb97d31598854a40d6"},{"version":"6a10615c4f9f1a2f4943223060d4f3c3e593e5147c3214891e6b5c8a821f967f","signature":"7159bd05767be13c4a7ba6d731e98fa282f0c26b9c14ea97c728870e01761b33"},{"version":"3c2c3349de4c7239811a88eb1dce95709432b9ede328a66b1df4c3b48b1c7e8d","signature":"795057e39cf21e76c5e393ca04d6457002c3f6250588682d48c5404b24454c7f"},{"version":"3ae2a60fe90d9be6d138c608f98eeae1ffe94e826686c4c29ec968e80a26492a","signature":"d03764288f8f0f1ab2c1a3673444c1ebb16c4a2cd2870b648ae16b23ba7cc6a3"},{"version":"85ead12d3a84427868cedd8283c7f19a892efc18f52872dd550cc4b59e00c340","signature":"83078aca6f4e00a583d9f1b0f210e77ae151908164b929942ffc2d9877d91622"},{"version":"7cef6dac9be9067ec64ff799e3769d0178a14d994002fe5f7fc8e6f32a733d94","signature":"58528afde29d23c1685bd6695842bd1e3cfa21ec865b0b6eef38967194db928f"},{"version":"46724b2db1163ba796e0e72a28565df1b900bdaee2ad629880f2c9f2e190ce94","signature":"011b0db18cab3e69866bed60486cdc8a240aa0b68f210b0472b207fa51f90e88"},{"version":"edfd03ddc57014be7644aac59083e64bc579ba257aa15e55292e594537f76303","signature":"2143bcca33532154509650778ad1cdd203c7bbde83c3e7672fce28536ed929f4"},{"version":"e5e0aedb6dd23c21874c625230bc69dc95e3c2eef1733308690d5dcc8e1f91d0","signature":"2c75f4e38fbceeda74934cd4eeceaa605744c12cc038cef1c95028ec682f17ef"},{"version":"e05e6536b56eff89dd4abd30daf6c25c4b0aa15a5ac8c641f54b7089091d2f2d","signature":"842cf9d01140ef2336d7de002ac27430b1ec1d3c1c9436779018ef076b29e86f"},{"version":"c5ba4b28a8e337860418ac81e1c1bf18a823f18ee78c5f048717283e9aeb40e0","signature":"d58f6e441744852cafb67094b531599849187ed18fe2afebc31f57d568275caa"},{"version":"777457db60433c45c4fd32262c5f9589989694421f728354d14eed9ff780951c","signature":"d4569fd3e3ee2b64235e61dc713e24065c921fe2cedca9822b5dae56a0e961e6"},{"version":"fed5b3da81fef8392e471937f3ac84a6ad62e35406ebd8452763642f7af16139","signature":"b49a1ad9ac4111ff0aaf3f3abbba05835090cec6a8a049e38b936893d5ab206b"},{"version":"3f343a7dafdc1e0e1d513c0baebc02af8016a408c3ad0a07f7bd045ecba2cc43","signature":"60ddf25ad3e766a1ac14fc6cb1929515e3ba5b2a0b4d8fa3a896d31df1f5e755"},{"version":"e1bfc8e4faa8d7f6c5501f8d570643232bfbdb2c6c056711de0a189a8dfd7732","signature":"e11b0e2ab4531ba8edd675e20dae332c4dac7e32e868941fe8453d12247c3dcc"},{"version":"1668e4a027bfc01a1158cc95a0720682eee2075700f2c9606553b2b98b406180","signature":"4527c20ddc08077f9db1a196cdb3e6a2bc0e217471f622e2fbe5c6b385091cdb"},"2bcb1acd536e696b5e4405ab92e847eb7b7eaa121c8e80c96394c130f141919f","be45d00618d0efc6391bf356981e8e94b455a9e35e82d9d4ee0f965b9910d420",{"version":"417008fe97aadd6ecca73ba7c54b2de4022cdcd8baf64f530086e3c2744186ae","signature":"80a1748b01a95df654272e3068e37836032ed348f16bbdb14cbaafa024431fa4"},{"version":"fd0f514aa7342c707a38590ab2101e7165d5d9175540fd887c3b953bbec65acb","signature":"7ed59af3b693cc826a99ac71c3904e1258ced2624cffe892e7313caf6fafd7a9"},{"version":"031d22b6aec9f83cc24bfd9d65dc24b29882ac8ff295c2de0c76f9cb4b1ebd90","signature":"cdfba960793689c099c32e06a5926d4778b012403128db36ca50a48c39615ad0"},{"version":"a49044d70c0034a114c9cbc796330c2c11d7a257fa86a7c2df1bf525ae94d28b","signature":"7b567f2f4f3b0134a790f8f521647a19399aa3c113c6511be66b7c9f7e09f094"},{"version":"0bbd124fe75ae215b74f05d5a0a665cade3150f964060eb02a08d54f7debe8ac","signature":"a05241106f31258c64db6d467116903af733ed0b3fbbe9f3f900f2c1d114ca59"},{"version":"ca64e5b08442008c6d6c7b7f18a4a6f4974d7c85d68234283289c74ab071bc1f","signature":"50bcd30b434d8e607b081cbef82b94da7924385503a9a7fc71652ac7726ece7e"},{"version":"0bc8eff8b6d08fb3afd2f833dd72daeb032474dfbd24b0deec5710396ba3e0f4","signature":"ff64e67ebf2293ec8981f11e96d0a43e858e252af56751c067b6c57d415a4034"},{"version":"32dad435576841816acd2736c0b29184bf9a8bbe011d1dbdb5aa3ca5d76e4319","signature":"dca41ed24b8d50db3416a1b460ca6e729d961f679439ce15f668066a67146209"},{"version":"116c46ece95f34376fb0c0404552973d84f30c18079de50c529c74825bf29c4d","signature":"ca4a1de15d5fccad587c09b3c3c6bf2d9ea13c26276b2a662264bcd4e8f053ef"},{"version":"75dfe98341e97a40eada7c125be21cee61d3c7540d9d5448c0f074d70615a42b","signature":"edd8eed6d3496ddd14f98d2d3de7ea707dc8f47ef0280e6985faf0331876717b"},{"version":"9fad5384eab9952819ac0e5b39f8e4b3de634cf33a41ecf0ea2d322d02a069cb","signature":"fc8cea23b0d3c4b74c325edbe4844dc09c020e5da9139347b53f58f48a88fb1e"},{"version":"943106f5938226c75094aee9c30aee67fde1fbc2a5ebc306df9bcc699cad4bd0","signature":"53d4343641c62cd9b3c5502102b3f1fdb51d219595da8684a32aef031c97de45"},{"version":"8526c64d7f4157bb28775febbc58958bb0557b9a2f293314763c21564f52b128","signature":"3578dfeeafe0c51cc735be99c07ca3d4d33a11f7183ffc68085b4e3561a050d4"},{"version":"6bdebd367ae09d927e3a090c47656a217569724c1e1a690867e9c0f18c00f673","signature":"035a7c3d6d9a82ee695e8b6b9016162bb0bb107320ff5e6943695ecd045a33b0"},{"version":"fba200c9afe3772cdf68bbaf54d64a3b3f3f24ed4fba7f9490944ffa1d2f1f09","signature":"d833069205801118694c4dc1cae4762053b6a0b511a2d8dbf93da27f711f2336"},{"version":"e300aec8c117f671cb13615312f749d0fb2111a47184134330d48a2da80fc934","signature":"14f179d5d86b3a6f2f14549b260bd8d9542cdb3473c01375addd3d99a444accf"},{"version":"a73fda0175437366ed4b8e2f84a502db5980a8049ec410c3628f16e144797563","signature":"3aa1e62307fdcfd8918596172c7f7b6b532743b6cff15f3c920c0ea84f24e759"},{"version":"f5efb9901e29a148a91303c7b70e2ed3e39ee6ed3cfe122e7b752535814e0d17","signature":"1f056d5b1020b7674c5849dc857dba6f6d70312f6edfd010ee24184456aeac6c"},"7e771891adaa85b690266bc37bd6eb43bc57eecc4b54693ead36467e7369952a","a69c09dbea52352f479d3e7ac949fde3d17b195abe90b045d619f747b38d6d1a",{"version":"ca72190df0eb9b09d4b600821c8c7b6c9747b75a1c700c4d57dc0bb72abc074c","affectsGlobalScope":true},"21a167fec8f933752fb8157f06d28fab6817af3ad9b0bdb1908a10762391eab9",{"version":"bb65c6267c5d6676be61acbf6604cf0a4555ac4b505df58ac15c831fcbff4e3e","affectsGlobalScope":true},"374ca798f244e464346f14301dc2a8b4b111af1a83b49fffef5906c338a1f922","5a94487653355b56018122d92392beb2e5f4a6c63ba5cef83bbe1c99775ef713",{"version":"d5135ad93b33adcce80b18f8065087934cdc1730d63db58562edcf017e1aad9b","affectsGlobalScope":true},"82408ed3e959ddc60d3e9904481b5a8dc16469928257af22a3f7d1a3bc7fd8c4","dab86d9604fe40854ef3c0a6f9e8948873dc3509213418e5e457f410fd11200f","bb9c4ffa5e6290c6980b63c815cdd1625876dadb2efaf77edbe82984be93e55e","489532ff54b714f0e0939947a1c560e516d3ae93d51d639ab02e907a0e950114","f30bb836526d930a74593f7b0f5c1c46d10856415a8f69e5e2fc3db80371e362","14b5aa23c5d0ae1907bc696ac7b6915d88f7d85799cc0dc2dcf98fbce2c5a67c","5c439dafdc09abe4d6c260a96b822fa0ba5be7203c71a63ab1f1423cd9e838ea",{"version":"6b526a5ec4a401ca7c26cfe6a48e641d8f30af76673bad3b06a1b4504594a960","affectsGlobalScope":true},{"version":"816ad2e607a96de5bcac7d437f843f5afd8957f1fa5eefa6bba8e4ed7ca8fd84","affectsGlobalScope":true},"cec36af22f514322f870e81d30675c78df82ae8bf4863f5fd4e4424c040c678d","d903fafe96674bc0b2ac38a5be4a8fc07b14c2548d1cdb165a80ea24c44c0c54","5eec82ac21f84d83586c59a16b9b8502d34505d1393393556682fe7e7fde9ef2","04eb6578a588d6a46f50299b55f30e3a04ef27d0c5a46c57d8fcc211cd530faa","8d3c583a07e0c37e876908c2d5da575019f689df8d9fa4c081d99119d53dba22","2c828a5405191d006115ab34e191b8474bc6c86ffdc401d1a9864b1b6e088a58",{"version":"e630e5528e899219ae319e83bef54bf3bcb91b01d76861ecf881e8e614b167f0","affectsGlobalScope":true},"d076fede3cb042e7b13fc29442aaa03a57806bc51e2b26a67a01fbc66a7c0c12","7c013aa892414a7fdcfd861ae524a668eaa3ede8c7c0acafaf611948122c8d93","b0973c3cbcdc59b37bf477731d468696ecaf442593ec51bab497a613a580fe30",{"version":"4989e92ba5b69b182d2caaea6295af52b7dc73a4f7a2e336a676722884e7139d","affectsGlobalScope":true},{"version":"b3624aed92dab6da8484280d3cb3e2f4130ec3f4ef3f8201c95144ae9e898bb6","affectsGlobalScope":true},"5153a2fd150e46ce57bb3f8db1318d33f6ad3261ed70ceeff92281c0608c74a3","210d54cd652ec0fec8c8916e4af59bb341065576ecda039842f9ffb2e908507c","36b03690b628eab08703d63f04eaa89c5df202e5f1edf3989f13ad389cd2c091","0effadd232a20498b11308058e334d3339cc5bf8c4c858393e38d9d4c0013dcf","25846d43937c672bab7e8195f3d881f93495df712ee901860effc109918938cc","fd93cee2621ff42dabe57b7be402783fd1aa69ece755bcba1e0290547ae60513","1b952304137851e45bc009785de89ada562d9376177c97e37702e39e60c2f1ff","69ee23dd0d215b09907ad30d23f88b7790c93329d1faf31d7835552a10cf7cbf","44b8b584a338b190a59f4f6929d072431950c7bd92ec2694821c11bce180c8a5","23b89798789dffbd437c0c423f5d02d11f9736aea73d6abf16db4f812ff36eda","223c37f62ce09a3d99e77498acdee7b2705a4ae14552fbdb4093600cd9164f3f",{"version":"970a90f76d4d219ad60819d61f5994514087ba94c985647a3474a5a3d12714ed","affectsGlobalScope":true},"e10177274a35a9d07c825615340b2fcde2f610f53f3fb40269fd196b4288dda6","4c8525f256873c7ba3135338c647eaf0ca7115a1a2805ae2d0056629461186ce","3c13ef48634e7b5012fcf7e8fce7496352c2d779a7201389ca96a2a81ee4314d","5d0a25ec910fa36595f85a67ac992d7a53dd4064a1ba6aea1c9f14ab73a023f2",{"version":"f0900cd5d00fe1263ff41201fb8073dbeb984397e4af3b8002a5c207a30bdc33","affectsGlobalScope":true},{"version":"4c50342e1b65d3bee2ed4ab18f84842d5724ad11083bd666d8705dc7a6079d80","affectsGlobalScope":true},"06d7c42d256f0ce6afe1b2b6cfbc97ab391f29dadb00dd0ae8e8f23f5bc916c3","ec4bd1b200670fb567920db572d6701ed42a9641d09c4ff6869768c8f81b404c","e59a892d87e72733e2a9ca21611b9beb52977be2696c7ba4b216cbbb9a48f5aa",{"version":"da26af7362f53d122283bc69fed862b9a9fe27e01bc6a69d1d682e0e5a4df3e6","affectsGlobalScope":true},"8a300fa9b698845a1f9c41ecbe2c5966634582a8e2020d51abcace9b55aa959e",{"version":"ab9b9a36e5284fd8d3bf2f7d5fcbc60052f25f27e4d20954782099282c60d23e","affectsGlobalScope":true},"8dbe725f8d237e70310977afcfa011629804d101ebaa0266cafda6b61ad72236","70e9a18da08294f75bf23e46c7d69e67634c0765d355887b9b41f0d959e1426e","ae84439d1ae42b30ced3df38c4285f35b805be40dfc95b0647d0e59c70b11f97","8b06ac3faeacb8484d84ddb44571d8f410697f98d7bfa86c0fda60373a9f5215","0d14fa22c41fdc7277e6f71473b20ebc07f40f00e38875142335d5b63cdfc9d2","7eb06594824ada538b1d8b48c3925a83e7db792f47a081a62cf3e5c4e23cf0ee","f5638f7c2f12a9a1a57b5c41b3c1ea7db3876c003bab68e6a57afd6bcc169af0","c085e9aa62d1ae1375794c1fb927a445fa105fed891a7e24edbb1c3300f7384a","f315e1e65a1f80992f0509e84e4ae2df15ecd9ef73df975f7c98813b71e4c8da","1b2108ed276861e310da6da15ed86b04c2b353835cda92803cead1b670d25113","70458d8fa8a3d1ceef46333a850f4a14d9c678ab009859c0689ec8892bb572eb","b0d10e46cfe3f6c476b69af02eaa38e4ccc7430221ce3109ae84bb9fb8282298","6fa5d56af71f07dc276aae3f6f30807a9cccf758517fb39742af72e963553d80","819dddfec57391f8458929ca8e4377f030d42107ff6ec431e620b70b0695d530","701bdef1f4a13932f64c4ce89537f2c66301eb46daf30a16a436c991df568686","6c1e688f95fcaf53b1e41c0fdadf2c1cfc96fa924eaf7f9fdb60f96deb0a4986","5b9586e9b0b6322e5bfbd2c29bd3b8e21ab9d871f82346cb71020e3d84bae73e","3e70a7e67c2cb16f8cd49097360c0309fe9d1e3210ff9222e9dac1f8df9d4fb6","ab68d2a3e3e8767c3fba8f80de099a1cfc18c0de79e42cb02ae66e22dfe14a66","6d969939c4a63f70f2aa49e88da6f64b655c8e6799612807bef41ccff6ea0da9","ac5f598a09eed39b957ae3d909b88126f3faf605bd4589c19e9ae85d23ef71e3","92abba98a71c0244a6bcdd3ad4d2e04f1d0a8bcae57d2bb865bf53d1ac86e3d0","d2afa0d86bc6f2e72c1cf2ecb2372bf1b0f002493706a81f2b9a3ee4f944e219","21522c0f405e58c8dd89cd97eb3d1aa9865ba017fde102d01f86ab50b44e5610","3cfb7c0c642b19fb75132154040bb7cd840f0002f9955b14154e69611b9b3f81","8387ec1601cf6b8948672537cf8d430431ba0d87b1f9537b4597c1ab8d3ade5b","d16f1c460b1ca9158e030fdf3641e1de11135e0c7169d3e8cf17cc4cc35d5e64","a46b66cf5b2d0e4323247cbf098671abbcd5e4f9c9781d9202defb49f7f47aaf","e3c5ad476eb2fca8505aee5bdfdf9bf11760df5d0f9545db23f12a5c4d72a718","462bccdf75fcafc1ae8c30400c9425e1a4681db5d605d1a0edb4f990a54d8094","5923d8facbac6ecf7c84739a5c701a57af94a6f6648d6229a6c768cf28f0f8cb","d0570ce419fb38287e7b39c910b468becb5b2278cf33b1000a3d3e82a46ecae2","3aca7f4260dad9dcc0a0333654cb3cde6664d34a553ec06c953bce11151764d7","a0a6f0095f25f08a7129bc4d7cb8438039ec422dc341218d274e1e5131115988","1d2699a343a347a830be26eb17ab340d7875c6f549c8d7477efb1773060cc7e5","45785e608b3d380c79e21957a6d1467e1206ac0281644e43e8ed6498808ace72","a3ce619711ff1bcdaaf4b5187d1e3f84e76064909a7c7ecb2e2f404f145b7b5c","2a90177ebaef25de89351de964c2c601ab54d6e3a157cba60d9cd3eaf5a5ee1a","82200e963d3c767976a5a9f41ecf8c65eca14a6b33dcbe00214fcbe959698c46","b4966c503c08bbd9e834037a8ab60e5f53c5fd1092e8873c4a1c344806acdab2","d1c08287c9c6a9c60c53142c122e9c1909f5a159301b9b06b0eaf12ab547920b","79410b2e5ccc5aef9710303a24d4101159e7b89a6b77dcb694b376b07a6b3b06","18d1bd2540f1feea5c97f9078da29aa96fd080b141272ecce0d091aae3d373e5",{"version":"5ef7906ca4ed8db049674a2af045ceeea567102d0cd59daf4ecbaf106b9c71fd","signature":"587a119393cdd89e38e0db4fe8811c12ef46d7682a76e06f6343d12665ab1537"},{"version":"56b93a1bae0e1acf844c2e1c90b18f1e30d3c19e9b57bba39f7878040a9bdc9b","signature":"2929d8318c9e3e8bcbebddee4bbd55f377d2b18fcb058f51965cb85be0f24b12"},{"version":"853a556e8382d01a9bbee7c6fc4a3e2c16b737dafd72bebf99ec1e053b86f3ed","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},"09f4ee30760c56c05ff1adea3fa2f67646bea56abb842e14e0dd2e0a23b1437e","4a91105167fdddb771b562d76791916987e8527881ed0f6c18c9b8902a2221e8","472c0a98c5de98b8f5206132c941b052f5cc1ae78860cb8712ac4f1ebf4550ca","04bfb659112e31ab13464014fbeac0ff61dc537995076e55a455ba841029f4f7","09a49217179a75e5428bb0da106e52903b5930a100702477cdc5f04095c11a60","a7798e86de8e76844f774f8e0e338149893789cdc08970381f0ae78c86e8667f","4f5247ca2cff5b143a88eed88f6630ada26ad28257592a94c8d0dd5e0afa8609","6b359d3c3138a9f4d3a9c9a8fda24be6fd15bd789e692252b53e68ce99db8edc","0cae2526039b34823b107f91bd9d48cd760ac3ffc994f5060932551b317e2c8c","e156513655462b5811a8f980e32ccd204c19042f8c9756430fe4e8d6f7c1326e","5679b694d138b8c4b3d56c9b1210f903c6b0ca2b5e7f1682a2dd41a6c955f094","b9d55a3efba09a2f59fb4d3b1d4e7532d5bc8e9c4246a50e30fdd63238975c3d","3cb43f44138bac4ee388286aac19c063a0e272d3bc896fbb1f51b2cc80c69f82",{"version":"dd0271250f1e4314e52d7e0da9f3b25a708827f8a43ceff847a2a5e3fd3283e8","affectsGlobalScope":true},{"version":"47971d8a8639a2a2dd684091c6e7660ec5909fed540c4479ca24e22ac237194e","affectsGlobalScope":true},"e1075312b07671ef1cbf46409a0fa2eb2b90bb59c6215c94f0e530113013eeda","1bfd63c3f3749c5dc925bb0c05f229f9a376b8d3f8173d0e01901c08202caf6f","da850b4fdbabdd528f8b9c2784c5ba3b3bedc4e2e1e34dcd08b6407f9ec61a25","e61c918bb5f4a39b795a06e22bc4d44befcefd22f6a5c8a732c9ed0b565a6128","ee56351989b0e6f31fd35c9048e222146ced0aac68c64ce2e034f7c881327d6d","2191c679b65cd74e6d93be90898a803a27ba29c62b55cb6874fff33f2abb82e5","4c805d3d1228c73877e7550afd8b881d89d9bc0c6b73c88940cffcdd2931b1f6","4aa74b4bc57c535815ae004550c59a953c8f8c3c61418ac47a7dcfefba76d1ba","78b17ceb133d95df989a1e073891259b54c968f71f416cd76185308af4f9a185","d76e5d04d111581b97e0aa35de3063022d20d572f22f388d3846a73f6ce0b788","0a53bb48eba6e9f5a56e3b85529fbbe786d96e84871579d10593d4f3ae0f9dba","d34fb8b0a66f0a406c7ce63a36f16dda7ff4500b11b0bd30a491aa0d59336d1f","48e3c30b91aac88fa1c489dc6feb4c22c5eb11c691e62cdd045dd347fb65a796","ed27d5ce258f069acf0036471d1fbb56b4cb3c16d7401b52a51297eca651db62","ec203a515afd88589bf1d384535024f5b90ebe6b5c416fb3dcca0abd428a8ba4","f743541a89bf790b04bd9010d974b369f7423116b4b28615544c315b51086288","9f1bab175e97553d5799e8edd2fb2f0163174ed9cd67169571b939c8cc5cf028",{"version":"cd8605d7bd1c899eada7bbcf87f4fde2587d01a8d983252b13b523e25b948065","affectsGlobalScope":true},"9fd080a9458c6d6f3eb6d4e2b12a3ec498d7d219863e9dca0646bdee9acce875",{"version":"833938e73d1ab6fd923deca6f73914e21175ef00bc11e5582f2597d82802ca41","affectsGlobalScope":true},"9a9ba9f6fd097bb2f57d68da8a39403bbe4dc818b8ccd155a780e4e23fa556f2","e50c4cd1f5cbce3e74c19a5bbf503c460e6ae86597e6d648a98c7f6c90b596dd",{"version":"fa140f881e20591ce163039a7968b54c5e51c11228708b4f9147473d06471cf5","affectsGlobalScope":true},"295eca0c47be1191690fd2fe588195fff9d4dc43852aceb8b4cab2aa634579f0","59ee7346e19b0050508a592702871dc943083c6dcb69a47d52e888115d840781","067712491fb2094c212c733dd8e2d56e74c309a9ce9dac9e919286b7245a1eb4","a5eae58ac55bd30c42359e4b01fb2be5eddac336869d3f04ffb4daa54b58f009","303be068c42b488de65f923b26a5a328cfd7e5301ad8c25a96ff058bad1f6cc7","23969f2674e1b5a0c4bdb30ac0b78bbb30e4dab45ae77cdbdfc7c98c239354ef","dfb274ab0f319cf18ce7152067c25f984c7fd1924fc72b3f66734588444c934a","108c8c05cbc3fbbbd4ff4fc0779c9bef55655c28528eb0f77829795dc9f0b484","a7e5444d24cdec45f113f4fb8a687e1c83a5d30c55d2da19a04be71108ad77bd","41ec17e218b7358fcff25c719bc419fec8ec98f13e561b9a33b07392d4fec24c","ab5317ac205b3b4cab2d3ab69512200f9e1af8c983cb418a852e20093b049d82","25f994b5d76ce6a3186a3319555bbba79706dac2174019915c39ac6080e98c7e","a7efb7d289181f18090a0a14d49c945907098c3d9c0facd2eef73300dd252c00","02c1705fa902f172be6e9020d74bcd92ce5db8d2ef3e1b03aabc2ac8eb46c3db","99d2d8a0c7bb3dd77459552269a7b5865fa912cedab69db686d40d2586b551f7","b47abe58626d76d258472b1d5f76752dd29efe681545f32698db84e7f83517df","5483b1245ca0ea9c385386508f89f572d683ce1866adafdce6a2e8842993112b","7e36cfdb2f02af20cd838f10dd0634aae1b5f5f50696a71ed4465d2442402af5","b8a87ee9f5a9e3fc124d50e8214ce2261027d32085992a6ee675f1bbe55e9cac","1c2ff71e61f524291236dd68108f66d9b9db37558444a216aa896b04b6a69ff4","ca7d57540bf2efe7bec71b265b1db01ec562a216139ca5fd10643e5329f0c933","7b496e53d5f7e1737adcb5610516476ee055bf547918797348f245c68e7418fe","213a4d9aee49a9e4da3b6e86a8dd21aaae651cc03f796609c2e0607f1e6ee242","689f4a13d317d68e9c407a1e5433da90ac93ae25fc398248e79a885661367306","a6a9f1d7fe6241788a342c11123c5ed6ca33ea482d33dba5211f438ffabbf849","2092b687629b317daed8d07e57af169183b7e30b8dcd8aa8d18d7102c326cf63","a48037f7af5f80df8973db5e562e17566407541de284b8dadf1879ea3aed8a2f","0a74fe3b5fd84a6a4b094dce4a1709806f54a31b90e07ee18cbb49a543ef263c","866e98940bef1f2960dd6cfa0015801aff0c0498a0c25040302e53f2a0611fba","4f2e3030f46de35b537a1c5245b83ba771bbfe14c9161c1e33dc3e9854d568f7","4bdc884fa1263192d7076841eb620442b56bf8267aab4f010bfa62f53bd8ea7c","f3d30f6ca231617c59aaa92f166395ea5b4021694326593767c39709ba2733a2","d6577effa37aae713c34363b7cc4c84851cbabe399882c60e2b70bcbb02bfa01","763c431fab07ffd51c008ff15bb89895f5cf16d0abebdf922abd1041dd7b31c0","361f51579349c645038fafb869e52e56c28fa871d87cfa70f4120f3909aecae1","992fc293d360fe3fb532a8d3ca391cb0d30e73ad3dd02b08e59609e25bd186eb","2b2ef76a9f36094b07ee6f76a5ac6903f2f65c0a20283201814a8d1e752cb592","138dbe2a2ca196de7217ca01540f8fbfcee39775ae127c24685a464849136a2b",{"version":"5bfad696c92928f610bbb5f5d9e57e2ce5ee0b169a58480602ceb647467bb70a","signature":"dce35ad1fa5a99fb06bb3a59db37a557de7fcdc833ceeb6eb8a93e1854485a9b"},{"version":"6aa148ce84117d5886d58b3225293bbc0e1c5ea6e9e132d8ef9bde62894b9efb","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"820c1e0be9226e8aa07e8700c28d72c19082589966368fc2e95e8f867939f994","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"bfbf63f4e8b6bc9d3d3cfd188e9d1e8f768c6ffea382f5c68c7db8238205e1c2","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"662c46b746cc4c66bf08e5082550d49ba07b8bd1b79e4babd473815f18a735c6","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"34e6b9146b18ffd50fcd2e4620b9b3934945e2668592ffde45416e83bccd56db","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"f666c963eb9cede06852fc4b098eb35fd96cd1709096bc3fc39deecd887775f7","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"ec5c23c36f9f602ea2523b16dbe61c4425c40554818970646406104cb251892d","signature":"90cba99adb7afed892d37e447664bea8b5f2ef4e90361806e8a4f4b781768c62"},{"version":"bb2fa735bc5200edda3e746a175b74788dad1b770038903a2aafba8e013a89e9","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"61924354678d0dccd7182741324d57859bca9c29f942dcf1fe16fd81d7639329","signature":"d8b6612ffd8100484208679301bd0742c4e34b5a579f28f28cfcbff582c167c0"},{"version":"7e5974860627a3d219b0624952633002bb0601d7984c2b5a6b33fc7a9bc2d7a0","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},"d8aab31ba8e618cc3eea10b0945de81cb93b7e8150a013a482332263b9305322","7adecb2c3238794c378d336a8182d4c3dd2c4fa6fa1785e2797a3db550edea62","dc12dc0e5aa06f4e1a7692149b78f89116af823b9e1f1e4eae140cd3e0e674e6","1bfc6565b90c8771615cd8cfcf9b36efc0275e5e83ac7d9181307e96eb495161","8a8a96898906f065f296665e411f51010b51372fa260d5373bf9f64356703190","7f82ef88bdb67d9a850dd1c7cd2d690f33e0f0acd208e3c9eba086f3670d4f73",{"version":"ccfd8774cd9b929f63ff7dcf657977eb0652e3547f1fcac1b3a1dc5db22d4d58","affectsGlobalScope":true}],"options":{"declaration":true,"emitDeclarationOnly":true,"esModuleInterop":true,"jsx":2,"noFallthroughCasesInSwitch":true,"noImplicitReturns":true,"noUncheckedIndexedAccess":true,"noUnusedLocals":true,"noUnusedParameters":true,"outDir":"./types","rootDir":"../src","skipLibCheck":true,"strict":true,"target":2},"fileIdsList":[[69,164,210,211],[164,291],[164,278,279,280],[164,273,274,275],[164],[164,251,252,253,254],[164,217,291],[164,217,218,219,220,265],[164,255],[164,250,256,257,258,259,260,261,262,263,264],[164,265],[164,269,271,272,291],[164,269,271],[164,266,269,291],[164,276,277,281,282,287],[164,270,272,282,290],[164,289,290],[164,266,270,272,288,289],[164,270,291],[164,268],[164,268,270,291],[164,266,267],[164,283,284,285,286],[164,272,291],[164,227],[164,221,228],[164,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249],[164,247,291],[164,166,171,180,181,184],[164,190,191,214],[164,180,181,183],[164,180,181,185,192],[164,178],[164,171,173,174,175,177,179],[164,198],[164,195,196,197,198,199,202,203,204,205,206,207,208,209],[164,194],[164,201],[164,195,196,197],[164,195,196],[164,198,199,201],[164,196],[164,174],[164,176],[164,201,309],[118,164],[121,164],[122,127,155,164],[123,134,135,142,152,163,164],[123,124,134,142,164],[125,164],[126,127,135,143,164],[127,152,160,164],[128,130,134,142,164],[129,164],[130,131,164],[134,164],[132,134,164],[134,135,136,152,163,164],[134,135,136,149,152,155,164],[164,168],[130,137,142,152,163,164],[134,135,137,138,142,152,160,163,164],[137,139,152,160,163,164],[118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170],[134,140,164],[141,163,164],[130,134,142,152,164],[143,164],[144,164],[121,145,164],[146,162,164,168],[147,164],[148,164],[134,149,150,164],[149,151,164,166],[122,134,152,153,154,155,164],[122,152,154,164],[152,153,164],[155,164],[156,164],[134,158,159,164],[158,159,164],[127,142,152,160,164],[161,164],[142,162,164],[122,137,148,163,164],[127,164],[152,164,165],[164,166],[164,167],[122,127,134,136,145,152,163,164,166,168],[152,164,169],[68,164],[68,164,211],[63,64,65,67,164],[62,63,64,65,164],[164,172],[98,164],[121,164,171,186,189],[164,304,305],[164,304,305,306,307],[164,187],[164,175,308],[164,175,188],[164,180,182],[164,180,187,190,214],[164,200],[164,179],[57,164],[58,59,61,164],[58,164],[58,59,60,164],[58,61,66,71,81,96,99,100,101,102,104,105,106,107,108,109,110,164],[56,66,80,82,164],[58,61,66,88,96,97,111,164],[66,78,92,164],[58,66,88,96,103,164],[61,66,80,88,96,164],[58,60,61,66,69,71,72,73,96,97,101,103,104,111,164],[58,61,66,164],[58,66,164],[61,66,71,72,73,74,77,93,94,95,113,164],[66,96,112,164],[55,66,88,96,164],[58,61,66,69,88,111,164],[66,88,96,164],[66,81,88,96,164],[66,81,164],[60,61,164,193,212,213,214,215],[60,61,75,164,193,212,213,214,215,292],[58,60,61,66,72,80,81,82,164,212,213,214],[58,60,66,72,164,212,213,214],[60,61,66,72,164,212,213,214],[58,60,61,164,212,213,214,215],[164,193,212,213,214,215],[66,88,164],[60,61,66,70,164],[66,164],[66,72,164],[66,79,95,164,212],[56,58,61,66,75,82,164],[61,164],[58,61,75,164],[58,61,76,81,164],[58,61,75,76,164],[60,61,66,71,80,95,164,212],[58,61,66,84,164],[61,66,70,164],[56,58,60,61,66,69,85,88,90,91,92,164],[61,66,71,79,164],[61,66,71,80,164],[60,61,66,70,71,80,164],[60,66,71,164],[66,78,164],[58,61,66,88,96,164],[66,93,164],[84,101,164],[72,80,81,82,84,101,113,114,115,116,164],[58,60,84,164],[58,60,61,81,83,84,164],[60,61,69,164],[58,60,164],[55,56,60,61,86,87,89,164],[56,58,60,61,88,164],[55,56,60,61,88,164],[56,58,60,61,66,80,84,113,114,164,190,193,212,213,214],[55,56,58,61,76,87,164],[58,61,66],[66,81],[58,61,66,88],[66],[58,66],[61],[58,61],[61,66,72,93],[66,112],[81],[66,88],[60,61,66,70],[66,72],[56,58,61,66,75,82],[58,61,75],[60,61,70],[56,60,61,66,70,88],[61,66],[61,70],[60],[93],[58],[72,80,81,82,84,101,113,114,115,116],[60,61],[58,60],[56,61],[58,60,61],[56,58,61,114,190,213,214],[56,58,61]],"referencedMap":[[212,1],[278,2],[279,2],[281,3],[280,2],[273,2],[274,2],[276,4],[275,2],[251,5],[253,5],[252,5],[255,6],[254,5],[218,7],[219,5],[266,8],[220,2],[256,9],[265,10],[257,5],[260,11],[258,5],[261,5],[263,5],[259,11],[262,5],[264,5],[217,5],[292,12],[277,2],[272,13],[282,14],[288,15],[289,16],[291,17],[290,18],[270,13],[271,19],[267,20],[269,21],[268,22],[283,2],[287,23],[284,2],[285,24],[286,2],[221,5],[222,5],[225,5],[223,5],[224,5],[227,5],[228,25],[229,5],[230,5],[226,5],[231,5],[232,5],[233,5],[234,5],[235,26],[236,5],[250,27],[237,5],[238,5],[239,5],[240,5],[241,5],[242,5],[243,5],[246,5],[244,5],[245,5],[247,2],[248,2],[249,28],[185,29],[192,30],[186,5],[184,31],[193,32],[179,33],[180,34],[178,5],[208,5],[205,5],[204,5],[199,35],[210,36],[195,37],[206,38],[198,39],[197,40],[207,5],[202,41],[209,5],[203,42],[196,5],[194,5],[174,5],[176,43],[177,44],[310,45],[118,46],[119,46],[121,47],[122,48],[123,49],[124,50],[125,51],[126,52],[127,53],[128,54],[129,55],[130,56],[131,56],[133,57],[132,58],[134,57],[135,59],[136,60],[120,61],[170,5],[137,62],[138,63],[139,64],[171,65],[140,66],[141,67],[142,68],[143,69],[144,70],[145,71],[146,72],[147,73],[148,74],[149,75],[150,75],[151,76],[152,77],[154,78],[153,79],[155,80],[156,81],[157,5],[158,82],[159,83],[160,84],[161,85],[162,86],[163,87],[164,88],[165,89],[166,90],[167,91],[168,92],[169,93],[64,5],[69,94],[211,95],[67,5],[68,96],[62,5],[66,97],[65,5],[182,5],[173,98],[172,5],[175,5],[99,99],[98,5],[63,5],[190,100],[304,5],[306,101],[308,102],[307,101],[305,38],[188,103],[309,104],[189,105],[183,106],[181,5],[191,107],[57,5],[201,108],[200,5],[187,109],[58,110],[60,111],[213,112],[59,112],[75,112],[61,113],[10,5],[12,5],[11,5],[2,5],[13,5],[14,5],[15,5],[16,5],[17,5],[18,5],[19,5],[20,5],[3,5],[4,5],[24,5],[21,5],[22,5],[23,5],[25,5],[26,5],[27,5],[5,5],[28,5],[29,5],[30,5],[31,5],[6,5],[35,5],[32,5],[33,5],[34,5],[36,5],[7,5],[37,5],[42,5],[43,5],[38,5],[39,5],[40,5],[41,5],[8,5],[47,5],[44,5],[45,5],[46,5],[48,5],[9,5],[49,5],[50,5],[51,5],[52,5],[53,5],[1,5],[54,5],[55,5],[111,114],[83,115],[112,116],[95,117],[104,118],[105,119],[106,120],[72,121],[103,122],[114,123],[113,124],[107,125],[108,126],[109,127],[110,128],[82,129],[216,130],[293,131],[294,132],[295,133],[296,134],[297,135],[298,136],[96,137],[71,138],[78,139],[73,140],[299,141],[81,142],[74,143],[76,144],[100,145],[77,146],[56,5],[301,147],[300,148],[91,149],[93,150],[80,151],[115,152],[116,153],[101,154],[92,139],[79,155],[97,156],[94,157],[102,158],[117,159],[303,160],[85,161],[70,162],[302,162],[84,163],[90,164],[86,143],[89,165],[87,166],[214,167],[215,5],[88,168]],"exportedModulesMap":[[212,1],[278,2],[279,2],[281,3],[280,2],[273,2],[274,2],[276,4],[275,2],[251,5],[253,5],[252,5],[255,6],[254,5],[218,7],[219,5],[266,8],[220,2],[256,9],[265,10],[257,5],[260,11],[258,5],[261,5],[263,5],[259,11],[262,5],[264,5],[217,5],[292,12],[277,2],[272,13],[282,14],[288,15],[289,16],[291,17],[290,18],[270,13],[271,19],[267,20],[269,21],[268,22],[283,2],[287,23],[284,2],[285,24],[286,2],[221,5],[222,5],[225,5],[223,5],[224,5],[227,5],[228,25],[229,5],[230,5],[226,5],[231,5],[232,5],[233,5],[234,5],[235,26],[236,5],[250,27],[237,5],[238,5],[239,5],[240,5],[241,5],[242,5],[243,5],[246,5],[244,5],[245,5],[247,2],[248,2],[249,28],[185,29],[192,30],[186,5],[184,31],[193,32],[179,33],[180,34],[178,5],[208,5],[205,5],[204,5],[199,35],[210,36],[195,37],[206,38],[198,39],[197,40],[207,5],[202,41],[209,5],[203,42],[196,5],[194,5],[174,5],[176,43],[177,44],[310,45],[118,46],[119,46],[121,47],[122,48],[123,49],[124,50],[125,51],[126,52],[127,53],[128,54],[129,55],[130,56],[131,56],[133,57],[132,58],[134,57],[135,59],[136,60],[120,61],[170,5],[137,62],[138,63],[139,64],[171,65],[140,66],[141,67],[142,68],[143,69],[144,70],[145,71],[146,72],[147,73],[148,74],[149,75],[150,75],[151,76],[152,77],[154,78],[153,79],[155,80],[156,81],[157,5],[158,82],[159,83],[160,84],[161,85],[162,86],[163,87],[164,88],[165,89],[166,90],[167,91],[168,92],[169,93],[64,5],[69,94],[211,95],[67,5],[68,96],[62,5],[66,97],[65,5],[182,5],[173,98],[172,5],[175,5],[99,99],[98,5],[63,5],[190,100],[304,5],[306,101],[308,102],[307,101],[305,38],[188,103],[309,104],[189,105],[183,106],[181,5],[191,107],[57,5],[201,108],[200,5],[187,109],[58,110],[60,111],[213,112],[59,112],[75,112],[61,113],[10,5],[12,5],[11,5],[2,5],[13,5],[14,5],[15,5],[16,5],[17,5],[18,5],[19,5],[20,5],[3,5],[4,5],[24,5],[21,5],[22,5],[23,5],[25,5],[26,5],[27,5],[5,5],[28,5],[29,5],[30,5],[31,5],[6,5],[35,5],[32,5],[33,5],[34,5],[36,5],[7,5],[37,5],[42,5],[43,5],[38,5],[39,5],[40,5],[41,5],[8,5],[47,5],[44,5],[45,5],[46,5],[48,5],[9,5],[49,5],[50,5],[51,5],[52,5],[53,5],[1,5],[54,5],[111,169],[83,170],[112,171],[95,172],[104,173],[105,174],[106,175],[72,169],[103,173],[114,176],[113,177],[108,171],[110,178],[82,170],[96,179],[71,180],[78,172],[73,181],[81,182],[74,174],[76,183],[100,175],[77,174],[300,174],[91,184],[93,185],[80,186],[115,174],[116,187],[101,188],[79,172],[97,171],[94,189],[102,190],[117,191],[85,192],[70,192],[302,192],[84,193],[90,194],[86,174],[89,195],[87,192],[214,196],[88,197]],"semanticDiagnosticsPerFile":[212,278,279,281,280,273,274,276,275,251,253,252,255,254,218,219,266,220,256,265,257,260,258,261,263,259,262,264,217,292,277,272,282,288,289,291,290,270,271,267,269,268,283,287,284,285,286,221,222,225,223,224,227,228,229,230,226,231,232,233,234,235,236,250,237,238,239,240,241,242,243,246,244,245,247,248,249,185,192,186,184,193,179,180,178,208,205,204,199,210,195,206,198,197,207,202,209,203,196,194,174,176,177,310,118,119,121,122,123,124,125,126,127,128,129,130,131,133,132,134,135,136,120,170,137,138,139,171,140,141,142,143,144,145,146,147,148,149,150,151,152,154,153,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,64,69,211,67,68,62,66,65,182,173,172,175,99,98,63,190,304,306,308,307,305,188,309,189,183,181,191,57,201,200,187,58,60,213,59,75,61,10,12,11,2,13,14,15,16,17,18,19,20,3,4,24,21,22,23,25,26,27,5,28,29,30,31,6,35,32,33,34,36,7,37,42,43,38,39,40,41,8,47,44,45,46,48,9,49,50,51,52,53,1,54,55,111,83,112,95,104,105,106,72,103,114,113,107,108,109,110,82,216,293,294,295,296,297,298,96,71,78,73,299,81,74,76,100,77,56,301,300,91,93,80,115,116,101,92,79,97,94,102,117,303,85,70,302,84,90,86,89,87,214,215,88]},"version":"4.9.5"} \ No newline at end of file diff --git a/dist/types/browser.d.ts b/dist/types/browser.d.ts deleted file mode 100644 index 75bb3d81..00000000 --- a/dist/types/browser.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -export declare const browser: { - ie: boolean; - ie_version: any; - gecko: boolean; - gecko_version: number | false; - chrome: boolean; - chrome_version: number; - safari: boolean; - ios: boolean; - mac: boolean; - windows: boolean; - android: boolean; - webkit: boolean; - webkit_version: number; -}; diff --git a/dist/types/components/ChildNodeViews.d.ts b/dist/types/components/ChildNodeViews.d.ts deleted file mode 100644 index 447bcd52..00000000 --- a/dist/types/components/ChildNodeViews.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Node } from "prosemirror-model"; -import { Decoration, DecorationSource } from "prosemirror-view"; -import React from "react"; -export declare function wrapInDeco(reactNode: JSX.Element | string, deco: Decoration): React.DetailedReactHTMLElement, HTMLInputElement> | React.FunctionComponentElement; -export declare function ChildNodeViews({ pos, node, innerDecorations, }: { - pos: number; - node: Node | undefined; - innerDecorations: DecorationSource; -}): JSX.Element | null; diff --git a/dist/types/components/CursorWrapper.d.ts b/dist/types/components/CursorWrapper.d.ts deleted file mode 100644 index 12eae4f2..00000000 --- a/dist/types/components/CursorWrapper.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import React from "react"; -export declare const CursorWrapper: React.ForwardRefExoticComponent<{ - widget: import("../decorations/ReactWidgetType.js").ReactWidgetDecoration; - pos: number; -} & React.HTMLAttributes & React.RefAttributes>; diff --git a/dist/types/components/DocNodeView.d.ts b/dist/types/components/DocNodeView.d.ts deleted file mode 100644 index 8bb3e005..00000000 --- a/dist/types/components/DocNodeView.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Node } from "prosemirror-model"; -import { Decoration, DecorationSource } from "prosemirror-view"; -import React, { ReactElement } from "react"; -import { NodeViewDesc } from "../viewdesc.js"; -export type DocNodeViewProps = { - className?: string; - node: Node | undefined; - innerDeco: DecorationSource; - outerDeco: Decoration[]; - as?: ReactElement; - viewDesc?: NodeViewDesc; -}; -export declare const DocNodeView: React.ForwardRefExoticComponent>; diff --git a/dist/types/components/LayoutGroup.d.ts b/dist/types/components/LayoutGroup.d.ts deleted file mode 100644 index 037ac0a3..00000000 --- a/dist/types/components/LayoutGroup.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import React from "react"; -export interface LayoutGroupProps { - children: React.ReactNode; -} -/** - * Provides a boundary for grouping layout effects. - * - * Descendant components can invoke the `useLayoutGroupEffect` hook to register - * effects that run after all descendants within the group have processed their - * regular layout effects. - */ -export declare function LayoutGroup({ children }: LayoutGroupProps): JSX.Element; diff --git a/dist/types/components/MarkView.d.ts b/dist/types/components/MarkView.d.ts deleted file mode 100644 index 45dd04db..00000000 --- a/dist/types/components/MarkView.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Mark } from "prosemirror-model"; -import React, { ReactNode } from "react"; -type Props = { - mark: Mark; - children: ReactNode; -}; -export declare const MarkView: React.ForwardRefExoticComponent>; -export {}; diff --git a/dist/types/components/NativeWidgetView.d.ts b/dist/types/components/NativeWidgetView.d.ts deleted file mode 100644 index dd9c1b1b..00000000 --- a/dist/types/components/NativeWidgetView.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Decoration } from "prosemirror-view"; -type Props = { - widget: Decoration; - pos: number; -}; -export declare function NativeWidgetView({ widget, pos }: Props): JSX.Element; -export {}; diff --git a/dist/types/components/NodeView.d.ts b/dist/types/components/NodeView.d.ts deleted file mode 100644 index bc5acc15..00000000 --- a/dist/types/components/NodeView.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Node } from "prosemirror-model"; -import { Decoration, DecorationSource } from "prosemirror-view"; -type NodeViewProps = { - outerDeco: readonly Decoration[]; - pos: number; - node: Node; - innerDeco: DecorationSource; -}; -export declare function NodeView({ outerDeco, pos, node, innerDeco, ...props }: NodeViewProps): JSX.Element; -export {}; diff --git a/dist/types/components/NodeViewComponentProps.d.ts b/dist/types/components/NodeViewComponentProps.d.ts deleted file mode 100644 index b6701806..00000000 --- a/dist/types/components/NodeViewComponentProps.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Node } from "prosemirror-model"; -import { Decoration, DecorationSource } from "prosemirror-view"; -import { HTMLAttributes, ReactNode } from "react"; -export type NodeViewComponentProps = { - nodeProps: { - decorations: readonly Decoration[]; - innerDecorations: DecorationSource; - node: Node; - children?: ReactNode | ReactNode[]; - isSelected: boolean; - pos: number; - }; -} & HTMLAttributes; diff --git a/dist/types/components/OutputSpec.d.ts b/dist/types/components/OutputSpec.d.ts deleted file mode 100644 index b1f5c829..00000000 --- a/dist/types/components/OutputSpec.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { DOMOutputSpec } from "prosemirror-model"; -import React, { ReactNode } from "react"; -type Props = { - outputSpec: DOMOutputSpec; - children?: ReactNode; -}; -declare const ForwardedOutputSpec: React.ForwardRefExoticComponent>; -export { ForwardedOutputSpec as OutputSpec }; diff --git a/dist/types/components/ProseMirror.d.ts b/dist/types/components/ProseMirror.d.ts deleted file mode 100644 index da65e9c0..00000000 --- a/dist/types/components/ProseMirror.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { NodeViewConstructor } from "prosemirror-view"; -import { ForwardRefExoticComponent, ReactNode, RefAttributes } from "react"; -import { UseEditorOptions } from "../hooks/useEditor.js"; -import { NodeViewComponentProps } from "./NodeViewComponentProps.js"; -export type Props = Omit & { - className?: string; - children?: ReactNode; - nodeViews?: { - [nodeType: string]: ForwardRefExoticComponent>; - }; - customNodeViews?: { - [nodeType: string]: NodeViewConstructor; - }; -}; -export declare function ProseMirror({ className, children, nodeViews, customNodeViews, ...props }: Props): JSX.Element; diff --git a/dist/types/components/ProseMirrorDoc.d.ts b/dist/types/components/ProseMirrorDoc.d.ts deleted file mode 100644 index 81fcf9da..00000000 --- a/dist/types/components/ProseMirrorDoc.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import React, { ReactElement } from "react"; -import { DocNodeViewProps } from "./DocNodeView.js"; -type DocNodeViewContextValue = Omit & { - setMount: (mount: HTMLElement | null) => void; -}; -export declare const DocNodeViewContext: React.Context; -type Props = { - as?: ReactElement; -}; -declare const ForwardedProseMirrorDoc: React.ForwardRefExoticComponent>; -export { ForwardedProseMirrorDoc as ProseMirrorDoc }; diff --git a/dist/types/components/SeparatorHackView.d.ts b/dist/types/components/SeparatorHackView.d.ts deleted file mode 100644 index 083a3849..00000000 --- a/dist/types/components/SeparatorHackView.d.ts +++ /dev/null @@ -1 +0,0 @@ -export declare function SeparatorHackView(): JSX.Element | null; diff --git a/dist/types/components/TextNodeView.d.ts b/dist/types/components/TextNodeView.d.ts deleted file mode 100644 index d73912a5..00000000 --- a/dist/types/components/TextNodeView.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Node } from "prosemirror-model"; -import { Decoration, EditorView } from "prosemirror-view"; -import { Component } from "react"; -import { ViewDesc } from "../viewdesc.js"; -type Props = { - view: EditorView | null; - node: Node; - pos: number; - siblingDescriptors: ViewDesc[]; - decorations: readonly Decoration[]; -}; -export declare class TextNodeView extends Component { - private viewDescRef; - updateEffect(): void; - componentDidMount(): void; - componentDidUpdate(): void; - render(): JSX.Element; -} -export {}; diff --git a/dist/types/components/TrailingHackView.d.ts b/dist/types/components/TrailingHackView.d.ts deleted file mode 100644 index f9988c33..00000000 --- a/dist/types/components/TrailingHackView.d.ts +++ /dev/null @@ -1 +0,0 @@ -export declare function TrailingHackView(): JSX.Element; diff --git a/dist/types/components/WidgetView.d.ts b/dist/types/components/WidgetView.d.ts deleted file mode 100644 index 292d4130..00000000 --- a/dist/types/components/WidgetView.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { ReactWidgetDecoration } from "../decorations/ReactWidgetType.js"; -type Props = { - widget: ReactWidgetDecoration; - pos: number; -}; -export declare function WidgetView({ widget, pos }: Props): JSX.Element; -export {}; diff --git a/dist/types/components/WidgetViewComponentProps.d.ts b/dist/types/components/WidgetViewComponentProps.d.ts deleted file mode 100644 index 25015bed..00000000 --- a/dist/types/components/WidgetViewComponentProps.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { HTMLAttributes } from "react"; -import { ReactWidgetDecoration } from "../decorations/ReactWidgetType.js"; -export type WidgetViewComponentProps = { - widget: ReactWidgetDecoration; - pos: number; -} & HTMLAttributes; diff --git a/dist/types/components/__tests__/ProseMirror.composition.d.ts b/dist/types/components/__tests__/ProseMirror.composition.d.ts deleted file mode 100644 index cb0ff5c3..00000000 --- a/dist/types/components/__tests__/ProseMirror.composition.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/dist/types/components/__tests__/ProseMirror.domchange.test.d.ts b/dist/types/components/__tests__/ProseMirror.domchange.test.d.ts deleted file mode 100644 index 4f951570..00000000 --- a/dist/types/components/__tests__/ProseMirror.domchange.test.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -/** - * @fileoverview - * This file tests that prosemirror-view's DOMObserver works correctly - * in conjunction with React ProseMirror. - * - * @important - * DOMObserver relies on a MutationObserver. The MutationObserver callback - * seems to get queued as a microtask; it will not run until after all - * synchronous code in a test has completed. This is why we manually call - * flush(view) in each test to ensure that the mutation records have been - * flushed. - * - * HOWEVER! If you use an awaited statement after changing the DOM, the - * MutationObserver WILL run. This means that a sequence of DOM changes - * that you want to be staged and detected as a single change may be - * detected and processed in multiple separate phases, which can lead to - * unexpected results. Unsure that you only have synchronous code between - * your first DOM change and your eventual call to flush(view) to avoid this. - */ -export {}; diff --git a/dist/types/components/__tests__/ProseMirror.draw-decoration.test.d.ts b/dist/types/components/__tests__/ProseMirror.draw-decoration.test.d.ts deleted file mode 100644 index cb0ff5c3..00000000 --- a/dist/types/components/__tests__/ProseMirror.draw-decoration.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/dist/types/components/__tests__/ProseMirror.draw.test.d.ts b/dist/types/components/__tests__/ProseMirror.draw.test.d.ts deleted file mode 100644 index cb0ff5c3..00000000 --- a/dist/types/components/__tests__/ProseMirror.draw.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/dist/types/components/__tests__/ProseMirror.node-view.test.d.ts b/dist/types/components/__tests__/ProseMirror.node-view.test.d.ts deleted file mode 100644 index cb0ff5c3..00000000 --- a/dist/types/components/__tests__/ProseMirror.node-view.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/dist/types/components/__tests__/ProseMirror.selection.test.d.ts b/dist/types/components/__tests__/ProseMirror.selection.test.d.ts deleted file mode 100644 index cb0ff5c3..00000000 --- a/dist/types/components/__tests__/ProseMirror.selection.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/dist/types/components/__tests__/ProseMirror.test.d.ts b/dist/types/components/__tests__/ProseMirror.test.d.ts deleted file mode 100644 index cb0ff5c3..00000000 --- a/dist/types/components/__tests__/ProseMirror.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/dist/types/contexts/ChildDescriptorsContext.d.ts b/dist/types/contexts/ChildDescriptorsContext.d.ts deleted file mode 100644 index 7648a081..00000000 --- a/dist/types/contexts/ChildDescriptorsContext.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -/// -import { ViewDesc } from "../viewdesc.js"; -export declare const ChildDescriptorsContext: import("react").Context; diff --git a/dist/types/contexts/EditorContext.d.ts b/dist/types/contexts/EditorContext.d.ts deleted file mode 100644 index 93d9a60d..00000000 --- a/dist/types/contexts/EditorContext.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -/// -import type { EditorState } from "prosemirror-state"; -import type { DOMEventMap, EditorView } from "prosemirror-view"; -import type { EventHandler } from "../plugins/componentEventListeners"; -export interface EditorContextValue { - view: EditorView | null; - state: EditorState; - registerEventListener(eventType: EventType, handler: EventHandler): void; - unregisterEventListener(eventType: EventType, handler: EventHandler): void; -} -/** - * Provides the EditorView, as well as the current - * EditorState. Should not be consumed directly; instead - * see `useEditorState`, `useEditorViewEvent`, and - * `useEditorViewLayoutEffect`. - */ -export declare const EditorContext: import("react").Context; diff --git a/dist/types/contexts/LayoutGroupContext.d.ts b/dist/types/contexts/LayoutGroupContext.d.ts deleted file mode 100644 index f1db05ac..00000000 --- a/dist/types/contexts/LayoutGroupContext.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import type { EffectCallback } from "react"; -export interface LayoutGroupContextValue { - (effect: EffectCallback): ReturnType; -} -export declare const LayoutGroupContext: import("react").Context; diff --git a/dist/types/contexts/NodeViewContext.d.ts b/dist/types/contexts/NodeViewContext.d.ts deleted file mode 100644 index f411d453..00000000 --- a/dist/types/contexts/NodeViewContext.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ForwardRefExoticComponent, RefAttributes } from "react"; -import { NodeViewComponentProps } from "../components/NodeViewComponentProps.js"; -export type NodeViewContextValue = { - nodeViews: Record>>; -}; -export declare const NodeViewContext: import("react").Context; diff --git a/dist/types/contexts/__tests__/DeferredLayoutEffects.test.d.ts b/dist/types/contexts/__tests__/DeferredLayoutEffects.test.d.ts deleted file mode 100644 index cb0ff5c3..00000000 --- a/dist/types/contexts/__tests__/DeferredLayoutEffects.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/dist/types/decorations/ReactWidgetType.d.ts b/dist/types/decorations/ReactWidgetType.d.ts deleted file mode 100644 index 1c220596..00000000 --- a/dist/types/decorations/ReactWidgetType.d.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Mark } from "prosemirror-model"; -import { Mappable } from "prosemirror-transform"; -import { Decoration } from "prosemirror-view"; -import { ForwardRefExoticComponent, RefAttributes } from "react"; -import { WidgetViewComponentProps } from "../components/WidgetViewComponentProps.js"; -import { DOMNode } from "../dom.js"; -export interface DecorationType { - spec: unknown; - map(mapping: Mappable, span: Decoration, offset: number, oldOffset: number): Decoration | null; - valid(node: Node, span: Decoration): boolean; - eq(other: DecorationType): boolean; - destroy(dom: DOMNode): void; -} -export type DecorationWithType = Decoration & { - type: DecorationType; -}; -type ReactWidgetSpec = { - side?: number; - marks?: readonly Mark[]; - stopEvent?: (event: Event) => boolean; - ignoreSelection?: boolean; - key?: string; -}; -export declare class ReactWidgetType implements DecorationType { - Component: ForwardRefExoticComponent & WidgetViewComponentProps>; - side: number; - spec: ReactWidgetSpec; - constructor(Component: ForwardRefExoticComponent & WidgetViewComponentProps>, spec?: ReactWidgetSpec); - map(mapping: Mappable, span: Decoration, offset: number, oldOffset: number): Decoration | null; - valid(): boolean; - eq(other: DecorationType): boolean; - destroy(): void; -} -export declare function widget(pos: number, component: ForwardRefExoticComponent & WidgetViewComponentProps>, spec?: ReactWidgetSpec): Decoration; -export interface ReactWidgetDecoration extends Decoration { - type: ReactWidgetType; - inline: false; -} -export {}; diff --git a/dist/types/decorations/computeDocDeco.d.ts b/dist/types/decorations/computeDocDeco.d.ts deleted file mode 100644 index 4bba20ee..00000000 --- a/dist/types/decorations/computeDocDeco.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { Decoration, EditorView } from "prosemirror-view"; -export declare function computeDocDeco(view: EditorView): Decoration[]; diff --git a/dist/types/decorations/internalTypes.d.ts b/dist/types/decorations/internalTypes.d.ts deleted file mode 100644 index 37b6b8fd..00000000 --- a/dist/types/decorations/internalTypes.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Node } from "prosemirror-model"; -import { Mapping } from "prosemirror-transform"; -import { Decoration, DecorationSource } from "prosemirror-view"; -export interface InternalDecorationSource { - map: (mapping: Mapping, node: Node) => DecorationSource; - locals(node: Node): readonly Decoration[]; - forChild(offset: number, child: Node): DecorationSource; - eq(other: DecorationSource): boolean; -} -export interface InternalDecorationSet extends InternalDecorationSource { - localsInner(node: Node): readonly Decoration[]; -} -export interface InternalDecoration extends Decoration { - copy(from: number, to: number): Decoration; -} diff --git a/dist/types/decorations/iterDeco.d.ts b/dist/types/decorations/iterDeco.d.ts deleted file mode 100644 index 634581d3..00000000 --- a/dist/types/decorations/iterDeco.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Node } from "prosemirror-model"; -import { Decoration, DecorationSource } from "prosemirror-view"; -export declare function iterDeco(parent: Node, deco: DecorationSource, onWidget: (widget: Decoration, isNative: boolean, offset: number, index: number, insideNode: boolean) => void, onNode: (node: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource, offset: number, index: number) => void): void; diff --git a/dist/types/decorations/viewDecorations.d.ts b/dist/types/decorations/viewDecorations.d.ts deleted file mode 100644 index 69cad852..00000000 --- a/dist/types/decorations/viewDecorations.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { Decoration, DecorationSource, EditorView } from "prosemirror-view"; -export declare function viewDecorations(view: EditorView, cursorWrapper: Decoration | null): DecorationSource; diff --git a/dist/types/dom.d.ts b/dist/types/dom.d.ts deleted file mode 100644 index fc905c46..00000000 --- a/dist/types/dom.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -export type DOMNode = InstanceType; -export type DOMSelection = InstanceType; -export type DOMSelectionRange = { - focusNode: DOMNode | null; - focusOffset: number; - anchorNode: DOMNode | null; - anchorOffset: number; -}; -export declare const domIndex: (node: Node) => number; -export declare const parentNode: (node: Node) => Node | null; -export declare const textRange: (node: Text, from?: number, to?: number) => Range; -export declare const isEquivalentPosition: (node: Node, off: number, targetNode: Node, targetOff: number) => boolean; -export declare function nodeSize(node: Node): number; -export declare function isOnEdge(node: Node, offset: number, parent: Node): boolean; -export declare function hasBlockDesc(dom: Node): boolean | null | undefined; -export declare const selectionCollapsed: (domSel: DOMSelectionRange) => boolean | null; -export declare function keyEvent(keyCode: number, key: string): KeyboardEvent; -export declare function deepActiveElement(doc: Document): Element | null; -export declare function caretFromPoint(doc: Document, x: number, y: number): { - node: Node; - offset: number; -} | undefined; diff --git a/dist/types/hooks/__tests__/useEditorViewLayoutEffect.test.d.ts b/dist/types/hooks/__tests__/useEditorViewLayoutEffect.test.d.ts deleted file mode 100644 index cb0ff5c3..00000000 --- a/dist/types/hooks/__tests__/useEditorViewLayoutEffect.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/dist/types/hooks/useBeforeInput.d.ts b/dist/types/hooks/useBeforeInput.d.ts deleted file mode 100644 index d2099314..00000000 --- a/dist/types/hooks/useBeforeInput.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { EditorView } from "prosemirror-view"; -export declare function useBeforeInput(view: EditorView | null): void; diff --git a/dist/types/hooks/useComponentEventListeners.d.ts b/dist/types/hooks/useComponentEventListeners.d.ts deleted file mode 100644 index b84db7e6..00000000 --- a/dist/types/hooks/useComponentEventListeners.d.ts +++ /dev/null @@ -1,33 +0,0 @@ -import type { DOMEventMap } from "prosemirror-view"; -import { EventHandler } from "../plugins/componentEventListeners.js"; -/** - * Produces a plugin that can be used with ProseMirror to handle DOM - * events at the EditorView.dom element. - * - * - `reactEventsPlugin` is a ProseMirror plugin for handling DOM events - * at the EditorView.dom element. It should be passed to `useEditorView`, - * along with any other plugins. - * - * - `registerEventListener` and `unregisterEventListener` should be - * passed to `EditorContext.Provider`. - * - * @privateRemarks - * - * This hook uses a combination of mutable and immutable updates to give - * us precise control over when we re-create the ProseMirror plugin. - * - * The plugin has a mutable reference to the set of handlers for each - * event type, but the set of event types is static. This means that we - * need to produce a new ProseMirror plugin whenever a new event type is - * registered. We avoid producing a new ProseMirrer plugin in any other - * scenario to avoid the performance overhead of reconfiguring the plugins - * in the EditorView. - * - * To accomplish this, we shallowly clone the registry whenever a new event - * type is registered. - */ -export declare function useComponentEventListeners(): { - registerEventListener: (eventType: keyof DOMEventMap, handler: EventHandler) => void; - unregisterEventListener: (eventType: keyof DOMEventMap, handler: EventHandler) => void; - componentEventListenersPlugin: import("prosemirror-state").Plugin; -}; diff --git a/dist/types/hooks/useEditor.d.ts b/dist/types/hooks/useEditor.d.ts deleted file mode 100644 index d85a6bf3..00000000 --- a/dist/types/hooks/useEditor.d.ts +++ /dev/null @@ -1,50 +0,0 @@ -/// -import { EditorState, Plugin, Transaction } from "prosemirror-state"; -import { Decoration, DirectEditorProps, EditorProps, EditorView } from "prosemirror-view"; -import { DOMNode } from "../dom.js"; -import { NodeViewDesc } from "../viewdesc.js"; -export declare class ReactEditorView extends EditorView { - private shouldUpdatePluginViews; - private oldProps; - private _props; - constructor(place: null | DOMNode | ((editor: HTMLElement) => void) | { - mount: HTMLElement; - }, props: DirectEditorProps & { - docView: NodeViewDesc; - }); - /** - * Like setProps, but without executing any side effects. - * Safe to use in a component render method. - */ - pureSetProps(props: Partial): void; - /** - * Triggers any side effects that have been queued by previous - * calls to pureSetProps. - */ - runPendingEffects(): void; - update(props: DirectEditorProps): void; - updatePluginViews(): void; -} -export interface UseEditorOptions extends EditorProps { - defaultState?: EditorState; - state?: EditorState; - plugins?: Plugin[]; - dispatchTransaction?(this: EditorView, tr: Transaction): void; -} -/** - * Creates, mounts, and manages a ProseMirror `EditorView`. - * - * All state and props updates are executed in a layout effect. - * To ensure that the EditorState and EditorView are never out of - * sync, it's important that the EditorView produced by this hook - * is only accessed through the `useEditorViewEvent` and - * `useEditorViewLayoutEffect` hooks. - */ -export declare function useEditor(mount: T | null, options: UseEditorOptions): { - view: EditorView | null; - state: EditorState; - registerEventListener: (eventType: keyof import("prosemirror-view").DOMEventMap, handler: import("../plugins/componentEventListeners.js").EventHandler) => void; - unregisterEventListener: (eventType: keyof import("prosemirror-view").DOMEventMap, handler: import("../plugins/componentEventListeners.js").EventHandler) => void; - cursorWrapper: Decoration | null; - docViewDescRef: import("react").MutableRefObject; -}; diff --git a/dist/types/hooks/useEditorEffect.d.ts b/dist/types/hooks/useEditorEffect.d.ts deleted file mode 100644 index cb025826..00000000 --- a/dist/types/hooks/useEditorEffect.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import type { EditorView } from "prosemirror-view"; -import type { DependencyList } from "react"; -/** - * Registers a layout effect to run after the EditorView has - * been updated with the latest EditorState and Decorations. - * - * Effects can take an EditorView instance as an argument. - * This hook should be used to execute layout effects that - * depend on the EditorView, such as for positioning DOM - * nodes based on ProseMirror positions. - * - * Layout effects registered with this hook still fire - * synchronously after all DOM mutations, but they do so - * _after_ the EditorView has been updated, even when the - * EditorView lives in an ancestor component. - */ -export declare function useEditorEffect(effect: (editorView: EditorView) => void | (() => void), dependencies?: DependencyList): void; diff --git a/dist/types/hooks/useEditorEventCallback.d.ts b/dist/types/hooks/useEditorEventCallback.d.ts deleted file mode 100644 index 8945b5d1..00000000 --- a/dist/types/hooks/useEditorEventCallback.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { EditorView } from "prosemirror-view"; -/** - * Returns a stable function reference to be used as an - * event handler callback. - * - * The callback will be called with the EditorView instance - * as its first argument. - * - * This hook is dependent on both the - * `EditorViewContext.Provider` and the - * `DeferredLayoutEffectProvider`. It can only be used in a - * component that is mounted as a child of both of these - * providers. - */ -export declare function useEditorEventCallback(callback: (view: EditorView, ...args: T) => R): (...args: T) => R | undefined; diff --git a/dist/types/hooks/useEditorEventListener.d.ts b/dist/types/hooks/useEditorEventListener.d.ts deleted file mode 100644 index a98b94f4..00000000 --- a/dist/types/hooks/useEditorEventListener.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { DOMEventMap } from "prosemirror-view"; -import type { EventHandler } from "../plugins/componentEventListeners.js"; -/** - * Attaches an event listener at the `EditorView`'s DOM node. See - * [the ProseMirror docs](https://prosemirror.net/docs/ref/#view.EditorProps.handleDOMEvents) - * for more details. - */ -export declare function useEditorEventListener(eventType: EventType, handler: EventHandler): void; diff --git a/dist/types/hooks/useEditorState.d.ts b/dist/types/hooks/useEditorState.d.ts deleted file mode 100644 index 69586b29..00000000 --- a/dist/types/hooks/useEditorState.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import type { EditorState } from "prosemirror-state"; -/** - * Provides access to the current EditorState value. - */ -export declare function useEditorState(): EditorState | null; diff --git a/dist/types/hooks/useForceUpdate.d.ts b/dist/types/hooks/useForceUpdate.d.ts deleted file mode 100644 index 69fab706..00000000 --- a/dist/types/hooks/useForceUpdate.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -/** - * Provides a function that forces an update of the - * component. - */ -export declare function useForceUpdate(): () => void; diff --git a/dist/types/hooks/useLayoutGroupEffect.d.ts b/dist/types/hooks/useLayoutGroupEffect.d.ts deleted file mode 100644 index 206e21ff..00000000 --- a/dist/types/hooks/useLayoutGroupEffect.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -import type { DependencyList, EffectCallback } from "react"; -/** Registers a layout effect to run at the nearest `LayoutGroup` boundary. */ -export declare function useLayoutGroupEffect(effect: EffectCallback, deps?: DependencyList): void; diff --git a/dist/types/hooks/useNodeViewDescriptor.d.ts b/dist/types/hooks/useNodeViewDescriptor.d.ts deleted file mode 100644 index f341dafb..00000000 --- a/dist/types/hooks/useNodeViewDescriptor.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { Node } from "prosemirror-model"; -import { Decoration, DecorationSource } from "prosemirror-view"; -import { MutableRefObject } from "react"; -import { NodeViewDesc, ViewDesc } from "../viewdesc.js"; -export declare function useNodeViewDescriptor(node: Node | undefined, domRef: undefined | MutableRefObject, nodeDomRef: MutableRefObject, innerDecorations: DecorationSource, outerDecorations: readonly Decoration[], viewDesc?: NodeViewDesc, contentDOMRef?: MutableRefObject): ViewDesc[]; diff --git a/dist/types/hooks/usePendingViewEffects.d.ts b/dist/types/hooks/usePendingViewEffects.d.ts deleted file mode 100644 index e1fc4b79..00000000 --- a/dist/types/hooks/usePendingViewEffects.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { ReactEditorView } from "./useEditor.js"; -export declare function usePendingViewEffects(view: ReactEditorView | null): void; diff --git a/dist/types/hooks/useReactKeys.d.ts b/dist/types/hooks/useReactKeys.d.ts deleted file mode 100644 index 66ad7622..00000000 --- a/dist/types/hooks/useReactKeys.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export declare function useReactKeys(): { - posToKey: Map; - keyToPos: Map; - posToNode: Map; -} | null | undefined; diff --git a/dist/types/index.d.ts b/dist/types/index.d.ts deleted file mode 100644 index 7c669daa..00000000 --- a/dist/types/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export { ProseMirror } from "./components/ProseMirror.js"; -export { ProseMirrorDoc } from "./components/ProseMirrorDoc.js"; -export { useEditorEffect } from "./hooks/useEditorEffect.js"; -export { useEditorEventCallback } from "./hooks/useEditorEventCallback.js"; -export { useEditorEventListener } from "./hooks/useEditorEventListener.js"; -export { useEditorState } from "./hooks/useEditorState.js"; -export { reactKeys } from "./plugins/reactKeys.js"; -export { widget } from "./decorations/ReactWidgetType.js"; -export type { NodeViewComponentProps } from "./components/NodeViewComponentProps.js"; -export type { WidgetViewComponentProps } from "./components/WidgetViewComponentProps.js"; diff --git a/dist/types/plugins/__tests__/reactKeys.test.d.ts b/dist/types/plugins/__tests__/reactKeys.test.d.ts deleted file mode 100644 index cb0ff5c3..00000000 --- a/dist/types/plugins/__tests__/reactKeys.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/dist/types/plugins/beforeInputPlugin.d.ts b/dist/types/plugins/beforeInputPlugin.d.ts deleted file mode 100644 index 9c857085..00000000 --- a/dist/types/plugins/beforeInputPlugin.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Plugin } from "prosemirror-state"; -import { Decoration } from "prosemirror-view"; -export declare function beforeInputPlugin(setCursorWrapper: (deco: Decoration | null) => void): Plugin; diff --git a/dist/types/plugins/componentEventListeners.d.ts b/dist/types/plugins/componentEventListeners.d.ts deleted file mode 100644 index e93b160b..00000000 --- a/dist/types/plugins/componentEventListeners.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { Plugin } from "prosemirror-state"; -import { DOMEventMap, EditorView } from "prosemirror-view"; -export type EventHandler = (this: Plugin, view: EditorView, event: DOMEventMap[EventType]) => boolean | void; -export declare function componentEventListeners(eventHandlerRegistry: Map>): Plugin; diff --git a/dist/types/plugins/componentEventListenersPlugin.d.ts b/dist/types/plugins/componentEventListenersPlugin.d.ts deleted file mode 100644 index 60d8f479..00000000 --- a/dist/types/plugins/componentEventListenersPlugin.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { Plugin } from "prosemirror-state"; -import { DOMEventMap, EditorView } from "prosemirror-view"; -export type EventHandler = (this: Plugin, view: EditorView, event: DOMEventMap[EventType]) => boolean | void; -export declare function createComponentEventListenersPlugin(eventHandlerRegistry: Map>): Plugin; diff --git a/dist/types/plugins/reactKeys.d.ts b/dist/types/plugins/reactKeys.d.ts deleted file mode 100644 index d638f4e7..00000000 --- a/dist/types/plugins/reactKeys.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Node } from "prosemirror-model"; -import { Plugin, PluginKey } from "prosemirror-state"; -export declare function createNodeKey(): string; -export declare const reactKeysPluginKey: PluginKey<{ - posToKey: Map; - keyToPos: Map; - posToNode: Map; -}>; -/** - * Tracks a unique key for each (non-text) node in the - * document, identified by its current position. Keys are - * (mostly) stable across transaction applications. The - * key for a given node can be accessed by that node's - * current position in the document, and vice versa. - */ -export declare function reactKeys(): Plugin<{ - posToKey: Map; - keyToPos: Map; -}>; diff --git a/dist/types/selection/SelectionDOMObserver.d.ts b/dist/types/selection/SelectionDOMObserver.d.ts deleted file mode 100644 index 8d6368ef..00000000 --- a/dist/types/selection/SelectionDOMObserver.d.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { EditorView } from "prosemirror-view"; -import { DOMSelectionRange } from "../dom.js"; -declare class SelectionState { - anchorNode: Node | null; - anchorOffset: number; - focusNode: Node | null; - focusOffset: number; - set(sel: DOMSelectionRange): void; - clear(): void; - eq(sel: DOMSelectionRange): boolean; -} -export declare class SelectionDOMObserver { - readonly view: EditorView; - flushingSoon: number; - currentSelection: SelectionState; - suppressingSelectionUpdates: boolean; - constructor(view: EditorView); - connectSelection(): void; - disconnectSelection(): void; - stop(): void; - start(): void; - suppressSelectionUpdates(): void; - setCurSelection(): void; - ignoreSelectionChange(sel: DOMSelectionRange): true | undefined; - registerMutation(): void; - flushSoon(): void; - updateSelection(): void; - selectionToDOM(): void; - flush(): void; - forceFlush(): void; - onSelectionChange(): void; -} -export {}; diff --git a/dist/types/selection/hasFocusAndSelection.d.ts b/dist/types/selection/hasFocusAndSelection.d.ts deleted file mode 100644 index 025fe0e0..00000000 --- a/dist/types/selection/hasFocusAndSelection.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { EditorView } from "prosemirror-view"; -export declare function hasFocusAndSelection(view: EditorView): boolean; -export declare function hasSelection(view: EditorView): boolean; diff --git a/dist/types/selection/selectionFromDOM.d.ts b/dist/types/selection/selectionFromDOM.d.ts deleted file mode 100644 index 0758b958..00000000 --- a/dist/types/selection/selectionFromDOM.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { ResolvedPos } from "prosemirror-model"; -import { EditorView } from "prosemirror-view"; -export declare function selectionBetween(view: EditorView, $anchor: ResolvedPos, $head: ResolvedPos, bias?: number): import("prosemirror-state").Selection; -export declare function selectionFromDOM(view: EditorView, origin?: string | null): import("prosemirror-state").Selection | null; diff --git a/dist/types/selection/selectionToDOM.d.ts b/dist/types/selection/selectionToDOM.d.ts deleted file mode 100644 index a7e74271..00000000 --- a/dist/types/selection/selectionToDOM.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Selection } from "prosemirror-state"; -import { EditorView } from "prosemirror-view"; -export declare const isEquivalentPosition: (node: Node, off: number, targetNode: Node, targetOff: number) => boolean; -export declare function hasBlockDesc(dom: Node): boolean | null | undefined; -export declare const domIndex: (node: Node) => number; -export declare function nodeSize(node: Node): number; -export declare function syncNodeSelection(view: EditorView, sel: Selection): void; -export declare function hasSelection(view: EditorView): boolean; -export declare function selectionToDOM(view: EditorView, force?: boolean): void; diff --git a/dist/types/testing/editorViewTestHelpers.d.ts b/dist/types/testing/editorViewTestHelpers.d.ts deleted file mode 100644 index 36e4eb0b..00000000 --- a/dist/types/testing/editorViewTestHelpers.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Node } from "prosemirror-model"; -import { doc } from "prosemirror-test-builder"; -import { EditorView as EditorViewT } from "prosemirror-view"; -import { Props } from "../components/ProseMirror.js"; -import { DOMNode } from "../dom.js"; -declare module "expect" { - interface AsymmetricMatchers { - toEqualNode(actual: Node): void; - } - interface Matchers { - toEqualNode(actual: Node): R; - } -} -export declare function tempEditor({ doc: startDoc, selection, plugins, state: stateProp, ...props }: { - doc?: ReturnType; - selection?: Selection; -} & Omit): { - view: EditorViewT; - rerender: (props: Omit) => void; - unmount: () => void; -}; -export declare function findTextNode(node: DOMNode, text: string): Text; diff --git a/dist/types/testing/setupProseMirrorView.d.ts b/dist/types/testing/setupProseMirrorView.d.ts deleted file mode 100644 index 3264b4c4..00000000 --- a/dist/types/testing/setupProseMirrorView.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export declare function setupProseMirrorView(): void; -export declare function teardownProseMirrorView(): void; diff --git a/dist/types/viewdesc.d.ts b/dist/types/viewdesc.d.ts deleted file mode 100644 index f18c1327..00000000 --- a/dist/types/viewdesc.d.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { Mark, Node, ParseRule } from "prosemirror-model"; -import { Decoration, DecorationSource, EditorView } from "prosemirror-view"; -import { DOMNode } from "./dom.js"; -export declare class ViewDesc { - parent: ViewDesc | undefined; - children: ViewDesc[]; - dom: DOMNode; - contentDOM: HTMLElement | null; - dirty: number; - node: Node | null; - constructor(parent: ViewDesc | undefined, children: ViewDesc[], dom: DOMNode, contentDOM: HTMLElement | null); - matchesWidget(_widget: Decoration): boolean; - matchesMark(_mark: Mark): boolean; - matchesNode(_node: Node, _outerDeco: readonly Decoration[], _innerDeco: DecorationSource): boolean; - matchesHack(nodeName: string): boolean; - parseRule(): ParseRule | null; - stopEvent(event: Event): boolean; - get size(): number; - get border(): number; - destroy(): void; - posBeforeChild(child: ViewDesc): number; - get posBefore(): number; - get posAtStart(): number; - get posAfter(): number; - get posAtEnd(): number; - localPosFromDOM(dom: DOMNode, offset: number, bias: number): number; - nearestDesc(dom: DOMNode): ViewDesc | undefined; - nearestDesc(dom: DOMNode, onlyNodes: true): NodeViewDesc | undefined; - getDesc(dom: DOMNode): ViewDesc | undefined; - posFromDOM(dom: DOMNode, offset: number, bias: number): number; - descAt(pos: number): ViewDesc | undefined; - domFromPos(pos: number, side: number): { - node: DOMNode; - offset: number; - atom?: number; - }; - parseRange(from: number, to: number, base?: number): { - node: DOMNode; - from: number; - to: number; - fromOffset: number; - toOffset: number; - }; - emptyChildAt(side: number): boolean; - domAfterPos(pos: number): DOMNode; - setSelection(anchor: number, head: number, root: Document | ShadowRoot, force?: boolean): void; - ignoreMutation(mutation: MutationRecord): boolean; - get contentLost(): boolean | null; - markDirty(from: number, to: number): void; - markParentsDirty(): void; - get domAtom(): boolean; - get ignoreForCoords(): boolean; -} -export declare class WidgetViewDesc extends ViewDesc { - readonly widget: Decoration; - constructor(parent: ViewDesc | undefined, widget: Decoration, dom: DOMNode); - matchesWidget(widget: Decoration): any; - parseRule(): { - ignore: boolean; - }; - stopEvent(event: Event): any; - ignoreMutation(mutation: MutationRecord): any; - get domAtom(): boolean; - get side(): number; -} -export declare class CompositionViewDesc extends ViewDesc { - textDOM: Text; - text: string; - constructor(parent: ViewDesc | undefined, dom: DOMNode, textDOM: Text, text: string); - get size(): number; - localPosFromDOM(dom: DOMNode, offset: number): number; - domFromPos(pos: number): { - node: Text; - offset: number; - }; - ignoreMutation(mut: MutationRecord): boolean; -} -export declare class MarkViewDesc extends ViewDesc { - readonly mark: Mark; - constructor(parent: ViewDesc | undefined, children: ViewDesc[], mark: Mark, dom: DOMNode, contentDOM: HTMLElement); - parseRule(): ParseRule | null; - matchesMark(mark: Mark): boolean; - markDirty(from: number, to: number): void; -} -export declare class NodeViewDesc extends ViewDesc { - node: Node; - outerDeco: readonly Decoration[]; - innerDeco: DecorationSource; - nodeDOM: DOMNode; - constructor(parent: ViewDesc | undefined, children: ViewDesc[], node: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource, dom: DOMNode, contentDOM: HTMLElement | null, nodeDOM: DOMNode); - updateOuterDeco(): void; - parseRule(): ParseRule | null; - matchesNode(node: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource): boolean; - get size(): number; - get border(): 1 | 0; - update(_node: Node, _outerDeco: readonly Decoration[], _innerDeco: DecorationSource, _view: EditorView): boolean; - selectNode(): void; - deselectNode(): void; - get domAtom(): boolean; -} -export declare class TextViewDesc extends NodeViewDesc { - constructor(parent: ViewDesc | undefined, children: ViewDesc[], node: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource, dom: DOMNode, nodeDOM: DOMNode); - parseRule(): ParseRule; - update(_node: Node, _outerDeco: readonly Decoration[], _innerDeco: DecorationSource, _view: EditorView): boolean; - inParent(): boolean; - domFromPos(pos: number): { - node: globalThis.Node; - offset: number; - }; - localPosFromDOM(dom: DOMNode, offset: number, bias: number): number; - ignoreMutation(mutation: MutationRecord): boolean; - markDirty(from: number, to: number): void; - get domAtom(): boolean; -} -export declare class TrailingHackViewDesc extends ViewDesc { - parseRule(): { - ignore: boolean; - }; - matchesHack(nodeName: string): boolean; - get domAtom(): boolean; - get ignoreForCoords(): boolean; -}