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