add spoiler_bbc

This commit is contained in:
snow flurry 2025-04-25 23:52:18 -07:00
parent 638fc72ccd
commit a401fc5f38
15 changed files with 1091 additions and 1 deletions

View file

@ -5,7 +5,8 @@ MODS := \
media_bbc \
yt_nocookie \
topic_mute \
dragdrop_attach
dragdrop_attach \
spoiler_bbc
PKGDIR := $(PWD)/../packages

View file

@ -168,4 +168,13 @@
/* ajax notification bar */
--notify-bar-background: var(--main-background);
--notify-bar-color: #f96f00;
/* spoilers (requires spoilers_bbc) */
--spoiler-border: #757;
--spoiler-head-background: #dcd;
--spoiler-main-background: #fff9ff;
--noguest-border: #557;
--noguest-head-background: #dde;
--noguest-main-background: #f9f9ff;
}

View file

@ -66,4 +66,11 @@
--input-valid: #242;
--input-invalid: #422;
/* spoilers (requires spoilers_bbc) */
--spoiler-head-background: #3f2a3f;
--spoiler-main-background: #3a333a;
--noguest-head-background: #2a2a3f;
--noguest-main-background: #33333f;
}

View file

@ -1,4 +1,6 @@
/*! SCEditor | (C) 2011-2013, Sam Clarke | sceditor.com/license */
@import url("../../default/css/spoiler_bbc.css");
html, p, code::before, div, table {
margin: 0;
padding: 0;

View file

@ -0,0 +1,3 @@
PROJECT := spoiler_bbc
include ../plugin.mk

View file

@ -0,0 +1,66 @@
<?php
function hook_spoiler_bbcode(&$codes, &$no_autolink_tags) {
global $modSettings, $context, $user_info;
$codes[] = array(
'tag' => 'spoiler',
'before' => '<details class="collapsible spoiler"><summary>Spoiler</summary> <div>',
'after' => '</div></details>',
'block_level' => true,
);
$codes[] = array(
'tag' => 'spoiler',
'type' => 'parsed_equals',
'before' => '<details class="collapsible spoiler"><summary>$1</summary> <div>',
'after' => '</div></details>',
'block_level' => true,
);
$codes[] = array(
'tag' => 'noguest',
// 'parsed_content' works by writing 'before' when it encounters the
// beginning tag, and eventually replacing the end tag with 'after'. We
// need to "parse" the content to perform the is_guest validation,
// though! So our compromise is to not allow BBCode within [noguest].
//
// *Theoretically*, we could recursively call parse_bbc, but that is a
// can of worms I do not wish to open today.
'type' => 'unparsed_content',
'content' => '<details class="collapsible noguest" open><summary>Logged-in users only</summary><div>$1</div></details>',
'validate' => function(&$tag, &$data, $disabled, $params) use ($modSettings, $context, $user_info)
{
if ($user_info['is_guest']) {
$data = 'Sorry, this content is only available for logged-in users.';
}
},
'block_level' => true,
);
}
function hook_spoiler_bbcode_buttons(&$bbc_tags) {
$bbc_tags[] = array(
array(
'code' => 'spoiler',
'description' => 'Insert Spoiler block',
),
array(
'code' => 'noguest',
'description' => 'Insert block for logged-in users only',
),
);
}
function spoiler_sce_options(&$sce_options) {
loadJavaScriptFile('sceditor.spoilerbbc.js', array('minimize' => true), 'smf_sceditor_spoiler');
loadCSSFile('sceditor.spoilerbbc.css', array('minimize' => true));
}
function spoiler_bbc_credits() {
global $context;
$context['credits_modifications'][] = 'Silk SVG icons by <a href="https://github.com/frhun">@frhun</a>, licensed under CC-BY-SA';
}
function hook_spoiler_load_theme() {
loadCSSFile('spoiler_bbc.css', array('minimize' => true));
}
?>

View file

@ -0,0 +1,175 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="31.999998"
height="31.999998"
viewBox="0 0 8.466666 8.466666"
version="1.1"
id="svg1"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1">
<linearGradient
id="linearGradient19">
<stop
style="stop-color:#b5bfc9;stop-opacity:0.76999998;"
offset="0"
id="stop20" />
<stop
style="stop-color:#cfd3d8;stop-opacity:0;"
offset="0.2510533"
id="stop22" />
<stop
style="stop-color:#ccd1d6;stop-opacity:0;"
offset="0.75"
id="stop23" />
<stop
style="stop-color:#c8d3da;stop-opacity:0.63999999;"
offset="1"
id="stop21" />
</linearGradient>
<linearGradient
id="linearGradient15">
<stop
style="stop-color:#cbd2d7;stop-opacity:0.75088906;"
offset="0"
id="stop16" />
<stop
style="stop-color:#e5e9eb;stop-opacity:1;"
offset="0.18264508"
id="stop18" />
<stop
style="stop-color:#cfd3d8;stop-opacity:1;"
offset="0.75229496"
id="stop19" />
<stop
style="stop-color:#bbc0c9;stop-opacity:1;"
offset="1"
id="stop17" />
</linearGradient>
<linearGradient
id="linearGradient8">
<stop
style="stop-color:#bec2c5;stop-opacity:0.60000002;"
offset="0"
id="stop8" />
<stop
style="stop-color:#e3e5e8;stop-opacity:0;"
offset="0.50365794"
id="stop10" />
<stop
style="stop-color:#e3e5e8;stop-opacity:0;"
offset="0.64754182"
id="stop11" />
<stop
style="stop-color:#d1d6db;stop-opacity:0.60000002;"
offset="1"
id="stop9" />
</linearGradient>
<linearGradient
id="linearGradient2">
<stop
style="stop-color:#a9b7c6;stop-opacity:1;"
offset="0"
id="stop2" />
<stop
style="stop-color:#cfd4d8;stop-opacity:1;"
offset="0.25"
id="stop5" />
<stop
style="stop-color:#cfd4d8;stop-opacity:1;"
offset="0.75"
id="stop4" />
<stop
style="stop-color:#c1c6cc;stop-opacity:1;"
offset="1"
id="stop3" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient2"
id="linearGradient3"
x1="-7.1332073"
y1="-7.1332073"
x2="-1.3334589"
y2="-1.3334588"
gradientUnits="userSpaceOnUse" />
<linearGradient
xlink:href="#linearGradient8"
id="linearGradient9"
x1="-6.8694334"
y1="-7.3749137"
x2="-1.5972348"
y2="-1.0917524"
gradientUnits="userSpaceOnUse" />
<linearGradient
xlink:href="#linearGradient15"
id="linearGradient17"
x1="3.8879335"
y1="0.28018543"
x2="4.5797324"
y2="8.1874809"
gradientUnits="userSpaceOnUse" />
<linearGradient
xlink:href="#linearGradient19"
id="linearGradient21"
x1="7.0401654"
y1="1.4275031"
x2="1.4275045"
y2="7.040164"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-8.4676666,-8.4676666)" />
</defs>
<rect
style="font-variation-settings:normal;opacity:1;vector-effect:none;fill:url(#linearGradient17);stroke:none;stroke-width:0.263583;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none"
id="rect8"
width="7.9375"
height="7.9375"
x="0.26508331"
y="0.26508331"
rx="1.5875"
ry="1.5875" />
<rect
style="font-variation-settings:normal;opacity:1;vector-effect:none;fill:url(#linearGradient21);stroke:none;stroke-width:0.263583;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none"
id="rect19"
width="7.9375"
height="7.9375"
x="-8.2025833"
y="-8.2025833"
rx="1.5875"
ry="1.5875"
transform="scale(-1)" />
<g
id="layer1"
style="font-variation-settings:normal;opacity:1;vector-effect:none;fill:url(#linearGradient3);fill-opacity:1;stroke:#525252;stroke-width:0.263583;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;stop-color:#000000;stop-opacity:1">
<rect
style="font-variation-settings:normal;vector-effect:none;fill:url(#linearGradient9);fill-opacity:1;stroke:#525252;stroke-width:0.263583;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;stop-color:#000000;stop-opacity:1"
id="rect5"
width="7.9385004"
height="7.9385004"
x="-8.2025833"
y="-8.2025833"
rx="1.5814996"
ry="1.5814996"
transform="scale(-1)" />
</g>
<g
id="layer2"
style="font-variation-settings:normal;opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.687917;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;stop-color:#000000;stop-opacity:1">
<path
style="font-variation-settings:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.687917;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;stop-color:#000000;stop-opacity:1"
d="M 2.1166666,4.2333333 H 6.3499999"
id="path2402" />
</g>
<g
id="layer2-6"
style="font-variation-settings:normal;vector-effect:none;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.79375;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;stop-color:#000000"
transform="rotate(90,4.2333333,4.233333)">
<path
style="font-variation-settings:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.687917;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;stop-color:#000000;stop-opacity:1"
d="M 2.1166666,4.2333333 H 6.3499999"
id="path2402-2" />
</g>
</svg>

