community.roxen.com
Not logged in Date: May 16, 2008
 DEMO  DOCS  PIKE
 COMMUNITY  DOWNLOAD
Home Articles Scriptlets www.roxen.com

Scriptlets - Universally Useful Bookmarks

Author: Johan Sundström <jhs@roxen.com>
Last modified: 2001-03-04 20:20:19


Web development can be tedious work. Indeed, just browsing the web can often be a pain in the neck, especially when encountering sites put together by web designers who cared more about the look of their site than their visitors' navigation convenience. This article won't particularly focus on Roxen, but it will be of interest to people browsing the web in general and lazy web developers in particular. So without further ado, let's fill up that navigation toolbar with convenient shorthands saving boring manual labour!

The Concept

For the part of the audience not yet familiar with scriptlets, or bookmarklets, as they are called by some, a scriptlet is a small piece of ECMAscript (formerly known as JavaScript, formerly known as LiveScript - in the grand tradition of changing names once in a while, in case somebody might have picked up the old name and associated it with something useless :-) code in the form of a bookmark. The bookmark, when activated, may access information about the page currently loaded in your browser window and alter it one way or another. You'll soon see how this opens up for some pretty interesting possibilities.

For optimum gain from reading this article, you're familiar with the language, but even if you are not, you can still adopt and use the example bookmarks introduced. I should warn you that not all scriptlets presented here will work in all browsers; I'm raised with Netscape browsers and, being your average heck-it-works-for-me hacker, am quite happy about my scriptlets as long as they work in my browser, which they do. Sue me. ;-)

Johan Sundström
The author, Johan Sundström
<jhs@roxen.com>

The Basics - Browsing the Web

If you've seen a link on the form <a href="javascript:alert('Hello world!')">Click Me</a>, you have met the most common form of scriptlets: the useless ones. They work in all browsers, but they don't do much good. Since they are a pretty boring subject, let's move on to the more interesting ones right away. For reasons of readability, I'll break this one down a bit with newlines and whitespace - when you make yours, you'll typically end up wiping out all extraneous whitespace before pasting it into your "edit bookmark" requester. And don't run off clicking this scriptlet just yet; it'll throw you off this page:



 javascript:
 with(location)
   href=protocol+"//"+host
       +pathname.substring(0,
                           pathname.lastIndexOf("/",pathname.length-2)+1) 

When you follow the link, you end up in the /articles/ directory of the server. No big deal; you've seen hyperlinks before. Bookmark the link and put it in your browser toolbar (I've named mine ".."). Click it twice, and you end up on the server root page, /. Neat, huh? Context sensitive links, bringing you to the parent directory on the server you are visiting. Go ahead, try it on any site you like. Works like a charm, as long as you don't turn off javascript in your browser settings.

Okay, so maybe a parent link isn't your average revolution in usability. Still, I use mine frequently, not to mention the root page link I keep next to it (called "/" to save valuable horizontal space for the rest of my scriptlet armada). Surely you can delete things from the URL field by hand when in need to without that much hassle, but why bother when you don't have to? After all, that's what laziness is all about; getting rid of boring, useless labour.


Fine, That's Cute. Was That It?

Okay, those were pretty basic tools, as indeed many of the best tools are, but let's move on to more intimidating hacks. I needn't shift my gaze much to reach the next scriptlet in my toolbar, verbosely named < - it tracks down the rightmost number of the current URL and decreases it by one as intelligently as it can (changing "010" into "009", "10" into "9" and moving on to the next earlier number when encountering a number entirely composed of zeroes; if it didn't find any number at all, it does nothing at all; I'm not particularly fond of requesters with annoying error messages to confirm):



 javascript:
 with(location)
 {
   u=href.split(/(0*[1-9]+0*)([^1-9]*)$/);
   if(u.length!=1)
   {
     n=u[1];
     l=n.length;
     n=String(parseInt(n.replace(/^0*/,''))-1); 
     if(u[1].charAt(0)=='0')
       while(n.length<l)
         n='0'+n;
     u[1]=n;
     href=u.join('')
   }
 }
 void 0

