137 lines
3.5 KiB
JavaScript
137 lines
3.5 KiB
JavaScript
|
|
// src/core/parser.ts
|
||
|
|
var mentionLinkRegexp = /@\[[^\]]+]\([0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}\)/g;
|
||
|
|
var parseMention = (mention) => {
|
||
|
|
const regex = /@\[([^\]]+)\]\(([\w-]{36})\)/;
|
||
|
|
const match = mention.match(regex);
|
||
|
|
if (!match) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
const mentionText = match[1];
|
||
|
|
const mentionId = match[2];
|
||
|
|
if (!mentionText || !mentionId) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
return {
|
||
|
|
mention: `@${mentionText}`,
|
||
|
|
id: mentionId
|
||
|
|
};
|
||
|
|
};
|
||
|
|
var findMentions = (text) => {
|
||
|
|
let match;
|
||
|
|
const matches = [];
|
||
|
|
while ((match = mentionLinkRegexp.exec(text)) !== null) {
|
||
|
|
const parsed = parseMention(match[0]);
|
||
|
|
const baseMention = {
|
||
|
|
start: match.index,
|
||
|
|
end: mentionLinkRegexp.lastIndex,
|
||
|
|
text: match[0],
|
||
|
|
type: "mention",
|
||
|
|
displayText: parsed?.mention ?? match[0]
|
||
|
|
};
|
||
|
|
matches.push(parsed?.id ? { ...baseMention, userId: parsed.id } : baseMention);
|
||
|
|
}
|
||
|
|
return matches;
|
||
|
|
};
|
||
|
|
var findTags = (content) => {
|
||
|
|
const regex = /#[^\s]{1,201}/g;
|
||
|
|
const results = [];
|
||
|
|
let match;
|
||
|
|
while ((match = regex.exec(content)) !== null) {
|
||
|
|
const value = match[0];
|
||
|
|
results.push({
|
||
|
|
start: match.index,
|
||
|
|
end: match.index + value.length,
|
||
|
|
text: value,
|
||
|
|
type: "tag",
|
||
|
|
tag: value.replace("#", "")
|
||
|
|
});
|
||
|
|
}
|
||
|
|
return results;
|
||
|
|
};
|
||
|
|
var findLinks = (content) => {
|
||
|
|
const regex = /\b((https?:\/\/)?(?:[\w-]+\.)+[a-z]{2,}(\/[\w\-._~:/?#[\]@!$&'()*+,;=]*)?)/gi;
|
||
|
|
const results = [];
|
||
|
|
let match;
|
||
|
|
while ((match = regex.exec(content)) !== null) {
|
||
|
|
const rawUrl = match[0];
|
||
|
|
const hasProtocol = /^https?:\/\//i.test(rawUrl);
|
||
|
|
const fullUrl = hasProtocol ? rawUrl : `https://${rawUrl}`;
|
||
|
|
results.push({
|
||
|
|
start: match.index,
|
||
|
|
end: match.index + rawUrl.length,
|
||
|
|
text: rawUrl,
|
||
|
|
url: fullUrl,
|
||
|
|
type: "link"
|
||
|
|
});
|
||
|
|
}
|
||
|
|
return results;
|
||
|
|
};
|
||
|
|
var findAllEntities = (content) => {
|
||
|
|
const mentions = findMentions(content);
|
||
|
|
const tags = findTags(content);
|
||
|
|
const links = findLinks(content);
|
||
|
|
return [...mentions, ...tags, ...links].sort((a, b) => a.start - b.start);
|
||
|
|
};
|
||
|
|
|
||
|
|
// src/angular/index.ts
|
||
|
|
var buildAngularTagHref = (entity) => {
|
||
|
|
return `/search/?query=${encodeURIComponent(entity.tag.toLowerCase())}`;
|
||
|
|
};
|
||
|
|
var createAngularContentTokens = (inputText) => {
|
||
|
|
const text = inputText ?? "";
|
||
|
|
const entities = findAllEntities(text);
|
||
|
|
let cursor = 0;
|
||
|
|
const tokens = [];
|
||
|
|
for (const entity of entities) {
|
||
|
|
if (entity.start > cursor) {
|
||
|
|
tokens.push({
|
||
|
|
kind: "text",
|
||
|
|
text: text.slice(cursor, entity.start),
|
||
|
|
start: cursor,
|
||
|
|
end: entity.start
|
||
|
|
});
|
||
|
|
}
|
||
|
|
if (entity.type === "mention") {
|
||
|
|
tokens.push({
|
||
|
|
kind: "mention",
|
||
|
|
entity
|
||
|
|
});
|
||
|
|
} else if (entity.type === "tag") {
|
||
|
|
tokens.push({
|
||
|
|
kind: "tag",
|
||
|
|
entity
|
||
|
|
});
|
||
|
|
} else {
|
||
|
|
tokens.push({
|
||
|
|
kind: "link",
|
||
|
|
entity
|
||
|
|
});
|
||
|
|
}
|
||
|
|
cursor = entity.end;
|
||
|
|
}
|
||
|
|
if (cursor < text.length) {
|
||
|
|
tokens.push({
|
||
|
|
kind: "text",
|
||
|
|
text: text.slice(cursor),
|
||
|
|
start: cursor,
|
||
|
|
end: text.length
|
||
|
|
});
|
||
|
|
}
|
||
|
|
return tokens;
|
||
|
|
};
|
||
|
|
var AngularContentSuggestionsAdapter = class {
|
||
|
|
snapshot(inputText) {
|
||
|
|
const text = inputText ?? "";
|
||
|
|
const entities = findAllEntities(text);
|
||
|
|
const tokens = createAngularContentTokens(text);
|
||
|
|
return {
|
||
|
|
text,
|
||
|
|
entities,
|
||
|
|
tokens
|
||
|
|
};
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
export { AngularContentSuggestionsAdapter, buildAngularTagHref, createAngularContentTokens };
|
||
|
|
//# sourceMappingURL=index.js.map
|
||
|
|
//# sourceMappingURL=index.js.map
|