formats

My "GMail Multiple From Address Extensions" Greasemonkey Script Goes Over 1,000 Downloads

At the request of another mostly anonymous Internet user I spent some time and knocked out a simple little addon for GMail that I oh-so-creatively named “GMail Multiple From Address Extensions“.  While the title may not be catchy, “wmblewett”‘s idea certainly seems to be.  In the first two days the script was widely available it has made a small splash and garnered over 1,000 downloads.

The script itself is very simple.  For users who have multiple email accounts set up in their GMail account, when you go to send a message it pops up a warning telling you which address you’re sending from and gives you the option of canceling or continuing.  You can visit the script’s homepage at UserScripts.org to install it or to see any potential future enhancements.

As these types of projects generally do, this one wound up being a really good learning experience for me, as chronicled in this earlier post.  So, thanks “wmblewett”.  I hope you enjoy the script as much as I enjoyed the experience writing it.

Now, back to work on those extended features that have been requested.

 
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
9 Comments  comments 
formats

Using the GMail Greasemonkey API and Succeeding: My Workaround

The new GMail interface is a giant mass of frames and obfuscated JavaScript.  Knowing this, Google released an API for Greasemonkey authors to use, called the GmailGreasemonkey10API.  Isn’t that nice of them?

Well, don’t get too excited.  First, it is fairly limited in what it can do.  Its greatest advantage for you is that it can give you handles to the various frames that it loads things into.  It does also give you some convenience methods for adding elements to the navigation box as well as other methods.

For performance reasons Google doesn’t load the API on every call to GMail.  It is only loaded if a script asks the API to initialize through a call to gmonkey.load.  This function takes a callback function as the first parameter which according to Google will be called when the API has successfully loaded.  My mileage has varied.  Greatly.

Even testing their ultra-simple example script I had serious issues with it not running much more often than it did run.  My own scripts would usually bomb at the same rate.

The issues were generally something to the effect of “vN is undefined” (calls to getCanvasElement, an undocumented function) or “a is undefined” (calls to registerViewChangeCallback).  Pretty much any short alpha-numeric combination coming up as “is undefined” is likely caused by this issue.

After much trial and error I seem to have found a viable work-around to the issue.  Instead of immediately making calls to the API functions when the load function completes, have it set a window timeout of 500ms.  This seems to resolve nearly all of the problems, though you will still occasionally get a hiccup.  For those occasions, simply catch the error and reload the page.  Is it an ugly hack?  Yes.  Does it work?  Seems to.

Here’s a quick example:

?View Code JAVASCRIPT
var gmail = null;
 
window.addEventListener('load', function() {
    if (unsafeWindow.gmonkey) {
        unsafeWindow.gmonkey.load('1.0', init);
    }
}, true);
 
function getCanvas() {
    try {
        gmail.getCanvasElement().addEventListener('click', function() { GM_log('Worked'); }, true);
        // Could also be a call like:
        gmail.registerViewChangeCallback(function() { GM_log('Also works'); });
    }
    catch (ex) {
        GM_log('3:'+ex.message);
        // This seems like a brutal hack, however the call to getCanvasElement
        // will sometimes fail when the page loads.  If that happens this seems
        // to resolve it eventually.
        window.location.reload();
    }
}
 
function init(g) {
    try {
        gmail = g;
        // Calls to the gmail API seem to fail far less often if you wait
        // for a bit to actually start using it.
        window.setTimeout(getCanvas, 500);
    }
    catch (ex) {
        GM_log('1:'+ex.message);
    }
}

I used this trick in my GMail Multiple From Address Extensions Greasemonkey script available at Userscripts.org.  I went through several different revisions on that site and probably a dozen more locally before I found this workaround.  So far it seems to work, though I’d love to hear if anyone has a different experience.

I’ve also experienced issues with Google’s scripts not honoring my calls to stopPropagation and preventDefault.  If anyone has any advice there I’m sure we’d all be interested.

 
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
4 Comments  comments 
formats

A Quick Note on Float: Right

Published on November 19, 2008 by in HowTos

Frankly I never thought I’d blog about this, but over the last several days I have had this question posed twice and found this issue in a released product.

When you want to wrap text around an element and position that element on the right, you do the obvious and float that element right using CSS.  Just about everyone gets this.  The problem you’re running into, though is that your floated element is below the text instead of at the top with the text wrapping it.  The solution I see over and over is to use a negative top margin.  Wrong answer.  That won’t hold up as the height of the text changes.  Here’s some example HTML:

