高亮关键词

高亮特定网页中感兴趣的关键词

当前为 2017-08-06 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name highlight-my-interest
  3. // @name:zh-CN 高亮关键词
  4. // @description highlight keywords in my favorites
  5. // @description:zh-CN 高亮特定网页中感兴趣的关键词
  6. // @version 0.2.2
  7. // @author jferroal
  8. // @license GPL-3.0
  9. // @grant GM_xmlhttpRequest
  10. // @require https://greasyfork.org/scripts/31793-jmul/code/JMUL.js?version=209567
  11. // @include http://*
  12. // @include https://*
  13. // @run-at document-end
  14. // @namespace https://greasyfork.org/users/34556-jferroal
  15. // ==/UserScript==
  16.  
  17. (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  18. let JMUL = window.JMUL || {};
  19.  
  20. const Map = (list, fn) => {
  21. let result = [];
  22. if (list && list.length) {
  23. for (let i = 0; i < list.length; i += 1) {
  24. result.push(fn(list[ i ]));
  25. }
  26. }
  27. return result;
  28. };
  29.  
  30. class TextElement {
  31. constructor (element) {
  32. this.element = new JMUL.Element(element);
  33. this.innerText = this.element.innerText;
  34. this.shouldHighlight = false;
  35. }
  36.  
  37. detect () {
  38. for (const keyword of TextElement.keywords) {
  39. const keywordPattern = new RegExp(keyword, 'gi');
  40. if (keywordPattern.test(this.innerText)) {
  41. this.shouldHighlight = true;
  42. break;
  43. }
  44. }
  45. return this;
  46. }
  47.  
  48. highlight () {
  49. if (this.shouldHighlight) {
  50. this.element.setCss(TextElement.highlightStyle);
  51. }
  52. }
  53.  
  54. static init (setting) {
  55. TextElement.highlightStyle = {
  56. background: setting.highlightBgColor,
  57. color: setting.highlightTxtColor,
  58. };
  59. }
  60.  
  61. static setKeywords (keywords) {
  62. TextElement.keywords = keywords;
  63. }
  64.  
  65. static findAll () {
  66. return TextElement.targetTagNames.reduce((res, tagName) => {
  67. const tags = document.getElementsByTagName(tagName);
  68. return res.concat(Map(tags, (e) => new TextElement(e)));
  69. }, []);
  70. }
  71. }
  72.  
  73. TextElement.targetTagNames = [ 'h1', 'h2', 'h3', 'h4', 'h5', 'p', 'a', 'pre', 'blockquote', 'summary' ];
  74. module.exports = TextElement;
  75.  
  76. },{}],2:[function(require,module,exports){
  77. const KeywordService = require('./keyword.service');
  78. const SettingService = require('./setting.service');
  79. const TextElement = require('./element');
  80.  
  81. const Config = {};
  82.  
  83. (function () {
  84. let highlightedCount = 0;
  85. // const href = window.location.href;
  86. const href = 'https://sspai.com';
  87. loadSetting().then((setting) => {
  88. KeywordService.init(setting, href);
  89. TextElement.init(setting);
  90. highlight()
  91. });
  92. window.addEventListener('scroll', highlight);
  93.  
  94. function loadSetting () {
  95. SettingService.init(Config);
  96. return SettingService.load();
  97. }
  98.  
  99. function highlight () {
  100. const elements = TextElement.findAll();
  101. if (elements.length === highlightedCount) return;
  102. KeywordService.list().then((keywords) => {
  103. TextElement.setKeywords(keywords);
  104. elements.map((e) => e.detect().highlight());
  105. highlightedCount = elements.length;
  106. });
  107. }
  108. })();
  109.  
  110. },{"./element":1,"./keyword.service":3,"./setting.service":5}],3:[function(require,module,exports){
  111. class KeywordService {
  112. static init (setting, href) {
  113. KeywordService.Setting = setting;
  114. KeywordService.keywords = [];
  115. const sites = Object.keys(KeywordService.Setting.keywords);
  116. if (!sites || !sites.length) return;
  117. sites.forEach((site) => {
  118. const sitePattern = new RegExp(site, 'gi');
  119. if (sitePattern.test(href)) {
  120. KeywordService.keywords.push(...KeywordService.Setting.keywords[ site ]);
  121. }
  122. });
  123. }
  124.  
  125. static list () {
  126. return Promise.resolve(KeywordService.keywords);
  127. }
  128. }
  129.  
  130. module.exports = KeywordService;
  131.  
  132. },{}],4:[function(require,module,exports){
  133. class Setting {
  134. constructor (jsonBody) {
  135. Object.assign(this, jsonBody);
  136. }
  137. }
  138.  
  139. module.exports = { Setting };
  140.  
  141. },{}],5:[function(require,module,exports){
  142. const Setting = require('./setting').Setting;
  143. const { Request } = window.JMUL || { JMUL: {} };
  144.  
  145. const DefaultKeywords = [
  146. '书籍',
  147. '效率',
  148. 'google.*?',
  149. 'nexus.*?',
  150. '爬虫',
  151. 'python.*?',
  152. 'angular.*?',
  153. 'node',
  154. 'javascript',
  155. 'ukulele',
  156. /gtd.*?/gi,
  157. '工作流',
  158. '日程',
  159. '英雄联盟',
  160. 'vps',
  161. '服务器',
  162. '书单',
  163. '免费',
  164. '限免',
  165. '数据分析',
  166. '自由职业',
  167. 'lol',
  168. 'react',
  169. 'mobx',
  170. ];
  171.  
  172. const DefaultResponseHandler = (_response) => {
  173. let response = _response;
  174. if (typeof _response === 'object' && _response.responseText) {
  175. response = _response.responseText;
  176. }
  177. return new Setting(JSON.parse(response));
  178. };
  179.  
  180. class SettingService {
  181. static init (config) {
  182. SettingService.loadUrl = config.loadUrl;
  183. SettingService.method = config.method || 'GET';
  184. SettingService.contentType = config.contentType || 'application/json';
  185. SettingService.data = config.data || {};
  186. SettingService.resHandler = config.resHandler || DefaultResponseHandler;
  187. }
  188.  
  189. static load () {
  190. if (!SettingService.loadUrl) return Promise.resolve(SettingService.DefaultSetting);
  191. const request = new Request({ headers: { 'content-type': SettingService.contentType } });
  192. request.setUrl(SettingService.loadUrl);
  193. request.setMethod(SettingService.method);
  194. request.setData(SettingService.data);
  195. return request.send().then((response) => {
  196. return SettingService.resHandler(response.responseText);
  197. });
  198. }
  199. }
  200.  
  201. SettingService.DefaultSetting = {
  202. highlightBgColor: '#FFDA5E',
  203. highlightTxtColor: 'black',
  204. keywords: {
  205. 'https://sspai.com/*': DefaultKeywords,
  206. 'https://toutiao.io/*': DefaultKeywords,
  207. 'http://www.inoreader.com/*': DefaultKeywords,
  208. },
  209. };
  210.  
  211. module.exports = SettingService;
  212.  
  213. },{"./setting":4}]},{},[2]);