Stack Overflow reformat for Evernote

Format contents on Stack Enchange websites such as stackoverflow.com and askubuntu.com for easy saving to Evernote.

  1. // ==UserScript==
  2. // @name Stack Overflow reformat for Evernote
  3. // @namespace https://gf.qytechs.cn/zh-TW/scripts/388100
  4. // @version 1.0
  5. // @description Format contents on Stack Enchange websites such as stackoverflow.com and askubuntu.com for easy saving to Evernote.
  6. // @author twchen
  7. // @include https://stackoverflow.com/questions/*
  8. // @include https://*.stackexchange.com/questions/*
  9. // @include https://superuser.com/questions/*
  10. // @include https://serverfault.com/questions/*
  11. // @include https://askubuntu.com/questions/*
  12. // @run-at document-idle
  13. // ==/UserScript==
  14.  
  15. (function () {
  16. "use strict";
  17. const description = document.querySelector("#question .post-layout");
  18. const body = document.body;
  19. let saveDesc = true;
  20. const answersToSave = [];
  21.  
  22. function addLinks() {
  23. const answers = document.querySelectorAll(".answer > .post-layout");
  24. answers.forEach(ans => {
  25. const text = ans.querySelector(".answercell .post-text");
  26. const menu = ans.querySelector(".post-menu");
  27. const saveAnsLink = document.createElement("a");
  28. saveAnsLink.href = "#";
  29. saveAnsLink.text = 'save this answer';
  30. saveAnsLink.onclick = event => {
  31. event.preventDefault();
  32. answersToSave.push(ans);
  33. saveDesc = false;
  34. save();
  35. };
  36. const saveQALink = document.createElement('a');
  37. saveQALink.href = '#';
  38. saveQALink.text = 'save this Q&A';
  39. saveQALink.onclick = event => {
  40. event.preventDefault();
  41. answersToSave.push(ans);
  42. save();
  43. };
  44. menu.append(saveAnsLink, saveQALink);
  45. });
  46.  
  47. const div = document.createElement('div');
  48. div.classList.add('pl8', 'aside-cta', 'grid--cell');
  49. const chooseLink = document.createElement('a');
  50. chooseLink.href = "#";
  51. chooseLink.classList.add("d-inline-flex", "ai-center", "ws-nowrap", "s-btn", "s-btn__primary");
  52. chooseLink.text = "Save Multiple Answers";
  53. chooseLink.onclick = event => {
  54. event.preventDefault();
  55. startChoosing();
  56. };
  57. div.appendChild(chooseLink);
  58. const header = document.querySelector('#question-header');
  59. header.append(div);
  60. }
  61.  
  62. function startChoosing() {
  63. const votingContainers = document.querySelectorAll('.js-voting-container');
  64. votingContainers.forEach((container, i) => {
  65. const checkbox = document.createElement('input');
  66. checkbox.type = 'checkbox';
  67. checkbox.id = `checkbox${i}`;
  68. checkbox.style.margin = 'auto';
  69. const label = document.createElement('label');
  70. label.htmlFor = `checkbox${i}`;
  71. label.innerText = 'Keep';
  72. label.style.margin = 'auto';
  73. container.prepend(checkbox, label);
  74. });
  75.  
  76. const doneButton = document.createElement('button');
  77. doneButton.innerText = "Done";
  78. Object.assign(doneButton.style, {
  79. position: 'fixed',
  80. right: '2rem',
  81. top: '50%',
  82. zIndex: '100'
  83. });
  84. doneButton.onclick = event => {
  85. event.preventDefault();
  86. doneChoosing();
  87. };
  88. body.appendChild(doneButton);
  89. }
  90.  
  91. function doneChoosing() {
  92. const question = document.querySelector('#question');
  93. const questionCheckbox = question.querySelector('.js-voting-container input[type="checkbox"]');
  94. saveDesc = questionCheckbox.checked;
  95. const answers = document.querySelectorAll(".answer > .post-layout");
  96. answers.forEach(ans => {
  97. const text = ans.querySelector(".answercell .post-text");
  98. const checkbox = ans.querySelector(".js-voting-container input[type='checkbox']");
  99. if (checkbox.checked) {
  100. answersToSave.push(ans);
  101. }
  102. });
  103. if (answersToSave.length == 0) {
  104. alert('Choose at least one answer to save!');
  105. } else {
  106. save();
  107. }
  108.  
  109. }
  110.  
  111. function save() {
  112. expandComments();
  113. removeAllChildren(body);
  114. const div = document.createElement("div");
  115. div.style.margin = 'auto';
  116. const posts = saveDesc ? [description, ...answersToSave] : answersToSave;
  117. posts.forEach((post, i) => {
  118. if(i > 0 || (!saveDesc && answersToSave.length > 1)){
  119. const hr = document.createElement("hr");
  120. hr.style.height = '3px';
  121. hr.style.marginTop = '4rem';
  122. div.appendChild(hr);
  123. }
  124. console.log(post);
  125. const checkbox = post.querySelector('input[id^=checkbox]');
  126. if (checkbox) {
  127. checkbox.remove();
  128. }
  129. const checkboxLabel = post.querySelector('label[for^=checkbox]');
  130. if (checkboxLabel) {
  131. checkboxLabel.remove();
  132. }
  133. div.appendChild(post);
  134. });
  135. body.appendChild(div);
  136. }
  137.  
  138. function expandComments() {
  139. const expandLinks = document.getElementsByClassName('js-show-link comments-link');
  140. for (let i = 0; i < expandLinks.length; i++) {
  141. expandLinks[i].click();
  142. }
  143. }
  144.  
  145. function removeAllChildren(el) {
  146. while (el.firstChild) {
  147. el.removeChild(el.firstChild);
  148. }
  149. }
  150.  
  151. addLinks();
  152. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址