You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

@remirror/extension-mention

Package Overview
Dependencies
Maintainers
2
Versions
333
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@remirror/extension-mention - npm Package Compare versions

Comparing version

to
0.0.0-pr2166.1

dist/_tsup-dts-rollup.d.mts

253

dist/remirror-extension-mention.d.ts

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

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 {};

@@ -1,43 +0,51 @@

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;
};
var _initClass, _MentionExtension, _dec, _dec2, _dec3, _dec4, _dec5, _initProto;
function createAddInitializerMethod(initializers, decoratorFinishedRef) { return function (initializer) { assertNotFinished(decoratorFinishedRef, "addInitializer"), assertCallable(initializer, "An initializer"), initializers.push(initializer); }; }
function assertInstanceIfPrivate(has, target) { if (!has(target)) throw new TypeError("Attempted to access private element on non-instance"); }
function memberDec(dec, thisArg, name, desc, initializers, kind, isStatic, isPrivate, value, hasPrivateBrand) { var kindStr; switch (kind) { case 1: kindStr = "accessor"; break; case 2: kindStr = "method"; break; case 3: kindStr = "getter"; break; case 4: kindStr = "setter"; break; default: kindStr = "field"; } var get, set, ctx = { kind: kindStr, name: isPrivate ? "#" + name : name, static: isStatic, private: isPrivate }, decoratorFinishedRef = { v: !1 }; if (0 !== kind && (ctx.addInitializer = createAddInitializerMethod(initializers, decoratorFinishedRef)), isPrivate || 0 !== kind && 2 !== kind) { if (2 === kind) get = function (target) { return assertInstanceIfPrivate(hasPrivateBrand, target), desc.value; };else { var t = 0 === kind || 1 === kind; (t || 3 === kind) && (get = isPrivate ? function (target) { return assertInstanceIfPrivate(hasPrivateBrand, target), desc.get.call(target); } : function (target) { return desc.get.call(target); }), (t || 4 === kind) && (set = isPrivate ? function (target, value) { assertInstanceIfPrivate(hasPrivateBrand, target), desc.set.call(target, value); } : function (target, value) { desc.set.call(target, value); }); } } else get = function (target) { return target[name]; }, 0 === kind && (set = function (target, v) { target[name] = v; }); var has = isPrivate ? hasPrivateBrand.bind() : function (target) { return name in target; }; ctx.access = get && set ? { get: get, set: set, has: has } : get ? { get: get, has: has } : { set: set, has: has }; try { return dec.call(thisArg, value, ctx); } finally { decoratorFinishedRef.v = !0; } }
function assertNotFinished(decoratorFinishedRef, fnName) { if (decoratorFinishedRef.v) throw new Error("attempted to call " + fnName + " after decoration was finished"); }
function assertCallable(fn, hint) { if ("function" != typeof fn) throw new TypeError(hint + " must be a function"); }
function assertValidReturnValue(kind, value) { var type = typeof value; if (1 === kind) { if ("object" !== type || null === value) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0"); void 0 !== value.get && assertCallable(value.get, "accessor.get"), void 0 !== value.set && assertCallable(value.set, "accessor.set"), void 0 !== value.init && assertCallable(value.init, "accessor.init"); } else if ("function" !== type) { var hint; throw hint = 0 === kind ? "field" : 5 === kind ? "class" : "method", new TypeError(hint + " decorators must return a function or void 0"); } }
function curryThis1(fn) { return function () { return fn(this); }; }
function curryThis2(fn) { return function (value) { fn(this, value); }; }
function applyMemberDec(ret, base, decInfo, decoratorsHaveThis, name, kind, isStatic, isPrivate, initializers, hasPrivateBrand) { var desc, init, value, newValue, get, set, decs = decInfo[0]; decoratorsHaveThis || Array.isArray(decs) || (decs = [decs]), isPrivate ? desc = 0 === kind || 1 === kind ? { get: curryThis1(decInfo[3]), set: curryThis2(decInfo[4]) } : 3 === kind ? { get: decInfo[3] } : 4 === kind ? { set: decInfo[3] } : { value: decInfo[3] } : 0 !== kind && (desc = Object.getOwnPropertyDescriptor(base, name)), 1 === kind ? value = { get: desc.get, set: desc.set } : 2 === kind ? value = desc.value : 3 === kind ? value = desc.get : 4 === kind && (value = desc.set); for (var inc = decoratorsHaveThis ? 2 : 1, i = decs.length - 1; i >= 0; i -= inc) { var newInit; if (void 0 !== (newValue = memberDec(decs[i], decoratorsHaveThis ? decs[i - 1] : void 0, name, desc, initializers, kind, isStatic, isPrivate, value, hasPrivateBrand))) assertValidReturnValue(kind, newValue), 0 === kind ? newInit = newValue : 1 === kind ? (newInit = newValue.init, get = newValue.get || value.get, set = newValue.set || value.set, value = { get: get, set: set }) : value = newValue, void 0 !== newInit && (void 0 === init ? init = newInit : "function" == typeof init ? init = [init, newInit] : init.push(newInit)); } if (0 === kind || 1 === kind) { if (void 0 === init) init = function (instance, init) { return init; };else if ("function" != typeof init) { var ownInitializers = init; init = function (instance, init) { for (var value = init, i = ownInitializers.length - 1; i >= 0; i--) value = ownInitializers[i].call(instance, value); return value; }; } else { var originalInitializer = init; init = function (instance, init) { return originalInitializer.call(instance, init); }; } ret.push(init); } 0 !== kind && (1 === kind ? (desc.get = value.get, desc.set = value.set) : 2 === kind ? desc.value = value : 3 === kind ? desc.get = value : 4 === kind && (desc.set = value), isPrivate ? 1 === kind ? (ret.push(function (instance, args) { return value.get.call(instance, args); }), ret.push(function (instance, args) { return value.set.call(instance, args); })) : 2 === kind ? ret.push(value) : ret.push(function (instance, args) { return value.call(instance, args); }) : Object.defineProperty(base, name, desc)); }
function applyMemberDecs(Class, decInfos, instanceBrand) { for (var protoInitializers, staticInitializers, staticBrand, ret = [], existingProtoNonFields = new Map(), existingStaticNonFields = new Map(), i = 0; i < decInfos.length; i++) { var decInfo = decInfos[i]; if (Array.isArray(decInfo)) { var base, initializers, kind = decInfo[1], name = decInfo[2], isPrivate = decInfo.length > 3, decoratorsHaveThis = 16 & kind, isStatic = !!(8 & kind), hasPrivateBrand = instanceBrand; if (kind &= 7, isStatic ? (base = Class, 0 !== kind && (initializers = staticInitializers = staticInitializers || []), isPrivate && !staticBrand && (staticBrand = function (_) { return _checkInRHS(_) === Class; }), hasPrivateBrand = staticBrand) : (base = Class.prototype, 0 !== kind && (initializers = protoInitializers = protoInitializers || [])), 0 !== kind && !isPrivate) { var existingNonFields = isStatic ? existingStaticNonFields : existingProtoNonFields, existingKind = existingNonFields.get(name) || 0; if (!0 === existingKind || 3 === existingKind && 4 !== kind || 4 === existingKind && 3 !== kind) 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: " + name); existingNonFields.set(name, !(!existingKind && kind > 2) || kind); } applyMemberDec(ret, base, decInfo, decoratorsHaveThis, name, kind, isStatic, isPrivate, initializers, hasPrivateBrand); } } return pushInitializers(ret, protoInitializers), pushInitializers(ret, staticInitializers), ret; }
function pushInitializers(ret, initializers) { initializers && ret.push(function (instance) { for (var i = 0; i < initializers.length; i++) initializers[i].call(instance); return instance; }); }
function applyClassDecs(targetClass, classDecs, decoratorsHaveThis) { if (classDecs.length) { for (var initializers = [], newClass = targetClass, name = targetClass.name, inc = decoratorsHaveThis ? 2 : 1, i = classDecs.length - 1; i >= 0; i -= inc) { var decoratorFinishedRef = { v: !1 }; try { var nextNewClass = classDecs[i].call(decoratorsHaveThis ? classDecs[i - 1] : void 0, newClass, { kind: "class", name: name, addInitializer: createAddInitializerMethod(initializers, decoratorFinishedRef) }); } finally { decoratorFinishedRef.v = !0; } void 0 !== nextNewClass && (assertValidReturnValue(5, nextNewClass), newClass = nextNewClass); } return [newClass, function () { for (var i = 0; i < initializers.length; i++) initializers[i].call(newClass); }]; } }
function _applyDecs(targetClass, memberDecs, classDecs, classDecsHaveThis, instanceBrand) { return { e: applyMemberDecs(targetClass, memberDecs, instanceBrand), get c() { return applyClassDecs(targetClass, classDecs, classDecsHaveThis); } }; }
function _checkInRHS(value) { if (Object(value) !== value) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== value ? typeof value : "null")); return value; }
// 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 {
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 +73,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 +130,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 +155,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,27 +169,19 @@ });

let cachedRange;
const options = pick(this.options, [
"invalidMarks",
"invalidNodes",
"isValidPosition",
"validMarks",
"validNodes",
"suggestTag",
"disableDecorations"
]);
return this.options.matchers.map((matcher) => ({
const options = pick(this.options, ["invalidMarks", "invalidNodes", "isValidPosition", "validMarks", "validNodes", "suggestTag", "disableDecorations"]);
return this.options.matchers.map(matcher => ({
...DEFAULT_MATCHER,
...options,
...matcher,
onChange: (props) => {
onChange: props => {
const command2 = (attrs = {}) => {
this.mentionExitHandler(props, attrs)(this.store.helpers.getCommandProp());
};
this.options.onChange(
{ ...props, defaultAppendTextValue: this.options.appendText },
command2
);
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)) {
if (!range || range.from === cachedRange?.from && range.to === cachedRange?.to) {
return;

@@ -194,3 +195,5 @@ }

cachedRange = range;
return this.store.chain(tr).removeMention({ range }).tr();
return this.store.chain(tr).removeMention({
range
}).tr();
}

@@ -200,3 +203,3 @@ }));

mentionExitHandler(handler, attrs = {}) {
return (props) => {
return props => {
const reason = handler.exitReason ?? handler.changeReason;

@@ -208,3 +211,5 @@ const isInvalid = isInvalidSplitReason(reason);

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

@@ -214,6 +219,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);

@@ -241,9 +261,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;

@@ -259,27 +285,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,

@@ -293,5 +343,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

@@ -302,3 +358,8 @@ })(props);

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

@@ -308,8 +369,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;

@@ -323,49 +389,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: "",

@@ -379,4 +413,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;
}

@@ -395,4 +432,2 @@ function getAppendText(preferred, fallback) {

}
export {
MentionExtension
};
export { MentionExtension };
{
"name": "@remirror/extension-mention",
"version": "0.0.0-pr2128.4",
"version": "0.0.0-pr2166.1",
"description": "Mention extension for the remirror wysiwyg editor",

@@ -34,12 +34,12 @@ "homepage": "https://github.com/remirror/remirror/tree/HEAD/packages/remirror__extension-mention",

"@babel/runtime": "^7.22.3",
"@remirror/core": "0.0.0-pr2128.4",
"@remirror/extension-events": "0.0.0-pr2128.4",
"@remirror/messages": "0.0.0-pr2128.4",
"@remirror/core": "0.0.0-pr2166.1",
"@remirror/extension-events": "0.0.0-pr2166.1",
"@remirror/messages": "0.0.0-pr2166.1",
"escape-string-regexp": "^4.0.0"
},
"devDependencies": {
"@remirror/pm": "0.0.0-pr2128.4"
"@remirror/pm": "0.0.0-pr2166.1"
},
"peerDependencies": {
"@remirror/pm": "0.0.0-pr2128.4"
"@remirror/pm": "0.0.0-pr2166.1"
},

@@ -46,0 +46,0 @@ "publishConfig": {

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