A userscript that adds a button to make the diff better
当前为
// ==UserScript==
// @name Github Better Diff
// @description A userscript that adds a button to make the diff better
// @license MIT
// @author Marco Pelegrini
// @namespace https://github.com/marcopelegrini
// @version 2.0.0
// @include https://github.com/*
// @exclude https://github.com/*/*.diff
// @exclude https://github.com/*/*.patch
// @run-at document-idle
// @grant GM.addStyle
// @grant GM_addStyle
// @icon https://github.githubassets.com/pinned-octocat.svg
// ==/UserScript==
(function () {
let bdAuto = JSON.parse(localStorage.bdAuto || true);
let bdExpandDeleted = JSON.parse(localStorage.bdExpandDeleted || false);
//console.log('BetterDiff Auto: ' + bdAuto);
//console.log('BetterDiff Expand deleted: ' + bdExpandDeleted);
function addButton() {
let e;
if (/\/pull\/\d*\/(files|commits)/.test(location.href) && (e = document.querySelector('#files_bucket .pr-toolbar .diffbar > .float-right'))) {
let r = e.querySelector('.GithubFixDiffButton');
if (r) {
r.parentElement.removeChild(r)
}
let betterDiffContainer = document.createElement('details');
betterDiffContainer.classList.add('details-reset', 'details-overlay', 'position-relative', 'float-left');
let detailsButton = document.createElement('summary');
detailsButton.classList.add('btn', 'btn-sm', 'select-menu-button');
detailsButton.style.cssFloat = 'inherit';
detailsButton.appendChild(document.createTextNode('Better Diff '));
betterDiffContainer.appendChild(detailsButton);
let popupDiv = document.createElement('div');
popupDiv.classList.add('Popover', 'js-diff-settings', 'mt-2', 'pt-1');
popupDiv.style.left = '-35px';
popupDiv.innerHTML += "" +
"<div class='Popover-message text-left p-3 mx-auto Box box-shadow-large'>" +
" <h5 class='mb-2'>" +
" <input type='checkbox' id='bd-auto' name='bd-auto' value='1' " + (bdAuto ? "checked='checked'" : "") + ">" +
" Execute automatically" +
" </h5>" +
" <h5 class='mb-2'>Deleted files content</h5>" +
" <div class='BtnGroup d-flex flex-content-stretch js-diff-style-toggle'>" +
" <label class='flex-auto btn btn-sm BtnGroup-item text-center " + (bdExpandDeleted ? "'" : "selected'") + ">" +
" <input class='sr-only' value='hide' name='bd-expand-deleted' type='radio' " + (bdExpandDeleted ? '' : "checked='checked'") + ">" +
" Hide" +
" </label>" +
" <label class='flex-auto btn btn-sm BtnGroup-item text-center " + (bdExpandDeleted ? "selected'" : "'") + ">" +
" <input class='sr-only' value='expand' name='bd-expand-deleted' type='radio' " + (bdExpandDeleted ? "checked='checked'" : "") + ">" +
" Expand" +
" </label>" +
" </div>" +
"</div>";
betterDiffContainer.appendChild(popupDiv);
let g = document.createElement('div');
g.classList.add('GithubFixDiffButton', 'diffbar-item');
g.appendChild(betterDiffContainer);
let runButton = document.createElement('a');
runButton.setAttribute('id', 'bdRun');
runButton.classList.add('social-count');
runButton.appendChild(document.createTextNode('▶'));
runButton.addEventListener('click', applyBetterDiff, false);
if (!bdAuto) {
detailsButton.classList.add('btn-with-count');
} else {
runButton.style.display = "none";
}
g.appendChild(runButton);
e.insertBefore(g, e.firstChild);
document.getElementById('bd-auto').addEventListener('change', function (e) {
//console.log('BetterDiff Auto changed: ' + e.target.checked);
localStorage.bdAuto = e.target.checked;
if (e.target.checked) {
runButton.style.display = "none";
detailsButton.classList.remove('btn-with-count');
} else {
runButton.style.display = "block";
detailsButton.classList.add('btn-with-count');
}
}, false);
document.getElementsByName('bd-expand-deleted').forEach(function (e) {
e.addEventListener("click", function () {
let bdExpandDeleted = e.value === 'expand';
localStorage.bdExpandDeleted = bdExpandDeleted;
//console.log('BetterDiff Expand deleted changed: ' + bdExpandDeleted);
});
});
}
}
function applyBetterDiff() {
setTimeout(function () {
// Fix deleted
Array.from(document.querySelectorAll('.js-diff-load-container'))
.filter(e => {
let diffReason = e.querySelector('.hidden-diff-reason');
return diffReason != null && diffReason.innerHTML.includes('This file was deleted');
})
.forEach(e => {
let content = e.parentElement.parentElement;
content.querySelector('.file-header').querySelector('.diffstat.tooltipped.tooltipped-e').innerHTML = 'DELETED';
e.style.display = "none";
});
// Fix renamed
Array.from(document.querySelectorAll('.data.highlight.empty'))
.forEach(e => {
let content = e.parentElement;
content.style.display = "none";
content.parentElement.querySelector('.file-header').querySelector('.diffstat.tooltipped.tooltipped-e').innerHTML = 'RENAMED'
});
// Expand large files
Array.from(document.querySelectorAll('.js-diff-load-container'))
.forEach(container => {
let querySelector = container.querySelector('.load-diff-button');
if (querySelector){
querySelector.click()
}
});
}, 100);
}
function whenSettled(cb, ms) {
function isSettled() {
waiter = last = null;
cb.apply(self, args);
}
ms = ms || 100;
let last, waiter, self, args;
return function () {
self = this;
args = arguments;
if (waiter) clearTimeout(waiter);
waiter = setTimeout(isSettled, ms);
};
}
function initObserver() {
let observer = new MutationObserver(function (mutations) {
setTimeout(process.bind(null, mutations), 0);
});
function process(mutations) {
console.log(mutations);
for (var m = 0, ml = mutations.length; m < ml; m++) {
var mutation = mutations[m];
console.log(mutation);
// if (mutation.type === "childList") {
// for (var n = 0, nodes = mutation.addedNodes, nl = nodes.length; n < nl; n++) {
// var node = nodes[n];
// if (node.localName === "iframe" && iframeIsDynamic(node)) {
// addDocumentStylesToIFrame(node);
// }
// }
// }
}
}
observer.start = function () {
// will be ignored by browser if already observing
observer.observe(document, {childList: true, subtree: true});
}
}
initObserver();
//document.addEventListener('DOMNodeInsertedIntoDocument', function () {
// console.log("DOMNodeInsertedIntoDocument");
// if (bdAuto) {
// whenSettled(applyBetterDiff);
// }
//}, true);
// Init
addButton();
if (bdAuto) {
applyBetterDiff();
}
// Pjax
document.addEventListener('pjax:end', function() {
console.log('BetterDiff - pjax:end');
if (bdAuto) {
console.log('BetterDiff - applying');
setTimeout(function () {
applyBetterDiff();
}, 100);
}
});
})();