☰

» »

Slo-Tech userscripts

Slo-Tech userscripts

hruske ::

Ok, pokažite svojo CSS spretnost in spravite skup najbolj bizarne, odštekane, uporabne, subverzivne Slo-Tech userscripte. :)

hruske ::

Moj prvi so pobarvani nicki v stilu XChata


// ==UserScript==
// @name           Slo-Tech XChat colored nicks
// @namespace      slo-tech
// @include        https://slo-tech.com/forum*
// @include        http://slo-tech.com/forum*
// ==/UserScript==

var rcolors = ["#2a8c2a", "#fa0505", "#9c109c", "#f6fb09", "#3dcc3d", "#369090", "#05f2fe", "#6290c9", "#f705da"];
	
function colorize() {
	if (n) {
		var summa = 0, p = 0, n = $(this).find('a').html();
		for (var i=0; i<n.length; i++) {
			summa = summa + n.charCodeAt(p);
			p++;
		}
		summa = summa % rcolors.length;
		color = rcolors[summa];
		
		$(this).find('a').css("color", color);
}
$("h4").each(colorize);

jype ::

// ==UserScript==
// @name           killfile
// @namespace      killfile
// @description    slo-tech killfile
// @include        http://slo-tech.com/forum*
// ==/UserScript==
var users = ['Thomas', 'mtosev'];
window.addEventListener(
	'load', 
	function () {
		var usersRe = '^(' + users.join('|') + ')';
		var posts, thisPost;
		posts = document.evaluate(
		"//div[@class='post even' or @class='post odd']",
		document,
		null,
		XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
		null);
		for (var i = 0; i < posts.snapshotLength; i++) {
			thisPost = posts.snapshotItem(i);
			if (thisPost.childNodes[0].title.match(usersRe)) {
				thisPost.style.display="none";
			}
		}
	},
	'true'
);

terryww ::

:D
It is the night. My body's weak.
I'm on the run. No time to sleep.

netanyahu ::

// ==UserScript==
// @name No fresh news (slotech.com)
// @description Removes fresh news box.
// @include http://slo-tech.com/*
// ==/UserScript==

GM_addStyle("#fresh_news_title, #fresh_news, #fresh_news_all { display: none; }");

preem ::

in kam daš to? greasemonkey?

hruske ::

Jp, greasemonkey.

ender ::

Pri Operi pa v UserJS mapo.
There are only two hard things in Computer Science:
cache invalidation, naming things and off-by-one errors.

ender ::

Ni userskripta, je pa CSS, ki naredi kodo bolj prijazno črni temi:
@charset "UTF-8";
/*
Name: Slo-Tech koda
Version: 1.0
Author: ender
Description: Slo-Tech koda

*/

/**
 * SyntaxHighlighter
 * http://alexgorbatchev.com/
 *
 * SyntaxHighlighter is donationware. If you are using it, please donate.
 * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate
 *
 * @version
 * 2.0.320 (May 03 2009)
 * 
 * @copyright
 * Copyright (C) 2004-2009 Alex Gorbatchev.
 *
 * @license
 * This file is part of SyntaxHighlighter.
 * 
 * SyntaxHighlighter is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * SyntaxHighlighter is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with SyntaxHighlighter.  If not, see <http://www.gnu.org/copyleft/lesser.html>.
 */
/************************************
 * Default Syntax Highlighter theme.
 * 
 * Interface elements.
 ************************************/

.syntaxhighlighter
{
	background-color: #000080 !important;
}

/* Highlighed line number */
.syntaxhighlighter .line.highlighted .number
{
	background-color: #1f9a1e !important;
	color: black !important;
}

/* Highlighed line */
.syntaxhighlighter .line.highlighted.alt1 .content,
.syntaxhighlighter .line.highlighted.alt2 .content
{
	background-color: #156b15 !important;
}

/* Gutter line numbers */
.syntaxhighlighter .line .number
{
	color: #b8b8b8 !important;
}

/* Add border to the lines */
.syntaxhighlighter .line .content
{
	border-left: 3px solid #1c8c1c !important;
	color: #ccc !important;
}

.syntaxhighlighter.printing .line .content 
{
	border: 0 !important;
}

/* First line */
.syntaxhighlighter .line.alt1 .content
{
	background-color: #000080 !important;
}

/* Second line */
.syntaxhighlighter .line.alt2 .content
{
	background-color: #000088 !important;
}

.syntaxhighlighter .line .content .block
{
	background: url(wrapping.png) 0 1.1em no-repeat !important;
}

.syntaxhighlighter .ruler
{
	color: silver !important;
	background-color: #000088 !important;
	border-left: 3px solid #1b8b1b !important;
}

.syntaxhighlighter.nogutter .ruler
{
	border: 0 !important;
}

.syntaxhighlighter .toolbar
{
	background-color: #000088 !important;
	border: #3b3829 solid 1px !important;
}

.syntaxhighlighter .toolbar a
{
	color: #a0a0a0 !important;
}

.syntaxhighlighter .toolbar a:hover
{
	color: red !important;
}

/************************************
 * Actual syntax highlighter colors.
 ************************************/
.syntaxhighlighter .plain,
.syntaxhighlighter .plain a
{ 
	color: #fff !important;
}

.syntaxhighlighter .comments,
.syntaxhighlighter .comments a
{ 
	color: #009491 !important;
}

.syntaxhighlighter .string,
.syntaxhighlighter .string a
{
	color: #ff0 !important; 
}

.syntaxhighlighter .keyword
{ 
	color: #0ff !important; 
	font-weight: bold !important; 
}

.syntaxhighlighter .preprocessor 
{ 
	color: gray !important; 
}

.syntaxhighlighter .variable 
{ 
	color: #fff !important; 
}

.syntaxhighlighter .value
{ 
	color: #ff0 !important; 
}

.syntaxhighlighter .functions
{ 
	color: #fff !important; 
}

.syntaxhighlighter .constants
{ 
	color: #0066CC !important; 
}

.syntaxhighlighter .script
{ 
	background-color: #440 !important;
}

.syntaxhighlighter .color1,
.syntaxhighlighter .color1 a
{ 
	color: #808080 !important; 
}

.syntaxhighlighter .color2,
.syntaxhighlighter .color2 a
{ 
	color: #ff1493 !important; 
}

.syntaxhighlighter .color3,
.syntaxhighlighter .color3 a
{ 
	color: red !important; 
}
There are only two hard things in Computer Science:
cache invalidation, naming things and off-by-one errors.

terryww ::

a ni bolj enostavno rečt FF oz karkoli že uporabljaš, da za slo-tech* uporablja določene barve?
It is the night. My body's weak.
I'm on the run. No time to sleep.

ender ::

Niti ne, ker potem izgubim vse označevanje z barvami.
There are only two hard things in Computer Science:
cache invalidation, naming things and off-by-one errors.

jype ::

Stari, moj:

// ==UserScript==
// @name           quoter
// @namespace      slo-tech
// @description    simple quotation helper
// @include        http://slo-tech.com/forum/*
// @require       http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.js
// ==/UserScript==


$("div.content").mouseup(function (e) {
  
	var getSelText = function () {
		var txt = '';
		if (window.getSelection) {
			txt = window.getSelection();
		} else if (document.getSelection) {
			txt = document.getSelection();
		} else if (document.selection) {
			txt = document.selection.createRange().text;
		} else {
			return "";
		}
		return txt.toString();
	}
  
	var timer;
	window.clearTimeout(timer);
	var delayCall = function (e) {
		return (function(){
			// copy text
			var txt = getSelText();
			if (txt.length > 0) {
				var handle = $(e.target).siblings("h4").children("a").text();
				unsafeWindow.edit.insertContent(
					  $("#content_field").get(0),
					  txt.replace(/\n+/g, "\n"+handle+"> ")
					    .replace(/^/, handle + "> ") + '\n\n');
			} // if txt.length
		}); // returning setTimeout function
	}; // closure
	quoteText = delayCall(e);
	timer = window.setTimeout(quoteText, 500);
});


Nov, "native":
// ==UserScript==
// @name           citator
// @namespace      slo-tech
// @description    Pomoč pri citiranju
// @include        http://slo-tech.com/forum/*
// @require       http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.js
// ==/UserScript==


$("div.content").mouseup(function (e) {
  
	var getSelText = function () {
		var txt = '';
		if (window.getSelection) {
			txt = window.getSelection();
		} else if (document.getSelection) {
			txt = document.getSelection();
		} else if (document.selection) {
			txt = document.selection.createRange().text;
		} else {
			return "";
		}
		return txt.toString();
	}
  
	var timer;
	window.clearTimeout(timer);
	var delayCall = function (e) {
		return (function(){
			// copy text
			var txt = getSelText();
			if (txt.length > 0) {
				var handle = $(e.target).siblings("h4").children("a").text();
				unsafeWindow.edit.insertContent(
					  $("#content_field").get(0),
					  '<p class="user-quoted">' + handle + ' naj bi izjavil:</p><blockquote>\n' + txt + '\n </blockquote>\n\n');
			} // if txt.length
		}); // returning setTimeout function
	}; // closure
	quoteText = delayCall(e);
	timer = window.setTimeout(quoteText, 500);
});

Zgodovina sprememb…

  • spremenilo: jype ()

jype ::

Citator za nove čase, ki sem ga obljubil, pa potem pozabil objaviti. Eventuelno ga morda začnem tudi uporabljati:

// ==UserScript==
// @name           citator
// @namespace      slo-tech
// @description    Pomoč pri citiranju
// @include        https://slo-tech.com/*
// @require        http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.js
// @grant          none
// ==/UserScript==
 
 
$("div.content").mouseup(function (e) {
   
    var getSelText = function () {
        var txt = '';
        if (window.getSelection) {
            txt = window.getSelection();
        } else if (document.getSelection) {
            txt = document.getSelection();
        } else if (document.selection) {
            txt = document.selection.createRange().text;
        } else {
            return "";
        }
        return txt.toString();
    }
   
    var timer;
    window.clearTimeout(timer);
    var delayCall = function (e) {
        return (function(){
            // copy text
            var txt = getSelText();
            if (txt.length > 0) {
                var handle = $(e.target).siblings("div.controls").children("a.cite").attr("href").match(/\/forum\/[^\/]+\/([^\/]+)\/citiraj/)[1];
                unsafeWindow.edit.insertContent(
                      $("#content_field").get(0),
                      '#st.citat ' + handle + ']' + txt + '#/st.citat]');
            } // if txt.length
        }); // returning setTimeout function
    }; // closure
    quoteText = delayCall(e);
    timer = window.setTimeout(quoteText, 500);
});


Znak "#" pred nizom "st.citat" oziroma "/st.citat" je treba zamenjati z znakom "[" - če to pošljem forumu, kodo obupno izmaliči.

Zgodovina sprememb…

  • spremenilo: jype ()

jype ::

// ==UserScript==
// @name           pngfilter
// @namespace      slo-tech
// @description    Odstranjevalec fekalij
// @include        https://slo-tech.com/*
// @require        http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.js
// @grant          none
// ==/UserScript==
$('img[src$="non_grata.png"]').parent().parent().css("display", "none");


Za silo bo.

Mesar ::

A nimaš to napake? Bi moglo bit nekak tak...

$('img[src$="avatar_gray.gif"]').parent().parent().css("display", "none");

pa kak to pol zgleda? A maš v vsaki temi samo 2 posta na stran? :))
Your turn to burn!

