Filter, Highlight & Delete

Highlights, Lowlights, or Deletes page elements based on their text.

当前为 2019-09-12 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Filter, Highlight & Delete
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.1.1
  5. // @description Highlights, Lowlights, or Deletes page elements based on their text.
  6. // @author listfilterErick
  7. // @grant none
  8.  
  9. // @match *://news.google.com/*
  10. // @match *://www.youtube.com/*
  11. // @match *://www.reddit.com/r/*
  12.  
  13. // @require http://code.jquery.com/jquery-1.12.4.min.js
  14. // @require https://greasyfork.org/scripts/5392-waitforkeyelements/code/WaitForKeyElements.js?version=115012
  15.  
  16. // @licence CC-BY-NC-SA-4.0; https://creativecommons.org/licenses/by-nc-sa/4.0/
  17. // @licence GPL-3.0-or-later; http://www.gnu.org/licenses/gpl-3.0.txt
  18. // ==/UserScript==
  19. /*jshint esversion: 6 */
  20.  
  21. /* Last update: 09-02-2019 */
  22.  
  23. /*
  24. Google News: Only works for the front page of google news. Need a more robust selector for other special sections.
  25. Reddit: Only works for compact view.
  26. */
  27.  
  28. /*
  29. Search for these markers for locations where you need to add new selectors for new sites.
  30. markA: select the text block
  31. markB: select the block you want to apply css to
  32. markC: css of each class
  33. */
  34.  
  35. (function () {
  36. 'use strict';
  37.  
  38. let lfShowFilterButton = 0; // set to 1 to show a button to manually run this script.
  39. let lfButtonTransparency = .33; // set to a value between 0 and 1, 1 is no transparency, .5 is 50% transparency.
  40. let lfDynamicChecking = 1; // set to 1 to run the script automatically when new block elements are detected.
  41.  
  42. let lfShowLogMsgs = 0; // set to 1 to show console messages, required to enable the following message rules.
  43. let lfLogMatches = 1; // set to 1 to log to console what was matched.
  44. let lfLogRuntime = 1; // set to 1 to log to console how long this takes to run.
  45.  
  46. function consolelog(text) {
  47. if (lfShowLogMsgs) {
  48. console.log(text);
  49. }
  50. }
  51. consolelog(" #### list filter script start. ####");
  52.  
  53. if (lfShowLogMsgs && lfLogRuntime) {
  54. var lfStartTime = performance.now();
  55. }
  56.  
  57. // ==== filter lists ==========================================================================|
  58.  
  59. if (1) {
  60. //strong highlight
  61. var highlight1 = [
  62. /apple/i,
  63. ];
  64. //weak highlight
  65. var highlight2 = [
  66. /gamestop/i,
  67. ];
  68. //weak lowlight
  69. var lowlight1 = [
  70. /goodbye/i,
  71. ];
  72. //strong lowlight
  73. var lowlight2 = [
  74. /\btv\b/i,
  75. ];
  76. //delete block
  77. var delete1 = [
  78. /throne|dany|\bgot\b/i,
  79. ];
  80. }
  81.  
  82. let domainName = window.location.hostname;
  83. let hrefString = window.location.href; //href lets you be more specific
  84.  
  85. // ==== function definitions ==================================================================|
  86.  
  87. // checks string against given list of regular expressions.
  88. function checkReg(string, regList) {
  89. for (let i = 0; i < regList.length; i++) {
  90. if (regList[i].test(string)) {
  91. return true;
  92. }
  93. }
  94. return false;
  95. }
  96.  
  97. let elementCounter = 0;
  98.  
  99. // check attributes of a block to choose what class to add to it.
  100. function checkBlock(index, element) {
  101.  
  102. let searchText;
  103.  
  104. // ==== markA start =======================================================================|
  105. if (/news\.google\.com/gi.test(domainName)) {
  106. searchText = jQuery(this).find("div>article>h3").eq(0).text().trim();
  107. } else if (/www\.youtube\.com/gi.test(domainName)) {
  108. searchText = jQuery(this).find("span#video-title").text().trim();
  109. } else if (/www\.reddit\.com/gi.test(domainName)) {
  110. searchText = jQuery(this).find("span>a>h2").text().trim();
  111. }
  112. // ==== markA end =========================================================================|
  113.  
  114. // class list identifies what was checked in past iterations
  115. let classList = "";
  116. if (jQuery(this).attr("class")) {
  117. classList = jQuery(this).attr("class");
  118. //consolelog(classList);
  119. }
  120.  
  121. if (searchText && (!classList || !/\blf-/.test(classList))) {
  122. //if ( searchText ) {
  123. elementCounter++;
  124. var matchCode = "n1";
  125.  
  126. // delete and lowlight lists are checked before highlight lists
  127. if (checkReg(searchText, delete1)) {
  128. matchCode = "d1";
  129. jQuery(this).remove();
  130. } else if (checkReg(searchText, lowlight2)) {
  131. matchCode = "l2";
  132. jQuery(this).addClass("lf-lowlight2");
  133. } else if (checkReg(searchText, lowlight1)) {
  134. matchCode = "l1";
  135. jQuery(this).addClass("lf-lowlight1");
  136. } else if (checkReg(searchText, highlight1)) {
  137. matchCode = "h1";
  138. jQuery(this).addClass("lf-highlight1");
  139. } else if (checkReg(searchText, highlight2)) {
  140. matchCode = "h2";
  141. jQuery(this).addClass("lf-highlight2");
  142. } else {
  143. jQuery(this).addClass("lf-checked");
  144. }
  145.  
  146. //if (1) {
  147. if (lfShowLogMsgs && lfLogMatches && /d|l/.test(matchCode)) {
  148. let printMsg = elementCounter;
  149. printMsg += " "+ matchCode;
  150. printMsg += ": "+ searchText;
  151. consolelog(printMsg);
  152. }
  153. //console.log(elementCounter +" "+ matchCode +": "+ searchText +"("+ vidLength +")");
  154. }
  155.  
  156. } // end function checkBlock()
  157.  
  158. let blockSelector = "article";
  159. // ==== markB start ===========================================================================|
  160. if (/news\.google\.com/gi.test(domainName)) {
  161. blockSelector = "main>c-wiz>div>div";
  162. } else if (/www\.youtube\.com/gi.test(domainName)) {
  163. blockSelector = "ytd-compact-video-renderer";
  164. } else if (/www\.reddit\.com/gi.test(domainName)) {
  165. blockSelector = ".scrollerItem>div>div:nth-child(2)";
  166. }
  167. // ==== markB end =============================================================================|
  168. checkBlocks();
  169.  
  170. function checkBlocks() {
  171. jQuery(blockSelector).each(checkBlock);
  172. consolelog("end checkBlocks().");
  173. }
  174.  
  175. jQuery("#lf-reset").click(function () {
  176. consolelog("highlight/lowlight reset began.");
  177. elementCounter = 0;
  178. checkBlocks();
  179. consolelog("highlight/lowlight reset finished.");
  180. });
  181.  
  182. if (lfDynamicChecking) {
  183. waitForKeyElements(blockSelector, checkBlocks);
  184. } else {
  185. checkBlocks();
  186. }
  187.  
  188. // ==== optional button code ==================================================================|
  189. if (lfShowFilterButton) {
  190. if (!jQuery("#wt-buttons").length) {
  191. consolelog("(LF) created #wt-buttons.");
  192. jQuery("body").prepend('<div id="wt-buttons"><div id="lf-reset">H/L</div><div id="wt-close">&times;</div></div>');
  193. jQuery("#wt-close").click(function () { jQuery("#wt-buttons").remove(); });
  194.  
  195. const webToolsCss =
  196. `<style type="text/css">
  197. #wt-buttons {
  198. width: 40px;
  199. display: block !important;
  200. position: fixed;
  201. top: 0px;
  202. right: 0px;
  203. z-index: 9000;
  204. opacity: `+ lfButtonTransparency + `;
  205. }
  206. #wt-buttons:hover {
  207. opacity: 1;
  208. }
  209. #wt-buttons div {
  210. display: block !important;
  211. padding: 5px;
  212. border-radius: 5px;
  213. margin-top: 2px;
  214. font-size: initial !important;
  215. font-weight: bold;
  216. color: white;
  217. cursor: pointer;
  218. }
  219. #wt-close {
  220. background: #777777;
  221. text-align: center;
  222. }
  223. </style>`;
  224. jQuery(document.body).append(webToolsCss);
  225. } else {
  226. jQuery("#wt-buttons").prepend('<div id="lf-reset">H/L</div>');
  227. }
  228. const listFilterCss =
  229. `<style>
  230. #lf-reset {
  231. background: #177e14;
  232. }
  233. </style>`;
  234. jQuery(document.body).append(listFilterCss);
  235. }
  236.  
  237. // ==== markC start ===========================================================================|
  238. // May want to define custom rules per site.
  239. if (/news\.google\.com/gi.test(domainName)) {
  240. var blockElement = "main>c-wiz>div>div";
  241. } else if (/www\.youtube\.com/gi.test(domainName)) {
  242. var blockElement = "ytd-compact-video-renderer";
  243. } else if (/www\.reddit\.com/gi.test(domainName)) {
  244. var blockElement = ".scrollerItem>div>div:nth-child(2)";
  245. }
  246. // ==== markC end =============================================================================|
  247. var filterCss =
  248. `<style>
  249. `+ blockElement +`.lf-highlight1 {
  250. background: #baffc9;/*green*/
  251. }
  252. `+ blockElement +`.lf-highlight2 {
  253. background: #ffffba;/*yellow*/
  254. }
  255. `+ blockElement +`.lf-lowlight1 {
  256. background: #ffdfba;/*orange*/
  257. opacity: .3;
  258. }
  259. `+ blockElement +`.lf-lowlight2 {
  260. background: #ffccca;/*red*/
  261. opacity: .5;
  262. }
  263. </style>`;
  264. jQuery(document.body).append(filterCss);
  265.  
  266. if (lfShowLogMsgs && lfLogRuntime) {
  267. let lfEndTime = performance.now();
  268. consolelog('(LF) finished after ' + ((lfEndTime - lfStartTime) / 1000).toFixed(2) + ' seconds.');
  269. }
  270.  
  271. consolelog("#### list filter script finished. ####");
  272. })();