JanitorAI CSS Toggle

Toggles JanitorAI custom CSS

Fra 25.04.2025. Se den seneste versjonen.

  1. // ==UserScript==
  2. // @name JanitorAI CSS Toggle
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1.1
  5. // @description Toggles JanitorAI custom CSS
  6. // @author IWasTheSyntaxError
  7. // @match https://janitorai.com/*
  8. // @grant none
  9. // @license MIT
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. let alreadyReloaded = true;
  16. let isMenuVisible = false;
  17. let isCustomCssDisabled = localStorage.getItem('janitorAICustomCssDisabled') === 'true';
  18.  
  19. let controlPanel = null;
  20. let controlsContainer = null;
  21.  
  22. const isAllowedPage = () => {
  23. const path = window.location.pathname;
  24. return path.startsWith('/characters') || path === '/my_characters' || path.startsWith('/profiles/');
  25. };
  26.  
  27. const isChatsPage = () => window.location.pathname.startsWith('/chats');
  28.  
  29. const getNextPageElement = () => {
  30. const currentPage = document.querySelector('.css-1xdrgup');
  31. if (!currentPage) return null;
  32.  
  33. let nextElement = currentPage.nextElementSibling;
  34. while (nextElement) {
  35. if (nextElement.classList.contains('css-kzd6o0') || nextElement.classList.contains('css-15aspjy')) {
  36. return nextElement;
  37. }
  38. nextElement = nextElement.nextElementSibling;
  39. }
  40. return null;
  41. };
  42.  
  43. const toggleMenu = () => {
  44. isMenuVisible = !isMenuVisible;
  45. updateElementsVisibility();
  46. updateControlText();
  47. };
  48.  
  49. const toggleCustomCss = () => {
  50. isCustomCssDisabled = !isCustomCssDisabled;
  51. localStorage.setItem('janitorAICustomCssDisabled', isCustomCssDisabled);
  52. applyCustomCssToggle();
  53. updateControlText();
  54. };
  55.  
  56. const applyCustomCssToggle = () => {
  57. if (isCustomCssDisabled) {
  58. alreadyReloaded = false;
  59. removeCustomStyles();
  60. const parentElement = document.querySelector('.css-1bn1yyx');
  61. if(parentElement){
  62. const childElements = parentElement.querySelectorAll('*');
  63. for (let i = 0; i < childElements.length; i++) {
  64. if (childElements[i].nodeName === "STYLE") {
  65. childElements[i].parentNode.removeChild(childElements[i]);
  66. }
  67. }
  68. const background = document.querySelector(".css-14l6kwv").firstChild;background.style.background = "none";
  69. }const char = document.querySelector(".css-fu9q4m");
  70. if(!char){
  71. const main = document.querySelector(".css-lo240v");
  72. const elementsWithStyle = main.querySelectorAll('[style]');elementsWithStyle.forEach(element => {
  73. element.removeAttribute('style');
  74. });
  75. } else {
  76. const elementsWithStyle = char.querySelectorAll('[style]');elementsWithStyle.forEach(element => {
  77. element.removeAttribute('style');
  78. });
  79. };
  80. //blockCustomElements();
  81. } else {
  82. if(!alreadyReloaded){
  83. console.log('alreadyReloaded');
  84. location.reload();
  85. alreadyReloaded = true;
  86. }
  87. }
  88. };
  89.  
  90. const removeCustomStyles = () => {
  91. const styles = document.querySelectorAll('body style');
  92. styles.forEach(style => style.remove());
  93. };
  94.  
  95. const blockCustomElements = () => {
  96. document.querySelectorAll('.css-1bn1yyx').forEach(element => {
  97. element.style.display = 'none';
  98. });
  99.  
  100. document.querySelectorAll('*').forEach(element => {
  101. const style = window.getComputedStyle(element);
  102. const bgImage = style.backgroundImage;
  103. if (bgImage && bgImage.includes('ella.janitorai.com/background-image/')) {
  104. element.style.backgroundImage = 'none';
  105. }
  106. });
  107. };
  108.  
  109. const updateControlText = () => {
  110. const cssToggleText = document.getElementById('css-toggle-text');
  111. if (cssToggleText) {
  112. cssToggleText.textContent = `Custom CSS: ${isCustomCssDisabled ? 'OFF' : 'ON'}`;
  113. cssToggleText.style.color = isCustomCssDisabled ? '#fff' : '#ccc';
  114. }
  115. };
  116.  
  117. const createControlPanel = () => {
  118. if (controlPanel) return;
  119.  
  120. controlPanel = document.createElement('div');
  121. controlPanel.id = 'janitor-control-panel';
  122. Object.assign(controlPanel.style, {
  123. position: 'fixed',
  124. top: '75px',
  125. left: '10px',
  126. zIndex: '100000',
  127. display: 'flex',
  128. flexDirection: 'column',
  129. gap: '5px',
  130. alignItems: 'flex-start'
  131. });
  132.  
  133. const settingsButton = document.createElement('button');
  134. settingsButton.id = 'token-filter-toggle';
  135. settingsButton.textContent = '⚙️';
  136. Object.assign(settingsButton.style, {
  137. width: '30px',
  138. height: '30px',
  139. padding: '0',
  140. backgroundColor: 'rgba(74, 74, 74, 0.7)',
  141. color: '#fff',
  142. border: 'none',
  143. borderRadius: '5px',
  144. cursor: 'pointer',
  145. display: 'flex',
  146. alignItems: 'center',
  147. justifyContent: 'center',
  148. fontSize: '16px',
  149. transition: 'background-color 0.2s'
  150. });
  151. settingsButton.addEventListener('click', toggleMenu);
  152.  
  153. controlsContainer = document.createElement('div');
  154. controlsContainer.id = 'controls-container';
  155. Object.assign(controlsContainer.style, {
  156. display: 'none',
  157. flexDirection: 'column',
  158. gap: '5px',
  159. backgroundColor: 'rgba(74, 74, 74, 0.7)',
  160. padding: '5px',
  161. borderRadius: '5px',
  162. zIndex: '100001'
  163. });
  164.  
  165. const cssToggleText = document.createElement('span');
  166. cssToggleText.id = 'css-toggle-text';
  167. cssToggleText.style.cursor = 'pointer';
  168. cssToggleText.style.fontSize = '12px';
  169. cssToggleText.addEventListener('click', toggleCustomCss);
  170.  
  171. controlsContainer.appendChild(cssToggleText);
  172. controlPanel.appendChild(settingsButton);
  173. controlPanel.appendChild(controlsContainer);
  174. document.body.appendChild(controlPanel);
  175. updateControlText();
  176. };
  177.  
  178. const updateElementsVisibility = () => {
  179. const shouldShow = isAllowedPage() && !isChatsPage();
  180. if (controlPanel) controlPanel.style.display = shouldShow ? 'flex' : 'none';
  181. if (controlsContainer) controlsContainer.style.display = shouldShow && isMenuVisible ? 'flex' : 'none';
  182. };
  183.  
  184. const initialize = () => {
  185. createControlPanel();
  186. updateElementsVisibility();
  187.  
  188. if (isAllowedPage() && !isChatsPage()) {
  189. applyCustomCssToggle();
  190.  
  191. new MutationObserver(() => {
  192. applyCustomCssToggle();
  193. }).observe(document.body, { childList: true, subtree: true });
  194.  
  195. const originalAppendChild = Element.prototype.appendChild;
  196. Element.prototype.appendChild = function(node) {
  197. if (isCustomCssDisabled && node.tagName === 'STYLE' && this.tagName === 'HEAD') {
  198. return node;
  199. }
  200. return originalAppendChild.call(this, node);
  201. };
  202. }
  203. };
  204.  
  205. const tryInitialize = () => {
  206. if (document.body) {
  207. initialize();
  208. let lastPath = window.location.pathname;
  209. setInterval(() => {
  210. if (lastPath !== window.location.pathname) {
  211. lastPath = window.location.pathname;
  212. updateElementsVisibility();
  213. if (isAllowedPage() && !isChatsPage()) {
  214. applyCustomCssToggle();
  215. }
  216. }
  217. }, 500);
  218. } else {
  219. setTimeout(tryInitialize, 1000);
  220. }
  221. };
  222.  
  223. tryInitialize();
  224. })();