Metal Archives discography pages - Reviews column split and sortable tables

Splits the Reviews column into Reviews(count) and Ratings and makes the tables in all discography tabs sortable.

  1. // ==UserScript==
  2. // @name Metal Archives discography pages - Reviews column split and sortable tables
  3. // @namespace darkred
  4. // @version 2.1.0
  5. // @date 2020.9.20
  6. // @description Splits the Reviews column into Reviews(count) and Ratings and makes the tables in all discography tabs sortable.
  7. // @author RobG, Brock Adams, Mottie, darkred
  8. // @license MIT
  9. // @include /^https?:\/\/www\.metal-archives\.com/bands?/.*$/
  10. // @grant GM_addStyle
  11. // @require https://code.jquery.com/jquery-3.5.1.min.js
  12. // @require https://gf.qytechs.cn/scripts/12036-mutation-summary/code/Mutation%20Summary.js
  13. // @require https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/js/jquery.tablesorter.min.js
  14. // @require https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/js/jquery.tablesorter.widgets.min.js
  15. // @require https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/js/extras/jquery.tablesorter.pager.min.js
  16. //
  17. // This userscript uses jQuery v1.11.1,
  18. // the jQuery plugin 'tablesorter' (forked by Rob Garrison (Mottie)) http://mottie.github.io/tablesorter/docs/index.html ,
  19. // and the JavaScript library 'Mutation Summary' (https://github.com/rafaelw/mutation-summary) (by Rafael Weinstein).
  20. //
  21. // Thanks a lot for the invaluable help to RobG, Mottie and especially Brock Adams.
  22. //
  23. // @supportURL https://github.com/darkred/Userscripts/issues
  24. // ==/UserScript==
  25.  
  26.  
  27. /* global MutationSummary */
  28.  
  29. // CSS rules in order to show 'up' and 'down' arrows in each table header
  30. var stylesheet = `
  31. <style>
  32. thead th {
  33. background-repeat: no-repeat;
  34. background-position: right center;
  35. }
  36. thead th.up {
  37. background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7);
  38. }
  39. thead th.down {
  40. background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7);
  41. }
  42. .discog th:nth-last-child(2){
  43. width: 38px;
  44. }
  45. .discog th:nth-last-child(1){
  46. width: 35px;
  47. }
  48. .tablesorter .filtered {
  49. display: none;
  50. }
  51.  
  52.  
  53.  
  54. /* All of the following css is already contained within each theme file; modify it as desired */
  55. /* filter row */
  56. .tablesorter-filter-row td {
  57. background: #000;
  58. line-height: normal;
  59. text-align: center; /* center the input */
  60. -webkit-transition: line-height 0.1s ease;
  61. -moz-transition: line-height 0.1s ease;
  62. -o-transition: line-height 0.1s ease;
  63. transition: line-height 0.1s ease;
  64. }
  65. /* optional disabled input styling */
  66. .tablesorter-filter-row .disabled {
  67. opacity: 0.5;
  68. filter: alpha(opacity=50);
  69. cursor: not-allowed;
  70. }
  71.  
  72. /* hidden filter row */
  73. .tablesorter-filter-row.hideme td {
  74. /*** *********************************************** ***/
  75. /*** change this padding to modify the thickness ***/
  76. /*** of the closed filter row (height = padding x 2) ***/
  77. padding: 2px;
  78. /*** *********************************************** ***/
  79. margin: 0;
  80. line-height: 0;
  81. cursor: pointer;
  82. }
  83. .tablesorter-filter-row.hideme * {
  84. height: 1px;
  85. min-height: 0;
  86. border: 0;
  87. padding: 0;
  88. margin: 0;
  89. /* don't use visibility: hidden because it disables tabbing */
  90. opacity: 0;
  91. filter: alpha(opacity=0);
  92. }
  93. /* filters */
  94. .tablesorter-filter {
  95. width: 95%;
  96. height: inherit;
  97. margin: 4px;
  98. padding: 4px;
  99. background-color: #1b0b0b;
  100. color: #c2b8af;
  101. -webkit-box-sizing: border-box;
  102. -moz-box-sizing: border-box;
  103. box-sizing: border-box;
  104. -webkit-transition: height 0.1s ease;
  105. -moz-transition: height 0.1s ease;
  106. -o-transition: height 0.1s ease;
  107. transition: height 0.1s ease;
  108. }
  109.  
  110. </style>`;
  111.  
  112. $('head').append(stylesheet);
  113.  
  114.  
  115.  
  116.  
  117.  
  118. function appendColumn(jNode) {
  119.  
  120. // STEP 1+2: SPLIT THE 'REVIEWS' COLUMN INTO A 'REVIEWS' COLUMN AND A 'RATINGS' COLUMN
  121. var tbl = jNode[0]; // table reference
  122.  
  123.  
  124. // If you have logged in (therefore the column 'Tools' exists in the discography table)
  125. if (document.getElementsByClassName('member_name').length >0){
  126. tbl.rows[0].cells[1].width = '45%'; // In order the column 'Name'(it's the 2nd) to have enough(in fact fixed) width
  127. } else {
  128. tbl.rows[0].cells[0].width = '53%'; // In order the column 'Name'(it's the 1nd) to have enough(in fact fixed) width
  129. }
  130.  
  131.  
  132.  
  133. // If the current sub-table has no data, then stop the execution of the function
  134. if (tbl.rows[1].cells[0].innerHTML === '<em>Nothing entered yet. Please add the releases, if applicable. </em>') {
  135. return;
  136. }
  137.  
  138. var newCell;
  139.  
  140. const cols = tbl.rows[0].cells.length - 1;
  141.  
  142. var tr = tbl.tHead.children[0],
  143. th = document.createElement('th');
  144.  
  145. th.innerHTML = 'Ratings';
  146. th.className = 'ratingsCol';
  147. tr.appendChild(th);
  148.  
  149. for (var i = 1; i < tbl.rows.length; i++) {
  150. var k = tbl.rows[i].cells[cols].innerHTML; // Retrieve the content of the current cell of the Review column and store it to variable k
  151.  
  152.  
  153. var re1 = /<a [^>]*>[^(]*[(]([^)]+)/ ; // (RegEx which matches the 'Ratings' percentage(incl.the % symbol)
  154. var l = re1.exec(k); // (Execute the RegEx and store it to variable l)
  155.  
  156. newCell = tbl.rows[i].insertCell(-1); // Add a new cell (for the new 'Ratings' column ) -for each row-
  157.  
  158. if (re1.test(k)){ // If the RegEx has matches, (only) then create new cells with...
  159.  
  160. var re0 = /(<a [^>]*>)[0-9]*[^(]/ ; // (RegEx which matches the reviews URL)
  161. var url = re0.exec(k); // (Execute the RegEx and store it to variable url)
  162.  
  163. newCell.innerHTML = url[1] + l[1] + '</url>'; // ...the Ratings percentage (which is also a link to the Reviews)...
  164.  
  165.  
  166. var re2 = /<a [^>]*>([0-9]*)[^(]/ ; // (RegEx which matches the 'Reviews' number)
  167. var m = re2.exec(k); // (Execute the RegEx and store it to variable m)
  168.  
  169. newCell = tbl.rows[i].cells[cols];
  170. newCell.innerHTML = url[1] + m[1] + '</url>'; // ...and the Reviews number (which is also a link to the Reviews)
  171. }
  172. }
  173.  
  174.  
  175. // TODO: are you login? Then header0: sorter: false
  176. let login;
  177. // if login form doesn't exist (=you have login), then disable sorting (NOT filtering too) on column 0 ("Edit/Tools")
  178. $('#login_form > div > button').length === 0 ? login = false : login = true;
  179.  
  180. // STEP 3: MAKE THE DISCOGRAPHY TABLE SORTABLE (using the jQuery plugin "tablesorter")
  181. $(tbl).tablesorter ( {
  182. cssAsc: 'up',
  183. cssDesc: 'down',
  184. headers: {
  185. // 0: {sorter: false}
  186. 0: { sorter: login,
  187. filter: login}
  188. },
  189. widgets: ['filter'],
  190. ignoreCase: true,
  191. widgetOptions : {
  192. filter_hideFilters : true,
  193. },
  194. } );
  195. }
  196.  
  197.  
  198. function handleDiscographyChanges (muteSummaries) {
  199. var mSummary = muteSummaries[0];
  200. if (mSummary.added.length) {
  201. appendColumn ( $(mSummary.added[0]) );
  202. }
  203. }
  204.  
  205.  
  206. new MutationSummary ( {
  207. callback: handleDiscographyChanges,
  208. rootNode: $('#band_disco')[0],
  209. queries: [ {element: '.discog'} ]
  210. } );

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址