@prosekit/core
Advanced tools
Comparing version 0.0.0-next-20240715033214 to 0.0.0-next-20240715045302
@@ -8,3 +8,3 @@ import { | ||
setupEditorExtension | ||
} from "./chunk-YWQGKV6X.js"; | ||
} from "./chunk-UDQXAK7F.js"; | ||
@@ -16,41 +16,78 @@ // src/test/test-editor.ts | ||
var createNodeForTest = (type, attrs, children) => { | ||
let tags = {}, pos = type === type.schema.topNodeType ? 0 : 1, normalizedChildren = []; | ||
for (let child of children) | ||
const tags = {}; | ||
const isTopNode = type === type.schema.topNodeType; | ||
let pos = isTopNode ? 0 : 1; | ||
const normalizedChildren = []; | ||
for (const child of children) { | ||
if (child.tags) { | ||
for (let [key, value] of Object.entries(child.tags)) | ||
for (const [key, value] of Object.entries(child.tags)) { | ||
tags[key] = pos + value; | ||
normalizedChildren.push(child), pos += child.nodeSize; | ||
} | ||
normalizedChildren.push(child); | ||
pos += child.nodeSize; | ||
} else if (child.isText) { | ||
let text = child.text, re = /<(a|b)>/g, i = 0, out = ""; | ||
for (let match of text.matchAll(re)) | ||
out += text.slice(i, match.index), tags[match[1]] = pos + out.length, i = match.index + match[0].length; | ||
out += text.slice(i), out && (normalizedChildren.push(child.type.schema.text(out).mark(child.marks)), pos += out.length); | ||
} else | ||
normalizedChildren.push(child), pos += child.nodeSize; | ||
let node = type.createAndFill( | ||
const text = child.text; | ||
const re = /<(a|b)>/g; | ||
let i = 0; | ||
let out = ""; | ||
for (const match of text.matchAll(re)) { | ||
out += text.slice(i, match.index); | ||
tags[match[1]] = pos + out.length; | ||
i = match.index + match[0].length; | ||
} | ||
out += text.slice(i); | ||
if (out) { | ||
normalizedChildren.push(child.type.schema.text(out).mark(child.marks)); | ||
pos += out.length; | ||
} | ||
} else { | ||
normalizedChildren.push(child); | ||
pos += child.nodeSize; | ||
} | ||
} | ||
const node = type.createAndFill( | ||
attrs, | ||
normalizedChildren | ||
); | ||
return assert(node, `Failed to create node ${type.name}`), node.tags = tags, node; | ||
}, applyMarkForTest = (mark, children) => children.map((node) => { | ||
let newNode = node.mark([mark]); | ||
return newNode.tags = node.tags, newNode; | ||
}); | ||
assert(node, `Failed to create node ${type.name}`); | ||
node.tags = tags; | ||
return node; | ||
}; | ||
var applyMarkForTest = (mark, children) => { | ||
return children.map((node) => { | ||
const newNode = node.mark([mark]); | ||
newNode.tags = node.tags; | ||
return newNode; | ||
}); | ||
}; | ||
// src/test/test-editor.ts | ||
function maybeResolve(doc, pos) { | ||
if (pos != null) | ||
if (pos != null) { | ||
return doc.resolve(pos); | ||
} | ||
return void 0; | ||
} | ||
function getSelection(doc) { | ||
let tags = doc.tags, $a = maybeResolve(doc, tags == null ? void 0 : tags.a), $b = maybeResolve(doc, tags == null ? void 0 : tags.b); | ||
return $a ? $a.parent.inlineContent ? new TextSelection($a, $b) : new NodeSelection($a) : TextSelection.atStart(doc); | ||
const tags = doc.tags; | ||
const $a = maybeResolve(doc, tags == null ? void 0 : tags.a); | ||
const $b = maybeResolve(doc, tags == null ? void 0 : tags.b); | ||
if ($a) { | ||
if ($a.parent.inlineContent) { | ||
return new TextSelection($a, $b); | ||
} else { | ||
return new NodeSelection($a); | ||
} | ||
} | ||
return TextSelection.atStart(doc); | ||
} | ||
var TestEditorInstance = class extends EditorInstance { | ||
constructor(extension) { | ||
super(extension), this.nodeBuilders = createNodeBuilders( | ||
super(extension); | ||
this.nodeBuilders = createNodeBuilders( | ||
this.schema, | ||
this.getState, | ||
createNodeForTest | ||
), this.markBuilders = createMarkBuilders( | ||
); | ||
this.markBuilders = createMarkBuilders( | ||
this.schema, | ||
@@ -61,3 +98,4 @@ this.getState, | ||
} | ||
}, TestEditor = class extends Editor { | ||
}; | ||
var TestEditor = class extends Editor { | ||
constructor(instance) { | ||
@@ -83,7 +121,9 @@ super(instance); | ||
"Document schema does not match editor schema" | ||
), assert( | ||
); | ||
assert( | ||
doc.type === this.schema.topNodeType, | ||
"Document type does not match editor top node type" | ||
); | ||
let selection = getSelection(doc), state = EditorState.create({ | ||
const selection = getSelection(doc); | ||
const state = EditorState.create({ | ||
doc, | ||
@@ -100,3 +140,3 @@ selection, | ||
function createTestEditor(options) { | ||
let extension = setupEditorExtension(options); | ||
const extension = setupEditorExtension(options); | ||
return new TestEditor(new TestEditorInstance(extension)); | ||
@@ -103,0 +143,0 @@ } |
@@ -38,3 +38,3 @@ import { | ||
union | ||
} from "./chunk-YWQGKV6X.js"; | ||
} from "./chunk-UDQXAK7F.js"; | ||
@@ -47,4 +47,10 @@ // src/commands/add-mark.ts | ||
var _a, _b; | ||
let mark = getMarkType(state.schema, options.type).create(options.attrs), from = (_a = options.from) != null ? _a : state.selection.from, to = (_b = options.to) != null ? _b : state.selection.to; | ||
return from > to ? !1 : (dispatch == null || dispatch(state.tr.addMark(from, to, mark)), !0); | ||
const mark = getMarkType(state.schema, options.type).create(options.attrs); | ||
const from = (_a = options.from) != null ? _a : state.selection.from; | ||
const to = (_b = options.to) != null ? _b : state.selection.to; | ||
if (from > to) { | ||
return false; | ||
} | ||
dispatch == null ? void 0 : dispatch(state.tr.addMark(from, to, mark)); | ||
return true; | ||
}; | ||
@@ -57,22 +63,48 @@ } | ||
return (state, dispatch) => { | ||
let markType = getMarkType(state.schema, options.type), predicate = (mark) => mark.type === markType, from = expandMarkBefore(state.selection.$from, predicate), to = expandMarkAfter(state.selection.$to, predicate); | ||
return from === state.selection.from && to === state.selection.to ? !1 : (dispatch && dispatch(state.tr.setSelection(TextSelection.create(state.doc, from, to))), !0); | ||
const markType = getMarkType(state.schema, options.type); | ||
const predicate = (mark) => mark.type === markType; | ||
const from = expandMarkBefore(state.selection.$from, predicate); | ||
const to = expandMarkAfter(state.selection.$to, predicate); | ||
if (from === state.selection.from && to === state.selection.to) { | ||
return false; | ||
} | ||
if (dispatch) { | ||
dispatch(state.tr.setSelection(TextSelection.create(state.doc, from, to))); | ||
} | ||
return true; | ||
}; | ||
} | ||
function expandMarkBefore($pos, predicate) { | ||
let { parent } = $pos; | ||
if (!$pos.marks().some(predicate)) | ||
const { parent } = $pos; | ||
if (!$pos.marks().some(predicate)) { | ||
return $pos.pos; | ||
let index = $pos.index(), boundaryIndex = index; | ||
for (let i = index; i >= 0 && parent.child(i).marks.some(predicate); i--) | ||
boundaryIndex = i; | ||
} | ||
const index = $pos.index(); | ||
let boundaryIndex = index; | ||
for (let i = index; i >= 0; i--) { | ||
const node = parent.child(i); | ||
if (node.marks.some(predicate)) { | ||
boundaryIndex = i; | ||
} else { | ||
break; | ||
} | ||
} | ||
return $pos.posAtIndex(boundaryIndex); | ||
} | ||
function expandMarkAfter($pos, predicate) { | ||
let { parent } = $pos; | ||
if (!$pos.marks().some(predicate)) | ||
const { parent } = $pos; | ||
if (!$pos.marks().some(predicate)) { | ||
return $pos.pos; | ||
let index = Math.max(0, $pos.indexAfter() - 1), childCount = parent.childCount, boundaryIndex = index; | ||
for (let i = index; i < childCount && parent.child(i).marks.some(predicate); i++) | ||
boundaryIndex = i; | ||
} | ||
const index = Math.max(0, $pos.indexAfter() - 1); | ||
const childCount = parent.childCount; | ||
let boundaryIndex = index; | ||
for (let i = index; i < childCount; i++) { | ||
const node = parent.child(i); | ||
if (node.marks.some(predicate)) { | ||
boundaryIndex = i; | ||
} else { | ||
break; | ||
} | ||
} | ||
return $pos.posAtIndex(boundaryIndex) + parent.child(boundaryIndex).nodeSize; | ||
@@ -88,3 +120,5 @@ } | ||
function setSelectionAround(tr, pos) { | ||
let docSize = tr.doc.content.size, $pos = tr.doc.resolve(pos > docSize ? docSize : pos < 0 ? 0 : pos), selection = TextSelection2.between($pos, $pos); | ||
const docSize = tr.doc.content.size; | ||
const $pos = tr.doc.resolve(pos > docSize ? docSize : pos < 0 ? 0 : pos); | ||
const selection = TextSelection2.between($pos, $pos); | ||
tr.setSelection(selection); | ||
@@ -97,5 +131,5 @@ } | ||
var _a; | ||
let node = options.node ? options.node : options.type ? getNodeType(state.schema, options.type).createAndFill(options.attrs) : null; | ||
const node = options.node ? options.node : options.type ? getNodeType(state.schema, options.type).createAndFill(options.attrs) : null; | ||
assert(node, "You must provide either a node or a type"); | ||
let insertPos = insertPoint( | ||
const insertPos = insertPoint( | ||
state.doc, | ||
@@ -105,8 +139,9 @@ (_a = options.pos) != null ? _a : state.selection.anchor, | ||
); | ||
if (insertPos == null) return !1; | ||
if (insertPos == null) return false; | ||
if (dispatch) { | ||
let tr = state.tr.insert(insertPos, node); | ||
setSelectionAround(tr, insertPos + node.nodeSize), dispatch(tr); | ||
const tr = state.tr.insert(insertPos, node); | ||
setSelectionAround(tr, insertPos + node.nodeSize); | ||
dispatch(tr); | ||
} | ||
return !0; | ||
return true; | ||
}; | ||
@@ -121,4 +156,11 @@ } | ||
var _a, _b; | ||
let markType = getMarkType(state.schema, options.type), mark = options.attrs ? markType.create(options.attrs) : markType, from = (_a = options.from) != null ? _a : state.selection.from, to = (_b = options.to) != null ? _b : state.selection.to; | ||
return from > to ? !1 : (dispatch == null || dispatch(state.tr.removeMark(from, to, mark)), !0); | ||
const markType = getMarkType(state.schema, options.type); | ||
const mark = options.attrs ? markType.create(options.attrs) : markType; | ||
const from = (_a = options.from) != null ? _a : state.selection.from; | ||
const to = (_b = options.to) != null ? _b : state.selection.to; | ||
if (from > to) { | ||
return false; | ||
} | ||
dispatch == null ? void 0 : dispatch(state.tr.removeMark(from, to, mark)); | ||
return true; | ||
}; | ||
@@ -129,5 +171,7 @@ } | ||
function findParentNode(nodeType, $pos) { | ||
for (let depth = $pos.depth; depth > 0; depth -= 1) | ||
if ($pos.node(depth).type === nodeType) { | ||
let from = $pos.before(depth), to = $pos.after(depth); | ||
for (let depth = $pos.depth; depth > 0; depth -= 1) { | ||
const node = $pos.node(depth); | ||
if (node.type === nodeType) { | ||
const from = $pos.before(depth); | ||
const to = $pos.after(depth); | ||
return { | ||
@@ -138,2 +182,3 @@ from, | ||
} | ||
} | ||
return { | ||
@@ -148,4 +193,10 @@ from: null, | ||
return (state, dispatch) => { | ||
let nodeType = getNodeType(state.schema, options.type), $pos = typeof options.pos == "number" ? state.doc.resolve(options.pos) : state.selection.$anchor, { from, to } = findParentNode(nodeType, $pos); | ||
return from == null || to == null || from > to ? !1 : (dispatch == null || dispatch(state.tr.delete(from, to)), !0); | ||
const nodeType = getNodeType(state.schema, options.type); | ||
const $pos = typeof options.pos === "number" ? state.doc.resolve(options.pos) : state.selection.$anchor; | ||
const { from, to } = findParentNode(nodeType, $pos); | ||
if (from == null || to == null || from > to) { | ||
return false; | ||
} | ||
dispatch == null ? void 0 : dispatch(state.tr.delete(from, to)); | ||
return true; | ||
}; | ||
@@ -160,5 +211,6 @@ } | ||
function getCustomSelection(state, from, to) { | ||
let pos = from != null ? from : to; | ||
const pos = from != null ? from : to; | ||
if (pos != null) { | ||
let $from = state.doc.resolve(from != null ? from : pos), $to = state.doc.resolve(to != null ? to : pos); | ||
const $from = state.doc.resolve(from != null ? from : pos); | ||
const $to = state.doc.resolve(to != null ? to : pos); | ||
return TextSelection3.between($from, $to); | ||
@@ -172,5 +224,8 @@ } | ||
return (state, dispatch) => { | ||
let nodeType = getNodeType(state.schema, options.type), selection = getCustomSelection(state, options.from, options.to), attrs = options.attrs, applicable = !1; | ||
const nodeType = getNodeType(state.schema, options.type); | ||
const selection = getCustomSelection(state, options.from, options.to); | ||
const attrs = options.attrs; | ||
let applicable = false; | ||
for (let i = 0; i < selection.ranges.length && !applicable; i++) { | ||
let { | ||
const { | ||
$from: { pos: from }, | ||
@@ -180,17 +235,17 @@ $to: { pos: to } | ||
state.doc.nodesBetween(from, to, (node, pos) => { | ||
if (applicable) return !1; | ||
if (!(!node.isTextblock || node.hasMarkup(nodeType, attrs))) | ||
if (node.type == nodeType) | ||
applicable = !0; | ||
else { | ||
let $pos = state.doc.resolve(pos), index = $pos.index(); | ||
applicable = $pos.parent.canReplaceWith(index, index + 1, nodeType); | ||
} | ||
if (applicable) return false; | ||
if (!node.isTextblock || node.hasMarkup(nodeType, attrs)) return; | ||
if (node.type == nodeType) { | ||
applicable = true; | ||
} else { | ||
const $pos = state.doc.resolve(pos), index = $pos.index(); | ||
applicable = $pos.parent.canReplaceWith(index, index + 1, nodeType); | ||
} | ||
}); | ||
} | ||
if (!applicable) return !1; | ||
if (!applicable) return false; | ||
if (dispatch) { | ||
let tr = state.tr; | ||
for (let range of selection.ranges) { | ||
let { | ||
const tr = state.tr; | ||
for (const range of selection.ranges) { | ||
const { | ||
$from: { pos: from }, | ||
@@ -203,3 +258,3 @@ $to: { pos: to } | ||
} | ||
return !0; | ||
return true; | ||
}; | ||
@@ -211,3 +266,6 @@ } | ||
function getNodeTypes(schema, types) { | ||
return Array.isArray(types) ? types.map((type) => getNodeType(schema, type)) : [getNodeType(schema, types)]; | ||
if (Array.isArray(types)) { | ||
return types.map((type) => getNodeType(schema, type)); | ||
} | ||
return [getNodeType(schema, types)]; | ||
} | ||
@@ -219,16 +277,27 @@ | ||
var _a, _b; | ||
let nodeTypes = getNodeTypes(state.schema, options.type), from = (_a = options.pos) != null ? _a : state.selection.from, to = (_b = options.pos) != null ? _b : state.selection.to, positions = []; | ||
if (state.doc.nodesBetween(from, to, (node, pos) => { | ||
if (nodeTypes.includes(node.type) && positions.push(pos), !dispatch && positions.length > 0) | ||
return !1; | ||
}), positions.length === 0) | ||
return !1; | ||
const nodeTypes = getNodeTypes(state.schema, options.type); | ||
const from = (_a = options.pos) != null ? _a : state.selection.from; | ||
const to = (_b = options.pos) != null ? _b : state.selection.to; | ||
const positions = []; | ||
state.doc.nodesBetween(from, to, (node, pos) => { | ||
if (nodeTypes.includes(node.type)) { | ||
positions.push(pos); | ||
} | ||
if (!dispatch && positions.length > 0) { | ||
return false; | ||
} | ||
}); | ||
if (positions.length === 0) { | ||
return false; | ||
} | ||
if (dispatch) { | ||
let { tr } = state; | ||
for (let pos of positions) | ||
for (let [key, value] of Object.entries(options.attrs)) | ||
const { tr } = state; | ||
for (const pos of positions) { | ||
for (const [key, value] of Object.entries(options.attrs)) { | ||
tr.setNodeAttribute(pos, key, value); | ||
} | ||
} | ||
dispatch(tr); | ||
} | ||
return !0; | ||
return true; | ||
}; | ||
@@ -241,52 +310,72 @@ } | ||
function markApplies(doc, ranges, type) { | ||
for (let { $from, $to } of ranges) { | ||
let can = $from.depth == 0 ? doc.inlineContent && doc.type.allowsMarkType(type) : !1; | ||
if (doc.nodesBetween($from.pos, $to.pos, (node) => { | ||
if (can) return !1; | ||
for (const { $from, $to } of ranges) { | ||
let can = $from.depth == 0 ? doc.inlineContent && doc.type.allowsMarkType(type) : false; | ||
doc.nodesBetween($from.pos, $to.pos, (node) => { | ||
if (can) return false; | ||
can = node.inlineContent && node.type.allowsMarkType(type); | ||
}), can) return !0; | ||
}); | ||
if (can) return true; | ||
} | ||
return !1; | ||
return false; | ||
} | ||
function baseToggleMark(markType, attrs = null, options) { | ||
let removeWhenPresent = (options && options.removeWhenPresent) !== !1; | ||
const removeWhenPresent = (options && options.removeWhenPresent) !== false; | ||
return function(state, dispatch) { | ||
let { empty, $cursor, ranges } = state.selection; | ||
const { empty, $cursor, ranges } = state.selection; | ||
if (empty && !$cursor || !markApplies(state.doc, ranges, markType)) | ||
return !1; | ||
if (dispatch) | ||
if ($cursor) | ||
markType.isInSet(state.storedMarks || $cursor.marks()) ? dispatch(state.tr.removeStoredMark(markType)) : dispatch(state.tr.addStoredMark(markType.create(attrs))); | ||
else { | ||
let add, tr = state.tr; | ||
removeWhenPresent ? add = !ranges.some( | ||
(r) => state.doc.rangeHasMark(r.$from.pos, r.$to.pos, markType) | ||
) : add = !ranges.every((r) => { | ||
let missing = !1; | ||
return tr.doc.nodesBetween(r.$from.pos, r.$to.pos, (node, pos, parent) => { | ||
if (missing) return !1; | ||
missing = !markType.isInSet(node.marks) && !!parent && parent.type.allowsMarkType(markType) && !(node.isText && /^\s*$/.test( | ||
node.textBetween( | ||
Math.max(0, r.$from.pos - pos), | ||
Math.min(node.nodeSize, r.$to.pos - pos) | ||
) | ||
)); | ||
}), !missing; | ||
}); | ||
for (let { $from, $to } of ranges) | ||
if (!add) | ||
return false; | ||
if (dispatch) { | ||
if ($cursor) { | ||
if (markType.isInSet(state.storedMarks || $cursor.marks())) | ||
dispatch(state.tr.removeStoredMark(markType)); | ||
else dispatch(state.tr.addStoredMark(markType.create(attrs))); | ||
} else { | ||
let add; | ||
const tr = state.tr; | ||
if (removeWhenPresent) { | ||
add = !ranges.some( | ||
(r) => state.doc.rangeHasMark(r.$from.pos, r.$to.pos, markType) | ||
); | ||
} else { | ||
add = !ranges.every((r) => { | ||
let missing = false; | ||
tr.doc.nodesBetween(r.$from.pos, r.$to.pos, (node, pos, parent) => { | ||
if (missing) return false; | ||
missing = !markType.isInSet(node.marks) && !!parent && parent.type.allowsMarkType(markType) && !(node.isText && /^\s*$/.test( | ||
node.textBetween( | ||
Math.max(0, r.$from.pos - pos), | ||
Math.min(node.nodeSize, r.$to.pos - pos) | ||
) | ||
)); | ||
}); | ||
return !missing; | ||
}); | ||
} | ||
for (const { $from, $to } of ranges) { | ||
if (!add) { | ||
tr.removeMark($from.pos, $to.pos, markType); | ||
else { | ||
let from = $from.pos, to = $to.pos, start = $from.nodeAfter, end = $to.nodeBefore, spaceStart = start && start.isText ? /^\s*/.exec(start.text)[0].length : 0, spaceEnd = end && end.isText ? /\s*$/.exec(end.text)[0].length : 0; | ||
from + spaceStart < to && (from += spaceStart, to -= spaceEnd), tr.addMark(from, to, markType.create(attrs)); | ||
} else { | ||
let from = $from.pos, to = $to.pos; | ||
const start = $from.nodeAfter, end = $to.nodeBefore; | ||
const spaceStart = start && start.isText ? /^\s*/.exec(start.text)[0].length : 0; | ||
const spaceEnd = end && end.isText ? /\s*$/.exec(end.text)[0].length : 0; | ||
if (from + spaceStart < to) { | ||
from += spaceStart; | ||
to -= spaceEnd; | ||
} | ||
tr.addMark(from, to, markType.create(attrs)); | ||
} | ||
} | ||
dispatch(tr.scrollIntoView()); | ||
} | ||
return !0; | ||
} | ||
return true; | ||
}; | ||
} | ||
function toggleMark({ type, attrs }) { | ||
return (state, dispatch, view) => baseToggleMark(getMarkType(state.schema, type), attrs, { | ||
removeWhenPresent: !1 | ||
})(state, dispatch, view); | ||
return (state, dispatch, view) => { | ||
return baseToggleMark(getMarkType(state.schema, type), attrs, { | ||
removeWhenPresent: false | ||
})(state, dispatch, view); | ||
}; | ||
} | ||
@@ -301,6 +390,9 @@ | ||
if (isNodeActive(state, type, attrs)) { | ||
let defaultType = state.schema.topNodeType.contentMatch.defaultType; | ||
return defaultType ? setBlockType2(defaultType)(state, dispatch, view) : !1; | ||
const defaultType = state.schema.topNodeType.contentMatch.defaultType; | ||
if (!defaultType) { | ||
return false; | ||
} | ||
return setBlockType2(defaultType)(state, dispatch, view); | ||
} else { | ||
let nodeType = getNodeType(state.schema, type); | ||
const nodeType = getNodeType(state.schema, type); | ||
return setBlockType2(nodeType, attrs)(state, dispatch, view); | ||
@@ -318,15 +410,23 @@ } | ||
var _a, _b; | ||
let from = (_a = options == null ? void 0 : options.from) != null ? _a : state.selection.from, to = (_b = options == null ? void 0 : options.to) != null ? _b : state.selection.to; | ||
if (from > to) return !1; | ||
let tr = state.tr; | ||
return unsetTextBlockType(tr, from, to) ? (dispatch == null || dispatch(tr), !0) : !1; | ||
const from = (_a = options == null ? void 0 : options.from) != null ? _a : state.selection.from; | ||
const to = (_b = options == null ? void 0 : options.to) != null ? _b : state.selection.to; | ||
if (from > to) return false; | ||
const tr = state.tr; | ||
if (unsetTextBlockType(tr, from, to)) { | ||
dispatch == null ? void 0 : dispatch(tr); | ||
return true; | ||
} | ||
return false; | ||
}; | ||
} | ||
function unsetTextBlockType(tr, from, to) { | ||
let mapFrom = tr.steps.length; | ||
return tr.doc.nodesBetween(from, to, (node, pos, parent, index) => { | ||
if (!parent || !node.isTextblock) return !0; | ||
let defaultType = parent.contentMatchAt(index).defaultType; | ||
const mapFrom = tr.steps.length; | ||
tr.doc.nodesBetween(from, to, (node, pos, parent, index) => { | ||
if (!parent || !node.isTextblock) return true; | ||
const defaultType = parent.contentMatchAt(index).defaultType; | ||
if (defaultType && defaultType.isTextblock && node.type !== defaultType && defaultType.validContent(node.content)) { | ||
let mapping = tr.mapping.slice(mapFrom), start = mapping.map(pos, 1), end = mapping.map(pos + node.nodeSize, 1), step = new ReplaceAroundStep( | ||
const mapping = tr.mapping.slice(mapFrom); | ||
const start = mapping.map(pos, 1); | ||
const end = mapping.map(pos + node.nodeSize, 1); | ||
const step = new ReplaceAroundStep( | ||
start, | ||
@@ -338,8 +438,9 @@ end, | ||
1, | ||
!0 | ||
true | ||
); | ||
tr.step(step); | ||
} | ||
return !1; | ||
}), tr.steps.length > mapFrom; | ||
return false; | ||
}); | ||
return tr.steps.length > mapFrom; | ||
} | ||
@@ -352,4 +453,7 @@ | ||
var _a, _b; | ||
let from = (_a = options == null ? void 0 : options.from) != null ? _a : state.selection.from, to = (_b = options == null ? void 0 : options.to) != null ? _b : state.selection.to; | ||
return from > to ? !1 : (dispatch == null || dispatch(state.tr.removeMark(from, to)), !0); | ||
const from = (_a = options == null ? void 0 : options.from) != null ? _a : state.selection.from; | ||
const to = (_b = options == null ? void 0 : options.to) != null ? _b : state.selection.to; | ||
if (from > to) return false; | ||
dispatch == null ? void 0 : dispatch(state.tr.removeMark(from, to)); | ||
return true; | ||
}; | ||
@@ -364,6 +468,9 @@ } | ||
return (state, dispatch) => { | ||
let { $from, $to } = state.selection, range = $from.blockRange($to); | ||
if (!range) return !1; | ||
let wrapping = findWrapping(range, nodeType, attrs); | ||
return wrapping ? (dispatch == null || dispatch(state.tr.wrap(range, wrapping)), !0) : !1; | ||
const { $from, $to } = state.selection; | ||
const range = $from.blockRange($to); | ||
if (!range) return false; | ||
const wrapping = findWrapping(range, nodeType, attrs); | ||
if (!wrapping) return false; | ||
dispatch == null ? void 0 : dispatch(state.tr.wrap(range, wrapping)); | ||
return true; | ||
}; | ||
@@ -374,4 +481,5 @@ } | ||
function withPriority(extension, priority) { | ||
let result = union(extension); | ||
return result.priority = priority, result; | ||
const result = union(extension); | ||
result.priority = priority; | ||
return result; | ||
} | ||
@@ -385,3 +493,8 @@ | ||
}) { | ||
return (state, dispatch) => (text && (dispatch == null || dispatch(state.tr.insertText(text, from, to))), !0); | ||
return (state, dispatch) => { | ||
if (text) { | ||
dispatch == null ? void 0 : dispatch(state.tr.insertText(text, from, to)); | ||
} | ||
return true; | ||
}; | ||
} | ||
@@ -392,3 +505,6 @@ | ||
function selectAll() { | ||
return (state, dispatch) => (dispatch == null || dispatch(state.tr.setSelection(new AllSelection(state.doc))), !0); | ||
return (state, dispatch) => { | ||
dispatch == null ? void 0 : dispatch(state.tr.setSelection(new AllSelection(state.doc))); | ||
return true; | ||
}; | ||
} | ||
@@ -398,5 +514,8 @@ | ||
var commandFacet = defineFacet({ | ||
reducer: (inputs) => ({ commands: Object.assign({}, ...inputs) }), | ||
reducer: (inputs) => { | ||
const commands2 = Object.assign({}, ...inputs); | ||
return { commands: commands2 }; | ||
}, | ||
parent: rootFacet, | ||
singleton: !0 | ||
singleton: true | ||
}); | ||
@@ -433,13 +552,18 @@ | ||
var _a; | ||
let nodes = OrderedMap.from({}), marks = OrderedMap.from({}), topNode; | ||
for (let spec of specs) | ||
nodes = nodes.append(spec.nodes), marks = marks.append((_a = spec.marks) != null ? _a : {}), topNode = topNode != null ? topNode : spec.topNode; | ||
let nodes = OrderedMap.from({}); | ||
let marks = OrderedMap.from({}); | ||
let topNode = void 0; | ||
for (const spec of specs) { | ||
nodes = nodes.append(spec.nodes); | ||
marks = marks.append((_a = spec.marks) != null ? _a : {}); | ||
topNode = topNode != null ? topNode : spec.topNode; | ||
} | ||
return { nodes, marks, topNode }; | ||
}, | ||
parent: schemaFacet, | ||
singleton: !0 | ||
singleton: true | ||
}); | ||
// src/utils/is-element.ts | ||
var hasElement = typeof Element != "undefined"; | ||
var hasElement = typeof Element !== "undefined"; | ||
function isElement(value) { | ||
@@ -451,13 +575,23 @@ return hasElement && value instanceof Element; | ||
function defineNodeSpec(options) { | ||
return defineFacetPayload(nodeSpecFacet, [[options, void 0]]); | ||
const payload = [options, void 0]; | ||
return defineFacetPayload(nodeSpecFacet, [payload]); | ||
} | ||
function defineNodeAttr(options) { | ||
return defineFacetPayload(nodeSpecFacet, [[void 0, options]]); | ||
const payload = [void 0, options]; | ||
return defineFacetPayload(nodeSpecFacet, [payload]); | ||
} | ||
var nodeSpecFacet = defineFacet({ | ||
reducer: (payloads) => { | ||
let nodes = OrderedMap2.from({}), topNodeName, specPayloads = payloads.map((input) => input[0]).filter(isNotNull), attrPayloads = payloads.map((input) => input[1]).filter(isNotNull); | ||
for (let { name, topNode, ...spec } of specPayloads) | ||
assert(!nodes.get(name), `Node type ${name} can only be defined once`), topNode && (topNodeName = name), nodes = nodes.addToStart(name, spec); | ||
for (let { | ||
let nodes = OrderedMap2.from({}); | ||
let topNodeName = void 0; | ||
const specPayloads = payloads.map((input) => input[0]).filter(isNotNull); | ||
const attrPayloads = payloads.map((input) => input[1]).filter(isNotNull); | ||
for (const { name, topNode, ...spec } of specPayloads) { | ||
assert(!nodes.get(name), `Node type ${name} can only be defined once`); | ||
if (topNode) { | ||
topNodeName = name; | ||
} | ||
nodes = nodes.addToStart(name, spec); | ||
} | ||
for (const { | ||
type, | ||
@@ -470,36 +604,59 @@ attr, | ||
} of attrPayloads) { | ||
let spec = nodes.get(type); | ||
if (assert(spec, `Node type ${type} must be defined`), spec.attrs || (spec.attrs = {}), spec.attrs[attr] = { | ||
const spec = nodes.get(type); | ||
assert(spec, `Node type ${type} must be defined`); | ||
if (!spec.attrs) { | ||
spec.attrs = {}; | ||
} | ||
spec.attrs[attr] = { | ||
default: defaultValue, | ||
splittable | ||
}, toDOM && spec.toDOM) { | ||
let existingToDom = spec.toDOM; | ||
}; | ||
if (toDOM && spec.toDOM) { | ||
const existingToDom = spec.toDOM; | ||
spec.toDOM = (node) => { | ||
let dom = existingToDom(node); | ||
if (!dom) | ||
const dom = existingToDom(node); | ||
if (!dom) { | ||
return dom; | ||
let attrDOM = toDOM(node.attrs[attr]); | ||
if (!attrDOM) | ||
} | ||
const attrDOM = toDOM(node.attrs[attr]); | ||
if (!attrDOM) { | ||
return dom; | ||
let [key, value] = attrDOM; | ||
return key ? Array.isArray(dom) ? typeof dom[1] == "object" ? [ | ||
dom[0], | ||
setObjectAttribute( | ||
dom[1], | ||
key, | ||
value | ||
), | ||
...dom.slice(2) | ||
] : [dom[0], { [key]: value }, ...dom.slice(1)] : (isElement(dom) ? setElementAttribute(dom, key, value) : typeof dom == "object" && "dom" in dom && isElement(dom.dom) && setElementAttribute(dom.dom, key, value), dom) : dom; | ||
} | ||
const [key, value] = attrDOM; | ||
if (!key) { | ||
return dom; | ||
} | ||
if (Array.isArray(dom)) { | ||
if (typeof dom[1] === "object") { | ||
return [ | ||
dom[0], | ||
setObjectAttribute( | ||
dom[1], | ||
key, | ||
value | ||
), | ||
...dom.slice(2) | ||
]; | ||
} else { | ||
return [dom[0], { [key]: value }, ...dom.slice(1)]; | ||
} | ||
} else if (isElement(dom)) { | ||
setElementAttribute(dom, key, value); | ||
} else if (typeof dom === "object" && "dom" in dom && isElement(dom.dom)) { | ||
setElementAttribute(dom.dom, key, value); | ||
} | ||
return dom; | ||
}; | ||
} | ||
if (parseDOM && spec.parseDOM) | ||
for (let rule of spec.parseDOM) { | ||
let existingGetAttrs = rule.getAttrs, existingAttrs = rule.attrs; | ||
if (parseDOM && spec.parseDOM) { | ||
for (const rule of spec.parseDOM) { | ||
const existingGetAttrs = rule.getAttrs; | ||
const existingAttrs = rule.attrs; | ||
rule.getAttrs = (dom) => { | ||
var _a; | ||
let attrs = (_a = existingGetAttrs == null ? void 0 : existingGetAttrs(dom)) != null ? _a : existingAttrs; | ||
if (attrs === !1 || !dom || !isElement(dom)) | ||
const attrs = (_a = existingGetAttrs == null ? void 0 : existingGetAttrs(dom)) != null ? _a : existingAttrs; | ||
if (attrs === false || !dom || !isElement(dom)) { | ||
return attrs != null ? attrs : null; | ||
let value = parseDOM(dom); | ||
} | ||
const value = parseDOM(dom); | ||
return { | ||
@@ -511,2 +668,3 @@ ...attrs, | ||
} | ||
} | ||
} | ||
@@ -516,9 +674,15 @@ return { nodes, topNode: topNodeName }; | ||
parent: schemaSpecFacet, | ||
singleton: !0 | ||
singleton: true | ||
}); | ||
function setObjectAttribute(obj, key, value) { | ||
return key === "style" && (value = `${value}${obj.style || ""}`), { ...obj, [key]: value }; | ||
if (key === "style") { | ||
value = `${value}${obj.style || ""}`; | ||
} | ||
return { ...obj, [key]: value }; | ||
} | ||
function setElementAttribute(element, key, value) { | ||
key === "style" && (value = `${value}${element.getAttribute("style") || ""}`), element.setAttribute(key, value); | ||
if (key === "style") { | ||
value = `${value}${element.getAttribute("style") || ""}`; | ||
} | ||
element.setAttribute(key, value); | ||
} | ||
@@ -531,3 +695,3 @@ | ||
content: "block+", | ||
topNode: !0 | ||
topNode: true | ||
}); | ||
@@ -543,23 +707,31 @@ } | ||
function definePlugin(plugin) { | ||
if (plugin instanceof Plugin) | ||
if (plugin instanceof Plugin) { | ||
return defineFacetPayload(pluginFacet, [() => [plugin]]); | ||
if (Array.isArray(plugin) && plugin.every((p) => p instanceof Plugin)) | ||
} | ||
if (Array.isArray(plugin) && plugin.every((p) => p instanceof Plugin)) { | ||
return defineFacetPayload(pluginFacet, [() => plugin]); | ||
if (typeof plugin == "function") | ||
} | ||
if (typeof plugin === "function") { | ||
return defineFacetPayload(pluginFacet, [plugin]); | ||
} | ||
throw new TypeError("Invalid plugin"); | ||
} | ||
var pluginFacet = defineFacet({ | ||
reducer: (payloads) => ({ schema }) => { | ||
let plugins = []; | ||
for (let payload of payloads) | ||
if (payload instanceof Plugin) | ||
plugins.push(payload); | ||
else if (Array.isArray(payload) && payload.every((p) => p instanceof Plugin)) | ||
plugins.push(...payload); | ||
else if (typeof payload == "function") | ||
plugins.push(...[payload({ schema })].flat()); | ||
else | ||
throw new ProseKitError("Invalid plugin"); | ||
return plugins.reverse(), { plugins }; | ||
reducer: (payloads) => { | ||
return ({ schema }) => { | ||
const plugins = []; | ||
for (const payload of payloads) { | ||
if (payload instanceof Plugin) { | ||
plugins.push(payload); | ||
} else if (Array.isArray(payload) && payload.every((p) => p instanceof Plugin)) { | ||
plugins.push(...payload); | ||
} else if (typeof payload === "function") { | ||
plugins.push(...[payload({ schema })].flat()); | ||
} else { | ||
throw new ProseKitError("Invalid plugin"); | ||
} | ||
} | ||
plugins.reverse(); | ||
return { plugins }; | ||
}; | ||
}, | ||
@@ -581,15 +753,24 @@ parent: stateFacet | ||
reduce: () => { | ||
let mountHandlers = [], updateHandlers = [], unmountHandlers = [], plugin = new ProseMirrorPlugin2({ | ||
let mountHandlers = []; | ||
let updateHandlers = []; | ||
let unmountHandlers = []; | ||
const plugin = new ProseMirrorPlugin2({ | ||
key: pluginKey, | ||
view: (view) => (mountHandlers.forEach((fn) => fn(view)), { | ||
update: (view2, prevState) => { | ||
updateHandlers.forEach((fn) => fn(view2, prevState)); | ||
}, | ||
destroy: () => { | ||
unmountHandlers.forEach((fn) => fn()); | ||
} | ||
}) | ||
}), register = (input) => { | ||
mountHandlers = [], updateHandlers = [], unmountHandlers = []; | ||
for (let args of input) | ||
view: (view) => { | ||
mountHandlers.forEach((fn) => fn(view)); | ||
return { | ||
update: (view2, prevState) => { | ||
updateHandlers.forEach((fn) => fn(view2, prevState)); | ||
}, | ||
destroy: () => { | ||
unmountHandlers.forEach((fn) => fn()); | ||
} | ||
}; | ||
} | ||
}); | ||
const register = (input) => { | ||
mountHandlers = []; | ||
updateHandlers = []; | ||
unmountHandlers = []; | ||
for (const args of input) { | ||
switch (args[0]) { | ||
@@ -606,10 +787,13 @@ case "mount": | ||
} | ||
} | ||
}; | ||
return function(input) { | ||
return register(input), plugin; | ||
return function reducer(input) { | ||
register(input); | ||
return plugin; | ||
}; | ||
}, | ||
parent: pluginFacet, | ||
singleton: !0 | ||
}), pluginKey = new PluginKey("prosekit-plugin-view-handler"); | ||
singleton: true | ||
}); | ||
var pluginKey = new PluginKey("prosekit-plugin-view-handler"); | ||
@@ -619,3 +803,5 @@ // src/extensions/events/doc-change.ts | ||
return defineUpdateHandler((view, prevState) => { | ||
view.state.doc.eq(prevState.doc) || handler(view, prevState); | ||
if (!view.state.doc.eq(prevState.doc)) { | ||
handler(view, prevState); | ||
} | ||
}); | ||
@@ -634,6 +820,8 @@ } | ||
function combinedEventHandler(...args) { | ||
for (let handler of _handlers) | ||
if (handler(...args)) | ||
return !0; | ||
return !1; | ||
for (const handler of _handlers) { | ||
if (handler(...args)) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
@@ -645,6 +833,10 @@ return [setHandlers, combinedEventHandler]; | ||
function groupEntries(entries) { | ||
let map = {}; | ||
for (let [key, value] of entries) { | ||
let values = map[key]; | ||
values ? values.push(value) : map[key] = [value]; | ||
const map = {}; | ||
for (const [key, value] of entries) { | ||
const values = map[key]; | ||
if (!values) { | ||
map[key] = [value]; | ||
} else { | ||
values.push(value); | ||
} | ||
} | ||
@@ -662,29 +854,38 @@ return map; | ||
reduce: () => { | ||
let setHandlersMap = {}, combinedHandlerMap = {}, plugin, update = (payloads) => { | ||
const setHandlersMap = {}; | ||
const combinedHandlerMap = {}; | ||
let plugin; | ||
const update = (payloads) => { | ||
var _a; | ||
let hasNewEvent = !1; | ||
for (let [event] of payloads) | ||
let hasNewEvent = false; | ||
for (const [event] of payloads) { | ||
if (!setHandlersMap[event]) { | ||
hasNewEvent = !0; | ||
let [setHandlers, combinedHandler] = combineEventHandlers(); | ||
hasNewEvent = true; | ||
const [setHandlers, combinedHandler] = combineEventHandlers(); | ||
setHandlersMap[event] = setHandlers; | ||
let e = (view, eventObject) => combinedHandler(view, eventObject); | ||
const e = (view, eventObject) => { | ||
return combinedHandler(view, eventObject); | ||
}; | ||
combinedHandlerMap[event] = e; | ||
} | ||
let map = groupEntries(payloads); | ||
for (let [event, setHandlers] of Object.entries(setHandlersMap)) { | ||
let handlers = (_a = map[event]) != null ? _a : []; | ||
} | ||
const map = groupEntries(payloads); | ||
for (const [event, setHandlers] of Object.entries(setHandlersMap)) { | ||
const handlers = (_a = map[event]) != null ? _a : []; | ||
setHandlers(handlers); | ||
} | ||
hasNewEvent && (plugin = new ProseMirrorPlugin3({ | ||
key: new PluginKey2("prosekit-dom-event-handler"), | ||
props: { handleDOMEvents: combinedHandlerMap } | ||
})); | ||
if (hasNewEvent) { | ||
plugin = new ProseMirrorPlugin3({ | ||
key: new PluginKey2("prosekit-dom-event-handler"), | ||
props: { handleDOMEvents: combinedHandlerMap } | ||
}); | ||
} | ||
}; | ||
return function(inputs) { | ||
return update(inputs), plugin != null ? plugin : []; | ||
return function reducer(inputs) { | ||
update(inputs); | ||
return plugin != null ? plugin : []; | ||
}; | ||
}, | ||
parent: pluginFacet, | ||
singleton: !0 | ||
singleton: true | ||
}); | ||
@@ -732,14 +933,41 @@ | ||
reduce: () => { | ||
let [update, plugin] = setupEditorEventPlugin(); | ||
return (entries) => (update(entries), plugin); | ||
const [update, plugin] = setupEditorEventPlugin(); | ||
return (entries) => { | ||
update(entries); | ||
return plugin; | ||
}; | ||
}, | ||
parent: pluginFacet, | ||
singleton: !0 | ||
singleton: true | ||
}); | ||
function setupEditorEventPlugin() { | ||
let [setKeyDownHandlers, handleKeyDown] = combineEventHandlers(), [setKeyPressHandlers, handleKeyPress] = combineEventHandlers(), [setTextInputHandlers, handleTextInput] = combineEventHandlers(), [setClickOnHandlers, handleClickOn] = combineEventHandlers(), [setClickHandlers, handleClick] = combineEventHandlers(), [setDoubleClickOnHandlers, handleDoubleClickOn] = combineEventHandlers(), [setDoubleClickHandlers, handleDoubleClick] = combineEventHandlers(), [setTripleClickOnHandlers, handleTripleClickOn] = combineEventHandlers(), [setTripleClickHandlers, handleTripleClick] = combineEventHandlers(), [setPasteHandlers, handlePaste] = combineEventHandlers(), [setDropHandlers, handleDrop] = combineEventHandlers(), [setScrollToSelectionHandlers, handleScrollToSelection] = combineEventHandlers(), update = (entries) => { | ||
const [setKeyDownHandlers, handleKeyDown] = combineEventHandlers(); | ||
const [setKeyPressHandlers, handleKeyPress] = combineEventHandlers(); | ||
const [setTextInputHandlers, handleTextInput] = combineEventHandlers(); | ||
const [setClickOnHandlers, handleClickOn] = combineEventHandlers(); | ||
const [setClickHandlers, handleClick] = combineEventHandlers(); | ||
const [setDoubleClickOnHandlers, handleDoubleClickOn] = combineEventHandlers(); | ||
const [setDoubleClickHandlers, handleDoubleClick] = combineEventHandlers(); | ||
const [setTripleClickOnHandlers, handleTripleClickOn] = combineEventHandlers(); | ||
const [setTripleClickHandlers, handleTripleClick] = combineEventHandlers(); | ||
const [setPasteHandlers, handlePaste] = combineEventHandlers(); | ||
const [setDropHandlers, handleDrop] = combineEventHandlers(); | ||
const [setScrollToSelectionHandlers, handleScrollToSelection] = combineEventHandlers(); | ||
const update = (entries) => { | ||
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l; | ||
let map = groupEntries(entries); | ||
setKeyDownHandlers((_a = map.keyDown) != null ? _a : []), setKeyPressHandlers((_b = map.keyPress) != null ? _b : []), setTextInputHandlers((_c = map.textInput) != null ? _c : []), setClickOnHandlers((_d = map.clickOn) != null ? _d : []), setClickHandlers((_e = map.click) != null ? _e : []), setDoubleClickOnHandlers((_f = map.doubleClickOn) != null ? _f : []), setDoubleClickHandlers((_g = map.doubleClick) != null ? _g : []), setTripleClickOnHandlers((_h = map.tripleClickOn) != null ? _h : []), setTripleClickHandlers((_i = map.tripleClick) != null ? _i : []), setPasteHandlers((_j = map.paste) != null ? _j : []), setDropHandlers((_k = map.drop) != null ? _k : []), setScrollToSelectionHandlers((_l = map.scrollToSelection) != null ? _l : []); | ||
}, plugin = new ProseMirrorPlugin4({ | ||
const map = groupEntries(entries); | ||
setKeyDownHandlers((_a = map.keyDown) != null ? _a : []); | ||
setKeyPressHandlers((_b = map.keyPress) != null ? _b : []); | ||
setTextInputHandlers((_c = map.textInput) != null ? _c : []); | ||
setClickOnHandlers((_d = map.clickOn) != null ? _d : []); | ||
setClickHandlers((_e = map.click) != null ? _e : []); | ||
setDoubleClickOnHandlers((_f = map.doubleClickOn) != null ? _f : []); | ||
setDoubleClickHandlers((_g = map.doubleClick) != null ? _g : []); | ||
setTripleClickOnHandlers((_h = map.tripleClickOn) != null ? _h : []); | ||
setTripleClickHandlers((_i = map.tripleClick) != null ? _i : []); | ||
setPasteHandlers((_j = map.paste) != null ? _j : []); | ||
setDropHandlers((_k = map.drop) != null ? _k : []); | ||
setScrollToSelectionHandlers((_l = map.scrollToSelection) != null ? _l : []); | ||
}; | ||
const plugin = new ProseMirrorPlugin4({ | ||
key: new PluginKey3("prosekit-editor-event"), | ||
@@ -766,5 +994,7 @@ props: { | ||
function defineFocusChangeHandler(handler) { | ||
const handleFocus = () => handler(true); | ||
const handleBlur = () => handler(false); | ||
return defineFacetPayload(domEventFacet, [ | ||
["focus", () => handler(!0)], | ||
["blur", () => handler(!1)] | ||
["focus", handleFocus], | ||
["blur", handleBlur] | ||
]); | ||
@@ -777,3 +1007,3 @@ } | ||
// src/utils/env.ts | ||
var isApple = typeof navigator != "undefined" ? /Mac|iP(hone|[ao]d)/.test(navigator.platform) : !1; | ||
var isApple = typeof navigator !== "undefined" ? /Mac|iP(hone|[ao]d)/.test(navigator.platform) : false; | ||
@@ -789,21 +1019,32 @@ // src/extensions/keymap.ts | ||
reduce: () => { | ||
let handler, handlerWrapper = (view, event) => handler ? handler(view, event) : !1, plugin = new Plugin2({ | ||
let handler; | ||
const handlerWrapper = (view, event) => { | ||
if (handler) return handler(view, event); | ||
return false; | ||
}; | ||
const plugin = new Plugin2({ | ||
key: keymapPluginKey, | ||
props: { handleKeyDown: handlerWrapper } | ||
}); | ||
return (keymaps) => (handler = keydownHandler( | ||
mergeKeymaps( | ||
// The keymap at the end have a higher priority. | ||
toReversed(keymaps) | ||
) | ||
), plugin); | ||
return (keymaps) => { | ||
handler = keydownHandler( | ||
mergeKeymaps( | ||
// The keymap at the end have a higher priority. | ||
toReversed(keymaps) | ||
) | ||
); | ||
return plugin; | ||
}; | ||
}, | ||
parent: pluginFacet, | ||
singleton: !0 | ||
singleton: true | ||
}); | ||
function mergeKeymaps(keymaps) { | ||
let bindings = {}; | ||
for (let keymap2 of keymaps) | ||
for (let [key, command] of Object.entries(keymap2)) | ||
(bindings[key] || (bindings[key] = [])).push(command); | ||
const bindings = {}; | ||
for (const keymap2 of keymaps) { | ||
for (const [key, command] of Object.entries(keymap2)) { | ||
const commands2 = bindings[key] || (bindings[key] = []); | ||
commands2.push(command); | ||
} | ||
} | ||
return Object.fromEntries( | ||
@@ -823,3 +1064,5 @@ Object.entries(bindings).map(([key, commands2]) => [ | ||
}; | ||
isApple || (keymap["Mod-y"] = redo); | ||
if (!isApple) { | ||
keymap["Mod-y"] = redo; | ||
} | ||
var commands = { | ||
@@ -857,7 +1100,9 @@ undo: () => undo, | ||
splitSplittableBlock | ||
), customBackspace = chainCommands2( | ||
); | ||
var customBackspace = chainCommands2( | ||
deleteSelection, | ||
joinTextblockBackward, | ||
selectNodeBackward | ||
), customBaseKeymap = { | ||
); | ||
var customBaseKeymap = { | ||
...baseKeymap, | ||
@@ -869,3 +1114,3 @@ Enter: customEnter, | ||
var _a; | ||
let priority = (_a = options == null ? void 0 : options.priority) != null ? _a : 1 /* low */; | ||
const priority = (_a = options == null ? void 0 : options.priority) != null ? _a : 1 /* low */; | ||
return withPriority(defineKeymap(customBaseKeymap), priority); | ||
@@ -876,16 +1121,21 @@ } | ||
function defineMarkSpec(options) { | ||
return defineFacetPayload(markSpecFacet, [[options, void 0]]); | ||
const payload = [options, void 0]; | ||
return defineFacetPayload(markSpecFacet, [payload]); | ||
} | ||
function defineMarkAttr(options) { | ||
return defineFacetPayload(markSpecFacet, [[void 0, options]]); | ||
const payload = [void 0, options]; | ||
return defineFacetPayload(markSpecFacet, [payload]); | ||
} | ||
var markSpecFacet = defineFacet({ | ||
reducer: (payloads) => { | ||
let marks = {}, specPayloads = payloads.map((input) => input[0]).filter(isNotNull), attrPayloads = payloads.map((input) => input[1]).filter(isNotNull); | ||
for (let { name, ...spec } of specPayloads) { | ||
if (marks[name]) | ||
const marks = {}; | ||
const specPayloads = payloads.map((input) => input[0]).filter(isNotNull); | ||
const attrPayloads = payloads.map((input) => input[1]).filter(isNotNull); | ||
for (const { name, ...spec } of specPayloads) { | ||
if (marks[name]) { | ||
throw new ProseKitError(`Mark type ${name} has already been defined`); | ||
} | ||
marks[name] = spec; | ||
} | ||
for (let { | ||
for (const { | ||
type, | ||
@@ -897,29 +1147,52 @@ attr, | ||
} of attrPayloads) { | ||
let spec = marks[type]; | ||
if (!spec) | ||
const spec = marks[type]; | ||
if (!spec) { | ||
throw new ProseKitError( | ||
`Mark type ${type} must be defined before defining attributes` | ||
); | ||
if (spec.attrs || (spec.attrs = {}), spec.attrs[attr] = { default: defaultValue }, toDOM && spec.toDOM) { | ||
let existingToDom = spec.toDOM; | ||
} | ||
if (!spec.attrs) { | ||
spec.attrs = {}; | ||
} | ||
spec.attrs[attr] = { default: defaultValue }; | ||
if (toDOM && spec.toDOM) { | ||
const existingToDom = spec.toDOM; | ||
spec.toDOM = (mark, inline) => { | ||
let dom = existingToDom(mark, inline); | ||
if (!dom) | ||
const dom = existingToDom(mark, inline); | ||
if (!dom) { | ||
return dom; | ||
let attrDOM = toDOM(mark.attrs[attr]); | ||
if (!attrDOM) | ||
} | ||
const attrDOM = toDOM(mark.attrs[attr]); | ||
if (!attrDOM) { | ||
return dom; | ||
let [key, value] = attrDOM; | ||
return key ? Array.isArray(dom) ? typeof dom[1] == "object" ? [dom[0], { ...dom[1], [key]: value }, ...dom.slice(2)] : [dom[0], { [key]: value }, ...dom.slice(1)] : (isElement(dom) ? dom.setAttribute(key, value) : typeof dom == "object" && "dom" in dom && isElement(dom.dom) && dom.dom.setAttribute(key, value), dom) : dom; | ||
} | ||
const [key, value] = attrDOM; | ||
if (!key) { | ||
return dom; | ||
} | ||
if (Array.isArray(dom)) { | ||
if (typeof dom[1] === "object") { | ||
return [dom[0], { ...dom[1], [key]: value }, ...dom.slice(2)]; | ||
} else { | ||
return [dom[0], { [key]: value }, ...dom.slice(1)]; | ||
} | ||
} else if (isElement(dom)) { | ||
dom.setAttribute(key, value); | ||
} else if (typeof dom === "object" && "dom" in dom && isElement(dom.dom)) { | ||
dom.dom.setAttribute(key, value); | ||
} | ||
return dom; | ||
}; | ||
} | ||
if (parseDOM && spec.parseDOM) | ||
for (let rule of spec.parseDOM) { | ||
let existingGetAttrs = rule.getAttrs, existingAttrs = rule.attrs; | ||
if (parseDOM && spec.parseDOM) { | ||
for (const rule of spec.parseDOM) { | ||
const existingGetAttrs = rule.getAttrs; | ||
const existingAttrs = rule.attrs; | ||
rule.getAttrs = (dom) => { | ||
var _a; | ||
let attrs = (_a = existingGetAttrs == null ? void 0 : existingGetAttrs(dom)) != null ? _a : existingAttrs; | ||
if (attrs === !1 || !dom || !isElement(dom)) | ||
const attrs = (_a = existingGetAttrs == null ? void 0 : existingGetAttrs(dom)) != null ? _a : existingAttrs; | ||
if (attrs === false || !dom || !isElement(dom)) { | ||
return attrs != null ? attrs : null; | ||
let value = parseDOM(dom); | ||
} | ||
const value = parseDOM(dom); | ||
return { | ||
@@ -931,2 +1204,3 @@ ...attrs, | ||
} | ||
} | ||
} | ||
@@ -936,3 +1210,3 @@ return { marks, nodes: {} }; | ||
parent: schemaSpecFacet, | ||
singleton: !0 | ||
singleton: true | ||
}); | ||
@@ -948,5 +1222,8 @@ | ||
reducer: (inputs) => { | ||
let nodeViews = {}; | ||
for (let input of inputs) | ||
nodeViews[input.name] || (nodeViews[input.name] = input.constructor); | ||
const nodeViews = {}; | ||
for (const input of inputs) { | ||
if (!nodeViews[input.name]) { | ||
nodeViews[input.name] = input.constructor; | ||
} | ||
} | ||
return () => [ | ||
@@ -966,13 +1243,18 @@ new ProseMirrorPlugin5({ | ||
function defineNodeViewFactory(options) { | ||
return defineFacetPayload(nodeViewFactoryFacet, [[options, null]]); | ||
const input = [options, null]; | ||
return defineFacetPayload(nodeViewFactoryFacet, [input]); | ||
} | ||
function defineNodeViewComponent(options) { | ||
return defineFacetPayload(nodeViewFactoryFacet, [[null, options]]); | ||
const input = [null, options]; | ||
return defineFacetPayload(nodeViewFactoryFacet, [input]); | ||
} | ||
var nodeViewFactoryFacet = defineFacet({ | ||
reducer: (inputs) => { | ||
let nodeViews = {}, factories = inputs.map((x) => x[0]).filter(isNotNull), options = inputs.map((x) => x[1]).filter(isNotNull); | ||
for (let { group, name, args } of options) { | ||
let factory = factories.find((factory2) => factory2.group === group); | ||
factory && (nodeViews[name] = factory.factory(args)); | ||
const nodeViews = {}; | ||
const factories = inputs.map((x) => x[0]).filter(isNotNull); | ||
const options = inputs.map((x) => x[1]).filter(isNotNull); | ||
for (const { group, name, args } of options) { | ||
const factory = factories.find((factory2) => factory2.group === group); | ||
if (!factory) continue; | ||
nodeViews[name] = factory.factory(args); | ||
} | ||
@@ -1015,4 +1297,9 @@ return () => [ | ||
function cache(fn) { | ||
let result; | ||
return () => (result === void 0 && (result = fn()), result); | ||
let result = void 0; | ||
return () => { | ||
if (result === void 0) { | ||
result = fn(); | ||
} | ||
return result; | ||
}; | ||
} | ||
@@ -1025,3 +1312,3 @@ | ||
} catch (error) { | ||
return !1; | ||
return false; | ||
} | ||
@@ -1037,10 +1324,13 @@ }); | ||
function collectNodes(content) { | ||
if (Array.isArray(content)) | ||
if (Array.isArray(content)) { | ||
return content.flatMap(collectNodes); | ||
if (content instanceof ProseMirrorNode2) | ||
} | ||
if (content instanceof ProseMirrorNode2) { | ||
return [content]; | ||
} | ||
if (content instanceof ProseMirrorFragment) { | ||
let nodes = []; | ||
for (let i = 0; i < content.childCount; i++) | ||
const nodes = []; | ||
for (let i = 0; i < content.childCount; i++) { | ||
nodes.push(content.child(i)); | ||
} | ||
return nodes; | ||
@@ -1054,3 +1344,3 @@ } | ||
for (let i = 0; i < match.edgeCount; i++) { | ||
let { type } = match.edge(i); | ||
const { type } = match.edge(i); | ||
if (type.isTextblock && !type.hasRequiredAttrs()) return type; | ||
@@ -1064,3 +1354,4 @@ } | ||
function getId() { | ||
return id = (id + 1) % Number.MAX_SAFE_INTEGER, `id:${id}`; | ||
id = (id + 1) % Number.MAX_SAFE_INTEGER; | ||
return `id:${id}`; | ||
} | ||
@@ -1070,4 +1361,6 @@ | ||
function isAtBlockStart(state, view) { | ||
let { $cursor } = state.selection; | ||
return !$cursor || (view ? !view.endOfTextblock("backward", state) : $cursor.parentOffset > 0) ? null : $cursor; | ||
const { $cursor } = state.selection; | ||
if (!$cursor || (view ? !view.endOfTextblock("backward", state) : $cursor.parentOffset > 0)) | ||
return null; | ||
return $cursor; | ||
} | ||
@@ -1085,3 +1378,3 @@ | ||
function maybeRun(value, ...args) { | ||
return typeof value == "function" ? value(...args) : value; | ||
return typeof value === "function" ? value(...args) : value; | ||
} | ||
@@ -1094,3 +1387,8 @@ | ||
function withSkipCodeBlock(command) { | ||
return (state, dispatch, view) => isInCodeBlock(state.selection) ? !1 : command(state, dispatch, view); | ||
return (state, dispatch, view) => { | ||
if (isInCodeBlock(state.selection)) { | ||
return false; | ||
} | ||
return command(state, dispatch, view); | ||
}; | ||
} | ||
@@ -1097,0 +1395,0 @@ export { |
{ | ||
"name": "@prosekit/core", | ||
"type": "module", | ||
"version": "0.0.0-next-20240715033214", | ||
"version": "0.0.0-next-20240715045302", | ||
"private": false, | ||
@@ -47,3 +47,3 @@ "author": { | ||
"type-fest": "^4.21.0", | ||
"@prosekit/pm": "^0.0.0-next-20240715033214" | ||
"@prosekit/pm": "^0.0.0-next-20240715045302" | ||
}, | ||
@@ -50,0 +50,0 @@ "devDependencies": { |
149870
4716