<html>
    <head>
        <style type="text/css">
            #wrapper {
                border: 2px solid #000000;
                padding: 5px;
                width: 300px;
            }
            #rightCol {
                background-color: #ffff00;
                float: right;
                width: 200px;
            }
        <style>
    <head>
    <body>
        <div id="wrapper">
            <div>
                <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque pede. Cras et dolor. Nulla lorem felis, euismod eu, adipiscing non, auctor ut, mi. Suspendisse potenti. Phasellus at turpis. Integer augue lorem, rutrum eget, malesuada nec, facilisis eu, dui. Praesent condimentum nunc non ligula. Sed est dolor, luctus nec, accumsan in, accumsan ac, libero. Proin pharetra augue at felis. Etiam et nibh. Praesent lobortis sem consectetuer turpis. Nullam velit eros, dictum imperdiet, pretium in, gravida sit amet, leo. Nulla nisl urna, vehicula et, varius non, sollicitudin non, nisi. Duis commodo lacus vel dolor.</p>
            </div>
            <div id="rightCol"><p>Right Float</p></div>
        </div>
    </body>
</html>

Here’s what this HTML renders as:

This element is incorrectly floated

This element is incorrectly floated

You’ll immediately notice the yellow, floated box is at the bottom of the page.  Here’s the answer to the kicker, the gotcha, the problem people run into.

You have to put the element into the document before the text you want wrapping around it.  This may seem counter-intuitive to some, but trust me on this.  Here’s the HTML:

<html>
    <head>
        <style type="text/css">
            #wrapper {
                border: 2px solid #000000;
                padding: 5px;
                width: 300px;
            }
            #rightCol {
                background-color: #ffff00;
                float: right;
                width: 200px;
            }
        </style>
    </head>
    <body>
        <div id="wrapper">
            <div id="rightCol"><p>Right Float</p></div>
            <div>
                <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque pede. Cras et dolor. Nulla lorem felis, euismod eu, adipiscing non, auctor ut, mi. Suspendisse potenti. Phasellus at turpis. Integer augue lorem, rutrum eget, malesuada nec, facilisis eu, dui. Praesent condimentum nunc non ligula. Sed est dolor, luctus nec, accumsan in, accumsan ac, libero. Proin pharetra augue at felis. Etiam et nibh. Praesent lobortis sem consectetuer turpis. Nullam velit eros, dictum imperdiet, pretium in, gravida sit amet, leo. Nulla nisl urna, vehicula et, varius non, sollicitudin non, nisi. Duis commodo lacus vel dolor.</p>
            </div>
        </div>
    </body>
</html>

…and the associated rendered document:

A properly implemented right float

A properly implemented right float

You’ll immediately see that the floated element is exactly where we intended it to be.  On the top and right.

Curious as to why it does this?  Well, we’re dealing with block level elements here.  Because of that they won’t render inline.  Since they won’t render inline, if the first element isn’t the floated element when it renders it fills the available space, not leaving any room for the next element.  When the floated element is rendered first the second element can be correctly rendered around it.

Happy floating.

 
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
1 Comment  comments 
formats

"Fix" the New Formatting for Nealz Nuze Pages

I frequently read a daily writeup called “Nealz Nuze” on the Internet by talk show host Neal Boortz.  Just this morning they updated the format of the page and I’m not a fan.  To quote Mr. Boortz: “This mess wasn’t our idea. I’m talking about the new format for Nealz Nuze.”  Judging by the comments we aren’t the only two people not in love with the new format.

update: I now have a native Firefox extension that you can download which does the same thing.  Right click and choose “Save Link”, then save it to your computer.  Then drag the file into a Firefox window and allow it to install.  Get it here. You can still use the GreaseMonkey script below if you prefer.

Well, problem solved.  My old friend GreaseMonkey and I got together for a minute and here’s what we came up with:

?View Code JAVASCRIPT
// ==UserScript==
// @name           Nealz Nuze Formatter
// @namespace      eric.biven
// @description    Restores Nealz Nuze to it's previous glory (with improvements).
// @include        http://boortz.com/*
// @include        http://www.boortz.com/*
// ==/UserScript==
 
var listenLive = document.getElementById('streamLink');
listenLive.style.cssFloat = 'right';
listenLive.style.width = '200px';
 
var header = document.getElementById('logoAdContainer');
header.removeChild(header.childNodes[1]);
header.appendChild(listenLive);
 
var ads = document.getElementById('rightColumnCell');
ads.parentNode.removeChild(ads);
 
