Reddit - Improve Saved Comments

reveals the save and report buttons and makes links right clickable

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

  1. // ==UserScript==
  2. // @name Reddit - Improve Saved Comments
  3. // @namespace https://openuserjs.org/users/zachhardesty7
  4. // @author Zach Hardesty <zachhardesty7@users.noreply.github.com> (https://github.com/zachhardesty7)
  5. // @description reveals the save and report buttons and makes links right clickable
  6. // @copyright 2019, Zach Hardesty (https://zachhardesty.com/)
  7. // @license GPL-3.0-only; http://www.gnu.org/licenses/gpl-3.0.txt
  8. // @version 1.2.2
  9.  
  10. // @homepageURL https://github.com/zachhardesty7/tamper-monkey-scripts-collection/raw/master/reddit-improve-saved-comments.user.js
  11. // @homepageURL https://openuserjs.org/scripts/zachhardesty7/Reddit_-_Improve_Saved_Comments
  12. // @supportURL https://openuserjs.org/scripts/zachhardesty7/Reddit_-_Improve_Saved_Comments/issues
  13.  
  14.  
  15. // @include https://www.reddit.com/user/*/saved/*
  16. // @require https://greasyfork.org/scripts/419640-onelementready/code/onElementReady.js?version=887637
  17. // ==/UserScript==
  18. /* global onElementReady */
  19.  
  20. /**
  21. * sometimes you really need access to react internals to fix somebody
  22. * else's broken app and add no-brainer features
  23. *
  24. * @param {HTMLElement} DOMNode - arbitrary DOM node with a hidden react instance
  25. * @returns {object} react instance object
  26. */
  27. const getReactInstance = (DOMNode) => DOMNode[Object.keys(DOMNode)[0]]
  28.  
  29. /**
  30. * add features to comments
  31. *
  32. * @param {HTMLElement} button - triple dot more button under comments
  33. */
  34. function improveComments(button) {
  35. const moreComponent = getReactInstance(button)
  36. const moreComponentProps = moreComponent.return.return.memoizedProps
  37. const genericButtonClass = button.parentElement.children[0].className
  38.  
  39. const reportButton = document.createElement("button")
  40. reportButton.textContent = "Report"
  41. reportButton.className = genericButtonClass
  42. // navigate react obj
  43. reportButton.addEventListener(
  44. "click",
  45. moreComponentProps.children[0].props.onClick
  46. )
  47.  
  48. // does not dynamically update text content
  49. const saveButton = document.createElement("button")
  50. saveButton.textContent = "Save / Unsave"
  51. saveButton.className = genericButtonClass
  52. saveButton.addEventListener(
  53. "click",
  54. moreComponentProps.children[1].props.onClick
  55. )
  56.  
  57. // not defined in a separate function just because this is a quick
  58. // way to ensure that all of the important parts are loaded
  59. const comment =
  60. button.parentElement.parentElement.parentElement.parentElement.parentElement
  61. .parentElement.parentElement.parentElement
  62.  
  63. // wrap the entirety of the comment in link el
  64. const container = comment.parentElement
  65. const wrapper = document.createElement("a")
  66. // link to comment page hidden in react instance
  67. wrapper.href = getReactInstance(
  68. comment
  69. ).return.memoizedProps.comment.permalink
  70. wrapper.append(comment) // move all original DOM children
  71. wrapper.addEventListener("click", (e) => e.preventDefault()) // allow original click handler to take over
  72.  
  73. container.append(wrapper)
  74.  
  75. button.parentElement.append(reportButton)
  76. button.parentElement.append(saveButton)
  77. button.remove()
  78. }
  79. // gross, but Reddit uses styled-components / emotion and has almost no
  80. // constant selectors that don't change between renders, detail allows react to hydrate first
  81. window.addEventListener(
  82. "load",
  83. () => {
  84. onElementReady(
  85. "div.Comment > div > div > div:last-child > div > div:nth-child(2) > div:nth-child(2) > div:last-child > button:last-child[aria-haspopup][aria-expanded][aria-label]",
  86. { findOnce: false },
  87. improveComments
  88. )
  89. },
  90. false
  91. )