From 669cad74f6ce3a63251a87086cc400be1a7d054f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Sat, 18 Jul 2015 01:14:17 -0500 Subject: [PATCH] Add wikidata asynchronously based on wikipedia ref #2680 --- index.html | 1 + js/id/services/wikidata.js | 22 ++++++++++++++++++++++ js/id/ui/preset/wikipedia.js | 20 ++++++++++++++++---- test/index.html | 1 + test/spec/ui/preset/wikipedia.js | 4 +++- 5 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 js/id/services/wikidata.js diff --git a/index.html b/index.html index 80d184a2f..cb539b9cc 100644 --- a/index.html +++ b/index.html @@ -43,6 +43,7 @@ + diff --git a/js/id/services/wikidata.js b/js/id/services/wikidata.js new file mode 100644 index 000000000..0718e2fdd --- /dev/null +++ b/js/id/services/wikidata.js @@ -0,0 +1,22 @@ +iD.services.wikidata = function() { + var wiki = {}, + endpoint = 'https://www.wikidata.org/w/api.php?'; + + // Given a Wikipedia language and article title, return an array of + // corresponding Wikidata entities. + wiki.itemsByTitle = function(lang, title, callback) { + lang = lang || 'en'; + d3.jsonp(endpoint + iD.util.qsString({ + action: 'wbgetentities', + format: 'json', + sites: lang.replace(/-/g, '_') + 'wiki', + titles: title, + languages: 'en', // shrink response by filtering to one language + callback: '{callback}' + }), function(data) { + callback(title, data.entities || {}); + }); + }; + + return wiki; +}; diff --git a/js/id/ui/preset/wikipedia.js b/js/id/ui/preset/wikipedia.js index b14ac9655..0d2317160 100644 --- a/js/id/ui/preset/wikipedia.js +++ b/js/id/ui/preset/wikipedia.js @@ -1,6 +1,7 @@ iD.ui.preset.wikipedia = function(field, context) { var dispatch = d3.dispatch('change'), wikipedia = iD.services.wikipedia(), + wikidata = iD.services.wikidata(), link, entity, lang, title; function i(selection) { @@ -88,7 +89,8 @@ iD.ui.preset.wikipedia = function(field, context) { var value = title.value(), m = value.match(/https?:\/\/([-a-z]+)\.wikipedia\.org\/(?:wiki|\1-[-a-z]+)\/([^#]+)(?:#(.+))?/), l = m && _.find(iD.data.wikipedia, function(d) { return m[1] === d[2]; }), - anchor; + anchor, + syncTags = {}; if (l) { // Normalize title http://www.mediawiki.org/wiki/API:Query#Title_normalization @@ -107,9 +109,19 @@ iD.ui.preset.wikipedia = function(field, context) { title.value(value); } - var t = {}; - t[field.key] = value ? language()[2] + ':' + value : undefined; - dispatch.change(t); + syncTags[field.key] = value ? language()[2] + ':' + value : undefined; + dispatch.change(syncTags); + + if (value && language()[2]) { + wikidata.itemsByTitle(language()[2], value, function (title, entities) { + var qids = entities && Object.keys(entities), + asyncTags = {}; + asyncTags.wikidata = qids && _.find(qids, function (id) { + return id.match(/^Q\d+$/); + }); + dispatch.change(asyncTags); + }); + } } i.tags = function(tags) { diff --git a/test/index.html b/test/index.html index 15775fc36..24aa35963 100644 --- a/test/index.html +++ b/test/index.html @@ -48,6 +48,7 @@ + diff --git a/test/spec/ui/preset/wikipedia.js b/test/spec/ui/preset/wikipedia.js index f90ab6e09..fc3ff1b41 100644 --- a/test/spec/ui/preset/wikipedia.js +++ b/test/spec/ui/preset/wikipedia.js @@ -27,7 +27,9 @@ describe('iD.ui.preset.wikipedia', function() { happen.once(selection.selectAll('.wiki-lang').node(), {type: 'change'}); wikipedia.on('change', function(tags) { - expect(tags).to.eql({wikipedia: 'de:Title'}); + expect(tags).to.satisfy(function (tags) { + return tags.wikipedia === 'de:Title' || 'wikidata' in tags; + }); }); selection.selectAll('.wiki-title').value('Title');