Custom Theme Editor

More theme control for my-online-database.com

  1. // ==UserScript==
  2. // @name Custom Theme Editor
  3. // @namespace https://my-online-database.com/
  4. // @version 1.0
  5. // @icon https://i.imgur.com/41ykvVf.png
  6. // @description More theme control for my-online-database.com
  7. // @author New Jack 9999
  8. // @match https://my-online-database.com/
  9. // @grant none
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. // Utility function to convert RGB to Hex
  17. function rgbToHex(rgb) {
  18. // Check if input is already in hex
  19. if (rgb.startsWith('#')) return rgb;
  20.  
  21. const result = rgb.match(/\d+/g);
  22. if (!result) return '#000000';
  23.  
  24. const r = parseInt(result[0]).toString(16).padStart(2, '0');
  25. const g = parseInt(result[1]).toString(16).padStart(2, '0');
  26. const b = parseInt(result[2]).toString(16).padStart(2, '0');
  27.  
  28. return `#${r}${g}${b}`;
  29. }
  30.  
  31. // Define the color picker elements
  32. const colorPickerElements = [
  33. { label: 'Primary Color', variable: '--primary-color' },
  34. { label: 'Secondary Color', variable: '--secondary-color' },
  35. { label: 'Border Color', variable: '--border-color' },
  36. { label: 'Header Background', variable: '--header-bg' },
  37. { label: 'Row Hover', variable: '--row-hover' },
  38. { label: 'Toolbar Background', variable: '--toolbar-bg' },
  39. { label: 'Selected Background', variable: '--selected-bg' },
  40. { label: 'Danger Color', variable: '--danger-color' },
  41. { label: 'Success Color', variable: '--success-color' },
  42. { label: 'Warning Color', variable: '--warning-color' },
  43. { label: 'App Header Background', variable: '--app-header-bg' },
  44. { label: 'Text Primary', variable: '--text-primary' },
  45. { label: 'Text Secondary', variable: '--text-secondary' },
  46. { label: 'Text Muted', variable: '--text-muted' },
  47. { label: 'Background Primary', variable: '--bg-primary' },
  48. { label: 'Background Secondary', variable: '--bg-secondary' },
  49. { label: 'Background Tertiary', variable: '--bg-tertiary' },
  50. { label: 'Input Background', variable: '--input-bg' },
  51. { label: 'Input Border', variable: '--input-border' },
  52. { label: 'Input Text', variable: '--input-text' },
  53. { label: 'Input Placeholder', variable: '--input-placeholder' },
  54. { label: 'Card Background', variable: '--card-bg' },
  55. { label: 'Modal Background', variable: '--modal-bg' },
  56. { label: 'Tooltip Background', variable: '--tooltip-bg' },
  57. { label: 'Tooltip Text', variable: '--tooltip-text' },
  58. { label: 'Button Text Color', variable: '--text-buttoncolor' }
  59. ];
  60.  
  61. // Define predefined themes with default colors
  62. const predefinedThemes = {
  63. 'Hello Kitty 1': {
  64. '--primary-color': '#FFC0CB', // Pink
  65. '--secondary-color': '#FF69B4', // HotPink
  66. '--border-color': '#FFD700', // Gold
  67. '--header-bg': '#FFB6C1', // LightPink
  68. '--row-hover': '#FFF0F5', // LavenderBlush
  69. '--toolbar-bg': '#FF1493', // DeepPink
  70. '--selected-bg': '#DB7093', // PaleVioletRed
  71. '--danger-color': '#FF4500', // OrangeRed
  72. '--success-color': '#32CD32', // LimeGreen
  73. '--warning-color': '#FFA500', // Orange
  74. '--app-header-bg': '#FF69B4', // HotPink
  75. '--text-primary': '#800080', // Purple
  76. '--text-secondary': '#FF1493', // DeepPink
  77. '--text-muted': '#DA70D6', // Orchid
  78. '--bg-primary': '#FFF0F5', // LavenderBlush
  79. '--bg-secondary': '#FFB6C1', // LightPink
  80. '--bg-tertiary': '#FFC0CB', // Pink
  81. '--input-bg': '#FFFAFA', // Snow
  82. '--input-border': '#FF69B4', // HotPink
  83. '--input-text': '#800080', // Purple
  84. '--input-placeholder': '#DA70D6', // Orchid
  85. '--card-bg': '#FFE4E1', // MistyRose
  86. '--modal-bg': '#FFDAB9', // PeachPuff
  87. '--tooltip-bg': '#FF69B4', // HotPink
  88. '--tooltip-text': '#FFFFFF', // White
  89. '--text-buttoncolor': '#FFFFFF' // White
  90. },
  91. 'DOS 1': {
  92. '--primary-color': '#000080', // Navy
  93. '--secondary-color': '#0000FF', // Blue
  94. '--border-color': '#808080', // Gray
  95. '--header-bg': '#00008B', // DarkBlue
  96. '--row-hover': '#C0C0C0', // Silver
  97. '--toolbar-bg': '#1E90FF', // DodgerBlue
  98. '--selected-bg': '#4682B4', // SteelBlue
  99. '--danger-color': '#FF0000', // Red
  100. '--success-color': '#00FF00', // Lime
  101. '--warning-color': '#FFD700', // Gold
  102. '--app-header-bg': '#0000CD', // MediumBlue
  103. '--text-primary': '#FFFFFF', // White
  104. '--text-secondary': '#D3D3D3', // LightGray
  105. '--text-muted': '#A9A9A9', // DarkGray
  106. '--bg-primary': '#000000', // Black
  107. '--bg-secondary': '#2F4F4F', // DarkSlateGray
  108. '--bg-tertiary': '#696969', // DimGray
  109. '--input-bg': '#1C1C1C', // Very Dark Gray
  110. '--input-border': '#FFFFFF', // White
  111. '--input-text': '#FFFFFF', // White
  112. '--input-placeholder': '#808080', // Gray
  113. '--card-bg': '#333333', // Dark Gray
  114. '--modal-bg': '#2F4F4F', // DarkSlateGray
  115. '--tooltip-bg': '#000080', // Navy
  116. '--tooltip-text': '#FFFFFF', // White
  117. '--text-buttoncolor': '#FFFFFF' // White
  118. },
  119. 'Ethereum': {
  120. '--primary-color': '#3C3C3D', // Ethereum Dark Gray
  121. '--secondary-color': '#8C8C8C', // Ethereum Light Gray
  122. '--border-color': '#CCCCCC', // Light Gray
  123. '--header-bg': '#24292E', // Dark Header
  124. '--row-hover': '#2C2F33', // Darker Hover
  125. '--toolbar-bg': '#7289DA', // Blurple
  126. '--selected-bg': '#99AAB5', // Light Gray
  127. '--danger-color': '#F04747', // Red
  128. '--success-color': '#43B581', // Green
  129. '--warning-color': '#FAA61A', // Orange
  130. '--app-header-bg': '#2C2F33', // Darker Header
  131. '--text-primary': '#FFFFFF', // White
  132. '--text-secondary': '#99AAB5', // Light Gray
  133. '--text-muted': '#72767D', // Gray
  134. '--bg-primary': '#23272A', // Dark Background
  135. '--bg-secondary': '#2C2F33', // Darker Background
  136. '--bg-tertiary': '#99AAB5', // Light Gray
  137. '--input-bg': '#2C2F33', // Dark Input
  138. '--input-border': '#99AAB5', // Light Gray
  139. '--input-text': '#FFFFFF', // White
  140. '--input-placeholder': '#72767D', // Gray
  141. '--card-bg': '#2C2F33', // Dark Card
  142. '--modal-bg': '#23272A', // Dark Modal
  143. '--tooltip-bg': '#99AAB5', // Light Gray
  144. '--tooltip-text': '#23272A', // Dark Text
  145. '--text-buttoncolor': '#FFFFFF' // White
  146. },
  147. 'Reddit': {
  148. '--primary-color': '#FF4500', // OrangeRed
  149. '--secondary-color': '#FFFFFF', // White
  150. '--border-color': '#FF4500', // OrangeRed
  151. '--header-bg': '#FF4500', // OrangeRed
  152. '--row-hover': '#FFD9B3', // Light Orange
  153. '--toolbar-bg': '#FF4500', // OrangeRed
  154. '--selected-bg': '#FFB347', // Light Orange
  155. '--danger-color': '#FF0000', // Red
  156. '--success-color': '#00FF00', // Lime
  157. '--warning-color': '#FFA500', // Orange
  158. '--app-header-bg': '#FF4500', // OrangeRed
  159. '--text-primary': '#FFFFFF', // White
  160. '--text-secondary': '#FF4500', // OrangeRed
  161. '--text-muted': '#B3B3B3', // Gray
  162. '--bg-primary': '#FFFFFF', // White
  163. '--bg-secondary': '#F5F5F5', // Light Gray
  164. '--bg-tertiary': '#FFDDCC', // Light Orange
  165. '--input-bg': '#FFFFFF', // White
  166. '--input-border': '#FF4500', // OrangeRed
  167. '--input-text': '#000000', // Black
  168. '--input-placeholder': '#B3B3B3', // Gray
  169. '--card-bg': '#FFFFFF', // White
  170. '--modal-bg': '#FFFFFF', // White
  171. '--tooltip-bg': '#FF4500', // OrangeRed
  172. '--tooltip-text': '#FFFFFF', // White
  173. '--text-buttoncolor': '#FFFFFF' // White
  174. },
  175. 'Google Chrome': {
  176. '--primary-color': '#4285F4', // Blue
  177. '--secondary-color': '#34A853', // Green
  178. '--border-color': '#EA4335', // Red
  179. '--header-bg': '#4285F4', // Blue
  180. '--row-hover': '#F4B400', // Yellow
  181. '--toolbar-bg': '#DB4437', // Red
  182. '--selected-bg': '#0F9D58', // Green
  183. '--danger-color': '#DB4437', // Red
  184. '--success-color': '#0F9D58', // Green
  185. '--warning-color': '#F4B400', // Yellow
  186. '--app-header-bg': '#4285F4', // Blue
  187. '--text-primary': '#FFFFFF', // White
  188. '--text-secondary': '#34A853', // Green
  189. '--text-muted': '#EA4335', // Red
  190. '--bg-primary': '#FFFFFF', // White
  191. '--bg-secondary': '#F1F3F4', // Light Gray
  192. '--bg-tertiary': '#D3D3D3', // Light Gray
  193. '--input-bg': '#FFFFFF', // White
  194. '--input-border': '#EA4335', // Red
  195. '--input-text': '#202124', // Dark Gray
  196. '--input-placeholder': '#5F6368', // Gray
  197. '--card-bg': '#FFFFFF', // White
  198. '--modal-bg': '#FFFFFF', // White
  199. '--tooltip-bg': '#EA4335', // Red
  200. '--tooltip-text': '#FFFFFF', // White
  201. '--text-buttoncolor': '#FFFFFF' // White
  202. },
  203. 'Firefox': {
  204. '--primary-color': '#FF7139', // Firefox Orange
  205. '--secondary-color': '#1C1C1C', // Dark Gray
  206. '--border-color': '#FF7139', // Firefox Orange
  207. '--header-bg': '#FF7139', // Firefox Orange
  208. '--row-hover': '#FFDAB9', // PeachPuff
  209. '--toolbar-bg': '#FF7139', // Firefox Orange
  210. '--selected-bg': '#FF8C00', // Dark Orange
  211. '--danger-color': '#FF0000', // Red
  212. '--success-color': '#00FF00', // Lime
  213. '--warning-color': '#FFA500', // Orange
  214. '--app-header-bg': '#FF7139', // Firefox Orange
  215. '--text-primary': '#FFFFFF', // White
  216. '--text-secondary': '#1C1C1C', // Dark Gray
  217. '--text-muted': '#A9A9A9', // DarkGray
  218. '--bg-primary': '#FFFFFF', // White
  219. '--bg-secondary': '#F5F5F5', // Light Gray
  220. '--bg-tertiary': '#D3D3D3', // Light Gray
  221. '--input-bg': '#FFFFFF', // White
  222. '--input-border': '#FF7139', // Firefox Orange
  223. '--input-text': '#1C1C1C', // Dark Gray
  224. '--input-placeholder': '#A9A9A9', // DarkGray
  225. '--card-bg': '#FFFFFF', // White
  226. '--modal-bg': '#FFFFFF', // White
  227. '--tooltip-bg': '#FF7139', // Firefox Orange
  228. '--tooltip-text': '#FFFFFF', // White
  229. '--text-buttoncolor': '#FFFFFF' // White
  230. },
  231. 'Internet Explorer': {
  232. '--primary-color': '#1C62CD', // IE Blue
  233. '--secondary-color': '#0078D7', // IE Light Blue
  234. '--border-color': '#FFFFFF', // White
  235. '--header-bg': '#1C62CD', // IE Blue
  236. '--row-hover': '#D0D0D0', // Light Gray
  237. '--toolbar-bg': '#0078D7', // IE Light Blue
  238. '--selected-bg': '#005A9E', // Darker Blue
  239. '--danger-color': '#FF0000', // Red
  240. '--success-color': '#00FF00', // Lime
  241. '--warning-color': '#FFA500', // Orange
  242. '--app-header-bg': '#1C62CD', // IE Blue
  243. '--text-primary': '#FFFFFF', // White
  244. '--text-secondary': '#0078D7', // IE Light Blue
  245. '--text-muted': '#A9A9A9', // DarkGray
  246. '--bg-primary': '#FFFFFF', // White
  247. '--bg-secondary': '#F5F5F5', // Light Gray
  248. '--bg-tertiary': '#D3D3D3', // Light Gray
  249. '--input-bg': '#0078D7', // IE Light Blue
  250. '--input-border': '#0078D7', // IE Light Blue
  251. '--input-text': '#1C62CD', // IE Blue
  252. '--input-placeholder': '#A9A9A9', // DarkGray
  253. '--card-bg': '#2F2F2F', // Darker Gray
  254. '--modal-bg': '#1C62CD', // Very Dark Gray
  255. '--tooltip-bg': '#0078D7', // IE Light Blue
  256. '--tooltip-text': '#FFFFFF', // White
  257. '--text-buttoncolor': '#FFFFFF' // White
  258. },
  259. 'Pirate Bay': {
  260. '--primary-color': '#000000', // Black
  261. '--secondary-color': '#FFD700', // Gold
  262. '--border-color': '#FFFFFF', // White
  263. '--header-bg': '#000000', // Black
  264. '--row-hover': '#333333', // Dark Gray
  265. '--toolbar-bg': '#FFD700', // Gold
  266. '--selected-bg': '#555555', // Medium Gray
  267. '--danger-color': '#FF0000', // Red
  268. '--success-color': '#00FF00', // Lime
  269. '--warning-color': '#FFA500', // Orange
  270. '--app-header-bg': '#000000', // Black
  271. '--text-primary': '#FFFFFF', // White
  272. '--text-secondary': '#FFD700', // Gold
  273. '--text-muted': '#A9A9A9', // DarkGray
  274. '--bg-primary': '#1C1C1C', // Very Dark Gray
  275. '--bg-secondary': '#333333', // Dark Gray
  276. '--bg-tertiary': '#555555', // Medium Gray
  277. '--input-bg': '#333333', // Dark Gray
  278. '--input-border': '#FFD700', // Gold
  279. '--input-text': '#FFFFFF', // White
  280. '--input-placeholder': '#A9A9A9', // DarkGray
  281. '--card-bg': '#2F2F2F', // Darker Gray
  282. '--modal-bg': '#1C1C1C', // Very Dark Gray
  283. '--tooltip-bg': '#FFD700', // Gold
  284. '--tooltip-text': '#000000', // Black
  285. '--text-buttoncolor': '#FFFFFF' // White
  286. },
  287. 'Black on White': { // New Theme Added
  288. '--primary-color': '#000000', // Black
  289. '--secondary-color': '#000000', // Black
  290. '--border-color': '#000000', // Black
  291. '--header-bg': '#FFFFFF', // White
  292. '--row-hover': '#FFFFFF', // White
  293. '--toolbar-bg': '#FFFFFF', // White
  294. '--selected-bg': '#FFFFFF', // White
  295. '--danger-color': '#FF0000', // Red
  296. '--success-color': '#00FF00', // Lime
  297. '--warning-color': '#FFA500', // Orange
  298. '--app-header-bg': '#FFFFFF', // White
  299. '--text-primary': '#000000', // Black
  300. '--text-secondary': '#000000', // Black
  301. '--text-muted': '#000000', // Black
  302. '--bg-primary': '#FFFFFF', // White
  303. '--bg-secondary': '#FFFFFF', // White
  304. '--bg-tertiary': '#FFFFFF', // White
  305. '--input-bg': '#FFFFFF', // White
  306. '--input-border': '#000000', // Black
  307. '--input-text': '#000000', // Black
  308. '--input-placeholder': '#000000', // Black
  309. '--card-bg': '#FFFFFF', // White
  310. '--modal-bg': '#FFFFFF', // White
  311. '--tooltip-bg': '#FFFFFF', // White
  312. '--tooltip-text': '#000000', // Black
  313. '--text-buttoncolor': '#000000' // Black
  314. }
  315. };
  316.  
  317. // Function to get theme from localStorage or use predefined default
  318. function getTheme(themeName) {
  319. const savedTheme = localStorage.getItem(`custom_css1_theme_${themeName}`);
  320. if (savedTheme) {
  321. return JSON.parse(savedTheme);
  322. } else {
  323. return predefinedThemes[themeName] || predefinedThemes['Default'];
  324. }
  325. }
  326.  
  327. // Function to save theme to localStorage
  328. function saveTheme(themeName, themeStyles) {
  329. localStorage.setItem(`custom_css1_theme_${themeName}`, JSON.stringify(themeStyles));
  330. console.log(`Theme "${themeName}" saved to localStorage.`);
  331. }
  332.  
  333. // Function to apply theme to the document
  334. function applyTheme(themeStyles) {
  335. Object.keys(themeStyles).forEach(variable => {
  336. document.documentElement.style.setProperty(variable, themeStyles[variable]);
  337. });
  338. }
  339.  
  340. // Function to reset a theme to its default
  341. function resetTheme(themeName) {
  342. const defaultTheme = predefinedThemes[themeName];
  343. if (defaultTheme) {
  344. applyTheme(defaultTheme);
  345. saveTheme(themeName, defaultTheme);
  346. updateColorPickerValues(defaultTheme);
  347. console.log(`Theme "${themeName}" has been reset to its default colors.`);
  348. } else {
  349. console.warn(`No default theme found for "${themeName}".`);
  350. }
  351. }
  352.  
  353. // Function to create the theme editor container
  354. function createThemeEditor() {
  355. // Create the theme editor container
  356. const themeEditorContainer = document.createElement('div');
  357. themeEditorContainer.classList.add('theme-editor-container');
  358. themeEditorContainer.style.position = 'fixed';
  359. themeEditorContainer.style.top = '20px';
  360. themeEditorContainer.style.right = '20px';
  361. themeEditorContainer.style.backgroundColor = '#FFFFFF'; // White background for the editor
  362. themeEditorContainer.style.padding = '20px';
  363. themeEditorContainer.style.borderRadius = '5px';
  364. themeEditorContainer.style.boxShadow = '0 0 10px rgba(0, 0, 0, 0.5)';
  365. themeEditorContainer.style.zIndex = '9999';
  366. themeEditorContainer.style.display = 'none'; // Initially hidden
  367. themeEditorContainer.style.maxHeight = '80vh';
  368. themeEditorContainer.style.overflowY = 'auto';
  369. themeEditorContainer.style.width = '400px';
  370. themeEditorContainer.style.fontFamily = 'Arial, sans-serif';
  371. themeEditorContainer.style.color = '#000000'; // Set all text inside the editor to black
  372.  
  373. // Create the theme editor header
  374. const themeEditorHeader = document.createElement('div');
  375. themeEditorHeader.style.display = 'flex';
  376. themeEditorHeader.style.justifyContent = 'space-between';
  377. themeEditorHeader.style.alignItems = 'center';
  378. themeEditorHeader.style.marginBottom = '10px';
  379.  
  380. const headerTitle = document.createElement('span');
  381. headerTitle.textContent = 'Custom Theme Editor';
  382. headerTitle.style.fontWeight = 'bold';
  383. headerTitle.style.fontSize = '16px';
  384. headerTitle.style.color = '#000000'; // Ensure title is black
  385.  
  386. const closeButton = document.createElement('button');
  387. closeButton.textContent = '×';
  388. closeButton.style.background = 'transparent';
  389. closeButton.style.border = 'none';
  390. closeButton.style.fontSize = '20px';
  391. closeButton.style.cursor = 'pointer';
  392. closeButton.title = 'Close';
  393. closeButton.style.lineHeight = '1';
  394. closeButton.style.padding = '0';
  395. closeButton.style.color = '#000000'; // Ensure close button is black
  396.  
  397. // Attach event listener for the close button
  398. closeButton.addEventListener('click', () => {
  399. themeEditorContainer.style.display = 'none';
  400. });
  401.  
  402. themeEditorHeader.appendChild(headerTitle);
  403. themeEditorHeader.appendChild(closeButton);
  404.  
  405. // Create the theme editor content
  406. const themeEditorContent = document.createElement('div');
  407. themeEditorContent.classList.add('theme-editor-content');
  408.  
  409. // Create theme selection dropdown
  410. const themeSelectionContainer = document.createElement('div');
  411. themeSelectionContainer.style.display = 'flex';
  412. themeSelectionContainer.style.alignItems = 'center';
  413. themeSelectionContainer.style.marginBottom = '15px';
  414.  
  415.  
  416. const themeSelectionLabel = document.createElement('label');
  417. themeSelectionLabel.textContent = 'Select Theme:';
  418. themeSelectionLabel.style.marginRight = '10px';
  419. themeSelectionLabel.style.flex = '0 0 100px';
  420. themeSelectionLabel.style.color = '#000000'; // Ensure label is black
  421.  
  422. const themeSelectionDropdown = document.createElement('select');
  423. themeSelectionDropdown.style.flex = '1';
  424. themeSelectionDropdown.style.padding = '5px';
  425. themeSelectionDropdown.style.color = '#000000'; // Ensure dropdown text is black
  426. themeSelectionDropdown.style.backgroundColor = '#dddddd'; // White background
  427. themeSelectionDropdown.style.border = '1px solid #000000'; // Black border
  428. themeSelectionDropdown.style.borderRadius = '3px';
  429.  
  430. // Populate dropdown with theme options
  431. Object.keys(predefinedThemes).forEach(themeName => {
  432. const option = document.createElement('option');
  433. option.value = themeName;
  434. option.textContent = themeName;
  435. themeSelectionDropdown.appendChild(option);
  436. });
  437.  
  438. themeSelectionContainer.appendChild(themeSelectionLabel);
  439. themeSelectionContainer.appendChild(themeSelectionDropdown);
  440. themeEditorContent.appendChild(themeSelectionContainer);
  441.  
  442. // Create color pickers container
  443. const colorPickersContainer = document.createElement('div');
  444. colorPickersContainer.classList.add('color-pickers-container');
  445.  
  446. // Create color pickers
  447. colorPickerElements.forEach(element => {
  448. const colorPickerContainer = document.createElement('div');
  449. colorPickerContainer.style.display = 'flex';
  450. colorPickerContainer.style.alignItems = 'center';
  451. colorPickerContainer.style.marginBottom = '10px';
  452.  
  453. const colorPickerLabel = document.createElement('label');
  454. colorPickerLabel.textContent = element.label;
  455. colorPickerLabel.style.marginRight = '10px';
  456. colorPickerLabel.style.flex = '1';
  457. colorPickerLabel.style.color = '#000000'; // Ensure label is black
  458.  
  459. const colorPickerInput = document.createElement('input');
  460. colorPickerInput.type = 'color';
  461. colorPickerInput.value = '#000000'; // Placeholder, will be updated later
  462. colorPickerInput.style.flex = '1';
  463. colorPickerInput.style.cursor = 'pointer';
  464. colorPickerInput.style.border = '1px solid #000000'; // Black border
  465. colorPickerInput.style.borderRadius = '3px';
  466. colorPickerInput.style.padding = '0';
  467. colorPickerInput.style.height = '30px';
  468.  
  469. // Attach event listener for color change
  470. colorPickerInput.addEventListener('input', () => {
  471. const selectedTheme = themeSelectionDropdown.value;
  472. const themeStyles = getTheme(selectedTheme);
  473. themeStyles[element.variable] = colorPickerInput.value;
  474. applyTheme(themeStyles);
  475. saveTheme(selectedTheme, themeStyles);
  476. });
  477.  
  478. colorPickerContainer.appendChild(colorPickerLabel);
  479. colorPickerContainer.appendChild(colorPickerInput);
  480. colorPickersContainer.appendChild(colorPickerContainer);
  481. });
  482.  
  483. themeEditorContent.appendChild(colorPickersContainer);
  484.  
  485. // Create Reset button
  486. const resetButton = document.createElement('button');
  487. resetButton.textContent = 'Reset to Default';
  488. resetButton.style.marginTop = '15px';
  489. resetButton.style.padding = '5px 10px';
  490. resetButton.style.cursor = 'pointer';
  491. resetButton.style.border = '1px solid #ccc';
  492. resetButton.style.borderRadius = '3px';
  493. resetButton.style.backgroundColor = '#f0f0f0';
  494. resetButton.title = 'Reset current theme to default colors';
  495. resetButton.style.fontSize = '14px';
  496. resetButton.style.color = '#000000'; // Ensure button text is black
  497.  
  498. resetButton.addEventListener('click', () => {
  499. const selectedTheme = themeSelectionDropdown.value;
  500. resetTheme(selectedTheme);
  501. });
  502.  
  503. themeEditorContent.appendChild(resetButton);
  504.  
  505. // Append header and content to the container
  506. themeEditorContainer.appendChild(themeEditorHeader);
  507. themeEditorContainer.appendChild(themeEditorContent);
  508. document.body.appendChild(themeEditorContainer);
  509.  
  510. // Function to update color pickers based on selected theme
  511. function updateColorPickers(themeStyles) {
  512. const colorPickerInputs = colorPickersContainer.querySelectorAll('input[type="color"]');
  513. colorPickerInputs.forEach((input, index) => {
  514. const variable = colorPickerElements[index].variable;
  515. input.value = rgbToHex(themeStyles[variable].trim()) || '#000000';
  516. });
  517. }
  518.  
  519. // Initialize with the first theme
  520. const initialTheme = themeSelectionDropdown.value;
  521. const initialThemeStyles = getTheme(initialTheme);
  522. applyTheme(initialThemeStyles);
  523. updateColorPickers(initialThemeStyles);
  524.  
  525. // Handle theme selection change
  526. themeSelectionDropdown.addEventListener('change', () => {
  527. const selectedTheme = themeSelectionDropdown.value;
  528. const themeStyles = getTheme(selectedTheme);
  529. applyTheme(themeStyles);
  530. updateColorPickers(themeStyles);
  531. });
  532.  
  533. return themeEditorContainer;
  534. }
  535.  
  536. // Function to create the toggle button in the toolbar
  537. function createToggleButton(themeEditorContainer) {
  538. const toolbar = document.querySelector('.toolbar');
  539. if (!toolbar) {
  540. console.warn('Toolbar not found. Theme Editor button not added.');
  541. return;
  542. }
  543.  
  544. const toggleButton = document.createElement('button');
  545. toggleButton.textContent = 'Theme Editor';
  546. toggleButton.style.marginLeft = '10px';
  547. toggleButton.style.padding = '5px 10px';
  548. toggleButton.style.cursor = 'pointer';
  549. toggleButton.style.border = '1px solid #ccc';
  550. toggleButton.style.borderRadius = '3px';
  551. toggleButton.style.backgroundColor = '#f0f0f0';
  552. toggleButton.title = 'Open Theme Editor';
  553. toggleButton.style.fontSize = '14px';
  554. toggleButton.style.color = '#000000'; // Ensure button text is black
  555.  
  556. toggleButton.addEventListener('click', () => {
  557. if (themeEditorContainer.style.display === 'none' || themeEditorContainer.style.display === '') {
  558. themeEditorContainer.style.display = 'block';
  559. } else {
  560. themeEditorContainer.style.display = 'none';
  561. }
  562. });
  563.  
  564. toolbar.appendChild(toggleButton);
  565. }
  566.  
  567. // Function to initialize the theme editor
  568. function initializeThemeEditor() {
  569. if (!window.themeEditorInitialized) {
  570. window.themeEditorInitialized = true;
  571. const themeEditorContainer = createThemeEditor();
  572. createToggleButton(themeEditorContainer);
  573. console.log('Advanced Custom Theme Editor initialized.');
  574. }
  575. }
  576.  
  577. // Observe DOM changes to detect when the toolbar is added
  578. function waitForToolbar() {
  579. const toolbar = document.querySelector('.toolbar');
  580. if (toolbar) {
  581. initializeThemeEditor();
  582. } else {
  583. // If toolbar is not found, set up a MutationObserver to watch for it
  584. const observer = new MutationObserver((mutations, obs) => {
  585. const toolbar = document.querySelector('.toolbar');
  586. if (toolbar) {
  587. initializeThemeEditor();
  588. obs.disconnect(); // Stop observing once toolbar is found
  589. }
  590. });
  591.  
  592. observer.observe(document.body, { childList: true, subtree: true });
  593. }
  594. }
  595.  
  596. // Run the waitForToolbar function after DOM is fully loaded
  597. if (document.readyState === 'loading') {
  598. document.addEventListener('DOMContentLoaded', waitForToolbar);
  599. } else {
  600. waitForToolbar();
  601. }
  602.  
  603. })();