// ==UserScript== // @name Fxxk GitHub's new UI // @name:zh-CN 拒绝 GitHub 新 UI // @namespace Aloxaf // @version 0.1.8 // @description Move repo information to the top. // @description:zh-CN 将 repo 信息移动至顶部 // @author Aloxaf // @match https://github.com/*/* // @run-at document-start // @downloadURL none // ==/UserScript== // jshint esversion: 6 // GreasyMonkey 4.0+ doesn't support GM_addStyle // https://stackoverflow.com/questions/23683439/gm-addstyle-equivalent-in-tampermonkey function GM_addStyle(css) { const style = document.getElementById("GM_addStyleBy8626") || (function() { const style = document.createElement('style'); style.type = 'text/css'; style.id = "GM_addStyleBy8626"; document.head.appendChild(style); return style; })(); const sheet = style.sheet; sheet.insertRule(css, (sheet.rules || sheet.cssRules || []).length); } GM_addStyle(` .Box-header { padding: 8px 16px !important; } `); function log(e) { // return console.log(e); } function $(e) { return document.querySelector(e); } function rename_node(node, name) { let ele = document.createElement(name); let old_attrs = node.attributes; let new_attrs = ele.attributes; for(let i = 0, len = old_attrs.length; i < len; i++) { new_attrs.setNamedItem(old_attrs.item(i).cloneNode()); } do { ele.appendChild(node.firstChild); } while (node.firstChild); node.parentNode.replaceChild(ele, node); return ele; } function xpath(s) { return document.evaluate(s, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; } function set_about(content) { log('setting about'); let about = xpath('//h2[text() = "About"]/following-sibling::p[1]'); about.className = "f4"; let url = xpath('//h2[text() = "About"]/following-sibling::div[1]/span/a'); if (url) { url.innerText = url.href; url.removeAttribute('class'); about.appendChild(url); } content.insertBefore(about, content.children[1]); } function set_topics(content) { log('setting topics'); let topics = xpath('//h3[text() = "Topics"]/following-sibling::div[1]'); if (topics) { topics.className = "repository-topics-container mt-2 mb-3 js-topics-list-container"; content.insertBefore(topics, content.children[1]); } } function set_summary(content) { log('setting summary'); let overall_summary = document.createElement('div'); overall_summary.className = "overall-summary"; let summary = xpath('//h2[text() = "Git stats"]/following-sibling::ul[1]'); summary.className = "numbers-summary"; // Add contributors log('setting contributors'); let contributors = document.createElement('li'); let contri_nums = xpath('//a[contains(text(), "Contributors")]/span/text()'); // ?.textContent ?? 1; contri_nums = contri_nums ? contri_nums.textContent : 1; let contri_href = xpath('//a[contains(text(), "Contributors")]/@href'); contri_href = contri_href ? contri_href.value : `//${window.location.host}/${window.location.pathname}/graphs/contributors`; contributors.innerHTML = ` ${contri_nums} contributors `; summary.appendChild(contributors); // Add license log('setting license'); let _license = xpath('//h3[text() = "License"]/following-sibling::div[1]/a'); if (_license) { let license = document.createElement('li'); license.appendChild(_license); license.children[0].className = "link-gray-dark no-underline d-inline-block"; summary.appendChild(license); } overall_summary.appendChild(summary); content.insertBefore(overall_summary, content.children[1]); for (let li of summary.childNodes) { li.className = ''; } // Add languages progress log('setting languages'); let progress = xpath('//h2[text() = "Languages"]/following-sibling::div[1]/span'); if (progress) { overall_summary.className += " border-bottom-0 mb-0 rounded-bottom-0"; let languages = document.createElement('div'); languages.className = 'repository-lang-stats'; languages.appendChild(rename_node(xpath('//h2[text() = "Languages"]/following-sibling::ul[1]'), 'ol')); languages.children[0].className = 'repository-lang-stats-numbers'; for (let li of languages.children[0].children) { li.removeAttribute('class'); li.children[0].removeAttribute('class'); let svg = li.children[0].children[0]; svg = rename_node(svg, "span"); svg.className = "color-block language-color"; svg.style.backgroundColor = svg.style.color; } let details = document.createElement('details'); details.className = "details-reset"; summary = document.createElement('summary'); summary.appendChild(progress); details.appendChild(summary); details.appendChild(languages); content.insertBefore(details, content.children[2]); } } function is_main_page() { return /^https:\/\/github\.com\/[^/]+\/[^/]+(\/?$|[^/]+$)/.test(window.location); } function fxxk() { add_hook(); let code = xpath('//a[./span[@data-content="Code"]]'); if (!(/ selected /.test(code.className) && is_main_page())) { return; } let content = $('.repository-content'); set_summary(content); set_topics(content); set_about(content); // Hide new tab $('.file-navigation').className += " in-mid-page"; $('.repository-content > div > .flex-shrink-0:last-child').style.display = 'hidden'; content = $('.repository-content > div > .flex-shrink-0'); content.className = content.className.replace('col-md-9', ''); } function wait_for(condition, callback) { if(!condition()) { log('waiting'); window.setTimeout(wait_for.bind(null, condition, callback), 100); } else { log('done'); callback(); } } function add_hook() { log('add hook'); let nodes = document.evaluate( '//nav[contains(@class, "UnderlineNav")]/ul/li/a', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null ); for (let i = 0; i < nodes.snapshotLength; i++) { let node = nodes.snapshotItem(i); node.addEventListener('click', () => { wait_for(() => { if (is_main_page()) { return xpath('//h2[text() = "About"]/following-sibling::p[1]') && xpath('//span[@class="Progress"]'); } else { let bounding = node.getBoundingClientRect(); return !(bounding.top > 0 && bounding.left > 0 && bounding.right < window.innerWidth && bounding.bottom < window.innerHeight); } }, fxxk); }); } } (function () { 'use strict' fxxk(); })();