Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
export const findPosition = ({ text, regexp, $pos, char, name }: FindMentionPositionParams) => {
let position: SuggestionStateField | undefined;
findMatches(text, regexp).forEach(match => {
// Check the character before the current match to check if it is supported
const matchPrefix = match.input.slice(Math.max(0, match.index - 1), match.index);
// ? Can this be switched for NOT `supportedCharacters` - TEST once refactored
if (/^[\s\0]?$/.test(matchPrefix)) {
// The absolute position of the match wrapper node
const from = match.index + $pos.start();
const to = from + match[0].length;
// If the $position is located within the matched substring, return that range
if (from < $pos.pos && to >= $pos.pos) {
position = {
name,
char,
range: {
from,
): SuggestionsPluginState | undefined => {
// Matching expressions used for later
const escapedChar = `\\${char}`;
const supported =
typeof supportedCharacters === 'string' ? supportedCharacters : supportedCharacters.source;
// const suffix = new RegExp(`\\s${escapedChar}$`);
const prefix = startOfLine ? '^' : '';
const regexp = new RegExp(`${prefix}${escapedChar}${supported}`, 'gm');
// Lookup the boundaries of the current node
const textFrom = $pos.before();
const textTo = $pos.end();
const text = $pos.doc.textBetween(textFrom, textTo, '\0', '\0');
let position: SuggestionsPluginState | undefined;
findMatches(text, regexp).forEach(match => {
// JavaScript doesn't have lookbehinds; this hacks a check that first character is " "
// or the line beginning
const matchPrefix = match.input.slice(Math.max(0, match.index - 1), match.index);
if (/^[\s\0]?$/.test(matchPrefix)) {
// The absolute position of the match in the document
const from = match.index + $pos.start();
const to = from + match[0].length;
// Edge case handling; if spaces are allowed and we're directly in between
// two triggers
// if (allowSpaces && suffix.test(text.slice(to - 1, to + 1))) {
// match[0] += ' ';
// to += 1;
// }
leafChar,
);
findMatches(prevSearchText, extractUrl).forEach(match => {
const startIndex = match.index;
const url = match[1];
const start = $pos.start() + startIndex;
const end = $pos.start() + startIndex + match[0].length;
collectedParams.push({ state, url, from: start, to: end, type });
});
tr.removeMark($pos.start(), $pos.end(), type);
}
// Finds matches within the current node when in the middle of a node
findMatches(searchText, extractUrl).forEach(match => {
const startIndex = match.index;
const url = match[1];
const start = $from.start() + startIndex;
const end = $from.start() + startIndex + match[0].length;
// The text directly before the match
const textBefore = doc.textBetween(start - 1, start, LEAF_NODE_REPLACING_CHARACTER, leafChar);
if (!/[\w\d]/.test(textBefore)) {
collectedParams.push({ state, url, from: start, to: end, type });
}
});
// Remove all marks within the current block
tr.removeMark($from.start(), $from.end(), type);
// Add all marks again for the nodes
const searchText =
doc.textBetween($from.start(), from, LEAF_NODE_REPLACING_CHARACTER, leafChar) +
doc.textBetween(to, $to.end(), LEAF_NODE_REPLACING_CHARACTER, leafChar);
const tr = state.tr;
const collectedParams: EnhancedLinkHandlerProps[] = [];
// If at the start of a new line (i.e. new block added and not at the start of the document)
if (from === $from.start() && from >= 2) {
const $pos = doc.resolve(from - 2);
const prevSearchText = doc.textBetween(
$pos.start(),
$pos.end(),
LEAF_NODE_REPLACING_CHARACTER,
leafChar,
);
findMatches(prevSearchText, extractUrl).forEach(match => {
const startIndex = match.index;
const url = match[1];
const start = $pos.start() + startIndex;
const end = $pos.start() + startIndex + match[0].length;
collectedParams.push({ state, url, from: start, to: end, type });
});
tr.removeMark($pos.start(), $pos.end(), type);
}
// Finds matches within the current node when in the middle of a node
findMatches(searchText, extractUrl).forEach(match => {
const startIndex = match.index;
const url = match[1];
const start = $from.start() + startIndex;
export const text = (value: string, schema: EditorSchema): TaggedContentItem => {
let stripped = '';
let textIndex = 0;
const tags: Tags = Object.create(null);
for (const match of findMatches(value, /([\\]+)?<(\w+)>/g)) {
const [taggedToken, escapeCharacters, tagName] = match;
let { index } = match;
const skipLen = escapeCharacters?.length;
if (skipLen) {
if (isOdd(skipLen)) {
stripped += value.slice(textIndex, index + (skipLen - 1) / 2);
stripped += value.slice(index + skipLen, index + taggedToken.length);
textIndex = index + taggedToken.length;
continue;
}
index += skipLen / 2;
}
stripped += value.slice(textIndex, index);
tags[tagName] = stripped.length;