@milkdown/prose
Advanced tools
Comparing version 7.3.2 to 7.3.3
import { InputRule } from 'prosemirror-inputrules'; | ||
import { PluginKey, Plugin, Transaction, Selection } from 'prosemirror-state'; | ||
import { MarkType, NodeType, Node, Schema, ResolvedPos } from 'prosemirror-model'; | ||
import { Attrs, MarkType, NodeType, Node, Schema, ResolvedPos } from 'prosemirror-model'; | ||
import { EditorView } from 'prosemirror-view'; | ||
@@ -40,4 +40,24 @@ | ||
declare function markRule(regexp: RegExp, markType: MarkType): InputRule; | ||
interface Captured { | ||
group: string | undefined; | ||
fullMatch: string; | ||
start: number; | ||
end: number; | ||
} | ||
interface BeforeDispatch { | ||
match: string[]; | ||
start: number; | ||
end: number; | ||
tr: Transaction; | ||
} | ||
interface Options { | ||
getAttr?: (match: RegExpMatchArray) => Attrs; | ||
updateCaptured?: (captured: Captured) => Partial<Captured>; | ||
beforeDispatch?: (options: BeforeDispatch) => void; | ||
} | ||
declare function markRule(regexp: RegExp, markType: MarkType, options?: Options): InputRule; | ||
declare function nodeRule(regexp: RegExp, nodeType: NodeType, options?: Options): InputRule; | ||
type Point = [top: number, left: number]; | ||
@@ -80,3 +100,3 @@ declare function calculateNodePosition(view: EditorView, target: HTMLElement, handler: (selectedRect: DOMRect, targetRect: DOMRect, parentRect: DOMRect) => Point): void; | ||
export { type ContentNodeWithPos, type NodeWithPos, browser, calculateNodePosition, calculateTextPosition, cloneTr, customInputRules, customInputRulesKey, equalNodeType, findChildren, findChildrenByMark, findParentNode, findParentNodeClosestToPos, findSelectedNodeOfType, flatten, getMarkFromSchema, getNodeFromSchema, markRule, posToDOMRect }; | ||
export { type BeforeDispatch, type Captured, type ContentNodeWithPos, type NodeWithPos, type Options, browser, calculateNodePosition, calculateTextPosition, cloneTr, customInputRules, customInputRulesKey, equalNodeType, findChildren, findChildrenByMark, findParentNode, findParentNodeClosestToPos, findSelectedNodeOfType, flatten, getMarkFromSchema, getNodeFromSchema, markRule, nodeRule, posToDOMRect }; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -102,44 +102,70 @@ import { PluginKey, Plugin, NodeSelection } from 'prosemirror-state'; | ||
function markRule(regexp, markType) { | ||
function markRule(regexp, markType, options = {}) { | ||
return new InputRule(regexp, (state, match, start, end) => { | ||
var _a, _b, _c, _d; | ||
const { tr } = state; | ||
const matchLength = match.length; | ||
let markStart = start; | ||
let group = match[matchLength - 1]; | ||
let fullMatch = match[0]; | ||
let initialStoredMarks = []; | ||
let markEnd = end; | ||
if (match[matchLength - 1]) { | ||
const first = match[0]; | ||
const last = match[matchLength - 1]; | ||
const last1 = match[matchLength - 2]; | ||
const matchStart = start + first.indexOf(last1); | ||
const matchEnd = matchStart + last1.length - 1; | ||
const textStart = matchStart + last1.lastIndexOf(last); | ||
const textEnd = textStart + last.length; | ||
const excludedMarks = getMarksBetween(start, end, state).filter((item) => item.mark.type.excludes(markType)).filter((item) => item.end > matchStart); | ||
if (excludedMarks.length) | ||
return null; | ||
if (textEnd < matchEnd) | ||
tr.delete(textEnd, matchEnd); | ||
if (textStart > matchStart) | ||
tr.delete(matchStart, textStart); | ||
markStart = matchStart; | ||
markEnd = markStart + last.length; | ||
const captured = { | ||
group, | ||
fullMatch, | ||
start, | ||
end | ||
}; | ||
const result = (_a = options.updateCaptured) == null ? void 0 : _a.call(options, captured); | ||
Object.assign(captured, result); | ||
({ group, fullMatch, start, end } = captured); | ||
if (fullMatch === null) | ||
return null; | ||
if ((group == null ? void 0 : group.trim()) === "") | ||
return null; | ||
if (group) { | ||
const startSpaces = fullMatch.search(/\S/); | ||
const textStart = start + fullMatch.indexOf(group); | ||
const textEnd = textStart + group.length; | ||
initialStoredMarks = (_b = tr.storedMarks) != null ? _b : []; | ||
if (textEnd < end) | ||
tr.delete(textEnd, end); | ||
if (textStart > start) | ||
tr.delete(start + startSpaces, textStart); | ||
markEnd = start + startSpaces + group.length; | ||
const attrs = (_c = options.getAttr) == null ? void 0 : _c.call(options, match); | ||
tr.addMark(start, markEnd, markType.create(attrs)); | ||
tr.setStoredMarks(initialStoredMarks); | ||
(_d = options.beforeDispatch) == null ? void 0 : _d.call(options, { match, start, end, tr }); | ||
} | ||
tr.addMark(markStart, markEnd, markType.create()); | ||
tr.removeStoredMark(markType); | ||
return tr; | ||
}); | ||
} | ||
function getMarksBetween(start, end, state) { | ||
let marks = []; | ||
state.doc.nodesBetween(start, end, (node, pos) => { | ||
marks = [ | ||
...marks, | ||
...node.marks.map((mark) => ({ | ||
start: pos, | ||
end: pos + node.nodeSize, | ||
mark | ||
})) | ||
]; | ||
function nodeRule(regexp, nodeType, options = {}) { | ||
return new InputRule(regexp, (state, match, start, end) => { | ||
var _a, _b, _c; | ||
const { tr } = state; | ||
let group = match[1]; | ||
let fullMatch = match[0]; | ||
const captured = { | ||
group, | ||
fullMatch, | ||
start, | ||
end | ||
}; | ||
const result = (_a = options.updateCaptured) == null ? void 0 : _a.call(options, captured); | ||
Object.assign(captured, result); | ||
({ group, fullMatch, start, end } = captured); | ||
if (fullMatch === null) | ||
return null; | ||
if (!group || group.trim() === "") | ||
return null; | ||
const attrs = (_b = options.getAttr) == null ? void 0 : _b.call(options, match); | ||
const node = nodeType.createAndFill(attrs); | ||
if (node) { | ||
tr.replaceRangeWith(nodeType.isBlock ? tr.doc.resolve(start).before() : start, end, node); | ||
(_c = options.beforeDispatch) == null ? void 0 : _c.call(options, { match: [fullMatch, group != null ? group : ""], start, end, tr }); | ||
} | ||
return tr; | ||
}); | ||
return marks; | ||
} | ||
@@ -297,3 +323,3 @@ | ||
export { browser, calculateNodePosition, calculateTextPosition, cloneTr, customInputRules, customInputRulesKey, equalNodeType, findChildren, findChildrenByMark, findParentNode, findParentNodeClosestToPos, findSelectedNodeOfType, flatten, getMarkFromSchema, getNodeFromSchema, markRule, posToDOMRect }; | ||
export { browser, calculateNodePosition, calculateTextPosition, cloneTr, customInputRules, customInputRulesKey, equalNodeType, findChildren, findChildrenByMark, findParentNode, findParentNodeClosestToPos, findSelectedNodeOfType, flatten, getMarkFromSchema, getNodeFromSchema, markRule, nodeRule, posToDOMRect }; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@milkdown/prose", | ||
"type": "module", | ||
"version": "7.3.2", | ||
"version": "7.3.3", | ||
"license": "MIT", | ||
@@ -70,46 +70,2 @@ "repository": { | ||
"main": "./lib/index.js", | ||
"types": "./lib/index.d.ts", | ||
"typesVersions": { | ||
"*": { | ||
"changeset": [ | ||
"lib/changeset.d.ts" | ||
], | ||
"commands": [ | ||
"lib/commands.d.ts" | ||
], | ||
"dropcursor": [ | ||
"lib/dropcursor.d.ts" | ||
], | ||
"gapcursor": [ | ||
"lib/gapcursor.d.ts" | ||
], | ||
"history": [ | ||
"lib/history.d.ts" | ||
], | ||
"inputrules": [ | ||
"lib/inputrules.d.ts" | ||
], | ||
"keymap": [ | ||
"lib/keymap.d.ts" | ||
], | ||
"model": [ | ||
"lib/model.d.ts" | ||
], | ||
"schema-list": [ | ||
"lib/schema-list.d.ts" | ||
], | ||
"state": [ | ||
"lib/state.d.ts" | ||
], | ||
"transform": [ | ||
"lib/transform.d.ts" | ||
], | ||
"view": [ | ||
"lib/view.d.ts" | ||
], | ||
"tables": [ | ||
"lib/tables.d.ts" | ||
] | ||
} | ||
}, | ||
"files": [ | ||
@@ -134,3 +90,3 @@ "lib", | ||
"tslib": "^2.5.0", | ||
"@milkdown/exception": "7.3.2" | ||
"@milkdown/exception": "7.3.3" | ||
}, | ||
@@ -166,3 +122,47 @@ "nx": { | ||
"build": "rollup -c && echo" | ||
}, | ||
"types": "./lib/index.d.ts", | ||
"typesVersions": { | ||
"*": { | ||
"changeset": [ | ||
"lib/changeset.d.ts" | ||
], | ||
"commands": [ | ||
"lib/commands.d.ts" | ||
], | ||
"dropcursor": [ | ||
"lib/dropcursor.d.ts" | ||
], | ||
"gapcursor": [ | ||
"lib/gapcursor.d.ts" | ||
], | ||
"history": [ | ||
"lib/history.d.ts" | ||
], | ||
"inputrules": [ | ||
"lib/inputrules.d.ts" | ||
], | ||
"keymap": [ | ||
"lib/keymap.d.ts" | ||
], | ||
"model": [ | ||
"lib/model.d.ts" | ||
], | ||
"schema-list": [ | ||
"lib/schema-list.d.ts" | ||
], | ||
"state": [ | ||
"lib/state.d.ts" | ||
], | ||
"transform": [ | ||
"lib/transform.d.ts" | ||
], | ||
"view": [ | ||
"lib/view.d.ts" | ||
], | ||
"tables": [ | ||
"lib/tables.d.ts" | ||
] | ||
} | ||
} | ||
} |
/* Copyright 2021, Milkdown by Mirone. */ | ||
export * from './custom-input-rules' | ||
export * from './mark-rule' | ||
export * from './node-rule' | ||
export * from './common' |
/* Copyright 2021, Milkdown by Mirone. */ | ||
import { InputRule } from '../../inputrules' | ||
import type { Mark, MarkType } from '../../model' | ||
import type { EditorState } from '../../state' | ||
import type { Captured, Options } from './common' | ||
export function markRule(regexp: RegExp, markType: MarkType): InputRule { | ||
/// Create an input rule for a mark. | ||
export function markRule(regexp: RegExp, markType: MarkType, options: Options = {}): InputRule { | ||
return new InputRule(regexp, (state, match, start, end) => { | ||
@@ -11,52 +12,51 @@ const { tr } = state | ||
let markStart = start | ||
let group = match[matchLength - 1] | ||
let fullMatch = match[0] | ||
let initialStoredMarks: readonly Mark[] = [] | ||
let markEnd = end | ||
if (match[matchLength - 1]) { | ||
const first = match[0] | ||
const last = match[matchLength - 1] as string | ||
const last1 = match[matchLength - 2] as string | ||
const captured: Captured = { | ||
group, | ||
fullMatch, | ||
start, | ||
end, | ||
} | ||
const matchStart = start + first.indexOf(last1) | ||
const matchEnd = matchStart + last1.length - 1 | ||
const textStart = matchStart + last1.lastIndexOf(last) | ||
const textEnd = textStart + last.length | ||
const result = options.updateCaptured?.(captured) | ||
Object.assign(captured, result); | ||
const excludedMarks = getMarksBetween(start, end, state) | ||
.filter(item => item.mark.type.excludes(markType)) | ||
.filter(item => item.end > matchStart) | ||
({ group, fullMatch, start, end } = captured) | ||
if (excludedMarks.length) | ||
return null | ||
if (fullMatch === null) | ||
return null | ||
if (textEnd < matchEnd) | ||
tr.delete(textEnd, matchEnd) | ||
if (group?.trim() === '') | ||
return null | ||
if (textStart > matchStart) | ||
tr.delete(matchStart, textStart) | ||
if (group) { | ||
const startSpaces = fullMatch.search(/\S/) | ||
const textStart = start + fullMatch.indexOf(group) | ||
const textEnd = textStart + group.length | ||
markStart = matchStart | ||
markEnd = markStart + last.length | ||
initialStoredMarks = tr.storedMarks ?? [] | ||
if (textEnd < end) | ||
tr.delete(textEnd, end) | ||
if (textStart > start) | ||
tr.delete(start + startSpaces, textStart) | ||
markEnd = start + startSpaces + group.length | ||
const attrs = options.getAttr?.(match) | ||
tr.addMark(start, markEnd, markType.create(attrs)) | ||
tr.setStoredMarks(initialStoredMarks) | ||
options.beforeDispatch?.({ match, start, end, tr }) | ||
} | ||
tr.addMark(markStart, markEnd, markType.create()) | ||
tr.removeStoredMark(markType) | ||
return tr | ||
}) | ||
} | ||
function getMarksBetween(start: number, end: number, state: EditorState) { | ||
let marks: { start: number, end: number, mark: Mark }[] = [] | ||
state.doc.nodesBetween(start, end, (node, pos) => { | ||
marks = [ | ||
...marks, | ||
...node.marks.map(mark => ({ | ||
start: pos, | ||
end: pos + node.nodeSize, | ||
mark, | ||
})), | ||
] | ||
}) | ||
return marks | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
68922
90
962
71
1
1
1
7
+ Added@milkdown/exception@7.3.3(transitive)
- Removed@milkdown/exception@7.3.2(transitive)
Updated@milkdown/exception@7.3.3