After

(image error) Size: 6.4 KiB

File diff suppressed because one or more lines are too long

After

(image error) Size: 25 KiB

View file

@ -0,0 +1,191 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="64"
height="64"
viewBox="0 0 64 64"
version="1.1"
id="svg8"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs
id="defs2">
<linearGradient
id="linearGradient914">
<stop
style="stop-color:#e9e9e9;stop-opacity:1"
offset="0"
id="stop910" />
<stop
style="stop-color:#fcfcfc;stop-opacity:1"
offset="1"
id="stop912" />
</linearGradient>
<linearGradient
id="linearGradient874">
<stop
style="stop-color:#000000;stop-opacity:0.21176471"
offset="0"
id="stop870" />
<stop
style="stop-color:#949494;stop-opacity:0.56862748"
offset="1"
id="stop872" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient874"
id="linearGradient905"
gradientUnits="userSpaceOnUse"
x1="8"
y1="60"
x2="48"
y2="8" />
<linearGradient
xlink:href="#linearGradient914"
id="linearGradient916"
x1="44"
y1="16"
x2="20"
y2="48"
gradientUnits="userSpaceOnUse" />
<linearGradient
xlink:href="#linearGradient884"
id="linearGradient886"
x1="12"
y1="24"
x2="54"
y2="24"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.75862238,0,0,0.75862238,18.482665,16.965424)" />
<linearGradient
id="linearGradient884">
<stop
style="stop-color:#fdf7df;stop-opacity:1"
offset="0"
id="stop880" />
<stop
style="stop-color:#fefcf3;stop-opacity:1"
offset="0.47619048"
id="stop888" />
<stop
style="stop-color:#fdf7df;stop-opacity:1"
offset="1"
id="stop882" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient876"
id="linearGradient878"
x1="48"
y1="52"
x2="16"
y2="8"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.75862238,0,0,0.75862238,18.482665,16.965424)" />
<linearGradient
id="linearGradient876">
<stop
style="stop-color:#dc9f30;stop-opacity:1"
offset="0"
id="stop872-3" />
<stop
style="stop-color:#edc13f;stop-opacity:1"
offset="1"
id="stop874" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient939"
id="linearGradient927"
gradientUnits="userSpaceOnUse"
x1="16"
y1="32"
x2="48"
y2="32" />
<linearGradient
id="linearGradient939">
<stop
style="stop-color:#f6dc7d;stop-opacity:1"
offset="0"
id="stop933" />
<stop
style="stop-color:#fcf29e;stop-opacity:1"
offset="0.5"
id="stop935" />
<stop
style="stop-color:#eeac28;stop-opacity:1"
offset="1"
id="stop937" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient996"
id="linearGradient927-6"
gradientUnits="userSpaceOnUse"
x1="45.192486"
y1="62.272038"
x2="35.138805"
y2="35.273148" />
<linearGradient
id="linearGradient996">
<stop
style="stop-color:#ffff00;stop-opacity:0.58911943"
offset="0"
id="stop990" />
<stop
style="stop-color:#ffff00;stop-opacity:0"
offset="1"
id="stop994" />
</linearGradient>
</defs>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1">
<path
style="fill:none;stroke:url(#linearGradient905);stroke-width:12;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers fill stroke"
d="M 10,6 V 58 H 54 V 18 L 48,12 42,6 Z"
id="path868-7" />
<path
style="fill:#e9e9e9;fill-opacity:1;stroke:none;stroke-width:12;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers fill stroke"
d="m 43,4 13,13 v 1 H 42 V 4 Z"
id="path908" />
<path
style="fill:url(#linearGradient916);fill-opacity:1;stroke:#fcfcfc;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;paint-order:markers fill stroke"
d="M 10,6 V 58 H 54 V 18 H 42 V 6 Z"
id="path868" />
<image
width="64"
height="64"
preserveAspectRatio="none"
style="image-rendering:optimizeSpeed"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAAK/INwWK6QAAABl0RVh0 U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAC4SURBVCjPdZFbDsIgEEWnrsMm7oGGfZro hxvU+Iq1TyjU60Bf1pac4Yc5YS4ZAtGWBMk/drQBOVwJlZrWYkLhsB8UV9K0BUrPGy9cWbng2CtE EUmLGppPjRwpbixUKHBiZRS0p+ZGhvs4irNEvWD8heHpbsyDXznPhYFOyTjJc13olIqzZCHBouE0 FRMUjA+s1gTjaRgVFpqRwC8mfoXPPEVPS7LbRaJL2y7bOifRCTEli3U7BMWgLzKlW/CuebZPAAAA AElFTkSuQmCC "
id="image858"
x="-60"
y="0" />
<path
style="fill:url(#linearGradient886);fill-opacity:1;stroke:url(#linearGradient878);stroke-width:3.03449;stroke-linecap:round;stroke-linejoin:round;paint-order:markers fill stroke"
d="m 42.758575,62.482763 c 6.8276,-2.27586 16.68969,-12.896579 16.68969,-18.206935 V 30.620625 c 1.51725,0 3.03449,-1.517245 3.03449,-3.03449 0,-1.517244 -1.51724,-3.034489 -3.03449,-3.034489 -1.51724,0 -3.03449,1.517245 -3.03449,3.034489 -5.31035,-1.517244 -10.62071,-2.275866 -13.6552,-6.068978 -3.03449,3.793112 -9.41991,4.877489 -13.6552,6.068978 0,-1.517244 -1.51725,-3.034489 -3.03449,-3.034489 -1.51725,0 -3.03449,1.517245 -3.03449,3.034489 0,1.517245 1.51724,3.03449 3.03449,3.03449 v 13.655203 c 0,5.310356 9.86209,15.931075 16.68969,18.206935 z"
id="path868-6" />
<path
id="path868-5"
style="fill:url(#linearGradient927);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;paint-order:markers fill stroke"
d="m 10,12 a 6.0006,6.0006 0 0 1 1.535156,0.636719 c -0.01815,-0.01859 -0.02635,-0.112286 -0.04297,-0.128906 C 11.299378,12.315003 11,12 10,12 Z m 44,0 c -1,0 -1.299378,0.315003 -1.492188,0.507813 -0.01662,0.01662 -0.02482,0.110314 -0.04297,0.128906 A 6.0006,6.0006 0 0 1 54,12 Z M 8,14 c 0,1 0.3150035,1.299378 0.5078125,1.492188 0.036341,0.03634 0.2333341,0.05363 0.28125,0.0957 A 6.0006,6.0006 0 0 1 8,14 Z m 48,0 a 6.0006,6.0006 0 0 1 -0.791016,1.587891 c 0.04831,-0.04235 0.246637,-0.05914 0.283203,-0.0957 C 55.684997,15.299378 56,15 56,14 Z m -24.015625,0.01367 C 26.391489,17.792401 19.900296,18.646969 16,19.6875 V 36 c 0,-0.214286 2.153449,5.216881 6.039062,9.435547 3.212042,3.487359 7.101019,6.2687 9.960938,7.767578 2.859919,-1.498878 6.748896,-4.280219 9.960937,-7.767578 C 45.846551,41.216881 48,35.785714 48,36 V 19.673828 C 43.124933,18.319706 37.137158,17.465673 31.984375,14.013672 Z"
transform="matrix(0.75862237,0,0,0.75862237,18.482665,16.965423)" />
<path
id="path868-5-2"
style="fill:url(#linearGradient927-6);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;paint-order:markers fill stroke"
d="m 10,12 a 6.0006,6.0006 0 0 1 1.535156,0.636719 c -0.01815,-0.01859 -0.02635,-0.112286 -0.04297,-0.128906 C 11.299378,12.315003 11,12 10,12 Z m 44,0 c -1,0 -1.299378,0.315003 -1.492188,0.507813 -0.01662,0.01662 -0.02482,0.110314 -0.04297,0.128906 A 6.0006,6.0006 0 0 1 54,12 Z M 8,14 c 0,1 0.3150035,1.299378 0.5078125,1.492188 0.036341,0.03634 0.2333341,0.05363 0.28125,0.0957 A 6.0006,6.0006 0 0 1 8,14 Z m 48,0 a 6.0006,6.0006 0 0 1 -0.791016,1.587891 c 0.04831,-0.04235 0.246637,-0.05914 0.283203,-0.0957 C 55.684997,15.299378 56,15 56,14 Z m -24.015625,0.01367 C 26.391489,17.792401 19.900296,18.646969 16,19.6875 V 36 c 0,-0.214286 2.153449,5.216881 6.039062,9.435547 3.212042,3.487359 7.101019,6.2687 9.960938,7.767578 2.859919,-1.498878 6.748896,-4.280219 9.960937,-7.767578 C 45.846551,41.216881 48,35.785714 48,36 V 19.673828 C 43.124933,18.319706 37.137158,17.465673 31.984375,14.013672 Z"
transform="matrix(0.75862237,0,0,0.75862237,18.482665,16.965423)" />
</g>
</svg>