var head = document.getElementsByTagName('head')[0];
if (head) {
    style = document.createElement('style');
    style.type = 'text/css';
    style.appendChild(document.createTextNode('.hrDivider, .blogFooter, .blogEntryByline { display: none; }'));
    style.appendChild(document.createTextNode('.blogEntry { padding-bottom:20px; }'));
    style.appendChild(document.createTextNode('.storyhed { padding-bottom:10px; display:block; }'));
    style.appendChild(document.createTextNode('.blogEntryBody &gt; table { margin:10px 0px 10px 20px; }'));
    style.appendChild(document.createTextNode('#pageWrapper, #centerColumn { width:auto; }'));
    style.appendChild(document.createTextNode('.pageContainer { margin:0px 10px 0px 10px; }'));
 
    head.appendChild(style);
}

This script is available for download from UserScripts.org at http://userscripts.org/scripts/show/36900.  It will return the page to a look that is more familiar to readers.  I’ve taken the liberty of adding a little more white space around some items as well.

New Layout

New Layout

If you aren’t familiar with GreaseMonkey, here’s a quick rundown.  GreaseMonkey is an addon for the Firefox web browser that lets you run scripts against pages and change how they look and/or behave.  In this case I’m removing ads, then changing the style of some elements.  You can install GreaseMonkey from here:

https://addons.mozilla.org/en-US/firefox/addon/748

Once you’ve installed GreaseMonkey and restarted Firefox, make sure the little monkey icon down at the bottom of your Firefox window is brown.  If he’s grey, click on him (this enables GreaseMonkey).  Then click this link and allow the script to install:

http://userscripts.org/scripts/source/36900.user.js

Once the script is installed you’ll be able to view Nealz Nuze in all of its former glory.  Enjoy.

Read more about this at:

http://boortz.com/nealz_nuze/2008/11/dont-blame-me-nor-the-web-wenc.html

update: Now corrects their page width so that the text is always the width of your browser.

update: It should now work on Neal’s entire site and it moves the listen live link into the header of the page.

 
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
11 Comments  comments 
formats

A Free Idea for the Folks at Pandora

I would like to see Pandora integrated with a lyrics engine.  Most people are probably going to think of some link in the user interface where they can click it and see the lyrics for the song.  Not me.  I want something much bigger.

I want the ability to exclude a song based on a word in its lyrics, preferably by frequency and/or total count.  I would love to be able to say, for instance, “don’t play any song where the word California is used more than twice”.  When I brought this idea up with a coworker he mentioned it would be great to only hear songs with the word “shotgun” in them.  So we’ll need this feature to allow for inclusion/exclusion of key phrases entered by the user.

You guys over at Pandora get to work on this for me please.  In the mean time I’m going to check into body armor in case my coworker has a particularly bad day…

 
Tags:
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
No Comments  comments 
formats

They Call it 'Repacking a Heavy Bag' for a Reason

I own an 80lb heavy bag that I use for exercise.  I got it used, and just hung it up and began banging away.  I love the workout, and the stress relief helps as well.

About a year has gone by, and the filling has begun to settle even more.  It was to the point where the top was flimsy and the bottom was hard as a rock.  So, time to refill  the bag.

What I can tell you after finally getting it finished (on my second try) is this: They call it repacking a heavy bag for a reason.  If you just fill the heavy bag you’ll never get enough material in there to make it the right density.  You have to actually pack the material.  I started by putting about one foot of rags back into the bottom of the bag, then I began smashing the material from the top down into the sides, spinning the bag as I went.  I continued this process until I couldn’t get any more material down the sides, then I added about six inches of material and repeated the process until it was full.

The bag isn’t perfectly smooth on the sides, but it’s pretty good and there aren’t any hard spots.  I got all but a couple of handfulls of the material back in the bag, so the weight should still be good.  The consistency when punching the bag is uniform from top to bottom, which was really what I was after.

Like so many other things in life, though, now that I’ve repacked it I have a greater feeling of ownership.  I guess you could say we spent some quality time together.  Time where it wasn’t just me dishing out a beating, but time where I was working on maintaining my equipment.  I would also say repacking the bag is not a bad low-intensity workout.  I can certainly feel it in my hands and forearms.

 
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
2 Comments  comments 
formats

Kubuntu 8.10 is Official: Color Me "Meh"

I don’t personally know many people who are bigger fans or proponents of KDE than I am.  I think it’s fantastic.  I love just about everything about it.

Except KDE 4.  It’s just not that exciting to me.  The new features aren’t that important to me and as a whole the desktop performs rather pitifully on Kubuntu 8.10.  I’m running an Intel Core 2 Duo with 2 Gigs of RAM and a nVidia 8600M GT with 256MB of RAM.  If that’s not enough of a system then perhaps we need to rename this release to “Kubuntu 8.10, Vista”.  On a side note, this computer runs Vista without a hitch.

The culprit could be just about any combination of lots of things.  KDE 4 may not be fully baked.  Kubuntu may not have implemented it well.  It may not deal well with Compiz.  However, it doesn’t really matter to me since there isn’t a compelling feature that would make me want to find out so that I can move.

