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.

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        Metal Archives discography pages - Reviews column split and sortable tables
// @namespace   darkred
// @version     2.1.0
// @date        2020.9.20
// @description Splits the Reviews column into Reviews(count) and Ratings and makes the tables in all discography tabs sortable.
// @author      RobG, Brock Adams, Mottie, darkred
// @license     MIT
// @include     /^https?:\/\/www\.metal-archives\.com/bands?/.*$/
// @grant       GM_addStyle
// @require     https://code.jquery.com/jquery-3.5.1.min.js
// @require     https://greasyfork.org/scripts/12036-mutation-summary/code/Mutation%20Summary.js
// @require     https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/js/jquery.tablesorter.min.js
// @require     https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/js/jquery.tablesorter.widgets.min.js
// @require     https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/js/extras/jquery.tablesorter.pager.min.js
//
// This userscript uses jQuery v1.11.1,
// the jQuery plugin 'tablesorter' (forked by Rob Garrison (Mottie)) http://mottie.github.io/tablesorter/docs/index.html ,
// and the JavaScript library 'Mutation Summary' (https://github.com/rafaelw/mutation-summary) (by Rafael Weinstein).
//
// Thanks a lot for the invaluable help to RobG, Mottie and especially Brock Adams.
//
// @supportURL  https://github.com/darkred/Userscripts/issues
// ==/UserScript==


/* global MutationSummary */

// CSS rules in order to show 'up' and 'down' arrows in each table header
var stylesheet = `
<style>
thead th {
	background-repeat: no-repeat;
	background-position: right center;
}
thead th.up {
	background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7);
}
thead th.down {
	background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7);
}
.discog th:nth-last-child(2){
	width: 38px;
}
.discog th:nth-last-child(1){
	width: 35px;
}
.tablesorter .filtered {
	display: none;
}



/* All of the following css is already contained within each theme file; modify it as desired */
/* filter row */
.tablesorter-filter-row td {
	background: #000;
  line-height: normal;
  text-align: center; /* center the input */
  -webkit-transition: line-height 0.1s ease;
  -moz-transition: line-height 0.1s ease;
  -o-transition: line-height 0.1s ease;
  transition: line-height 0.1s ease;
}
/* optional disabled input styling */
.tablesorter-filter-row .disabled {
  opacity: 0.5;
  filter: alpha(opacity=50);
  cursor: not-allowed;
}

/* hidden filter row */
.tablesorter-filter-row.hideme td {
  /*** *********************************************** ***/
  /*** change this padding to modify the thickness     ***/
  /*** of the closed filter row (height = padding x 2) ***/
  padding: 2px;
  /*** *********************************************** ***/
  margin: 0;
  line-height: 0;
  cursor: pointer;
}
.tablesorter-filter-row.hideme * {
  height: 1px;
  min-height: 0;
  border: 0;
  padding: 0;
  margin: 0;
  /* don't use visibility: hidden because it disables tabbing */
  opacity: 0;
  filter: alpha(opacity=0);
}
/* filters */
.tablesorter-filter {
  width: 95%;
  height: inherit;
  margin: 4px;
  padding: 4px;
  background-color: #1b0b0b;
  color: #c2b8af;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  -webkit-transition: height 0.1s ease;
  -moz-transition: height 0.1s ease;
  -o-transition: height 0.1s ease;
  transition: height 0.1s ease;
}

</style>`;

$('head').append(stylesheet);





function appendColumn(jNode) {

	// STEP 1+2: SPLIT THE 'REVIEWS' COLUMN INTO A 'REVIEWS' COLUMN AND A 'RATINGS' COLUMN
	var tbl = jNode[0];     // table reference


	// If you have logged in (therefore the column 'Tools' exists in the discography table)
	if (document.getElementsByClassName('member_name').length >0){
		tbl.rows[0].cells[1].width = '45%';            // In order the column 'Name'(it's the 2nd) to have enough(in fact fixed) width
	} else {
		tbl.rows[0].cells[0].width = '53%';           // In order the column 'Name'(it's the 1nd) to have enough(in fact fixed) width
	}



	// If the current sub-table has no data, then stop the execution of the function
	if (tbl.rows[1].cells[0].innerHTML === '<em>Nothing entered yet. Please add the releases, if applicable. </em>') {
		return;
	}

	var newCell;

	const cols = tbl.rows[0].cells.length - 1;

	var tr = tbl.tHead.children[0],
		th = document.createElement('th');

	th.innerHTML = 'Ratings';
	th.className = 'ratingsCol';
	tr.appendChild(th);

	for (var i = 1; i < tbl.rows.length; i++) {
		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


		var re1 = /<a [^>]*>[^(]*[(]([^)]+)/ ;        // (RegEx which matches the 'Ratings' percentage(incl.the % symbol)
		var l = re1.exec(k);                          // (Execute the RegEx and store it to variable l)

		newCell = tbl.rows[i].insertCell(-1);     // Add a new cell (for the new 'Ratings' column ) -for each row-

		if (re1.test(k)){                    // If the RegEx has matches, (only) then create new cells with...

			var re0 = /(<a [^>]*>)[0-9]*[^(]/ ;       // (RegEx which matches the reviews URL)
			var url = re0.exec(k);                    // (Execute the RegEx and store it to variable url)

			newCell.innerHTML = url[1] + l[1] + '</url>'; // ...the Ratings percentage (which is also a link to the Reviews)...


			var re2 = /<a [^>]*>([0-9]*)[^(]/ ;       // (RegEx which matches the 'Reviews' number)
			var m = re2.exec(k);                      // (Execute the RegEx and store it to variable m)

			newCell = tbl.rows[i].cells[cols];
			newCell.innerHTML = url[1] + m[1] + '</url>'; // ...and the Reviews number (which is also a link to the Reviews)
		}
	}


	// TODO: are you login? Then header0: sorter: false
	let login;
	// if login form doesn't exist (=you have login), then disable sorting (NOT filtering too) on column 0 ("Edit/Tools")
	$('#login_form > div > button').length === 0 ? login = false : login = true;

	//  STEP 3: MAKE THE DISCOGRAPHY TABLE SORTABLE  (using the jQuery plugin "tablesorter")
	$(tbl).tablesorter ( {
		cssAsc: 'up',
		cssDesc: 'down',
		headers: {
			// 0: {sorter: false}
			0: { sorter: login,
				filter: login}
		},
		widgets: ['filter'],
		ignoreCase: true,
		widgetOptions : {
			filter_hideFilters : true,
		},
	} );
}


function handleDiscographyChanges (muteSummaries) {
	var mSummary    = muteSummaries[0];
	if (mSummary.added.length) {
		appendColumn ( $(mSummary.added[0]) );
	}
}


new MutationSummary ( {
	callback: handleDiscographyChanges,
	rootNode: $('#band_disco')[0],
	queries: [ {element: '.discog'} ]
} );