ecmanaut

The author

2005-12-22, 18:22

What is a user script, anyway?

Mtl3p and Hugh of dose got into a bit of discussion about my semi-automated CommentBlogging user script in the comments on mtl3p's post, interspersed by some general skepticism about or even animosity towards Firefox and Greasemonkey.

There is little need for fearing the proprietarism of the technology, though; while I don't think any other browser has taken user script handling usability as far as does Greasemonkey in Firefox, both Internet Explorer and Opera also handle them, natively in Opera's case and with Reify's extension Turnabout for IE. User javascript was actually first implemented in Opera, which still has the technological advantage.

This came in Opera 8, and was the next logical step in improving the Opera browsing experience, by making it possible for the Opera engineers to have their baby properly handle even the most broken and explicitly browser incompatibile of pages "just as well as Internet Explorer does", as the typical unsuspecting end user would call it when some loonie has made a web, sorry, Internet Explorer page. Anyway, Opera added a whole aspect oriented subsystem to invoke javascript code to do any amount needed of wizardry, to any web page, rewriting the world to fit the page's conceptions, or the other way around. Heck, if Microsoft can rewrite their pages to break Opera, Opera can rewrite Microsoft's pages to work, even when they standards defyingly assume an Internet Explorer world, the clever Scandinavian engieers at Opera reasoned.

Some time later, Greasemonkey came around and turned the idea into a playground for doing page modifications, building another web of the present web, and doing it in a style easily shared with friends. Inspired by Greasemonkey, Reify came around and did their own take on the concept, improving on some aspects, not going as far in some. So, again, just as we are used to on the web from the old bad days of competing browsers, we have a field of a few players, all doing their thing, a bit differently, prior to any emerging standards. This time around it isn't a battlefield, though, it's just somewhat immature technology that has yet to find standardization and cross browser portability.

I'm eager to see that happening, and am interested in any feedback, in particular developer feedback, about my own user scripts and how they work or break when run in other environments that I don't use myself, and why they do, or how they ought to do to work better. To find best practices, we need to unite, exchanging experiences and spreading them, so others can learn from them and better scripts useful to more people, regardless of browser preferences, will come out of it in the end.

The userscripts.org community features 2,400 user scripts today, most of which were probably written for (and using) Greasemonkey. A similar community for the Opera user Javascript community is called userjs.org, and features 100 scripts. As far as I know, Reify has no similar following, but emulate and extend the Greasemonkey model hoping to remain compatible. The numbers above probably more reflect the ease of user script installation in Greasemonkey than anything else; it's "right click and pick install", versus "turn on a browser option, specify a directory, find that directory and save each user script there" in Opera. I'm afraid I don't remember how Turnabout does it.

0 Comment:

Post a Comment

http://ecmanaut.blogspot.com/2005/12/what-is-user-script-anyway.html

02:45

[external]
Central hosting of all javascript libraries

Ian Holsman voices an idea I have long been considering ought to be done, which would do the web very much good: setting up a central repository of all versions of all major (and some minor ones too, of course) javascript libraries and frameworks, in one single place.

Pros

Why is this such a good idea? There are several reasons. Here are a few, off the top of my head:

  • Shorter load times. While bandwidth availability has generally increased in recent years, loading the same bits of code used everywhere for every site that use the very same library anyway, is wasteful. The more sites that use one canonic URL for importing a library, the quicker these sites will load, since visitors to larger extents will already have the code cached locally. Shared resources make better use of the browser cache.

  • Quicker deployment. There are reasons why projects who have already taken this approach (Google Maps, for instance) spread like wildfire.

    Multiply the number of libraries in active development with their number of releases over time and the average time it takes for a developer to download and install one such package. Multiply this figure with the number of developers that choose to use (or upgrade to) each such release, minus one, and we have the amount of developer time that could optimally instead be used for doing active development (or hugging somebody, or some other meaningful activity, adding value in and of itself).

    Moving on, this point has additional good implications, building on top of one another:

    • Lowering the adoption threshold for all web developers. This is especially pertinent to the still very large body of people stranded in environments where they have limited storage space of their own, or indeed can not even host text/javascript files in the first place.

    • Increased portability is a common effect of standing on the shoulders of giants such as Bob Ippolito, David Flanagan, Aaron Boodman, and all the other very knowledgeable, skilled artisans who know more about good code, best cross browser practices, good design, and more, than the average Joe cooking his own set of bugs and browser incompatibilities, from the very limited typical perspective of what works in their own favourite browser. Using code wrought by these skilled people, eyed through and improved by great masses of other skilled people adds up to some serious quality code, over time. While there are good reasons for not adopting typical frameworks, the same does not hold for the general case of libraries.
  • Better visibility of available libraries through gathering them all in one place, in itself likely to have many favourable consequences, such as spreading good ideas quicker across projects.

