buttons.js 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import { isMobile, isShorts } from "./state";
  2. import { isInViewport } from "./utils";
  3. function getButtons() {
  4. //--- If Watching Youtube Shorts: ---//
  5. if (isShorts()) {
  6. let elements = document.querySelectorAll(
  7. isMobile()
  8. ? "ytm-like-button-renderer"
  9. : "#like-button > ytd-like-button-renderer"
  10. );
  11. for (let element of elements) {
  12. //Youtube Shorts can have multiple like/dislike buttons when scrolling through videos
  13. //However, only one of them should be visible (no matter how you zoom)
  14. if (isInViewport(element)) {
  15. return element;
  16. }
  17. }
  18. }
  19. //--- If Watching On Mobile: ---//
  20. if (isMobile()) {
  21. return document.querySelector(".slim-video-action-bar-actions");
  22. }
  23. //--- If Menu Element Is Displayed: ---//
  24. if (document.getElementById("menu-container")?.offsetParent === null) {
  25. return document.querySelector("ytd-menu-renderer.ytd-watch-metadata > div");
  26. //--- If Menu Element Isn't Displayed: ---//
  27. } else {
  28. return document
  29. .getElementById("menu-container")
  30. ?.querySelector("#top-level-buttons-computed");
  31. }
  32. }
  33. function getLikeButton() {
  34. return getButtons().children[0].tagName ===
  35. "YTD-SEGMENTED-LIKE-DISLIKE-BUTTON-RENDERER"
  36. ? getButtons().children[0].children[0]
  37. : getButtons().children[0];
  38. }
  39. function getLikeTextContainer() {
  40. return (
  41. getLikeButton().querySelector("#text") ??
  42. getLikeButton().getElementsByTagName("yt-formatted-string")[0] ??
  43. getLikeButton().querySelector("span[role='text']")
  44. );
  45. }
  46. function getDislikeButton() {
  47. return getButtons().children[0].tagName ===
  48. "YTD-SEGMENTED-LIKE-DISLIKE-BUTTON-RENDERER"
  49. ? getButtons().children[0].children[1]
  50. : getButtons().children[1];
  51. }
  52. function createDislikeTextContainer() {
  53. const textNodeClone = getLikeButton().querySelector("button > div[class*='cbox']").cloneNode(true);
  54. textNodeClone.setAttribute("style", "margin-left: 1rem;");
  55. const insertPreChild = getDislikeButton().querySelector("yt-touch-feedback-shape");
  56. getDislikeButton().querySelector("button").insertBefore(textNodeClone, insertPreChild);
  57. getDislikeButton().querySelector("button").classList.remove("yt-spec-button-shape-next--icon-button");
  58. getDislikeButton().querySelector("button").classList.add("yt-spec-button-shape-next--icon-leading");
  59. textNodeClone.querySelector("span[role='text']").innerText = "";
  60. return textNodeClone.querySelector("span[role='text']");
  61. }
  62. function getDislikeTextContainer() {
  63. let result =
  64. getDislikeButton().querySelector("#text") ??
  65. getDislikeButton().getElementsByTagName("yt-formatted-string")[0] ??
  66. getDislikeButton().querySelector("span[role='text']");
  67. if (result == null) {
  68. result = createDislikeTextContainer();
  69. }
  70. return result;
  71. }
  72. function checkForSignInButton() {
  73. if (
  74. document.querySelector(
  75. "a[href^='https://accounts.google.com/ServiceLogin']"
  76. )
  77. ) {
  78. return true;
  79. } else {
  80. return false;
  81. }
  82. }
  83. export {
  84. getButtons,
  85. getLikeButton,
  86. getDislikeButton,
  87. getLikeTextContainer,
  88. getDislikeTextContainer,
  89. checkForSignInButton,
  90. };