Themes - Bonk.io

Recolors elements in Bonk.io to customizable colors, and allows toggling your theme with a hotkey

目前为 2021-11-23 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Themes - Bonk.io
  3. // @description Recolors elements in Bonk.io to customizable colors, and allows toggling your theme with a hotkey
  4. // @author Excigma
  5. // @namespace https://greasyfork.org/users/416480
  6. // @license GPL-3.0
  7. // @version 0.1.7
  8. // @match https://bonk.io/*
  9. // @grant GM_addStyle
  10. // @grant GM_registerMenuCommand
  11. // @grant unsafeWindow
  12. // @run-at document-start
  13. // ==/UserScript==
  14.  
  15. (() => {
  16. const configuration_metadata_map = {
  17. hotkey: {
  18. default_dark: "d",
  19. default_light: "d",
  20. description: "Hotkey used to toggle the theme on and off\n(Ctrl + Alt + <key>)",
  21. datatype: "char"
  22. },
  23. colored_text: {
  24. default_dark: "#40c99e",
  25. default_light: "#032a71",
  26. description: "Text color of custom games with friends online in the room, and 'Added by' in picks",
  27. datatype: "color"
  28. },
  29. primary_text: {
  30. default_dark: "#f8fafd",
  31. default_light: "#000000",
  32. description: "Primary text color",
  33. datatype: "color"
  34. },
  35. secondary_text: {
  36. default_dark: "#bebebe",
  37. default_light: "#505050",
  38. description: "Secondary text color\nNote: Some of the texts are lightened by 'brightness_lighter' above\nthis will have no affect on such texts (Eg: Chat usernames)",
  39. datatype: "color"
  40. },
  41. window_color: {
  42. default_dark: "#2b6351",
  43. default_light: "#009688",
  44. description: "Color of window titles\n(Eg: Custom games, Leave Game, Chat, Level Select, ...)",
  45. datatype: "color"
  46. },
  47. window_text: {
  48. default_dark: "#f8fafd",
  49. default_light: "#ffffff",
  50. description: "Color of text in window titles\n(Eg: Custom games, Leave Game, Chat, Level Select, ...)",
  51. datatype: "color"
  52. },
  53. page_background: {
  54. default_dark: "#111111",
  55. default_light: "#1a2733",
  56. description: "Used for the main page's background",
  57. datatype: "color"
  58. },
  59. primary_background: {
  60. default_dark: "#222222",
  61. default_light: "#e2e2e2",
  62. description: "Used as the main background color of windows\n(Eg: Chat background, Leave lobby background, Login page)",
  63. datatype: "color"
  64. },
  65. secondary_background: {
  66. default_dark: "#333333",
  67. default_light: "#f3f3f3",
  68. description: "Secondary background color for things inside windows\n(Eg: Auto login, Joining room status text, Map Editor inputs, ...)",
  69. datatype: "color"
  70. },
  71. behind_lobby_background: {
  72. default_dark: "#131313",
  73. default_light: "#1a2733",
  74. description: "Color for the Lobby's background\n(Eg: Behind the Lobby and Map Editor)",
  75. datatype: "color"
  76. },
  77. red_text: {
  78. default_dark: "#e14747",
  79. default_light: "#cc3333",
  80. description: "Used for player nerf indicator in the lobby",
  81. datatype: "color"
  82. },
  83. blue_text: {
  84. default_dark: "#179be8",
  85. default_light: "#0955c7",
  86. description: "Used for [Load] when a map is suggested, and Copy link is clicked",
  87. datatype: "color"
  88. },
  89. green_text: {
  90. default_dark: "#17e88b",
  91. default_light: "#155824",
  92. description: "Used for player buff and in chat friend requests",
  93. datatype: "color"
  94. },
  95. purple_text: {
  96. default_dark: "#8f68e8",
  97. default_light: "#6033cc",
  98. description: "Used for output of /curate",
  99. datatype: "color"
  100. },
  101. magenta_text: {
  102. default_dark: "#d23cfb",
  103. default_light: "#800d6e",
  104. description: "Used for when [Load] is clicked, or when you are now the host of the game",
  105. datatype: "color"
  106. },
  107. button_color: {
  108. default_dark: "#4f382f",
  109. default_light: "#795548",
  110. description: "Button/dropdown color",
  111. datatype: "color"
  112. },
  113. hover_button_color: {
  114. default_dark: "#3a2a24",
  115. default_light: "#7f5d51",
  116. description: "Button/dropdown hover color",
  117. datatype: "color"
  118. },
  119. active_button_color: {
  120. default_dark: "#362620",
  121. default_light: "#4b252b",
  122. description: "Button/dropdown click color",
  123. datatype: "color"
  124. },
  125. disabled_button_color: {
  126. default_dark: "#444444",
  127. default_light: "#777777",
  128. description: "Button/dropdown disabled color",
  129. datatype: "color"
  130. },
  131. button_text: {
  132. default_dark: "#f8fafd",
  133. default_light: "#ffffff",
  134. description: "Button/dropdown text color",
  135. datatype: "color"
  136. },
  137. xp_bar_fill: {
  138. default_dark: "#473aaf",
  139. default_light: "#473aaf",
  140. description: "XP bar fill color at the top of your screen whilst in-game",
  141. datatype: "color"
  142. },
  143. top_bar_opacity: {
  144. default_dark: "0.8",
  145. default_light: "0.8",
  146. description: "Opacity of the 'top bar' that contains your:\nSkin, Username, Level, Volume Settings, ...",
  147. datatype: "percentage"
  148. },
  149. top_bar_color: {
  150. default_dark: "#333333",
  151. default_light: "#273749",
  152. description: "Color of the 'top bar'\nMake sure this value is dark, the icon colors are white and can't really be easily changed",
  153. datatype: "color"
  154. },
  155. top_bar_hover_color: {
  156. default_dark: "#222222",
  157. default_light: "#2d435a",
  158. description: "Color of buttons in the 'top bar' then hovered",
  159. datatype: "color"
  160. },
  161. top_bar_text: {
  162. default_dark: "#bebebe",
  163. default_light: "#bebebe",
  164. description: "Color of text in the 'top bar'",
  165. datatype: "color"
  166. },
  167. football_background: {
  168. default_dark: "#161616",
  169. default_light: "#5a7f64",
  170. description: "Color for the Football gamemode's background\n(Note: Requires restarting the football to apply)\nWarning: Unstable, experimental",
  171. datatype: "color"
  172. },
  173. border_color: {
  174. default_dark: "#333333",
  175. default_light: "#a5acb0",
  176. description: "Color used for subtile borders\n(Eg. Settings border, line separating chat and messages in lobby)",
  177. datatype: "color"
  178. },
  179. mini_menu_color: {
  180. default_dark: "#191919",
  181. default_light: "#1e2833",
  182. description: "Used for Tooltips and 'Filter by' in Custom Games",
  183. datatype: "color"
  184. },
  185. mini_menu_text: {
  186. default_dark: "#bebebe",
  187. default_light: "#ffffff",
  188. description: "Used for Tooltips and 'Filter by' in Custom Games",
  189. datatype: "color"
  190. },
  191. scrollbar_background: {
  192. default_dark: "#191919",
  193. default_light: "#dddddd",
  194. description: "Used for the scrollbar's background (Chromium only)",
  195. datatype: "color"
  196. },
  197. scrollbar_thumb: {
  198. default_dark: "#555555",
  199. default_light: "#aaaaaa",
  200. description: "Used for the scrollbar's thumb - which is the thing you drag (Chromium only)",
  201. datatype: "color"
  202. },
  203. list_headers: {
  204. default_dark: "#2b3839",
  205. default_light: "#a8bcc0",
  206. description: "Used for the colors of lists\n(Eg: Friends list and the sections in the Map Editor, ...)",
  207. datatype: "color"
  208. },
  209. table_color: {
  210. default_dark: "#444444",
  211. default_light: "#c1cdd2",
  212. description: "Stripe color for use in tables\n(Eg: Custom games, Friends list, Map Editor, Skin Editor, ...)",
  213. datatype: "color"
  214. },
  215. table_alt_color: {
  216. default_dark: "#333333",
  217. default_light: "#d2dbde",
  218. description: "Alternative stripe color used in tables",
  219. datatype: "color"
  220. },
  221. table_hover_color: {
  222. default_dark: "#222222",
  223. default_light: "#aac5d7",
  224. description: "Color used when a row in a table is hovered",
  225. datatype: "color"
  226. },
  227. table_active_color: {
  228. default_dark: "#111111",
  229. default_light: "#9cc8d6",
  230. description: "Color used when a row in a table is selected",
  231. datatype: "color"
  232. },
  233. brightness_lighter: {
  234. default_dark: "2.5",
  235. default_light: "1",
  236. description: "Used to lighten text that have bad contrast with dark colors\nNote: Change to 1 if making a light theme\n(0.5 = 50%, 1.5 = 150% brightness)",
  237. datatype: "brightness"
  238. },
  239. brightness_darker: {
  240. default_dark: "0.5",
  241. default_light: "1",
  242. description: "Used to darken images that that are too bright\nNote: Change to 1 if making a light theme\n(0.5 = 50%, 1.5 = 150% brightness)",
  243. datatype: "brightness"
  244. },
  245. description_invert: {
  246. default_dark: "1",
  247. default_light: "0",
  248. description: "How much to invert description at the bottom of the page by\n(Value from 0 to 1, Don't use 0.5)",
  249. datatype: "percentage"
  250. },
  251. };
  252.  
  253. const datatype_metadata_map = {
  254. "color": {
  255. value: "value",
  256. attributes: {
  257. type: "color"
  258. }
  259. },
  260. "percentage": {
  261. value: "value",
  262. attributes: {
  263. type: "number",
  264. max: 1,
  265. min: 0,
  266. step: 0.01
  267. }
  268. },
  269. "brightness": {
  270. value: "value",
  271. attributes: {
  272. type: "number",
  273. max: 10,
  274. min: 0,
  275. step: 0.05
  276. }
  277. },
  278. "char": {
  279. value: "value",
  280. attributes: {
  281. type: "text" ,
  282. maxLength: 1
  283. }
  284. },
  285. };
  286.  
  287. const default_configuration = {};
  288. for (const [key, value] of Object.entries(configuration_metadata_map))
  289. default_configuration[key] = value.default_dark;
  290. // If running inside maingameframe, inject our injectors
  291. if (unsafeWindow.parent !== unsafeWindow) {
  292. unsafeWindow.bonk_theme = {
  293. on: true,
  294. get_football_background: () => parseInt(getComputedStyle(document.documentElement)
  295. .getPropertyValue("--bonk_theme_football_background").trim().slice(1), 16),
  296. get_hotkey: () => getComputedStyle(document.documentElement)
  297. .getPropertyValue("--bonk_theme_hotkey").trim() || default_configuration.hotkey
  298. };
  299.  
  300. // Injector for football mode, if it doesn't work, ...well football will be bright
  301. if (!unsafeWindow.bonkCodeInjectors) unsafeWindow.bonkCodeInjectors = [];
  302. unsafeWindow.bonkCodeInjectors.push(bonkCode => {
  303. try {
  304. // Default football background color, not used elsewhere (yet?)
  305. const FOOTBALL_BACKGROUND_COLOR = "0x5a7f64";
  306. let newBonkCode = bonkCode;
  307. newBonkCode = newBonkCode
  308. .replace(
  309. FOOTBALL_BACKGROUND_COLOR,
  310. `(window.bonk_theme.on ? window.bonk_theme.get_football_background() : ${FOOTBALL_BACKGROUND_COLOR})`
  311. );
  312. if (bonkCode === newBonkCode) throw "[Themes] Injection failed!";
  313.  
  314. console.log("Themes injector run");
  315. return newBonkCode;
  316. } catch (er) {
  317. // Silently ignore errors, only football's background will be affected
  318. console.log("[Themes] Failed to inject");
  319. console.error(er);
  320. return bonkCode;
  321. }
  322. });
  323. }
  324.  
  325. document.addEventListener("DOMContentLoaded", () => {
  326. document.body.classList.add("themed-colors");
  327. // Get the currently applied theme
  328. const get_stored_theme = () => {
  329. // Get the stored theme, if it doesn't exist, it will be null
  330. let stored_theme = localStorage.getItem("bonk_theme");
  331. try {
  332. stored_theme = JSON.parse(stored_theme);
  333. } catch (er) {
  334. // If the stored theme is somehow corrupted - use blank theme
  335. console.log("[Themes] Failed to load theme from localstorage");
  336. console.log(`[Themes] ${stored_theme}`);
  337. console.error(er);
  338. alert("Failed to load theme from localstorage");
  339. stored_theme = {};
  340. }
  341. // Merge the stored theme with the default (if null, it will overwrite)
  342. return {...default_configuration, ...stored_theme};
  343. };
  344.  
  345. // Get the stored theme when the page loads
  346. const configuration = get_stored_theme();
  347. // Check if the script is running inside maingameframe or not
  348. if (unsafeWindow.parent === unsafeWindow) {
  349. // Outer bonk.io website
  350. // Hotkey to turn the script on and off
  351. const maingameframe = document.getElementById("maingameframe");
  352. document.addEventListener("keydown", evt => {
  353. if (evt.key?.toLowerCase() === maingameframe.contentWindow.bonk_theme.get_hotkey() && evt.ctrlKey && evt.altKey) {
  354. document.body.classList.toggle("themed-colors");
  355. maingameframe.contentDocument.body.classList.toggle("themed-colors");
  356. maingameframe.contentWindow.bonk_theme.on = !maingameframe.contentWindow.bonk_theme.on;
  357. }
  358. });
  359.  
  360. // Flag to check whether the theme container already exists
  361. let theme_container_created = false;
  362. // Create the menu only when someone clicks on the thing in the menu
  363. // Show the theme container when you click the menu command thing
  364. // eslint-disable-next-line no-undef
  365. GM_registerMenuCommand("Edit theme", () => {
  366. // Creating a new theme_container, don't make new ones after this
  367. if (theme_container_created) return document.getElementById("theme_container").style.display = "block";
  368. theme_container_created = true;
  369.  
  370. // Create the theme menu. This is really ugly but there's like no other way idk.
  371. const theme_container = document.createElement("div");
  372. const theme_container_title = document.createElement("p");
  373. const configuration_container = document.createElement("div");
  374. const configuration_container_label = document.createElement("label");
  375. const configuration_list = document.createElement("div");
  376. const configuration_json = document.createElement("textarea");
  377. const configuration_json_label = document.createElement("label");
  378. const theme_cancel = document.createElement("div");
  379. const theme_save = document.createElement("div");
  380. const theme_reset_dark = document.createElement("div");
  381. const theme_reset_light = document.createElement("div");
  382. // Add the IDs so we can style them with CSS
  383. theme_container_title.id = "theme_container_title";
  384. theme_container.id = "theme_container";
  385. configuration_container_label.id = "configuration_container_label";
  386. configuration_list.id = "configuration_list";
  387. configuration_json.id = "configuration_json";
  388. theme_cancel.id = "theme_cancel";
  389. theme_save.id = "theme_save";
  390. theme_reset_dark.class = "theme_reset";
  391. theme_reset_light.class = "theme_reset";
  392.  
  393. // Add the classes
  394. theme_container_title.classList.add("classicTopBar");
  395. theme_cancel.classList.add("brownButton", "brownButton_classic", "buttonShadow");
  396. theme_save.classList.add("brownButton", "brownButton_classic", "buttonShadow");
  397. theme_reset_dark.classList.add("brownButton", "brownButton_classic", "buttonShadow");
  398. theme_reset_light.classList.add("brownButton", "brownButton_classic", "buttonShadow");
  399.  
  400. // Add text to buttons and titles
  401. theme_container_title.textContent = "Theme Editor";
  402. theme_cancel.textContent = "CANCEL";
  403. theme_save.textContent = "SAVE";
  404. theme_reset_dark.textContent = "RESET THEME TO DARK PRESET";
  405. theme_reset_light.textContent = "RESET THEME TO LIGHT PRESET";
  406. configuration_container_label.textContent = "Hover over settings for more info";
  407. configuration_json_label.textContent = "Share, Backup or Import theme data - Copy or paste themes from/into the textbox below";
  408. configuration_json_label.for = "configuration_json";
  409. configuration_json.value = JSON.stringify(configuration);
  410. theme_container.appendChild(theme_container_title);
  411.  
  412. configuration_list.appendChild(configuration_container_label);
  413. configuration_list.appendChild(document.createElement("br"));
  414.  
  415. // Populate the themes list with the theme that is currently loaded
  416. for (const [key, value] of Object.entries(configuration)) {
  417. // Check if the setting exists
  418. if (!configuration_metadata_map[key]) continue;
  419. const datatype_metadata = datatype_metadata_map[configuration_metadata_map[key].datatype];
  420. const configuration_container = document.createElement("div");
  421. const configuration_name = document.createElement("p");
  422. const configuration_value = document.createElement("input");
  423. configuration_container.classList.add("configuration_container");
  424. configuration_name.classList.add("configuration_name");
  425. configuration_value.classList.add("configuration_value");
  426.  
  427. configuration_container.dataset["configuration_name"] = key;
  428. configuration_container.title = configuration_metadata_map[key].description ?? "No description";
  429. configuration_name.textContent = key.replace(/_/g, " ");
  430.  
  431. for (const [key, value] of Object.entries(datatype_metadata.attributes))
  432. configuration_value[key] = value;
  433. configuration_value[datatype_metadata.value] = value;
  434. // Using "oninput" instead of addEventListener so we can call it somewhere else
  435. configuration_value.oninput = () => {
  436. if (!datatype_metadata.ignore_change) {
  437. // Update the CSS variable on both bonk.io and maingameframe
  438. document.documentElement.style
  439. .setProperty(`--bonk_theme_${key}`, configuration_value.value);
  440. maingameframe.contentDocument.documentElement.style
  441. .setProperty(`--bonk_theme_${key}`, configuration_value.value);
  442. // Store it in the current configuration (so it can be saved later)
  443. configuration[key] = configuration_value[datatype_metadata.value];
  444. }
  445.  
  446. // Update the data at the bottom
  447. configuration_json.value = JSON.stringify(configuration);
  448. };
  449.  
  450. // Add the current config to the list of settings
  451. configuration_container.appendChild(configuration_name);
  452. configuration_container.appendChild(configuration_value);
  453. configuration_list.appendChild(configuration_container);
  454. }
  455.  
  456. // Add the Save and Cancel buttons
  457. configuration_container.appendChild(theme_cancel);
  458. configuration_container.appendChild(theme_save);
  459.  
  460. configuration_list.appendChild(document.createElement("br")); // this
  461. configuration_list.appendChild(configuration_container);
  462. configuration_list.appendChild(document.createElement("br")); // is
  463. configuration_list.appendChild(configuration_json_label);
  464. configuration_list.appendChild(document.createElement("br")); // so
  465. configuration_list.appendChild(configuration_json);
  466. configuration_list.appendChild(document.createElement("br")); // bad
  467. configuration_list.appendChild(theme_reset_dark);
  468. configuration_list.appendChild(theme_reset_light);
  469. theme_container.appendChild(configuration_list);
  470.  
  471. // When save is clicked, try save theme to localstorage
  472. theme_save.addEventListener("click", () => {
  473. try {
  474. localStorage.setItem("bonk_theme", JSON.stringify(configuration));
  475. theme_container.style.display = "none";
  476. } catch (er) {
  477. console.log("[Themes] Failed to save theme to localstorage");
  478. console.log(`[Themes] ${JSON.stringify(configuration)}`);
  479. console.error(er);
  480. alert("Failed to save theme to localstorage");
  481. }
  482. });
  483.  
  484. // Reset the state of configuration from localstorage
  485. theme_cancel.addEventListener("click", () => {
  486. configuration_json.value = JSON.stringify(get_stored_theme());
  487. configuration_json.oninput();
  488. theme_container.style.display = "none";
  489. });
  490.  
  491. // Get the currently saved theme, and overwrite everything with it
  492. theme_reset_dark.addEventListener("click", () => {
  493. configuration_json.value = JSON.stringify(default_configuration);
  494. configuration_json.oninput();
  495. });
  496.  
  497. theme_reset_light.addEventListener("click", () => {
  498. // Light theme defaults are not calculated by default, so we need to calculate it here now
  499. const default_light_configuration = {};
  500. for (const [key, value] of Object.entries(configuration_metadata_map))
  501. default_light_configuration[key] = value.default_light;
  502.  
  503. configuration_json.value = JSON.stringify(default_light_configuration);
  504. configuration_json.oninput();
  505. });
  506.  
  507. configuration_json.oninput = () => {
  508. try {
  509. const new_theme = JSON.parse(configuration_json.value);
  510. // Update the configurations
  511. const configuration_list_children = Array.from(configuration_list.children);
  512. for (const configuration_container of configuration_list_children) {
  513. const key = configuration_container.dataset["configuration_name"];
  514. const value = new_theme[key];
  515. if (!value) continue;
  516.  
  517. const configuration_value = configuration_container.querySelector("input");
  518. const datatype_meta = datatype_metadata_map[configuration_metadata_map[key].datatype];
  519. configuration_value[datatype_meta.value] = value;
  520. configuration_value.oninput();
  521. }
  522.  
  523. // If success, remove the border
  524. configuration_json.style.setProperty("border", "none");
  525. } catch (er) {
  526. console.log("[Themes] Failed to load theme from <textarea>");
  527. console.log(`[Themes] ${configuration_json.value}`);
  528. console.error(er);
  529. // If there is an error, set a red border
  530. configuration_json.style.setProperty("border", "3px solid var(--bonk_theme_red)", "important");
  531. }
  532. };
  533.  
  534. // Add the theme dialog to body
  535. document.body.appendChild(theme_container);
  536. });
  537. } else {
  538. // This code is for inside maingameframe
  539. // Hotkey to turn the script on and off
  540. document.addEventListener("keydown", evt => {
  541. if (evt.key?.toLowerCase() === unsafeWindow.bonk_theme.get_hotkey() && evt.ctrlKey && evt.altKey) {
  542. unsafeWindow.bonk_theme.on = !unsafeWindow.bonk_theme.on;
  543. document.body.classList.toggle("themed-colors");
  544. unsafeWindow.parent.document.body.classList.toggle("themed-colors");
  545. }
  546. });
  547. }
  548.  
  549. // List of default CSS variables
  550. let root_vars = [];
  551. for (const [key, value] of Object.entries(configuration))
  552. root_vars.push(`--bonk_theme_${key}: ${value};`);
  553.  
  554. // eslint-disable-next-line no-undef
  555. GM_addStyle(`
  556. /* CSS Variables, so we can edit their values on the fly */
  557. :root {
  558. ${root_vars.join("\n ")}
  559. }
  560.  
  561. /* Page background color */
  562. .themed-colors #pagecontainer,
  563. body.themed-colors {
  564. background-color: var(--bonk_theme_page_background) !important;
  565. --kkleeMultiSelectColour: ${configuration.colored_text};
  566. --kkleeErrorColour: ${configuration.red_text};
  567. --kkleeCheckboxTfsTrue: ${configuration.green_text};
  568. --kkleeCheckboxTfsFalse: ${configuration.red_text};
  569. }
  570.  
  571. /* Dark scroll bar tracks on Firefox and Chromium-based browsers */
  572. .themed-colors {
  573. scrollbar-color: var(--bonk_theme_scrollbar_thumb) var(--bonk_theme_scrollbar_background) !important;
  574. }
  575.  
  576. .themed-colors ::-webkit-scrollbar-track {
  577. background-color: var(--bonk_theme_scrollbar_background) !important;
  578. }
  579.  
  580. .themed-colors ::-webkit-scrollbar-thumb {
  581. background-color: var(--bonk_theme_scrollbar_thumb) !important;
  582. }
  583.  
  584. /* Color tooltips */
  585. .themed-colors #friendsToolTip,
  586. .themed-colors #pretty_top_replay_report_tooltip,
  587. .themed-colors #pretty_top_replay_fav_tooltip,
  588. .themed-colors #newbonklobby_tooltip,
  589. .themed-colors #mapeditor_rightbox_shapeaddmenucontainer,
  590. .themed-colors #mapeditor_leftbox_createmenucontainerleft,
  591. .themed-colors #mapeditor_leftbox_createmenucontainerright,
  592. .themed-colors #mapeditor_leftbox_copywindow,
  593. .themed-colors #mapeditor_rightbox_newjointmenu,
  594. .themed-colors .newbonklobby_playerentry_menu,
  595. .themed-colors .newbonklobby_playerentry_menu_submenu {
  596. background-color: var(--bonk_theme_mini_menu_color) !important;
  597. color: var(--bonk_theme_mini_menu_text) !important;
  598. }
  599.  
  600. /* Color the lobby's background */
  601. .themed-colors #bonkiocontainer {
  602. background-color: var(--bonk_theme_behind_lobby_background) !important;
  603. }
  604. /* Dialogs - I can just do windowShadow, but it might break things if new things are added */
  605. /* It's better to have a new thing visibly light rather than broken */
  606. .themed-colors .bt-primary-background,
  607. .themed-colors #autoLoginContainer,
  608. .themed-colors #guestOrAccountContainer_accountBox,
  609. .themed-colors #guestOrAccountContainer_guestBox,
  610. .themed-colors #guestContainer,
  611. .themed-colors .accountContainer,
  612. .themed-colors #registerwindow_remember_label,
  613. .themed-colors #loginwindow_remember_label,
  614. .themed-colors #loginwindow,
  615. .themed-colors #registerwindow,
  616. .themed-colors #settingsContainer,
  617. .themed-colors .settingsHeading,
  618. .themed-colors .redefineControls_selectionCell:hover,
  619. .themed-colors #newswindow,
  620. .themed-colors #skinmanager,
  621. .themed-colors .skineditor_shapewindow,
  622. .themed-colors .skineditor_shapewindow_imagecontainer,
  623. .themed-colors #skineditor_propertiesbox,
  624. .themed-colors #skineditor_propertiesbox_table,
  625. .themed-colors #skineditor_previewbox,
  626. .themed-colors #skineditor_layerbox,
  627. .themed-colors #skineditor_layerbox_baselabel,
  628. .themed-colors #quickPlayWindow,
  629. .themed-colors #roomlistcreatewindow,
  630. .themed-colors .roomlistcreatewindowlabel,
  631. .themed-colors #roomlistjoinpasswordwindow,
  632. .themed-colors #sm_connectingWindow,
  633. .themed-colors #newbonklobby_specbox,
  634. .themed-colors #newbonklobby_playerbox,
  635. .themed-colors #newbonklobby_chatbox,
  636. .themed-colors #newbonklobby_settingsbox,
  637. .themed-colors #newbonklobby_votewindow,
  638. .themed-colors #newbonklobby_votewindow_maptitle,
  639. .themed-colors #newbonklobby_votewindow_mapauthor,
  640. .themed-colors #leaveconfirmwindow,
  641. .themed-colors #leaveconfirmwindow_text2,
  642. .themed-colors #hostleaveconfirmwindow,
  643. .themed-colors #hostleaveconfirmwindow_text2,
  644. .themed-colors #maploadwindow,
  645. .themed-colors #maploadwindowgreybar,
  646. .themed-colors #maploadwindowstatustext,
  647. .themed-colors #mapeditor_leftbox,
  648. .themed-colors #mapeditor_midbox,
  649. .themed-colors #mapeditor_rightbox,
  650. .themed-colors #mapeditor_save_window,
  651. .themed-colors #kkleeRoot,
  652. .themed-colors #skineditor_colorpicker,
  653. .themed-colors #mapeditor_colorpicker,
  654. .themed-colors #friendsSendWindow,
  655. .themed-colors #roomlistfilterwindow,
  656. .themed-colors #ingamecountdown,
  657. .themed-colors #mapeditor_save_overwrite_window,
  658. #theme_container {
  659. background-color: var(--bonk_theme_primary_background) !important;
  660. color: var(--bonk_theme_primary_text) !important;
  661. }
  662. /* Lighter backgrounds for some menus and stuff */
  663. .themed-colors .bt-secondary-background,
  664. .themed-colors #bonkioheader,
  665. .themed-colors .windowTopBar_classic,
  666. .themed-colors #autoLogin_text,
  667. .themed-colors .guestOrAccountContainerLabelBox,
  668. .themed-colors #guest_nametext,
  669. .themed-colors #loginwindow_username,
  670. .themed-colors #loginwindow_password,
  671. .themed-colors #registerwindow_username,
  672. .themed-colors #registerwindow_password,
  673. .themed-colors #guest_skinbox,
  674. .themed-colors #skineditor_propertiesbox_blocker,
  675. .themed-colors #newswindow_white,
  676. .themed-colors .quickPlayWindowModeDiv,
  677. .themed-colors .quickPlayWindowText1,
  678. .themed-colors .quickPlayWindowText2,
  679. .themed-colors .quickPlayWindowText3,
  680. .themed-colors #roomlist,
  681. .themed-colors #roomlisttableheadercontainer,
  682. .themed-colors .roomlistcreatewindowinput,
  683. .themed-colors .whiteInputField,
  684. .themed-colors #sm_connectingWindow_text,
  685. .themed-colors #friendsContainer,
  686. .themed-colors .friends_table,
  687. .themed-colors .skinmanager_icon,
  688. .themed-colors #maploadwindowsearchinput,
  689. .themed-colors .maploadwindowmapdiv,
  690. .themed-colors #mapeditor_midbox_explain,
  691. .themed-colors #mapeditor_rightbox_namefield,
  692. .configuration_value,
  693. #configuration_json {
  694. border-color: transparent !important;
  695. background-color: var(--bonk_theme_secondary_background) !important;
  696. color: var(--bonk_theme_primary_text) !important;
  697. }
  698. .themed-colors .mapeditor_field,
  699. .themed-colors .skineditor_field,
  700. .themed-colors .mapeditor_rightbox_table_shape_headerfield {
  701. border-color: transparent;
  702. background-color: var(--bonk_theme_secondary_background);
  703. color: var(--bonk_theme_primary_text);
  704. }
  705.  
  706. .themed-colors .newbonklobby_playerentry_name,
  707. .themed-colors #newbonklobby_modetext,
  708. .themed-colors #newbonklobby_roundslabel,
  709. .themed-colors .maploadwindowtext,
  710. .themed-colors #roomliststatustext,
  711. .themed-colors #roomlisttable,
  712. .themed-colors .mapeditor_rightbox_table_leftcell,
  713. .themed-colors .mapeditor_rightbox_table_rightcell,
  714. .themed-colors #ingamecountdown_text,
  715. .themed-colors #bonkiobugemail {
  716. color: var(--bonk_theme_primary_text) !important;
  717. }
  718.  
  719. .themed-colors .newbonklobby_mapsuggest_high,
  720. .themed-colors .maploadwindowtext_picks,
  721. .themed-colors .newbonklobby_chat_msg_name,
  722. .themed-colors .newbonklobby_playerentry_balancetext {
  723. color: var(--bonk_theme_primary_text);
  724. }
  725.  
  726. .themed-colors .newbonklobby_playerentry_level,
  727. .themed-colors .newbonklobby_playerentry_pingtext,
  728. .themed-colors #newbonklobby_chat_lowerinstruction,
  729. .themed-colors #newbonklobby_chat_lowerline,
  730. .themed-colors .newbonklobby_chat_msg_txt,
  731. .themed-colors #newbonklobby_chat_input,
  732. .themed-colors #newbonklobby_maptext,
  733. .themed-colors #newbonklobby_roundsinput,
  734. .themed-colors #newbonklobby_mapauthortext,
  735. .themed-colors #newbonklobby_votewindow_maptitle_by,
  736. .themed-colors #hostleaveconfirmwindow_text1,
  737. .themed-colors #leaveconfirmwindow_text1,
  738. .themed-colors .maploadwindowtextmode_picks,
  739. .themed-colors .maploadwindowtextmode,
  740. .themed-colors .maploadwindowtextauthor,
  741. .themed-colors .maploadwindowtextauthor_picks,
  742. .themed-colors .roomlisttablejoined {
  743. color: var(--bonk_theme_secondary_text) !important;
  744. }
  745.  
  746. /* Lobby chat */
  747. .themed-colors .newbonklobby_mapsuggest_low {
  748. color: var(--bonk_theme_secondary_text);
  749. }
  750.  
  751. /* Copy link */
  752. .themed-colors #newbonklobby_chat_content span[style="color: rgb(9, 85, 199);"],
  753. .themed-colors .newbonklobby_chat_link {
  754. color: var(--bonk_theme_blue_text) !important;
  755. }
  756.  
  757. /* /help, player join */
  758. .themed-colors .newbonklobby_playerentry_balance_nerf,
  759. .themed-colors #newbonklobby_chat_content span[style="color: rgb(204, 68, 68);"],
  760. .themed-colors #newbonklobby_chat_content span[style="color: rgb(204, 51, 51);"],
  761. .themed-colors #newbonklobby_chat_content span[style="color: rgb(255, 0, 0);"] {
  762. color: var(--bonk_theme_red_text) !important;
  763. }
  764.  
  765. /* Friend requests */
  766. .themed-colors .newbonklobby_playerentry_balance_buff,
  767. .themed-colors #newbonklobby_chat_content span[style="color: rgb(0, 103, 93);"] {
  768. color: var(--bonk_theme_green_text) !important;
  769. }
  770.  
  771. /* /curate */
  772. .themed-colors #newbonklobby_chat_content span[style="color: rgb(96, 51, 204);"] {
  773. color: var(--bonk_theme_purple_text) !important;
  774. }
  775.  
  776. /* "You are now host" */
  777. .themed-colors #newbonklobby_chat_content span[style="color: rgb(122, 25, 154);"],
  778. .themed-colors #newbonklobby_chat_content span[style="color: rgb(128, 13, 110);"] {
  779. color: var(--bonk_theme_magenta_text) !important;
  780. }
  781.  
  782. .themed-colors .newbonklobby_chat_status:not([style]) {
  783. filter: brightness(var(--bonk_theme_brightness_lighter)) !important;
  784. }
  785.  
  786. .themed-colors #descriptioncontainer,
  787. .themed-colors #gamethumbbox,
  788. .themed-colors #bgreplay {
  789. filter: brightness(var(--bonk_theme_brightness_darker)) !important;
  790. }
  791.  
  792. /* Style sliders and buttons */
  793. .themed-colors .compactSlider {
  794. background-color: transparent !important;
  795. color: var(--bonk_theme_button_text) !important;
  796. }
  797.  
  798. .themed-colors .brownButton_classic,
  799. .themed-colors .dropdown_classic,
  800. .themed-colors .skineditor_field_button,
  801. .themed-colors .mapeditor_field_button,
  802. #theme_save, #theme_cancel, .theme_reset {
  803. border-color: transparent !important;
  804. background-color: var(--bonk_theme_button_color) !important;
  805. color: var(--bonk_theme_button_text) !important;
  806. }
  807.  
  808. .themed-colors .brownButtonDisabled,
  809. .themed-colors .brownButton_disabled_classic,
  810. .themed-colors .dropdown-option-disabled {
  811. background-color: var(--bonk_theme_disabled_button_color) !important;
  812. color: var(--bonk_theme_button_text) !important;
  813. }
  814.  
  815. .themed-colors .brownButton_classic:hover,
  816. .themed-colors .dropdown_classic:hover,
  817. #theme_save:hover, #theme_cancel:hover, .theme_reset:hover {
  818. background-color: var(--bonk_theme_hover_button_color) !important;
  819. color: var(--bonk_theme_button_text) !important;
  820. }
  821.  
  822. .themed-colors .brownButton_classic:active,
  823. .themed-colors .dropdown_classic:active,
  824. .themed-colors .newbonklobby_teamlockbutton_warn,
  825. #theme_save:active, #theme_cancel:active, .theme_reset:active {
  826. background-color: var(--bonk_theme_active_button_color) !important;
  827. color: var(--bonk_theme_button_text) !important;
  828. }
  829.  
  830. /* Tables in the game - Skin editor, Map Editor and Custom game list */
  831. .themed-colors #roomlisttable tr:nth-child(odd),
  832. .themed-colors .friends_table>tbody:nth-child(odd),
  833. .themed-colors #skineditor_layerbox_layertable tr:nth-child(odd),
  834. .themed-colors #mapeditor_leftbox_platformtable tr:nth-child(odd),
  835. .themed-colors #mapeditor_leftbox_spawntable tr:nth-child(odd),
  836. .themed-colors #redefineControls_table tr:nth-child(odd),
  837. .themed-colors .roomlistfilterwindow_a,
  838. .themed-colors #redefineControls_table th {
  839. background-color: var(--bonk_theme_table_color) !important;
  840. color: var(--bonk_theme_primary_text) !important;
  841. }
  842.  
  843. .themed-colors #roomlisttable tr:nth-child(even),
  844. .themed-colors .friends_table tr:nth-child(even),
  845. .themed-colors #skineditor_layerbox_layertable tr:nth-child(even),
  846. .themed-colors #mapeditor_leftbox_platformtable tr:nth-child(even),
  847. .themed-colors #mapeditor_leftbox_spawntable tr:nth-child(even),
  848. .themed-colors #redefineControls_table tr:nth-child(even),
  849. .themed-colors #roomlisttableheadercontainer,
  850. .themed-colors .roomlistfilterwindow_b {
  851. background-color: var(--bonk_theme_table_alt_color) !important;
  852. color: var(--bonk_theme_primary_text) !important;
  853. }
  854.  
  855. .themed-colors #roomlisttable tr.FRIENDSPRESENT,
  856. .themed-colors .maploadwindowtextaddedby_picks {
  857. color: var(--bonk_theme_colored_text) !important;
  858. }
  859.  
  860. .themed-colors tr.HOVERUNSELECTED:hover td {
  861. background-color: var(--bonk_theme_table_hover_color) !important;
  862. }
  863.  
  864. .themed-colors tr.HOVERSELECTED td,
  865. .themed-colors tr.SELECTED td {
  866. background-color: var(--bonk_theme_table_active_color) !important;
  867. }
  868.  
  869. /* "popup" color, custom room list top bar */
  870. .themed-colors .bt-titlebar,
  871. .themed-colors .windowTopBar_classic,
  872. .themed-colors .classicTopBar,
  873. .themed-colors .newbonklobby_boxtop,
  874. .themed-colors .newbonklobby_boxtop_classic,
  875. .themed-colors .friends_topbar,
  876. .themed-colors #newbonklobby_votewindow_top,
  877. .themed-colors #hostleaveconfirmwindow_top,
  878. .themed-colors #leaveconfirmwindow_top,
  879. .themed-colors #ingamecountdown_top,
  880. .themed-colors #roomlisthidepasswordedcheckboxlabel,
  881. #theme_container_title {
  882. background-color: var(--bonk_theme_window_color) !important;
  883. color: var(--bonk_theme_window_text) !important;
  884. }
  885.  
  886. /* Style the top bar */
  887. .themed-colors #pretty_top_bar {
  888. background-color: var(--bonk_theme_top_bar_color) !important;
  889. opacity: var(--bonk_theme_top_bar_opacity) !important;
  890. color: var(--bonk_theme_top_bar_text) !important;
  891. }
  892.  
  893. .themed-colors .pretty_top_button,
  894. .themed-colors #pretty_top_name,
  895. .themed-colors #pretty_top_name,
  896. .themed-colors #pretty_top_level,
  897. .themed-colors #pretty_top_playercount {
  898. background-color: var(--bonk_theme_top_bar_color) !important;
  899. color: var(--bonk_theme_top_bar_text) !important;
  900. }
  901.  
  902. .themed-colors .pretty_top_button:hover {
  903. background-color: var(--bonk_theme_top_bar_hover_color) !important;
  904. }
  905.  
  906. /* Invert the Bonk.io description at the bottom of the page */
  907. .themed-colors #descriptioninner,
  908. .themed-colors #descriptioninner .descriptionthumbr,
  909. .themed-colors #descriptioninner .descriptionthumbl {
  910. filter: invert(var(--bonk_theme_description_invert)) !important;
  911. }
  912.  
  913. /* Change color of borders in settings */
  914. .themed-colors #redefineControls_table td,
  915. .themed-colors #redefineControls_table th,
  916. .themed-colors #redefineControls_table {
  917. border: 1px solid var(--bonk_theme_border_color) !important;
  918. }
  919.  
  920. /* Players in lobby */
  921. .themed-colors .newbonklobby_playerentry {
  922. border-left: 4px solid var(--bonk_theme_primary_background) !important;
  923. border-top: 4px solid var(--bonk_theme_primary_background) !important;
  924. border-right: 4px solid var(--bonk_theme_primary_background) !important;
  925. background-color: var(--bonk_theme_primary_background) !important;
  926. color: var(--bonk_theme_primary_text) !important;
  927. }
  928.  
  929. .themed-colors .newbonklobby_playerentry:hover {
  930. border-left: 4px solid var(--bonk_theme_secondary_background) !important;
  931. border-top: 4px solid var(--bonk_theme_secondary_background) !important;
  932. border-right: 4px solid var(--bonk_theme_secondary_background) !important;
  933. background-color: var(--bonk_theme_secondary_background) !important;
  934. }
  935.  
  936. .themed-colors #newbonklobby_chat_lowerline {
  937. border-top: 1px solid var(--bonk_theme_border_color) !important;
  938. }
  939.  
  940. .themed-colors #newbonklobby_playerbox_middleline {
  941. border-left: 1px solid var(--bonk_theme_border_color) !important;
  942. }
  943.  
  944. /* Headings in the Map Editor and stuff */
  945. .themed-colors .friends_titles,
  946. .themed-colors .mapeditor_table_heading_div {
  947. background-color: var(--bonk_theme_list_headers) !important;
  948. }
  949.  
  950. /* Change the XP bar to use the colors we want */
  951. .themed-colors #xpbarfill {
  952. background-color: var(--bonk_theme_xp_bar_fill) !important;
  953. }
  954.  
  955. /* Below is CSS for our theme editor thing */
  956. #theme_container {
  957. border-radius: 3px 0px 3px 3px;
  958. z-index: 999;
  959. font-family: "futurept_b1";
  960. padding: 0px;
  961. right: 0px;
  962. top: 0px;
  963. position: fixed;
  964. overflow-y: scroll;
  965. max-height: 100vh;
  966. width: 20em;
  967. }
  968.  
  969. #configuration_list {
  970. padding: 1.5em;
  971. display: flex;
  972. flex-direction: column;
  973. }
  974.  
  975. #theme_container_title {
  976. text-align: center;
  977. margin: 0px;
  978. font-size: 20px;
  979. line-height: 32px;
  980. font-family: "futurept_b1"
  981. }
  982.  
  983. .configuration_container {
  984. white-space: pre-line;
  985. display: flex;
  986. justify-content: space-between;
  987. align-items: center;
  988. height: 2.25em;
  989. }
  990.  
  991. .configuration_name {
  992. text-transform: capitalize;
  993. float: left;
  994. width: 70%;
  995. }
  996.  
  997. .configuration_value {
  998. float: right;
  999. width: 25%;
  1000. }
  1001.  
  1002. #theme_cancel {
  1003. float: left;
  1004. }
  1005.  
  1006. #theme_save {
  1007. float: right;
  1008. }
  1009.  
  1010. #theme_save,
  1011. #theme_cancel {
  1012. width: 45%;
  1013. height: 30px;
  1014. line-height: 30px;
  1015. }
  1016.  
  1017. #configuration_json {
  1018. align-self: center;
  1019. resize: none;
  1020. width: 100%;
  1021. height: 15em;
  1022. }
  1023. `);
  1024. });
  1025. })();