XKCD -- Easy Random

Quicker and more reliable "random comic" button

  1. // ==UserScript==
  2. // @name XKCD -- Easy Random
  3. // @description Quicker and more reliable "random comic" button
  4. // @license MIT
  5. // @version 1
  6. // @namespace https://keybase.io/jpaugh
  7. // @support Chat with me on Keybase
  8. // @author Jonathan Paugh
  9. // @grant none
  10. // @match https://xkcd.com/*
  11. // @compatible firefox
  12. // @compatible chrome
  13. // @compatible IE11 --- not that it helps
  14. // ==/UserScript==
  15.  
  16. var MAGICAL_BG_COLOR = "orangered"
  17. var XKCDS_WHEN_CHECKED = 2134
  18. var XKCD_CHECK_DATE = new Date(2019, 4, 9)
  19. var COMICS_PER_WEEK = 3
  20.  
  21. function guestimateCurrentCount() {
  22. var now = new Date()
  23. var MILLI_PER_WEEK = 7 * 24 * 60 * 60 * 1000
  24. var weeksSinceChecked = (now.getTime() - XKCD_CHECK_DATE.getTime()) / MILLI_PER_WEEK
  25. return XKCDS_WHEN_CHECKED + Math.floor(weeksSinceChecked * COMICS_PER_WEEK) // Works for past and future dates! :-D
  26. }
  27.  
  28. function getRandomComicInclusive(min, max) {
  29. min = Math.ceil(min) // Why did you give me a fractional min? You sneaky caller!
  30. max = Math.floor(max)
  31. return Math.floor(Math.random() * (max - min + 1)) + min
  32. }
  33.  
  34. var min = 1
  35. var max = guestimateCurrentCount()
  36. // TODO: Add a fudge factor (+20) to the max, and then pre-load the new comic to ensure it exists.
  37. // Maybe I should load it via AJAX and overwrite the current page? IDK
  38.  
  39. var randLinks = document.querySelectorAll("a[href^='//c.xkcd.com/random/comic']")
  40. Array.prototype.forEach.call(randLinks, function (el) {
  41. el.style.backgroundColor = MAGICAL_BG_COLOR
  42. el.addEventListener("click", function (event) {
  43. (event.preventDefault)
  44. ? event.preventDefault()
  45. : (event.returnValue = false)
  46. window.location.href = "https://xkcd.com/" + getRandomComicInclusive(min, max)
  47. })
  48. });