/contextificator

A js client side bookmarklet that adds context to the web pages you're reading

Primary LanguageJavaScript

Contextificator

Contextificator was my entry to Yahoo Hack Europe 2013.
It's currently a javascript bookmarklet that adds a side panel to the page you're viewing, showing additional context. It uses the Yahoo! Content Analysis API, YUI, YQL, Yahoo BOSS, Google Maps, the Wikipedia API, and is entirely client-side.

Use

It's not really good for actual use at the moment. For one thing, everything is served from github via rawgithub, and you shouldn't use those for anything more than testing. For another, some of the APIs used won't work beyond the hack weekend (time limited keys) so you won't get too much data.

Because this is under 24 hours work (I went to bed) from a hack weekend it's also very inefficient (in terms of network requests), probably badly structured (though not complete spaghetti), and lightly tested. Comments and docblocks are mostly present but fairly brief.

Code

This is mainly intended as a note-to-self for when I come back to it...

Starting up

  • inlinejs.js contains the javascript that goes in the bookmarklet.
  • bookmarklet.js is the first page that's loaded. It injects the iframe into the parent page, which contains the requests for YUI and goContext.js (and Google maps). Everything happens in the iframe so we don't mess with the parent page, especially if it has YUI (potentially a different version) on it already.
  • goContext.js is the main 'application'. It sets up the YUI instances (one bound to the parent window, one to the iframe) and loads the modules which request data, parse responses, and render it.

Content analysis

The main classes for the first stage of content analysis is CFContextAnalyseParser.js which receives the results from the Content Analysis API and creates a set of CFContextAnalyseEntity instances. CFContextAnalyseEntity extends Model, but the Parser does not extend ModelList - I wasn't sure that all the Models I'd end up with were going to be of the same type, and I wasn't sure whether there'd be any issues with ModelList if that was the case.

Each 'Entity' is a detected person, place, concept etc that comes from the Content Analysis. The CFContextAnalyseEntity class has a findDetail method.

Now the CFContextAnalyseParser holds an object which contains 'data services' - classes described below that request data from particular places.

Each Entity has a reference to the parent Parser, so can use these services to request data about itself. So the findDetail method accesses the services provided by the parser, and renders them using the 'static' renderers object passed to the method.

This is almost certainly sub-optimal. However once it was set up it seemed pretty quick and easy to add data sources: create a 'service' class, a 'view' to render it, provide them via the parser and consume them in the Entity.

'Additional data' classes - services and views

The rest are extensions of Base, Model, or View.

Things like CFDataBoss.js have a one or two public methods (text(str) or url(address)), make a YQL or jsonp request and parse the results, firing an event when they're available.

Things like CFDataBossWebView.js extend View but perhaps shouldn't. They're really used as static rendering functions, and would probably be better as such unless there's going to be DOM events to deal with (which I suppose there might in the future). Anyway, they generally have just one public method render() which renders the data parsed by the relevant data-getter-parser (e.g. CFDataBoss.js). Because they are essentially static at the moment, they use a renderTo attribute because container is writeOnce, which is no good because I want to be able to render to different places with the same View. That's also why I think they probably shouldn't be Views.