// ==UserScript== // @name TFS Helper // @namespace http://jonas.ninja // @version 1.9.4 // @description Adds styles and moves things around so that oft-used functions are easier // @author @_jnblog // @match http://*/tfs/DefaultCollection/*/_backlogs* // @match http://*/tfs/DefaultCollection/*/_versionControl* // @match http://*/tfs/DefaultCollection/*/_workitems* // @grant GM_addStyle // @grant GM_setClipboard // @downloadURL none // ==/UserScript== /* jshint -W097 */ /* global GM_addStyle */ /* jshint asi: true, multistr: true */ var $ = unsafeWindow.jQuery; var topClass = "makeTfsNotAwful" var cursorUrl = 'url(data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTYuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjI0cHgiIGhlaWdodD0iMjRweCIgdmlld0JveD0iMCAwIDQxNS41ODIgNDE1LjU4MiIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNDE1LjU4MiA0MTUuNTgyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxnPgoJPHBhdGggZD0iTTQxMS40Nyw5Ni40MjZsLTQ2LjMxOS00Ni4zMmMtNS40ODItNS40ODItMTQuMzcxLTUuNDgyLTE5Ljg1MywwTDE1Mi4zNDgsMjQzLjA1OGwtODIuMDY2LTgyLjA2NCAgIGMtNS40OC01LjQ4Mi0xNC4zNy01LjQ4Mi0xOS44NTEsMGwtNDYuMzE5LDQ2LjMyYy01LjQ4Miw1LjQ4MS01LjQ4MiwxNC4zNywwLDE5Ljg1MmwxMzguMzExLDEzOC4zMSAgIGMyLjc0MSwyLjc0Miw2LjMzNCw0LjExMiw5LjkyNiw0LjExMmMzLjU5MywwLDcuMTg2LTEuMzcsOS45MjYtNC4xMTJMNDExLjQ3LDExNi4yNzdjMi42MzMtMi42MzIsNC4xMTEtNi4yMDMsNC4xMTEtOS45MjUgICBDNDE1LjU4MiwxMDIuNjI4LDQxNC4xMDMsOTkuMDU5LDQxMS40Nyw5Ni40MjZ6IiBmaWxsPSIjMmQ5ZTFlIi8+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPC9zdmc+Cg==), auto !important' $('body').addClass(topClass) waitForKeyElements("div.tab-page[rawtitle=Links]", doEverything, false) waitForKeyElements(".workitem-info-bar > .info-text-wrapper", addTaskIdCopyUtilities, false) $(document).on('click', '.ijg-js-copyButton', copy) function doEverything(linksPane) { if ($(linksPane).data('moved')) { return } showLinksPane(linksPane) stackAllTabs($(linksPane)) addBlockedButton(linksPane) window.setTimeout(function() { addTaskIdCopyUtilities(linksPane) changeDialogBorderColor(linksPane) }, 250) refreshNowAndLater(); } function showLinksPane(linksPane) { $(linksPane).data('moved', true) .addClass('linksPanel') .prepend($("

").addClass('linksPanelHeader') .text($(linksPane).attr('rawtitle'))) var link = $('a[rawtitle=Links]') link.closest('td').parent().closest('td').prev().css({'width': '35%' /*, 'padding-right': '12px'*/}) link.closest('td').prepend(linksPane) link.parent().remove() } function changeDialogBorderColor(linksPane) { // depending on the type of this work item, color the border differently var dialog = $(linksPane).closest('.workitem-dialog') var caption = dialog.find('a.caption').text() if (caption.indexOf('Product Backlog Item ') !== -1) { dialog.css('border-color', '#009CCC') // blue } else if (caption.indexOf('Bug ') !== -1) { dialog.css('border-color', '#CC293D') // red } else if (caption.indexOf('Feature ') !== -1) { dialog.css('border-color', '#773B93') // purple } else { // Task dialog.css('border-color', '#E0C252') // yellow } } function stackAllTabs($linksPane) { if (Math.max(window.innerWidth, document.documentElement.clientWidth) >= 1600) { // not stackable } else { // stackable var column2 = $linksPane.closest('table.content').parent('.column') var column1 = column2.prev() column2.add(column1).css({width: '100%', display: 'block'}) } fillVerticalHeight($linksPane) } function fillVerticalHeight($linksPane) { var column2 = $linksPane.closest('table.content').parent('.column') var column1 = column2.prev() var modalRect = $linksPane.closest('.work-item-view')[0].getBoundingClientRect() var editorContainer = column1.find('.richeditor-editarea') if (Math.max(window.innerWidth, document.documentElement.clientWidth) >= 1600) { // not stackable var editorRect = editorContainer[0].getBoundingClientRect() var newheight = modalRect.bottom - editorRect.bottom + editorRect.height - 10 var col2height = column2.height() - 58 editorContainer.css('min-height', Math.max(newheight, col2height)) .children('iframe').css('height', Math.max(newheight, col2height)) } else { // stackable var contentHeight = $linksPane.closest('.work-item-view').children('.witform-layout')[0].getBoundingClientRect().bottom var newHeight = editorContainer.height() + modalRect.bottom - contentHeight - 8 editorContainer/*.css('min-height', Math.max(editorContainer.height(), newHeight))*/ .children('iframe').css('height', Math.max(editorContainer.height(), newHeight)) } } function addTaskIdCopyUtilities() { $('.workitem-info-bar').find('.info-text-wrapper').each(function(idx, header) { var $header = $(header) if ($header.hasClass('ijg-isProcessed')) { return } $header.addClass('ijg-isProcessed') var id = $header.find('a.caption').text().match(/\d+/)[0] var url = $header.find('a.caption').prop('href') var formattedUrl = '*' + $header.find('.info-text').text() + '*\n' + url var message = makeMessage($header) var $container = $('
') var button = $('