@dialpad/dialtone
Version:
Dialpad's Dialtone design system monorepo
106 lines (105 loc) • 2.94 kB
JavaScript
import { getMarksBetween } from "@tiptap/core";
import { linkRegex, getPhoneNumberRegex } from "../../../../common/utils.js";
function getRegexMatches(text, regex, validator = () => true) {
const matches = [];
regex.lastIndex = 0;
let match;
while (match = regex.exec(text)) {
if (validator(text, match)) {
matches.push(match);
}
}
return matches;
}
function hasValidPrefix(text, match) {
return !["#", "@"].includes(text.charAt(match.index)) && !["#", "@"].includes(text.charAt(match.index - 1));
}
function trimEndPunctiation(string) {
const endPunctuationRegex = new RegExp(
"(?:" + [
`[!?.,:;'"]`,
"(?:&|&)(?:lt|gt|quot|apos|raquo|laquo|rsaquo|lsaquo);)+$"
].join("|"),
"g"
);
return string.replace(endPunctuationRegex, "");
}
function getWordAt(text, index) {
const left = text.slice(0, index + 1).search(/\S+\s*$/);
const right = text.slice(index).search(/\s/);
if (right < 0) {
const word = text.slice(left);
return {
text: word,
from: left,
to: left + word.length
};
}
return {
text: text.slice(left, right + index),
from: left,
to: right + index
};
}
function getWordAtUntil(text, index, direction, regex) {
const word = getWordAt(text, index);
regex.lastIndex = 0;
if (!regex.test(word.text)) {
return word;
}
const newIndex = direction === "left" ? word.from - 1 : word.to + 1;
if (newIndex <= 0 || newIndex >= text.length || newIndex === index) {
return word;
}
return getWordAtUntil(text, newIndex, direction, regex);
}
function removeMarks(range, doc, tr, type) {
const from = Math.max(range.from - 1, 0);
const to = Math.min(range.to + 1, doc.content.size);
const marksInRange = getMarksBetween(from, to, doc);
for (const mark of marksInRange) {
if (mark.mark.type !== type) {
continue;
}
tr.removeMark(mark.from, mark.to, type);
}
}
const partialPhoneNumberRegex = getPhoneNumberRegex(1, 15);
function addMarks(text, pos, from, to, tr, type) {
if (!text) {
return;
}
let rangeFrom = from - pos - 1;
rangeFrom = rangeFrom < 0 ? 0 : rangeFrom;
const rangeTo = to - pos;
const firstWordInRange = getWordAtUntil(
text,
rangeFrom,
"left",
partialPhoneNumberRegex
);
const lastWordInRange = getWordAtUntil(
text,
rangeTo,
"right",
partialPhoneNumberRegex
);
const wordsInRange = text.slice(firstWordInRange.from, lastWordInRange.to);
const matches = getRegexMatches(wordsInRange, linkRegex, hasValidPrefix);
matches.forEach((match) => {
const word = trimEndPunctiation(match[0]);
const from2 = pos + firstWordInRange.from + match.index + 1;
const to2 = from2 + word.length;
tr.addMark(from2, to2, type.create());
});
}
export {
addMarks,
getRegexMatches,
getWordAt,
getWordAtUntil,
hasValidPrefix,
removeMarks,
trimEndPunctiation
};
//# sourceMappingURL=utils.js.map