After

(image error) Size: 8.5 KiB

View file

@ -0,0 +1 @@
<?xml version='1.0' encoding='ASCII' standalone='yes'?><svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" width="64" height="64" viewBox="0 0 64 64" version="1.1" id="svg8"><defs id="defs2"><linearGradient id="linearGradient914"><stop style="stop-color:#e9e9e9;stop-opacity:1" offset="0" id="stop910"/><stop style="stop-color:#fcfcfc;stop-opacity:1" offset="1" id="stop912"/></linearGradient><linearGradient id="linearGradient874"><stop style="stop-color:#000000;stop-opacity:0.21176471" offset="0" id="stop870"/><stop style="stop-color:#949494;stop-opacity:0.56862748" offset="1" id="stop872"/></linearGradient><linearGradient xlink:href="#linearGradient874" id="linearGradient905" gradientUnits="userSpaceOnUse" x1="8" y1="60" x2="48" y2="8"/><linearGradient xlink:href="#linearGradient914" id="linearGradient916" x1="44" y1="16" x2="20" y2="48" gradientUnits="userSpaceOnUse"/></defs><metadata id="metadata5"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><g id="layer1"><path style="fill:none;stroke:url(#linearGradient905);stroke-width:12;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers fill stroke" d="M 10,6 V 58 H 54 V 18 L 48,12 42,6 Z" id="path868-7"/><path style="fill:#e9e9e9;fill-opacity:1;stroke:none;stroke-width:12;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers fill stroke" d="m 43,4 13,13 v 1 H 42 V 4 Z" id="path908"/><path style="fill:url(#linearGradient916);fill-opacity:1;stroke:#fcfcfc;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;paint-order:markers fill stroke" d="M 10,6 V 58 H 54 V 18 H 42 V 6 Z" id="path868"/></g><svg width="64" height="64" viewBox="0 0 64 64" version="1.1" id="svg8"><defs id="defs2"><linearGradient id="linearGradientKeyLayer1177"><stop style="stop-color:#e9bb3a;stop-opacity:0.9896782" offset="0" id="stop1173"/><stop style="stop-color:#c16803;stop-opacity:1" offset="1" id="stop1175"/></linearGradient><linearGradient xlink:href="#linearGradientKeyLayer1177" id="linearGradientKeyLayer1179" x1="20" y1="20" x2="36" y2="60" gradientUnits="userSpaceOnUse" gradientTransform="translate(20,4)"/></defs><metadata id="metadata5"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><g id="layer1"><path style="fill:#ffffff;fill-opacity:1;stroke:url(#linearGradientKeyLayer1179);stroke-width:8;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill" d="M 24,60 H 60 L 42,28 Z" id="path1169"/><path style="fill:#f5d852;fill-opacity:1;stroke:none;stroke-width:8;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers fill stroke" d="M 28,58 H 56 L 42,33 Z" id="path1171"/><path style="fill:#c58711;fill-opacity:1;stroke:none;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill" d="m 40,52 v 4 h 4 v -4 z" id="path1219"/><path style="fill:#c58711;fill-opacity:1;stroke:none;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill" d="m 40,48 h 4 v -8 h -4 z" id="path1221"/></g></svg></svg>

