让 hololyzer 的超级留言清单支持按姓名排序
当前为
// ==UserScript==
// @name hololyzer Sort Tool
// @name:zh hololyzer 排序工具
// @name:zh-TW hololyzer 排序工具
// @name:zh-CN hololyzer 排序工具
// @namespace https://github.com/kevin823lin
// @version 0.1
// @description Add support for sort hololyzer's super chat list by name.
// @description:zh 讓 hololyzer 的超級留言清單支援按姓名排序
// @description:zh-TW 讓 hololyzer 的超級留言清單支援按姓名排序
// @description:zh-CN 让 hololyzer 的超级留言清单支持按姓名排序
// @author kevin823lin
// @match https://www.hololyzer.net/*/superchat/*
// @icon https://www.google.com/s2/favicons?domain=hololyzer.net
// @grant none
// @date 2021-12-11
// ==/UserScript==
(function () {
'use strict';
// Your code here...
window.addEventListener('load', function (event) {
document.body.dataset.sortBy = "time";
insertButton();
}, false);
function insertButton() {
const sortByTime = document.createElement('button');
const sortByName = document.createElement('button');
sortByTime.innerHTML = "時間排序";
sortByName.innerHTML = "姓名排序";
sortByTime.addEventListener("click", function () {
if (document.body.dataset.sortBy !== "time") {
window.location.href = window.location.href;
}
});
sortByName.addEventListener("click", async function () {
if ((document.body.dataset.sortBy) !== "name") {
document.body.dataset.sortBy = "name";
await waitElementsLoaded('table[border]');
main();
}
});
document.body.insertAdjacentElement('afterbegin', sortByName);
document.body.insertAdjacentElement('afterbegin', sortByTime);
}
function main() {
move();
sort();
insert();
}
function move() {
const tbody = document.querySelector('table[border] > tbody');
const trs = tbody.querySelectorAll("tr");
const insertIndex = [...tbody.querySelectorAll("th")].findIndex(th => th.matches('[style]'));
tbody.querySelectorAll('[rowspan]').forEach(a => a.removeAttribute('rowspan'))
trs.forEach((tr, i) => {
if (i % 2) {
const parentEle = trs[i - 1];
const childrenEle = parentEle.children[insertIndex + 1];
const insertEle = tr.querySelector("th") || tr.querySelector("td");
childrenEle.removeAttribute('style');
insertEle.removeAttribute('style');
insertEle.parentElement.remove();
parentEle.insertBefore(insertEle, childrenEle);
}
})
}
function sort() {
const tbody = document.querySelector('table[border] > tbody');
const trs = [...tbody.querySelectorAll("tr")].filter(tr => {
return tr.querySelector('td');
});
let sortIndex = [...tbody.querySelectorAll('th')].findIndex(th => th.innerText === "チャンネル名");
if (sortIndex === -1) {
sortIndex = 6;
}
trs.sort(function (a, b) {
var keyA = a.querySelector(`td:nth-child(${sortIndex + 1})`).textContent;
var keyB = b.querySelector(`td:nth-child(${sortIndex + 1})`).textContent;
return keyA.localeCompare(keyB, 'ja');
});
for (const tr of trs) {
tbody.append(tr);
}
}
function insert() {
const tbody = document.querySelector('table[border] > tbody');
const trs = [...tbody.querySelectorAll("tr")].filter(tr => {
return tr.querySelector('td');
});
let insertIndex = [...tbody.querySelectorAll('th')].findIndex(th => th.innerText === "No");
if (insertIndex === -1) {
insertIndex = 0;
}
let sortIndex = [...tbody.querySelectorAll('th')].findIndex(th => th.innerText === "チャンネル名");
if (sortIndex === -1) {
sortIndex = 6;
}
let count = 0;
const countList = new Array();
for (const [i, tr] of trs.entries()) {
const preName = trs[i - 1] && trs[i - 1].querySelector(`:nth-child(${sortIndex + 1})`)?.innerText;
const name = tr.querySelector(`:nth-child(${sortIndex + 1})`)?.innerText;
countList.push(preName !== name ? ++count : count);
}
for (const [i, tr] of trs.entries()) {
const insertEle = tr.insertCell(insertIndex + 1);
insertEle.innerHTML = countList[i];
insertEle.style = "text-align: right";
}
const parentEle = tbody.querySelector("tr");
const childrenEle = parentEle.children[insertIndex + 1];
const insertEle = document.createElement("th");
insertEle.innerHTML = "去除重複";
insertEle.style = "white-space: nowrap;";
parentEle.insertBefore(insertEle, childrenEle);
}
function waitElementsLoaded(...eles) {
return Promise.all(eles.map(ele => {
return new Promise(async resolve => {
while (!document.querySelector(ele)) {
await wait(100);
}
resolve();
});
}));
}
function wait(ms) {
try {
return new Promise(r => setTimeout(r, ms));
} catch (e) {
console.error(`wait: ${e}`);
}
}
})();