Showing posts with label GreaseMonkey. Show all posts
Showing posts with label GreaseMonkey. Show all posts

Thursday, April 24, 2014

Hide Done Column On TFS Web Portal Task Boards

Working with TFS's kanbon board layout can be difficult as the number of tasks grow and the number of tasks in your done column ever increase. If the done column is hidden, it becomes easier to scroll to find things that are still in play. Below is a script that I use to accomplish that.

This script handles custom setups where the Done column is not in it's default location.
// ==UserScript==
// @name        TFS Boards Hide Done Column
// @namespace   net.intellectualponderings.TFSBoardsHideDoneColumn
// @include     http://*:8080/tfs/*/_boards*
// @require     http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js
// @version     1
// @grant       GM_addStyle
// @grant       unsafeWindow
// ==/UserScript==

// Default easy method, doesn't work on customized layouts.
//GM_addStyle('#taskboard-table_s3, td[axis="taskboard-table_s3"] { display: none ! important; }');

var ob = (function () {
    var MutationObserver = window.MutationObserver || window.WebKitMutationObserver,
    eventListenerSupported = window.addEventListener;
    return function (obj, callback) {
        if (MutationObserver) {
            var obs = new MutationObserver(function (mutations, observer) {
                if (mutations[0].addedNodes.length || mutations[0].removedNodes.length)
                callback();
            });
            obs.observe(obj, {
                childList: true,
                subtree: true
            });
        } else if (eventListenerSupported) {
            obj.addEventListener('DOMNodeInserted', callback, false);
            obj.addEventListener('DOMNodeRemoved', callback, false);
        }
    }
}) ();
ob(document.getElementById('taskboard'), function () {
    var dth = $('.taskboard-row th:contains("Done")');
    if (dth) {
        var col = dth[0].id;
        // Hide the column
        GM_addStyle('#' + col + ', td[axis="' + col + '"] { display: none ! important; }');
        var numColumns = $('th.taskboard-cell:not(.taskboard-parent):visible').length
        if (numColumns > 0) {
            var newColumnWidth = 100 / numColumns;
            GM_addStyle('th.taskboard-cell:not(.taskboard-parent) { width: ' + newColumnWidth + '% !important; }');
        }
    }
});

Tuesday, September 24, 2013

Trello Board Bing Wallpaper GreaseMonkey UserScript

I occasionally use Trello for maintaining tasks for projects. It helps me stay on task and estimate completion times better. The interface makes managing/creating/completing tasks very easy. It is a breath of fresh air for task management.

I thought it would be cool to see a different background everyday. So decided to use the Bing wallpaper rss feed to get me an amazing image every day.

The GreaseMonkey script below works in Firefox. I have tested it in Chrome (via TamperMonkey) and there are a couple issues. I will try to resolve them and update it here.

// ==UserScript==
// @name        Trello Board Canvas Bing Image
// @namespace   net.intellectualponderings.TrelloBoardCanvas
// @require     http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js
// @grant       GM_getValue
// @grant       GM_setValue
// @grant       GM_log
// @grant       GM_xmlhttpRequest
// @grant       unsafeWindow
// @include     https://trello.com/b/*
// @version     1
// ==/UserScript==

GM_xmlhttpRequest({
    url: "http://feeds.feedburner.com/bingimages",
    dataType: "xml",
    //data: "",
    //type: "GET",
    method: "GET",
    //success: function (data){
    onload: function (responseObject){
        var data = responseObject.responseText;
        GM_log(data);
        var enclosures = $(data).find("enclosure"), // /rss/channel/item/enclosure[url]
            imgurl = $(enclosures[0]).attr('url'); //alert(imgurl);
        $(".board-canvas").css({ 
            'background': 'url(' + imgurl.replace("http://", 'https://') + ') no-repeat center center', 
            'background-size': '100%;'});
    },
    //Error: function (XMLHttpRequest, textStatus, errorThrown) {
    onerror: function () {
      // Same code as in my question...
    }
});

Tuesday, August 14, 2012

Blogger Template Edit HTML Font Fixup

On occasion I update the HTML of my blog using bloggers built in editor and it displays using something resembling Times New Roman. It is a terrible font to view code with. I tried to see what errors were occurring and FireBug didn't reveal anything. After some digging, I openned Venkman and discovered this little gem:
Error: downloadable font: download not allowed (font-family: "Open Sans" style:normal weight:normal stretch:normal src index:1): content blocked
source: http://themes.googleusercontent.com/static/fonts/opensans/v5/u-WUoqrET9fUeobQW7jkRT8E0i7KZn-EPnyo3HZu7kw.woff
Source Code:
@font-face {   font-family: "Open Sans";   font-style: normal;   font-weight: normal;   src: local("Open Sans"), url("//themes.googleusercontent.com/static/fonts/opensans/v5/u-WUoqrET9fUeobQW7jkRT8E0i7KZn-EPnyo3HZu7kw.woff") format("woff"); }
I felt like i was hot on the trail. After a while googling and not finding any good way to fix it, I created the following GreaseMonkey script.
// ==UserScript==
// @name        Blogger Template Edit HTML Fixup
// @description Script that fixes the HTML template editor dialog's text area.  monospace font unavailable, defaulting to consolas.  Firefox gives me: Error: downloadable font: download not allowed (font-family: "Open Sans" style:normal weight:normal stretch:normal src index:1): content blocked.
// @namespace   net.intellectualponderings.BloggerTemplateEditHTMLFixup
// @include     http://draft.blogger.com/*
// @include     https://draft.blogger.com/*
// @grant       GM_addStyle
// @grant       GM_getValue
// @grant       GM_setValue
// @version     1
// ==/UserScript==

(function () {
  var cssTemplateEditHTMLFixFont = (<>).toString();
  
  //Initial Styles
  GM_addStyle( cssTemplateEditHTMLFixFont );
})();

UPDATE 2012-09-04: Added the @grant statements in the header to make the scripts work with GreaseMonkey 1.0.

Wednesday, June 27, 2012

Google Top Bar Rearrange UserScript for GreaseMonkey

I ran across a script on UserScripts.org called Google topbar. It doesn’t appear to be maintained any longer and doesn’t worked in FireFox 13 (not sure if it didn't work before, but that is what I tested on). So I decided that I would use it as a base for an updated script to make it display the links I most commonly use. 

// ==UserScript==
// @name          Google Top Bar Rearrange
// @namespace     com.blogspot.intellectualponderings.GoogleToolBarRearrange
// @description   Custom Google Links and Order, based on http://userscripts.org/scripts/show/18128
// @include       http://*.google.*/*
// @include       https://*.google.*/*
// ==/UserScript==

(function(undefined) {
  var shared = {
    more: ['Maps', 'Images', 'Play', 'YouTube', 'News', 'Shopping'],
    top: ['Blogger', 'Calendar', 'Reader'],
    topBarList: "//ol[@class='gbtc']",
    topBarNode: "//li[@class='gbt'][a[span[text()='{{0}}']]]",
    moreList: "//ol[@id='gbmm']",
    moreNode: "//li[@class='gbmtc'][a[text()='{{0}}']|text()='{{0}}']",
    nodeLink: "//a"
  };
  
  var node = function(path, text, context) {
    path = (text) ? path.replace(/\{\{0\}\}/g, text) : path;
    context = context || document;
    return document.evaluate(path, context, null, XPathResult.ANY_TYPE,null).iterateNext();
  },
  toMoreMenu = function(text) {
    var tag = node(shared.topBarNode, text);
    if (tag) {
      var more = node(shared.moreList);
      if (more) {
          more.appendChild(tag);
          tag.className = 'gbmtc';
      }
    }
  },
  toTopMenu = function(text) {
    var more = node(shared.moreList),
        tag = node(shared.moreNode, text, more),
        alink, moreli;
    if (tag) {
      var topBar = node(shared.topBarList);
      if (topBar) {
        moreli = topBar.lastChild;
        topBar.appendChild(tag);
        tag.className = "gbt";
        alink = node(shared.nodeLink);
        alink.className = "gbzt";
        if (moreli) {
          topBar.removeChild(moreli);
          topBar.appendChild(moreli);
        }
      }
    }
  };

  if (window.top == window.self) {
      var i;
      for (i = 0; i < shared.more.length; i++) {
        toMoreMenu(shared.more[i]);
      }
      for (i = 0; i < shared.top.length; i++) {
        toTopMenu(shared.top[i]);
      }
  }
})();

And then I decided to change it so that it would use jQuery and be a bit more complete. In fact, I didn't keep much.

// ==UserScript==
// @name          Google Top Bar Rearrange
// @namespace     com.blogspot.intellectualponderings.GoogleToolBarRearrange
// @description   Custom Google Links and Order, based on http://userscripts.org/scripts/show/18128
// @include       http://*.google.*/*
// @include       https://*.google.*/*
// @grant         GM_getValue
// @grant         GM_setValue
// @require       https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js
// ==/UserScript==


(function(undefined) {
  var context = $("#gbz ol.gbtc"),
      more = ['Maps', 'Images', 'Play', 'YouTube', 'News', 'Shopping'],
      top = ['Blogger', 'Calendar', 'Reader'];
      
  var addItem = function(url, text) {
    var item = $("<li />").addClass("gbt").append(
                  $("<a />").attr("href", url).addClass("gbzt").attr("target", "_blank").append(
                    $("<span/>").addClass("gbtb2")
                  ).append(
                      $("<span />").addClass("gbts").html(text)
                  )
                );
        $(context).find("li.gbt:last-child").before(item);
    },
    removeItem = function(text) {
    var link = $(context).find("li.gbt span:contains('" + text + "')").parent(),
        href = link.attr("href");
        link.remove();
        return href;
    },
    moveItemToMore = function(text) {
    if ($(context).find("ol.gbmcc li.gbmtc a:contains('" + text + "')").size() == 0) {
      var url = removeItem(text);
      addMoreItem(url, text);
    }
    },
    addMoreItem = function(url, text) {
    var item = $("<li />").addClass("gbmtc").append(
                  $("<a />").attr("href", url).addClass("gbmt").attr("target", "_blank").html(text));
        $(context).find("ol.gbmcc li.gbmtc:last-child").prev().before(item);
    },    
    removeMoreItem = function(text) {
    var link = $(context).find("ol.gbmcc li.gbmtc a:contains('" + text + "')"),
        href = link.attr("href");
        link.remove();
        return href;
    },
    moveItemToTop = function(text) {    
    if ($(context).find("a span.gbts:contains('" + text + "')").size() == 0) {
      var url = removeMoreItem(text);
      addItem(url, text);
    }
    };
    
  if (window.top == window.self) {
      var i;
      for (i = 0; i < more.length; i++) {
        moveItemToMore(more[i]);
      }
      for (i = 0; i < top.length; i++) {
        moveItemToTop(top[i]);
      }
  }
})();

I am much happier with this one.  Using the DOM XML functions seems so pre-jQuery.

UPDATE 2012-08-29: GreaseMonkey updated and made Google Reader not display feed items. I added some @grant lines in the header and everything works again. My discussion on Google Groups is located here.

// @grant         GM_getValue
// @grant         GM_setValue

Tuesday, January 26, 2010

Google Reader Grease Monkey Script

I was bored one day and decided that I wanted to fix up the Google Reader interface a little bit and this was the result. Sure there are more useful GM scripts, but this is a start.
// ==UserScript==
// @name           Google Reader Fixup
// @namespace      http://intellectualponderings.blogspot.com
// @version        1.0
// @description    Hides the sliding navigation pane.  Hides header below the blog name and the footer bar.  Adds "Info" button next to the blog name to toggle header and footer bar.  
// @include        htt*://www.google.*/reader*
// @include        http://www.google.com/reader/view/*
// ==/UserScript==

var cssHidechromeheader = <><![CDATA[
    #viewer-header, #viewer-footer { display: none; }
    ]]></>.toString();
var cssShowchromeheader = <><![CDATA[
    #viewer-header, #viewer-footer { display: inline; }
    ]]></>.toString();
var cssHideNav= <><![CDATA[
    #chrome-lhn-toggle { display: none; }
    ]]></>.toString();
 
function getElementPosition(element) {
    var pos = {x:0, y:0};
    if (element.offsetParent) {
        while (element.offsetParent) {
            pos.x += element.offsetLeft;
            pos.y += element.offsetTop;
            element = element.offsetParent;
        }
    } else if (element.x) {
        pos.x += element.x;
        pos.y += element.y;
    }
    return pos; 
}

function InfoMouseClick(e) {
    var gei = document.getElementById,
        header = gei('viewer-header'),
        hDisplay = header.style.display,
        footer = gei('viewer-footer'),
        entries = gei('entries'),
        entriesStatus = gei('entries-status');
    if ((hDisplay == "none")||(hDisplay == null)||(hDisplay == "")) {
        header.style.display = footer.style.display = "inline";
        entriesStatus.style.right = "0.5em";
    } else {
        header.style.display = footer.style.display = "none";
    }
    entries.style.height = String(d.documentElement.clientHeight - getElementPosition(entries).y - footer.offsetHeight) + "px";
}

(function () {
    //Initial Styles
    GM_addStyle( cssHidechromeheader );
    GM_addStyle( cssHideNav );
    var chrome = document.getElementById('chrome-header');
    //Button Element
    var buttonStr = " 
 
Info
"; var googbutton=document.createElement('div'); googbutton.className='goog-button-base goog-button-base-outer-box goog-inline-block'; googbutton.style.margin = "0px 0px 0px 6px"; googbutton.innerHTML=buttonStr; chrome.appendChild(googbutton); googbutton.addEventListener('click', InfoMouseClick, false); })();

Saturday, May 23, 2009

GreaseMonkey Daptiv Fix to Allow Multiple Item Popup Windows

I have found that the paradigm that Daptiv uses to display items in a list to be very prohibitive. The biggest issue I have found is that by default (and they offer no way to change the behavior) that they only allow one item window to be open at the same time. I have contacted Daptiv to see if there was a way to change it (there wasn't). So I turned to GreaseMonkey to save the day. Here is the GreaseMonkey script to allow multiple item windows open at the same time.
// ==UserScript==
// @name           Daptiv Change Window Name and Title
// @namespace      http://na04.daptiv.com/global
// @include        http://na04.daptiv.com/global/itembrowser.aspx
// ==/UserScript==

if (window.name == "IB_Grid") {
 window.name = "b"+String(Math.random());
 // Change the title
 var items = document.getElementsByClassName("itembrowser-itemlabel");
 if (items.length > 0) {
  var item = items[0].innerHTML.replace(/^\s+|\s+$/, '');
  document.title = "Item: " + item + " - " + document.title;
 }
}

I added a bonus to the script in that it will change the title of the window to include the "Name" of the item you clicked on.

This in addition to the speed improvements in FireFox 3 (I can't wait for 3.5 to come out) make Daptiv actually usable. There are other improvements I would like to see, but I will leave fixing those things to another time.