As part of an upcoming article on geo location I am putting together a few Geo Toys for myself and here is the first one. Addmap.js is a JavaScript that analyses an elements text content, finds geographical locations and links them to Google Maps. It also adds a map preview and a list of the found locations to the element.
See addmap.js in action below - all the content in the green box is generated from the paragraph of text above it. You can try it out for yourself by clicking the screenshot.
Using addmap.js is easy - sign up for a Google Maps Key and provide it as a configuration parameter. Then call the analyse function with the ID of the element to analyse as the parameter:
This loads the document any link with a class of "ajaxtrigger" points to and updates the content of the element with the ID "target". If the link is a third party link on another domain it fails though - and silently at that. Normally you'd work around that with a server-side proxy, but you can actually do without it.
YQL is a hosted web service that can scrape HTML for you. It also runs the HTML through HTML Tidy and caches it for you. For example to load http://bbc.co.uk you'd use the following statement:
You could request JSON-P by setting the output format to json and define a callback, but that would give the HTML back as a massive object which is not nice. YQL also offers JSON-P-X as an alternative which is a JSON object with a callback and the HTML as a string inside a simple Array. See it by clicking the following URL:
Now, using jQuery's getJSON() we can load this even without a named callback function. That way we can use one method for content that is third party and simply use load() for the other:
Douglas Crockford is Yahoo!'s JavaScript architect and a member of the committee designing future versions of the world's most popular programming language. In the first three months of 2010, Douglas will be delivering his acclaimed series of lectures on the history of JavaScript, its features, and its use.
Wednesday, March 31: Style and Performance in JavaScript (RSVP)
Lectures will be held in URLs Café, Building C, on Yahoo's main campus in Sunnyvale, CA. Doors open at 5:30 p.m.; lectures begin at 6 p.m. Pizza and refreshments will be served. Attendance is free, but seating is limited; RSVP is required for admittance.
It is amazing how much easier it is these days to build pretty sweet mashups by using hosted services. Here's a screencast of using Yahoo, Bing and Google to build a search interface in under 25 minutes without having to read any API docs or installing SDKs by using YQL:
We’re pleased to announce today the general-availability release of YUI 3.0.0. YUI 3’s core infrastructure (YUI, Node and Event) and its utility suite (including Animation, IO, Drag & Drop and more) are all considered production-ready with today’s release.
This is a ground-up redesign of YUI:
Selector-driven: YUI 3 is built around one of the lightest, fastest selector engines available, bringing the expressive power of the CSS selector specification into actions that target DOM nodes.
Syntactically terse: Without polluting the global namespace, YUI 3 supports a more terse coding style in which more can be accomplished with less code.
Self-completing: YUI 3’s light (6.2KB gzipped) seed file can serve as the starting point for any implementation. As long as this seed file is present on the page, you can load any module in the library on the fly. And all modules brought into the page via the built-in loader are done so via combo-handled, non-blocking HTTP requests. This makes loading the library safe, easy and fast.
Sandboxed: YUI modules are bound to YUI instances when you use() them; this protects you against changes that might happen later in the page’s lifecycle. (In other words, if someone blows away a module you’re using after you’ve created your YUI instance, your code won’t be affected.)
It's especially nice to see the new terse YUI namespacing, so you can just type YUI() instead of the older longer syntax.
The cool thing about YUI (and this release) is that it is literally driving the Yahoo! Home Page. That's pretty awesome of Yahoo! to release this code and make it generally available to the wider community. Congrats to the whole YUI team on the new release.
The Storage Utility is a wrapper for local storage supporting Google Gears, Flash or HTML5 and was submitted by Matt Snider who works for Mint.com.
The SWFStore utility, written by Alaric Cole provides a predictable API for interaction of Flash and JavaScript whilst Allen Rabinovic's SWF Utility is a more granular way of embedding Flash in web sites than SWFobject.
The ProgressBar control by Daniel Barreiro aka Satyam is another example of just how detailed YUI controls are when it comes to exposing custom events. This allows you to either use it out of the box or extend it by overwriting only what you need rather than messing around with the main code of the control.
Other noteworthy changes in YUI with the 2.8.0 release are an extension to the event handling component to support event delegation without having to write it in detail, the connection manager supporting crossdomain requests and getting cut up into smaller on-demand components, and the Carousel control getting a "gallery style".
Check out the more in-depth overview on the YUI blog.
Here's what it is and why it is useful: YQL data can be returned in XML which is annoying to use in JavaScript (for starters because of crossdomain issues in Ajax). JSON is much easier as it is native to JavaScript. JSON-P makes it even more easy for us to use as JSON data wrapped in a function call allows us to get the data by creating script nodes dynamically.
Where it falls apart is when you want to get back HTML from some system (not on your own server) and use it in JavaScript. You either need to convert the XML to JavaScript and create HTML elements from it or you need to loop through a JSON construct and assemble HTML from it. JSONP-X works around that step for you. In essence it is XML as a string returned inside a JSON object.
The way to invoke the JSONP-X output is to provide a format parameter of xml and a callback parameter.
This allows me for example to get the list of people I follow on twitter from my twitter homepage and display it in another document with a few lines of JavaScript without any need of using the API or having a local proxy:
As preparation for an upcoming tech talk about Placemaker I thought it would be good to take a bit of the pain out of the geolocation service by making an interface for it. Placemaker works the following way: you post some content or a URL to it, it goes through the content or gets the content from the URL and analyzes it. It then finds geographical locations in the text and disambiguates them (for example to skip names like "Jack London" and not consider it the city London). Finally you get it back as XML.
The annoying thing is that Placemaker only support POST request and does not have a JSON output - for now. GeoMaker allows non-developers to enter some text or a URL, filter the results (using YUI datatable) to remove false positives (no system is perfect) and get the embed code for a Yahoo Map or a list of microformatted locations as copy+paste. See the screencast to get the end user experience:
Of course, every time you build something like that, red-blooded developers will ask for an API to do the same thing (and pointing them to Placemaker wasn't enough). So here it is:
http://icant.co.uk/geomaker/api.php takes two parameters: url of the web document to load and output which could be map, kml, microformats, csv, or json (with callback for JSON-P). Using this you can analyze a url in JavaScript and get the data back as an array:
We’ve spent a lot of time in this release cycle refining the core elements of YUI 3 — YUI, Node, and Event — to ensure that we have the right API going forward. Performance is improved, and we’ve refined our module/submodule structure. In some cases we’ve added significant new features, including intrinsic support for event delegation in the Event package; however, the focus is on moving the base library to production quality.
Several YUI 2.x components make their YUI 3 debut in this release:
DataSource: YUI’s data abstraction layer provides a standard interface into data sets, regardless of the data’s origin (local, XHR, XSS, etc.) and format (JSON, XML, CSV, etc.);
ImageLoader: ImageLoader allows you to defer the loading of images that aren’t in the viewport when the page paints, throttling bandwidth usage and improving performance;
History: The History component gives you control of the brower’s back button within the context of a single-page web application;
StyleSheet: StyleSheet makes it easy to create and modify CSS rules on the fly, allowing you to dynamically style page elements with fewer repaints.
As part of the more granular packaging in the new codeline, we’ve created separate YUI 3 modules to house functionality that in YUI 2 was bundled with other components. Cache, DataType and DataSchema debut in this release; each of these used to be a part of DataSource.
To keep up to date, check out the roadmap and dashboard that the team keeps up to date.
One thing that annoys me is that in the days of geolocation and location recognition I still have to enter my country and city in forms over and over again. This is especially annoying when you like in the UK which could be anywhere in these wonderful large dropdowns (UK, England, Great Britain, United Kingdom, Blighty...).
There are many geo lookup tools and a lot of (at least UK) web sites started doing post code lookup tools. This is cool, but as annoying when I spent another reload of a full large form for a postcode lookup that went wrong. With the UK being quite a mess when it comes to post codes this is not uncommon.
Now, to work around these issues I've put together a small JavaScript wrapper library called GeoFill (also available on GitHub). This one makes it easy to provide a "is this your location" functionality in JavaScript:
GeoFill has two different methods to automatically fill forms with geo information:
geofill.find(properties) does an IP lookup of the current user and tries to get the geographical data from that one.
geofill.lookup(properties,postcode) tries to get the geographical data from the postcode provided in your form.
Both methods can either automatically fill a form when you provide them with an object telling it which info should go into the form with a given ID, but also have a callback property that allows you to use the data immediately
Talks about JavaScript are not a rare occasion any more, everybody has something to say about this wonderfully versatile language. Douglas Crockford taught us a lot about the language itself, John Resig and Peter Paul Koch taught us how browsers deal (and fail dealing) with it and there are dozens of screencasts of how to use this or that language.
What most of these talks and videos have in common is application of JavaScript and how to deal with issues that will occur. Information about designing and architecting large JavaScript solutions on the other hand are rare. Satyen Desai now broke the silence and gave a great talk on the architecture and design decisions of the the third generation of the Yahoo User Interface library:
I am a big fan of YQL, a terribly easy and fuss-free way to access APIs and mix data retrieved from them in a simple, SQL style language. Say for example you want photos of Paris,France from Flickr that are licensed with Creative Commons attribution, you can do this with a single command:
select * from flickr.photos.info where photo_id in (select id from flickr.photos.search where woe_id in (select woeid from geo.places where text='paris,france') and license=4)
One thing that's been burning on my tongue to tell the world about has been finally released now: YQL execute. Instead of making the YQL language itself much more complex (and thus running in circles) we now allow you to embed JavaScript in the Open Table XML that will run on the YQL server and allow you to access other web services, authenticate and scrape HTML with JavaScript and E4X. As Simon Willison put it:
This is nuts (in a good way). Yahoo!’s intriguing universal SQL-style XML/JSONP web service interface now supports JavaScript as a kind of stored procedure language, meaning you can use JavaScript and E4X to screen-scrape web pages, then query the results with YQL.
Using this, you can augment the original functionality of YQL to whatever you need. For example, you can scrape HTML with YQL using XPATH, but there was no way to use CSS selectors. Using an open table that invokes James Padolsey's css2xpath JavaScript on the server side, this is now possible.
use 'http://yqlblog.net/samples/data.html.cssselect.xml' as data.html.cssselect; select * from data.html.cssselect where url="www.yahoo.com" and css="#news a"
The main findings of the team were that eval() is not only evil but also very slow whereas dynamic script nodes are fast but insecure. The solution was to do a custom evaluation of string data rather than using JSON:
Having set the performance bar pretty high with the last approach, we dove into custom data formats. The challenge would be to create a format that we could parse ourselves, using JavaScript’s String and RegExp methods, that would also match the speed of JSON executed natively. This would allow us to use Ajax again, but keep the data restricted to our domain.
Since we had already discovered that some methods of string manipulation didn’t perform well on large strings, we restricted ourselves to a method that we knew to be fast: split(). We used control characters to delimit each contact, and a different control character to delimit the fields within each contact. This allowed us to parse the string into contact objects with one split, then loop through that array and split again on each string.
for(var n = 0, len = that.contacts.length, contactSplit; n <len; n++){
contactSplit = that.contacts[n].split("\\a");
that.contacts[n] = {};
that.contacts[n].n = contactSplit[0];
that.contacts[n].e = contactSplit[1];
that.contacts[n].u = contactSplit[2];
that.contacts[n].r = contactSplit[3];
that.contacts[n].s = contactSplit[4];
that.contacts[n].f = contactSplit[5];
that.contacts[n].a = contactSplit[6];
that.contacts[n].d = contactSplit[7];
that.contacts[n].y = contactSplit[8];
}
Once this had been speeded up, all they needed to use was the YUI AutoComplete control and voilà - fast client side searches even with massive datasets.
Using the Selector utility in YUI2 I would find myself hitting bugs and roadblocks where my expectations weren’t matching the outcomes. I’ve felt since first using the selector engine in YUI that it didn’t compare in speed, robustness, or completeness to jQuery’s. With the Sizzle project, there’s a narrow focus and distinct vision: To make the best damn selector engine. Since a selector engine is an essential component to any modern JavaScript library, why not make one really good one for all libraries to use? That’s the route the Sizzle project has taken.
Once Sweeney’s branch is merged into the YUI3 Master Head, I’ll be doing a git pull and give it some exercise.