diff --git a/deno.json b/deno.json index 4755028..04fc917 100644 --- a/deno.json +++ b/deno.json @@ -33,12 +33,12 @@ "imports": { "@andyburke/fsdb": "jsr:@andyburke/fsdb@^1.0.2", "@andyburke/lurid": "jsr:@andyburke/lurid@^0.2.0", - "@andyburke/serverus": "jsr:@andyburke/serverus@^0.12.5", + "@andyburke/serverus": "jsr:@andyburke/serverus@^0.13.0", "@da/bcrypt": "jsr:@da/bcrypt@^1.0.1", - "@std/assert": "jsr:@std/assert@^1.0.13", + "@std/assert": "jsr:@std/assert@^1.0.14", "@std/encoding": "jsr:@std/encoding@^1.0.10", "@std/fs": "jsr:@std/fs@^1.0.19", "@std/http": "jsr:@std/http@^1.0.20", - "@std/path": "jsr:@std/path@^1.1.1" + "@std/path": "jsr:@std/path@^1.1.2" } } diff --git a/deno.lock b/deno.lock index 2c74cb8..3c409a2 100644 --- a/deno.lock +++ b/deno.lock @@ -3,10 +3,10 @@ "specifiers": { "jsr:@andyburke/fsdb@^1.0.2": "1.0.2", "jsr:@andyburke/lurid@0.2": "0.2.0", - "jsr:@andyburke/serverus@~0.12.5": "0.12.5", + "jsr:@andyburke/serverus@0.13": "0.13.0", "jsr:@da/bcrypt@*": "1.0.1", "jsr:@da/bcrypt@^1.0.1": "1.0.1", - "jsr:@std/assert@^1.0.13": "1.0.13", + "jsr:@std/assert@^1.0.14": "1.0.14", "jsr:@std/cli@^1.0.19": "1.0.21", "jsr:@std/cli@^1.0.20": "1.0.21", "jsr:@std/cli@^1.0.21": "1.0.21", @@ -17,12 +17,13 @@ "jsr:@std/fs@^1.0.19": "1.0.19", "jsr:@std/html@^1.0.4": "1.0.4", "jsr:@std/http@^1.0.20": "1.0.20", - "jsr:@std/internal@^1.0.6": "1.0.10", + "jsr:@std/internal@^1.0.10": "1.0.10", "jsr:@std/internal@^1.0.9": "1.0.10", "jsr:@std/media-types@^1.1.0": "1.1.0", "jsr:@std/net@^1.0.4": "1.0.4", - "jsr:@std/path@^1.1.0": "1.1.1", - "jsr:@std/path@^1.1.1": "1.1.1", + "jsr:@std/path@^1.1.0": "1.1.2", + "jsr:@std/path@^1.1.1": "1.1.2", + "jsr:@std/path@^1.1.2": "1.1.2", "jsr:@std/streams@^1.0.10": "1.0.10", "npm:@types/node@*": "22.15.15" }, @@ -41,8 +42,8 @@ "jsr:@std/cli@^1.0.19" ] }, - "@andyburke/serverus@0.12.5": { - "integrity": "c6bf017e82f20625f9d29dacaa7e2b034e91c37b8171f6725fade4599db66864", + "@andyburke/serverus@0.13.0": { + "integrity": "73f451e1b68cd9be3938333b06290bfeab275361453559f40dfeab19dc4ad6d7", "dependencies": [ "jsr:@std/cli@^1.0.21", "jsr:@std/fmt@^1.0.6", @@ -55,10 +56,10 @@ "@da/bcrypt@1.0.1": { "integrity": "d2172d3acbcff52e0465557a1a48b1ff1c92df08c90712dae5372255a8c45eb3" }, - "@std/assert@1.0.13": { - "integrity": "ae0d31e41919b12c656c742b22522c32fb26ed0cba32975cb0de2a273cb68b29", + "@std/assert@1.0.14": { + "integrity": "68d0d4a43b365abc927f45a9b85c639ea18a9fab96ad92281e493e4ed84abaa4", "dependencies": [ - "jsr:@std/internal@^1.0.6" + "jsr:@std/internal@^1.0.10" ] }, "@std/cli@1.0.21": { @@ -103,10 +104,10 @@ "@std/net@1.0.4": { "integrity": "2f403b455ebbccf83d8a027d29c5a9e3a2452fea39bb2da7f2c04af09c8bc852" }, - "@std/path@1.1.1": { - "integrity": "fe00026bd3a7e6a27f73709b83c607798be40e20c81dde655ce34052fd82ec76", + "@std/path@1.1.2": { + "integrity": "c0b13b97dfe06546d5e16bf3966b1cadf92e1cc83e56ba5476ad8b498d9e3038", "dependencies": [ - "jsr:@std/internal@^1.0.9" + "jsr:@std/internal@^1.0.10" ] }, "@std/streams@1.0.10": { @@ -131,13 +132,13 @@ "dependencies": [ "jsr:@andyburke/fsdb@^1.0.2", "jsr:@andyburke/lurid@0.2", - "jsr:@andyburke/serverus@~0.12.5", + "jsr:@andyburke/serverus@0.13", "jsr:@da/bcrypt@^1.0.1", - "jsr:@std/assert@^1.0.13", + "jsr:@std/assert@^1.0.14", "jsr:@std/encoding@^1.0.10", "jsr:@std/fs@^1.0.19", "jsr:@std/http@^1.0.20", - "jsr:@std/path@^1.1.1" + "jsr:@std/path@^1.1.2" ] } } diff --git a/public/base.css b/public/base.css index 8e5c01e..b96af08 100644 --- a/public/base.css +++ b/public/base.css @@ -1,12 +1,11 @@ - /* Dark mode default */ :root { --base-color: #fa0; --bg: hsl(from var(--base-color) h 20% 7.5%); - --text: hsl(from var(--base-color) h 5% 100% ); - --accent: hsl(from var(--base-color) h clamp( 0, calc(s + 10), 100 ) clamp( 0, calc(l + 20), 100 ) ); + --text: hsl(from var(--base-color) h 5% 100%); + --accent: hsl(from var(--base-color) h clamp(0, calc(s + 10), 100) clamp(0, calc(l + 20), 100)); --border-subtle: hsl(from var(--base-color) h 50% 25%); --border-normal: hsl(from var(--base-color) h 50% 50%); @@ -20,8 +19,8 @@ :root { --bg: hsl(from var(--base-color) h 20% 95%); - --text: hsl(from var(--base-color) h 5% 5% ); - --accent: hsl(from var(--base-color) h calc(s + 10) calc(l + 20) ); + --text: hsl(from var(--base-color) h 5% 5%); + --accent: hsl(from var(--base-color) h calc(s + 10) calc(l + 20)); --border-subtle: hsl(from var(--base-color) h 50% 90%); --border-normal: hsl(from var(--base-color) h 50% 50%); @@ -121,7 +120,20 @@ body { background-color: var(--bg); display: flex; flex-direction: column; - height: 100vh; // fixed height? + height: 100vh; /* fixed height? */ +} + +input[type="text"]:focus, +input[type="textarea"]:focus, +textarea:focus { + border-color: rgb(from var(--border-highlight) r g b / 60%); + outline: 0; + -webkit-box-shadow: + inset 0 1px 1px rgba(0, 0, 0, 0.075), + 0 0 2px rgb(from var(--border-highlight) r g b / 60%); + box-shadow: + inset 0 1px 1px rgba(0, 0, 0, 0.075), + 0 0 2px rgb(from var(--border-highlight) r g b / 60%); } .clickable { @@ -134,6 +146,26 @@ body { border-right: 4px solid #444; } +.mockup { + position: relative; +} + +.mockup::after { + content: ""; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: repeating-linear-gradient( + -55deg, + rgba(0, 0, 0, 0.25) 0px, + rgba(0, 0, 0, 0.25) 20px, + rgba(255, 177, 1, 0.25) 20px, + rgba(255, 177, 1, 0.25) 40px + ); +} + form div { position: relative; display: flex; @@ -164,7 +196,7 @@ form input:valid ~ label { form input { width: 100%; padding: 20px; - border: 1px solid var(--text); + border: 1px solid rgb(from var(--text) r g b / 60%); font-size: 20px; background-color: var(--bg); color: var(--text); @@ -288,7 +320,11 @@ body[data-perms*="topics.create"] [data-requires-permission="topics.create"] { max-width: 800px; } -.audio-container .audio-controls-container .progress-container .slider-container input[name="progress"] { +.audio-container + .audio-controls-container + .progress-container + .slider-container + input[name="progress"] { width: 100%; } @@ -320,56 +356,58 @@ body[data-perms*="topics.create"] [data-requires-permission="topics.create"] { } .audio-container .audio-controls-container input[type="range"] { - --c: var(--accent); /* active color */ - --g: 4px; /* the gap */ - --l: 2px; /* line thickness*/ - --s: 15px; /* thumb size*/ + --c: var(--accent); /* active color */ + --g: 4px; /* the gap */ + --l: 2px; /* line thickness*/ + --s: 15px; /* thumb size*/ - width: 100%; - height: var(--s); /* needed for Firefox*/ - --_c: color-mix(in srgb, var(--c), #000 var(--p,0%)); - -webkit-appearance :none; - -moz-appearance :none; - appearance :none; - background: none; - cursor: pointer; - overflow: hidden; + width: 100%; + height: var(--s); /* needed for Firefox*/ + --_c: color-mix(in srgb, var(--c), #000 var(--p, 0%)); + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background: none; + cursor: pointer; + overflow: hidden; } .audio-container .audio-controls-container input[type="range"]:focus-visible, .audio-container .audio-controls-container input[type="range"]:hover { - --p: 25%; + --p: 25%; } .audio-container .audio-controls-container input[type="range"]:active, -.audio-container .audio-controls-container input[type="range"]:focus-visible{ - --_b: var(--s) +.audio-container .audio-controls-container input[type="range"]:focus-visible { + --_b: var(--s); } /* chromium */ -.audio-container .audio-controls-container input[type="range"]::-webkit-slider-thumb{ - height: var(--s); - aspect-ratio: 1; - border-radius: 50%; - box-shadow: 0 0 0 var(--_b,var(--l)) inset var(--_c); - border-image: linear-gradient(90deg,var(--_c) 50%,#ababab 0) 0 1/calc(50% - var(--l)/2) 100vw/0 calc(100vw + var(--g)); - -webkit-appearance: none; - appearance: none; - transition: .2s; +.audio-container .audio-controls-container input[type="range"]::-webkit-slider-thumb { + height: var(--s); + aspect-ratio: 1; + border-radius: 50%; + box-shadow: 0 0 0 var(--_b, var(--l)) inset var(--_c); + border-image: linear-gradient(90deg, var(--_c) 50%, #ababab 0) 0 1 / calc(50% - var(--l) / 2) + 100vw/0 calc(100vw + var(--g)); + -webkit-appearance: none; + appearance: none; + transition: 0.2s; } /* Firefox */ .audio-container .audio-controls-container input[type="range"]::-moz-range-thumb { - height: var(--s); - width: var(--s); - background: none; - border-radius: 50%; - box-shadow: 0 0 0 var(--_b,var(--l)) inset var(--_c); - border-image: linear-gradient(90deg,var(--_c) 50%,#ababab 0) 0 1/calc(50% - var(--l)/2) 100vw/0 calc(100vw + var(--g)); - -moz-appearance: none; - appearance: none; - transition: .2s; + height: var(--s); + width: var(--s); + background: none; + border-radius: 50%; + box-shadow: 0 0 0 var(--_b, var(--l)) inset var(--_c); + border-image: linear-gradient(90deg, var(--_c) 50%, #ababab 0) 0 1 / calc(50% - var(--l) / 2) + 100vw/0 calc(100vw + var(--g)); + -moz-appearance: none; + appearance: none; + transition: 0.2s; } -@supports not (color: color-mix(in srgb,red,red)) { - .audio-container .audio-controls-container input[type="range"] { - --_c: var(--c); - } +@supports not (color: color-mix(in srgb, red, red)) { + .audio-container .audio-controls-container input[type="range"] { + --_c: var(--c); + } } .audio-container .audio-controls-container .volume label[for="volume"] { @@ -399,6 +437,14 @@ body[data-perms*="topics.create"] [data-requires-permission="topics.create"] { display: block; } +.html-from-markdown { + padding: 2em; +} + +.inline { + display: inline-block !important; +} + /* ICONS */ .icon { width: 24px; @@ -447,7 +493,6 @@ body[data-perms*="topics.create"] [data-requires-permission="topics.create"] { left: 8px; } - /* ICON - ATTACHMENT */ .icon.attachment { box-sizing: border-box; @@ -490,6 +535,38 @@ body[data-perms*="topics.create"] [data-requires-permission="topics.create"] { bottom: 4px; } +/* ICON - BLURB */ +.icon.blurb { + box-sizing: border-box; + position: relative; + display: block; + transform: scale(var(--icon-scale, 1)); + border: 2px solid; + border-radius: 3px; + width: 22px; + height: 16px; +} +.icon.blurb::after, +.icon.blurb::before { + content: ""; + display: block; + box-sizing: border-box; + position: absolute; + height: 2px; + border-radius: 3px; + background: currentColor; + bottom: 2px; +} +.icon.blurb::before { + width: 10px; + left: 2px; + box-shadow: 4px -4px 0; +} +.icon.blurb::after { + width: 3px; + right: 2px; + box-shadow: -11px -4px 0; +} /* ICON - CALENDAR */ .icon.calendar, @@ -524,13 +601,8 @@ body[data-perms*="topics.create"] [data-requires-permission="topics.create"] { position: relative; display: block; transform: scale(var(--icon-scale, 1)); - width: 20px; - height: 16px; - border: 2px solid; - border-bottom: 0; - box-shadow: - -6px 8px 0 -6px, - 6px 8px 0 -6px; + width: 14px; + height: 10px; } .icon.chat::after, .icon.chat::before { @@ -538,53 +610,60 @@ body[data-perms*="topics.create"] [data-requires-permission="topics.create"] { display: block; box-sizing: border-box; position: absolute; - width: 8px; -} -.icon.chat::before { - border: 2px solid; - border-top-color: transparent; - border-bottom-left-radius: 20px; - right: 4px; - bottom: -6px; - height: 6px; -} -.icon.chat::after { + border-radius: 3px; height: 2px; background: currentColor; - box-shadow: 0 4px 0 0; - left: 4px; - top: 4px; +} +.icon.chat::before { + width: 10px; + opacity: 0.5; + box-shadow: 0 4px 0; +} +.icon.chat::after { + width: 14px; + bottom: 0; +} + +/* ICON - CIRCLE */ +.icon.circle { + box-sizing: border-box; + position: relative; + display: block; + transform: scale(var(--icon-scale, 1)); + width: 19px; + height: 19px; + border: 2px solid; + border-radius: 100px; } /* ICON - CONTROLLER */ .icon.controller { - box-sizing: border-box; - position: relative; - display: block; - transform: scale(var(--icon-scale, 1)); - width: 8px; - height: 8px; - border: 2px solid; - border-radius: 100px; + box-sizing: border-box; + position: relative; + display: block; + transform: scale(var(--icon-scale, 1)); + width: 8px; + height: 8px; + border: 2px solid; + border-radius: 100px; } .icon.controller::before { - content: ""; - display: block; - box-sizing: border-box; - position: absolute; - width: 14px; - height: 14px; - box-shadow: - -6px -6px 0 -4px, - 6px 6px 0 -4px, - 6px -6px 0 -4px, - -6px 6px 0 -4px; - left: -5px; - top: -5px; - transform: rotate(45deg); + content: ""; + display: block; + box-sizing: border-box; + position: absolute; + width: 14px; + height: 14px; + box-shadow: + -6px -6px 0 -4px, + 6px 6px 0 -4px, + 6px -6px 0 -4px, + -6px 6px 0 -4px; + left: -5px; + top: -5px; + transform: rotate(45deg); } - /* ICON - DOWNLOAD */ .icon.download { box-sizing: border-box; @@ -625,6 +704,42 @@ body[data-perms*="topics.create"] [data-requires-permission="topics.create"] { bottom: 5px; } +/* ICON - ESSAY */ +.icon.essay { + box-sizing: border-box; + position: relative; + display: block; + transform: scale(var(--icon-scale, 1)); + width: 22px; + height: 18px; + border: 2px solid; + border-radius: 3px; + box-shadow: 0 -1px 0; +} +.icon.essay::after, +.icon.essay::before { + content: ""; + display: block; + box-sizing: border-box; + position: absolute; + width: 6px; + top: 2px; +} +.icon.essay::before { + background: currentColor; + left: 2px; + box-shadow: + 0 4px 0, + 0 8px 0; + border-radius: 3px; + height: 2px; +} +.icon.essay::after { + height: 10px; + border: 2px solid; + right: 2px; + border-radius: 1px; +} /* ICON - EXCHANGE */ .icon.exchange, @@ -657,6 +772,40 @@ body[data-perms*="topics.create"] [data-requires-permission="topics.create"] { right: -5px; } +/* ICON - FORUM */ +.icon.forum { + box-sizing: border-box; + position: relative; + display: block; + transform: scale(var(--icon-scale, 1)); + width: 16px; + height: 14px; + border-bottom: 2px solid; +} +.icon.forum::after, +.icon.forum::before { + content: ""; + display: block; + box-sizing: border-box; + position: absolute; + top: 2px; +} +.icon.forum::before { + border-left: 4px solid; + left: 1px; + width: 0; + height: 0; + border-top: 3px solid transparent; + border-bottom: 3px solid transparent; +} +.icon.forum::after { + width: 8px; + height: 6px; + border-top: 2px solid; + border-bottom: 2px solid; + right: 0; +} + /* ICON - FORWARD */ .icon.forward-copy { box-sizing: border-box; @@ -696,10 +845,8 @@ body[data-perms*="topics.create"] [data-requires-permission="topics.create"] { /* ICON - HOME */ .icon.home { background: - linear-gradient(to left, currentColor 5px, transparent 0) no-repeat 0 bottom/4px - 2px, - linear-gradient(to left, currentColor 5px, transparent 0) no-repeat right - bottom/4px 2px; + linear-gradient(to left, currentColor 5px, transparent 0) no-repeat 0 bottom/4px 2px, + linear-gradient(to left, currentColor 5px, transparent 0) no-repeat right bottom/4px 2px; box-sizing: border-box; position: relative; display: block; @@ -768,8 +915,8 @@ body[data-perms*="topics.create"] [data-requires-permission="topics.create"] { top: 6px; left: 8px; box-shadow: - -5px 0 0, - 5px 0 0; + -5px 0 0, + 5px 0 0; } /* ICON - MOREBORDERLESS */ @@ -823,11 +970,10 @@ body[data-perms*="topics.create"] [data-requires-permission="topics.create"] { top: 8px; left: 8px; box-shadow: - -5px 0 0, - 5px 0 0; + -5px 0 0, + 5px 0 0; } - /* ICON - PLUS */ .icon.plus, .icon.plus::after, @@ -996,7 +1142,10 @@ body[data-perms*="topics.create"] [data-requires-permission="topics.create"] { width: 10px; height: 12px; border: 2px solid transparent; - box-shadow: 0 0 0 2px, inset -2px 0 0, inset 2px 0 0; + box-shadow: + 0 0 0 2px, + inset -2px 0 0, + inset 2px 0 0; border-bottom-left-radius: 1px; border-bottom-right-radius: 1px; margin-top: 4px; @@ -1149,175 +1298,172 @@ body[data-perms*="topics.create"] [data-requires-permission="topics.create"] { left: 11px; } - /* AUDIO PLAYER ICONS */ .icon.skip-back { - box-sizing: border-box; - position: relative; - display: block; - transform: scale(var(--icon-scale, 1)); - width: 22px; - height: 22px; - border: 2px solid; - border-radius: 4px; + box-sizing: border-box; + position: relative; + display: block; + transform: scale(var(--icon-scale, 1)); + width: 22px; + height: 22px; + border: 2px solid; + border-radius: 4px; } .icon.skip-back::after, .icon.skip-back::before { - content: ""; - display: block; - box-sizing: border-box; - position: absolute; - height: 8px; - top: 5px; + content: ""; + display: block; + box-sizing: border-box; + position: absolute; + height: 8px; + top: 5px; } .icon.skip-back::before { - width: 2px; - border-radius: 2px; - right: 11px; - background: currentColor; + width: 2px; + border-radius: 2px; + right: 11px; + background: currentColor; } .icon.skip-back::after { - width: 0; - border-top: 4px solid transparent; - border-bottom: 4px solid transparent; - border-right: 5px solid; - right: 5px; + width: 0; + border-top: 4px solid transparent; + border-bottom: 4px solid transparent; + border-right: 5px solid; + right: 5px; } .icon.rewind { - box-sizing: border-box; - position: relative; - display: block; - transform: scale(var(--icon-scale, 1)); - border: 2px solid; - border-radius: 4px; - width: 22px; - height: 22px; + box-sizing: border-box; + position: relative; + display: block; + transform: scale(var(--icon-scale, 1)); + border: 2px solid; + border-radius: 4px; + width: 22px; + height: 22px; } .icon.rewind::after, .icon.rewind::before { - content: ""; - display: block; - box-sizing: border-box; - position: absolute; - width: 6px; - height: 6px; - border-left: 2px solid; - border-bottom: 2px solid; - transform: rotate(45deg); - top: 6px; - left: 5px; + content: ""; + display: block; + box-sizing: border-box; + position: absolute; + width: 6px; + height: 6px; + border-left: 2px solid; + border-bottom: 2px solid; + transform: rotate(45deg); + top: 6px; + left: 5px; } .icon.rewind::after { - left: 9px; + left: 9px; } - .icon.play { - box-sizing: border-box; - position: relative; - display: block; - transform: scale(var(--icon-scale, 1)); - width: 22px; - height: 22px; - border: 2px solid; - border-radius: 4px; + box-sizing: border-box; + position: relative; + display: block; + transform: scale(var(--icon-scale, 1)); + width: 22px; + height: 22px; + border: 2px solid; + border-radius: 4px; } .icon.play::before { - content: ""; - display: block; - box-sizing: border-box; - position: absolute; - width: 0; - height: 10px; - border-top: 5px solid transparent; - border-bottom: 5px solid transparent; - border-left: 6px solid; - top: 4px; - left: 7px; + content: ""; + display: block; + box-sizing: border-box; + position: absolute; + width: 0; + height: 10px; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 6px solid; + top: 4px; + left: 7px; } .icon.pause { - box-sizing: border-box; - position: relative; - display: block; - transform: scale(var(--icon-scale, 1)); - width: 22px; - height: 22px; - border: 2px solid; - border-radius: 4px; + box-sizing: border-box; + position: relative; + display: block; + transform: scale(var(--icon-scale, 1)); + width: 22px; + height: 22px; + border: 2px solid; + border-radius: 4px; } .icon.pause::before { - content: ""; - display: block; - box-sizing: border-box; - position: absolute; - width: 6px; - height: 6px; - left: 6px; - top: 6px; - border-left: 2px solid; - border-right: 2px solid; + content: ""; + display: block; + box-sizing: border-box; + position: absolute; + width: 6px; + height: 6px; + left: 6px; + top: 6px; + border-left: 2px solid; + border-right: 2px solid; } .icon.fastforward { - box-sizing: border-box; - position: relative; - display: block; - transform: scale(var(--icon-scale, 1)); - border: 2px solid; - border-radius: 4px; - width: 22px; - height: 22px; + box-sizing: border-box; + position: relative; + display: block; + transform: scale(var(--icon-scale, 1)); + border: 2px solid; + border-radius: 4px; + width: 22px; + height: 22px; } .icon.fastforward::after, .icon.fastforward::before { - content: ""; - display: block; - box-sizing: border-box; - position: absolute; - width: 6px; - height: 6px; - border-right: 2px solid; - border-top: 2px solid; - transform: rotate(45deg); - top: 6px; - right: 5px; + content: ""; + display: block; + box-sizing: border-box; + position: absolute; + width: 6px; + height: 6px; + border-right: 2px solid; + border-top: 2px solid; + transform: rotate(45deg); + top: 6px; + right: 5px; } .icon.fastforward::after { - right: 9px; + right: 9px; } - .icon.skip-forward { - box-sizing: border-box; - position: relative; - display: block; - transform: scale(var(--icon-scale, 1)); - width: 22px; - height: 22px; - border: 2px solid; - border-radius: 4px; + box-sizing: border-box; + position: relative; + display: block; + transform: scale(var(--icon-scale, 1)); + width: 22px; + height: 22px; + border: 2px solid; + border-radius: 4px; } .icon.skip-forward::after, .icon.skip-forward::before { - content: ""; - display: block; - box-sizing: border-box; - position: absolute; - height: 8px; - top: 5px; + content: ""; + display: block; + box-sizing: border-box; + position: absolute; + height: 8px; + top: 5px; } .icon.skip-forward::before { - width: 2px; - border-radius: 2px; - left: 11px; - background: currentColor; + width: 2px; + border-radius: 2px; + left: 11px; + background: currentColor; } .icon.skip-forward::after { - width: 0; - border-top: 4px solid transparent; - border-bottom: 4px solid transparent; - border-left: 5px solid; - left: 5px; + width: 0; + border-top: 4px solid transparent; + border-bottom: 4px solid transparent; + border-left: 5px solid; + left: 5px; } diff --git a/public/js/smartforms.js b/public/js/smartforms.js index 9c4ca1f..e1366b9 100644 --- a/public/js/smartforms.js +++ b/public/js/smartforms.js @@ -21,6 +21,18 @@ document.addEventListener("DOMContentLoaded", () => { const form_data = new FormData(form); for (const [key, value] of form_data.entries()) { + if (key.length === 0) { + continue; + } + + if (typeof value === "string" && value.length === 0) { + const input = form.querySelector(`[name="${key}"]`); + const should_submit_empty = input && input.dataset["smartformsSubmitEmpty"]; + if (!should_submit_empty) { + continue; + } + } + const elements = key.split("."); let current = json; for (const element of elements.slice(0, elements.length - 1)) { diff --git a/public/sidebar/sidebar.html b/public/sidebar/sidebar.html index a97b32f..38f80d4 100644 --- a/public/sidebar/sidebar.html +++ b/public/sidebar/sidebar.html @@ -129,63 +129,244 @@ -