mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Merge pull request #3284 from SillyTavern/css-var-slash-command
Add `/css-var` slash command
This commit is contained in:
@@ -4,7 +4,7 @@ import { eventSource, event_types, saveSettings, saveSettingsDebounced, getReque
|
||||
import { showLoader } from './loader.js';
|
||||
import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup } from './popup.js';
|
||||
import { renderTemplate, renderTemplateAsync } from './templates.js';
|
||||
import { delay, isSubsetOf, setValueByPath } from './utils.js';
|
||||
import { delay, isSubsetOf, sanitizeSelector, setValueByPath } from './utils.js';
|
||||
import { getContext } from './st-context.js';
|
||||
import { isAdmin } from './user.js';
|
||||
import { t } from './i18n.js';
|
||||
@@ -509,10 +509,11 @@ function addExtensionStyle(name, manifest) {
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const url = `/scripts/extensions/${name}/${manifest.css}`;
|
||||
const id = sanitizeSelector(`${name}-css`);
|
||||
|
||||
if ($(`link[id="${name}"]`).length === 0) {
|
||||
if ($(`link[id="${id}"]`).length === 0) {
|
||||
const link = document.createElement('link');
|
||||
link.id = name;
|
||||
link.id = id;
|
||||
link.rel = 'stylesheet';
|
||||
link.type = 'text/css';
|
||||
link.href = url;
|
||||
@@ -540,11 +541,12 @@ function addExtensionScript(name, manifest) {
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const url = `/scripts/extensions/${name}/${manifest.js}`;
|
||||
const id = sanitizeSelector(`${name}-js`);
|
||||
let ready = false;
|
||||
|
||||
if ($(`script[id="${name}"]`).length === 0) {
|
||||
if ($(`script[id="${id}"]`).length === 0) {
|
||||
const script = document.createElement('script');
|
||||
script.id = name;
|
||||
script.id = id;
|
||||
script.type = 'module';
|
||||
script.src = url;
|
||||
script.async = true;
|
||||
|
@@ -277,7 +277,7 @@ function makeMovable(id = 'gallery') {
|
||||
const newElement = $(template);
|
||||
newElement.css('background-color', 'var(--SmartThemeBlurTintColor)');
|
||||
newElement.attr('forChar', id);
|
||||
newElement.attr('id', `${id}`);
|
||||
newElement.attr('id', id);
|
||||
newElement.find('.drag-grabber').attr('id', `${id}header`);
|
||||
newElement.find('.dragTitle').text('Image Gallery');
|
||||
//add a div for the gallery
|
||||
|
@@ -3962,6 +3962,95 @@ $(document).ready(() => {
|
||||
</div>
|
||||
`,
|
||||
}));
|
||||
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
||||
name: 'css-var',
|
||||
/** @param {{to: string, varname: string }} args @param {string} value @returns {string} */
|
||||
callback: (args, value) => {
|
||||
// Map enum to target selector
|
||||
const targetSelector = {
|
||||
chat: '#chat',
|
||||
background: '#bg1',
|
||||
gallery: '#gallery',
|
||||
zoomedAvatar: 'div.zoomed_avatar',
|
||||
}[args.to || 'chat'];
|
||||
|
||||
if (!targetSelector) {
|
||||
toastr.error(`Invalid target: ${args.to}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!args.varname) {
|
||||
toastr.error('CSS variable name is required');
|
||||
return;
|
||||
}
|
||||
if (!args.varname.startsWith('--')) {
|
||||
toastr.error('CSS variable names must start with "--"');
|
||||
return;
|
||||
}
|
||||
|
||||
const elements = document.querySelectorAll(targetSelector);
|
||||
if (elements.length === 0) {
|
||||
toastr.error(`No elements found for ${args.to ?? 'chat'} with selector "${targetSelector}"`);
|
||||
return;
|
||||
}
|
||||
|
||||
elements.forEach(element => {
|
||||
element.style.setProperty(args.varname, value);
|
||||
});
|
||||
|
||||
console.info(`Set CSS variable "${args.varname}" to "${value}" on "${targetSelector}"`);
|
||||
},
|
||||
namedArgumentList: [
|
||||
SlashCommandNamedArgument.fromProps({
|
||||
name: 'varname',
|
||||
description: 'CSS variable name (starting with double dashes)',
|
||||
typeList: [ARGUMENT_TYPE.STRING],
|
||||
isRequired: true,
|
||||
}),
|
||||
SlashCommandNamedArgument.fromProps({
|
||||
name: 'to',
|
||||
description: 'The target element to which the CSS variable will be applied',
|
||||
typeList: [ARGUMENT_TYPE.STRING],
|
||||
enumList: [
|
||||
new SlashCommandEnumValue('chat', null, enumTypes.enum, enumIcons.message),
|
||||
new SlashCommandEnumValue('background', null, enumTypes.enum, enumIcons.image),
|
||||
new SlashCommandEnumValue('zoomedAvatar', null, enumTypes.enum, enumIcons.character),
|
||||
new SlashCommandEnumValue('gallery', null, enumTypes.enum, enumIcons.image),
|
||||
],
|
||||
defaultValue: 'chat',
|
||||
}),
|
||||
],
|
||||
unnamedArgumentList: [
|
||||
SlashCommandArgument.fromProps({
|
||||
description: 'CSS variable value',
|
||||
typeList: [ARGUMENT_TYPE.STRING],
|
||||
isRequired: true,
|
||||
}),
|
||||
],
|
||||
helpString: `
|
||||
<div>
|
||||
Sets a CSS variable to a specified value on a target element.
|
||||
<br />
|
||||
Only setting of variable names is supported. They have to be prefixed with double dashes ("--exampleVar").
|
||||
Setting actual CSS properties is not supported. Custom CSS in the theme settings can be used for that.
|
||||
<br /><br />
|
||||
<b>This value will be gone after a page reload!</b>
|
||||
</div>
|
||||
<div>
|
||||
<strong>Example:</strong>
|
||||
<ul>
|
||||
<li>
|
||||
<pre><code>/css-var varname="--SmartThemeBodyColor" #ff0000</code></pre>
|
||||
Sets the text color of the chat to red
|
||||
</li>
|
||||
<li>
|
||||
<pre><code>/css-var to=zoomedAvatar varname="--SmartThemeBlurStrength" 0</code></pre>
|
||||
Remove the blur from the zoomed avatar
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
`,
|
||||
}));
|
||||
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
||||
name: 'movingui',
|
||||
callback: setmovingUIPreset,
|
||||
|
@@ -37,6 +37,7 @@ export const enumIcons = {
|
||||
voice: '🎤',
|
||||
server: '🖥️',
|
||||
popup: '🗔',
|
||||
image: '🖼️',
|
||||
|
||||
true: '✔️',
|
||||
false: '❌',
|
||||
|
@@ -67,6 +67,16 @@ export function escapeHtml(str) {
|
||||
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
||||
}
|
||||
|
||||
/**
|
||||
* Make string safe for use as a CSS selector.
|
||||
* @param {string} str String to sanitize
|
||||
* @param {string} replacement Replacement for invalid characters
|
||||
* @returns {string} Sanitized string
|
||||
*/
|
||||
export function sanitizeSelector(str, replacement = '_') {
|
||||
return String(str).replace(/[^a-z0-9_-]/ig, replacement);
|
||||
}
|
||||
|
||||
export function isValidUrl(value) {
|
||||
try {
|
||||
new URL(value);
|
||||
|
Reference in New Issue
Block a user