New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
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 0.0.0-pr2128.4 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

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc