Skip to content

Instantly share code, notes, and snippets.

@tylerdavis
Last active March 1, 2018 23:32
Show Gist options
  • Save tylerdavis/26ebb4f1cdc296287f1781c871b1d708 to your computer and use it in GitHub Desktop.
Save tylerdavis/26ebb4f1cdc296287f1781c871b1d708 to your computer and use it in GitHub Desktop.
Bitbucket PR File Collapse - Add a button to each file in bitbucket PRs to collapse and expand the file
// ==UserScript==
// @name Bitbucket PR File Collapse
// @version 0.1
// @description Add a button to each file in bitbucket PRs to collapse and expand the file
// @author Tyler Davis <tyler@tmd.io>
// @match https://bitbucket.org/atlassian/*/pull-requests/*
// @grant none
// ==/UserScript==
(window.addEventListener('load', function () {
'use strict';
console.log('Loading Bitbucket PR File Collapse');
function button (name, title) {
let container = document.createElement('div');
container.className = 'aui-buttons';
let button = document.createElement('button');
button.className = 'collapse-button execute click aui-button aui-button-light sbs';
button.href = '#';
button.title = title;
button.innerText = name;
container.appendChild(button);
container.changeText = (text) => button.innerText = text;
return container;
}
function onCollapse (contentContainer, button, heading, parentSection) {
if (button.innerText === 'Collapse') {
collapseContentContainer(contentContainer, button, heading, parentSection);
} else {
expandContentContainer(contentContainer, button, heading, parentSection);
}
}
function collapseContentContainer (contentContainer, button, heading, parentSection) {
contentContainer.style.display = 'none';
button.changeText('Expand');
styleCollapsedHeading(heading);
parentSection.nextElementSibling.style.marginTop = 0;
}
function expandContentContainer (contentContainer, button, heading, parentSection) {
contentContainer.style.display = 'block';
button.changeText('Collapse');
styleExpandedHeading(heading);
parentSection.nextElementSibling.style.marginTop = '40px';
}
function styleCollapsedHeading (heading) {
heading.style.borderBottom = '1px solid #ccc';
heading.style.borderBottomRightRadius = '5px';
heading.style.borderBottomLeftRadius = '5px';
}
function styleExpandedHeading (heading) {
heading.style.borderBottom = null;
heading.style.borderBottomRightRadius = '0px';
heading.style.borderBottomLeftRadius = '0px';
}
function lozenge (element) {
return element.querySelector('.heading .filename span.diff-entry-lozenge');
}
function isDeletedFile (element) {
const indicator = lozenge(element);
if (!indicator) return false;
return (indicator.innerText === 'DELETED');
}
function isRenamedFile (element) {
const indicator = lozenge(element);
if (!indicator) return false;
return (indicator.innerText === 'RENAMED');
}
function initializeDiffContainer (element) {
let heading = element.querySelector('.heading');
let contentContainer = element.querySelector('.diff-content-container');
let actions = heading.querySelector('.diff-actions');
let collapseButton = button('Collapse', 'Collapse this file');
let parentSection = contentContainer.closest('section.commentable-diff');
collapseButton.onclick = () => onCollapse(contentContainer, collapseButton, heading, parentSection);
actions.prepend(collapseButton);
// Automatically collapse all deleted and renamed files
if (isDeletedFile(element) || isRenamedFile(element)) {
collapseContentContainer(contentContainer, collapseButton, heading, parentSection);
}
}
function init (diffContainers) {
for (let diffContainer of diffContainers) {
initializeDiffContainer(diffContainer);
}
console.log('Loaded Bitbucket PR File Collapse');
}
var loadInterval = setInterval(() => {
let diffContainers = document.getElementsByClassName('diff-container');
if (diffContainers.length > 0) {
clearInterval(loadInterval);
init(diffContainers);
}
}, 300);
}()));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment