Pocket-goto-Original

Opens the original link instead of the pocket View! (please use Ctrl+click)

  1. // ==UserScript==
  2. // @name Pocket-goto-Original
  3. // @namespace garyli.rocks
  4. // @description Opens the original link instead of the pocket View! (please use Ctrl+click)
  5. // @include http://getpocket.com/my-list*
  6. // @include https://getpocket.com/my-list*
  7. // @version 2.0
  8. // ==/UserScript==
  9.  
  10. (function (window) {
  11. 'use strict';
  12.  
  13. // add a new class for original link
  14. const customStyle = document.createElement('style');
  15. customStyle.innerText = `
  16. a.__original_link {
  17. text-decoration: none;
  18. }
  19.  
  20. a.__original_link:hover {
  21. text-decoration: none !important;
  22. }
  23.  
  24. a.__original_link h2::before {
  25. margin-right: .2em;
  26. padding: .2em;
  27. padding-left: 0;
  28. content: '○';
  29. position: relative;
  30. top: -1px;
  31. }
  32.  
  33. a.__original_link:hover h2::before {
  34. content: '●';
  35. }
  36. `;
  37. document.querySelector('head').appendChild(customStyle);
  38.  
  39. function addOriginalLinks() {
  40. console.log('Add original links');
  41.  
  42. const allItems = window.__NEXT_REDUX_WRAPPER_STORE__.getState()
  43. .myListItemsById;
  44.  
  45. // wrap title in an <a> element with original url
  46. document
  47. .querySelectorAll('article[data-cy^=article-card-]')
  48. .forEach(function (e) {
  49. if (e.dataset['original_link_added']) {
  50. return;
  51. }
  52.  
  53. const itemId = e.dataset['cy'].replace(/article-card-(\d+)/, '$1');
  54.  
  55. if (allItems[itemId]) {
  56. const originalUrl = allItems[itemId]['save_url'];
  57. const originalLink = document.createElement('a');
  58. originalLink.href = originalUrl;
  59. originalLink.classList.add('__original_link');
  60. originalLink.append(e.querySelector('h2'));
  61. e.querySelector('.content').prepend(originalLink);
  62. }
  63.  
  64. e.dataset['original_link_added'] = 'true';
  65. });
  66. }
  67.  
  68. let prevList;
  69.  
  70. const getListNode = () => {
  71. return document.querySelector('.main header + div');
  72. };
  73.  
  74. const config = { subtree: true, childList: true };
  75.  
  76. // Callback function to execute when mutations are observed
  77. const callback = function (mutationsList, observer) {
  78. for (const mutation of mutationsList) {
  79. addOriginalLinks();
  80. }
  81. };
  82.  
  83. // Create an observer instance linked to the callback function
  84. const observer = new MutationObserver(callback);
  85.  
  86. const checkList = setInterval(function () {
  87. const newList = getListNode();
  88. if (newList !== prevList) {
  89. if (observer) {
  90. observer.disconnect();
  91. }
  92.  
  93. if (newList) {
  94. console.log('A new list loaded');
  95. prevList = newList;
  96. addOriginalLinks();
  97.  
  98. // Start observing the target node for configured mutations
  99. observer.observe(prevList, config);
  100. } else {
  101. console.log('waiting');
  102. }
  103. }
  104. }, 1000);
  105. })(window.unsafeWindow);
  106.