Socket
Socket
Sign inDemoInstall

@remirror/extension-mention

Package Overview
Dependencies
222
Maintainers
2
Versions
324
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 2.0.15 to 3.0.0-beta.0

dist/_tsup-dts-rollup.d.cts

263

dist/remirror-extension-mention.d.ts

@@ -1,252 +0,11 @@

import { Static, Handler, GetMarkRange, MarkExtension, ApplySchemaAttributes, MarkSpecOverride, MarkExtensionSpec, CommandFunction, RangeProps, ProsemirrorAttributes } from '@remirror/core';
import { CreateEventHandlers } from '@remirror/extension-events';
import { MarkPasteRule } from '@remirror/pm/paste-rules';
import { Suggester, SuggestChangeHandlerProps, RangeWithCursor, MatchValue } from '@remirror/pm/suggest';
/**
* The static settings passed into a mention
*/
interface MentionOptions extends Pick<Suggester, 'invalidNodes' | 'validNodes' | 'invalidMarks' | 'validMarks' | 'isValidPosition' | 'disableDecorations'> {
/**
* Provide a custom tag for the mention
*/
mentionTag?: Static<string>;
/**
* Provide the custom matchers that will be used to match mention text in the
* editor.
*/
matchers: Static<MentionExtensionMatcher[]>;
/**
* Text to append after the mention has been added.
*
* **NOTE**: If you're using whitespace characters but it doesn't seem to work
* for you make sure you're using the css provided in `@remirror/styles`.
*
* The `white-space: pre-wrap;` is what allows editors to add space characters
* at the end of a section.
*
* @defaultValue ''
*/
appendText?: string;
/**
* Tag for the prosemirror decoration which wraps an active match.
*
* @defaultValue 'span'
*/
suggestTag?: string;
/**
* Called whenever a suggestion becomes active or changes in any way.
*
* @remarks
*
* It receives a parameters object with the `reason` for the change for more
* granular control.
*
* The second parameter is a function that can be called to handle exits
* automatically. This is useful if you're mention can be any possible value,
* e.g. a `#hashtag`. Call it with the optional attributes to automatically
* create a mention.
*
* @defaultValue () => void
*/
onChange?: Handler<MentionChangeHandler>;
/**
* Listen for click events to the mention extension.
*/
onClick?: Handler<(event: MouseEvent, markRange: GetMarkRange) => boolean | undefined | void>;
/**
* A predicate check for whether the mention is valid. It proves the mention
* mark and it's attributes as well as the text it contains.
*
* This is used for checking that a recent update to the document hasn't made
* a mention invalid.
*
* For example a mention for `@valid` => `valid` would be considered
* invalidating. Return false to remove the mention.
*
* @param attrs - the attrs for the mention
* @param text - the text which is wrapped by the mention
*/
isMentionValid?: (attrs: NamedMentionExtensionAttributes, text: string) => boolean;
}
/**
* The mention extension wraps mentions as a prosemirror mark. It allows for
* fluid social experiences to be built. The implementation was inspired by the
* way twitter and similar social sites allows mentions to be edited after
* they've been created.
*
* @remarks
*
* Mentions have the following features
* - An activation character or regex pattern which you define.
* - A min number of characters before mentions are suggested
* - Ability to exclude matching character.
* - Ability to wrap content in a decoration which excludes mentions from being
* suggested.
* - Decorations for in-progress mentions
*/
declare class MentionExtension extends MarkExtension<MentionOptions> {
get name(): "mention";
/**
* Tag this as a behavior influencing mark.
*/
createTags(): ("behavior" | "excludeFromInputRules")[];
createMarkSpec(extra: ApplySchemaAttributes, override: MarkSpecOverride): MarkExtensionSpec;
onCreate(): void;
/**
* Track click events passed through to the editor.
*/
createEventHandlers(): CreateEventHandlers;
/**
* Manages the paste rules for the mention.
*
* It creates regex tests for each of the configured matchers.
*/
createPasteRules(): MarkPasteRule[];
/**
* Create the suggesters from the matchers that were passed into the editor.
*/
createSuggesters(): Suggester[];
/**
* This is the command which can be called from the `onChange` handler to
* automatically handle exits for you. It decides whether a mention should
* be updated, removed or created and also handles invalid splits.
*
* It does nothing for changes and only acts when an exit occurred.
*
* @param handler - the parameter that was passed through to the
* `onChange` handler.
* @param attrs - the options which set the values that will be used (in
* case you want to override the defaults).
*/
mentionExitHandler(handler: SuggestChangeHandlerProps, attrs?: MentionChangeHandlerCommandAttributes): CommandFunction;
/**
* Create a new mention
*/
createMention(config: NamedMentionExtensionAttributes & KeepSelectionProps): CommandFunction;
/**
* Update an existing mention.
*/
updateMention(config: NamedMentionExtensionAttributes & KeepSelectionProps): CommandFunction;
/**
* Remove the mention(s) at the current selection or provided range.
*/
removeMention({ range }?: Partial<RangeProps>): CommandFunction;
/**
* The factory method for mention commands to update and create new mentions.
*/
private createMentionFactory;
private shouldSkipInputRule;
/**
* Check whether the mark is active within the provided start and end range.
*/
private isMatcherActive;
}
interface OptionalMentionExtensionProps {
/**
* The text to append to the replacement.
*
* @defaultValue ''
*/
appendText?: string;
/**
* The range of the requested selection.
*/
range?: RangeWithCursor;
/**
* Whether to replace the whole match (`full`) or just the part up until the
* cursor (`partial`).
*/
replacementType?: keyof MatchValue;
}
interface KeepSelectionProps {
/**
* Whether to preserve the original selection after the replacement has
* occurred.
*/
keepSelection?: boolean;
}
/**
* The attrs that will be added to the node. ID and label are plucked and used
* while attributes like href and role can be assigned as desired.
*/
type MentionExtensionAttributes = ProsemirrorAttributes<OptionalMentionExtensionProps & {
/**
* A unique identifier for the suggesters node
*/
id: string;
/**
* The text to be placed within the suggesters node
*/
label: string;
}>;
type NamedMentionExtensionAttributes = ProsemirrorAttributes<OptionalMentionExtensionProps & {
/**
* A unique identifier for the suggesters node
*/
id: string;
/**
* The text to be placed within the suggesters node
*/
label: string;
} & {
/**
* The identifying name for the active matcher. This is stored as an
* attribute on the HTML that will be produced
*/
name: string;
}>;
/**
* The options for the matchers which can be created by this extension.
*/
interface MentionExtensionMatcher extends Pick<Suggester, 'char' | 'name' | 'startOfLine' | 'supportedCharacters' | 'validPrefixCharacters' | 'invalidPrefixCharacters' | 'matchOffset' | 'suggestClassName'> {
/**
* Provide customs class names for the completed mention
*/
mentionClassName?: string;
/**
* Text to append after the suggestion has been added.
*
* @defaultValue ''
*/
appendText?: string;
}
type MentionChangeHandlerCommand = (attrs?: MentionChangeHandlerCommandAttributes) => void;
interface MentionChangeHandlerProps extends SuggestChangeHandlerProps {
/**
* The default text to be appended if text should be appended.
*/
defaultAppendTextValue: string;
}
/**
* A handler that will be called whenever the the active matchers are updated or
* exited. The second argument which is the exit command is a function which is
* only available when the matching suggester has been exited.
*/
type MentionChangeHandler = (handlerState: MentionChangeHandlerProps, command: (attrs?: MentionChangeHandlerCommandAttributes) => void) => void;
/**
* The dynamic properties used to change the behavior of the mentions created.
*/
type MentionChangeHandlerCommandAttributes = ProsemirrorAttributes<Partial<Pick<MentionExtensionAttributes, 'appendText' | 'replacementType'>> & {
/**
* The ID to apply the mention.
*
* @defaultValue query.full
*/
id?: string;
/**
* The text that is displayed within the mention bounds.
*
* @defaultValue text.full
*/
label?: string;
}>;
declare global {
namespace Remirror {
interface AllExtensions {
mention: MentionExtension;
}
}
}
export { MentionChangeHandler, MentionChangeHandlerCommand, MentionChangeHandlerCommandAttributes, MentionExtension, MentionExtensionAttributes, MentionExtensionMatcher, MentionOptions, NamedMentionExtensionAttributes, OptionalMentionExtensionProps };
export { MentionChangeHandler } from './_tsup-dts-rollup';
export { MentionChangeHandlerCommand } from './_tsup-dts-rollup';
export { MentionChangeHandlerCommandAttributes } from './_tsup-dts-rollup';
export { MentionExtensionAttributes } from './_tsup-dts-rollup';
export { MentionExtensionMatcher } from './_tsup-dts-rollup';
export { MentionOptions } from './_tsup-dts-rollup';
export { NamedMentionExtensionAttributes } from './_tsup-dts-rollup';
export { OptionalMentionExtensionProps } from './_tsup-dts-rollup';
export { MentionExtension } from './_tsup-dts-rollup';
export { isMentionValidDefault } from './_tsup-dts-rollup';
export { MentionChangeHandlerProps } from './_tsup-dts-rollup';

