Passmark CPU/GPU Filter

Passmark CPU/GPU Filter by Brand, Model or Inputed Text. @ cpubenchmark, videocardbenchmark.

当前为 2022-02-18 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @namespace ATGT
  3. // @name Passmark CPU/GPU Filter
  4. // @version 4
  5. // @description Passmark CPU/GPU Filter by Brand, Model or Inputed Text. @ cpubenchmark, videocardbenchmark.
  6. // @author StrongOpx
  7. // @match https://www.cpubenchmark.net/*
  8. // @match https://www.videocardbenchmark.net/*
  9. // @grant none
  10. // @icon https://www.cpubenchmark.net/favicon.ico
  11. // @run-at document-end
  12. // ==/UserScript==
  13.  
  14.  
  15. console.log(`=== cpu benchmark filter on '${location.href}' ===`);
  16.  
  17. const active_bg_color = 'bisque';
  18. const inactive_bg_color = 'slategray';
  19. const active_fg_color = 'black';
  20. const inactive_fg_color = 'lightgray';
  21.  
  22. function gen_filter_keyword(kw_regex, prod_map) {
  23. let regex = new RegExp(kw_regex, 'i');
  24. let products = document.querySelectorAll('ul.chartlist .prdname');
  25. for (let prod of products) {
  26. let m = prod.innerText.match(regex);
  27. if (m && m.length >= 2) {
  28. let kw = m[1];
  29. kw = kw.replace(/(AMD|Intel)\s+/i, '').replace('-', '').replace(/\s+/, '\\s+');
  30. //console.log(`gen filter m ${m} kw ${kw}`);
  31. if (!(kw in prod_map))
  32. prod_map[kw] = {};
  33. }
  34. }
  35. return prod_map;
  36. }
  37.  
  38. function gen_filter_map(filter_map) {
  39. let products = document.querySelectorAll('ul.chartlist .prdname');
  40. for (let k of Object.keys(filter_map)) {
  41. let regex = filter_map['regex'];
  42. if (!regex) {
  43. regex = filter_map[k]['regex'] = new RegExp(k);
  44. }
  45. filter_map[k]['products'] = [];
  46. for (let prod of products) {
  47. //console.log('prod', prod.innerText);
  48. if (regex.test(prod.innerText)) {
  49. //console.log('Add prod', prod.innerText);
  50. filter_map[k]['products'].push(prod.parentNode.parentNode);
  51. }
  52. }
  53. }
  54. }
  55.  
  56. function gen_filter_toolbar(toolbar, filter_map) {
  57. function filter_action(event) {
  58. let tool = event.target;
  59. if (tool.className.indexOf('filter_tool') < 0) {
  60. tool = tool.parentNode;
  61. if (tool.className.indexOf('filter_tool') < 0) {
  62. return;
  63. }
  64. }
  65.  
  66. let active = tool.attributes['active'];
  67. // console.log('event on ', event.target, 'active', active);
  68. active = !active;
  69. tool.attributes['active'] = active;
  70. let display = active ? '' : 'none';
  71. for (let node of tool.attributes['map']) {
  72. // console.log('node of map ', node);
  73. node.style.display = display;
  74. }
  75. tool.style.backgroundColor = active ? active_bg_color : inactive_bg_color;
  76. tool.style.color = active ? active_fg_color : inactive_fg_color;
  77. tool.style.border = active ? '1px solid black' : '1px dotted lightgray';
  78. if (node.className.indexOf('filter_all') >= 0) {
  79. for (let node of document.querySelectorAll('.filter_tool.filter_part')) {
  80. //console.log('alter', node);
  81. node.attributes['active'] = active;
  82. node.style.background = active ? active_bg_color : inactive_bg_color;
  83. node.style.color = active ? active_fg_color : inactive_fg_color;
  84. node.style.border = active ? '1px solid black' : '1px dotted lightgray';
  85. }
  86. }
  87. }
  88.  
  89. let container = document.createElement('DIV');
  90. container.className = 'filter_container';
  91. container.style.borderTop = '6px dotted white';
  92. container.style.textAlign = 'left';
  93. toolbar.appendChild(container);
  94.  
  95. let node;
  96. for (let k of Object.keys(filter_map).sort()) {
  97. node = document.createElement('DIV');
  98. let name = k.replace(/(\\\w\+?|\.)+/i, ' ');
  99. let prod_cnt = filter_map[k]['products'].length;
  100. if (prod_cnt == 0)
  101. continue;
  102. name += ` <span style='color: slateblue;'>(${prod_cnt})</span>`
  103. node.innerHTML = name;
  104. node.style.border = '1px solid black';
  105. node.style.borderRadius = '4px';
  106. node.style.padding = '2px 4px';
  107. node.style.margin = '4px';
  108. node.style.cursor = 'pointer';
  109. node.style.textAlign = 'left';
  110. node.style.background = active_bg_color;
  111. node.style.color = active_fg_color;
  112. //node.style.float = 'left';
  113. node.addEventListener('click', filter_action, { capture: true });
  114. node.attributes['active'] = true;
  115. node.attributes['map'] = filter_map[k]['products'];
  116. if (name.search(/^\s*\.?\*\s*/) < 0)
  117. node.className = 'filter_tool filter_part';
  118. else
  119. node.className = 'filter_tool filter_all';
  120. container.appendChild(node);
  121. }
  122. return container;
  123. }
  124.  
  125. function gen_input_filter(header, all_cpu_map) {
  126. function update_filter(e) {
  127. let flt = e.target.value;
  128. try {
  129. flt = flt.replace(/\s+/, '.*');
  130. let regex = new RegExp(flt, 'i');
  131. let products = all_cpu_map[Object.keys(all_cpu_map)[0]]['products'];
  132. for (let node of products) {
  133. node.style.display = regex.test(node.innerText) ? '' : 'none';
  134. }
  135. } catch (e) {
  136. console.log('update filter for input error', e);
  137. }
  138. }
  139. let input = document.createElement('INPUT');
  140. input.type = 'text';
  141. input.style.margin = '2px 4px 6px 4px';
  142. input.style.width = '90%';
  143. input.addEventListener('input', update_filter);
  144. header.appendChild(input);
  145. }
  146.  
  147. function create_filter_toolbar() {
  148. let toolbar = document.createElement('DIV');
  149. //toolbar.innerText = 'Filter: ';
  150. toolbar.style.borderRadius = '4px';
  151. toolbar.style.lineHeight = '1em';
  152. toolbar.style.position = 'fixed';
  153. toolbar.style.right = '2px';
  154. toolbar.style.top = '120px';
  155. toolbar.style.backgroundColor = inactive_bg_color;
  156. toolbar.style.color = active_fg_color;
  157. toolbar.style.zIndex = '10000';
  158. toolbar.style.fontSize = 'small';
  159. toolbar.style.padding = '4px';
  160. toolbar.style.maxWidth = '10rem';
  161. toolbar.style.maxHeight = '80%';
  162. //toolbar.style.overflowY = 'scroll';
  163.  
  164. function fold_filters(event) {
  165. console.log('Fold Filters');
  166. let target = event.target;
  167. target.attributes['fold'] = !target.attributes['fold'];
  168. for (let node of document.querySelectorAll('.filter_container')) {
  169. node.style.display = target.attributes['fold'] ? 'none' : 'block';
  170. }
  171. }
  172.  
  173. let header_sub_div = document.createElement('DIV');
  174. toolbar.appendChild(header_sub_div);
  175.  
  176. let label = document.createElement('DIV');
  177. label.innerHTML = 'FILTERS';
  178. label.style.borderRadius = '4px';
  179. label.style.textAlign = 'center';
  180. label.style.padding = '2px';
  181. label.style.margin = '2px 2px 10px';
  182. label.style.cursor = 'pointer';
  183. label.style.fontWeight = 'bold';
  184. label.style.background = 'white';
  185. label.attributes['fold'] = false;
  186. label.onclick = fold_filters;
  187. header_sub_div.appendChild(label);
  188.  
  189. let tool_sub_div = document.createElement('DIV');
  190. tool_sub_div.className = 'filter_container';
  191. tool_sub_div.style.maxWidth = '100%';
  192. tool_sub_div.style.maxHeight = '30rem';
  193. tool_sub_div.style.overflowY = 'scroll';
  194. toolbar.appendChild(tool_sub_div);
  195.  
  196. document.body.appendChild(toolbar);
  197.  
  198. return [header_sub_div, tool_sub_div];
  199. }
  200.  
  201. function filter_cpus() {
  202. if (!/cpu/i.test(location.href)) {
  203. console.log('not cpu page');
  204. return;
  205. }
  206. if (document.querySelectorAll('ul.chartlist .prdname').length == 0) {
  207. return;
  208. }
  209.  
  210. let [header, tools] = create_filter_toolbar();
  211.  
  212. let all_cpu_map = {
  213. '.*': {}
  214. };
  215.  
  216. let apple_cpu_map = {
  217. };
  218.  
  219. let intel_cpu_map = {
  220. 'Intel': {},
  221. };
  222.  
  223. let amd_cpu_map = {
  224. 'AMD': {},
  225. };
  226.  
  227. gen_filter_map(all_cpu_map);
  228. let container = gen_filter_toolbar(header, all_cpu_map);
  229. gen_input_filter(container, all_cpu_map);
  230.  
  231. gen_filter_keyword('(Apple)\\s+([a-zA-Z0-9]+)', apple_cpu_map);
  232. gen_filter_map(apple_cpu_map);
  233. gen_filter_toolbar(tools, apple_cpu_map);
  234.  
  235. gen_filter_keyword('(Intel\\s+(?:[a-zA-Z]+\\s+)(?:[a-zA-Z][\\d-]|\\d|[a-zA-Z]{2,}))', intel_cpu_map);
  236. gen_filter_map(intel_cpu_map);
  237. gen_filter_toolbar(tools, intel_cpu_map);
  238.  
  239. gen_filter_keyword('(AMD\\s+(?:[a-zA-Z]+\\s+)(?:[a-zA-Z][\\d-]|\\d|[a-zA-Z]{2,}))', amd_cpu_map);
  240. gen_filter_map(amd_cpu_map);
  241. gen_filter_toolbar(tools, amd_cpu_map);
  242.  
  243. /*
  244. for (let k of Object.keys(cpu_map)) {
  245. console.log('k', k, cpu_map[k]);
  246. }
  247. */
  248.  
  249. }
  250.  
  251. function filter_gpus() {
  252. if (!/video/i.test(location.href)) {
  253. console.log('not gpu page');
  254. return;
  255. }
  256. if (document.querySelectorAll('ul.chartlist .prdname').length == 0) {
  257. return;
  258. }
  259.  
  260. let [header, tools] = create_filter_toolbar();
  261.  
  262. let all_gpu_map = {
  263. '.*': {}
  264. };
  265.  
  266. let intel_gpu_map = {
  267. };
  268.  
  269. //let apple_gpu_map = {
  270. //};
  271.  
  272. let nvidia_gpu_map = {
  273. };
  274.  
  275. let amd_gpu_map = {
  276. };
  277.  
  278. gen_filter_map(all_gpu_map);
  279. let container = gen_filter_toolbar(header, all_gpu_map);
  280. gen_input_filter(container, all_gpu_map);
  281.  
  282. gen_filter_keyword('((?:Intel)\\s+(?:[a-zA-Z]+\\s+)?(?:[a-zA-Z][\\d-]|\\d|[a-zA-Z]{2,}))', intel_gpu_map);
  283. gen_filter_map(intel_gpu_map);
  284. gen_filter_toolbar(tools, intel_gpu_map);
  285.  
  286. gen_filter_keyword('((?:Nvidia|Geforce|TITAN|Quadro|Tesla)\\s+(?:[a-zA-Z]+\\s+)?(?:[a-zA-Z][\\d-]|\\d+(?=\\d\\d\\s)|[a-zA-Z]{2,}))', nvidia_gpu_map);
  287. gen_filter_map(nvidia_gpu_map);
  288. gen_filter_toolbar(tools, nvidia_gpu_map);
  289.  
  290. gen_filter_keyword('(Apple)\\s+([a-zA-Z0-9]+)', apple_gpu_map);
  291. gen_filter_map(apple_gpu_map);
  292. gen_filter_toolbar(tools, apple_gpu_map);
  293.  
  294. gen_filter_keyword('((?:AMD|Radeon|FirePro)\\s+(?:[a-zA-Z]+\\s+)?(?:[a-zA-Z][\\d-]|\\d|[a-zA-Z]{2,}))', amd_gpu_map);
  295. gen_filter_map(amd_gpu_map);
  296. gen_filter_toolbar(tools, amd_gpu_map);
  297.  
  298. /*
  299. for (let k of Object.keys(gpu_map)) {
  300. console.log('k', k, gpu_map[k]);
  301. }
  302. */
  303.  
  304. }
  305.  
  306. function refine_layout(e) {
  307. let container = document.querySelector('#block_content > .container') || document.querySelector('.block_content > .container')
  308. let marginLeft = (container.parentNode.clientWidth - container.clientWidth) / 2 - 20;
  309. container.style.marginLeft = marginLeft + 'px';
  310. }
  311.  
  312. try {
  313. refine_layout();
  314. } catch (e) {
  315. console.log('refine_layout error', e);
  316. }
  317. window.addEventListener('resize', refine_layout);
  318.  
  319. filter_cpus();
  320.  
  321. filter_gpus();
  322.  
  323. console.log(`=== /cpu benchmark filter on '${location.href}' ===`);
  324.  
  325.  
  326. /*
  327. let intel_cpu_map = {
  328. 'Atom': {},
  329. 'Celeron': {},
  330. 'Core\\s+i3': {},
  331. 'Core\\s+i5': {},
  332. //'Core\\s+i7': {},
  333. //'Core\\s+i9': {},
  334. 'Core': {},
  335. 'Pentium': {},
  336.  
  337. //'Xeon\\s+X': {},
  338. 'Xeon\\s+D': {},
  339. 'Xeon\\s+E3': {},
  340. 'Xeon\\s+E5': {},
  341. 'Xeon\\s+W': {},
  342. 'Xeon\\s+Silver': {},
  343. 'Xeon\\s+Gold': {},
  344. //'Xeon\\s+Platinum': {},
  345.  
  346. 'Xeon': {},
  347. };
  348.  
  349. let amd_cpu_map = {
  350. 'Athlon': {},
  351.  
  352. 'FX': {},
  353.  
  354. 'Opteron': {},
  355.  
  356. 'Ryzen\\s+3': {},
  357. 'Ryzen\\s+5': {},
  358. 'Ryzen\\s+7': {},
  359.  
  360. 'EPYC\\s+3': {},
  361. 'EPYC\\s+7': {},
  362. 'Threadripper': {},
  363. };
  364. */