Notion Copy Properties

Copy Notion Database item property values by clicking Shift + LeftMouseButton on it

目前為 2021-10-14 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Notion Copy Properties
  3. // @namespace https://www.notion.so/
  4. // @version 0.7
  5. // @description Copy Notion Database item property values by clicking Shift + LeftMouseButton on it
  6. // @author Maxim Kurbatov
  7. // @match https://www.notion.so/*
  8. // @grant GM_addStyle
  9. // @run-at document-end
  10. // ==/UserScript==
  11.  
  12. var debug = false;
  13. GM_addStyle(`#notion-app .notion-frame > div.notion-scroller.vertical.horizontal > div:nth-child(2) > div:nth-child(1) > div:nth-child(2) > div > div:nth-child(1) > div > div:nth-child(1) > div > div:nth-child(2) > div:hover,
  14. #notion-app div.notion-default-overlay-container div.notion-scroller.vertical > div:nth-child(2) > div:nth-child(3) > div:nth-child(2) > div > div:nth-child(1) > div > div:nth-child(1) > div > div:nth-child(2) > div:hover
  15. { font-style: italic; }`);
  16.  
  17. // create an observer instance
  18. var observer = new MutationObserver(function(mutations) {
  19. mutations.forEach(function(mutation) {
  20. var target = false;
  21. if ( mutation.target.nodeName == "DIV" ) target = mutation.target;
  22. else target = mutation.target.parentElement;
  23. if ( target.getAttribute("contentEditable") == "true" ) target = target.parentElement;
  24. if ( ! target ) return;
  25. addCopyHandler(target);
  26. });
  27. });
  28. var config = { characterData: true, attributes: false, childList: true, subtree: true };
  29. var mutgt = document.body;
  30. observer.observe(mutgt, config);
  31. var lastBlock = false;
  32.  
  33. function addCopyHandler(elm) {
  34. elm = elm || document;
  35. //if ( typeof elm.querySelectorAll !== 'function' ) return;
  36. //var blocks = elm.querySelectorAll("#notion-app .notion-focusable");
  37. const blocks = document.querySelectorAll(`#notion-app .notion-frame > div.notion-scroller.vertical.horizontal > div:nth-child(2) > div:nth-child(1) > div:nth-child(2) > div > div:nth-child(1) > div > div:nth-child(1) > div > div:nth-child(2) > div,
  38. #notion-app div.notion-default-overlay-container div.notion-scroller.vertical > div:nth-child(2) > div:nth-child(3) > div:nth-child(2) > div > div:nth-child(1) > div > div:nth-child(1) > div > div:nth-child(2) > div`);
  39. blocks.forEach(function(block) {
  40. block.addEventListener('click', onClick);
  41. });
  42. }
  43.  
  44. function onClick(e) {
  45. const elem = e.currentTarget;
  46. console.log("Copying text: " + elem.innerText);
  47. if (e.shiftKey) {
  48. copyTextToClipboard(elem.innerText);
  49. const color = elem.style.color;
  50. elem.style.color = "red";
  51. setTimeout(function() { elem.style.color = color; }, 300);
  52. }
  53. }
  54.  
  55. function fallbackCopyTextToClipboard(text) {
  56. var textArea = document.createElement("textarea");
  57. textArea.value = text;
  58.  
  59. // Avoid scrolling to bottom
  60. textArea.style.top = "0";
  61. textArea.style.left = "0";
  62. textArea.style.position = "fixed";
  63.  
  64. document.body.appendChild(textArea);
  65. textArea.focus();
  66. textArea.select();
  67.  
  68. try {
  69. var successful = document.execCommand('copy');
  70. var msg = successful ? 'successful' : 'unsuccessful';
  71. console.log('Fallback: Copying text command was ' + msg);
  72. } catch (err) {
  73. console.error('Fallback: Oops, unable to copy', err);
  74. }
  75.  
  76. document.body.removeChild(textArea);
  77. }
  78. function copyTextToClipboard(text) {
  79. if (!navigator.clipboard) {
  80. fallbackCopyTextToClipboard(text);
  81. return;
  82. }
  83. navigator.clipboard.writeText(text).then(function() {
  84. console.log('Async: Copying to clipboard was successful!');
  85. }, function(err) {
  86. console.error('Async: Could not copy text: ', err);
  87. });
  88. }