diff --git a/modules/parser-parsedown.php b/modules/parser-parsedown.php index 7377466..82caa69 100644 --- a/modules/parser-parsedown.php +++ b/modules/parser-parsedown.php @@ -389,6 +389,8 @@ register_module([ Some text ==marked text== more textSome text marked text more textMarked / highlighted text [ ] Unticked checkboxAn unticked checkbox. Must be at the beginning of a line or directly after a list item (e.g. - or 1. ). [x] Ticked checkboxAn ticked checkbox. The same rules as unticked checkboxes apply here too. + some text >!spoiler text!< more textA spoiler. Users much click it to reveal the content hidden beneath. + some text ||spoiler text|| more textAlternative spoiler syntax inspired by Discord.

Note that the all image image syntax above can be mixed and matched to your liking. The caption option in particular must come last or next to last.

Templating

@@ -506,6 +508,9 @@ class PeppermintParsedown extends ParsedownExtra $this->addInlineType("=", "Mark"); $this->addInlineType("^", "Superscript"); $this->addInlineType("~", "Subscript"); + + $this->addInlineType(">", "Spoiler", true); + $this->addInlineType("|", "Spoiler", true); } /** @@ -783,7 +788,9 @@ class PeppermintParsedown extends ParsedownExtra * ██ ███████ ██ ██ ██ */ protected function inlineMark($fragment) { - if(preg_match('/==([^=]+)==/', $fragment["text"], $matches) !== 1) + // A question mark makes the PCRE 1-or-more + there lazy instead of greedy. + // Ref https://www.rexegg.com/regex-quantifiers.html#greedytrap + if(preg_match('/==([^=]+?)==/', $fragment["text"], $matches) !== 1) return; $marked_text = $matches[1]; @@ -817,7 +824,7 @@ class PeppermintParsedown extends ParsedownExtra * ██████ ██████ ██ ██ ██ ██ ██ */ protected function inlineSuperscript($fragment) { - if(preg_match('/\^([^^]+)\^/', $fragment["text"], $matches) !== 1) + if(preg_match('/\^([^^]+?)\^/', $fragment["text"], $matches) !== 1) return; $superscript_text = $matches[1]; @@ -836,7 +843,7 @@ class PeppermintParsedown extends ParsedownExtra return $result; } protected function inlineSubscript($fragment) { - if(preg_match('/~([^~]+)~/', $fragment["text"], $matches) !== 1) + if(preg_match('/~([^~]+?)~/', $fragment["text"], $matches) !== 1) return; $subscript_text = $matches[1]; @@ -855,6 +862,41 @@ class PeppermintParsedown extends ParsedownExtra return $result; } + + /* + * ███████ ██████ ██████ ██ ██ ███████ ██████ + * ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ + * ███████ ██████ ██ ██ ██ ██ █████ ██████ + * ██ ██ ██ ██ ██ ██ ██ ██ ██ + * ███████ ██ ██████ ██ ███████ ███████ ██ ██ + */ + protected function inlineSpoiler($fragment) { + if(preg_match('/(?:\|\||>!)([^|]+?)(?:\|\||!<)/', $fragment["text"], $matches) !== 1) + return; + + $spoiler_text = $matches[1]; + $id = "spoiler-".crypto_id(24); + + $result = [ + "extent" => strlen($matches[0]), + "element" => [ + "name" => "a", + "attributes" => [ + "id" => $id, + "class" => "spoiler", + "href" => "#$id" + ], + "handler" => [ + "function" => "lineElements", + "argument" => $spoiler_text, + "destination" => "elements" + ] + ] + ]; + return $result; + } + + /* * ██ ███ ██ ████████ ███████ ██████ ███ ██ █████ ██ * ██ ████ ██ ██ ██ ██ ██ ████ ██ ██ ██ ██ diff --git a/themes/blue/theme.css b/themes/blue/theme.css index 5189203..a2cc5a8 100644 --- a/themes/blue/theme.css +++ b/themes/blue/theme.css @@ -227,6 +227,19 @@ a.redlink:link{ a.redlink:visited{ color:rgb(130, 15, 15); } + +.spoiler { background: #333333; border-radius: 0.2em; color: transparent; } +.spoiler:target { background: transparent; color: inherit; } + +/* Ref https://devdocs.io/html/element/del#Accessibility_concerns it's better than nothing, but I'm not happy with it. How would a screen reader user skipt he spsoiler if they don't want to hear it? */ +.spoiler::before, .spoiler::after { + clip-path: inset(100%); clip: rect(1px, 1px, 1px, 1px); + position: absolute; width: 1px; height: 1px; + overflow: hidden; white-space: nowrap; +} +.spoiler::before { content: " [spoiler start] "; } +.spoiler::after { content: " [spoiler end] "; } + .matching-tags-display{ display:flex; margin:0 -2em; diff --git a/themes/default/theme.css b/themes/default/theme.css index b5020b5..4dfe61b 100644 --- a/themes/default/theme.css +++ b/themes/default/theme.css @@ -182,6 +182,19 @@ a.interwiki_link { color: var(--accent-d1); } a.interwiki_link:visited { color: var(--accent-d2); } a.interwiki_link:active { color: var(--accent-d3); } +.spoiler { background: var(--accent-a2); border: 0.1em dashed var(--accent-b1); border-radius: 0.2em; color: transparent !important; text-decoration: none; } +.spoiler:target { color: inherit !important; } + +/* Ref https://devdocs.io/html/element/del#Accessibility_concerns it's better than nothing, but I'm not happy with it. How would a screen reader user skipt he spsoiler if they don't want to hear it? */ +.spoiler::before, .spoiler::after { + clip-path: inset(100%); clip: rect(1px, 1px, 1px, 1px); + position: absolute; width: 1px; height: 1px; + overflow: hidden; white-space: nowrap; +} +.spoiler::before { content: " [spoiler start] "; } +.spoiler::after { content: " [spoiler end] "; } + + .matching-tags-display { display: flex; margin: 0 -2em; padding: 1em 2em; background: hsla(30, 84%, 72%, 0.75); } .matching-tags-display > label { flex: 0; font-weight: bold; color: var(--accent-a3); } .matching-tags-display > .tags { flex: 2; } @@ -194,7 +207,7 @@ a.interwiki_link:active { color: var(--accent-d3); } .search-context { min-height: 3em; max-height: 20em; overflow: hidden; } .editform { position: relative; } -textarea[name=content] { resize: none; } +textarea[name=content] { resize: none; min-height: 75vh; } .fit-text-mirror { position: absolute; top: 0; left: -10000vw; word-wrap: break-word; white-space: pre-wrap; } .awesomplete { width: 100%; color: var(--text-dark); } diff --git a/themes/photo/theme.css b/themes/photo/theme.css index 9985c60..70d502c 100644 --- a/themes/photo/theme.css +++ b/themes/photo/theme.css @@ -113,6 +113,18 @@ th, td { padding: 0.25em 0.45em; } pre, code, input, textarea { font-size: 1rem; } img, video, audio { max-width: 100%; } +.spoiler { background: #333333; border-radius: 0.2em; color: transparent; } +.spoiler:target { background: transparent; color: inherit; } + +/* Ref https://devdocs.io/html/element/del#Accessibility_concerns it's better than nothing, but I'm not happy with it. How would a screen reader user skipt he spsoiler if they don't want to hear it? */ +.spoiler::before, .spoiler::after { + clip-path: inset(100%); clip: rect(1px, 1px, 1px, 1px); + position: absolute; width: 1px; height: 1px; + overflow: hidden; white-space: nowrap; +} +.spoiler::before { content: " [spoiler start] "; } +.spoiler::after { content: " [spoiler end] "; } + main label { font-weight: bold; display: inline-block; min-width: 12em; } textarea { min-height: 10em; }