Permalink
Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign up
translators/COinS.js
Find file
Copy path
Fetching contributors…
Cannot retrieve contributors at this time
{ | |
"translatorID": "05d07af9-105a-4572-99f6-a8e231c0daef", | |
"label": "COinS", | |
"creator": "Simon Kornblith", | |
"target": "", | |
"minVersion": "2.1", | |
"maxVersion": "", | |
"priority": 310, | |
"inRepository": true, | |
"translatorType": 6, | |
"browserSupport": "gcsv", | |
"lastUpdated": "2015-06-04 03:25:10" | |
} | |
function detectWeb(doc, url) { | |
var spanTags = doc.getElementsByTagName("span"); | |
var encounteredType = false; | |
// This and the x: prefix in the XPath are to work around an issue with pages | |
// served as application/xhtml+xml | |
// | |
// https://developer.mozilla.org/en/Introduction_to_using_XPath_in_JavaScript#Implementing_a_default_namespace_for_XML_documents | |
function nsResolver() { | |
return 'http://www.w3.org/1999/xhtml'; | |
} | |
var spans = doc.evaluate('//x:span[contains(@class, " Z3988") or contains(@class, "Z3988 ") or @class="Z3988"][@title]', doc, nsResolver, XPathResult.ANY_TYPE, null); | |
var span; | |
while (span = spans.iterateNext()) { | |
// determine if it's a valid type | |
var item = new Zotero.Item; | |
var success = Zotero.Utilities.parseContextObject(span.title, item); | |
if (item.itemType) { | |
if (encounteredType) { | |
return "multiple"; | |
} else { | |
encounteredType = item.itemType; | |
} | |
} | |
} | |
return encounteredType; | |
} | |
// Borrowed from Nature translator | |
function supplementItem(item, supp, prefer, ignore) { | |
if (!prefer) prefer = []; | |
if (!ignore) ignore = []; | |
for (var i in supp) { | |
if (ignore.indexOf(i) != -1) continue; | |
if (i == 'creators' || i == 'attachments' || i == 'notes' | |
|| i == 'tags' || i == 'seeAlso' | |
) { | |
if ( (item.hasOwnProperty(i) && item[i].length) // Supplement only if completely empty | |
|| (!supp[i].length || typeof supp[i] == 'string') | |
) { | |
continue; | |
} | |
} else if (!supp.hasOwnProperty(i) | |
|| (item.hasOwnProperty(i) && prefer.indexOf(i) == -1)) { | |
continue; | |
} | |
Z.debug('Supplementing item.' + i); | |
item[i] = supp[i]; | |
} | |
return item; | |
} | |
// used to retrieve next COinS object when asynchronously parsing COinS objects | |
// on a page | |
function retrieveNextCOinS(needFullItems, newItems, couldUseFullItems, doc) { | |
if (needFullItems.length) { | |
var item = needFullItems.shift(); | |
Zotero.debug("Looking up contextObject"); | |
var search = Zotero.loadTranslator("search"); | |
search.setHandler("itemDone", function(obj, newItem) { | |
supplementItem(newItem, item, [], ['contextObject', 'repository']); | |
newItems.push(newItem); | |
}); | |
search.setHandler("done", function() { | |
retrieveNextCOinS(needFullItems, newItems, couldUseFullItems, doc); | |
}); | |
// Don't throw on error | |
search.setHandler("error", function() { | |
Zotero.debug("Failed to look up item:"); | |
Zotero.debug(item); | |
}); | |
// look for translators | |
search.setHandler("translators", function(obj, translators) { | |
if (translators.length) { | |
search.setTranslator(translators); | |
search.translate(); | |
} else { | |
retrieveNextCOinS(needFullItems, newItems, couldUseFullItems, doc); | |
} | |
}); | |
search.setSearch(item); | |
search.getTranslators(); | |
} else { | |
completeCOinS(newItems, couldUseFullItems, doc); | |
Zotero.done(); | |
} | |
} | |
// saves all COinS objects | |
function completeCOinS(newItems, couldUseFullItems, doc) { | |
if (newItems.length > 1) { | |
var selectArray = new Array(newItems.length); | |
for (var i in newItems) { | |
selectArray[i] = newItems[i].title; | |
} | |
Zotero.selectItems(selectArray, function (selectArray) { | |
if (!selectArray) return true; | |
var useIndices = new Array(); | |
for (var i in selectArray) { | |
useIndices.push(i); | |
} | |
completeItems(newItems, useIndices, couldUseFullItems, doc); | |
}); | |
} else if (newItems.length) { | |
completeItems(newItems, [0], couldUseFullItems, doc); | |
} | |
} | |
function completeItems(newItems, useIndices, couldUseFullItems, doc) { | |
if (!useIndices.length) { | |
return; | |
} | |
var i = useIndices.shift(); | |
// grab full item if the COinS was missing an author | |
if (couldUseFullItems[i]) { | |
Zotero.debug("Looking up contextObject"); | |
var search = Zotero.loadTranslator("search"); | |
var firstItem = false; | |
search.setHandler("itemDone", function(obj, newItem) { | |
supplementItem(newItem, newItems[i], [], ['contextObject', 'repository']); | |
if (!firstItem) { | |
// add doc as attachment | |
newItem.attachments.push({document:doc}); | |
newItem.complete(); | |
firstItem = true; | |
} | |
}); | |
search.setHandler("done", function(obj) { | |
// if we didn't find anything, use what we had before (even if it | |
// lacks the creator) | |
if (!firstItem) { | |
newItems[i].complete(); | |
} | |
// call next | |
completeItems(newItems, useIndices, couldUseFullItems); | |
}); | |
// Don't throw on error | |
search.setHandler("error", function() {}); | |
search.setHandler("translators", function(obj, translators) { | |
if (translators.length) { | |
search.setTranslator(translators); | |
search.translate(); | |
} else { | |
// add doc as attachment | |
newItems[i].attachments.push({document:doc}); | |
newItems[i].complete(); | |
// call next | |
completeItems(newItems, useIndices, couldUseFullItems); | |
} | |
}); | |
search.setSearch(newItems[i]); | |
search.getTranslators(); | |
} else { | |
// add doc as attachment | |
newItems[i].attachments.push({document:doc}); | |
newItems[i].complete(); | |
// call next | |
completeItems(newItems, useIndices, couldUseFullItems); | |
} | |
} | |
function doWeb(doc, url) { | |
var newItems = new Array(); | |
var needFullItems = new Array(); | |
var couldUseFullItems = new Array(); | |
// See note in detectWeb() | |
function nsResolver() { | |
return 'http://www.w3.org/1999/xhtml'; | |
} | |
var spans = doc.evaluate('//x:span[contains(@class, " Z3988") or contains(@class, "Z3988 ") or @class="Z3988"][@title]', doc, nsResolver, XPathResult.ANY_TYPE, null); | |
var span; | |
while (span = spans.iterateNext()) { | |
var spanTitle = span.title; | |
var newItem = new Zotero.Item(); | |
newItem.repository = false; // do not save repository | |
if (Zotero.Utilities.parseContextObject(spanTitle, newItem)) { | |
if (newItem.title) { | |
if (!newItem.creators.length) { | |
// if we have a title but little other identifying | |
// information, say we'll get full item later | |
newItem.contextObject = spanTitle; | |
couldUseFullItems[newItems.length] = true; | |
} | |
// title and creators are minimum data to avoid looking up | |
newItems.push(newItem); | |
} else { | |
// retrieve full item | |
newItem.contextObject = spanTitle; | |
needFullItems.push(newItem); | |
} | |
} | |
} | |
Zotero.debug(needFullItems); | |
if (needFullItems.length) { | |
// retrieve full items asynchronously | |
Zotero.wait(); | |
retrieveNextCOinS(needFullItems, newItems, couldUseFullItems, doc); | |
} else { | |
completeCOinS(newItems, couldUseFullItems, doc); | |
} | |
} | |
function doExport() { | |
var item; | |
var co; | |
while (item = Zotero.nextItem()) { | |
co = Zotero.Utilities.createContextObject(item, "1.0"); | |
if (co) { | |
Zotero.write("<span class='Z3988' title='"+ Zotero.Utilities.htmlSpecialChars(co) +"'></span>\n"); | |
} | |
} | |
} | |
/** BEGIN TEST CASES **/ | |
var testCases = [ | |
{ | |
"type": "web", | |
"url": "http://www.husdal.com/2011/06/19/disruptions-in-supply-networks/", | |
"items": [ | |
{ | |
"itemType": "journalArticle", | |
"creators": [ | |
{ | |
"firstName": "Phil", | |
"lastName": "Greening", | |
"creatorType": "author" | |
}, | |
{ | |
"firstName": "Christine", | |
"lastName": "Rutherford", | |
"creatorType": "author" | |
} | |
], | |
"notes": [], | |
"tags": [], | |
"seeAlso": [], | |
"attachments": [ | |
{} | |
], | |
"publicationTitle": "International Journal of Logistics Management", | |
"title": "Disruptions and supply networks: a multi-level, multi-theoretical relational perspective", | |
"date": "2011", | |
"volume": "22", | |
"issue": "1", | |
"pages": "104-126", | |
"libraryCatalog": false, | |
"shortTitle": "Disruptions and supply networks" | |
} | |
] | |
}, | |
{ | |
"type": "web", | |
"url": "http://gamblershouse.wordpress.com/2011/06/19/the-view-from-dolores/", | |
"items": "multiple" | |
}, | |
{ | |
"type": "web", | |
"url": "http://www.hubmed.org/display.cgi?uids=21665052", | |
"items": [ | |
{ | |
"itemType": "journalArticle", | |
"creators": [ | |
{ | |
"creatorType": "author", | |
"firstName": "Hui-Wen Vivian", | |
"lastName": "Tang" | |
} | |
], | |
"notes": [], | |
"tags": [], | |
"seeAlso": [], | |
"attachments": [ | |
{} | |
], | |
"publicationTitle": "Evaluation and Program Planning", | |
"volume": "34", | |
"issue": "4", | |
"language": "en", | |
"ISSN": "01497189", | |
"date": "11/2011", | |
"pages": "343-352", | |
"DOI": "10.1016/j.evalprogplan.2011.04.002", | |
"url": "http://linkinghub.elsevier.com/retrieve/pii/S0149718911000449", | |
"title": "Optimizing an immersion ESL curriculum using analytic hierarchy process", | |
"libraryCatalog": "CrossRef" | |
} | |
] | |
} | |
] | |
/** END TEST CASES **/ |