Cons

There will of course never be 100% adoption of any endeavour such as this, but benefits will grow exponentially as more applications and web pages join up under this common roof. There are also reasons for not joining up, of course, many ranging along axes such as Distrust, Fear, Uncertainty and Doubt.

Trust is important. A party taking on this project needs to have or build an excellent reputation for reliability, availability, good throughput, response times and security (this is not the site you would want to see hacked). Naturally also to never ever abuse the position of power it is to have the opportunity of serving any code they choose to that millions of web sites use for their core functionality. Failing to meet that trustworthiness is also an instant kiss of death for the hosting center's role in this, on the other hand, so that particular danger would not keep me awake at night.

Why?

Doing this kind of massive project, and doing it well, would be a huge goodwill boost for any company to attempt it and succeed (a good side to it is that it would not be bad for the web community, if multiple vendors were to take it on). It's the kind of thing I would intuitively expect of companies such as Dreamhost (but weigh my opinion on that as you will -- yes, it is an affiliate link), who have outstanding records for being attentive, offering front line services and aim high for growing better and larger at the same time. I'm not well read up in the field, so my guess is as good as anyone's -- though after having read Jesse Ruderman on their merits a year ago, I think my own migration path was set. But I digress.

How?

The first step to take is in devising a host name and directory structure for the site. Shorter is better; lots of people will type this frequently. For inspiration, di.fm is a very good host name (for another good service) -- but if you really want to grasp the opportunity of marketing yourself by name, picking some free spot in the root of your main site, http://google.com/lib/ for example, will of course work too. (But, in case you do, don't respond on that address with a redirect; that would defeat the goal of minimum response time.)

Let's say we end up at http://lib.js/. For reasons apparent to some of the readership we probably won't, but never mind that. Devise short and to the point paths, and place each project tree verbatim under its name and version number, however these may look. http://lib.js/mochikit/1.1/ could be one example. In case you would like to reserve room in your root for local content, be creative: http://lib.js//mochikit/1.1/ would work too; your URL namespace semantics are your own, though few challenge classic unix conventions today. Pick one and stay with it for all eternity.

Line up all other libraries side by side with the first, starting with those more popular today, moving on to less known niche software. Add as much of past versions of all projects as you can get your hands on, when you have achieved good coverage on current most wanteds. This makes it possible to migrate forward in due time, as each party choses, and to quickly import past projects and sites, without doing any prior future compatibility testing.

You might also opt to set up and maintain a rewrite rule list for linking the most recent version of every library under a common to all projects alias, such as http://lib.js//dojo/latest/. Not because it is a very good idea to use for published applications, but because it is a nice option to have. Maintaining two sets of rewrite rules, the latter doing proper HTTP redirects, is another nice option, where http://lib.js/latest/dojo/ would bounce away to http://lib.js//dojo/0.2.1/. Today, anyway, assuming above sketched URL semantics.

That's your baseline. Next, you may choose to line up project docs in their own tree branched off at the root, gathering up what http://lib.js/doc/prototype/1.0/ has to offer in way of documentation, otherwise keeping the native project file docs' structure below there. Similarly, you may of course over time also provide discussion forums, issue tracking and other services useful to library projects, but don't rush those bits; it's not your core value, and most projects already have their own and might well not look favourably on having them diluted by your (well meant) services.

Invocation

Ajaxian further suggests integrating such a repository with library mechanisms to do programmatical import by way of the library native methods of each library (or at least that of Dojo; not all libraries meet the same sophistication levels, unfortunately), rather than the time tested default and minimal footprint "write a <script> tag here" approach. Also an idea in very good taste.

Adding selective library import tools by way of native javascript function calls from the live system, rather than pasting static bits of HTML into the page head section, is where wise minds must meet and ponder the options, to come up with a really good, and probably rather small, set of primitives for defining the core loader API. It will very likely not end up shared among all projects, but over time projects will most likely move towards adopting it, if it gets as good as it should.

The coarse outline of it solves the basic problem of code transport and program flow control: fetching the code, and kicking off the code that sent for it in the first place. One rather good, clean and minimalist way of doing it is the JSONP approach, wherein the URL API gets passed a ?callback=methodname parameter, that would simply add a methodname() call to the end of the fetched file. (Given what ends up coming out of final API discussions from bearded gentlemen's tables, there may of course be some parameters passed back to the callback too, or even some other scheme entirely chosen.)

Methodname here is used strictly as a placeholder; any bit of javascript code provided by the calling part would be valid, and most likely the URL API will not even be exposed to the caller herself; the loader will probably maintain its own id/callback mapping internally. As present javascript-in-browsers design goes though, on some level the API will have to look like this, since there is no cross browser way of getting onload callbacks, especially not for <script> tags.

On the whole, this project is way too good not to be embarked on by anyone. Any takers? You would get lots of outbound traffic in a snap -- good for peering. ;-)

3 Comment:

  • Johan, why not you? You seem to have the passion and the skill necessary. And http://scriptlib.org is available... (as of right now at least)

    By Blogger Oskar, on Fri Dec 23, 05:08:00 PM CET  

  • While I believe I might indeed possess the technical skills required to devise, setup, run and develop this endeavour, I am not backed by the kind of business organization that would ensure longevity or quality of service for an operation on this scale. Long term committment is probably also better driven by some party that has a business incitament for generating the goodwill that comes out of this operation; I don't believe the fame argument would power me to for long.

    I would gladly do some freelancing or consulting with anyone interested in setting up or developing this service though.

    By Blogger Johan Sundström, on Sat Dec 24, 03:11:00 AM CET  

  • ibiblio?

    By Anonymous Anonymous, on Mon Aug 07, 08:20:00 PM CEST  

Post a Comment

http://ecmanaut.blogspot.com/2005/12/central-hosting-of-all-javascript.html

01:28

[external]
Greasemonkey tip: running your handler before the page handler

I figured as it just took me well over an hour to diagnose and come up with a work-around for this issue (for adding BlogThis! support to my Blogger publish helper, which is done now, by the way -- feel free to reinstall it), others in the same situation might be glad if I shared this knowledge where search engines roam.

I faced a problem where I wanted to add an onclick handler that would run prior to an already defined onclick handler in a page, as my handler was changing the lots of page state intended for the original handler to see. node.addEventListener( event, handler, false ); would install my own callback after the already existing handler, which wouldn't do much good here.

The kludge I came up with was adjusting the present node to wait for a decisecond before executing, so my greasemonkey injected hook would have ample time to do its business before it would run the original code:
var code = node.getAttribute( 'onclick' );
if( code )
node.setAttribute( 'onclick', 'setTimeout("' +code+ '", 100)' );
Really ugly, but it does work. I'd love to hear of better solutions for this.

1 Comment:

  • I just removed the onclick attribute. It only sets the draft field value to 1 on draft posts and submits the form. I added the draft field handling to the click listener function.

    By Blogger Jasper, on Thu Dec 22, 10:21:00 AM CET  

Post a Comment

http://ecmanaut.blogspot.com/2005/12/greasemonkey-tip-running-your-handler.html

00:20

[external]
BlogThis! with my updated post tagger helper

After having kindly been slipped a slew of bug reports and feature requests by Oskar, I have now done some fairly substantial upgrades and bug fixes to my Blogger publish helper.

First and foremost, it now supports tagging things when you use the BlogThis! button in the Blogger navbar. (It does not do any fancy things on the publish page, though.) It took ages getting it to work, but it was something of a learning experience too.

If I got everything right this time, those of you who have previously been pestered with popup prompts asking you what tags you want on all your posts should hopefully be relieved of that from now on.

In other related news, it now appends the linked URL, when available, to the Del.icio.us text field that previously only held the post time.

While at it, I also incorporated Jasper's recent upgrade to support compose mode too.

Reinstall the most recent version of it and have a go.

4 Comment:

Post a Comment

http://ecmanaut.blogspot.com/2005/12/blogthis-with-my-updated-post-tagger.html