Scripting LittleSnapper… Slight Return
Less then a week after writing [*this*][sls] AppleScript — which launches [LittleSnapper][ls] and snaps the website currently in view in Safari — the boys at Realmac Software come out with [*this bookmarklet*][bml] that does exactly the same thing, only with a mouse-click instead of a hot-key combination… unless you’re me.
I loath the mouse and if I can avoid ever using it I will go to great lengths to make sure my hands stay firmly atop my keyboard. Perhaps you’re the same way, so for kicks I turned Realmac Software’s bookmarklet into an executable AppleScript that I can assign a hot-key to.
## What’s a bookmarklet? ##
First you have to understand what a bookmarklet does. A bookmarklet is nothing more then a bit of javascript (in many cases) that when clicked performs a basic task. It’s like a mini application… like an applet… in fact, it *is* an applet, hence the name “bookmark”-”let”. In the case of the LittleSnapper bookmarklet, clicking the bookmark (or URL) tells your browser (in javascript) to change the URL in the address bar from `http://example.com` to `littlesnapper://snap/http://example.com`. You’re just adding `littlesnapper://snap/` to the front of any URL! You can actually do this yourself, provided you have LittleSnapper. Try going your favorite website, click the address field, type `littlesnapper://snap/` in front of the URL and hit return… ta-da!
## Make one-click easier? ##
So let’s go back to actually using the bookmarklet… you have to click on it and that’s no fun. It’s time to turn it into AppleScript!
The bookmarklet, if you look at it in your bookmarks folder, looks like this:
javascript:location.href=’littlesnapper://snap/’+location.href;
The quick and dirty way to turn this into an executable AppleScript would be to use Safari’s built in `do JavaScript` method, like this:
tell application “Safari”
do JavaScript “location.href=’littlesnapper://snap/’\n
+location.href;” in document 1
end tell
But that would leave you pretty much locked into using the script with Safari when using hot-keys, while *clicking* the bookmarklet will work in any browser. So `do JavaScript` is too limiting.
Since we only need to pass in the string `littlesnapper://snap/` before the URL, why not just write a method that does that:
tell application “Safari”
set currentURL to URL of front document
open location “littlesnapper://snap/” & currentURL
end tell
This works, but if you want to apply it to all other browsers — Opera, Camino, Firefox, etc — you have a lot of work ahead of you as you discover the various degrees of scriptability each app has. To grab the URL in some of these apps you have to jump through hoops:
* in safari it’s `URL of front document`
* for Firefox `«class curl» of window 1` will sometimes work
* Camino is `URL of browser window 1` and so on…
Some apps need to use System Events to access them, others don’t. And then try and tell each one that you want to `open location`, again with or without System Events… it turns into argument soup very quickly.
A good rule of thumb when trying to script anything is to simplify the number of tasks you assign to any given process. In this case, for each browser I am trying to do two things; get the current URL and then open a new, modified URL.
## LittleSnapper is a browser too! ##
Then it got me thinking — LittleSnapper uses webkit as it’s rendering engine and therefor it should share a lot of the same scripting dictionary that Safari uses. So I thought I would test something out; I attempted to `open location “littlesnapper://snap…` with LittleSnapper itself:
set currentURL to “http://www.google.ca”
tell application “LittleSnapper”
open location “littlesnapper://snap/” & currentURL
end tell
Viola! Without opening a “browser”, I just snapped a web shot of Google.ca, right in LittleSnapper. This now cuts the workload of running unique scripts for each browser in half since I can now tell LittleSnapper to open the URL… once I have it.
## Scripting a common thread ##
So now to get the URL from the browser — any browser — without making a code spaghetti like this mess:
if application “Firefox”is running then
tell application “Firefox”
set currentURL to «class curl» of window 1
end tell
else if application “Safari”is running then
tell application “Safari”
set currentURL to URL of front document
end tell
else if application “Opera”is running then
tell application “Opera”
set props to GetWindowInfo of window 1
set currentURL to item 1 of props
end tell
else if application “Camino”is running then
tell application “Camino”
set currentURL to URL of window 1
end tell
end if
There has to be a better way… and there is. Here comes System Events to the rescue with a couple of keystroke executions like so:
tell application “System Events”
– highlight address field with ⌘L
keystroke “l” using {command down}
– copy to clipboard with ⌘C
keystroke “c” using {command down}
end tell
This will allow us to access any browser the same way, with global hot-keys as executed by AppleScript.
Now we just need to talk to those browsers to find out which one is in use. We can do this with an if statement, like this:
if application “Safari” is running then
tell application “System Events”
keystroke “l” using {command down}
keystroke “c” using {command down}
end tell
end if
But with four or more browsers this would be a bit much.
## The full deal ##
So let’s make an array out of our favorite browsers, run that array through a loop, mash in our System Event keystrokes, and finish it all off with a variable passed into LittleSnapper and this is what we get:
– let’s define our array
set appArray to {“Safari”, “Firefox”, “Opera”, “Camino”}
– then run that array through a loop
repeat with appName in appArray
if application appName is running then
tell application appName to activate
tell application “System Events”
keystroke “l” using {command down}
keystroke “c” using {command down}
end tell
delay 0.5
– make a variable from the clipboard
set currentURL to the clipboard
end if
end repeat
– pass that variable in to LittleSnapper
tell application “LittleSnapper”
activate
open location “littlesnapper://snap/” & currentURL
end tell
Is this overkill to get a hot-key combo that does what a bookmarklet does in one click? Depends on who you ask I guess. I think it’s a pretty good solution in fact. Now instead of copying a bookmarklet to the toolbar of every browser I use, I have a script that I can assign a global hot-key to (via [FastScripts][fs] or some such tool) and use it across any browser I set in my array.
Yes, I am *that* much of a geek.
## Download ##
[Get it fresh from CodeCollector.net][ccdn2]
[tags]applescript,littlesnapper,realmac,software,safari,firefox,opera,camino,browser,bookmarklet,hot-key[/tags]
[sls]: http://www.seydoggy.com/2009/09/30/scripting-littlesnapper/ “seyDoggy Web and Graphic Design – seyDoggy weblog – my thoughts on the web and the mac”
[ls]: http://www.realmacsoftware.com/littlesnapper/ “LittleSnapper – Screenshot and Website Capture for Mac OS X Leopard”
[bml]: http://www.realmacsoftware.com/blog/index_files/littlesnapper-bookmarklet.php “Realmac Software Blog – RapidWeaver and LittleSnapper News”
[fs]: http://www.red-sweater.com/fastscripts/ “FastScripts”
[ccdn2]: http://www.codecollector.net/view/E8CE65D6-67B3-45DF-A3E5-745F9616F1B3 “Download from CodeCollector.net”
FireFox CSS Hacks
Sometimes it’s not Internet Explorer, and sometimes it’s not FireFox… Sometimes it’s (*gasp*) Safari. I always develop for Safari and then fix everything else but sometimes, just *sometimes* you come across a situation where IE7, IE8 and FireFox 3 all render the same way. By law of averages, wouldn’t that mean that Safari has it wrong? Well let’s not jump to nasty conclusions, that doesn’t *prove* anything right?
Well regardless, I’m not about to start hacking for Safari (on moral grounds), so that leaves CSS hacking for IE7, IE8 and FireFox 3 (IE6 is just a given so were not going there). IE7 and IE8 are dealt with well enough using condition comments, <!–[if IE 7]> or <!–[if IE 8]> for example, but CSS hacks for FireFox are a different beast.
Some time ago I stumbled across [this guys trick](http://pornel.net/firefoxhack “CSS hack for Firefox 1.x/2.x only”) that goes something like this:
`#yourSelector, x:-moz-any-link {styles for Firefox 2.0 here}`
`#yourSelector, x:-moz-any-link, x:default {restore styles for Firefox 3.0 and newer}`
You can read more about it there, but in short, the :-moz-any-link is a private Gecko selector that other browser just ignore. Be warned though, it doesn’t validate so you’ll want to move it out to a javascript file or something if you are concerned about that sort of thing.
I don’t use this that often (only once before in fact), but it sure is handy to have in the toolbox sometimes.
[tags]firefox, css, hacks, ie6, ie7, ie8, internet explorer, safari, web design[/tags]
Camino 1.5.2
Camino issues a maintenance releases to 1.5.1
Camino 1.5.2 contains the following improvements over version 1.5.1:
- Upgraded to version 1.8.1.8 of the Mozilla Gecko rendering engine, which includes several critical security and stability fixes.
- Large download lists and corrupt site icons will no longer cause Camino to stop loading pages or opening windows.
- When viewing the source of a frame, Camino now uses cached data instead of requesting the frame again.
- When JavaScript code wants to focus a minimized window, Camino now properly restores the window from the Dock.
- Pages which perform actions when the tab or window is closed now function properly.
- Camino no longer adds site icons for local files to the site icon cache.
- Upgraded the “Block flash animations†code to use Flashblock 1.5.4.1.
- Upgraded the bundled Java Embedding Plugin to version 0.9.6.3.
- Improved ad-blocking.
[tags]Camino, Mozilla, Firefox, web browser[/tags]

