@hhgtech/hhg-components
Version:
Hello Health Group common components
268 lines (265 loc) • 11.9 kB
JavaScript
import { a as __awaiter } from './tslib.es6-ea4dfe68.js';
import { ADMIN_PATHS, PATHS } from './togetherApiPaths.js';
import { d as getApiPath, q as callApiWithAdminAuth, b as callApiWithAuth } from './utils-40e61585.js';
const EncodeUrlRegexMap = {
edit: /<mocka ([^>]*)data-url="true"[^<>]*>(.*?)<\/mocka>/gim,
url: /((?:=")|(?:data-url="true">)|)(https?:\/\/(www\.)?(?:\([-A-Z0-9+&@#\/%=~_|$?!:,.]*\)|[-A-Z0-9+&@#\/%=~_|$?!:,.])*(?:\([-A-Z0-9+&@#\/%=~_|$?!:,.]*\)|[A-Z0-9+&@#\/%=~_|$]))/gim,
encodedUrl: /\[a\+href="([^<"]+)"(?:\+text=\"([^<"]+)")?\]/gim,
editorMention: /<mention [^>]*data-id="([^<"]+)"[^>]*>([^<]+)<\/mention>/gim,
editorFullMention: /<mention [^>]*data-id="([^<"]+)" [^\>]*data-name="([^<"]+)"[^>]*>([^<]+)<\/mention>/gim,
savedMention: /\[mention\+id="([^<"]+)"([^\]]*)\]/gim,
rawUrl: /^(https?:\/\/(www\.)?(?:\([-A-Z0-9+&@#\/%=~_|$?!:,.]*\)|[-A-Z0-9+&@#\/%=~_|$?!:,.])*(?:\([-A-Z0-9+&@#\/%=~_|$?!:,.]*\)|[A-Z0-9+&@#\/%=~_|$]))$/gim,
optionalProtocol: /^((https?:\/\/)?(www\.)?(?:\([-A-Z0-9+&@#\/%=~_|$?!:,.]*\)|[-A-Z0-9+&@#\/%=~_|$?!:,.])*(?:\([-A-Z0-9+&@#\/%=~_|$?!:,.]*\)|[A-Z0-9+&@#\/%=~_|$]))$/gim,
encodedUrl2: /<a [^>]*href="([^>"]+)"[^>]*>([^<]+)<\/a>/gim,
};
const BadWordRegex = /<mocka [^\>]*data-bad-word="[^\"]*" [^\>]*data-error="true"[^\>]*>(.*?)<\/mocka>/gim;
const encodePostUrl = (s, sanitizeFunction = (s) => s) => {
var _a;
return sanitizeFunction((_a = s
.replace(/(\ )+/g, ' ')
.replace(/(\&)+/g, '&')) === null || _a === void 0 ? void 0 : _a.replace(/(\u200c|‌)+/g, '').replace(EncodeUrlRegexMap.url, (match, p1, p2) => {
if (p1 !== '="' && p1 !== 'data-url="true">')
return `<a href="${p2}" target="_blank">${p2}</a>`;
return match;
}).replace(EncodeUrlRegexMap.edit, (match, p1, p2) => {
var _a;
const cleanUrl = (_a = p1.match(/data-href="([^"]*)"/im)) === null || _a === void 0 ? void 0 : _a[1];
if (cleanUrl)
return `<a href="${cleanUrl}" target="_blank">${p2}</a>`;
return `<a href="${p2}" target="_blank">${p2}</a>`;
}));
};
const encodeMention = (s) => s.replace(EncodeUrlRegexMap.editorMention, (match, p1, p2) => {
return `[mention+id="${p1}"+name="${p2}"]`;
});
const getAnchorHtml = ({ url, text, method, }) => {
// remove white space before and after link element, put them outside of current tag
const trimStartIndex = text.indexOf(text.trimStart());
const trimEndIndex = text.trimEnd().length;
const preSpaces = text.substring(0, trimStartIndex);
const trimmedText = text.substring(trimStartIndex, trimEndIndex);
const postSpaces = text.substring(trimEndIndex);
if (method === 'edit') {
return `${preSpaces}<mocka data-href="${url}" data-url="true">${trimmedText}</mocka>${postSpaces}`;
}
if (method === 'display') {
if (url.startsWith('http://') || url.startsWith('https://')) {
return `${preSpaces}<a href="${url}" target="_blank">${trimmedText}</a>${postSpaces}`;
}
}
return text;
};
const decodePostUrl = (s, method) => s
.replace(EncodeUrlRegexMap.encodedUrl, (match, p1, p2) => {
const text = p2 || p1;
return getAnchorHtml({
text,
url: p1,
method,
});
})
.replace(EncodeUrlRegexMap.encodedUrl2, (match, p1, p2) => {
const text = p2 || p1;
return getAnchorHtml({
text,
url: p1,
method,
});
});
const decodeMention = (s, users = []) => s.replace(EncodeUrlRegexMap.savedMention, (match, p1, p2) => {
const foundUser = users.find((u) => String(u.id) === p1);
if (!foundUser) {
if (!p2)
return '';
let tempName = '';
p2.replace(/\+name="([^<"]+)"/i, (m, _p1) => {
tempName = _p1;
return m;
});
return `<mention data-id="${p1}" data-name="${tempName}">${tempName}</mention>`;
}
return `<mention data-id="${p1}" data-name="${foundUser.name}">${foundUser.name}</mention>`;
});
const getUrlsFromString = (s) => {
const res = [];
s.replace(/(\&)+/g, '&').replace(EncodeUrlRegexMap.url, (match, p1, p2) => {
if (p1 !== '="' && p1 !== 'data-url="true">') {
res.push(p2);
}
return match;
});
return res;
};
const LIMIT_MENTION = 30;
const getMentionIdsFromString = (s, disableLimit) => {
const res = [];
s.replace(EncodeUrlRegexMap.editorMention, (match, p1) => {
res.push(p1);
return match;
}).replace(EncodeUrlRegexMap.savedMention, (match, p1) => {
res.push(p1);
return match;
});
if (!disableLimit) {
return Array.from(new Set(res)).slice(0, LIMIT_MENTION);
}
return res;
};
const getUrlsFromEditorString = (s) => {
var _a;
return [
...getUrlsFromString(s),
...(((_a = s.match(EncodeUrlRegexMap.edit)) === null || _a === void 0 ? void 0 : _a.map((s) => {
var _a, _b;
const cleanUrl = (_a = s.match(/data-href="([^"]*)"/im)) === null || _a === void 0 ? void 0 : _a[1];
const text = (_b = s.match(/>(.*?)<\/mocka>/im)) === null || _b === void 0 ? void 0 : _b[1];
return cleanUrl || text;
})) || []),
].filter((s) => !!s);
};
const escapeRegExp = (string) => {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
};
const wrapAnchorAroundUrls = (s) => {
var _a, _b;
return (_b = (_a = s
.replace(/(\ )+/g, ' ')) === null || _a === void 0 ? void 0 : _a.replace(/(\u200c|‌)+/g, '')) === null || _b === void 0 ? void 0 : _b.replace(EncodeUrlRegexMap.edit, (match, p1, p2) => {
var _a;
const cleanUrl = (_a = p1.match(/data-href="([^"]*)"/im)) === null || _a === void 0 ? void 0 : _a[1];
if (!cleanUrl || cleanUrl === p2 || p2.match(EncodeUrlRegexMap.rawUrl))
return p2;
if (cleanUrl)
return `<a href="${cleanUrl}">${p2}</a>`;
return `<a href="${p2}">${p2}</a>`;
}).replace(EncodeUrlRegexMap.url, (match, p1, p2) => {
if (p1 !== '="' && p1 !== 'data-url="true">') {
const lowercase = p2.toLowerCase();
const addHttps = !lowercase.startsWith('http') ? ' https://' : '';
const url = `${addHttps}${lowercase}`;
return getAnchorHtml({
text: url,
url: url,
method: 'edit',
});
}
return match;
}).replace(EncodeUrlRegexMap.encodedUrl2, (match, p1, p2) => {
const text = p2 || p1;
return getAnchorHtml({
text: text,
url: p1,
method: 'edit',
});
});
};
const removeEdittedBannedWord = (s) => s.replace(BadWordRegex, (s, m1) => {
const w = document.createElement('div');
w.innerHTML = s;
const child = w.firstChild;
if ((child === null || child === void 0 ? void 0 : child.innerText) !== (child === null || child === void 0 ? void 0 : child.getAttribute('data-bad-word')))
return m1;
else
return s;
});
const removeBannedWordWrapper = (s) => s.replace(BadWordRegex, '$1');
const removeFontFormat = (s) => s.replace(/<font [^\>]*>(.+)<\/font>/gim, (s, m1) => {
return m1.replace(/<u[^\>]*>(.+)<\/u>/gim, '$1');
});
const encodePostContent = (s, sanitizeFunction = (s) => s) => encodePostUrl(encodeMention(removeBannedWordWrapper(s)), sanitizeFunction);
const ALLOW_DOMAIN_URL = [
'hellobacsi.com',
'hellosehat.com',
'hellodoktor.com',
'hellokrupet.com',
'hellodoctor.com.ph',
'hellokhunmor.com',
'hellosayarwon.com',
'helloyishi.com.tw',
'helloswasthya.com',
'marrybaby.vn',
];
const reformatUrl = (s) => {
if (s.match(EncodeUrlRegexMap.optionalProtocol)) {
if (s.startsWith('https://') || s.startsWith('http://'))
return s;
else
return `https://${s}`;
}
return '';
};
const highlightBadWords = (text, bannedWords) => {
const filteredBanedWords = bannedWords.filter(Boolean);
if (text && filteredBanedWords.length > 0) {
const submitTitle = removeBannedWordWrapper(text);
return submitTitle.replace(new RegExp(`\\b(${filteredBanedWords
.map((banned) => escapeRegExp(banned))
.join('|')})\\b`, 'gi'), (s, m1) => {
const escape = document.createElement('mocka');
escape.setAttribute('data-bad-word', m1);
escape.setAttribute('data-error', 'true');
escape.innerText = m1;
return `${escape.outerHTML}`;
});
}
return text;
};
const fixMalformedMention = (text) => {
return text.replace(EncodeUrlRegexMap.editorFullMention, (match, id, originalName, nameText) => {
if (nameText !== originalName) {
// fix logic here
const splittedName = originalName.split(' ');
const cutoffIndex = splittedName.findIndex((_, index) => {
const nameSection = splittedName.slice(0, index + 1).join(' ');
if (nameText.startsWith(nameSection)) {
return false;
}
return true;
});
if (cutoffIndex === 0)
return `@${nameText}`;
else {
const nameSection = (cutoffIndex < 0 ? splittedName : splittedName.slice(0, cutoffIndex)).join(' ');
const restText = nameText.slice(nameSection.length).trim();
console.log(cutoffIndex, nameSection, restText);
return `<mention data-id="${id}" data-name="${nameSection}">${nameSection}</mention> ${restText} `;
}
}
return match;
});
};
// CREDIT: https://regexr.com/3nsop
const youtubeVidIdGetter = (url) => {
var _a;
if (!url.includes('youtu'))
return '';
const regex = /(.*?)(^|\/|v=)([a-z0-9_-]{11})(.*)?/gim;
return ((_a = regex.exec(url)) === null || _a === void 0 ? void 0 : _a[3]) || '';
};
const uploadAndGetSrc = (file, locale, isAdmin) => typeof file === 'string'
? Promise.resolve(file)
: (() => __awaiter(void 0, void 0, void 0, function* () {
var _a;
const imageFormData = new FormData();
if (file.type.startsWith('image/gif')) {
imageFormData.append('image', file);
}
else {
const imageCompression = yield import('browser-image-compression');
const compressed = yield imageCompression.default(file, {
maxSizeMB: 0.4,
maxWidthOrHeight: 1536,
useWebWorker: true,
});
imageFormData.append('image', compressed);
}
const callApiFunction = isAdmin ? callApiWithAdminAuth : callApiWithAuth;
const imageRes = yield callApiFunction(getApiPath(isAdmin
? ADMIN_PATHS.COMMENT.IMAGE_UPLOAD
: PATHS.COMMENT.IMAGE_UPLOAD, {
_locale: locale,
}), 'POST', {
data: imageFormData,
});
return ((_a = imageRes === null || imageRes === void 0 ? void 0 : imageRes.data) === null || _a === void 0 ? void 0 : _a.image) || '';
}))();
export { ALLOW_DOMAIN_URL as A, LIMIT_MENTION as L, removeEdittedBannedWord as a, decodePostUrl as b, reformatUrl as c, decodeMention as d, escapeRegExp as e, fixMalformedMention as f, getUrlsFromEditorString as g, highlightBadWords as h, getMentionIdsFromString as i, removeBannedWordWrapper as j, encodePostContent as k, removeFontFormat as r, uploadAndGetSrc as u, wrapAnchorAroundUrls as w, youtubeVidIdGetter as y };