After

(image error) Size: 3.6 KiB

View file

@ -0,0 +1,41 @@
<?xml version="1.0"?>
<!DOCTYPE package-info SYSTEM "http://www.simplemachines.org/xml/package-info">
<package-info xmlns="http://www.simplemachines.org/xml/package-info" xmlns:smf="http://www.simplemachines.org/">
<id>@flurry:spoiler_bbc</id>
<name>Spoiler BBCode Tags</name>
<version>1.0</version>
<type>modification</type>
<install for="2.1.* - 2.1.99">
<readme parsebbc="true">readme.txt</readme>
<require-file name="Subs-SpoilerCode.php" destination="$sourcedir" />
<require-file name="sceditor.spoilerbbc.css" destination="Themes/default/css" />
<require-file name="spoiler_bbc.css" destination="Themes/default/css" />
<require-file name="sceditor.spoilerbbc.js" destination="Themes/default/scripts" />
<require-file name="asset/icon_page_shield.svg" destination="Themes/default/images" />
<require-file name="asset/icon_page_warn.svg" destination="Themes/default/images" />
<require-file name="asset/icon_minimize.svg" destination="Themes/default/images" />
<require-file name="asset/icon_expand.svg" destination="Themes/default/images" />
<hook hook="integrate_bbc_codes" function="hook_spoiler_bbcode" file="$sourcedir/Subs-SpoilerCode.php" />
<hook hook="integrate_bbc_buttons" function="hook_spoiler_bbcode_buttons" file="$sourcedir/Subs-SpoilerCode.php" />
<hook hook="integrate_sceditor_options" function="spoiler_sce_options" file="$sourcedir/Subs-SpoilerCode.php" />
<hook hook="integrate_credits" function="spoiler_bbc_credits" file="$sourcedir/Subs-SpoilerCode.php" />
<hook hook="integrate_load_theme" function="hook_spoiler_load_theme" file="$sourcedir/Subs-SpoilerCode.php" />
</install>
<uninstall for="2.1.* - 2.1.99">
<remove-file name="$sourcedir/Subs-SpoilerCode.php" />
<remove-file name="Themes/default/scripts/sceditor.spoilerbbc.js" />
<remove-file name="Themes/default/css/sceditor.spoilerbbc.css" />
<remove-file name="Themes/default/css/spoiler_bbc.css" />
<remove-file name="Themes/default/images/icon_page_shield.svg" />
<remove-file name="Themes/default/images/icon_page_warn.svg" />
<remove-file name="Themes/default/images/icon_minimize.svg" />
<remove-file name="Themes/default/images/icon_expand.svg" />
<hook hook="integrate_load_theme" function="hook_spoiler_load_theme" file="$sourcedir/Subs-SpoilerCode.php" reverse="true" />
<hook hook="integrate_bbc_codes" function="hook_spoiler_bbcode" file="$sourcedir/Subs-SpoilerCode.php" reverse="true" />
<hook hook="integrate_bbc_buttons" function="hook_spoiler_bbcode_buttons" file="$sourcedir/Subs-SpoilerCode.php" reverse="true" />
<hook hook="integrate_sceditor_options" function="spoiler_sce_options" file="$sourcedir/Subs-SpoilerCode.php" reverse="true" />
<hook hook="integrate_credits" function="spoiler_bbc_credits" file="$sourcedir/Subs-SpoilerCode.php" reverse="true" />
</uninstall>
</package-info>

