rhino-editor
Version:
A custom element wrapped rich text editor
416 lines (408 loc) • 17.1 kB
JavaScript
import {
Decoration,
DecorationSet,
Extension
} from "./chunk-TVRRLXKH.js";
import {
Plugin,
PluginKey,
TextSelection
} from "./chunk-ZEDCHN2I.js";
// node_modules/.pnpm/prosemirror-codemark@0.4.2_prosemirror-inputrules@1.4.0_prosemirror-model@1.23.0_prosemirror-_rwgskrtfqtz7desswyga6gztka/node_modules/prosemirror-codemark/dist/esm/utils.js
var DEFAULT_ID = "codemark";
var MAX_MATCH = 100;
var pluginKey = new PluginKey(DEFAULT_ID);
function getMarkType(view, opts) {
var _a, _b;
if ("schema" in view)
return (_a = opts === null || opts === void 0 ? void 0 : opts.markType) !== null && _a !== void 0 ? _a : view.schema.marks.code;
return (_b = opts === null || opts === void 0 ? void 0 : opts.markType) !== null && _b !== void 0 ? _b : view.state.schema.marks.code;
}
function safeResolve(doc, pos) {
return doc.resolve(Math.min(Math.max(1, pos), doc.nodeSize - 2));
}
// node_modules/.pnpm/prosemirror-codemark@0.4.2_prosemirror-inputrules@1.4.0_prosemirror-model@1.23.0_prosemirror-_rwgskrtfqtz7desswyga6gztka/node_modules/prosemirror-codemark/dist/esm/inputRules.js
function stopMatch(markType, view, from, to) {
var _a;
const stored = markType.isInSet((_a = view.state.storedMarks) !== null && _a !== void 0 ? _a : view.state.doc.resolve(from).marks());
const range = view.state.doc.rangeHasMark(from, to, markType);
if (stored || range)
return true;
return false;
}
var markBefore = {
match: /`((?:[^`\w]|[\w])+)`$/,
handler: (markType, view, text, match, from, to, plugins) => {
if (stopMatch(markType, view, from, to))
return false;
const code = match[1];
const mark = markType.create();
const pos = from + code.length;
const tr = view.state.tr.delete(from, to).insertText(code).addMark(from, pos, mark);
const selected = tr.setSelection(TextSelection.create(tr.doc, pos)).removeStoredMark(markType);
const withMeta = selected.setMeta(plugins.input, {
transform: selected,
from,
to,
text: `\`${code}${text}`
});
view.dispatch(withMeta);
return true;
}
};
var markAfter = {
match: /^`((?:[^`\w]|[\w])+)`/,
handler: (markType, view, text, match, from, to, plugins) => {
if (stopMatch(markType, view, from, to))
return false;
const mark = markType.create();
const code = match[1];
const pos = from;
const tr = view.state.tr.delete(from, to).insertText(code).addMark(from, from + code.length, mark);
const selected = tr.setSelection(TextSelection.create(tr.doc, pos)).addStoredMark(markType.create());
const withMeta = selected.setMeta(plugins.input, {
transform: selected,
from,
to,
text: `\`${code}${text}`
});
view.dispatch(withMeta);
return true;
}
};
function run(markType, view, from, to, text, plugins) {
if (view.composing)
return false;
const { state } = view;
const $from = state.doc.resolve(from);
if ($from.parent.type.spec.code)
return false;
const leafText = "\uFFFC";
const textBefore = $from.parent.textBetween(Math.max(0, $from.parentOffset - MAX_MATCH), $from.parentOffset, void 0, leafText) + text;
const textAfter = text + $from.parent.textBetween($from.parentOffset, Math.min($from.parent.nodeSize - 2, $from.parentOffset + MAX_MATCH), void 0, leafText);
const matchB = markBefore.match.exec(textBefore);
const matchA = markAfter.match.exec(textAfter);
if (matchB) {
const handled = markBefore.handler(markType, view, text, matchB, from - matchB[0].length + text.length, to, plugins);
if (handled)
return handled;
}
if (matchA)
return markAfter.handler(markType, view, text, matchA, from, to + matchA[0].length - text.length, plugins);
return false;
}
function createInputRule(cursorPlugin, opts) {
const plugin = new Plugin({
isInputRules: true,
state: {
init: () => null,
apply(tr, prev) {
const meta = tr.getMeta(plugin);
if (meta)
return meta;
return tr.selectionSet || tr.docChanged ? null : prev;
}
},
props: {
handleTextInput(view, from, to, text) {
const markType = getMarkType(view, opts);
return run(markType, view, from, to, text, { input: plugin, cursor: cursorPlugin });
}
}
});
return plugin;
}
// node_modules/.pnpm/prosemirror-codemark@0.4.2_prosemirror-inputrules@1.4.0_prosemirror-model@1.23.0_prosemirror-_rwgskrtfqtz7desswyga6gztka/node_modules/prosemirror-codemark/dist/esm/actions.js
function stepOutsideNextTrAndPass(view, plugin, action = "next") {
const meta = { action };
view.dispatch(view.state.tr.setMeta(plugin, meta));
return false;
}
function onBacktick(view, plugin, event, markType) {
if (view.state.selection.empty)
return false;
if (event.metaKey || event.shiftKey || event.altKey || event.ctrlKey)
return false;
const { from, to } = view.state.selection;
if (to - from >= MAX_MATCH || view.state.doc.rangeHasMark(from, to, markType))
return false;
const tr = view.state.tr.addMark(from, to, markType.create());
const selected = tr.setSelection(TextSelection.create(tr.doc, to)).removeStoredMark(markType);
view.dispatch(selected);
return true;
}
function onArrowRightInside(view, plugin, event, markType) {
var _a;
if (event.metaKey)
return stepOutsideNextTrAndPass(view, plugin);
if (event.shiftKey || event.altKey || event.ctrlKey)
return false;
const { selection, doc } = view.state;
if (!selection.empty)
return false;
const pluginState = plugin.getState(view.state);
const pos = selection.$from;
const inCode = !!markType.isInSet(pos.marks());
const nextCode = !!markType.isInSet((_a = pos.marksAcross(safeResolve(doc, selection.from + 1))) !== null && _a !== void 0 ? _a : []);
if (pos.pos === view.state.doc.nodeSize - 3 && pos.parentOffset === pos.parent.nodeSize - 2 && (pluginState === null || pluginState === void 0 ? void 0 : pluginState.active)) {
view.dispatch(view.state.tr.removeStoredMark(markType));
return true;
}
if (inCode === nextCode && pos.parentOffset !== 0)
return false;
if (inCode && (!(pluginState === null || pluginState === void 0 ? void 0 : pluginState.active) || pluginState.side === -1) && pos.parentOffset !== 0) {
view.dispatch(view.state.tr.removeStoredMark(markType));
return true;
}
if (nextCode && (pluginState === null || pluginState === void 0 ? void 0 : pluginState.side) === -1) {
view.dispatch(view.state.tr.addStoredMark(markType.create()));
return true;
}
return false;
}
function onArrowRight(view, plugin, event, markType) {
const handled = onArrowRightInside(view, plugin, event, markType);
if (handled)
return true;
const { selection } = view.state;
const pos = selection.$from;
if (selection.empty && pos.parentOffset === pos.parent.nodeSize - 2) {
return stepOutsideNextTrAndPass(view, plugin);
}
return false;
}
function onArrowLeftInside(view, plugin, event, markType) {
var _a;
if (event.metaKey)
return stepOutsideNextTrAndPass(view, plugin);
if (event.shiftKey || event.altKey || event.ctrlKey)
return false;
const { selection, doc } = view.state;
const pluginState = plugin.getState(view.state);
const inCode = !!markType.isInSet(selection.$from.marks());
const nextCode = !!markType.isInSet((_a = safeResolve(doc, selection.empty ? selection.from - 1 : selection.from + 1).marks()) !== null && _a !== void 0 ? _a : []);
if (inCode && (pluginState === null || pluginState === void 0 ? void 0 : pluginState.side) === -1 && selection.$from.parentOffset === 0) {
return false;
}
if ((pluginState === null || pluginState === void 0 ? void 0 : pluginState.side) === 0 && selection.$from.parentOffset === 0) {
view.dispatch(view.state.tr.removeStoredMark(markType));
return true;
}
if (inCode && nextCode && (pluginState === null || pluginState === void 0 ? void 0 : pluginState.side) === 0) {
view.dispatch(view.state.tr.addStoredMark(markType.create()));
return true;
}
if (inCode && !nextCode && (pluginState === null || pluginState === void 0 ? void 0 : pluginState.active) && selection.$from.parentOffset === 0) {
view.dispatch(view.state.tr.removeStoredMark(markType));
return true;
}
if (!inCode && (pluginState === null || pluginState === void 0 ? void 0 : pluginState.active) && (pluginState === null || pluginState === void 0 ? void 0 : pluginState.side) === 0) {
view.dispatch(view.state.tr.removeStoredMark(markType));
return true;
}
if (inCode === nextCode)
return false;
if (nextCode || !selection.empty && inCode) {
const from = selection.empty ? selection.from - 1 : selection.from;
const selected = view.state.tr.setSelection(TextSelection.create(doc, from));
if (!selection.empty && nextCode) {
view.dispatch(selected.addStoredMark(markType.create()));
} else {
view.dispatch(selected.removeStoredMark(markType));
}
return true;
}
if ((nextCode || !selection.empty && inCode) && !(pluginState === null || pluginState === void 0 ? void 0 : pluginState.active)) {
const from = selection.empty ? selection.from - 1 : selection.from;
view.dispatch(view.state.tr.setSelection(TextSelection.create(doc, from)).removeStoredMark(markType));
return true;
}
if (inCode && !(pluginState === null || pluginState === void 0 ? void 0 : pluginState.active) && selection.$from.parentOffset > 0) {
view.dispatch(view.state.tr.setSelection(TextSelection.create(doc, selection.from - 1)).addStoredMark(markType.create()));
return true;
}
if (inCode && !nextCode && (pluginState === null || pluginState === void 0 ? void 0 : pluginState.active) && pluginState.side !== -1) {
view.dispatch(view.state.tr.addStoredMark(markType.create()));
return true;
}
if (inCode && !nextCode && (pluginState === null || pluginState === void 0 ? void 0 : pluginState.active)) {
const pos = selection.from - 1;
view.dispatch(view.state.tr.setSelection(TextSelection.create(doc, pos)).addStoredMark(markType.create()));
return true;
}
return false;
}
function onArrowLeft(view, plugin, event, markType) {
const handled = onArrowLeftInside(view, plugin, event, markType);
if (handled)
return true;
const { selection } = view.state;
const pos = selection.$from;
const pluginState = plugin.getState(view.state);
if (pos.pos === 1 && pos.parentOffset === 0 && (pluginState === null || pluginState === void 0 ? void 0 : pluginState.side) === -1) {
return true;
}
if (selection.empty && pos.parentOffset === 0) {
return stepOutsideNextTrAndPass(view, plugin);
}
return false;
}
function onBackspace(view, plugin, event, markType) {
if (event.metaKey || event.shiftKey || event.altKey || event.ctrlKey)
return false;
const { selection, doc } = view.state;
const from = safeResolve(doc, selection.from - 1);
const fromCode = !!markType.isInSet(from.marks());
const startOfLine = from.parentOffset === 0;
const toCode = !!markType.isInSet(safeResolve(doc, selection.to + 1).marks());
if ((!fromCode || startOfLine) && !toCode) {
return stepOutsideNextTrAndPass(view, plugin);
}
const pluginState = plugin.getState(view.state);
if (selection.empty && (pluginState === null || pluginState === void 0 ? void 0 : pluginState.side) === -1) {
const tr = view.state.tr.delete(selection.from - 1, selection.from);
view.dispatch(tr);
return true;
}
return false;
}
function onDelete(view, plugin, event, markType) {
if (event.metaKey || event.shiftKey || event.altKey || event.ctrlKey)
return false;
const { selection, doc } = view.state;
const fromCode = !!markType.isInSet(selection.$from.marks());
const startOfLine = selection.$from.parentOffset === 0;
const toCode = !!markType.isInSet(safeResolve(doc, selection.to + 2).marks());
if ((!fromCode || startOfLine) && !toCode) {
return stepOutsideNextTrAndPass(view, plugin);
}
return false;
}
function stepOutside(state, markType) {
var _a, _b;
if (!state)
return null;
const { selection, doc } = state;
if (!selection.empty)
return null;
const stored = !!markType.isInSet((_a = state.storedMarks) !== null && _a !== void 0 ? _a : []);
const inCode = !!markType.isInSet(selection.$from.marks());
const nextCode = !!markType.isInSet((_b = safeResolve(doc, selection.from + 1).marks()) !== null && _b !== void 0 ? _b : []);
const startOfLine = selection.$from.parentOffset === 0;
if (inCode !== nextCode || !inCode && stored !== inCode || inCode && startOfLine)
return state.tr.removeStoredMark(markType);
return null;
}
// node_modules/.pnpm/prosemirror-codemark@0.4.2_prosemirror-inputrules@1.4.0_prosemirror-model@1.23.0_prosemirror-_rwgskrtfqtz7desswyga6gztka/node_modules/prosemirror-codemark/dist/esm/plugin.js
function toDom() {
const span = document.createElement("span");
span.classList.add("fake-cursor");
return span;
}
function getDecorationPlugin(opts) {
const plugin = new Plugin({
key: pluginKey,
appendTransaction: (trs, oldState, newState) => {
var _a;
const prev = plugin.getState(oldState);
const meta = (_a = trs[0]) === null || _a === void 0 ? void 0 : _a.getMeta(plugin);
if ((prev === null || prev === void 0 ? void 0 : prev.next) || (meta === null || meta === void 0 ? void 0 : meta.action) === "click") {
return stepOutside(newState, getMarkType(newState, opts));
}
return null;
},
state: {
init: () => null,
apply(tr, value, oldState, state) {
var _a;
const meta = tr.getMeta(plugin);
if ((meta === null || meta === void 0 ? void 0 : meta.action) === "next")
return { next: true };
const markType = getMarkType(state, opts);
const nextMark = markType.isInSet((_a = state.storedMarks) !== null && _a !== void 0 ? _a : state.doc.resolve(tr.selection.from).marks());
const inCode = markType.isInSet(state.doc.resolve(tr.selection.from).marks());
const nextCode = markType.isInSet(safeResolve(state.doc, tr.selection.from + 1).marks());
const startOfLine = tr.selection.$from.parentOffset === 0;
if (!tr.selection.empty)
return null;
if (!nextMark && nextCode && (!inCode || startOfLine)) {
return { active: true, side: -1 };
}
if (nextMark && (!inCode || startOfLine)) {
return { active: true, side: 0 };
}
if (!nextMark && inCode && !nextCode) {
return { active: true, side: 0 };
}
if (nextMark && inCode && !nextCode) {
return { active: true, side: -1 };
}
return null;
}
},
props: {
attributes: (state) => {
var _a;
const { active = false } = (_a = plugin.getState(state)) !== null && _a !== void 0 ? _a : {};
return Object.assign({}, active ? { class: "no-cursor" } : {});
},
decorations: (state) => {
var _a;
const { active, side } = (_a = plugin.getState(state)) !== null && _a !== void 0 ? _a : {};
if (!active)
return DecorationSet.empty;
const deco = Decoration.widget(state.selection.from, toDom, { side });
return DecorationSet.create(state.doc, [deco]);
},
handleKeyDown(view, event) {
switch (event.key) {
case "`":
return onBacktick(view, plugin, event, getMarkType(view, opts));
case "ArrowRight":
return onArrowRight(view, plugin, event, getMarkType(view, opts));
case "ArrowLeft":
return onArrowLeft(view, plugin, event, getMarkType(view, opts));
case "Backspace":
return onBackspace(view, plugin, event, getMarkType(view, opts));
case "Delete":
return onDelete(view, plugin, event, getMarkType(view, opts));
case "ArrowUp":
case "ArrowDown":
case "Home":
case "End":
return stepOutsideNextTrAndPass(view, plugin);
case "e":
case "a":
if (!event.ctrlKey)
return false;
return stepOutsideNextTrAndPass(view, plugin);
default:
return false;
}
},
handleClick(view) {
return stepOutsideNextTrAndPass(view, plugin, "click");
}
}
});
return plugin;
}
function codemark(opts) {
const cursorPlugin = getDecorationPlugin(opts);
const inputRule = createInputRule(cursorPlugin, opts);
const rules = [cursorPlugin, inputRule];
return rules;
}
// node_modules/.pnpm/prosemirror-codemark@0.4.2_prosemirror-inputrules@1.4.0_prosemirror-model@1.23.0_prosemirror-_rwgskrtfqtz7desswyga6gztka/node_modules/prosemirror-codemark/dist/esm/index.js
var esm_default = codemark;
// src/exports/extensions/codemark-plugin.ts
var CodemarkPlugin = Extension.create({
name: "rhino-codemark-plugin",
addProseMirrorPlugins() {
return esm_default({ markType: this.editor.schema.marks.code });
}
});
export {
CodemarkPlugin
};
//# sourceMappingURL=chunk-W43LLTN2.js.map