Frankly 8.10 reminds me of 7.04.  Much ado about nothing except moving back to the previous release.  If they follow that same trend, however, 9.04 will be as fantastic as 7.10 was.

Thankfully for me (and the many others I suspect share my opinion) 8.04 was a long term support (LTS) release, so we have another year to hope the bugs get ironed out of KDE 4.

PS: Am I the only one who things the new desktop background looks like a bunch of hair under a microscope?

 
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
2 Comments  comments 
formats

Getting Katapult to Reindex Your Installed Programs

Published on October 26, 2008 by in HowTos

If you use Katapult (which is a fantastic feature of KDE) then you may wonder how to get it to find newly installed software in Kubuntu.  Simply press Alt-Space to pull up the Katapult screen and imediately press Ctrl-C to launch the config menu.  Simply exit the config menu and your Katapult will reindex it’s catalog.  Unless it crashes, at which time you’ll simply need to re-launch it from KMenu -> Utilities -> Katapult.

 
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
No Comments  comments 
formats

Having Problems With Pandora Not Playing Whole Songs On Vista?

Published on October 10, 2008 by in HowTos

I’ve been having problems using Pandora Internet radio on Windows Vista.  Frequently a song will begin playing, then after ten to twenty seconds it will stop and skip to the next track.  I started my troubleshooting by watching the HTTP traffic using HttpFox and discovered there were several transmission errors (including NS_ERROR_FAILURE) communicating to the servers that deliver the audio files.  My next step was to look at the TCP traffic with Wireshark, and I noticed a lot of TCP retransmits and aborts.

So I did some reading and found out that Vista uses TCP window auto-scaling.  While in theory this shouldn’t cause issues, I disabled it just to see using the netsh command:

netsh interface tcp set global autotuninglevel=disabled

Sure enough, Pandora began behaving correctly.  Now, I’m far from a networking guru, so if you have any information as to why this helps I’d be thrilled to know.  For now I’m just happy that I’m hearing the whole song again.

 
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
4 Comments  comments 
formats

Far Future Expiration and File Versioning: Change the File Name or Add a Query String?

If you’re wondering what far future expiration is then odds are you haven’t spent much time looking into web delivery best practices.  Take a moment and read up.  I promise it won’t hurt and it will probably do you a lot of good.

We’ll use this blog as an example.  It has a total of eight images that may be loaded, three of which are external to this server (related to the PayPal ‘Donate’ button [please use it] and the Add-To-Any button).  The eight images comprise about 6KB worth of the page size with 2KB coming from the external ‘Donate’ button.  Then there are the stylesheets, between two and four (one extra to fix IE problems, one more if your version of IE is less than 7).  Those are about 16KB, but are gzipped to only require 3KB of bandwidth.  Then there are my two JavaScript files totaling 65KB uncompressed, 21KB gzipped.  All of these items need only be downloaded once.

So, of the total page size of 156KB (56KB compressed) for this article, around half won’t change with any regularity and falls within my control.  By setting a far future expires header on those items your browser won’t feel the need to check and see if there is a new version the next time you visit this site, saving both of us TCP connections.  When you first visited this site it told your browser those files don’t expire for ten years.

Sounds great, but what if I want to change, say, my CSS file?  Well in that case I need to change the file name so that your browser doesn’t think it already has a copy and will go ahead and download the changes.  This is generally accomplished in one of two ways: Change the filename or add a query string to the original filename.  But which is better?

Adding a query string to the existing filename is easy.  Especially in the case of a CSS file that is included once in a header file, such as this blog.  If you view the source you’ll notice I use this method.

<link rel="stylesheet" type="text/css" href="http://eric.biven.us/wp-content/themes/eric2/style.css?v3" />

Notice that “?3″ at the end?  That fools your browser into asking for the file again and my server just ignores that part of the request.  Now when you get this new version your browser again gets a response from my server saying “this file doesn’t expire for ten years”.

With that said, I prefer to change the filename.  Using a query string has the drawback that some internet caching proxies don’t cache files with query strings by default and others are configured not to by their administrators.  Since my goal is to reduce bandwidth it only makes sense that I would want to offload as much as possible onto other people’s caches.

So why not do that with my CSS file here?  Well, in the case of the WordPress stylesheet I haven’t found a good way to use a file with a different name.  According to the WordPress Codex the stylesheet_url parameter for the bloginfo template tag is hard coded to output a link to a file named “style.css”.  That means that adding the query string parameter is far easier.  Sometimes the path of least resistance is good, especially when it lets me go to bed earlier.

 
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
No Comments  comments 
© All Content Copyright Eric Biven
credit