View file

@ -0,0 +1,25 @@
[size=x-large][b]Spoiler and Hidden Tags[/b][/size]
This adds the following BBCode tags to SMF:
[size=large][b]Spoilers[/b][/size]
Hides a block of text from users behind a warning of potential spoilers.
Follows the somewhat-standard spoiler tag definition.
By default, the following uses the subject "[b]Spoiler Text[/b]":
[nobbc][spoiler]Example Spoiler[/spoiler][/nobbc]
To set the subject text for the spoiler, use the following:
[nobbc][spoiler=Super Fantasy RPG XXV Spoilers]Example Spoiler[/spoiler][/nobbc]
[size=large][b]Login-Restricted Text[/b][/size]
This is useful for content users want to keep restricted to logged-in users.
For example, a game server's password, or a link to an unlisted YouTube video.
[nobbc][noguest]The password is "haggis"[/noguest][/nobbc]
No subject can be set here, it will always appear as "Logged-in users only".

View file

@ -0,0 +1,11 @@
.sceditor-button-spoiler div {
background-image: url('../../default/images/icon_page_warn.svg');
background-size: contain;
background-repeat: no-repeat;
}
.sceditor-button-noguest div {
background-image: url('../../default/images/icon_page_shield.svg');
background-size: contain;
background-repeat: no-repeat;
}

