Webxtend

Something that I don't think many web developers and extension developers seem to be picking up on, but yet some are, is what I'm calling webxtending, which is providing APIs that allow their users to extend their website/webapp or extension with a browser extension. To illustrate this idea take the Gmail-Greasemonkey API, this is a front-end JS API that a user script can easily access to be notified of Gmail's custom events, change state variables, and perform actions with the Gmail interface (afaik the api used to work, and some parts do not work at the moment). This was a wonderful idea because it allowed user script authors to save a lot of development time, also maintenance time, and write more cpu efficient scripts. Furthermore I imagine such a API would be extremely useful to internal development, it would at least reduce the chance of sloppiness.

Webxtending doesn't always mean providing a Javascript API though, it often simply means writing semantic code by using microformats, and structuring the markup in a logical manner, taking into account how others may want to change the UI, and making those changes as easy for them to make as possible. This means using the id attribute even when you don't need it, because others may, but it also means thinking carefully about every facet of the structure. XUL overlays used in Firefox extension development are a good example of this structural extendibility idea.

Webxtend is a gold standard quality requirement, if your website or browser extension is not webxtendable then it's not gold standard quality. =p

UserScript: Showing Page Titles & URLs in Google Analytics

Often, when you're using Google Analytics, you want to be able to segment by the page's title, but there is no default way to do this with Google Analytics.

Well, a couple of hours ago I started catching up on my reading in Google Reader, and I noticed a blog post from LunaMetrics titled "Showing Page Titles & URLs in Google Analytics", and that post pointed out exactly how to segment by page title.

So, I took a couple of minutes and wrote a userscript to add this dimension to the 'segment by' drop down with a userscript so that you can easily segment by page title, without having to think about how to do this. Here's the code:

This userscript is available on userscripts.org as well, here: Google Analytics Page Title Segmentation

Enjoy!

User Script Tip: Using jQuery

A very common question that I see asked on stackoverflow.com, the greasemonkey-users mailing list, and in #greasemonkey on freenode, is how to use third party libraries with a user script.

The common response is to use @require, but these days people want their user scripts to work on Google Chrome too, and unfortunately Google Chrome user scripts do not support a lot of the Greasemonkey metadata block, including @require.. so another method is required.

Cross Browser Solutions

Use script element & setTimeouts

One method that has been mentioned elsewhere is to create a script element and add it to the page, and use setTimeout's to wait until the third party js, in this example jQuery, is loaded. The example in the link I provided is for Greasemonkey, but with little effort it can be made to work with Google Chrome.

Use script element & associated onload event

This method creates script element for jQuery (or some other third party script), and appends it to the body element, and listens to the load event to figure out when the library is loaded and ready to be used.

Google Chrome does not allow user scripts to access javascript objects in the page scope from the user script's scope, so in order to use jQuery at all on Google Chrome you must load jQuery into the page scope and inject your script into the page scope. So this is what my example below does essentially, more specifically it stringifys a callback function which is called when jQuery is done loading.

Example

Easier GitHub Fork Switching

There are many issues I have with my favorite site to host git repositories, GitHub, but today I decided to solve one of them.

The Problem

When you are on a page in one of your project forks on GitHub for say some file in the repository, and you want to switch to see the same page for the project that you forked from, then you have a number of clicks and page loads ahead of you. My feeling is that there should be a single link that allows you to do this, and vice versa.

[More]

Extending Firefox with Jetpack @ VanJS

I gave a presentation on Jetpack to the VanJS meetup group last night and I had a good time. It was my first presentation and I learned a lot I think, time will surely tell though. My main goal was to shine the light on Jetpack and hopefully start people thinking about how they might want to extend Firefox with Jetpack, which I think I achieved for the most part, so I'm happy about that.

Remember that if you have any questions that you'd like to ask me I'm easy to contact, and please feel free to do so. Also, the Jetpack discussion group is a great place to talk Jetpack.

Slides

Anyhow, here are the slides if you're interested, but they're sparse:

[More]

A Jetpack Module for the Microformats API

After a blog post I wrote last month, "The Context Menu Module & Microformats", Michael Kaply wrote a comment reminding me that there is an API for Microformats built in to Firefox.

So I spent a little time getting familiar with with the API and wrote a Jetpack module for it, which you can find here. This module just a wrapper to export the Microformats API, which can be seen in this file (only viewable from Firefox).

It might be the smallest module that I ever write =]

Get the Microformats Jetpack Module here.

The Principle of JavaScript Illumination

