Colorize bug list based on status
当前为
// ==UserScript==
// @name crbug colorize
// @description Colorize bug list based on status
// @match https://bugs.chromium.org/*
// @version 1.0.3
// @author wOxxOm
// @namespace wOxxOm.scripts
// @license MIT License
// @run-at document-start
// @grant none
// ==/UserScript==
const sheet = new CSSStyleSheet();
sheet.replaceSync(`
.wOxxOm-Starred { font-weight: bold }
.wOxxOm-Archived { color: gray }
.wOxxOm-Assigned { color: #3f71b1 }
.wOxxOm-Available { color: #92479a }
.wOxxOm-Duplicate,
.wOxxOm-Invalid { opacity: 0.3 }
.wOxxOm-ExternalDependency { color: #ababab }
.wOxxOm-Fixed { color: #227700 }
.wOxxOm-Started,
.wOxxOm-FixPending { color: #06908b }
.wOxxOm-Unconfirmed,
.wOxxOm-New { color: black }
.wOxxOm-Untriaged { color: #947911 }
.wOxxOm-Verified, .wOxxOm-Accepted { color: #6a846f }
.wOxxOm-WontFix { color: #d00 }
tr[class*="wOxxOm-"] td[width="100%"] a {
color: inherit;
text-decoration: underline;
}
`);
(async () => {
const app = await added('mr-app');
const main = await added('main', app);
while (true) await colorize(main);
})();
async function colorize(main) {
const page = await added('mr-list-page', main);
const list = await shadowOf(await added('mr-issue-list', page));
const sheets = list.adoptedStyleSheets;
if (!sheets.includes(sheet))
list.adoptedStyleSheets = [...sheets, sheet];
for (const el of list.querySelectorAll('td')) {
const text = el.textContent.trim();
switch (text) {
case '':
continue;
case 'Accepted':
case 'Archived':
case 'Assigned':
case 'Available':
case 'Duplicate':
case 'ExternalDependency':
case 'FixPending':
case 'Fixed':
case 'Invalid':
case 'New':
case 'Started':
case 'Unconfirmed':
case 'Untriaged':
case 'Verified':
case 'WontFix':
el.parentNode.classList.add('wOxxOm-' + text);
continue;
case '★':
el.parentNode.classList.add('wOxxOm-Starred');
continue;
}
if (el.align === 'right' && (text === '1' || text === '0')) {
el.textContent = '';
}
if (/% regression in|\b\d(\.\d)?%(-\d(\.\d)?%)? improvement in|test.*?is flaky|^(Android|Chrome)$/.test(text) && el.parentNode) {
el.parentNode.remove();
}
}
await removed(page);
}
async function added(sel, parent = document.documentElement) {
const target =
parent.shadowRoot ||
!parent.localName.includes('-') && parent ||
await shadowOf(parent);
return target.querySelector(sel) || new Promise(resolve => {
const mo = new MutationObserver(() => {
const el = target.querySelector(sel);
if (el) {
mo.disconnect();
resolve(el);
}
});
mo.observe(target, {childList: true, subtree: true});
});
}
function removed(el) {
const root = el.getRootNode();
return root.contains(el) && new Promise(resolve => {
const mo = new MutationObserver(() => {
if (!root.contains(el)) {
mo.disconnect();
resolve();
}
});
mo.observe(root, {childList: true, subtree: true});
});
}
function shadowOf(el) {
return el.shadowRoot || new Promise(resolve => {
el.attachShadow = function (...args) {
delete el.attachShadow;
const root = el.attachShadow(...args);
resolve(root);
return root;
};
});
}