Reddit CSS

New Design with new functionalities

  1. // ==UserScript==
  2. // @name Reddit CSS
  3. // @namespace https://www.reddit.com
  4. // @version 7.4
  5. // @description New Design with new functionalities
  6. // @author Agreasyforkuser
  7. // @match https://old.reddit.com/*
  8. // @match https://rapidsave.com/*
  9. // @exclude https://new.reddit.com/*
  10. // @icon https://www.redditstatic.com/desktop2x/img/favicon/android-icon-192x192.png
  11. // @license MIT
  12. // @grant GM_addStyle
  13. // ==/UserScript==
  14.  
  15. /////////////////// add CSS styles ////////////////////////////////////////////////////////////////////////
  16.  
  17. (function() {
  18. 'use strict';
  19.  
  20. GM_addStyle(`
  21.  
  22. :root {
  23. --theme-color-new: #cee3f8;
  24. --tab-text-color: #336699;
  25. --tab-text-color-selected: #ff4500;
  26. --action-button-color: #000000c7;
  27. --action-button-background: #0000000d;
  28. --general-text-background: white;
  29. --video-background: white;
  30. }
  31.  
  32.  
  33.  
  34. #header, #header:hover {background-color: var(--theme-color-new)}
  35. #header-bottom-right {background: var(--theme-color-new)}
  36. #header-bottom-right:hover {background: var(--general-text-background)}
  37. #header-bottom-right a:not(.message-count), .userkarma {color: var(--tab-text-color) !important}
  38. #header-bottom-right:not(:hover) .user a {opacity: 0 !important}
  39. #header-bottom-right:not(:hover) .user a.login-required {opacity: 1 !important}
  40. .user .userkarma {font-weight: normal}
  41. .user {color: var(--tab-text-color)}
  42. #sr-more-link {background-color: var(--theme-color-new)}
  43. #sr-header-area {background-color: var(--theme-color-new) !important}
  44. #sr-header-area a {background-color: var(--theme-color-new) !important; color: var(--tab-text-color) !important}
  45. .selected.title {color: var(--tab-text-color) !important}
  46. .media-gallery .gallery-nav-bar {color:var(--tab-text-color)}
  47. .media-gallery .gallery-nav-next,
  48. .media-gallery .gallery-nav-prev,
  49. .media-gallery .gallery-nav-back {border:1px solid var(--tab-text-color);background:var(--theme-color-new)}
  50. .nav-buttons {border: 3px solid var(--theme-color-new); background-color: var(--theme-color-new)}
  51. #header .tabmenu li a {color: var(--tab-text-color); background: var(--theme-color-new) !important}
  52. #header .tabmenu li.selected a {color:var(--tab-text-color-selected); background-color: var(--general-text-background) !important}
  53. #header .tabmenu li a:hover {background: var(--general-text-background) !important; color: var(--tab-text-color)}
  54. body.with-listing-chooser #header .pagename {color: var(--general-text-background)}
  55. .pagename {background-color: var(--general-text-background) !important}
  56. .pagename a {color: black !important}
  57. body, body > .content {background: var(--general-text-background)}
  58. .thing.even, .thing.odd {background: var(--general-text-background) !important}
  59. .side {background-color: var(--general-text-background)}
  60. .entry .buttons li a {color: var(--action-button-color)}
  61. .entry .buttons li {background: var(--action-button-background)}
  62. .reddit-video-player-root {background: var(--video-background) !important}
  63.  
  64.  
  65.  
  66. /* Adjust the size of the thumbnails */
  67.  
  68. .thumbnail, .thumbnail img, .link .thumbnail img{
  69. width: 200px !important;
  70. height: auto !important;
  71. position: relative;
  72. margin-bottom: 0;
  73. }
  74.  
  75. .comments-page .thumbnail, .comments-page .thumbnail img {width: 50px !important; height: auto !important; max-height: 50px !important}
  76.  
  77. /* Hide weird empty thumbnail placeholders on textposts or other posts */
  78.  
  79. .thumbnail.invisible-when-pinned.self.may-blank,
  80. .thumbnail.invisible-when-pinned.default.may-blank.outbound,
  81. .thumbnail.invisible-when-pinned.nsfw.may-blank,
  82. .thumbnail.invisible-when-pinned.nsfw.may-blank.outbound {display: none !important}
  83.  
  84. /* similar thing on search page */
  85. .combined-search-page .may-blank.thumbnail.self,.combined-search-page .may-blank.thumbnail.default {height: 50px !important}
  86.  
  87.  
  88.  
  89. .expando-button {opacity: 0.1 !important; float:right !important}
  90.  
  91. /* Visibility of text posts */
  92. .expando-button.selftext {opacity:0.1; height:50px !important; width:200px !important; float:left !important; background-image:none !important;background-color: black !important}
  93.  
  94.  
  95.  
  96. /* search page */
  97. /*.search-result :link {display:inline-table !important}*/
  98. .search-result :link:not(a.option.remove) {display: inline-table !important}
  99. .search-result-group {max-width: none}
  100. .search-header-menus {float: none}
  101. .search-header-label {display: none}
  102. .combined-search-page .raisedbox h4 {opacity: 0}
  103.  
  104.  
  105. /* Video Controls for Mobile */
  106. video::-webkit-media-controls-panel {background: none; opacity: 1}
  107. video::-webkit-media-controls-overlay-play-button {opacity: 0}
  108.  
  109. /* Video controls for Desktop */
  110. .reddit-video-controller-root.playback-controls {background: rgba(0,0,0,0.75) !important; border-radius: 50px !important}
  111. .reddit-video-controller-root.playback-controls:hover {background: rgba(0,0,0,0.95) !important}
  112. .reddit-video-controller-root.playback-controls a.permalink {display: none !important}
  113. .reddit-video-controller-root.ended-controls, .reddit-video-controller-root.buffering-controls {background: none !important}
  114. .reddit-video-controller-root.ended-controls .centered span.replay-video {display: none !important}
  115. .reddit-video-controller-root.playback-controls .reddit-video-seek-bar-root .seek-bar-thumb {opacity: 1 !important}
  116. .reddit-video-controller-root.playback-controls .time-label {font-weight: bold}
  117.  
  118. /* Video Duration Info */
  119. .duration-overlay {font-size: 10pt; font-weight: bold; width:auto !important; padding:2px; right:0}
  120.  
  121.  
  122. /* Stamps */
  123. .nsfw-stamp {background: #d10023; color:white; font-weight:bold !important; border: 2px solid #d10023 !important;}
  124. .spoiler-stamp {background: black; color:white; font-weight:bold !important; border: 2px solid black !important;}
  125.  
  126.  
  127.  
  128. /* Subreddit Name */
  129. body.with-listing-chooser #header .pagename {position:inherit}
  130. .pagename a {margin-left:4px; margin-right:4px; padding:0}
  131. .pagename {font-variant: normal; border-radius:0px; margin: 0 !important; padding: 0 !important}
  132. /* match pagename height with subreddit logo */
  133. .pagename {display: inline-grid !important; height: 35px !important; align-content: center !important}
  134. .pagename a {vertical-align: middle !important}
  135.  
  136.  
  137. /* no margin left for expanded media */
  138. .entry {margin-left:0}
  139.  
  140. /* size videos correctly */
  141. .no-constraints-when-pinned {min-width:0 !important; min-height: 0 !important;}
  142.  
  143. /* OP indicator */
  144. .tagline .submitter, .search-result-meta .submitter {color: #228822}
  145.  
  146. /* sort menu*/
  147. .menuarea {border:none}
  148. .dropdown.lightdrop .selected {text-decoration: none; background-image: none}
  149.  
  150. /* Post */
  151. .thing .title {font-weight: normal !important; color: black !important}
  152. .link .subreddit {font-weight: bold !important}
  153. .link .flat-list {font-weight: normal !important; font-size: medium !important}
  154. .entry .buttons li a {font-weight: normal !important}
  155.  
  156. /*revert graying-out function on hover*/
  157. .entry .buttons li:hover {opacity:1 !important}
  158.  
  159.  
  160. /* Text Posts Background/Fontcolor/Border */
  161. .link .usertext-body .md {color: black !important; background: none !important; border-color: var(--theme-color-new)}
  162.  
  163.  
  164.  
  165.  
  166. /* Space between Posts */
  167. .link {margin-bottom: 0px;}
  168.  
  169. /* Expanded Post Margins */
  170. .expando {margin: 0}
  171.  
  172. /* hide some buttons */
  173. .domain {display: none}
  174. .reportbtn {display: none}
  175. .post-crosspost-button {display: none}
  176. .post-sharing-button {display: none}
  177. .buttons .give-gold.gold-give-gold {display: none}
  178. .hide-button {display: none !important}
  179. .comments-page .reportbtn {display: block}
  180. .profile-page .reportbtn {display: block}
  181. .comments-page .post-crosspost-button {display: block}
  182. .comments-page a.comments {display: none}
  183. .comments-page a.embed-comment {display: none}
  184. .comments-page .sendreplies-button {display: none !important}
  185. .comments-page .bylink {display: none !important}
  186. .comments-page .stamp {display: none !important}
  187.  
  188.  
  189. /* Gallery Buttons */
  190. .media-gallery .gallery-nav-bar {font-size:large; display:grid}
  191. .media-gallery .gallery-nav-next {text-align: right !important}
  192. .media-gallery .gallery-nav-prev {text-align: left !important}
  193. .media-gallery .gallery-nav-back {text-align: center !important}
  194. .media-gallery .gallery-nav-next:after {content:" ▶"}
  195. .media-gallery .gallery-nav-prev:before {content:"◀ "}
  196. .gallery-navigation {border: none}
  197. .gallery-nav-disabled {opacity:0 !important}
  198.  
  199. /* Rank / Scores */
  200. .link .rank {display: none}
  201. .link .arrow.up {display: none}
  202. .link .arrow.down {display: none}
  203.  
  204. /* Header Font Size and Icon */
  205. #header-bottom-left {font-size: large}
  206. #header-bottom-left {margin-top: 0}
  207. .comments-page #header-img:not(:hover) {opacity: 0}
  208. .comments-page #header-img.default-header:not(:hover) {opacity: 0}
  209. #header-img, #header-img.default-header {vertical-align: bottom; margin: 0}
  210. #header-img {max-width: 32px; max-height: 32px}
  211.  
  212. /* Upper Bars */
  213. #sr-header-area {border-bottom: none}
  214. #sr-header-area .redesign-beta-optin {display:none}
  215. .pref-lang {font-weight: normal}
  216. #header-bottom-right {border-radius:0; border: none !important}
  217. #header-bottom-right {font-size: larger}
  218. #header {border:none}
  219. .separator {color: transparent}
  220. .tabmenu li a {font-weight: normal;opacity:1 !important}
  221. .tabmenu li.selected a {opacity:1; font-weight: bold; border: none}
  222.  
  223.  
  224.  
  225. /* Sidebar */
  226. .sidecontentbox .content {border: none; background: none}
  227. .sidebox .spacer {display: none}
  228. .premium-banner {display: none}
  229. .giftgold {display: none}
  230. .titlebox .bottom {border:none}
  231. #searchexpando, .linkinfo, .linkinfo .shortlink input {border: none}
  232. .morelink .nub {display: none}
  233. .morelink {border: none; background: #eff7ff;background-image:none}
  234. .subscription-box:not(:hover) {opacity: 0}
  235.  
  236.  
  237. /* Comment Page */
  238. .comments-page .tabmenu a.choice[href*="comments"] {display:none !important}
  239. .panestack-title {padding-bottom: 0px; border-bottom: none}
  240. .panestack-title .title {font-size: large !important}
  241. .panestack-title::after {font-size: large !important}
  242. .commentarea .menuarea {font-size: large !important}
  243. .comments-page .dropdown-title.lightdrop {display: none}
  244. .comments-page .comment .author {font-size: unset; float: left !important; margin-right: 5px !important}
  245. .comments-page .comment .score {font-size: unset; float: left !important; margin-right: 5px !important}
  246. .comments-page .comment .tagline .userattrs {font-size: unset; float: left !important; margin-right: 5px !important}
  247. .comments-page .comment .tagline time {font-size: unset; float: left !important; margin-right: 5px !important; margin-left: 0px}
  248. .comments-page .comment .tagline {margin-bottom: 26px}
  249. .comments-page .numchildren {font-size: unset; float: left !important}
  250. .comments-page .comment .flair {font-size: unset; float: left !important}
  251. .comments-page .comment .expand {font-size: unset; float: left !important; margin: 0 !important; padding: 0 !important; opacity: 0.09}
  252. .comments-page .comment.collapsed .expand {opacity:1}
  253. .comment .midcol {z-index:9999}
  254. .comment .child {border-left: 3px solid var(--theme-color-new)}
  255. .commentarea .entry:not(:hover) .buttons {opacity: 0}
  256. .comments-page #siteTable .thing {display: flex !important;border: none}
  257.  
  258.  
  259. /* text-area */
  260. .commentarea > .usertext textarea {max-width: 95vw !important; height: 40px}
  261. .usertext-edit {max-width: 95vw !important; margin: 0 !important}
  262. .commentarea > .usertext button {margin: 0 !important}
  263. .commentarea .md {margin: 0 !important}
  264.  
  265.  
  266.  
  267. .comments-page .comment .score {visibility: visible; margin-right: 0}
  268. .comments-page .link .arrow.up {display:block}
  269. .comments-page .link .arrow.down {display:block}
  270. .pinnable-content.pinned {background-color: #FFFFFFF7 !important;box-shadow: none !important}
  271. .reddiquette {display: none}
  272. .edited-timestamp {color: red}
  273.  
  274. .comments-page .expando-button {opacity: 1 !important}
  275. /* without this voting comments on mobile is impossible */
  276. .comments-page .entry {margin-left:4px}
  277.  
  278.  
  279.  
  280. /* mark controversial comments even when logged-out */
  281. .comment.controversial>.entry .score:after {content: "†"; position: relative; top: -2px}
  282.  
  283. /* bigger profile picture next to post */
  284. /* .link .reddit-profile-picture {width: 33px !important; height: 33px !important} */
  285.  
  286.  
  287. /* submissions */
  288. .formtabs-content .infobar {border:none}
  289. .content.submit .info-notice {display: none}
  290. #items-required {display: none}
  291.  
  292.  
  293. /* Bottom Page */
  294. .footer {display:none}
  295. .footer-parent {opacity:0}
  296. .debuginfo {display:none}
  297. .bottommenu {display:none}
  298.  
  299. /* Navbar */
  300. .nav-buttons {
  301. position: fixed;
  302. display:table;
  303. bottom: 0 !important;
  304. right: 0 !important;
  305. text-align: center !important;
  306. font-size: larger;
  307. z-index: 1000000 !important;
  308. }
  309. .nextprev a {background:none !important}
  310.  
  311.  
  312. /* promoted posts/ads */
  313. .link.promotedlink.promoted, .link.promotedlink.external {display:none !important}
  314. .mobile-web-redirect-bar {display:none !important}
  315.  
  316.  
  317. .email-collection-banner, .email-verification-tooltip, #eu-cookie-policy {display:none !important}
  318. .infobar.listingsignupbar, .infobar.commentsignupbar {display: none !important;}
  319. .infobar, .timeout-infobar {border:none}
  320. .help-hoverable {display:none}
  321. /*.reddit-infobar.with-icon {min-height: 35px !important;padding: 0 0 0 55px !important;height: 35px !important;}*/
  322. /*.reddit-infobar.with-icon:not(:hover) {min-height: 0 !important;padding: 0 0 0 55px !important;margin: 0 !important;height: 9px !important;opacity:0 !important}*/
  323.  
  324. /* chat window */
  325. .chat-app-window.regular {width: 100%; height: 70%}
  326. .chat-app-window {right: 0; border: none; border-radius: 0}
  327.  
  328.  
  329. /* Turn off custom subreddit styles */
  330. #header, #header:hover {background-image: none !important}
  331. .link {padding: 0}
  332. .thumbnail, .thumbnail img {max-width: none; max-height: none; transform: none}
  333. .link .entry .buttons li a.comments {color:#000000c7 !important}
  334. .link.odd, .link.even {padding: 0 !important; margin-right: 0px !important}
  335. body > .content {max-width: none !important}
  336. html body div#header div#header-bottom-left span.pagename a {font-size: 1.2em !important; padding: 0; padding-right: 0; height: 0}
  337. span.hover.pagename.redditname {font-size: 1.2em !important}
  338. #header-bottom-left #header-img-a {margin: 0}
  339. .pagename a {line-height: 0px; background: none}
  340. .pagename a {border: none}
  341. #header .pagename a {line-height: 0px}
  342. #header .pagename > a {color: black !important}
  343. .link > .thumbnail {border-radius:0 !important}
  344. * {text-shadow: none !important}
  345. .title {color:black !important}
  346. .thing.link .title a.title {color: black !important}
  347. body {border: none}
  348. .tabmenu li.selected a {opacity: 1 !important;color: #ff4500 !important; border: none !important}
  349. #header-bottom-left .tabmenu {left: 0 !important}
  350. #header {margin: 0 !important}
  351. #header .tabmenu li a {border: none}
  352. `);
  353. //////////////////////////////// over 18 button ///////////////////////////////////////////////////////
  354.  
  355. const button = document.querySelector('button.c-btn.c-btn-primary[type="submit"][name="over18"][value="yes"]');
  356. if (button) {button.click();}
  357.  
  358. //////////////////////////////// auto-click on NSFW-disclaimers ////////////////////////////////////////
  359.  
  360. (function() {
  361. 'use strict';
  362. // Function to click on elements with class 'expando-gate__show-once'
  363. function clickExpandoGate() {
  364. var elements = document.querySelectorAll('.expando-gate.expando-gate--overlay, .expando-gate.expando-gate--interstitial');
  365. elements.forEach(function(element) {
  366. if (!element.dataset.expandoClicked) {
  367. element.click();
  368. element.dataset.expandoClicked = true;
  369. }
  370. });
  371. }
  372. // Create a MutationObserver to watch for changes in the DOM
  373. var observer = new MutationObserver(function(mutations) {
  374. mutations.forEach(function(mutation) {
  375. // Check if the target node or its descendants have elements with class 'expando-gate__show-once'
  376. if (mutation.target.matches('.expando-gate.expando-gate--overlay') || mutation.target.querySelector('.expando-gate.expando-gate--overlay')) {clickExpandoGate();}
  377. // embedded youtube-videos need this
  378. if (mutation.target.matches('.expando-gate.expando-gate--interstitial') || mutation.target.querySelector('.expando-gate.expando-gate--interstitial')) {clickExpandoGate();}
  379. });
  380. });
  381. // Define the configuration for the MutationObserver
  382. var config = { subtree: true, childList: true };
  383. // Start observing the document with the specified configuration
  384. observer.observe(document.body, config);
  385. // Initial click on elements with class 'expando-gate__show-once'
  386. clickExpandoGate();
  387. })();
  388.  
  389. GM_addStyle(`.expando-gate.expando-gate--overlay {display:none !important}`);
  390.  
  391. /////////////////////////////// auto-click download link after opening the rapidsave page ///////////////
  392. const dbutton = document.querySelector('.downloadbutton');
  393. if (dbutton) {
  394. dbutton.click();
  395. }
  396.  
  397. })();
  398.  
  399. ////////////////////////////////////// comments page //////////////////////////////////
  400.  
  401. var commentpage = /https:\/\/.*\.reddit\.com\/.*\/comments\/.*/;
  402. if (commentpage.test(window.location.href)) {
  403.  
  404.  
  405. ////////////////////////////////// Download Button ////////////////////////////////////
  406.  
  407. 'use strict';
  408.  
  409. function downloadVideo() {
  410. var postUrl = window.location.href;
  411. var baseUrl = 'https://rapidsave.com/info?url=';
  412. var downloadUrl = baseUrl + encodeURIComponent(postUrl);
  413. window.open(downloadUrl, '_blank');
  414. }
  415.  
  416. function createDownloadButton() {
  417. var listItem = document.createElement('li');
  418. listItem.classList.add('reddit-video-download-button');
  419.  
  420. var button = document.createElement('button');
  421. button.innerHTML = 'download ⤓';
  422. button.style.color = 'var(--action-button-color)';
  423. button.style.background = 'none';
  424. button.style.border = 'none';
  425. button.style.fontSize = 'inherit';
  426. button.style.margin = 'inherit';
  427. button.style.padding = 'inherit';
  428. // button.style.borderRadius = '10px';
  429. button.style.fontWeight = 'inherit';
  430. button.style.height = 'inherit';
  431. button.style.textTransform = 'none';
  432. button.onclick = downloadVideo;
  433.  
  434. listItem.appendChild(button);
  435.  
  436. var buttonsList = document.querySelector('ul.buttons');
  437. if (buttonsList) {
  438. buttonsList.appendChild(listItem);
  439. }
  440. }
  441.  
  442. createDownloadButton();
  443.  
  444.  
  445. /////////////////////add profile pictures next to comments ///////////////////////
  446.  
  447. // const addAvatars = async (root = document) => {
  448. // Array.from(root.querySelectorAll('.thing:not(.morechildren)')).forEach(async (thing) => {
  449. // if (!thing) return;
  450. // if (thing.hasAttribute('data-reddit-profile-picture')) return;
  451. // const img = document.createElement('img');
  452. // img.classList.add('reddit-profile-picture');
  453. // img.style.height = '22px';
  454. // img.style.width = '22px';
  455. // img.style.float = 'left';
  456. // img.style.margin = '0px';
  457. // thing.insertBefore(img, thing.querySelector('.entry'));
  458. // thing.setAttribute('data-reddit-profile-picture', 1);
  459. // if (!thing.id) return;
  460. // const authorElement = thing.querySelector('.author');
  461. // if (authorElement && authorElement.href) {
  462. // const xhr = new XMLHttpRequest();
  463. // xhr.open('GET', `${authorElement.href}/about.json`);
  464. // xhr.addEventListener('load', async () => {
  465. // if (xhr.status === 200) {
  466. // try {
  467. // const profile = JSON.parse(xhr.responseText).data;
  468. // const ta = document.createElement('textarea');
  469. // ta.innerHTML = profile.icon_img;
  470. // img.src = ta.value;
  471. // } catch (error) {
  472. // // Error parsing JSON or extracting URL
  473. // console.error('Error parsing JSON or extracting URL:', error);
  474. // removeAvatar(img);
  475. // }
  476. // } else {
  477. // // Non-200 status, handle error
  478. // console.error('Error fetching user data:', xhr.status, xhr.statusText);
  479. // removeAvatar(img);
  480. // }
  481. // });
  482. // xhr.addEventListener('error', () => {
  483. // // Network error
  484. // console.error('Network error while fetching user data.');
  485. // removeAvatar(img);
  486. // });
  487. // xhr.send();
  488. // }
  489. // });
  490. // };
  491.  
  492. // const removeAvatar = (imgElement) => {
  493. // if (imgElement && imgElement.parentNode) {
  494. // imgElement.parentNode.removeChild(imgElement);
  495. // }
  496. // };
  497.  
  498. // addAvatars();
  499.  
  500. // const mo = new MutationObserver((muts) => {
  501. // muts.forEach((mut) => {
  502. // Array.from(mut.addedNodes).forEach((node) => {
  503. // if (node instanceof HTMLElement) {
  504. // addAvatars();
  505. // }
  506. // });
  507. // });
  508. // });
  509. // mo.observe(document.body, { childList: true, subtree: true });
  510. };
  511.  
  512. ////////////////////////////// userpage ///////////////////////////////////////////////////////////////////
  513.  
  514. var userpage = /https:\/\/.*\.reddit\.com\/user\/.*/;
  515. if (userpage.test(window.location.href)) {
  516.  
  517. GM_addStyle(`.comment, .content .details {border-bottom: 2px solid var(--theme-color-new) !important}`);
  518.  
  519. const addProfilePictures = async (root = document) => {
  520. Array.from(root.querySelectorAll('.pagename')).forEach(async (pagename) => {
  521. if (!pagename) return;
  522. if (pagename.hasAttribute('data-reddit-profile-picture')) return;
  523.  
  524. const username = pagename.textContent.trim();
  525. if (!username) return;
  526.  
  527. const img = document.createElement('img');
  528. img.classList.add('reddit-profile-picture');
  529. img.style.height = '35px';
  530. img.style.width = '35px';
  531. img.style.verticalAlign = 'middle';
  532.  
  533.  
  534. pagename.parentNode.insertBefore(img, pagename.nextSibling);
  535.  
  536. pagename.setAttribute('data-reddit-profile-picture', 1);
  537.  
  538. const xhr = new XMLHttpRequest();
  539. xhr.open('GET', `https://www.reddit.com/user/${username}/about.json`);
  540. xhr.addEventListener('load', async () => {
  541. const profile = JSON.parse(xhr.responseText).data;
  542. const ta = document.createElement('textarea');
  543. ta.innerHTML = profile.icon_img;
  544. img.src = ta.value;
  545. });
  546. xhr.send();
  547. });
  548. };
  549.  
  550. addProfilePictures();
  551.  
  552. const mo = new MutationObserver((muts) => {
  553. muts.forEach((mut) => {
  554. Array.from(mut.addedNodes).forEach((node) => {
  555. if (node instanceof HTMLElement) {
  556. addProfilePictures(node);
  557. }
  558. });
  559. });
  560. });
  561.  
  562. mo.observe(document.body, { childList: true, subtree: true });
  563.  
  564. };
  565.  
  566.  
  567. //////////////////////////////////////////// red numbers if score is less than one //////////////////////////////////////
  568.  
  569. if (userpage.test(window.location.href) || commentpage.test(window.location.href)) {
  570. (function() {
  571. 'use strict';
  572.  
  573. // Function to check if the text starts with a "-" or "0"
  574. function startsWithNegativeSymbolOrZero(text) {
  575. return text.trim().startsWith('-') || text.trim().startsWith('0');
  576. }
  577.  
  578. // Get all elements with class "score likes"
  579. var scoreElements = document.querySelectorAll('.comment .score');
  580.  
  581. // Iterate over each score element using forEach
  582. scoreElements.forEach(function(scoreElement) {
  583. var scoreText = scoreElement.textContent.trim();
  584.  
  585. // Check if the score starts with a "-" or "0"
  586. if (startsWithNegativeSymbolOrZero(scoreText)) {
  587. // Change the color to red
  588. scoreElement.style.color = 'red';
  589. scoreElement.style.fontWeight = 'bold';
  590. } else if (parseFloat(scoreText) > 1) {
  591. // Change the color to green
  592. scoreElement.style.color = 'green';
  593. scoreElement.style.fontWeight = 'bold';
  594. }
  595. });
  596. })();
  597. }
  598. ////////////////////////////// open links in new tab, sorts comments by new, gray-out comments button if there are no comments /////////////////////////////////
  599. if (!commentpage.test(window.location.href)) {
  600. 'use strict';
  601.  
  602. const removeCommentsCount = element => {
  603. const text = element.textContent.trim();
  604. if (!isNaN(parseInt(text.charAt(0), 10))) return;
  605. element.closest('.entry .buttons li a').style.opacity = '0.1';
  606. };
  607.  
  608. const openInNewTab = element => {
  609. element.setAttribute('target', '_blank');
  610. };
  611.  
  612. const modifyCommentLink = element => {
  613. element.addEventListener('click', event => {
  614. event.preventDefault(); // Prevent the default action (navigation) for now
  615. const url = new URL(element.href); // Parse the current URL
  616. url.searchParams.set('sort', 'new'); // Add or update the "sort=new" parameter
  617. window.open(url.toString(), '_blank'); // Open the updated URL in a new tab
  618. });
  619. };
  620.  
  621. const commentElements = document.querySelectorAll('a.comments');
  622. const postTitleElements = document.querySelectorAll('.thing .title');
  623. const postLinkElements = document.querySelectorAll('.link .title');
  624. const postauthorElements = document.querySelectorAll('.author');
  625. const subredditElements = document.querySelectorAll('.subreddit');
  626.  
  627. commentElements.forEach(removeCommentsCount);
  628. commentElements.forEach(modifyCommentLink);
  629. postTitleElements.forEach(openInNewTab);
  630. postLinkElements.forEach(openInNewTab);
  631. postauthorElements.forEach(openInNewTab);
  632. subredditElements.forEach(openInNewTab);
  633.  
  634. const observer = new MutationObserver(mutationsList => {
  635. for (const mutation of mutationsList) {
  636. if (mutation.type === 'childList') {
  637. const newCommentElements = mutation.addedNodes;
  638. newCommentElements.forEach(node => {
  639. if (node instanceof HTMLElement) {
  640. const element = node.querySelector('a.comments');
  641. const element2 = node.querySelector('.author');
  642. const element3 = node.querySelector('.subreddit');
  643. if (element) {
  644. removeCommentsCount(element);
  645. modifyCommentLink(element); // Apply modification for new comment links
  646. }
  647. if (element2) {openInNewTab(element2);}
  648. if (element3) {openInNewTab(element3);}
  649. }
  650. });
  651. }
  652. }
  653. });
  654. observer.observe(document.body, { childList: true, subtree: true });
  655. }
  656.  
  657. /////////////////////////////////////////////////Thumbnail Click Functionality //////////////////
  658.  
  659. // Custom CSS for the clicked thumbnail
  660. const customCSS = `
  661. /* Makes Clicking Easier */
  662. .thumbnail {z-index:99}
  663.  
  664. .thumbnail.clicked {
  665. width: 80px !important;
  666. height: 80px !important;
  667. opacity:0.5;
  668. }
  669.  
  670. .thumbnail.clicked img {
  671. width: 80px !important;
  672. height: 80px !important;
  673. }
  674.  
  675. .thing.clicked .arrow.up {display: block}
  676. .thing.clicked .arrow.down {display:block}
  677. `;
  678.  
  679. function expandPostOnElementClick(element) {
  680. const expandoButton = element.closest('.thing').querySelector('.expando-button');
  681.  
  682. if (expandoButton) {
  683. expandoButton.click();
  684. }
  685. }
  686.  
  687. function handleElementClick(event) {
  688. event.stopPropagation();
  689. event.preventDefault();
  690.  
  691. const element = event.currentTarget;
  692. const thumbnail = element.closest('.thumbnail');
  693. const thing = element.closest('.thing');
  694.  
  695. // Check if the thumbnail has the 'clicked' class
  696. const isClicked = thumbnail.classList.contains('clicked');
  697.  
  698. if (isClicked) {
  699. // Remove the 'clicked' class to revert the changes
  700. thumbnail.classList.remove('clicked');
  701. thing.classList.remove('clicked');
  702. } else {
  703. // Add 'clicked' class to the thumbnail
  704. thumbnail.classList.add('clicked');
  705. thing.classList.add('clicked');
  706. }
  707.  
  708. expandPostOnElementClick(element);
  709. }
  710.  
  711. function attachClickListenersToElements() {
  712. const elements = document.querySelectorAll('.thumbnail, img[src*="external-preview.redd.it"]');
  713.  
  714. elements.forEach((element) => {
  715. element.addEventListener('click', handleElementClick);
  716. });
  717. }
  718.  
  719. // Add custom CSS styles
  720. GM_addStyle(customCSS);
  721.  
  722. // Attach click listeners to elements initially
  723. attachClickListenersToElements();
  724.  
  725. // Create a MutationObserver to monitor the page for changes
  726. const observer = new MutationObserver(() => {
  727. // Attach click listeners to elements whenever new content is added to the page
  728. attachClickListenersToElements();
  729. });
  730.  
  731. // Start observing the document for changes
  732. observer.observe(document, { childList: true, subtree: true });
  733.  
  734.  
  735. ////////////////////////////////////// Subreddit Icon next to Subreddit name /////////////////////////
  736.  
  737. // (function() {
  738. // 'use strict';
  739.  
  740. // function setSubredditIcon() {
  741. // const pagenameLink = document.querySelector('.pagename');
  742. // const subredditIcon = document.createElement('img');
  743. // subredditIcon.style.verticalAlign = 'middle';
  744. // subredditIcon.style.width = 'auto';
  745. // subredditIcon.style.height = '35px';
  746. // subredditIcon.classList.add('subreddit-icon');
  747.  
  748. // const srName = getSrName();
  749.  
  750. // const srDataUrl = `https://www.reddit.com/r/${srName}/about.json`;
  751. // fetch(srDataUrl)
  752. // .then(response => response.json())
  753. // .then(data => {
  754. // const communityIcon = cleanUpCommunityIcon(data.data.community_icon);
  755. // const iconUrl = communityIcon || data.data.icon_img || data.data.header_img;
  756. // if (!iconUrl || iconUrl.length === 0)
  757. // {
  758. // return;
  759. // }
  760. // subredditIcon.src = iconUrl;
  761. // pagenameLink.parentNode.insertBefore(subredditIcon, pagenameLink.nextSibling);
  762. // })
  763. // }
  764. // function getSrName() {
  765. // const srNameRegex = /https:[/][/](www|old|new)[.]reddit[.]com[/]r[/](\w+)/g;
  766. // const match = srNameRegex.exec(document.location.href);
  767.  
  768. // return match[2];
  769. // }
  770. // function cleanUpCommunityIcon(url) {
  771. // if (!url || url.length === 0) {
  772. // return url;
  773. // }
  774. // function htmlDecode(input) {
  775. // const doc = new DOMParser().parseFromString(input, 'text/html');
  776. // return doc.documentElement.textContent;
  777. // }
  778. // const decodedUrl = htmlDecode(url);
  779. // return decodedUrl;
  780. // }
  781. // setSubredditIcon();
  782. // })();
  783. //////////////////////////////// add button that redirects to the new.reddit.com version of the page //////////////////////////
  784.  
  785. function changeUrl() {
  786. // Replace "old" with "new" in the current URL
  787. var oldUrl = window.location.href;
  788. var newUrl = oldUrl.replace('old', 'new');
  789. // Open the new URL in the same window
  790. window.location.href = newUrl;
  791. }
  792.  
  793. function createChangeUrlButton() {
  794. var button = document.createElement('button');
  795. button.innerHTML = 'new.reddit';
  796. button.style.color = 'var(--tab-text-color)';
  797. button.style.background = 'transparent';
  798. button.style.border = 'none';
  799. button.style.fontSize = 'inherit';
  800. button.onclick = changeUrl;
  801. // Add the button to the document body
  802. document.body.appendChild(button);
  803. }
  804.  
  805. // Call the function to create the "Change URL" button
  806. createChangeUrlButton();
  807.  
  808. /////////////////////////////////////////// sort subreddits by new ///////////////////////////////////////////
  809. (function() {
  810. 'use strict';
  811. const re = /https?:\/\/(?:www\.|old\.|new\.)?reddit\.com/i;
  812. for (var i=0, l=document.links.length; i<l; i++) {
  813. if (re.test(document.links[i].href)) {
  814. var path = document.links[i].pathname;
  815. if (path === '/' || path.startsWith('/r/')) {
  816. var pathlen = path.split('/').length - 1 - (path.endsWith('/') ? 1 : 0);
  817. if ((pathlen <= 2) && (document.links[i].closest('.tabmenu') === null)) {
  818. document.links[i].href += path.endsWith('/') ? 'new/' : '/new/';
  819. }
  820. }
  821. }
  822. }
  823. })();