Every web developer knows that their site should work when the site's users disables JavaScript, but I constantly find this principal is violated when it is simple thing to obey. When web UI developers violate this principal it shows an extreme laziness and a failure to understand good practices on their part; this can greatly worsen the user experience. So, I'd like to articulate what I'm going to call The Principle of JavaScript Illumination which is an idea I haven't seen articulated yet, but that everyone knows in their gut they should do, and yet I hardly ever see this principal adhered to in practice.

Definition

The Principle of JavaScript Illumination is a simple one, if some user interface element will not work when JavaScript is disabled, then have JavaScript add the element.

Implications

If you have a user interface (UI) element that uses JavaScript, then make sure there is a default functionality that will work when JavaScript is disabled. If the UI element cannot work at all without JavaScript, then you should make JavaScript add the element, this way if JavaScript is disabled then the user will not see UI elements that will not work, causing a bad user experience.

Examples

Facebook Chat

When you log in to Facebook with JavaScript disabled, the chat widget is displayed to you on the bottom right of the screen, but it doesn't do anything, it's completely useless to you and it's just in the way, so why the heck is it displayed to the user?

Kampyle

Kampyle provides some widget code for anyone to put on their site which adds a "Give Feedback" button to the bottom right of the user's screen, which the user can click on to give feedback for the site. The trouble is, when JS is disabled, or when the user uses NoScript to block assets from the kampyle.com domain, then the button doesn't work (see ROIRevolution's site for an example of this), so why the heck is it displayed to the user?

Conclusion

Be a good web citizen, and a smart web developer by obeying The Principle of JavaScript Illumination, because it's the right thing to do and because you're users will thank you for it.

My Solution to the Alt-Tab Problem

While I was reading through my subscriptions the other day I noticed Aza Raskin's recent blog post, "Solving the Alt-Tab Problem", where he describes issues with the current alt-tab implementation which orders the applications by Most Recently Used (MRU), please take a moment to read his very detailed post before continuing with this post.

I thought this was a very interesting problem. I've personally always hated the way that alt-tab works, and hardly ever use it because of this, even though I know it should be helpful, it just is not. So, I thought a bit about this in the back of my mind and I finally came up with a solution that I like, and I haven't seen it mentioned yet so I will explain it here, but first I want to list the issues Aza mentioned with MRU and my main issue with it, then I'll quickly describe some of the other solutions I've heard, and finally I'll give you my solution.

Issues With MRU

  • Switching between 3+ applications is brutal (see Aza's post).
  • Constant seethings of MRU confound a person's strong spatial memory (see Aza's post).
  • Thinking about how to switch tabs rips a person's attention from their real task (see Aza's post).
  • If a user presses alt-tab, then decide they made a mistake and want to return to the application that they were using before pressing alt-tab, then they need press alt-shift-tab, because if they just let go of the alt key, then they will be switched to the last application that they used (my issue).

The first and last issues listed above are the two main reasons why I never use alt-tab today.

Proposed Solutions

Aza's HRMRU

In Aza's post he mentions a possible solution, which he admits he doesn't think is great, which is a habit respecting design which he dubbed HRMRU. HRMRU is basically a prediction algorithm which allows the computer to try to predict the order that you desire (read his post for a full explanation). He mentioned the possibility of using a Markov model, but an HRMRU could be implemented an infinite number of ways.

