From 1769a6b81f8946a4c22a5e5dc71bdbecb306127e Mon Sep 17 00:00:00 2001
From: "Evgeny @ SimpleX Chat"
<259188159+evgeny-simplex@users.noreply.github.com>
Date: Sun, 31 May 2026 07:28:29 +0000
Subject: [PATCH] website: use cpp to inject JS functions
---
.gitignore | 1 +
website/.eleventy.js | 2 +-
website/src/js/directory.js | 297 +++++++++++++++++++-----------------
website/web.sh | 4 +
4 files changed, 163 insertions(+), 141 deletions(-)
diff --git a/.gitignore b/.gitignore
index 7bd3d04e59..1cd2a09f40 100644
--- a/.gitignore
+++ b/.gitignore
@@ -55,6 +55,7 @@ website/src/img/images/
website/src/images/
website/src/js/lottie.min.js
website/src/js/ethers*
+website/src/js/directory.js
website/src/file-assets/
website/src/link-images/
website/src/privacy.md
diff --git a/website/.eleventy.js b/website/.eleventy.js
index f0310c5665..0567dd45d8 100644
--- a/website/.eleventy.js
+++ b/website/.eleventy.js
@@ -310,7 +310,7 @@ module.exports = function (ty) {
ty.addPassthroughCopy("src/img")
ty.addPassthroughCopy("src/video")
ty.addPassthroughCopy("src/css")
- ty.addPassthroughCopy("src/js")
+ ty.addPassthroughCopy("src/js/**/*.js")
ty.addPassthroughCopy("src/lottie_file")
ty.addPassthroughCopy("src/contact/*.js")
ty.addPassthroughCopy("src/call")
diff --git a/website/src/js/directory.js b/website/src/js/directory.js
index afaac1053f..64bb4b2097 100644
--- a/website/src/js/directory.js
+++ b/website/src/js/directory.js
@@ -1,3 +1,160 @@
+
+
+
+
+
+
+
+
+
+
+
+const isMobile = {
+ Android: () => navigator.userAgent.match(/Android/i),
+ iOS: () => navigator.userAgent.match(/iPhone|iPad|iPod/i),
+ any: () => navigator.userAgent.match(/Android|iPhone|iPad|iPod/i)
+};
+
+function escapeHtml(text) {
+ return text
+ .replace(/&/g, "&")
+ .replace(//g, ">")
+ .replace(/"/g, """)
+ .replace(/'/g, "'")
+ .replace(/\n/g, "
");
+}
+
+function getSimplexLinkDescr(linkType) {
+ switch (linkType) {
+ case 'contact': return 'SimpleX contact address';
+ case 'invitation': return 'SimpleX one-time invitation';
+ case 'group': return 'SimpleX group link';
+ case 'channel': return 'SimpleX channel link';
+ case 'relay': return 'SimpleX relay link';
+ default: return 'SimpleX link';
+ }
+}
+
+function viaHost(smpHosts) {
+ const first = smpHosts[0] ?? '?';
+ return `via ${first}`;
+}
+
+function isCurrentSite(uri) {
+ return uri.startsWith("https://simplex.chat") || uri.startsWith("https://www.simplex.chat")
+}
+
+function targetBlank(uri) {
+ return isCurrentSite(uri) ? '' : ' target="_blank"'
+}
+
+function renderMarkdown(fts) {
+ let html = '';
+ for (const ft of fts) {
+ const { format, text } = ft;
+ if (!format) {
+ html += escapeHtml(text);
+ continue;
+ }
+ try {
+ switch (format.type) {
+ case 'bold':
+ html += `${escapeHtml(text)}`;
+ break;
+ case 'italic':
+ html += `${escapeHtml(text)}`;
+ break;
+ case 'strikeThrough':
+ html += `${escapeHtml(text)}`;
+ break;
+ case 'snippet':
+ html += `${escapeHtml(text)}`;
+ break;
+ case 'secret':
+ html += `${escapeHtml(text)}`;
+ break;
+ case 'small':
+ html += `${escapeHtml(text)}`;
+ break;
+ case 'colored':
+ html += `${escapeHtml(text)}`;
+ break;
+ case 'uri':
+ let href = text.startsWith('http://') || text.startsWith('https://') || text.startsWith('simplex:/') ? text : 'https://' + text;
+ html += `${escapeHtml(text)}`;
+ break;
+ case 'hyperLink': {
+ const { showText, linkUri } = format;
+ html += `${escapeHtml(showText ?? linkUri)}`;
+ break;
+ }
+ case 'simplexLink': {
+ const { showText, linkType, simplexUri, smpHosts } = format;
+ const linkText = showText ? escapeHtml(showText) : getSimplexLinkDescr(linkType);
+ html += `${linkText} (${viaHost(smpHosts)})`;
+ break;
+ }
+ case 'command':
+ html += `${escapeHtml(text)}`;
+ break;
+ case 'mention':
+ html += `${escapeHtml(text)}`;
+ break;
+ case 'email':
+ html += `${escapeHtml(text)}`;
+ break;
+ case 'phone':
+ html += `${escapeHtml(text)}`;
+ break;
+ case 'unknown':
+ html += escapeHtml(text);
+ break;
+ default:
+ html += escapeHtml(text);
+ }
+ } catch(e) {
+ console.log(e);
+ html += escapeHtml(text);
+ }
+ }
+ return html;
+}
+
+const simplexAddressRegexp = /^simplex:\/([a-z]+)#(.+)/i;
+
+const simplexShortLinkTypes = ["a", "c", "g", "i", "r"];
+
+function platformSimplexUri(uri) {
+ if (isMobile.any()) return uri;
+ const res = uri.match(simplexAddressRegexp);
+ if (!res || !Array.isArray(res) || res.length < 3) return uri;
+ const linkType = res[1];
+ const fragment = res[2];
+ if (simplexShortLinkTypes.includes(linkType)) {
+ const queryIndex = fragment.indexOf('?');
+ if (queryIndex === -1) return uri;
+ const hashPart = fragment.substring(0, queryIndex);
+ const queryStr = fragment.substring(queryIndex + 1);
+ const params = new URLSearchParams(queryStr);
+ const host = params.get('h');
+ if (!host) return uri;
+ params.delete('h');
+ let newFragment = hashPart;
+ const remainingParams = params.toString();
+ if (remainingParams) newFragment += '?' + remainingParams;
+ return `https://${host}:/${linkType}#${newFragment}`;
+ } else {
+ return `https://simplex.chat/${linkType}#${fragment}`;
+ }
+}
+
+const simplexDirectoryDataURL = 'https://directory.simplex.chat/data/';
+
+// const simplexDirectoryDataURL = 'http://localhost:8080/directory-data/';
+
+const simplexUsersGroup = 'SimpleX users group';
+
(function() {
if (!document.location.pathname.startsWith('/directory')) return;
@@ -428,144 +585,4 @@ if (document.readyState === 'loading') {
} else {
initDirectory();
}
-
-function escapeHtml(text) {
- return text
- .replace(/&/g, "&")
- .replace(//g, ">")
- .replace(/"/g, """)
- .replace(/'/g, "'")
- .replace(/\n/g, "
");
-}
-
-function getSimplexLinkDescr(linkType) {
- switch (linkType) {
- case 'contact': return 'SimpleX contact address';
- case 'invitation': return 'SimpleX one-time invitation';
- case 'group': return 'SimpleX group link';
- case 'channel': return 'SimpleX channel link';
- case 'relay': return 'SimpleX relay link';
- default: return 'SimpleX link';
- }
-}
-
-function viaHost(smpHosts) {
- const first = smpHosts[0] ?? '?';
- return `via ${first}`;
-}
-
-function isCurrentSite(uri) {
- return uri.startsWith("https://simplex.chat") || uri.startsWith("https://www.simplex.chat")
-}
-
-function targetBlank(uri) {
- return isCurrentSite(uri) ? '' : ' target="_blank"'
-}
-
-function renderMarkdown(fts) {
- let html = '';
- for (const ft of fts) {
- const { format, text } = ft;
- if (!format) {
- html += escapeHtml(text);
- continue;
- }
- try {
- switch (format.type) {
- case 'bold':
- html += `${escapeHtml(text)}`;
- break;
- case 'italic':
- html += `${escapeHtml(text)}`;
- break;
- case 'strikeThrough':
- html += `${escapeHtml(text)}`;
- break;
- case 'snippet':
- html += `${escapeHtml(text)}`;
- break;
- case 'secret':
- html += `${escapeHtml(text)}`;
- break;
- case 'small':
- html += `${escapeHtml(text)}`;
- break;
- case 'colored':
- html += `${escapeHtml(text)}`;
- break;
- case 'uri':
- let href = text.startsWith('http://') || text.startsWith('https://') || text.startsWith('simplex:/') ? text : 'https://' + text;
- html += `${escapeHtml(text)}`;
- break;
- case 'hyperLink': {
- const { showText, linkUri } = format;
- html += `${escapeHtml(showText ?? linkUri)}`;
- break;
- }
- case 'simplexLink': {
- const { showText, linkType, simplexUri, smpHosts } = format;
- const linkText = showText ? escapeHtml(showText) : getSimplexLinkDescr(linkType);
- html += `${linkText} (${viaHost(smpHosts)})`;
- break;
- }
- case 'command':
- html += `${escapeHtml(text)}`;
- break;
- case 'mention':
- html += `${escapeHtml(text)}`;
- break;
- case 'email':
- html += `${escapeHtml(text)}`;
- break;
- case 'phone':
- html += `${escapeHtml(text)}`;
- break;
- case 'unknown':
- html += escapeHtml(text);
- break;
- default:
- html += escapeHtml(text);
- }
- } catch(e) {
- console.log(e);
- html += escapeHtml(text);
- }
- }
- return html;
-}
})();
-
-const simplexDirectoryDataURL = 'https://directory.simplex.chat/data/';
-
-// const simplexDirectoryDataURL = 'http://localhost:8080/directory-data/';
-
-const simplexUsersGroup = 'SimpleX users group';
-
-const simplexAddressRegexp = /^simplex:\/([a-z]+)#(.+)/i;
-
-const simplexShortLinkTypes = ["a", "c", "g", "i", "r"];
-
-function platformSimplexUri(uri) {
- if (isMobile.any()) return uri;
- const res = uri.match(simplexAddressRegexp);
- if (!res || !Array.isArray(res) || res.length < 3) return uri;
- const linkType = res[1];
- const fragment = res[2];
- if (simplexShortLinkTypes.includes(linkType)) {
- const queryIndex = fragment.indexOf('?');
- if (queryIndex === -1) return uri;
- const hashPart = fragment.substring(0, queryIndex);
- const queryStr = fragment.substring(queryIndex + 1);
- const params = new URLSearchParams(queryStr);
- const host = params.get('h');
- if (!host) return uri;
- params.delete('h');
- let newFragment = hashPart;
- const remainingParams = params.toString();
- if (remainingParams) newFragment += '?' + remainingParams;
- return `https://${host}:/${linkType}#${newFragment}`;
- } else {
- return `https://simplex.chat/${linkType}#${fragment}`;
- }
-}
diff --git a/website/web.sh b/website/web.sh
index 9464982a45..49888f78aa 100755
--- a/website/web.sh
+++ b/website/web.sh
@@ -55,6 +55,10 @@ for lang in "${langs[@]}"; do
echo "done $lang copying"
done
+for f in src/js/*.jsc; do
+ [ -f "$f" ] && cpp -P -traditional-cpp "$f" "${f%.jsc}.js"
+done
+
npm run build
for lang in "${langs[@]}"; do