View file

@ -0,0 +1,263 @@
(function (sceditor) {
const DEFAULT_SPOILER_TEXT = 'Spoiler';
const DEFAULT_NOGUEST_TEXT = 'Logged-in users only';
function isArray(x) {
return (x != null && 'constructor' in x && x.constructor === Array);
}
/**
* Creates an HTML element.
*
* This can set not only element properties, but also children and events,
* using their respectively-named properties. For example, using a button:
*
* ```js
* createElement('button', {
* innerText: 'Button!',
* events: {
* 'click': function() { alert('Button clicked!'); },
* },
* });
* ```
*
* And an example div with children:
*
* ```js
* createElement('div', {
* children: [
* createElement('h1', {
* innerText: 'Header',
* }),
* createElement('p', {
* innerText: 'Paragraph 1',
* }),
* createElement('p', {
* innerText: 'Paragraph 2',
* }),
* ],
* });
* ```
*
* @param tag The HTML tag name. For example, 'input' for an `<input/>` element.
* @param params The element's parameters (e.g. `id`, `innerText`, etc).
* @return The HTML element.
*/
function createElement(tag, params) {
const elem = document.createElement(tag);
if (params != null && typeof params === 'object') {
for (const key of Object.keys(params)) {
if (key === 'children' && isArray(params['children'])) {
for (const child of params['children']) {
elem.appendChild(child);
}
} else if (key === 'events' && params != null && typeof params['events'] === 'object') {
for (const evkey of Object.keys(params['events'])) {
elem.addEventListener(evkey, params['events'][evkey]);
}
} else {
elem[key] = params[key];
}
}
}
return elem;
}
/**
* BBCode-to-HTML for Spoiler-adjacent tags.
*/
function makeSpoilerHtml(tagname, title, content) {
let isOpen = false;
if (tagname === 'noguest') {
title = DEFAULT_NOGUEST_TEXT;
isOpen = true;
} else if (tagname === 'spoiler') {
if (title == null || title.trim() === '') {
title = DEFAULT_SPOILER_TEXT;
}
}
return '<details class="collapsible ' + tagname + '"' + (isOpen ? ' open' : '') + '>' +
'<summary>' + title + '</summary>' + ' ' + // <-- Load-bearing space??
'<div>' + content + '</div>' +
'</details>';
}
// This creates the dropdown for the user to provide a spoiler subject
function spoilerDropDown(editor, caller, callback) {
const clickAction = function (ev) {
const spoilSubject = document.getElementById('spoilsubject');
// The spoiler title must a) exist, and b) be a non-empty string
let title = null;
if (spoilSubject && spoilSubject.value) {
const val = spoilSubject.value.trim();
if (val !== '') {
title = val;
}
}
callback(title);
editor.closeDropDown(true);
ev.preventDefault();
};
const dropDown = createElement('div', {
children: [
// Text input
createElement('form', {
children: [
createElement('label', {
htmlFor: 'spoilsubject',
innerText: 'Spoiler Subject:',
}),
createElement('input', {
id: 'spoilsubject',
name: 'spoilsubject',
type: 'text',
dir: 'ltr',
placeholder: DEFAULT_SPOILER_TEXT,
}),
],
events: {
'submit': clickAction,
},
}),
// Submit button
createElement('div', {
children: [
createElement('input', {
className: 'button',
type: 'button',
value: 'Insert',
events: {
'click': clickAction,
},
}),
],
}),
],
});
editor.createDropDown(caller, 'insertspoiler', dropDown);
}
/**
* HTML-to-BBCode for Spoiler-adjacent tags.
*/
function makeSpoilerBBCode(editor, tagname, element) {
let title = null;
let contentNodes = [];
let content = null;
let summaryNode = null;
for (const child of Array.from(element.children)) {
if (child.tagName === 'SUMMARY') {
summaryNode = child;
} else {
contentNodes.push(child);
}
}
if (summaryNode) {
element.removeChild(summaryNode);
}
if (tagname === 'spoiler' && summaryNode != null) {
// Get the custom spoiler text, if any
const summary = summaryNode.textContent.trim();
if (summary !== '' && summary !== 'Spoiler') {
title = '=' + summary;
}
}
if (contentNodes.length > 1) {
// Wrap the content in a <div/> to be safe
content = createElement('div', {
children: contentNodes,
});
} else if (contentNodes.length === 1) {
content = contentNodes[0];
}
return '[' + tagname + (title ?? '') + ']'
+ editor.elementToBbcode(content)
+ '[/' + tagname + ']';
}
sceditor.formats.bbcode.set(
'spoiler', {
tags: {
details: {
class: 'collapsible spoiler'
}
},
isInline: false,
breakBefore: true,
breakStart: true,
breakEnd: true,
breakAfter: true,
skipLastLineBreak: true,
format: function (element, content) {
return makeSpoilerBBCode(this, 'spoiler', element);
},
html: function (token, attrs, content) {
return makeSpoilerHtml('spoiler', attrs.defaultattr, content);
}
});
sceditor.formats.bbcode.set(
'noguest', {
tags: {
details: {
class: 'collapsible noguest'
}
},
isInline: false,
breakBefore: true,
breakStart: true,
breakEnd: true,
breakAfter: true,
skipLastLineBreak: true,
format: function (element, content) {
return makeSpoilerBBCode(this, 'noguest', element);
},
html: function (token, attrs, content) {
return makeSpoilerHtml('noguest', null, content);
}
});
sceditor.command.set(
'spoiler', {
exec: function (caller) {
const editor = this;
spoilerDropDown(this, caller, function (title) {
// TODO: can we include the selection like txtExec here?
editor.wysiwygEditorInsertHtml(makeSpoilerHtml('spoiler', title, ''));
});
},
txtExec: function (caller, selected) {
const editor = this;
spoilerDropDown(this, caller, function (title) {
editor.insertText(
'[spoiler' + (title ? '=' + title : '') + ']'
+ selected
+ '[/spoiler]'
);
});
}
}
);
sceditor.command.set(
'noguest', {
exec: function (caller) {
// TODO: can we include the selection like txtExec here?
this.wysiwygEditorInsertHtml(makeSpoilerHtml('noguest', null, ''));
},
txtExec: function (caller, selected) {
this.insertText('[noguest]' + selected + '[/noguest]');
}
}
);
})(sceditor);