zee ::

@jype: Hvala. Prebiranje slo-techa je bistveno manj stresno brez fekalij.
zee
Linux: Be Root, Windows: Re Boot
Giant Amazon and Google Compute Cloud in the Sky.

ender ::

Na to temo sem pa čisto pozabil. Skripta, ki povrne linearni prikaz novic:
// ==UserScript==
// @name          Popravi Slo-Tech
// @description   Popravi stran z novicami na Slo-Techu
// @include       https://*.slo-tech.com/*
// @include       https://slo-tech.com/*
// ==/UserScript==

window.addEventListener('load',function ()
{
	function __click(where) {
		if (where.fireEvent) {
			(where.fireEvent('onclick'));
		} else {
			var evObj = document.createEvent('Events');
			evObj.initEvent('click', true, false);
			where.dispatchEvent(evObj);
		}
	}

	var inputs = document.getElementsByTagName('input');
	for (var i = 0; i < inputs.length; i++) {
		if (inputs[i].value == "Prika\u017ei starej\u0161e novice") {
			__click(inputs[i]);
			break;
		}
	}

	window.setTimeout(function() //pusti ostalim skriptam dobro sekundo, da naložijo preostanek novic
	{
		var divs = document.getElementsByTagName('div');
		for (var i = 0; i < divs.length; i++) {
			if (divs[i].className == 'news_item short') {
				divs[i].className = 'news_item exposed';
			}
		}

    	var ps = document.getElementsByTagName('p');
	
		for (var i = 0; i < ps.length; i++) {
			if (ps[i].className == 'read_more' && ps[i].getElementsByTagName('a')) {
				if (ps[i].getElementsByTagName('a')[0].textContent.substring(0,10) == "Preberi ve") {
					ps[i].getElementsByTagName('a')[0].href = '#'; //firefox workaround
					//ps[i].getElementsByTagName('a')[0].click();
					__click(ps[i].getElementsByTagName('a')[0]);
				}
			}
		}
	},1111);
}
,false);
Zadnja verzija je vedno tu.
There are only two hard things in Computer Science:
cache invalidation, naming things and off-by-one errors.

