UNPKG

@dialpad/dialtone

Version:

Dialpad's Dialtone design system monorepo

106 lines (105 loc) 2.94 kB
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( "(?:" + [ `[!?.,:;'"]`, "(?:&|&amp;)(?: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