The way that HRMRU is implemented doesn't really matter imo, throughout my time at UBC studying statistics and computer science (with a focus on machine learning), and the rest of my life, I haven't seen an algorithm that would be suitable to implement HRMRU, indeed I wouldn't trust a human being with all of the time in the world to predict my habits (in this context). Furthermore, if some HRMRU method were implemented, then in order to switch applications in the blink of an eye I would have to predict the predictions made by the HRMRU implementation, and that would a terrible user experience. My last issue with this solution is that it would bog down my machine; I absolutely hate it when applications use cpu cycles when it is not necessary, when that happens I start losing control of myself, and I seriously want to start bitching at the developers, because it's what they deserve (if they didn't give me the option of turning their crappy code off).

Lukas Mathis' Solution

I'm not sure what to call Luka's solution, but he explains it here. Basically his idea is to have the currently open application in the second position, and the last application opened in the first position, and the rest are listed in positions 3 and on. Read his post for full details.

This solution would solve the last issue listed above, but does not solve the other issues.

Others

In the comments of Aza's post I saw a number of other options/~solutions mentioned, some of which I think are worth mentioning here, which I'll do as best as I can. There are other solutions mentioned in the comments of Aza's post though, so don't assume this is a comprehensive summary, because it's quite far from that.

Constant Order

This solution is very simple, the applications are listed in the same order that they were opened.

Truth be told I think this was the best solution mentioned in the long list of comments on Aza's post, it's even better than MRU, it takes care of all issues except for allowing quick application switching, which happens to be very important.

alt-tab-mouse

This is implemented on OSX and the windows alt-tab power toy (maybe winXP too I haven't checked). It's a simple solution, the user presses alt-tab, then uses their mouse to select the desired application.

This is a great solution, there is no doubt about it, but switching from keyboard to mouse all of the time is a terrible user experience, so a fully keyboard based solution is a must have, so this is only really part of a solution. Also, switching between 3+ applications in the blink of an eye is not possible with this solution, so it's just not enough.

Application Grouping (Activity Grouping)

I didn't really bother figuring out how this solution is supposed to work, as I understand it though you'll be able to group applications together, then some how you're able to switch quickly between applications..

Albeit, I don't fully understand this idea, and may not fully appreciate it, but it doesn't sound great to me. Presumably I would have to switch group/activity, then choose an application, and how I would do this isn't clear to me. This does sound like it could be an option, but it sounds like switching between 3+ apps may still be an issue, or at least it's not something that you could do in the blink of an eye.

Number the Listed Applications

This idea is simple, number or letter each open application (with 0-9 and a-z, then nothing). This way a user can alt-tab, then hit the number/letter associated to the desired application.

I like this solution.

My Solution

To start with I think a few of the solutions mentioned above should be implemented, namely the alt-tab-mouse solution, the lettering of the first 26 open applications, and ordering the applications by the order that they were opened.

Obviously, I think that if the user presses alt-tab then lets go of these keys, then I don't think the application should be changed. Also, I think the user needs to be able to customize the order that the applications are ordered (the default ordering would be the order they were opened, and this would be customizable on the fly), so the question is how should the user be able to do this? well I thought of a couple ways, one is to use the mouse to change the order via drag & drop, and the keyboard method I thought up was to incorporate the ctrl key. To change the order of the applications by keyboard only a user would simply move the selection box to the application that they want to move (so alt-tab or alt-shift-tab to the application, while holding the alt key) then they hold the ctrl key along with the alt key which 'picks up' the application, and then the user could press alt-ctrl-tab to move it right, or alt-ctrl-shift-tab to move the application left.

Now when the user presses alt-tab the currently focused application will be selected, and they can quickly alt-tab to switch to the application to the right, or alt-shift-tab to switch to the application to the left, and they can manually alter the order of the applications to something suitable for them at that moment in time.

There should also be a separate key for switching back and forth between the last application used, I don't care what it is, maybe alt-tab-`, it doesn't matter I think. It would also be nice if the last application used was easy to spot in the alt-tab list somehow, so that the user could slow down and ensure that they are going to the right application before switching, so in this case they would press alt-tab, then hold tab see the last application used, and then press ` to select it and then they just let go of the alt key to switch to it.

Finally, I've got another set of hotkeys that I think will help, which are to use the numbers 1-5 or 1-9 such that the user can quickly switch to the application that is some # positions away from the currently application in the alt-tab list by pressing alt-# or alt-shift-# (ie: pressing a number while holding alt) which would select the application some # of positions to the right or left of the current application (ie: pressing tab while holding alt is equivalent to pressing 1), and if the desired application is 100 positions away or whatever, then they just press alt-tab-5 20x, or reorder the list so that they don't have to do that every time. This may sound bad for a large number of applications, but that'll be the case with any solution, even HRMRU.

You'll notice that all of the issues listed above are solved, and the code would be lightening fast, the only issue I see is that unless you've read about these hotkeys you may not find them, but alt-tab will still work, and be useful.

Building a Jetpack Package for Userscripts

Most members of the userscript community already know about Anthony Lieuallen's User Script Compiler, and Gina Trapani's Greasemonkey Multi Script Compiler (GMSC) which she based on Anthony's compiler. These two compilers allow a user script author to convert their userscript in to a Firefox extension, at which point the author can add functionality/features that Firefox extensions have, and usersripts do not have. So for example they can add UI elements to the browser that work with the userscript, or read+write files from the file system, etc..

I've used both compilers in the past and I find they are very handy, especially when you want to package disparate user scripts together in a single Firefox extension, or add functionality to a existing userscript, essentially upgrading the user script.

Now, around the time that the Jetpack SDK was released last month I started thinking about how the possibility of creating compilers similar to the ones above but for making Jetpacks that use userscripts. The other goal that immediately struck me was to make a userscript manager out of Jetpack, which is an idea I know others have been thinking about, at least Tim Smart expressed the same idea in the #greasemonkey irc channel not long ago.

Well, last week I was toying around with the idea of running a userscript within a Jetpack, and I had a lot of success, because within a few hours I was able to create a Jetpack which contained a collection of userscripts and it worked perfectly!

After I accomplished this, I started thinking about a road map for these ideas, so here it is..

Roadmap

Here are my goals for this project:

Complete the Userscript Package

This package has got to be dead simple to use, so that adding a userscript to a jetpack is as simple as dropping the userscript(s) in to the data folder of your jetpack, requiring the userscript package, and adding a line or two of code to your jetpack's main module which would make the jetpack aware that it has a userscript and act accordingly.

Furthermore, I want this package to be extendable so that third party's can create APIs that will be available in the userscript sandboxes. For example, a common question asked by new userscript authors is how to store data to disk in a file, which they quickly learn that they cannot do. But, when this package is complete their new option would be to write their userscript as they normally would, then if they come to the point where they want more API features than the GM_* API provides, then they will have the option to compile their userscript in to a jetpack, at which point they can start providing their userscript with more APIs that allow things such as storing data to a file on the file system.

Create a Userscript to Jetpack Compiler

This could be a website, command line package, or both, I don't really care at this point, but this must exist, and shouldn't be difficult once the Userscript package is complete. All that should be needed is a sparse Jetpack skeleton, which takes 1 or more userscripts and dumps them into the data folder, then creates a basic main module to run the userscripts.

Create a Jetpack to Manage Userscripts

Simply put this would be an alternative to Greasemonkey, maybe not quite as advanced as Greasemonkey, or with as nice a UI, but works and has all of the advantages of a Jetpack, namely you can install/update/remove without the need to restart, and takes advantage of the jetpack-core APIs which should mean that I won't have to worry as much about platform changes.

The Userscript Jetpack Package

I've posted the code I was working with last week in a git repo which is available on Github here. If you'd like to help out then fork this project and start hacking.

Example

If you would like to see the example I was working on last week, then it is available on Github as well here. This example is a remake of the BetterGWO Firefox addon that I created last year with Gina's GMSC.

Conclusion

If any of those goals sparked your interest then consider helping out, I would enjoy the company. Otherwise, I hope to have at least the userscript package mainly complete by the end of this month, so stay tuned.

The Context Menu Module & Microformats

Originally posted on Mozilla's Jetpack Blog

The Jetpack team recently released a context menu module in version 0.3 of the Jetpack SDK. This post will discuss the context menu module’s features and how it can be used to create an extension that allows users to interact with microformatted data on the web.

Microformats

If you are familiar with microformats, you can skip this section. In case you are not familiar with microformats, they are simply specifications on how to pattern commonly published data (contacts, events, reviews, etc.) in HTML so it can be easily consumed.

hCard, geo, & adr

Take the hCard microformat specification for example, an hCard represents a person, organization, or place and includes information such as a name, contact info, address info, and perhaps their geo coordinates all in HTML. Here is an example of a microformat that contains this information:

<div class="vcard">
<a class="fn org url" href="http://www.commerce.net/">CommerceNet</a>
<div class="adr">
<span class="type">Work</span>:
<div class="street-address">169 University Avenue</div>
<span class="locality">Palo Alto</span>,
<abbr class="region" title="California">CA</abbr>
<span class="postal-code">94301</span>
<div class="country-name">USA</div>
</div>
<div class="geo">Geo Coords:
<span class="latitude">37.386013</span>
<span class="longitude">-122.082932</span>
</div>
</div>

The Context Menu Module

You can find documentation and further details on the context menu module here. The primary feature of the context menu module is the ability to create items in the context menu that are shown when right clicking on various content within the browser or a web page. CSS is used to specify in which contexts your new context menu items will appear. If you create a new context menu item whose context is set to “a” then the menu item will appear in all menus shown when the user right-clicks a link.

Bring The Two Together

The combination of microformats and the context menu module makes many practical Jetpack ideas possible. When websites microformat data on their site, and users have extensions installed in their browser which allow for consumption of microformatted data, users productivity can be greatly enhanced.

Even when a website does not microformat data on its pages, a user script or a Jetpack Page Mod can be written to enhance the data on those pages with microformatting.

An Example

In order to show you how useful and extension that combines microformats and Jetpack’s context menu module is, I have created a jetpack-based extension which adds a ‘Find on Google Maps’ menu item to the context menu when the user right clicks on a geo or adr microformat – geo is used for geo coordinates, and adr for addresses. When the user clicks the extension’s context menu item, the targeted geo coordinate or address is displayed on Google Maps in a new tab. You can find this extension here on AMO, as well as the source code here. The bulk of the source code is < 50 lines.

Summary

If you maintain a website that isn’t properly tagged with microformats I would suggest you consider adding them to your content. If you are a user that notices a site that hasn’t properly tagged their site then you can either request that they do so, or write either a user script or page mod that does so for you. Once you have microformatted data you can then write & use extensions to interact with the data.

More Entries

© Erik Vold 2007-2010. Contact Erik Vold. Top ^