<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>techno.blog(&#34;Dion&#34;) &#187; greasemonkey</title>
	<atom:link href="http://almaer.com/blog/tag/greasemonkey/feed" rel="self" type="application/rss+xml" />
	<link>http://almaer.com/blog</link>
	<description>blogging about life, the universe, and everything tech</description>
	<lastBuildDate>Tue, 03 Jan 2012 19:27:51 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Endpoint Resolver: Getting tinyurl out of the Twitter stream</title>
		<link>http://almaer.com/blog/endpoint-resolver-getting-tinyurl-out-of-the-twitter-stream</link>
		<comments>http://almaer.com/blog/endpoint-resolver-getting-tinyurl-out-of-the-twitter-stream#comments</comments>
		<pubDate>Sun, 22 Jun 2008 14:42:44 +0000</pubDate>
		<dc:creator>dion</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Web Services]]></category>
		<category><![CDATA[endpoint]]></category>
		<category><![CDATA[greasemonkey]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://almaer.com/blog/endpoint-resolver-getting-tinyurl-out-of-the-twitter-stream</guid>
		<description><![CDATA[Sometimes you can get in the zone just enough to be productive on a plane. On my flight to Mexico City yesterday, I created Endpoint a project that contains a server proxy, JavaScript client, and Greasemonkey Script with a mission. The mission is to take a URL, work out if it is a redirect (via [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes you can get in the zone just enough to be productive on a plane. On my flight to Mexico City yesterday, I created <a href="http://almaer.com/endpoint">Endpoint</a> a project that contains a <a href="http://endpoint-resolver.googlecode.com/svn/trunk/resolver.php">server proxy</a>, <a href="http://almaer.com/endpoint/twitter-resolveurl.user.js">JavaScript client</a>, and <a href="http://almaer.com/endpoint/twitter-resolveurl.user.js">Greasemonkey Script</a> with a mission. The mission is to take a URL, work out if it is a redirect (via a <code>Location:</code> header), and then return the final endpoint for it.</p>
<p><b>Why did I do this?</b></p>
<p>I was brainstorming functionality for a Twitter client with James Strachan (he is working on <a href="http://gtwit.com/">gtwit</a>) and we talked about how annoying tinyurl / is.gd / snurl / you name it URLs are. They don&#8217;t tell you where you are going, and you could get Rick Rolled (if you are lucky) or much much worse.</p>
<p>So, I wanted to create a library, and one client (Greasemonkey) to test it out. Then anyone else could use it too to resolve directly from their Web pages.</p>
<p><b>How does it work</b></p>
<p>You load up the JavaScript via <code>script src</code> and then you can call resolve, passing the URL and a callback that will get the result. A few examples:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Simple version</span>
Endpoint.<span style="color: #660066;">resolve</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'http://snurl.com/2luj3'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>url<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
  <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>url<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Using the original URL to work out if it has changed</span>
Endpoint.<span style="color: #660066;">resolve</span><span style="color: #009900;">&#40;</span>
  document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'testurl'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">value</span><span style="color: #339933;">,</span> 
  <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>url<span style="color: #339933;">,</span> orig<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
    <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>url<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
    <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>Endpoint.<span style="color: #660066;">isRedirecting</span><span style="color: #009900;">&#40;</span>url<span style="color: #339933;">,</span> orig<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// How it is used in the Twitter Endpoint Resolver</span>
Endpoint.<span style="color: #660066;">resolve</span><span style="color: #009900;">&#40;</span>url<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>resulturl<span style="color: #339933;">,</span> originalurl<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>Endpoint.<span style="color: #660066;">isRedirecting</span><span style="color: #009900;">&#40;</span>resulturl<span style="color: #339933;">,</span> originalurl<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">return</span><span style="color: #339933;">;</span>
&nbsp;
  newtext <span style="color: #339933;">=</span> newtext.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span>originalurl<span style="color: #339933;">,</span> resulturl<span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;g&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  jQuery<span style="color: #009900;">&#40;</span>el<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">html</span><span style="color: #009900;">&#40;</span>newtext<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Under the hood, a bunch of stuff is happening. I would love to be able to just use <code>XMLHttpRequest</code> to dynamically hit the URL and look at the headers, but the same-origin policy stops me.</p>
<p>This is why I have the server proxy, which returns a JSONP callback.</p>
<p>When you call <code>resolve(url, callback)</code> the <code>script</code> tag is created on the fly and added to the DOM. The callback function is all handled to allow multiple calls, and then the chain unravels.</p>
<p>Here you can see it all in action, showing how my Twitter stream will go through and the URLs will dynamically change from their tinyurl versions to whereyouaregoing.com:</p>
<p><object width="425" height="350"><param name="movie" value="http://www.youtube.com/v/fxuUNEhOQwk"></param><embed src="http://www.youtube.com/v/fxuUNEhOQwk" type="application/x-shockwave-flash" width="425" height="350"></embed></object></p>
<p>I wanted to use App Engine to host the server proxy, but unfortunately I can&#8217;t work out how to do that yet. You have access to the <a href="http://code.google.com/appengine/docs/urlfetch/">URLFetch</a> API to access resources from App Engine. Unfortunately for me, one of the features is that it understands redirects and just goes on through to the full resource itself, with no way to get the endpoint from the <code>headers</code> in the response.</p>
<p>It was also interesting to read <a href="http://www.techcrunch.com/2008/06/21/surviving-the-net/">Steve Gilmor talk about these services</a> all be it in a post that is hard to actually understand ;)</p>
<p>Also, Simon Willison just put up a simple service on App Engine, <a href="http://json-time.appspot.com/">json-time</a>, that &#8220;exposes Python’s pytz timezone library over JSON.&#8221; I think that we will see a lot of these types of mini-Web services hosted on App Engine. Taking Python utility and making services from its goodness is an obvious choice.</p>
]]></content:encoded>
			<wfw:commentRss>http://almaer.com/blog/endpoint-resolver-getting-tinyurl-out-of-the-twitter-stream/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Gmail Greasemonkey Macros: Back, and Gmail even has support!</title>
		<link>http://almaer.com/blog/gmail-greasemonkey-macros-back-and-gmail-even-has-support</link>
		<comments>http://almaer.com/blog/gmail-greasemonkey-macros-back-and-gmail-even-has-support#comments</comments>
		<pubDate>Tue, 06 Nov 2007 04:41:50 +0000</pubDate>
		<dc:creator>dion</dc:creator>
				<category><![CDATA[Google]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[gmail]]></category>
		<category><![CDATA[greasemonkey]]></category>

		<guid isPermaLink="false">http://almaer.com/blog/gmail-greasemonkey-macros-back-and-gmail-even-has-support</guid>
		<description><![CDATA[Gmail recently got a JavaScript facelift which has subtle new features. For example, calendar attachments, smart top notices when you are disconnected and how the interface is retrying, and more.
However, most Greasemonkey scripts broke. This is bad news for me, as without Mihai&#8217;s macros script I feel real pain as I try to vi my [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://ajaxian.com/archives/gmail-gets-a-javascript-facelift">Gmail recently got a JavaScript facelift</a> which has subtle new features. For example, calendar attachments, smart top notices when you are disconnected and how the interface is retrying, and more.</p>
<p>However, most Greasemonkey scripts broke. This is bad news for me, as without <a href="http://blog.persistent.info/">Mihai</a>&#8217;s macros script I feel real pain as I try to vi my way around the interface.</p>
<p>The new Gmail interface did add more keyboard shortcuts such as:</p>
<ul>
<li><strong>shift + i</strong>: Mark as read</li>
<li><strong>shift + u</strong>: Mark as unread</li>
<li><strong>shift + 3</strong>: Move to trash (not actually new, but not many people seem to know this one)</li>
<li><strong>shift + 8</strong> and <strong>a</strong>, <strong>n</strong>, <strong>r</strong>, <strong>u</strong>, <strong>s</strong>, <strong>t</strong>: Select all, none, read, unread, starred, unread</li>
</ul>
<p>But, this isn&#8217;t quite enough. Luckily, Mihai has stepped up and <a href="http://blog.persistent.info/2007/11/macros-for-new-version-of-gmail.html">ported over his work</a>.</p>
<p>He has ported over:</p>
<ul>
<li><strong>g:</strong> Go to label</li>
<li><strong>l:</strong> Apply label</li>
<li><strong>b:</strong> Remove label</li>
<li><strong>e:</strong> Archive (regardless of view, unlike &#8220;y&#8221;)</li>
<li><strong>d:</strong> Discard (mark as read and archive)</li>
</ul>
<p>and added:</p>
<ul>
<li><strong>f:</strong> &#8220;Focus&#8221; the current view (only show unread, starred or inbox messages)</li>
</ul>
<p>What is really cool is how Dan Pupius and the team have truly acknowledge the Greasemonkey folk and have given us hooks to help us monkey around with Gmail:</p>
<blockquote><p>
For those of you adventurous enough to look at the script source, you&#8217;ll notice that it uses a gmonkey object that is present on the window, which in turn gets you a gmail object with methods like getNavPaneElement() and getActiveViewType(). What this means is that the version of Gmail, in addition to being faster, also has semi-official support for Greasemonkey scripts. I&#8217;m pretty sure official docs for this API will be out soon, but in the meantime, feel free to look at the script and use a tool like Firebug to investigate the properties of the gmonkey and gmail objects and play around.
</p></blockquote>
<p>Thanks Mihai and Dan!</p>
]]></content:encoded>
			<wfw:commentRss>http://almaer.com/blog/gmail-greasemonkey-macros-back-and-gmail-even-has-support/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Changing my view of Google Code via Greasemonkey</title>
		<link>http://almaer.com/blog/changing-my-view-of-google-code-via-greasemonkey</link>
		<comments>http://almaer.com/blog/changing-my-view-of-google-code-via-greasemonkey#comments</comments>
		<pubDate>Sun, 14 Oct 2007 16:53:32 +0000</pubDate>
		<dc:creator>dion</dc:creator>
				<category><![CDATA[Google]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[greasemonkey]]></category>

		<guid isPermaLink="false">http://almaer.com/blog/changing-my-view-of-google-code-via-greasemonkey</guid>
		<description><![CDATA[Man I love Greasemonkey. I am a heavy user of Google Code, and there are a few links that I wish were on the site for my use cases. I could bug the team to get these links added, but to begin with, I wanted to add them for myself to see if I really [...]]]></description>
			<content:encoded><![CDATA[<p>Man I love Greasemonkey. I am a heavy user of Google Code, and there are a few links that I wish were on the site for my use cases. I could bug the team to get these links added, but to begin with, I wanted to add them for myself to see if I really needed them.</p>
<p>I have changed two pages, first the home page:</p>
<p><a href='http://code.google.com/' title='Greasemonkey: Google Code Home'><img src='http://almaer.com/blog/uploads/googlecodehome.png' alt='Greasemonkey: Google Code Home' width='480' height='244' /></a></p>
<p>All I did here was add a link to my open source projects page. Before hand, I would have clicked on Project Hosting and futzed around, or just remembered to type /u/ and gone via history. Now I have a big bold link on the top right thanks to the <a href="http://almaer.com/firefox/userscripts/googlecode-homepage.user.js">simple userscript</a>.</p>
<p>Secondly, I have changed the project pages to add:</p>
<ul>
<li>A tab to go directly to the trunk of the Subversion repository for the project. This saves 3 normal clicks</li>
<li>A link back to my projects on the top right, for jumping between projects. Ideally, I would change this to have a drop down of the projects.</li>
</ul>
<p>This <a href="http://almaer.com/firefox/userscripts/googlecode-project.user.js">simple userscript</a> does the deed.</p>
<p><a href='http://code.google.com/p/google-ajax-examples/' title='Greasemonkey: Google Code Project'><img src='http://almaer.com/blog/uploads/googlecodeproject.png' alt='Greasemonkey: Google Code Project' width='540' height='105' /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://almaer.com/blog/changing-my-view-of-google-code-via-greasemonkey/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

