diff --git a/css/app.css b/css/app.css index 9edceb57c..82e90b0e3 100644 --- a/css/app.css +++ b/css/app.css @@ -883,8 +883,16 @@ div.typeahead a:first-child { padding: 20px; border-bottom: 1px solid #ccc; } + .modal-section:last-child { border-bottom: 0;} +.modal-section img.wiki-image { + max-width: 400px; + max-height: 300px; + padding: 10px; + display: block; +} + .changeset-list li { border-top:1px solid #ccc; padding:5px 10px; diff --git a/index.html b/index.html index a9cee5311..e44acbd39 100644 --- a/index.html +++ b/index.html @@ -20,6 +20,7 @@ + @@ -30,6 +31,7 @@ + @@ -48,6 +50,7 @@ + diff --git a/js/id/services/wiki.js b/js/id/services/wiki.js new file mode 100644 index 000000000..7273dffed --- /dev/null +++ b/js/id/services/wiki.js @@ -0,0 +1,32 @@ +iD.wiki = function() { + var wiki = {}, + endpoint = 'http://wiki.openstreetmap.org/w/api.php'; + // ?action=query&prop=imageinfo&titles=Image:Residential.jpg&iiprop=url%7Ccontent&format=json&callback=foo', + + wiki.image = function(img, callback) { + d3.jsonp(endpoint + '?' + + iD.util.qsString({ + action: 'query', + prop: 'imageinfo', + titles: img, + iiprop: 'url', + format: 'json', + callback: '{callback}' + }), function(d) { + try { + callback(null, + d.query.pages[Object.keys(d.query.pages)[0]].imageinfo[0].url); + } catch(e) { + callback(new Error('Image not found')); + } + }); + }; + + wiki.endpoint = function(_) { + if (!arguments.length) return endpoint; + endpoint = _; + return wiki; + }; + + return wiki; +}; diff --git a/js/id/ui/inspector.js b/js/id/ui/inspector.js index 6ad48acc5..f0ee956a4 100644 --- a/js/id/ui/inspector.js +++ b/js/id/ui/inspector.js @@ -151,10 +151,14 @@ iD.Inspector = function() { if (en.on_node) types.push('point'); if (en.on_way) types.push('line'); en.types = types; - var mod = iD.modal(); - mod.select('.content') + iD.modal() + .select('.content') .datum(en) .call(iD.tagReference); + } else { + iD.flash() + .select('.content') + .text('This is no documentation available for this tag combination'); } }); d3.event.preventDefault(); diff --git a/js/id/ui/tag_reference.js b/js/id/ui/tag_reference.js index 338408823..f88576bef 100644 --- a/js/id/ui/tag_reference.js +++ b/js/id/ui/tag_reference.js @@ -21,9 +21,22 @@ iD.tagReference = function(selection) { referenceBody = selection.append('div') .attr('class','modal-section'); + referenceBody .append('h5') .text('Description'); + + if (selection.datum().image) { + iD.wiki().image(selection.datum().image, function(err, src) { + if (!err) { + referenceBody + .append('img') + .attr('class', 'wiki-image') + .attr('src', src); + } + }); + } + referenceBody .append('p') .text(g('description')); diff --git a/js/lib/d3.jsonp.js b/js/lib/d3.jsonp.js new file mode 100644 index 000000000..fba9951a9 --- /dev/null +++ b/js/lib/d3.jsonp.js @@ -0,0 +1,27 @@ +d3.jsonp = function (url, callback) { + + function rand() { + var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', + c = '', i = -1; + while (++i < 15) c += chars.charAt(Math.floor(Math.random() * 52)); + return c; + } + + function create(url) { + var e = url.match(/callback=d3.jsonp.(\w+)/), + c = e ? e[1] : rand(); + d3.jsonp[c] = function(data) { + callback(data); + delete d3.jsonp[c]; + script.remove(); + }; + return 'd3.jsonp.' + c; + } + + var cb = create(url), + script = d3.select('head') + .append('script') + .attr('type', 'text/javascript') + .attr('src', url.replace(/({|%7B)callback({|%7D)/, cb)); + +}; diff --git a/test/data/foo.jsonp b/test/data/foo.jsonp new file mode 100644 index 000000000..5266fcbdc --- /dev/null +++ b/test/data/foo.jsonp @@ -0,0 +1 @@ +d3.jsonp.foo('foo'); diff --git a/test/index.html b/test/index.html index 55c1e95a8..db5464e14 100644 --- a/test/index.html +++ b/test/index.html @@ -24,6 +24,7 @@ + @@ -32,6 +33,7 @@ + @@ -133,6 +135,8 @@ + + diff --git a/test/spec/lib/jsonp.js b/test/spec/lib/jsonp.js new file mode 100644 index 000000000..764a8a58d --- /dev/null +++ b/test/spec/lib/jsonp.js @@ -0,0 +1,7 @@ +describe('JSONP', function() { + it('can request data', function() { + d3.jsonp('data/foo.jsonp?callback=d3.jsonp.foo', function(d) { + expect(d).to.eql('foo'); + }); + }); +});