jype ::

Popravil skripto za citiranje, da deluje tudi pri kopiranju podelementov besedila (strong in podobni tagi - previdno pri klikanju na večnivojsko citiranje) ter za prvo sporočilo v temi (zopet je treba # pri #st.citat in #/st.citat popraviti v [):

// ==UserScript==
// @name           quoter
// @namespace      slo-tech
// @description    simple quotation helper
// @include        https://slo-tech.com/*
// @require        http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.js
// ==/UserScript==


window.setInterval(function () {
	$("div.content").mouseup(function (e) {
	  
		var getSelText = function () {
			var txt = '';
			if (window.getSelection) {
				txt = window.getSelection();
			} else if (document.getSelection) {
				txt = document.getSelection();
			} else if (document.selection) {
				txt = document.selection.createRange().text;
			} else {
				return "";
			}
			return txt.toString();
		}
	  
		var timer;
		window.clearTimeout(timer);
		var delayCall = function (e) {
			return (function(){
				// copy text
				var txt = getSelText();
				if (txt.length > 0) {
					var handle = $(e.target).siblings("h4").children("a").text();
					//var threadid = window.location.pathname.match(/(t\d+)/)[0];
					var postid = $(e.target).closest("div.post").children("a.avatar").attr("name");
          if (postid == "p0") { // title post
            re_topic = /^\/forum\/(t[0-9]+)\/citiraj$/;
            postid = $(e.target).closest("div.post").find("a.cite").attr("href").match(re_topic)[1];
          }
					unsafeWindow.edit.insertContent(
						  $("#content_field").get(0),
						  "#st.citat " + postid + "]" + $.trim(txt) + "#/st.citat]"
					);
				} // if txt.length
			}); // returning setTimeout function
		}; // closure
		quoteText = delayCall(e);
		timer = window.setTimeout(quoteText, 500);
	});
}, 500);

Zgodovina sprememb…

  • spremenilo: jype ()

deepsick ::

Lahko bi to temo malo oživili, navsezadnje smo leta 2026, karkoli to že pomeni - če drugega ne, vsaj želje, če kdo ni vešč kakšnega orodja :D

Ales ::

deepsick je izjavil:

Lahko bi to temo malo oživili, navsezadnje smo leta 2026, karkoli to že pomeni - če drugega ne, vsaj želje, če kdo ni vešč kakšnega orodja :D

Kaj pa te zanima oz. kaj bi želel narediti?

Ali morda samo preverjaš, če sodelujoči v tej temi sploh vidijo tvojo objavo?? >:D

deepsick ::

Zanima me, če ima kdo kakšno idejo za kakšno klientsko skripto, ki je ni uspel realizirati niti v letu 2026
Se pa čudim, da je tema 8+ let neaktivna in najbolj koristnih skript niti ni navedenih, vsaj ne profi-level...
Niti v času kronično blaznih sockpuppetov :D

Zgodovina sprememb…

  • spremenilo: deepsick ()

Kripto mesi ::

Pravi model s 1001 racuni

HotBurek ::

Lahko kdo napiše skripto, ki v pogledu Teme zadnjih 24 ur za vsak oddelek (primer: Oddelek: Loža) različno obarva ime oddelka?
root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window

deepsick ::

 Bodi bolj precizen, če hočeš boljše

Bodi bolj precizen, če hočeš boljše



// ==UserScript==
// @name         Slo-Tech Teme 24ur - TR Styler Exact Span Match
// @namespace    https://slo-tech.com/
// @version      1.2
// @description  Targets span.oddelek, extracts innermost text, normalizes, applies CSS class to parent tr
// @author       Pro
// @match        https://slo-tech.com/forum/32*
// @grant        GM_addStyle
// ==/UserScript==

(function() {
    'use strict';

    if (typeof window === 'undefined') return;

    GM_addStyle(`
        tr.dept-znanostintehnologija { background-color: rgba(40, 167, 69, 0.18) !important; }
        tr.dept-loza { background-color: rgba(217, 83, 79, 0.18) !important; }
        tr.dept-problemi { background-color: rgba(240, 173, 78, 0.18) !important; }
        tr.dept-igre { background-color: rgba(92, 184, 92, 0.18) !important; }
        tr.dept-slotech { background-color: rgba(2, 117, 216, 0.18) !important; }
        tr.dept-malioglasi { background-color: rgba(111, 66, 193, 0.18) !important; }
        tr.dept-default { background-color: rgba(108, 117, 125, 0.12) !important; }
    `);

    const DEPARTMENT_CLASSES = {
        "znanostintehnologija": "dept-znanostintehnologija",
        "loža": "dept-loza",
        "loza": "dept-loza",
        "problemichlovestva": "dept-problemi",
        "igre": "dept-igre",
        "slo-tech": "dept-slotech",
        "slotech": "dept-slotech",
        "malioglasi": "dept-mali-oglasi"
    };

    const DEFAULT_CLASS = "dept-default";

    function processTableRows() {
        const oddelekSpans = document.querySelectorAll('span.oddelek');

        oddelekSpans.forEach(span => {
            const parentRow = span.closest('tr');
            if (!parentRow || parentRow.dataset.stylerProcessed === "true") return;

            // Find the <a> tag inside span.oddelek to extract innermost department text safely, ignoring href
            const anchor = span.querySelector('a');
            const innerText = anchor ? anchor.textContent : span.textContent;

            // Remove prefix if present ("Oddelek:") and clean up
            const cleanText = innerText.replace(/^Oddelek:\s*/i, "").trim();

            // Normalize: remove all internal/external spaces, lowercase
            const normalizedKey = cleanText.replace(/\s+/g, '').toLowerCase();

            const targetClass = DEPARTMENT_CLASSES[normalizedKey] || DEFAULT_CLASS;

            parentRow.classList.add(targetClass);
            parentRow.dataset.stylerProcessed = "true";
        });
    }

    const observer = new MutationObserver(() => {
        processTableRows();
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true
    });

    if (document.readyState === "complete" || document.readyState === "interactive") {
        processTableRows();
    } else {
        window.addEventListener("DOMContentLoaded", processTableRows);
    }

})();

garamond ::

Uporabnik Nevsky je imel ideje glede prikaza citatov:

-Nevsky- je izjavil:

Ali bi bilo možno v nastavitve poleg možnosti za ne prikazovanje podpisov dodati tudi možnost, da se ne prikazuje citatov. Sam imam s tem še poseben problem: sem namreč slaboviden in stran povečini poslušam preko sintetizatorja govora, ki pač prebere vse po vrsti. Tu pa se z citati zaplete. Isti posti se tekom debate ponavljajo skoraj v neskončnost. In tu ne gre za kratke citate ampak za celotne poste, ki so včasih precej dolgi. Ko tekom komentarjev dvajsetič slišiš "nekdo pač je danes ob xx:xx:xx izjavil:" čemur sledi post in nato celotna zgodovina citatov in spet njihovih citatov, ki jihznam skoraj že na pamet, me vse mine...
Ja, vem, rekli boste, to nas vse moti, je že bilo neštetokrat predlagano. Ampak potrebno bo tudi kaj narediti (vas gledam, admini), saj se Slo-Tech spreminja v neberljivo greznico citatov.
A parody of extremism is impossible to differentiate from sincere extremism.

deepsick ::

 Olepašno - tule, na vrhu desno, malo lamersko izgleda - se da dodatno, Alt+C bližnjica

Olepašno - tule, na vrhu desno, malo lamersko izgleda - se da dodatno, Alt+C bližnjica



// ==UserScript==
// @name         Slo-Tech Skrij Citate
// @namespace    http://tampermonkey.net/
// @version      1.3
// @description  Estetsko skrije citate na forumu in iz polja za vnos, dodana bližnjica Alt+C.
// @author       Pro
// @match        *://slo-tech.com/forum/*
// @match        *://www.slo-tech.com/forum/*
// @match        *://slo-tech.com/novice/*
// @match        *://www.slo-tech.com/novice/*
// @match        *://slo-tech.com/script/forum/vnossporocil.php*
// @match        *://www.slo-tech.com/script/forum/vnossporocil.php*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    const SETTINGS_KEY = 'sloTechHideQuotes';
    let isFeatureEnabled = localStorage.getItem(SETTINGS_KEY) === 'true';

    function toggleQuotesDisplay() {
        const displayMode = isFeatureEnabled ? 'none' : '';
        const userQuotedHeaders = document.querySelectorAll('.content p.user-quoted');
        const quoteBlocks = document.querySelectorAll('.content blockquote');

        userQuotedHeaders.forEach(el => el.style.display = displayMode);
        quoteBlocks.forEach(el => el.style.display = displayMode);
    }

    function cleanupTextareas() {
        if (!isFeatureEnabled) return;

        const textareas = document.querySelectorAll('textarea');
        const htmlQuoteRegex = /<blockquote>[\s\S]*?<\/blockquote>/gi;
        const plainQuoteRegex = /\[citat.*?\][\s\S]*?\[\/citat\]/gi;
        const nestedQuoteRegex = /\[st\.citat[^\]]*\](?:(?!\[st\.citat)[\s\S])*?\[\/st\.citat\]/gi;

        textareas.forEach(textarea => {
            let content = textarea.value;

            content = content.replace(htmlQuoteRegex, '');
            content = content.replace(plainQuoteRegex, '');

            while (nestedQuoteRegex.test(content)) {
                content = content.replace(nestedQuoteRegex, '');
            }

            content = content.replace(/^\s+/, '');

            if (content !== textarea.value) {
                textarea.value = content;
            }
        });
    }

    function injectStyles() {
        const styleNode = document.createElement('style');
        styleNode.textContent = `
            .st-quote-panel {
                position: fixed;
                top: 20px;
                right: 20px;
                background: #ffffff;
                padding: 8px 16px;
                border: 1px solid #e0e0e0;
                box-shadow: 0 4px 12px rgba(0,0,0,0.15);
                z-index: 999999;
                border-radius: 20px;
                font-family: Arial, sans-serif;
                font-size: 13px;
                display: flex;
                align-items: center;
                gap: 12px;
                user-select: none;
                transition: opacity 0.2s ease;
            }
            .st-quote-panel:hover {
                box-shadow: 0 6px 16px rgba(0,0,0,0.2);
            }
            .st-toggle-switch {
                position: relative;
                width: 36px;
                height: 20px;
                background-color: #ccc;
                border-radius: 20px;
                cursor: pointer;
                transition: background-color 0.3s;
            }
            .st-toggle-switch::after {
                content: '';
                position: absolute;
                top: 2px;
                left: 2px;
                width: 16px;
                height: 16px;
                background-color: white;
                border-radius: 50%;
                transition: transform 0.3s;
                box-shadow: 0 1px 3px rgba(0,0,0,0.3);
            }
            .st-toggle-switch.active {
                background-color: #4CAF50;
            }
            .st-toggle-switch.active::after {
                transform: translateX(16px);
            }
            .st-toggle-label {
                color: #333;
                font-weight: 500;
                cursor: pointer;
            }
            .st-toggle-shortcut {
                color: #888;
                font-size: 11px;
                margin-left: 4px;
            }
        `;
        document.head.appendChild(styleNode);
    }

    function buildUserInterface() {
        injectStyles();

        const container = document.createElement('div');
        container.className = 'st-quote-panel';

        const labelText = document.createElement('span');
        labelText.className = 'st-toggle-label';
        labelText.textContent = 'Skrij citate';

        const shortcutText = document.createElement('span');
        shortcutText.className = 'st-toggle-shortcut';
        shortcutText.textContent = '(Alt+C)';
        labelText.appendChild(shortcutText);

        const toggleSwitch = document.createElement('div');
        toggleSwitch.className = isFeatureEnabled ? 'st-toggle-switch active' : 'st-toggle-switch';

        function handleToggle() {
            isFeatureEnabled = !isFeatureEnabled;
            localStorage.setItem(SETTINGS_KEY, isFeatureEnabled);

            if (isFeatureEnabled) {
                toggleSwitch.classList.add('active');
            } else {
                toggleSwitch.classList.remove('active');
            }

            toggleQuotesDisplay();
            cleanupTextareas();
        }

        toggleSwitch.addEventListener('click', handleToggle);
        labelText.addEventListener('click', handleToggle);

        container.appendChild(toggleSwitch);
        container.appendChild(labelText);
        document.body.appendChild(container);

        // Dodaj poslušalec za bližnjico na tipkovnici (Alt + C)
        document.addEventListener('keydown', (event) => {
            if (event.altKey && event.code === 'KeyC') {
                event.preventDefault(); // Prepreči morebitne privzete funkcije brskalnika
                handleToggle();
            }
        });
    }

    // Inicializacija
    buildUserInterface();
    toggleQuotesDisplay();

    // Čiščenje textarea polj
    const textareaNodes = document.querySelectorAll('textarea');
    textareaNodes.forEach(node => {
        cleanupTextareas();
        node.addEventListener('focus', cleanupTextareas);
        node.addEventListener('input', cleanupTextareas);
    });

    const domObserver = new MutationObserver(() => {
        toggleQuotesDisplay();
    });
    domObserver.observe(document.body, { childList: true, subtree: true });

})();