JQuery IFrame Plugin

This article by Nick Zakas, covering some technical issues in iframe loading, triggered me to surface a JQuery IFrame plugin I made a little while ago, which supports loading IFrames. (I did tweet it at the time, though I’ve since changed the location.)

JQuery IFrame plugin

The plugin basically tells you, the programmer of the parent document, when your child iframe has loaded. It also has some other bells and whistles, like timing the load duration.

It’s inspired by the use cases of WebWait (http://webwait.com) and the Scrumptious trails player (http://scrumptious.tv). Both are applications whose whole mission in life is to open up an external page in an iframe, and do something when it has loaded.

There’s already an IFrame JQuery plugin, but it’s to do with controlling what’s inside the iframe, i.e. the situation which is only possible when the iframes are from the same domain. What I’m dealing with here is the parent knowing when the iframe is loaded, regardless of when it comes from and agnostic to what it does.

Making a Bookmarklet: A Challenge on All Fronts

Scrumptious, a social bookmarking/comments app I began building recently, has a bookmarklet.

The bookmarklet is added from the demo homepage.

It’s not the first time I’ve made a bookmarklet for a website, the first time being WebWait.

I found the Scrumptious edition more challenging though, for several reasons. This brief article outlines the challenges. Some I’ve solved to an extent, but all need further work.

Launch UI Challenge

The most obvious challenge is, how do you explain to users what they can do with a bookmarklet. Most users aren’t geeks and I suspect most people still haven’t heard of bookmarklets. Or what are sometimes called “favelets”, since IE users have favourites, not bookmarks, which further highlights the problem. Here, I’ve explained with some text, but it ideally needs a diagram and perhaps a link to a separate page with a more detailed explanation, alongside a video.

Overlay UI Challenge

The next obvious challenge is UI design of the comments overlay. We’re overlaying comments onto a page. One of the issues was using a z-index that’s higher than what’s on the site, hence my article on max z-index. Other questions too. How much transparency, if any? What kind of positioning and scrolling, and how wide should it be?

Coding Challenge

Bookmarklets need to be fairly small. IE6 limits you to just 508 characters, so if you are doing anything remotely interactive, you’ll need to make the bookmarklet pull in a script from elsewhere, using On-Demand Javascript. This is a good practice anyway (as bookmarklet guru Alex Kirk explained to me a while ago) because it means you can always update the app. The downside is you still have to be quite concerned about size, as you want the bookmarklet to come into effect straight away. For this reason, I wrote the Scrumptious bookmarklet without using JQuery, which meant going back to Javascript 101, and lots of ugly low-level DOM manipulation therein.

Deployment Challenge

While there are various websites that let you cut-and-paste Javascript code to build a bookmarklet, I wanted to automate the process. Continuous integration, Automated Deployment, and all that. Luckily, John Gruber has a bookmarklet builder perl script. I yoinked and tweaked it so that I could keep the Scrumptious bookmarklet in its own form.

Another issue is the URL of the Javascript which the bookmarklet requests. Since Scrumptious can run on different servers, this URL will change depending on where the server is stored. Right now, there’s no server-side processing – all server-side content is static HTML. So I wrote a shell script to set the bookmarklet which any site operator could use.

Modularity Challenge

A bookmarklet is not the only place Scrumptious injects itself into the page. There’s also a Greasemonkey script under construction, and I’ve experimented with JetPack. I’ll also be building support for a site toolbar, so that an intranet operator could let you click on a “comments” link and inject Scrumptious comments on the page (so that users don’t have to bother installing the bookmarklet, at least to comment on intranet sites). The bookmarklet script has to be flexible enough to cover these subtly different scenarios. For example, the Greasemonkey script wants the comments overlay to be closed initially with a small button to launch it; the bookmarklet wants it to be open initially; and the Jetpack and toolbar want it to be off altogether until its explicitly launched.

Scrumptious Update: Open ID Support, UI Enhancements

I’ve released a new version of Scrumptious. Main change is it now supports Open ID. You can click a “login” link to comment by Open ID. It’s optional by default, though a Scrumptious site operator could easily make it mandatory for read, write, or both by just changing a couple of words in the “policy” config files. Similar to other CMSs like WordPress, non logged in users can indicate their name and URL when they submit a comment.

There are also UI enhancements – the design is cleaner and looks closer to the original original TiddlyWiki comments plugin. Interestingly, I retained almost identical markup, so I was able to cut-and-paste the original CSS for the comments plugin and it mostly worked. I also now include the default TiddlyWiki stylesheets as well. It’s not just look-and-feel which is closer to the original plugin, but the content – you now have info like modifier, modified date, and a permalink available.

I also added something I always wanted to add on the original plugin, which is some animation, e.g. when you add a new reply, the page scrolls to that reply, and a yellow fade effect highlights it. This is a genuinely useful feature as I was finding it difficult to see which reply I’d just added, when there are a lot of comments around.

I’ve also begun work on a Comments Report showing recent comments. Obvious related enhancement is to take the TiddlyWeb Atom plugin and make a comments feed.

Right now, all this is only tested on Firefox (the original was tested on all browsers, at least the full website view); my next priority is to work on browser compatibility, and after that, extract a modular JQuery comments plugin.

Implementation Notes

Regarding the implementation, TiddlyWeb ships with Open ID by default (Open ID is one of two default challengers, the other being the usual simple user-pass key pair config). The most challenging thing here was getting the UI right for both anonymous users and logged in users, as well as handling a redirect in the popup after a successful login; but at the back end, Open ID “just works”.

In summary, I added Open ID support as follows:

  • Add a “login” link to the TiddlyWeb OpenID challenger UI, using a “target” attribute so the challenger opens in a popup.
  • The challenger URL in that link also contains a redirect param, which I redirected to a new static page. This static page shows the user their login ID (by inspecting the “tiddlyweb_user” cookie value), calls a callback “onLogin” method on the original page, and closes itself.
  • The “onLogin” callback updates the login display to show the logged in user and a logout link; the logout link simply runs some Javascript to remove the cookie. The callback also updates any forms that are open prompting for bio info; it hides this info and in its place, shows the current user ID (read-only).

Thanks to Ben and Chris for pointing me in the right direction on TiddlyWeb’s Open ID support.

PS I discovered late in the day (literally) that TiddlyWeb lets the client specify whatever modifier they want

When Resource IDs are URLs

Being a web app about websites and other resources, Scrumptious has a resource which is basically a URL, called “Pages”. A Scrumptious resource modelling google.com/about looks like:

http://scrumptious.tv/comments/bags/ pages/tiddlers/http%3A%2F%2Fgoogle.com%2Fabout

See? The resource ID is http://google.com/about, encoded. (encodeURIComponent("http://google.com/about")

This was working fine on my dev machine, running “twanager server comments.boz 8080” (comments.boz being an alias for my local machine). But on the server, and run through apache and TiddlyWeb’s apache.py, it failed:

The fix was twofold – both of the following were required:

  • AllowEncodedSlashes On in apache config. This option ensures encoded slashes (%2F) are passed through to the end-app.
  • PathInfoHack plugin As with any TiddlyWeb plugin, I downloaded it and added it to ‘system_plugins’ list in tiddlywebconfig.py. (Thanks Chris for the pointer.)

And now we can happily talk resources with URLs as IDs to the server.

Scrumptious: Conversations About Websites (and other resources)

Scrumptious is a web framework I’ve begun working on at Osmosoft. It’s a web app and web service for sharing bookmarks and comments about websites, and pretty much anything else with a unique URL. Things it is related to: Delicious (bookmarking), Digg (threaded comments), JS-Kit and Disqus (embedded comments with common identity across multiple sites).

Scrumptious is open source, under the BSD license (meaning you can do just about anything you like with it). There are already many open-source clones of this sort of thing, so why make a new one? There are a few reasons:

  • Adherence to RESTful principles – Scrumptious is backed by TiddlyWeb, a RESTful data service.
  • A non-TiddlyWiki TiddlyWeb client – So far, people who have used TiddlyWeb as a server have used TiddlyWiki as a client. They do play nicely together, but TiddlyWeb is a powerful RESTful framework on its own. Part of the motivation for Scrumptious was to port the TiddlyWiki nest comments plugin to a generic JQuery plugin that could be used on any web page. (Comments are indeed implemented as a plugin right now, but more work needs to be done to extract it into something truly modular and reusable; for example, the plugin right now assumes comments are about a web page; also, they are tied to TiddlyWeb. Nevertheless, the app still does achieve the main purpose of demonstrating TiddlyWeb is a fine data service for generic web apps.)
  • Demonstrating the power of URLs – In evangelising web standards, a very practical piece of advice is simply to associate a unique URL with each distinct resource. That’s REST 101, but it’s something lacking in many web apps. With a tool like Scrumptious, you get a comment system “for free” as long as each resource in your system has a unique URL. We’ll be developing a similar framework for URL Trails in the future, and the same principle applies: use unique URLs, and people can put your stuff in trails “for free”.
  • Flexible security model – Again, TiddlyWeb offers flexible permissioning, so you can use the app in different ways. e.g. a private conversation between colleagues; a public conversation (as with the demo), a publicly readable conversation where only certain individuals can contribute, etc. Likewise, TiddlyWeb offers flexible authentication, so you could hook into an organisation’s LDAP system, use open ID, simple user-password pairs, or any other form of authentication you wish to use.

Scrumptious is still at an early stage. Future work includes:

  • Bookmarking – for now, there is only commenting rather than social bookmarking per se.
  • Nested comments UI needs work to give it the same kind of UI as in the TiddlyWiki comments UI. e.g. show info like creator and creation data, and use suitable rendering and indenting.
  • Graceful degradation – It would be possible to provide a basic system not requiring Javascript. This would be probably be done using TiddlyWeb plugins, though I’d also be interested in running the JQuery-powered web app on the server, using server-side Javascript.
  • TiddlyWiki comments plugin harmonisation – As TiddlyWiki now ships with JQuery, it would be ideal if there was a single code base for the comments plugin, running in and out of TiddlyWiki. Indeed, I hope TiddlyWiki moves towards a general microkernel architecture, in which all plugins are useful outside TiddlyWiki. This is certainly becoming the case, with generic JQuery plugins being extracted for core activities like file saving, CSS applying, and wikifying.
  • Browser extensions – instead of a bookmarklet, use a browser extension to show, for each page, if comments are available, as well as bookmarking info. (Similar to the StumbleUpon or Delicious Firefox extensions.) A good opportunity to get my hands dirty with JetPack.
  • Login and identity management – while TiddlyWeb already provides the security and permissioning model, work is required to handle this at the UI level. For example, let anonymous users enter their email address and homepage, and/or register.
  • User admin – for situations where users must be authenticated, some form of user management would be handy. Again, TiddlyWeb provides a good model for this – a “bag” of tiddlers has its permission specified in JSON, which may include a list of users for each access type, so you simply need to PUT and GET this if you are sufficiently permissioned (ie an admin). What’s missing right now is a UI (in TiddlyWiki too, let alone standalone web apps).

Scrumptious Screencast:


p>Scrumptious from Michael Mahemoff on Vimeo.