| 1 |
(function () { |
| 2 |
'use strict'; |
| 3 |
|
| 4 |
var _typoKeys = [['family','font-family'],['weight','font-weight'],['style','font-style'],['decoration','text-decoration'],['transform','text-transform']]; |
| 5 |
var _sizeKeys = [['Desktop','d'],['Tablet','t'],['Mobile','m']]; |
| 6 |
var _lhKeys = [['Desktop','d'],['Tablet','t'],['Mobile','m']]; |
| 7 |
var _lsKeys = [['Desktop','d'],['Tablet','t'],['Mobile','m']]; |
| 8 |
var _wsKeys = [['Desktop','d'],['Tablet','t'],['Mobile','m']]; |
| 9 |
|
| 10 |
function typoCssVarsForEl(el, obj, prefix) { |
| 11 |
if (!obj || typeof obj !== 'object') return; |
| 12 |
_typoKeys.forEach(function (p) { if (obj[p[0]]) el.style.setProperty(prefix + '-' + p[1], obj[p[0]]); }); |
| 13 |
var u = obj.sizeUnit || 'px'; |
| 14 |
_sizeKeys.forEach(function (p) { var v = obj['size' + p[0]]; if (v !== undefined && v !== '') el.style.setProperty(prefix + '-font-size-' + p[1], v + u); }); |
| 15 |
_lhKeys.forEach(function (p) { var v = obj['lineHeight' + p[0]]; if (v !== undefined && v !== '') el.style.setProperty(prefix + '-line-height-' + p[1], String(v)); }); |
| 16 |
_lsKeys.forEach(function (p) { var v = obj['letterSpacing' + p[0]]; if (v !== undefined && v !== '') el.style.setProperty(prefix + '-letter-spacing-' + p[1], v + 'px'); }); |
| 17 |
_wsKeys.forEach(function (p) { var v = obj['wordSpacing' + p[0]]; if (v !== undefined && v !== '') el.style.setProperty(prefix + '-word-spacing-' + p[1], v + 'px'); }); |
| 18 |
} |
| 19 |
|
| 20 |
var TYPE_DEFAULTS = { |
| 21 |
warning: { accent:'#f59e0b', labelBg:'#fffbeb', labelColor:'#92400e', border:'#f59e0b', btn:'#f59e0b', btnTxt:'#ffffff' }, |
| 22 |
info: { accent:'#3b82f6', labelBg:'#eff6ff', labelColor:'#1e40af', border:'#3b82f6', btn:'#3b82f6', btnTxt:'#ffffff' }, |
| 23 |
danger: { accent:'#ef4444', labelBg:'#fef2f2', labelColor:'#991b1b', border:'#ef4444', btn:'#ef4444', btnTxt:'#ffffff' }, |
| 24 |
success: { accent:'#10b981', labelBg:'#f0fdf4', labelColor:'#065f46', border:'#10b981', btn:'#10b981', btnTxt:'#ffffff' }, |
| 25 |
neutral: { accent:'#6b7280', labelBg:'#f9fafb', labelColor:'#374151', border:'#d1d5db', btn:'#6b7280', btnTxt:'#ffffff' }, |
| 26 |
custom: { accent:'#6c3fb5', labelBg:'#f5f3ff', labelColor:'#4c1d95', border:'#6c3fb5', btn:'#6c3fb5', btnTxt:'#ffffff' }, |
| 27 |
}; |
| 28 |
|
| 29 |
function getColors(opts) { |
| 30 |
if (opts.spoilerType !== 'custom') { |
| 31 |
var d = TYPE_DEFAULTS[opts.spoilerType] || TYPE_DEFAULTS.warning; |
| 32 |
return { labelBg: d.labelBg, labelColor: d.labelColor, border: d.border, btn: d.btn, btnColor: d.btnTxt }; |
| 33 |
} |
| 34 |
return { labelBg: opts.labelBg, labelColor: opts.labelColor, border: opts.borderColor, btn: opts.btnBg, btnColor: opts.btnColor }; |
| 35 |
} |
| 36 |
|
| 37 |
function setIconNode(el, type, charVal, dashicon, imageUrl, dashiconColor) { |
| 38 |
while (el.firstChild) el.removeChild(el.firstChild); |
| 39 |
var _IP = window.bkbgIconPicker; |
| 40 |
if (_IP && type && type !== 'custom-char') { |
| 41 |
var node = _IP.buildFrontendIcon(type, charVal, dashicon, imageUrl, dashiconColor); |
| 42 |
if (node) { el.appendChild(node); return; } |
| 43 |
} |
| 44 |
el.textContent = charVal || ''; |
| 45 |
} |
| 46 |
|
| 47 |
function setBtnIconContent(btn, showIcon, type, charVal, dashicon, imageUrl, dashiconColor, text) { |
| 48 |
while (btn.firstChild) btn.removeChild(btn.firstChild); |
| 49 |
if (showIcon) { |
| 50 |
var _IP = window.bkbgIconPicker; |
| 51 |
if (_IP && type && type !== 'custom-char') { |
| 52 |
var node = _IP.buildFrontendIcon(type, charVal, dashicon, imageUrl, dashiconColor); |
| 53 |
if (node) btn.appendChild(node); |
| 54 |
else btn.appendChild(document.createTextNode(charVal || '')); |
| 55 |
} else { |
| 56 |
btn.appendChild(document.createTextNode(charVal || '')); |
| 57 |
} |
| 58 |
btn.appendChild(document.createTextNode(' ')); |
| 59 |
} |
| 60 |
btn.appendChild(document.createTextNode(text)); |
| 61 |
} |
| 62 |
|
| 63 |
function buildApp(app) { |
| 64 |
var opts = {}; |
| 65 |
try { opts = JSON.parse(app.getAttribute('data-opts') || '{}'); } catch (e) {} |
| 66 |
|
| 67 |
var c = getColors(opts); |
| 68 |
var cRadius = (opts.cardRadius || 12) + 'px'; |
| 69 |
var bRadius = (opts.btnRadius || 8) + 'px'; |
| 70 |
var pV = (opts.paddingV || 20) + 'px'; |
| 71 |
var pH = (opts.paddingH || 24) + 'px'; |
| 72 |
var maxW = (opts.maxWidth || 720) + 'px'; |
| 73 |
var dur = (opts.animDuration || 300); |
| 74 |
var isOpen = false; |
| 75 |
|
| 76 |
/* Wrapper */ |
| 77 |
var wrap = document.createElement('div'); |
| 78 |
wrap.className = 'bkbg-sp-wrap'; |
| 79 |
wrap.style.cssText = [ |
| 80 |
'max-width:' + maxW, |
| 81 |
'margin:0 auto', |
| 82 |
'border:2px solid ' + c.border, |
| 83 |
'border-radius:' + cRadius, |
| 84 |
'overflow:hidden', |
| 85 |
].join(';'); |
| 86 |
|
| 87 |
/* Header */ |
| 88 |
var header = document.createElement('div'); |
| 89 |
header.className = 'bkbg-sp-header'; |
| 90 |
header.style.cssText = [ |
| 91 |
'display:flex', 'align-items:center', 'justify-content:space-between', |
| 92 |
'gap:12px', 'padding:' + pV + ' ' + pH, 'background:' + c.labelBg, |
| 93 |
'cursor:pointer', 'user-select:none', |
| 94 |
].join(';'); |
| 95 |
|
| 96 |
var leftGroup = document.createElement('div'); |
| 97 |
leftGroup.style.cssText = 'display:flex;align-items:center;gap:10px;flex-wrap:wrap'; |
| 98 |
|
| 99 |
var labelEl = document.createElement('span'); |
| 100 |
labelEl.className = 'bkbg-sp-label'; |
| 101 |
labelEl.style.cssText = 'color:' + c.labelColor; |
| 102 |
labelEl.textContent = opts.label || '⚠ Spoiler Warning'; |
| 103 |
leftGroup.appendChild(labelEl); |
| 104 |
|
| 105 |
if (opts.showSubLabel !== false && opts.subLabel) { |
| 106 |
var subEl = document.createElement('span'); |
| 107 |
subEl.className = 'bkbg-sp-sublabel'; |
| 108 |
subEl.style.cssText = 'font-size:13px;font-style:italic;opacity:0.72;color:' + c.labelColor; |
| 109 |
subEl.textContent = opts.subLabel; |
| 110 |
leftGroup.appendChild(subEl); |
| 111 |
} |
| 112 |
|
| 113 |
var iconEl = document.createElement('span'); |
| 114 |
iconEl.className = 'bkbg-sp-icon'; |
| 115 |
iconEl.style.cssText = 'font-size:13px;opacity:0.72;color:' + c.labelColor + ';flex-shrink:0'; |
| 116 |
if (opts.showIcon !== false) { |
| 117 |
setIconNode(iconEl, opts.iconClosedType, opts.iconClosed || '▼', opts.iconClosedDashicon, opts.iconClosedImageUrl, opts.iconClosedDashiconColor); |
| 118 |
} |
| 119 |
|
| 120 |
header.appendChild(leftGroup); |
| 121 |
header.appendChild(iconEl); |
| 122 |
wrap.appendChild(header); |
| 123 |
|
| 124 |
/* Content area (shown when open) */ |
| 125 |
var contentWrap = document.createElement('div'); |
| 126 |
contentWrap.className = 'bkbg-sp-slide'; |
| 127 |
contentWrap.style.cssText = 'overflow:hidden;transition:max-height ' + dur + 'ms ease,opacity ' + dur + 'ms ease;max-height:0;opacity:0'; |
| 128 |
|
| 129 |
var contentInner = document.createElement('div'); |
| 130 |
contentInner.className = 'bkbg-sp-content'; |
| 131 |
contentInner.style.cssText = 'padding:' + pV + ' ' + pH + ';background:' + (opts.contentBg || '#ffffff'); |
| 132 |
|
| 133 |
var textEl = document.createElement('div'); |
| 134 |
textEl.className = 'bkbg-sp-text'; |
| 135 |
textEl.style.cssText = 'color:' + (opts.contentColor || '#374151'); |
| 136 |
textEl.innerHTML = opts.content || ''; |
| 137 |
|
| 138 |
contentInner.appendChild(textEl); |
| 139 |
|
| 140 |
/* Hide button inside content */ |
| 141 |
var hideBtn = document.createElement('button'); |
| 142 |
hideBtn.className = 'bkbg-sp-btn'; |
| 143 |
hideBtn.style.cssText = [ |
| 144 |
'display:inline-flex', 'align-items:center', 'gap:6px', |
| 145 |
'margin-top:16px', 'padding:8px 20px', |
| 146 |
'border:none', 'border-radius:' + bRadius, |
| 147 |
'font-size:14px', 'font-weight:600', 'cursor:pointer', |
| 148 |
'background:' + c.btn, 'color:' + c.btnColor, |
| 149 |
].join(';'); |
| 150 |
hideBtn.textContent = ''; |
| 151 |
setBtnIconContent(hideBtn, opts.showIcon !== false, opts.iconOpenType, opts.iconOpen || '▲', opts.iconOpenDashicon, opts.iconOpenImageUrl, opts.iconOpenDashiconColor, opts.hideBtnText || 'Hide Spoiler'); |
| 152 |
|
| 153 |
contentInner.appendChild(hideBtn); |
| 154 |
contentWrap.appendChild(contentInner); |
| 155 |
wrap.appendChild(contentWrap); |
| 156 |
|
| 157 |
/* Reveal button area (shown when closed) */ |
| 158 |
var revealWrap = document.createElement('div'); |
| 159 |
revealWrap.className = 'bkbg-sp-body-hidden'; |
| 160 |
revealWrap.style.cssText = 'display:flex;flex-direction:column;align-items:center;gap:12px;padding:24px;background:' + (opts.contentBg || '#ffffff'); |
| 161 |
|
| 162 |
var revealBtn = document.createElement('button'); |
| 163 |
revealBtn.className = 'bkbg-sp-btn'; |
| 164 |
revealBtn.style.cssText = [ |
| 165 |
'display:inline-flex', 'align-items:center', 'gap:6px', |
| 166 |
'padding:10px 28px', 'border:none', 'border-radius:' + bRadius, |
| 167 |
'font-size:15px', 'font-weight:600', 'cursor:pointer', |
| 168 |
'background:' + c.btn, 'color:' + c.btnColor, |
| 169 |
].join(';'); |
| 170 |
revealBtn.textContent = ''; |
| 171 |
setBtnIconContent(revealBtn, opts.showIcon !== false, opts.iconClosedType, opts.iconClosed || '▼', opts.iconClosedDashicon, opts.iconClosedImageUrl, opts.iconClosedDashiconColor, opts.revealBtnText || 'Reveal Spoiler'); |
| 172 |
|
| 173 |
revealWrap.appendChild(revealBtn); |
| 174 |
wrap.appendChild(revealWrap); |
| 175 |
|
| 176 |
/* Legacy + typo CSS vars on wrap */ |
| 177 |
wrap.style.setProperty('--bksp-lb-sz', (opts.labelSize || 16) + 'px'); |
| 178 |
wrap.style.setProperty('--bksp-lb-w', String(opts.labelFontWeight || '700')); |
| 179 |
wrap.style.setProperty('--bksp-lb-lh', String(opts.labelLineHeight || 1.4)); |
| 180 |
wrap.style.setProperty('--bksp-ct-sz', (opts.contentSize || 16) + 'px'); |
| 181 |
wrap.style.setProperty('--bksp-ct-w', String(opts.contentFontWeight || '400')); |
| 182 |
wrap.style.setProperty('--bksp-ct-lh', String(opts.contentLineHeight || 1.7)); |
| 183 |
typoCssVarsForEl(wrap, opts.labelTypo, '--bksp-lb'); |
| 184 |
typoCssVarsForEl(wrap, opts.contentTypo, '--bksp-ct'); |
| 185 |
|
| 186 |
app.innerHTML = ''; |
| 187 |
app.appendChild(wrap); |
| 188 |
|
| 189 |
/* Toggle logic */ |
| 190 |
function reveal() { |
| 191 |
isOpen = true; |
| 192 |
revealWrap.style.display = 'none'; |
| 193 |
contentWrap.style.maxHeight = contentInner.scrollHeight + 200 + 'px'; |
| 194 |
contentWrap.style.opacity = '1'; |
| 195 |
if (opts.showIcon !== false) setIconNode(iconEl, opts.iconOpenType, opts.iconOpen || '▲', opts.iconOpenDashicon, opts.iconOpenImageUrl, opts.iconOpenDashiconColor); |
| 196 |
header.style.borderBottom = '1px solid ' + c.border; |
| 197 |
} |
| 198 |
|
| 199 |
function hide() { |
| 200 |
isOpen = false; |
| 201 |
contentWrap.style.maxHeight = '0'; |
| 202 |
contentWrap.style.opacity = '0'; |
| 203 |
if (opts.showIcon !== false) setIconNode(iconEl, opts.iconClosedType, opts.iconClosed || '▼', opts.iconClosedDashicon, opts.iconClosedImageUrl, opts.iconClosedDashiconColor); |
| 204 |
header.style.borderBottom = 'none'; |
| 205 |
setTimeout(function () { |
| 206 |
if (!isOpen) revealWrap.style.display = ''; |
| 207 |
}, dur); |
| 208 |
} |
| 209 |
|
| 210 |
header.addEventListener('click', function () { isOpen ? hide() : reveal(); }); |
| 211 |
revealBtn.addEventListener('click', function (e) { e.stopPropagation(); reveal(); }); |
| 212 |
hideBtn.addEventListener('click', function (e) { e.stopPropagation(); hide(); }); |
| 213 |
} |
| 214 |
|
| 215 |
document.querySelectorAll('.bkbg-sp-app').forEach(buildApp); |
| 216 |
})(); |
| 217 |
|