diff options
| author | Xe Iaso <me@christine.website> | 2022-11-24 18:55:21 -0500 |
|---|---|---|
| committer | Xe Iaso <me@christine.website> | 2022-11-24 18:55:21 -0500 |
| commit | e174b7ba4dc1f6e755d6142f0d26a3e6357be771 (patch) | |
| tree | 6d063747b3215100cc0e01038944f0b990d8a5fe /src | |
| parent | facf97b1f861ea66961a72e43595c5a1b1db8a31 (diff) | |
| download | xesite-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-x | src/frontend/build.sh | 6 | ||||
| -rw-r--r-- | src/frontend/deno.json | 8 | ||||
| -rw-r--r-- | src/frontend/import_map.json | 8 | ||||
| -rw-r--r-- | src/frontend/mastodon_share_button.tsx | 55 | ||||
| -rw-r--r-- | src/frontend/xeact/jsx-runtime.js | 16 | ||||
| -rw-r--r-- | src/frontend/xeact/xeact.js | 88 | ||||
| -rw-r--r-- | src/frontend/xeact/xeact.ts | 9 |
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; + } + } +} |
