aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorXe Iaso <me@christine.website>2022-11-24 18:55:21 -0500
committerXe Iaso <me@christine.website>2022-11-24 18:55:21 -0500
commite174b7ba4dc1f6e755d6142f0d26a3e6357be771 (patch)
tree6d063747b3215100cc0e01038944f0b990d8a5fe /src
parentfacf97b1f861ea66961a72e43595c5a1b1db8a31 (diff)
downloadxesite-e174b7ba4dc1f6e755d6142f0d26a3e6357be771.tar.xz
xesite-e174b7ba4dc1f6e755d6142f0d26a3e6357be771.zip
make new mastodon share button
Signed-off-by: Xe Iaso <me@christine.website>
Diffstat (limited to 'src')
-rwxr-xr-xsrc/frontend/build.sh6
-rw-r--r--src/frontend/deno.json8
-rw-r--r--src/frontend/import_map.json8
-rw-r--r--src/frontend/mastodon_share_button.tsx55
-rw-r--r--src/frontend/xeact/jsx-runtime.js16
-rw-r--r--src/frontend/xeact/xeact.js88
-rw-r--r--src/frontend/xeact/xeact.ts9
7 files changed, 190 insertions, 0 deletions
diff --git a/src/frontend/build.sh b/src/frontend/build.sh
new file mode 100755
index 0000000..ad31763
--- /dev/null
+++ b/src/frontend/build.sh
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+
+set -e
+
+export RUST_LOG=info
+deno bundle ./mastodon_share_button.tsx ../../static/js/mastodon_share_button.js
diff --git a/src/frontend/deno.json b/src/frontend/deno.json
new file mode 100644
index 0000000..b763d25
--- /dev/null
+++ b/src/frontend/deno.json
@@ -0,0 +1,8 @@
+{
+ "compilerOptions": {
+ "jsx": "react-jsx",
+ "jsxImportSource": "xeact",
+ "lib": ["esnext", "dom", "dom.iterable"]
+ },
+ "importMap": "./import_map.json",
+}
diff --git a/src/frontend/import_map.json b/src/frontend/import_map.json
new file mode 100644
index 0000000..20cfc64
--- /dev/null
+++ b/src/frontend/import_map.json
@@ -0,0 +1,8 @@
+{
+ "imports": {
+ "xeact": "./xeact/xeact.ts",
+ "xeact/jsx-runtime": "./xeact/jsx-runtime.js",
+ "/": "./",
+ "./": "./"
+ }
+}
diff --git a/src/frontend/mastodon_share_button.tsx b/src/frontend/mastodon_share_button.tsx
new file mode 100644
index 0000000..64164a7
--- /dev/null
+++ b/src/frontend/mastodon_share_button.tsx
@@ -0,0 +1,55 @@
+import { g, r, u, x } from "xeact";
+
+r(() => {
+ const root = g("mastodon_share_button");
+
+ let defaultURL = localStorage["mastodon_instance"];
+
+ const title = document.querySelectorAll('meta[property="og:title"]')[0]
+ .getAttribute("content");
+ let series = g("mastodon_share_series").innerText;
+ if (series != "") {
+ series = `#${series} `;
+ }
+ const tags = g("mastodon_share_tags");
+ const articleURL = u();
+
+ const tootTemplate = `${title}
+
+${articleURL}
+
+${series}${tags.innerText}@cadey@pony.social`;
+
+ const instanceBox = (
+ <input type="text" placeholder="https://pony.social" value={defaultURL} />
+ );
+ const tootBox = <textarea rows="6" cols="40">{tootTemplate}</textarea>;
+
+ const doShare = () => {
+ const instanceURL = instanceBox.value;
+ localStorage["mastodon_instance"] = instanceURL;
+ const text = tootBox.value;
+ const mastodon_url = u(instanceURL + "/share", { text });
+ console.log({ text, mastodon_url });
+ window.open(mastodon_url, "_blank");
+ };
+
+ const shareButton = <button onclick={doShare}>Share</button>;
+
+ x(root);
+
+ root.appendChild(
+ <div>
+ <details>
+ <summary>Share on Mastodon</summary>
+ <span>Instance URL (https://mastodon.example)</span>
+ <br />
+ {instanceBox}
+ <br />
+ {tootBox}
+ <br />
+ {shareButton}
+ </details>
+ </div>,
+ );
+});
diff --git a/src/frontend/xeact/jsx-runtime.js b/src/frontend/xeact/jsx-runtime.js
new file mode 100644
index 0000000..58ccfaa
--- /dev/null
+++ b/src/frontend/xeact/jsx-runtime.js
@@ -0,0 +1,16 @@
+import { h } from './xeact.ts';
+
+/**
+ * Create a DOM element, assign the properties of `data` to it, and append all `data.children`.
+ *
+ * @type{function(string, Object=): HTMLElement}
+ */
+export const jsx = (tag, data) => {
+ let children = data.children;
+ delete data.children;
+ const result = h(tag, data, children);
+ result.classList.value = result.class;
+ return result;
+};
+export const jsxs = jsx;
+export const jsxDEV = jsx;
diff --git a/src/frontend/xeact/xeact.js b/src/frontend/xeact/xeact.js
new file mode 100644
index 0000000..7be9a1c
--- /dev/null
+++ b/src/frontend/xeact/xeact.js
@@ -0,0 +1,88 @@
+/**
+ * Creates a DOM element, assigns the properties of `data` to it, and appends all `children`.
+ *
+ * @type{function(string|Function, Object=, Node|Array.<Node|string>=)}
+ */
+const h = (name, data = {}, children = []) => {
+ const result = typeof name == "function" ? name(data) : Object.assign(document.createElement(name), data);
+ if (!Array.isArray(children)) {
+ children = [children];
+ }
+ result.append(...children);
+ return result;
+};
+
+/**
+ * Create a text node.
+ *
+ * Equivalent to `document.createTextNode(text)`
+ *
+ * @type{function(string): Text}
+ */
+const t = (text) => document.createTextNode(text);
+
+/**
+ * Remove all child nodes from a DOM element.
+ *
+ * @type{function(Node)}
+ */
+const x = (elem) => {
+ while (elem.lastChild) {
+ elem.removeChild(elem.lastChild);
+ }
+};
+
+/**
+ * Get all elements with the given ID.
+ *
+ * Equivalent to `document.getElementById(name)`
+ *
+ * @type{function(string): HTMLElement}
+ */
+const g = (name) => document.getElementById(name);
+
+/**
+ * Get all elements with the given class name.
+ *
+ * Equivalent to `document.getElementsByClassName(name)`
+ *
+ * @type{function(string): HTMLCollectionOf.<Element>}
+ */
+const c = (name) => document.getElementsByClassName(name);
+
+/** @type{function(string): HTMLCollectionOf.<Element>} */
+const n = (name) => document.getElementsByName(name);
+
+/**
+ * Get all elements matching the given HTML selector.
+ *
+ * Matches selectors with `document.querySelectorAll(selector)`
+ *
+ * @type{function(string): Array.<HTMLElement>}
+ */
+const s = (selector) => Array.from(document.querySelectorAll(selector));
+
+/**
+ * Generate a relative URL from `url`, appending all key-value pairs from `params` as URL-encoded parameters.
+ *
+ * @type{function(string=, Object=): string}
+ */
+const u = (url = "", params = {}) => {
+ let result = new URL(url, window.location.href);
+ Object.entries(params).forEach((kv) => {
+ let [k, v] = kv;
+ result.searchParams.set(k, v);
+ });
+ return result.toString();
+};
+
+/**
+ * Takes a callback to run when all DOM content is loaded.
+ *
+ * Equivalent to `window.addEventListener('DOMContentLoaded', callback)`
+ *
+ * @type{function(function())}
+ */
+const r = (callback) => window.addEventListener('DOMContentLoaded', callback);
+
+export { h, t, x, g, c, n, u, s, r };
diff --git a/src/frontend/xeact/xeact.ts b/src/frontend/xeact/xeact.ts
new file mode 100644
index 0000000..8974ec1
--- /dev/null
+++ b/src/frontend/xeact/xeact.ts
@@ -0,0 +1,9 @@
+export * from "./xeact.js";
+
+declare global {
+ export namespace JSX {
+ interface IntrinsicElements {
+ [elemName: string]: any;
+ }
+ }
+}