View file

@ -0,0 +1,66 @@
.collapsible {
border-width: 1px 1px 1px 3px;
border-style: solid;
margin: 0 auto 8px;
}
.collapsible > summary,
.collapsible > div {
padding: 4px;
margin: 0;
}
.collapsible > summary {
list-style-type: none;
font-weight: bold;
}
.collapsible > summary::before {
display: inline-block;
width: 0.8em;
height: 0.8em;
margin-right: 0.25em;
margin-top: auto;
margin-bottom: auto;
background: url('../images/icon_expand.svg') no-repeat 0 0 / contain;
content: '';
}
.collapsible > summary::-webkit-details-marker {
display: none;
}
.collapsible[open] > summary {
border-bottom-width: 1px;
border-bottom-style: solid;
}
.collapsible[open] > summary::before {
background-image: url('../images/icon_minimize.svg');
}
.spoiler > summary {
background-color: var(--spoiler-head-background, #dcd);
border-color: var(--spoiler-border, #969);
}
.spoiler > div {
background-color: var(--spoiler-main-background, #fff9ff);
}
.spoiler {
border-color: var(--spoiler-border, #969);
}
.noguest > summary {
background-color: var(--noguest-head-background, #cce);
border-color: var(--noguest-border, #66a);
}
.noguest {
border-color: var(--noguest-border, #66a);
}
.noguest > div {
background-color: var(--noguest-main-background, #f9f9ff);
}