And yes, you guessed it, of course I keep a > scriptlet right beside it. You'd be amazed at how convenient this is when browsing around numbered articles, cartoon archives and so on and so forth. It works more or less the same way, changing "010" into "011" and "999" into "1000" as you probably would have yourself, had you bothered to edit the URL on your own. If you'd want scriptlets that add or subtract more than one, track down and alter the value added or subtracted right after the parseInt() statement in the above two examples (it's right there at the end of the longest line of the code example), and you're in business.

Agreeably, the code isn't particularly readable, but I attribute that to the fine hobby of minimalism, something Macintosh users may end up thankful to; some common versions of (aging) Mac browsers out there don't allow a bookmark to grow beyond some 256-or-so bytes in length, and if you do, well, the scriptlet won't work. Plus, this article does not really aim to teach you all the secrets of scriptlet hacking; I just to plant the idea and give you a set of really useful toys to play with to begin with.

There's one more set of navigational hacks I want to cover before moving on to the next section. Incrementing and decrementing numbers in the URL is useful, but when browsing cartoons, daily columns et cetera, it's more common that they are named by date rather than by number, and when you've read the entry for December 31:s, you end up with a whole lot of labour all over again just because you wanted to read the January 1:st entry too. Okay, I'm not going to give you The Final Scriptlet that tracks down everything in the URL that might be a reference to a date, but I do indeed have something not far from it.

Being a Swede, I'm a fan of the ISO date format (YYYY-MM-DD), and tracking down YYYY...MM...DD sequences in the URL shouldn't be that hard a task for a language capable of regexp twiddling, right? Right. So, here's a decrease date scriptlet, and the accompaning increase date. It doesn't eat the ugly YY...MM...DD dates, used by e g Sherman's Lagoon, but these two do: « and ». (Yes, you are still free to name them otherwise. :-) Most of the time they do fine, but of course they don't do too well with century boundaries, figure out how many days there are in February and so on. I'll throw in a few variations of them:

Operate on YYYY-MM-DD dates Operate on YY-MM-DD dates
Period: 1 Day Period: 1 Week Period: 1 Day Period: 1 Week
Subtract Add Subtract Add Subtract Add Subtract Add

Searching the Web

Martin strolled by a few minutes ago, peeking over my shoulder, asking whether I was planning on mentioning the world's today most used scriptlet, or perhaps rather enticing me to do so. After all, it is rather convenient, and with Google being my top candidate for "most useful search engine present on the web today", a link to their own set of scriptlets for searching the web isn't entirely out of place in an article such as this. They're a little talkative, but they do fulfill their task nicely.

I used to be fond of Altavista's "advanced search" facility in the past, due to it giving me the power of expressing very specific queries for tracking down what I was looking for, and constructed a similar Altavista search scriptlet to minimize the fuss of round-trip times, focusing forms and pasting text by hand. I'd enter queries like "soil of sound" ~ music or, perhaps a bit more likely in those days, "roxen modules" & ! host:roxen.com. I'm not particularly impressed by them nowadays though, in part because they don't keep up, in part because it's crufty, in part because they're too obsessed by scooting up information about what links you follow (another useless roundtrip to you) and clobber the place with ads. I hardly ever use it anymore.

Another scriptlet I made at the same time for practically the same purpose, though, is still in frequent use, and, by a lucky chance, it works equally well with Google. It's tough giving the scriptlet an explanatory name; post-websearch in-page search doesn't quite cut it for a toolbar (I settled for "vista" in my toolbar in the end, calling the previous scriptlet "Alta"), but it gives a fair grasp of its purpose. In essence, it repeats the search you performed at the Google (or Altavista) site, but on the page you ended up on, trying to find one term after the other in the order you gave in your original search query. If you try searching for "cache replacement" "cache-control" "RFC 2616" (in one query), pick one of the links to RFC 2616 (HTTP/1.1), you'll end up in a huge document, having to perform the search all over again to end up with what you were really looking for. Bothersome, isn't it? Well, accessing the scriptlet will search the document for occurences of the keywords in turn on the page, until one is found. Repeat at your leisure.

An Eye for an Eye

Lots of people hate javascript (as they've learned to call it), and not without reason. It's the tool that poor web designers lacking in respect for the comfort and trust of their visitors use to pop up uncalled-for windows with ads or annoying click-for-cash sites when entering (or even upon leaving!) their pages, forging or just covering up URLs in your browser's status bar and so on and so forth. The lesson here, however, isn't that javascript is evil, it's just that potent tools always can be used for both good and bad. If they couldn't, they would be of no use, and ECMAscript, in most browser implementations, is in fact so hampered by the browser's security model that lots of the applications you might want to put it to aren't possible.

The net is littered with these examples of poor taste in web design, and the point of my bringing up the subject is that the very same abuse of the language can be battled with the witful use of scriptlets, if you don't do as some, turning both off altogether. Mainly to see if it was possible with a language so seriously hampered by Netscape, I tried to come up with a scriptlet that would zap all event handlers of a page, and, much to my surprise, did. It wasn't as slick and beautiful as a solution in Pike probably would have been, but it did work. Just to show it off, I added two miserable event handlers flashing the background when moving the mouse on and off the link, so you can see the effect of running the scriptlet right away without resorting to tracking down the scum of the web.

Buy Roxen Platform today!

Perhaps not as irritating, but even more frequent, is the use and abuse almost everywhere - of banners. Or links opening themselves in new windows even though you didn't ask them to, for that matter. Those details that pester you during your stay on the web, in short. I used to have a scriptlet lying around my toolbar to get rid of those annoyances (plus removing onUnLoad and onMouseOver handlers), until I finally came up with a way of binding it to a hotkey, (ctrl-z, in my netscape) and lived happily ever after.

(You other unixoid people who prefer that kind of setup may feel free to borrow at your leisure from the Netscape section of my ~/.Xdefaults file. To get the scriptlet bound to Alt-7 all you need is the section on "Netscape Radio", to get it bound to Ctrl-z you'll also need the entire Netscape*globalTranslations.)

Cookies and Other Web Developer Treats

So far we've mostly seen scriptlets that alter the URL of things; either that of the loaded page or of images on the page in question. But there's more. If there is set of tools I've had really much use of when doing web development of my own (with Roxen, of course), it would probably be my set of cookie hacks. Debugging cookies was always a lot of fuss before I came up with the idea of handling them the intuitive (yeah, right) way with a few scriptlets tucked up my sleeve. First of all, a scriptlet that shows the cookies sent with this request (to the page currently loaded, i e this article). All right, now load that Altavista page again in a new window and see the cookies they set you up with. Customer tracking. Be so sure that they associate all your queries with those cookies. Feel like wiping them out, breaking the connection between your track history and you, in their eyes? Sure you do. :-) This scriptlet zaps all cookies that were sent with the latest request. (Well, to be really honest, it does not touch cookies set for multiple domains.)

Showing and zapping cookies, for all it's worth, may not always solve all of your problems; not seldom the need of tweaking cookies in greater detail - both altering those you have and setting new ones - arises, and of course it isn't much harder to make scriptlets that set cookies for you. Or, for that matter, that destroy an individual cookie.

Any Goodies for a Roxen Hacker?

Of course I won't finish this article without dropping a few tools useful specifically for you roxen developers / administrators out there; being one myself, I have naturally come to build up a small collection of those too.

Ever encountered or dribbled with prestates? Well, in case you haven't, you really haven't missed out the site building tool of the century, but they can be quite convenient when testing things or for adding a publicly accessable, yet hidden debug mode. A prestate is some identifier chosen at your leisure that you insert within parentheses as the first component of the virtual path, as in http://community.roxen.com/(prestate)/articles/010_scriptlets/. Following that URL won't make too much happen, but you may build some page logic that tests for the presence of a prestate using the RXML tag <if prestate> or, for pike programmers, look at the multiset id->prestate, and perform some appropriate actions. (Don't use this to open up security holes, content that only you know the name of the prestate; such information has a tendency to leak out.)

So, now that we know what prestates are, I'll introduce and solve a particular common problem, sneaking in a scriptlet in the process. :-) If you've ever built your own tables in HTML, or for that matter been trying to follow somebody else's, you know how helpful it is to add an attribute "border=1" to the <table> tags and instantly see and understand what really goes where. Well, perhaps not that instantly; you'd have to track down the table tags in the source file, alter them, save them, possibly upload them to some ftp server, reload the page, see the difference, remove the border attribute for your file and repeat the procedure to be back where you were again. I've seen people design XSL templates that parametrize table borders on/off and many creative constructs to solve this problem, but none so far that beats my own. ;-)

The idea came to me when I set out to write an article about how to make a basic roxen filter module (my personal favourite among the module types at hand); how about toggling table borders on and off, site-globally, by toggling a prestate "tables" on and off? Yep, would you believe it: community.roxen.com is equipped with this module! ;-) (Quite the coincidence, huh?)

Well, that about wraps it up for this time. I hope you enjoyed your stay and make good use of scriptlets for more comfortable, efficient and not to mention fun surfing. The possibilities are endless.