NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Trello Hide Lists // @namespace http://trello.com/* // @description Trello Hide Lists (without having to archive) // @include /^https?://trello\.com/.*$/ // @grant none // @version 1.0.1 // @license GPL-3.0 // Additional credits to : // * https://github.com/shesek/trello-hide-lists // * FooBarWidget @ https://github.com/shesek/trello-hide-lists/issues/1#issuecomment-199693936 // // ==/UserScript== (function () { function AddMinimizeButtons() { var closeList = function (list) { list.style.transition = 'max-height 0.2s ease-in-out, max-width .2s 0.21s ease-in-out'; list.style.maxHeight = '30px'; }; var openList = function (list) { list.style.transition = 'max-height .2s 0.2s ease-in-out, max-width .1s ease-in-out'; list.style.overflow = 'hidden'; list.style.maxHeight = '100%'; }; // Get all of the lists for the current board var lists = document.getElementById('board').querySelectorAll('div.list'); // Add the show/hide selectors to each list (and update the default show/hide state) for (var i = 0; i < lists.length; i++) { (function () { var list = lists[i]; // Close button element and a container Div for it var close = document.createElement('a'); var closeDiv = document.createElement('div'); openList(list); close.setAttribute('href', '#'); close.setAttribute('class', 'toggle-list-opened'); // Use a Triangle HTML character for the close button close.innerHTML = '▾'; close.style.textDecoration = 'none'; close.style.opacity = '0.40'; close.style.fontSize = '15pt'; // Add the Close button to a container Div and set the position closeDiv.appendChild(close); closeDiv.style.position = 'absolute'; closeDiv.style.top = '6px'; // Locate the show/hide button left of the list header name text field var attachElements = list.getElementsByClassName('list-header-name'); // Attach the show/hide click handler if (attachElements.length >=0) { // Bump the list header name to the right so there is room for the Close button // then insert the button before it attachElements[0].style.paddingLeft = '20px'; attachElements[0].parentNode.insertBefore(closeDiv, attachElements[0]); // TODO : convert to non-inline toggle function close.addEventListener('click', function (e) { e.preventDefault(); if (close.getAttribute('class') == 'toggle-list-opened') { closeList(list); close.setAttribute('class', 'toggle-list-closed'); close.innerHTML = '▸'; } else { openList(list); close.setAttribute('class', 'toggle-list-opened'); close.innerHTML = '▾'; } }); // TODO : Move this to a function // Determine default hide/show state based on presence of "--" var headingElements = list.getElementsByClassName('list-header-name'); if (headingElements.length >=0) { var collapseTokenMatch = /.*-.*/i.exec(headingElements[0].value); // If a match was found then collapse the list by default if (collapseTokenMatch != null) { // TODO : consolidate to function closeList(list); close.setAttribute('class', 'toggle-list-closed'); close.innerHTML = '▸'; } } } })(); } } // // Toggle showing/hiding all boards with "--' in the name // function toggleAutoLists(e) { e.preventDefault(); // Get all of the lists for the current board var lists = document.getElementById('board').querySelectorAll('div.list'); for (var i = 0; i < lists.length; i++) { // Can't simplify this with a [value$="--"] selector since textareas don't support it // Check the heading textarea for each board, toggle it based on presence of "--" var headingElements = lists[i].getElementsByClassName('list-header-name'); if (headingElements.length >=0) { // If the list header name has "--" present then click it's show/hide button var collapseTokenMatch = /.*\-\-.*/i.exec(headingElements[0].value); if (collapseTokenMatch != null) { var closeButtons = lists[i].querySelectorAll('[class*=toggle-list]'); if (closeButtons.length >=0) { // Self click the toggle button closeButtons[0].click(); } } } } } // // Add a button near the top to toggle showing/hiding all boards with "--' in the name // function AddToggleAutoButton() { if (!document.getElementById('toggleAutoAnchorButton')) { var toggleAutoAnchor = document.createElement('a'); toggleAutoAnchor.setAttribute( 'href', '#'); toggleAutoAnchor.setAttribute( 'class', 'toggle-list-close-hide-button board-header-btn'); toggleAutoAnchor.innerHTML = '-- / ++'; toggleAutoAnchor.style.paddingLeft = '10px'; toggleAutoAnchor.style.paddingRight = '20px'; // Add the button right after (to the right) of the board permission selector document.getElementById('permission-level').parentNode.appendChild(toggleAutoAnchor); // When clicked : trigger open or close event on all of the boards that match the "--" toggleAutoAnchor.addEventListener('click', toggleAutoLists ); toggleAutoAnchor.setAttribute("id", "toggleAutoAnchorButton"); } }; // // Util : Installs a mutation observer callback for nodes matching the given css selector // function registerMutationObserver(selectorCriteria, monitorSubtree, callbackFunction) { // Cross browser mutation observer support var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; // Find the requested DOM nodes var targetNodeList = document.querySelectorAll(selectorCriteria); // Make sure the required elements were found, otherwise don't install the observer if ((targetNodeList != null) && (MutationObserver != null)) { // Create an observer and callback var observer = new MutationObserver( callbackFunction ); // Start observing the target element(s) for(var i = 0; i < targetNodeList.length; ++i) { observer.observe(targetNodeList[i], { attributes: true, childList: true, characterData: true, subtree: monitorSubtree, characterDataOldValue: true }); } } } // // Set a timer to wait until the board is loaded before running the script // Use this plus the mutation observer instead of purely the load event // since the load event misses page loads and board changes sometimes // function checkReady() { if (document.getElementById('board')) { AddMinimizeButtons(); AddToggleAutoButton(); } else { setTimeout(checkReady, 100); } } // // Once logged in, the actively displayed board can change without a page load. // Register a hook to trigger on changes to the "content" div which is the container // for the boards, then re-apply the script as needed // function installBoardChangeHook() { // TODO : debug visual hook hinting // if (document.getElementById('content')) // document.getElementById('content').style.border = "1px dashed red"; // Subtree monitoring disabled to avoid excessive triggering registerMutationObserver('[id=content]', false, function(mutations) { setTimeout(checkReady, 100); } ); } // // Apply the script to the newly loaded board and try // to capture any future non-page-reload board changes // function init() { setTimeout(checkReady, 100); installBoardChangeHook(); } // TODO : Fix Me // Firefox 57 no longer supports window.addEventListener() // For the time being work around by calling init() directly. // That won't capture page event loads though. A new listener/observer // may be required. // // Add an event to start the script once the page has loaded // window.addEventListener ("load", init, false); init(); })();