@@ -1,43 +0,52 @@

var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __decorateClass = (decorators, target, key, kind) => {
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
for (var i = decorators.length - 1, decorator; i >= 0; i--)
if (decorator = decorators[i])
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
if (kind && result)
__defProp(target, key, result);
return result;
};
// packages/remirror__extension-mention/src/mention-extension.ts
import {
command,
ErrorConstant,
extension,
ExtensionTag,
getMarkRange,
getMatchString,
InputRulesExtension,
invariant,
isElementDomNode,
isMarkActive,
isPlainObject,
isString,
LEAF_NODE_REPLACING_CHARACTER,
MarkExtension,
omitExtraAttributes,
pick,
removeMark,
replaceText
} from "@remirror/core";
import {
createRegexFromSuggester,
DEFAULT_SUGGESTER,
isInvalidSplitReason,
isRemovedReason,
isSelectionExitReason,
isSplitReason
} from "@remirror/pm/suggest";
var MentionExtension = class extends MarkExtension {
var _initClass, _MentionExtension, _dec, _dec2, _dec3, _dec4, _dec5, _initProto;
function createAddInitializerMethod(e, t) { return function (r) { assertNotFinished(t, "addInitializer"), assertCallable(r, "An initializer"), e.push(r); }; }
function assertInstanceIfPrivate(e, t) { if (!e(t)) throw new TypeError("Attempted to access private element on non-instance"); }
function memberDec(e, t, r, a, n, i, s, o, c, l, u) { var f; switch (i) { case 1: f = "accessor"; break; case 2: f = "method"; break; case 3: f = "getter"; break; case 4: f = "setter"; break; default: f = "field"; } var d, p, h = { kind: f, name: o ? "#" + r : r, static: s, private: o, metadata: u }, v = { v: !1 }; if (0 !== i && (h.addInitializer = createAddInitializerMethod(n, v)), o || 0 !== i && 2 !== i) { if (2 === i) d = function (e) { return assertInstanceIfPrivate(l, e), a.value; };else { var y = 0 === i || 1 === i; (y || 3 === i) && (d = o ? function (e) { return assertInstanceIfPrivate(l, e), a.get.call(e); } : function (e) { return a.get.call(e); }), (y || 4 === i) && (p = o ? function (e, t) { assertInstanceIfPrivate(l, e), a.set.call(e, t); } : function (e, t) { a.set.call(e, t); }); } } else d = function (e) { return e[r]; }, 0 === i && (p = function (e, t) { e[r] = t; }); var m = o ? l.bind() : function (e) { return r in e; }; h.access = d && p ? { get: d, set: p, has: m } : d ? { get: d, has: m } : { set: p, has: m }; try { return e.call(t, c, h); } finally { v.v = !0; } }
function assertNotFinished(e, t) { if (e.v) throw new Error("attempted to call " + t + " after decoration was finished"); }
function assertCallable(e, t) { if ("function" != typeof e) throw new TypeError(t + " must be a function"); }
function assertValidReturnValue(e, t) { var r = typeof t; if (1 === e) { if ("object" !== r || null === t) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0"); void 0 !== t.get && assertCallable(t.get, "accessor.get"), void 0 !== t.set && assertCallable(t.set, "accessor.set"), void 0 !== t.init && assertCallable(t.init, "accessor.init"); } else if ("function" !== r) { var a; throw a = 0 === e ? "field" : 5 === e ? "class" : "method", new TypeError(a + " decorators must return a function or void 0"); } }
function curryThis1(e) { return function () { return e(this); }; }
function curryThis2(e) { return function (t) { e(this, t); }; }
function applyMemberDec(e, t, r, a, n, i, s, o, c, l, u) { var f, d, p, h, v, y, m = r[0]; a || Array.isArray(m) || (m = [m]), o ? f = 0 === i || 1 === i ? { get: curryThis1(r[3]), set: curryThis2(r[4]) } : 3 === i ? { get: r[3] } : 4 === i ? { set: r[3] } : { value: r[3] } : 0 !== i && (f = Object.getOwnPropertyDescriptor(t, n)), 1 === i ? p = { get: f.get, set: f.set } : 2 === i ? p = f.value : 3 === i ? p = f.get : 4 === i && (p = f.set); for (var g = a ? 2 : 1, b = m.length - 1; b >= 0; b -= g) { var I; if (void 0 !== (h = memberDec(m[b], a ? m[b - 1] : void 0, n, f, c, i, s, o, p, l, u))) assertValidReturnValue(i, h), 0 === i ? I = h : 1 === i ? (I = h.init, v = h.get || p.get, y = h.set || p.set, p = { get: v, set: y }) : p = h, void 0 !== I && (void 0 === d ? d = I : "function" == typeof d ? d = [d, I] : d.push(I)); } if (0 === i || 1 === i) { if (void 0 === d) d = function (e, t) { return t; };else if ("function" != typeof d) { var w = d; d = function (e, t) { for (var r = t, a = w.length - 1; a >= 0; a--) r = w[a].call(e, r); return r; }; } else { var M = d; d = function (e, t) { return M.call(e, t); }; } e.push(d); } 0 !== i && (1 === i ? (f.get = p.get, f.set = p.set) : 2 === i ? f.value = p : 3 === i ? f.get = p : 4 === i && (f.set = p), o ? 1 === i ? (e.push(function (e, t) { return p.get.call(e, t); }), e.push(function (e, t) { return p.set.call(e, t); })) : 2 === i ? e.push(p) : e.push(function (e, t) { return p.call(e, t); }) : Object.defineProperty(t, n, f)); }
function applyMemberDecs(e, t, r, a) { for (var n, i, s, o = [], c = new Map(), l = new Map(), u = 0; u < t.length; u++) { var f = t[u]; if (Array.isArray(f)) { var d, p, h = f[1], v = f[2], y = f.length > 3, m = 16 & h, g = !!(8 & h), b = r; if (h &= 7, g ? (d = e, 0 !== h && (p = i = i || []), y && !s && (s = function (t) { return _checkInRHS(t) === e; }), b = s) : (d = e.prototype, 0 !== h && (p = n = n || [])), 0 !== h && !y) { var I = g ? l : c, w = I.get(v) || 0; if (!0 === w || 3 === w && 4 !== h || 4 === w && 3 !== h) throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + v); I.set(v, !(!w && h > 2) || h); } applyMemberDec(o, d, f, m, v, h, g, y, p, b, a); } } return pushInitializers(o, n), pushInitializers(o, i), o; }
function pushInitializers(e, t) { t && e.push(function (e) { for (var r = 0; r < t.length; r++) t[r].call(e); return e; }); }
function applyClassDecs(e, t, r, a) { if (t.length) { for (var n = [], i = e, s = e.name, o = r ? 2 : 1, c = t.length - 1; c >= 0; c -= o) { var l = { v: !1 }; try { var u = t[c].call(r ? t[c - 1] : void 0, i, { kind: "class", name: s, addInitializer: createAddInitializerMethod(n, l), metadata: a }); } finally { l.v = !0; } void 0 !== u && (assertValidReturnValue(5, u), i = u); } return [defineMetadata(i, a), function () { for (var e = 0; e < n.length; e++) n[e].call(i); }]; } }
function defineMetadata(e, t) { return Object.defineProperty(e, Symbol.metadata || Symbol.for("Symbol.metadata"), { configurable: !0, enumerable: !0, value: t }); }
function _applyDecs(e, t, r, a, n, i) { if (arguments.length >= 6) var s = i[Symbol.metadata || Symbol.for("Symbol.metadata")]; var o = Object.create(void 0 === s ? null : s), c = applyMemberDecs(e, t, n, o); return r.length || defineMetadata(e, o), { e: c, get c() { return applyClassDecs(e, r, a, o); } }; }
function _checkInRHS(e) { if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null")); return e; }
// src/mention-extension.ts
import { command, ErrorConstant, extension, ExtensionTag, getMarkRange, getMatchString, InputRulesExtension, invariant, isElementDomNode, isMarkActive, isPlainObject, isString, LEAF_NODE_REPLACING_CHARACTER, MarkExtension, omitExtraAttributes, pick, removeMark, replaceText } from "@remirror/core";
import { createRegexFromSuggester, DEFAULT_SUGGESTER, isInvalidSplitReason, isRemovedReason, isSelectionExitReason, isSplitReason } from "@remirror/pm/suggest";
var MentionExtension = ((_dec = extension({
defaultOptions: {
mentionTag: "a",
matchers: [],
appendText: "",
suggestTag: "a",
disableDecorations: false,
invalidMarks: [],
invalidNodes: [],
isValidPosition: () => true,
validMarks: null,
validNodes: null,
isMentionValid: isMentionValidDefault
},
handlerKeyOptions: {
onClick: {
earlyReturnValue: true
}
},
handlerKeys: ["onChange", "onClick"],
staticKeys: ["mentionTag", "matchers"]
}), _dec2 = command(), _dec3 = command(), _dec4 = command(), _dec5 = command(), class MentionExtension extends MarkExtension {
static {
({
e: [_initProto],
c: [_MentionExtension, _initClass]
} = _applyDecs(this, [[_dec2, 2, "mentionExitHandler"], [_dec3, 2, "createMention"], [_dec4, 2, "updateMention"], [_dec5, 2, "removeMention"]], [_dec]));
}
constructor(...args) {
super(...args);
_initProto(this);
}
get name() {

@@ -65,31 +74,32 @@ return "mention";

},
parseDOM: [
{
tag: `${this.options.mentionTag}[${dataAttributeId}]`,
getAttrs: (element) => {
if (!isElementDomNode(element)) {
return false;
}
const id = element.getAttribute(dataAttributeId);
const name = element.getAttribute(dataAttributeName);
const label = element.textContent;
return { ...extra.parse(element), id, label, name };
parseDOM: [{
tag: `${this.options.mentionTag}[${dataAttributeId}]`,
getAttrs: element => {
if (!isElementDomNode(element)) {
return false;
}
},
...override.parseDOM ?? []
],
toDOM: (mark) => {
const { id, name } = omitExtraAttributes(mark.attrs, extra);
const matcher = this.options.matchers.find((matcher2) => matcher2.name === name);
const id = element.getAttribute(dataAttributeId);
const name = element.getAttribute(dataAttributeName);
const label = element.textContent;
return {
...extra.parse(element),
id,
label,
name
};
}
}, ...(override.parseDOM ?? [])],
toDOM: mark => {
const {
id,
name
} = omitExtraAttributes(mark.attrs, extra);
const matcher = this.options.matchers.find(matcher2 => matcher2.name === name);
const mentionClassName = matcher ? matcher.mentionClassName ?? DEFAULT_MATCHER.mentionClassName : DEFAULT_MATCHER.mentionClassName;
return [
this.options.mentionTag,
{
...extra.dom(mark),
class: name ? `${mentionClassName} ${mentionClassName}-${name}` : mentionClassName,
[dataAttributeId]: id,
[dataAttributeName]: name
},
0
];
return [this.options.mentionTag, {
...extra.dom(mark),
class: name ? `${mentionClassName} ${mentionClassName}-${name}` : mentionClassName,
[dataAttributeId]: id,
[dataAttributeName]: name
}, 0];
}

@@ -121,19 +131,22 @@ };

createPasteRules() {
return this.options.matchers.map((matcher) => {
const { startOfLine, char, supportedCharacters, name, matchOffset } = {
return this.options.matchers.map(matcher => {
const {
startOfLine,
char,
supportedCharacters,
name,
matchOffset
} = {
...DEFAULT_MATCHER,
...matcher
};
const regexp = new RegExp(
`(${createRegexFromSuggester({
char,
matchOffset,
startOfLine,
supportedCharacters,
captureChar: true,
caseInsensitive: false,
multiline: false
}).source})`,
"g"
);
const regexp = new RegExp(`(${createRegexFromSuggester({
char,
matchOffset,
startOfLine,
supportedCharacters,
captureChar: true,
caseInsensitive: false,
multiline: false
}).source})`, "g");
return {

@@ -143,10 +156,7 @@ type: "mark",

markType: this.type,
getAttributes: (string) => {
var _a;
return {
id: getMatchString(string.slice((_a = string[2]) == null ? void 0 : _a.length, string.length)),
label: getMatchString(string),
name
};
}
getAttributes: string => ({
id: getMatchString(string.slice(string[2]?.length, string.length)),
label: getMatchString(string),
name
})
};

@@ -160,48 +170,35 @@ });

let cachedRange;
const options = pick(this.options, [
"invalidMarks",
"invalidNodes",
"isValidPosition",
"validMarks",
"validNodes",
"suggestTag",
"disableDecorations"
]);
return this.options.matchers.map((matcher) => {
return {
...DEFAULT_MATCHER,
...options,
...matcher,
onChange: (props) => {
const command2 = (attrs = {}) => {
this.mentionExitHandler(props, attrs)(this.store.helpers.getCommandProp());
};
this.options.onChange(
{ ...props, defaultAppendTextValue: this.options.appendText },
command2
);
},
checkNextValidSelection: ($pos, tr) => {
const range = getMarkRange($pos, this.type);
if (!range || range.from === (cachedRange == null ? void 0 : cachedRange.from) && range.to === (cachedRange == null ? void 0 : cachedRange.to)) {
return;
}
const text = $pos.doc.textBetween(
range.from,
range.to,
LEAF_NODE_REPLACING_CHARACTER,
" "
);
const isValidMention = isValidMentionAttributes(range.mark.attrs) && this.options.isMentionValid(range.mark.attrs, text);
if (isValidMention) {
return;
}
cachedRange = range;
return this.store.chain(tr).removeMention({ range }).tr();
const options = pick(this.options, ["invalidMarks", "invalidNodes", "isValidPosition", "validMarks", "validNodes", "suggestTag", "disableDecorations"]);
return this.options.matchers.map(matcher => ({
...DEFAULT_MATCHER,
...options,
...matcher,
onChange: props => {
const command2 = (attrs = {}) => {
this.mentionExitHandler(props, attrs)(this.store.helpers.getCommandProp());
};
this.options.onChange({
...props,
defaultAppendTextValue: this.options.appendText
}, command2);
},
checkNextValidSelection: ($pos, tr) => {
const range = getMarkRange($pos, this.type);
if (!range || range.from === cachedRange?.from && range.to === cachedRange?.to) {
return;
}
};
});
const text = $pos.doc.textBetween(range.from, range.to, LEAF_NODE_REPLACING_CHARACTER, " ");
const isValidMention = isValidMentionAttributes(range.mark.attrs) && this.options.isMentionValid(range.mark.attrs, text);
if (isValidMention) {
return;
}
cachedRange = range;
return this.store.chain(tr).removeMention({
range
}).tr();
}
}));
}
mentionExitHandler(handler, attrs = {}) {
return (props) => {
return props => {
const reason = handler.exitReason ?? handler.changeReason;

@@ -213,3 +210,5 @@ const isInvalid = isInvalidSplitReason(reason);

try {
return isInvalid && this.removeMention({ range: handler.range })(props);
return isInvalid && this.removeMention({
range: handler.range
})(props);
} catch {

@@ -219,6 +218,21 @@ return true;

}
const { tr } = props;
const { range, text, query, name } = handler;
const { from, to } = range;
const isActive = isMarkActive({ from, to, type: this.type, trState: tr });
const {
tr
} = props;
const {
range,
text,
query,
name
} = handler;
const {
from,
to
} = range;
const isActive = isMarkActive({
from,
to,
type: this.type,
trState: tr
});
const command2 = isActive ? this.updateMention.bind(this) : this.createMention.bind(this);

@@ -246,9 +260,15 @@ const {

createMention(config) {
return (props) => this.createMentionFactory(config, false)(props);
return props => this.createMentionFactory(config, false)(props);
}
updateMention(config) {
return (props) => this.createMentionFactory(config, true)(props);
return props => this.createMentionFactory(config, true)(props);
}
removeMention({ range } = {}) {
const value = removeMark({ type: this.type, expand: true, range });
removeMention({
range
} = {}) {
const value = removeMark({
type: this.type,
expand: true,
range
});
return value;

@@ -264,27 +284,51 @@ }

});
const { range, appendText, replacementType, keepSelection, name, ...attributes } = config;
const allowedNames = this.options.matchers.map(({ name: name2 }) => name2);
const {
range,
appendText,
replacementType,
keepSelection,
name,
...attributes
} = config;
const allowedNames = this.options.matchers.map(({
name: name2
}) => name2);
const matcher = getMatcher(name, this.options.matchers);
invariant(allowedNames.includes(name) && matcher, {
code: ErrorConstant.EXTENSION,
message: `The name '${name}' specified for this command is invalid. Please choose from: ${JSON.stringify(
allowedNames
)}.`
message: `The name '${name}' specified for this command is invalid. Please choose from: ${JSON.stringify(allowedNames)}.`
});
return (props) => {
const { tr } = props;
const { from, to } = {
from: (range == null ? void 0 : range.from) ?? tr.selection.from,
to: (range == null ? void 0 : range.cursor) ?? tr.selection.to
return props => {
const {
tr
} = props;
const {
from,
to
} = {
from: range?.from ?? tr.selection.from,
to: range?.cursor ?? tr.selection.to
};
if (shouldUpdate) {
let { oldFrom, oldTo } = { oldFrom: from, oldTo: range ? range.to : to };
let {
oldFrom,
oldTo
} = {
oldFrom: from,
oldTo: range ? range.to : to
};
const $oldTo = tr.doc.resolve(oldTo);
({ from: oldFrom, to: oldTo } = getMarkRange($oldTo, this.type) ?? {
({
from: oldFrom,
to: oldTo
} = getMarkRange($oldTo, this.type) ?? {
from: oldFrom,
to: oldTo
});
tr.removeMark(oldFrom, oldTo, this.type).setMeta("addToHistory", false);
const $newTo = tr.selection.$from;
const { from: newFrom, to: newTo } = getMarkRange($newTo, this.type) ?? {
const {
from: newFrom,
to: newTo
} = getMarkRange($newTo, this.type) ?? {
from: $newTo.pos,

@@ -298,5 +342,11 @@ to: $newTo.pos

type: this.type,
attrs: { ...attributes, name },
attrs: {
...attributes,
name
},
appendText: getAppendText(appendText, matcher.appendText),
range: range ? { from, to: replacementType === "full" ? range.to || to : to } : void 0,
range: range ? {
from,
to: replacementType === "full" ? range.to || to : to
} : void 0,
content: attributes.label

@@ -307,3 +357,8 @@ })(props);

shouldSkipInputRule(props) {
const { ruleType, state, end, start } = props;
const {
ruleType,
state,
end,
start
} = props;
if (ruleType === "node") {

@@ -313,8 +368,13 @@ return false;

if (
// Check if the mark for this mention is active anywhere in the captured
// input rule group.
isMarkActive({ trState: state, type: this.type, from: start, to: end }) || // Check whether the suggester is active and it's name is one of the
// registered matchers.
this.isMatcherActive(start, end)
) {
// Check if the mark for this mention is active anywhere in the captured
// input rule group.
isMarkActive({
trState: state,
type: this.type,
from: start,
to: end
}) ||
// Check whether the suggester is active and it's name is one of the
// registered matchers.
this.isMatcherActive(start, end)) {
return true;

@@ -328,49 +388,17 @@ }

isMatcherActive(start, end) {
var _a;
const suggestState = this.store.helpers.getSuggestState();
const names = new Set(this.options.matchers.map(({ name }) => name));
const activeName = (_a = suggestState.match) == null ? void 0 : _a.suggester.name;
return this.options.matchers.some((matcher) => activeName === matcher.name) || suggestState.decorationSet.find(start, end, ({ name }) => names.has(name)).length > 0;
const names = new Set(this.options.matchers.map(({
name
}) => name));
const activeName = suggestState.match?.suggester.name;
return this.options.matchers.some(matcher => activeName === matcher.name) || suggestState.decorationSet.find(start, end, ({
name
}) => names.has(name)).length > 0;
}
};
__decorateClass([
command()
], MentionExtension.prototype, "mentionExitHandler", 1);
__decorateClass([
command()
], MentionExtension.prototype, "createMention", 1);
__decorateClass([
command()
], MentionExtension.prototype, "updateMention", 1);
__decorateClass([
command()
], MentionExtension.prototype, "removeMention", 1);
MentionExtension = __decorateClass([
extension({
defaultOptions: {
mentionTag: "a",
matchers: [],
appendText: "",
suggestTag: "a",
disableDecorations: false,
invalidMarks: [],
invalidNodes: [],
isValidPosition: () => true,
validMarks: null,
validNodes: null,
isMentionValid: isMentionValidDefault
},
handlerKeyOptions: { onClick: { earlyReturnValue: true } },
handlerKeys: ["onChange", "onClick"],
staticKeys: ["mentionTag", "matchers"]
})
], MentionExtension);
static {
_initClass();
}
}), _MentionExtension);
var DEFAULT_MATCHER = {
...pick(DEFAULT_SUGGESTER, [
"startOfLine",
"supportedCharacters",
"validPrefixCharacters",
"invalidPrefixCharacters",
"suggestClassName"
]),
...pick(DEFAULT_SUGGESTER, ["startOfLine", "supportedCharacters", "validPrefixCharacters", "invalidPrefixCharacters", "suggestClassName"]),
appendText: "",

@@ -384,4 +412,7 @@ matchOffset: 1,

function getMatcher(name, matchers) {
const matcher = matchers.find((matcher2) => matcher2.name === name);
return matcher ? { ...DEFAULT_MATCHER, ...matcher } : void 0;
const matcher = matchers.find(matcher2 => matcher2.name === name);
return matcher ? {
...DEFAULT_MATCHER,
...matcher
} : void 0;
}

@@ -400,4 +431,2 @@ function getAppendText(preferred, fallback) {

}
export {
MentionExtension
};
export { MentionExtension };
{
"name": "@remirror/extension-mention",
"version": "2.0.15",
"version": "3.0.0-beta.0",
"description": "Mention extension for the remirror wysiwyg editor",

@@ -33,17 +33,24 @@ "homepage": "https://github.com/remirror/remirror/tree/HEAD/packages/remirror__extension-mention",

"dependencies": {
"@babel/runtime": "^7.21.0",
"@remirror/core": "^2.0.13",
"@remirror/extension-events": "^2.1.14",
"@remirror/messages": "^2.0.3",
"@babel/runtime": "^7.22.3",
"@remirror/core": "3.0.0-beta.0",
"@remirror/extension-events": "3.0.0-beta.0",
"@remirror/messages": "3.0.0-beta.0",
"escape-string-regexp": "^4.0.0"
},
"devDependencies": {
"@remirror/pm": "^2.0.5"
"@remirror/cli": "1.0.1",
"@remirror/pm": "3.0.0-beta.0"
},
"peerDependencies": {
"@remirror/pm": "^2.0.5"
"@remirror/pm": "^3.0.0-beta.0"
},
"publishConfig": {
"access": "public"
},
"@remirror": {
"sizeLimit": "5 KB"
"sizeLimit": "10 KB"
},
"scripts": {
"build": "remirror-cli build"
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc