Status Update: Week 41

Well I blame bug 604368 for bogging me down a bit this week. I lost some time dealing with crashes and trying to determine the cause at first, until I finally came across #604368. Oh well though, no hard feelings, it is called Minefield, and the changes are meant to improve performance, so I'm not upset at all. I was able to get some progress done on Scriptish still by installing the latest Firefox beta and Seamonkey beta and using those.

Done

Scriptish

  • Seamonkey is now supported (issue #52).
  • Auto generating homepage URLs from download URLs when @homepageURL is not defined for user scripts installed from userscripts.org (issue #76), gist.github.com (issue #77), or github.com (issue #85).
  • Updated GM_notification(msg) api to now be GM_notification(msg, title, img, callback).
  • Added a new default user script icon.
  • Fixed a bug for scripts that attempt to overwrite a global variable, like scrollTo.
  • Fixed a bug where the uninstall state of a user script was forgotten when returning to the user script list view from a user script detail view.
  • Closing GM_worker threads when a window closes now.
  • Fixed a small bug where content pages could have detected Scritpish on the user's browser by checking for the presence of some resource: url files which Scriptish provides. Now afaik Scriptish cannot be detected, and Greasemonkey can be detected.
  • Made a small UX change to the status bar menu, when enabling or disabling a script the menu no longer automatically closes, so that you can easily enable/disable multiple scripts and it's still easy to close the menu by clicking anywhere else.

I also got some progress made on implementing @run-at document-start, it isn't going to be part of 0.1 I think at this point, but so far it looks promising, nothing pushed online yet though.

[More]

Why is Scriptish only for Firefox 4?

One little tidbit I didn't go over yesterday about Scriptish was why I decided not to support any version of Firefox less than 4.0, so I thought I should mention my reasons behind that decision.

The primary reason I did it was to shave a large amount of time off of the time to release tbh. Another reason was that by raising the min version of Firefox supported to 4.0 I was able to delete large amounts of legacy code, which means performance gains. The final reason was that there was a Add-on Manager API being introduced in Firefox 4 which allows Firefox extensions to easily add extension types to the add-on manager, which means Scriptish can rely on that entirely, and ditch even more legacy code, Dave Townsend (Mossop) describes how to extend the add-on manager here.

Scriptish Beta! A New Greasemonkey

My favorite browser extension for quite a while has been Greasemonkey (GM), I loved how simple it made customizing the web with JavaScript (JS) which allows all users to both filter out the crap that site owners try to provide us (ie: ads, share links, suggested junk) and add new useful features anywhere you that wish. Greasemonkey allowed us to customize the waves as we surfed the web, as well as making a few modifications to the board, and I loved it for that.

Some problems arose with Greasemonkey though, because it was built for Firefox (FF) 1.5, and even the latest GM version (0.8.6) claimed to support 1.5, which meant that Greasemonkey the GM maintainers did not want to introduce new features that would not be available in FF 1.5, and they did not want to take advantage a of newer version, like say FF 3.0's JavaScript Modules (JSM), which would allow GM to use much less memory and improve performance when a user is using multiple windows, and on startup because less JS would need to be loaded at startup.

The good news for GM is that with the next major release, 0.9 (which contributors including myself have been working on for quite some time now) is that the minimum version of Firefox that Greasemonkey will support will be FF 3.0, which means it can now take advantage of the benefits that FF 3.0 offers, finally. The trouble I found while trying to contribute to GM is that the maintainers don't really want to alter the code base, they're actually seem to be fine with doing the minimum necessary and bug fixing for the rest of the future, at least that is how it seemed to me after writing quite a few patches which were rejected, either outright, or by degradation (meaning I would have to basically redo everything, on crappy architecture, because they've sat on their hands for so long). Patches such as using JSM, reg exp @includes, @icon, and a few more.

So the reason that I decided to bypass Greasemonkey and start working on a fork, which I now call Scriptish, is because I was tired of beating my head against a wall, I wanted to have and use the Greasemonkey that I always wanted asap, so I'm making it now. I've always enjoyed working with others, and I hope that I can convince some GM contributors to start working on Scriptish in the future.

Scriptish

Scriptish is a fork of GM, you can think of it as a superset of Greasemonkey, it can do whatever GM does, and more. Some of it's new features are:

  • @author - displayed to users in the addon manager
  • @contributor - displayed to users in the addon manager
  • @homepage or @homepageURL - displayed to users in the addon manager
  • @icon or @iconURL - Include a icon for your user script which is displayed in the addon manager and for notifications from the script.
  • @screenshot - displayed to users in the addon manager.
  • @match - a include pattern introduced by Google Chrome user scripts.
  • @noframes - a simple way to prevent a user script from running in iframes.
  • GM_worker - use a Worker within user scripts.
  • GM_notification - send a Growl style notification to the user.
  • GM_setClipboard - save data to the clipboard from a user script.
If you'd like to do some reading on these features, then checkout the Scriptish wiki, which should explain them all in detail.

Other changes include major reorganization of the internal code, using JSM, in a way that only loads code into memory that will actually be used, by loading the req'd code the first time that it is going to be used. I was also able to remove a bunch of legacy code, because Scriptish will only support Firefox 4.0 or higher for the moment.

Give it a try!

If you'd like to give Scriptish a try, then you can download Scriptish here. If you want to get involved here are some links for you:

I hope you like it, I'll be working on it for the next few months at least, pretty hard I imagine; I'd like to make it restartless, and implement user script updates & communication asap. If you think you'd like to open it up and hack on it, then please do!!

Click Tracking JavaScript Library Now Available

Purpose

To help web publishers easily track link clicks the correct way, across browser platforms, with tools like Google Analytics (GA) and Google Website Optimizer (GWO).

Typically a web publisher will want to do something like track all external links on a website with GA, setup a GWO test where the conversion is a click through, or do both on the same page for a few pages of their site. This javascript library was designed to make tasks such as these simple.

About

clickTrackingLib

Adding the click-tracking-lib.js or the click-tracking-lib-with-presets.js to a web page provides you with a clickTrackingLib javascript object. Once you provide clickTrackingLib with some match objects, you can then have clickTrackingLib scan a single, set, or all document links to determine if the link(s) should have tracking functions applied to it or not, and do so if needed. If one or more tracking functions are applied to a link, then a delay function will be applied to the link (this can be disabled too of course, and the delay can user defined but the default is 99 ms).

The Delay Function

The delay function is meant to delay the user from being redirected to a new page for just a bit to allow time for say a Google Analytics image request to complete, and avoid being canceled by the user's browser. It can be disabled, but it is added by with a 99 sec delay by default, which can be customized, as the very last onClick event listener, after all of the desired provided Match object trackingFunc's are applied.

The delay function technically only sets a timeout to redirect the user after x ms, but in order for the delay to work the link's default functionality, namely redirecting the user, needs to be disabled, if the link doesn't just open in a new tab (target="_blank" and target="_new" are checked for). To disable the default functionality the link's onclick attribute must be set to onclick="return false;" which I figured should be fine because all well made websites won't use that attribute except to make it equal to "return false;" anyhow. If your site is not well made, then you should think about fixing it or having it fixed for you, but you can still use this library by simply not using the delay function and implementing it by some other means.

Presets

There are a number of presets available if you use click-tracking-lib-with-presets.js or click-tracking-presets.js; presets are predefined match functions for common use cases, such as matching all internal links, or external links, or download links. They can be used as they written, you could cut out the ones you won't use, or simply use them as examples when you define your own custom match objects.

The can be accessed from the clickTrackingLib.getMatchPreset( name ) method. The possible name values and the meanings behind them are as follows:

  • 'rel-external': matches rel-external links
  • 'external-hostname': matches external hostname links
  • 'all-external': matches all rel-external and external hostname links
  • 'filetypes': matches file names: (docx*|xlsx*|pptx*|exe|zip|pdf|xpi|rar|xls)
  • 'non-rel-external': matches non-rel-external links
  • 'internal-hostname': matches internal hostname links
  • 'all-internal': matches non-rel-external links or internal hostname links

Match Objects

Any object that has a 'match(link):boolean' method and 'trackingFunc(event,link):void' method defined.

match(link):boolean

This method will take a link element as input, run some test on it and return true or false, if true is returned then the Match object's trackingFunc will be added to the link.

trackingFunc(event,link):void

This method will be provided with two input values; event is the click event object, and link is a reference to the link element. You can obtain a reference to this from the event object, but there is some cross browser logic you would need to implement, so I thought a direct reference to the link would be handy. The function should not return anything.

new clickTrackingLib._clickTrackingLib();

If you want to create multiple clickTrackingLib objects, that contain different sets of match object arrays, then you need to create a new one, like so:

var myNewClickTrackingObj = new clickTrackingLib._clickTrackingLib();

This will give you a new object, myNewClickTrackingObj, which is like clickTrackingLib in all but two ways. First myNewClickTrackingObj will not have a _clickTrackingLib() method, and second it will not have a getMatchPreset() method, even if clickTrackingLib.getMatchPreset() was defined. This is because you don't need a bunch of objects in memory with those two methods, only one, which is the singleton clickTrackingLib object.

How To Use

  1. Download either click-tracking-lib-with-presets.js or click-tracking-lib.js (see ABOUT fore more information) from the project repository at GitHub.
  2. Minify it with one of the following options:
  3. Upload the minified script to your site.
  4. Add <script src=".." type="text/javascript"></script> for the script to the desired pages.
  5. Write some code:
    • define some match objects (just an object with a match method and trackingFunc method)
    • Add match objects to your clickTrackingLib object
    • Call the clickTrackingLib.attachTrackingFunctions( links, delay ) when desired.
      • links: can be a single anchor element, an array of anchor elements, or falsely so that the default is used, which is document.links.
      • delay: should be a positive integer or falsey, in the latter case no delay function will be added to the links scanned, in the former case a delay function will be applied with the specified delay value.

[More]

Start Tracking Your JavaScript Disabled Visitors With GA.CFC

Google Analytics depends on JavaScript to make image requests to GA servers, and therefore only tracks your JavaScript enabled visitors. This is why Remy Sharp wrote a blog post a few weeks ago called "The Missing Stat: noscript" where he outlined some work he'd done on how to track your noscript visitors with Google Analytics and PHP.

If you read the comments on Remy's post, you will see that his PHP code was ported to .NET by Erik Zaadi which is available at Github here and called "GA.NET". Erik also wrote about his project here.

So after reading all of this I decided to port the code to ColdFusion, but after reviewing the code Remy wrote I started to see some real potential for handing the GA tracking logic for the image requests made to GA servers with server side code. In other words, you should be able to track page views, events, and more on your visitors that have JavaScript disabled.

So I started GA.CFC for ColdFusion and put it on GitHub, it's basically Remy's PHP code ported to CF, with the one difference being that when using GA.CFC you must provide the domain hash which GA generates to GA.CFC, which I guess Remy thought was a random number; his code worked anyhow apparently though.

I plan to extract GA's hash function later so that you won't have to input the domain hash, and I have plenty more updates planned for the future, but I decided to upload GA.CFC to GitHub now so that others can use it in the meantime.

Currently you can track pageviews, but each page view is considered a new visitor. Please read the README file for GA.CFC for usage instructions.

Get GA.CFC at GitHub here

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