Show Amazon Questions button + Show Amazon Questions context menu

Creates a "Show questions" button next to the "answered questions" text, if any. Once pressed it opens a new tab of the questions.

目前為 2023-12-05 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Show Amazon Questions button + Show Amazon Questions context menu
  3. // @author u/iNeedAProperAccount
  4. // @description Creates a "Show questions" button next to the "answered questions" text, if any. Once pressed it opens a new tab of the questions.
  5. // It also creates a "Open questions tab" context menu entry.
  6. // Thanks to u/CaptSkinny, u/lilgeeky, u/Sanpete_in_Utah and u/TTum.
  7. // How it looks like:
  8. // https://i.imgur.com/XJYWiQ4.png
  9. // https://i.imgur.com/2Xm9NC5.png
  10. // Original thread at: https://old.reddit.com/r/AmazonVine/comments/14aynxt/are_product_question_and_answer_sections_gone/
  11. // @version 0.2
  12. // @license MIT License
  13. // @match *://*.amazon.com/*
  14. // @match *://*.amazon.ca/*
  15. // @match *://*.amazon.com.mx/*
  16. // @match *://*.amazon.co.uk/*
  17. // @match *://*.amazon.fr/*
  18. // @match *://*.amazon.de/*
  19. // @match *://*.amazon.es/*
  20. // @match *://*.amazon.it/*
  21. // @match *://*.amazon.nl/*
  22. // @match *://*.amazon.be/*
  23. // @match *://*.amazon.lu/*
  24. // @match *://*.amazon.se/*
  25. // @match *://*.amazon.pl/*
  26. // @match *://*.amazon.com.tr/*
  27. // @match *://*.amazon.ae/*
  28. // @match *://*.amazon.sa/*
  29. // @match *://*.amazon.co.jp/*
  30. // @match *://*.amazon.in/*
  31. // @match *://*.amazon.sg/*
  32. // @match *://*.amazon.com.au/*
  33. // @match *://*.amazon.com.br/*
  34. // @icon https://www.google.com/s2/favicons?sz=64&domain=amazon.ca
  35. // @grant GM_registerMenuCommand
  36. // @namespace https://greasyfork.org/users/877912
  37. // ==/UserScript==
  38.  
  39. GM_registerMenuCommand("Open Questions tab", contextOpenQuestionsTab, "q");
  40.  
  41. const ASK_LINK_ID = "askATFLink";
  42. const REGEX_PATTERN = "^(http[s]?://[^/]+)/(?:.+?/)?(?:dp|gp/product|asin)/(?:.+?/)?([a-zA-Z0-9]{10})(?:[/?]|$)";
  43.  
  44. function getQuestionsUrl() {
  45. const url = document.URL;
  46. const regex = new RegExp(REGEX_PATTERN, "i");
  47. const matches = url.match(regex);
  48.  
  49. if (matches) {
  50. const scheme_and_host = matches[1];
  51. const asin = matches[2];
  52. if (scheme_and_host && asin) {
  53. return `${scheme_and_host}/ask/questions/asin/${asin}`;
  54. }
  55. }
  56. }
  57.  
  58. function contextOpenQuestionsTab() {
  59. const questions_url = getQuestionsUrl();
  60. if (questions_url) {
  61. window.open(questions_url, '_blank');
  62. }
  63. };
  64.  
  65. function openQuestionsTab() {
  66. const questions_url = getQuestionsUrl();
  67.  
  68. if (questions_url) {
  69. const askATFLink = document.getElementById(ASK_LINK_ID);
  70. if (askATFLink) {
  71. const button = document.createElement("button");
  72. button.innerHTML = "Show Questions";
  73. button.addEventListener("click", function () {
  74. window.open(questions_url, '_blank');
  75. });
  76.  
  77. askATFLink.parentNode.insertBefore(button, askATFLink.nextSibling);
  78. }
  79. }
  80. }
  81.  
  82. const observer = new MutationObserver(function (mutations) {
  83. mutations.forEach(function (mutation) {
  84. if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
  85. for (let i = 0; i < mutation.addedNodes.length; i++) {
  86. const addedNode = mutation.addedNodes[i];
  87. if (addedNode.id === ASK_LINK_ID) {
  88. openQuestionsTab();
  89. break;
  90. }
  91. }
  92. }
  93. });
  94. });
  95.  
  96. const observerConfig = {
  97. childList: true,
  98. subtree: true
  99. };
  100.  
  101. observer.observe(document.body, observerConfig);
  102.  
  103. openQuestionsTab();