Passmark CPU/GPU Filter

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

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