From e61dd6002456543b26869da7030b49bb054d461b Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Wed, 27 Oct 2010 00:36:20 +0000 Subject: [PATCH] move Zotero.Date and Zotero.OpenURL to independent files --- chrome/content/zotero/xpcom/date.js | 695 ++++++++++++++++++ .../content/zotero/xpcom/mimeTypeHandler.js | 61 +- .../zotero/xpcom/{ingester.js => openurl.js} | 45 -- chrome/content/zotero/xpcom/translate.js | 4 +- chrome/content/zotero/xpcom/utilities.js | 1 - chrome/content/zotero/xpcom/zotero.js | 672 ----------------- components/zotero-service.js | 3 +- 7 files changed, 754 insertions(+), 727 deletions(-) create mode 100644 chrome/content/zotero/xpcom/date.js rename chrome/content/zotero/xpcom/{ingester.js => openurl.js} (89%) diff --git a/chrome/content/zotero/xpcom/date.js b/chrome/content/zotero/xpcom/date.js new file mode 100644 index 000000000..075e4cbb5 --- /dev/null +++ b/chrome/content/zotero/xpcom/date.js @@ -0,0 +1,695 @@ +/* + ***** BEGIN LICENSE BLOCK ***** + + Copyright © 2009 Center for History and New Media + George Mason University, Fairfax, Virginia, USA + http://zotero.org + + This file is part of Zotero. + + Zotero is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Zotero is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Zotero. If not, see . + + ***** END LICENSE BLOCK ***** +*/ + +Zotero.Date = new function(){ + this.sqlToDate = sqlToDate; + this.dateToSQL = dateToSQL; + this.strToDate = strToDate; + this.formatDate = formatDate; + this.strToISO = strToISO; + this.strToMultipart = strToMultipart; + this.isMultipart = isMultipart; + this.multipartToSQL = multipartToSQL; + this.multipartToStr = multipartToStr; + this.isSQLDate = isSQLDate; + this.isSQLDateTime = isSQLDateTime; + this.sqlHasYear = sqlHasYear; + this.sqlHasMonth = sqlHasMonth; + this.sqlHasDay = sqlHasDay; + this.getUnixTimestamp = getUnixTimestamp; + this.toUnixTimestamp = toUnixTimestamp; + this.getFileDateString = getFileDateString; + this.getFileTimeString = getFileTimeString; + this.getLocaleDateOrder = getLocaleDateOrder; + + var _localeDateOrder = null; + + + /** + * Convert an SQL date in the form '2006-06-13 11:03:05' into a JS Date object + * + * Can also accept just the date part (e.g. '2006-06-13') + **/ + function sqlToDate(sqldate, isUTC){ + try { + var datetime = sqldate.split(' '); + var dateparts = datetime[0].split('-'); + if (datetime[1]){ + var timeparts = datetime[1].split(':'); + } + else { + timeparts = [false, false, false]; + } + + // Invalid date part + if (dateparts.length==1){ + return false; + } + + if (isUTC){ + return new Date(Date.UTC(dateparts[0], dateparts[1]-1, dateparts[2], + timeparts[0], timeparts[1], timeparts[2])); + } + + return new Date(dateparts[0], dateparts[1]-1, dateparts[2], + timeparts[0], timeparts[1], timeparts[2]); + } + catch (e){ + Zotero.debug(sqldate + ' is not a valid SQL date', 2) + return false; + } + } + + + /** + * Convert a JS Date object to an SQL date in the form '2006-06-13 11:03:05' + * + * If _toUTC_ is true, creates a UTC date + **/ + function dateToSQL(date, toUTC) + { + try { + if (toUTC){ + var year = date.getUTCFullYear(); + var month = date.getUTCMonth(); + var day = date.getUTCDate(); + var hours = date.getUTCHours(); + var minutes = date.getUTCMinutes(); + var seconds = date.getUTCSeconds(); + } + else { + return date.toLocaleFormat('%Y-%m-%d %H:%M:%S'); + } + + year = Zotero.Utilities.lpad(year, '0', 4); + month = Zotero.Utilities.lpad(month + 1, '0', 2); + day = Zotero.Utilities.lpad(day, '0', 2); + hours = Zotero.Utilities.lpad(hours, '0', 2); + minutes = Zotero.Utilities.lpad(minutes, '0', 2); + seconds = Zotero.Utilities.lpad(seconds, '0', 2); + + return year + '-' + month + '-' + day + ' ' + + hours + ':' + minutes + ':' + seconds; + } + catch (e){ + Zotero.debug(date + ' is not a valid JS date', 2); + return ''; + } + } + + + /** + * Convert a JS Date object to an ISO 8601 UTC date/time + * + * @param {Date} date JS Date object + * @return {String} ISO 8601 UTC date/time + * e.g. 2008-08-15T20:00:00Z + */ + this.dateToISO = function (date) { + var year = date.getUTCFullYear(); + var month = date.getUTCMonth(); + var day = date.getUTCDate(); + var hours = date.getUTCHours(); + var minutes = date.getUTCMinutes(); + var seconds = date.getUTCSeconds(); + + year = Zotero.Utilities.lpad(year, '0', 4); + month = Zotero.Utilities.lpad(month + 1, '0', 2); + day = Zotero.Utilities.lpad(day, '0', 2); + hours = Zotero.Utilities.lpad(hours, '0', 2); + minutes = Zotero.Utilities.lpad(minutes, '0', 2); + seconds = Zotero.Utilities.lpad(seconds, '0', 2); + + return year + '-' + month + '-' + day + 'T' + + hours + ':' + minutes + ':' + seconds + 'Z'; + } + + + /** + * Convert an ISO 8601–formatted UTC date/time to a JS Date + * + * Adapted from http://delete.me.uk/2005/03/iso8601.html (AFL-licensed) + * + * @param {String} isoDate ISO 8601 date + * @return {Date} JS Date + */ + this.isoToDate = function (isoDate) { + var re8601 = /([0-9]{4})(-([0-9]{2})(-([0-9]{2})(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?/; + var d = isoDate.match(re8601); + + var offset = 0; + var date = new Date(d[1], 0, 1); + + if (d[3]) { date.setMonth(d[3] - 1); } + if (d[5]) { date.setDate(d[5]); } + if (d[7]) { date.setHours(d[7]); } + if (d[8]) { date.setMinutes(d[8]); } + if (d[10]) { date.setSeconds(d[10]); } + if (d[12]) { date.setMilliseconds(Number("0." + d[12]) * 1000); } + if (d[14]) { + offset = (Number(d[16]) * 60) + Number(d[17]); + offset *= ((d[15] == '-') ? 1 : -1); + } + + offset -= date.getTimezoneOffset(); + var time = (Number(date) + (offset * 60 * 1000)); + return new Date(time); + } + + + /* + * converts a string to an object containing: + * day: integer form of the day + * month: integer form of the month (indexed from 0, not 1) + * year: 4 digit year (or, year + BC/AD/etc.) + * part: anything that does not fall under any of the above categories + * (e.g., "Summer," etc.) + * + * Note: the returned object is *not* a JS Date object + */ + var _slashRe = /^(.*?)\b([0-9]{1,4})(?:([\-\/\.\u5e74])([0-9]{1,2}))?(?:([\-\/\.\u6708])([0-9]{1,4}))?((?:\b|[^0-9]).*?)$/ + var _yearRe = /^(.*?)\b((?:circa |around |about |c\.? ?)?[0-9]{1,4}(?: ?B\.? ?C\.?(?: ?E\.?)?| ?C\.? ?E\.?| ?A\.? ?D\.?)|[0-9]{3,4})\b(.*?)$/i; + var _monthRe = null; + var _dayRe = null; + + function strToDate(string) { + // Parse 'yesterday'/'today'/'tomorrow' + var lc = (string + '').toLowerCase(); + if (lc == 'yesterday' || lc == Zotero.getString('date.yesterday')) { + string = Zotero.Date.dateToSQL(new Date(new Date().getTime() - 86400000)).substr(0, 10); + } + else if (lc == 'today' || lc == Zotero.getString('date.today')) { + string = Zotero.Date.dateToSQL(new Date()).substr(0, 10); + } + else if (lc == 'tomorrow' || lc == Zotero.getString('date.tomorrow')) { + string = Zotero.Date.dateToSQL(new Date(new Date().getTime() + 86400000)).substr(0, 10); + } + + var date = new Object(); + + // skip empty things + if(!string) { + return date; + } + + string = string.toString().replace(/^\s+/, "").replace(/\s+$/, "").replace(/\s+/, " "); + + // first, directly inspect the string + var m = _slashRe.exec(string); + if(m && + (!m[5] || m[3] == m[5] || (m[3] == "\u5e74" && m[5] == "\u6708")) && // require sane separators + ((m[2] && m[4] && m[6]) || (!m[1] && !m[7]))) { // require that either all parts are found, + // or else this is the entire date field + // figure out date based on parts + if(m[2].length == 3 || m[2].length == 4 || m[3] == "\u5e74") { + // ISO 8601 style date (big endian) + date.year = m[2]; + date.month = m[4]; + date.day = m[6]; + } else { + // local style date (middle or little endian) + date.year = m[6]; + var country = Zotero.locale.substr(3); + if(country == "US" || // The United States + country == "FM" || // The Federated States of Micronesia + country == "PW" || // Palau + country == "PH") { // The Philippines + date.month = m[2]; + date.day = m[4]; + } else { + date.month = m[4]; + date.day = m[2]; + } + } + + if(date.year) date.year = parseInt(date.year, 10); + if(date.day) date.day = parseInt(date.day, 10); + if(date.month) { + date.month = parseInt(date.month, 10); + + if(date.month > 12) { + // swap day and month + var tmp = date.day; + date.day = date.month + date.month = tmp; + } + } + + if((!date.month || date.month <= 12) && (!date.day || date.day <= 31)) { + if(date.year && date.year < 100) { // for two digit years, determine proper + // four digit year + var today = new Date(); + var year = today.getFullYear(); + var twoDigitYear = year % 100; + var century = year - twoDigitYear; + + if(date.year <= twoDigitYear) { + // assume this date is from our century + date.year = century + date.year; + } else { + // assume this date is from the previous century + date.year = century - 100 + date.year; + } + } + + if(date.month) date.month--; // subtract one for JS style + Zotero.debug("DATE: retrieved with algorithms: "+date.toSource()); + + date.part = m[1]+m[7]; + } else { + // give up; we failed the sanity check + Zotero.debug("DATE: algorithms failed sanity check"); + date = {"part":string}; + } + } else { + Zotero.debug("DATE: could not apply algorithms"); + date.part = string; + } + + // couldn't find something with the algorithms; use regexp + // YEAR + if(!date.year) { + var m = _yearRe.exec(date.part); + if(m) { + date.year = m[2]; + date.part = m[1]+m[3]; + Zotero.debug("DATE: got year ("+date.year+", "+date.part+")"); + } + } + + // MONTH + if(!date.month) { + // compile month regular expression + var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', + 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; + // If using a non-English bibliography locale, try those too + if (Zotero.locale != 'en-US') { + months = months.concat(Zotero.Cite.getMonthStrings("short")); + } + if(!_monthRe) { + _monthRe = new RegExp("^(.*)\\b("+months.join("|")+")[^ ]*(?: (.*)$|$)", "i"); + } + + var m = _monthRe.exec(date.part); + if(m) { + // Modulo 12 in case we have multiple languages + date.month = months.indexOf(m[2][0].toUpperCase()+m[2].substr(1).toLowerCase()) % 12; + date.part = m[1]+m[3]; + Zotero.debug("DATE: got month ("+date.month+", "+date.part+")"); + } + } + + // DAY + if(!date.day) { + // compile day regular expression + if(!_dayRe) { + var daySuffixes = Zotero.getString("date.daySuffixes").replace(/, ?/g, "|"); + _dayRe = new RegExp("\\b([0-9]{1,2})(?:"+daySuffixes+")?\\b(.*)", "i"); + } + + var m = _dayRe.exec(date.part); + if(m) { + var day = parseInt(m[1], 10); + // Sanity check + if (day <= 31) { + date.day = day; + if(m.index > 0) { + date.part = date.part.substr(0, m.index); + if(m[2]) { + date.part += " "+m[2];; + } + } else { + date.part = m[2]; + } + + Zotero.debug("DATE: got day ("+date.day+", "+date.part+")"); + } + } + } + + // clean up date part + if(date.part) { + date.part = date.part.replace(/^[^A-Za-z0-9]+/, "").replace(/[^A-Za-z0-9]+$/, ""); + } + + if(date.part === "" || date.part == undefined) { + delete date.part; + } + + return date; + } + + /** + * does pretty formatting of a date object returned by strToDate() + * + * @param {Object} date A date object, as returned from strToDate() + * @param {Boolean} shortFormat Whether to return a short (12/1/95) date + * @return A formatted date string + * @type String + **/ + function formatDate(date, shortFormat) { + if(shortFormat) { + var localeDateOrder = getLocaleDateOrder(); + var string = localeDateOrder[0]+"/"+localeDateOrder[1]+"/"+localeDateOrder[2]; + return string.replace("y", (date.year !== undefined ? date.year : "00")) + .replace("m", (date.month !== undefined ? 1+date.month : "0")) + .replace("d", (date.day !== undefined ? date.day : "0")); + } else { + var string = ""; + + if(date.part) { + string += date.part+" "; + } + + var months = Zotero.Cite.getMonthStrings("long"); + if(date.month != undefined && months[date.month]) { + // get short month strings from CSL interpreter + string += months[date.month]; + if(date.day) { + string += " "+date.day+", "; + } else { + string += " "; + } + } + + if(date.year) { + string += date.year; + } + } + + return string; + } + + function strToISO(str) { + var date = Zotero.Date.strToDate(str); + + if(date.year) { + var dateString = Zotero.Utilities.lpad(date.year, "0", 4); + if(date.month) { + dateString += "-"+Zotero.Utilities.lpad(date.month+1, "0", 2); + if(date.day) { + dateString += "-"+Zotero.Utilities.lpad(date.day, "0", 2); + } + } + return dateString; + } + return false; + } + + function strToMultipart(str){ + if (!str){ + return ''; + } + + var parts = strToDate(str); + + // FIXME: Until we have a better BCE date solution, + // remove year value if not between 1 and 9999 + if (parts.year) { + var year = parts.year + ''; + if (!year.match(/^[0-9]{1,4}$/)) { + delete parts.year; + } + } + + parts.month = typeof parts.month != "undefined" ? parts.month + 1 : ''; + + var multi = (parts.year ? Zotero.Utilities.lpad(parts.year, '0', 4) : '0000') + '-' + + Zotero.Utilities.lpad(parts.month, '0', 2) + '-' + + (parts.day ? Zotero.Utilities.lpad(parts.day, '0', 2) : '00') + + ' ' + + str; + return multi; + } + + // Regexes for multipart and SQL dates + // Allow zeroes in multipart dates + // TODO: Allow negative multipart in DB and here with \-? + var _multipartRE = /^[0-9]{4}\-(0[0-9]|10|11|12)\-(0[0-9]|[1-2][0-9]|30|31) /; + var _sqldateRE = /^\-?[0-9]{4}\-(0[1-9]|10|11|12)\-(0[1-9]|[1-2][0-9]|30|31)$/; + var _sqldateWithZeroesRE = /^\-?[0-9]{4}\-(0[0-9]|10|11|12)\-(0[0-9]|[1-2][0-9]|30|31)$/; + var _sqldatetimeRE = /^\-?[0-9]{4}\-(0[1-9]|10|11|12)\-(0[1-9]|[1-2][0-9]|30|31) ([0-1][0-9]|[2][0-3]):([0-5][0-9]):([0-5][0-9])$/; + + /** + * Tests if a string is a multipart date string + * e.g. '2006-11-03 November 3rd, 2006' + */ + function isMultipart(str){ + if (isSQLDateTime(str)) { + return false; + } + return _multipartRE.test(str); + } + + + /** + * Returns the SQL part of a multipart date string + * (e.g. '2006-11-03 November 3rd, 2006' returns '2006-11-03') + */ + function multipartToSQL(multi){ + if (!multi){ + return ''; + } + + if (!isMultipart(multi)){ + return '0000-00-00'; + } + + return multi.substr(0, 10); + } + + + /** + * Returns the user part of a multipart date string + * (e.g. '2006-11-03 November 3rd, 2006' returns 'November 3rd, 2006') + */ + function multipartToStr(multi){ + if (!multi){ + return ''; + } + + if (!isMultipart(multi)){ + return multi; + } + + return multi.substr(11); + } + + + function isSQLDate(str, allowZeroes) { + if (allowZeroes) { + return _sqldateWithZeroesRE.test(str); + } + return _sqldateRE.test(str); + } + + + function isSQLDateTime(str){ + return _sqldatetimeRE.test(str); + } + + + function sqlHasYear(sqldate){ + return isSQLDate(sqldate, true) && sqldate.substr(0,4)!='0000'; + } + + + function sqlHasMonth(sqldate){ + return isSQLDate(sqldate, true) && sqldate.substr(5,2)!='00'; + } + + + function sqlHasDay(sqldate){ + return isSQLDate(sqldate, true) && sqldate.substr(8,2)!='00'; + } + + + function getUnixTimestamp() { + return Math.round(Date.now() / 1000); + } + + + function toUnixTimestamp(date) { + if (date === null || typeof date != 'object' || + date.constructor.name != 'Date') { + throw ('Not a valid date in Zotero.Date.toUnixTimestamp()'); + } + return Math.round(date.getTime() / 1000); + } + + + /** + * Convert a JS Date to a relative date (e.g., "5 minutes ago") + * + * Adapted from http://snipplr.com/view/10290/javascript-parse-relative-date/ + * + * @param {Date} date + * @return {String} + */ + this.toRelativeDate = function (date) { + var str; + var now = new Date(); + var timeSince = now.getTime() - date; + var inSeconds = timeSince / 1000; + var inMinutes = timeSince / 1000 / 60; + var inHours = timeSince / 1000 / 60 / 60; + var inDays = timeSince / 1000 / 60 / 60 / 24; + var inYears = timeSince / 1000 / 60 / 60 / 24 / 365; + + var n; + + // in seconds + if (Math.round(inSeconds) == 1) { + var key = "secondsAgo"; + } + else if (inMinutes < 1.01) { + var key = "secondsAgo"; + n = Math.round(inSeconds); + } + + // in minutes + else if (Math.round(inMinutes) == 1) { + var key = "minutesAgo"; + } + else if (inHours < 1.01) { + var key = "minutesAgo"; + n = Math.round(inMinutes); + } + + // in hours + else if (Math.round(inHours) == 1) { + var key = "hoursAgo"; + } + else if (inDays < 1.01) { + var key = "hoursAgo"; + n = Math.round(inHours); + } + + // in days + else if (Math.round(inDays) == 1) { + var key = "daysAgo"; + } + else if (inYears < 1.01) { + var key = "daysAgo"; + n = Math.round(inDays); + } + + // in years + else if (Math.round(inYears) == 1) { + var key = "yearsAgo"; + } + else { + var key = "yearsAgo"; + var n = Math.round(inYears); + } + + return Zotero.getString("date.relative." + key + "." + (n ? "multiple" : "one"), n); + } + + + function getFileDateString(file){ + var date = new Date(); + date.setTime(file.lastModifiedTime); + return date.toLocaleDateString(); + } + + + function getFileTimeString(file){ + var date = new Date(); + date.setTime(file.lastModifiedTime); + return date.toLocaleTimeString(); + } + + /** + * Figure out the date order from the output of toLocaleDateString() + * + * Returns a string with y, m, and d (e.g. 'ymd', 'mdy') + */ + function getLocaleDateOrder(){ + if (_localeDateOrder) { + return _localeDateOrder; + } + + var date = new Date("October 5, 2006"); + var parts = date.toLocaleDateString().match(/([0-9]+)[^0-9]+([0-9]+)[^0-9]+([0-9]+)/); + + // The above only works on OS X and Linux, + // where toLocaleDateString() produces "10/05/2006" + if (!parts) { + var country = Zotero.locale.substr(3); + switch (country) { + // I don't know where this country list came from, but these + // are little-endian in Zotero.strToDate() + case 'US': // The United States + case 'FM': // The Federated States of Micronesia + case 'PW': // Palau + case 'PH': // The Philippines + return 'mdy'; + break; + + default: + return 'dmy'; + } + } + + switch (parseInt(parts[1])){ + case 2006: + var order = 'y'; + break; + case 10: + var order = 'm'; + break; + case 5: + var order = 'd'; + break; + } + switch (parseInt(parts[2])){ + case 2006: + order += 'y'; + break; + case 10: + order += 'm'; + break; + case 5: + order += 'd'; + break; + } + switch (parseInt(parts[3])){ + case 2006: + order += 'y'; + break; + case 10: + order += 'm'; + break; + case 5: + order += 'd'; + break; + } + + _localeDateOrder = order; + + return order; + } +} \ No newline at end of file diff --git a/chrome/content/zotero/xpcom/mimeTypeHandler.js b/chrome/content/zotero/xpcom/mimeTypeHandler.js index edc6eaf3b..e48d38afa 100644 --- a/chrome/content/zotero/xpcom/mimeTypeHandler.js +++ b/chrome/content/zotero/xpcom/mimeTypeHandler.js @@ -50,18 +50,18 @@ Zotero.MIMETypeHandler = new function () { _observers = []; if(Zotero.Prefs.get("parseEndNoteMIMETypes")) { - this.addHandler("application/x-endnote-refer", Zotero.Ingester.importHandler, true); - this.addHandler("application/x-research-info-systems", Zotero.Ingester.importHandler, true); + this.addHandler("application/x-endnote-refer", _importHandler, true); + this.addHandler("application/x-research-info-systems", _importHandler, true); // // And some non-standard ones // - this.addHandler("text/x-research-info-systems", Zotero.Ingester.importHandler, true); + this.addHandler("text/x-research-info-systems", _importHandler, true); // Nature uses this one - this.addHandler("text/application/x-research-info-systems", Zotero.Ingester.importHandler, true); + this.addHandler("text/application/x-research-info-systems", _importHandler, true); // Cell uses this one - this.addHandler("text/ris", Zotero.Ingester.importHandler, true); + this.addHandler("text/ris", _importHandler, true); // Not even trying - this.addHandler("ris", Zotero.Ingester.importHandler, true); + this.addHandler("ris", _importHandler, true); } this.addHandler("text/x-csl", function(a1, a2) { Zotero.Styles.install(a1, a2) }); this.addHandler("application/x-zotero-schema", Zotero.Schema.importSchema); @@ -88,6 +88,55 @@ Zotero.MIMETypeHandler = new function () { _observers.push(fn); } + + /** + * Handles Refer/RIS MIME types + * @param {String} string The Refer/RIS formatted records + * @param {String} uri The URI from which the Refer/RIS formatted records were downloaded + */ + function _importHandler(string, uri) { + var frontWindow = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]. + getService(Components.interfaces.nsIWindowWatcher).activeWindow; + + if (Zotero.locked) { + frontWindow.Zotero_Browser.progress.changeHeadline(Zotero.getString("ingester.scrapeError")); + var desc = Zotero.localeJoin([ + Zotero.getString('general.operationInProgress'), Zotero.getString('general.operationInProgress.waitUntilFinishedAndTryAgain') + ]); + frontWindow.Zotero_Browser.progress.addDescription(desc); + frontWindow.Zotero_Browser.progress.show(); + frontWindow.Zotero_Browser.progress.startCloseTimer(8000); + return; + } + + // attempt to import through Zotero.Translate + var translation = new Zotero.Translate("import"); + translation.setLocation(uri); + translation.setString(string); + + frontWindow.Zotero_Browser.progress.show(); + var libraryID = null; + var collection = null; + try { + libraryID = frontWindow.ZoteroPane.getSelectedLibraryID(); + collection = frontWindow.ZoteroPane.getSelectedCollection(); + } catch(e) {} + translation.setHandler("itemDone", function(obj, item) { frontWindow.Zotero_Browser.itemDone(obj, item, collection) }); + translation.setHandler("done", function(obj, item) { frontWindow.Zotero_Browser.finishScraping(obj, item, collection) }); + + // attempt to retrieve translators + var translators = translation.getTranslators(); + if(!translators.length) { + // we lied. we can't really translate this file. + frontWindow.Zotero_Browser.progress.close(); + throw "No translator found for handled RIS or Refer file" + } + + // translate using first available + translation.setTranslator(translators[0]); + translation.translate(libraryID); + } + /** * Called to observe a page load */ diff --git a/chrome/content/zotero/xpcom/ingester.js b/chrome/content/zotero/xpcom/openurl.js similarity index 89% rename from chrome/content/zotero/xpcom/ingester.js rename to chrome/content/zotero/xpcom/openurl.js index e061a007c..e826d047b 100644 --- a/chrome/content/zotero/xpcom/ingester.js +++ b/chrome/content/zotero/xpcom/openurl.js @@ -23,51 +23,6 @@ ***** END LICENSE BLOCK ***** */ -Zotero.Ingester = new function() { - this.importHandler = function(string, uri) { - var frontWindow = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]. - getService(Components.interfaces.nsIWindowWatcher).activeWindow; - - if (Zotero.locked) { - frontWindow.Zotero_Browser.progress.changeHeadline(Zotero.getString("ingester.scrapeError")); - var desc = Zotero.localeJoin([ - Zotero.getString('general.operationInProgress'), Zotero.getString('general.operationInProgress.waitUntilFinishedAndTryAgain') - ]); - frontWindow.Zotero_Browser.progress.addDescription(desc); - frontWindow.Zotero_Browser.progress.show(); - frontWindow.Zotero_Browser.progress.startCloseTimer(8000); - return; - } - - // attempt to import through Zotero.Translate - var translation = new Zotero.Translate("import"); - translation.setLocation(uri); - translation.setString(string); - - frontWindow.Zotero_Browser.progress.show(); - var libraryID = null; - var collection = null; - try { - libraryID = frontWindow.ZoteroPane.getSelectedLibraryID(); - collection = frontWindow.ZoteroPane.getSelectedCollection(); - } catch(e) {} - translation.setHandler("itemDone", function(obj, item) { frontWindow.Zotero_Browser.itemDone(obj, item, collection) }); - translation.setHandler("done", function(obj, item) { frontWindow.Zotero_Browser.finishScraping(obj, item, collection) }); - - // attempt to retrieve translators - var translators = translation.getTranslators(); - if(!translators.length) { - // we lied. we can't really translate this file. - frontWindow.Zotero_Browser.progress.close(); - throw "No translator found for handled RIS or Refer file" - } - - // translate using first available - translation.setTranslator(translators[0]); - translation.translate(libraryID); - } -} - Zotero.OpenURL = new function() { this.resolve = resolve; this.discoverResolvers = discoverResolvers; diff --git a/chrome/content/zotero/xpcom/translate.js b/chrome/content/zotero/xpcom/translate.js index 5bc6aae70..02ae96aa8 100644 --- a/chrome/content/zotero/xpcom/translate.js +++ b/chrome/content/zotero/xpcom/translate.js @@ -939,8 +939,8 @@ Zotero.Translate.prototype._generateSandbox = function() { var m = searchSandboxRe.exec(tempURL); if(m) sandboxLocation = m[0]; } - } else if(this._sandboxLocation) { - sandboxLocation = this._sandboxLocation; + //} else if(this._sandboxLocation) { + // sandboxLocation = this._sandboxLocation; } Zotero.debug("Translate: Binding sandbox to "+(typeof sandboxLocation == "object" ? sandboxLocation.document.location : sandboxLocation), 4); diff --git a/chrome/content/zotero/xpcom/utilities.js b/chrome/content/zotero/xpcom/utilities.js index 6da573f0a..4f4ace1e5 100644 --- a/chrome/content/zotero/xpcom/utilities.js +++ b/chrome/content/zotero/xpcom/utilities.js @@ -85,7 +85,6 @@ Zotero.Utilities = { */ "trim":function(/**String*/ s) { if (typeof(s) != "string") { - Zotero.debug(s); throw "trim: argument must be a string"; } diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js index 663887a16..c07731928 100644 --- a/chrome/content/zotero/xpcom/zotero.js +++ b/chrome/content/zotero/xpcom/zotero.js @@ -1832,678 +1832,6 @@ Zotero.Text = new function() { } } -Zotero.Date = new function(){ - this.sqlToDate = sqlToDate; - this.dateToSQL = dateToSQL; - this.strToDate = strToDate; - this.formatDate = formatDate; - this.strToISO = strToISO; - this.strToMultipart = strToMultipart; - this.isMultipart = isMultipart; - this.multipartToSQL = multipartToSQL; - this.multipartToStr = multipartToStr; - this.isSQLDate = isSQLDate; - this.isSQLDateTime = isSQLDateTime; - this.sqlHasYear = sqlHasYear; - this.sqlHasMonth = sqlHasMonth; - this.sqlHasDay = sqlHasDay; - this.getUnixTimestamp = getUnixTimestamp; - this.toUnixTimestamp = toUnixTimestamp; - this.getFileDateString = getFileDateString; - this.getFileTimeString = getFileTimeString; - this.getLocaleDateOrder = getLocaleDateOrder; - - var _localeDateOrder = null; - - - /** - * Convert an SQL date in the form '2006-06-13 11:03:05' into a JS Date object - * - * Can also accept just the date part (e.g. '2006-06-13') - **/ - function sqlToDate(sqldate, isUTC){ - try { - var datetime = sqldate.split(' '); - var dateparts = datetime[0].split('-'); - if (datetime[1]){ - var timeparts = datetime[1].split(':'); - } - else { - timeparts = [false, false, false]; - } - - // Invalid date part - if (dateparts.length==1){ - return false; - } - - if (isUTC){ - return new Date(Date.UTC(dateparts[0], dateparts[1]-1, dateparts[2], - timeparts[0], timeparts[1], timeparts[2])); - } - - return new Date(dateparts[0], dateparts[1]-1, dateparts[2], - timeparts[0], timeparts[1], timeparts[2]); - } - catch (e){ - Zotero.debug(sqldate + ' is not a valid SQL date', 2) - return false; - } - } - - - /** - * Convert a JS Date object to an SQL date in the form '2006-06-13 11:03:05' - * - * If _toUTC_ is true, creates a UTC date - **/ - function dateToSQL(date, toUTC) - { - try { - if (toUTC){ - var year = date.getUTCFullYear(); - var month = date.getUTCMonth(); - var day = date.getUTCDate(); - var hours = date.getUTCHours(); - var minutes = date.getUTCMinutes(); - var seconds = date.getUTCSeconds(); - } - else { - return date.toLocaleFormat('%Y-%m-%d %H:%M:%S'); - } - - year = Zotero.Utilities.lpad(year, '0', 4); - month = Zotero.Utilities.lpad(month + 1, '0', 2); - day = Zotero.Utilities.lpad(day, '0', 2); - hours = Zotero.Utilities.lpad(hours, '0', 2); - minutes = Zotero.Utilities.lpad(minutes, '0', 2); - seconds = Zotero.Utilities.lpad(seconds, '0', 2); - - return year + '-' + month + '-' + day + ' ' - + hours + ':' + minutes + ':' + seconds; - } - catch (e){ - Zotero.debug(date + ' is not a valid JS date', 2); - return ''; - } - } - - - /** - * Convert a JS Date object to an ISO 8601 UTC date/time - * - * @param {Date} date JS Date object - * @return {String} ISO 8601 UTC date/time - * e.g. 2008-08-15T20:00:00Z - */ - this.dateToISO = function (date) { - var year = date.getUTCFullYear(); - var month = date.getUTCMonth(); - var day = date.getUTCDate(); - var hours = date.getUTCHours(); - var minutes = date.getUTCMinutes(); - var seconds = date.getUTCSeconds(); - - year = Zotero.Utilities.lpad(year, '0', 4); - month = Zotero.Utilities.lpad(month + 1, '0', 2); - day = Zotero.Utilities.lpad(day, '0', 2); - hours = Zotero.Utilities.lpad(hours, '0', 2); - minutes = Zotero.Utilities.lpad(minutes, '0', 2); - seconds = Zotero.Utilities.lpad(seconds, '0', 2); - - return year + '-' + month + '-' + day + 'T' - + hours + ':' + minutes + ':' + seconds + 'Z'; - } - - - /** - * Convert an ISO 8601–formatted UTC date/time to a JS Date - * - * Adapted from http://delete.me.uk/2005/03/iso8601.html (AFL-licensed) - * - * @param {String} isoDate ISO 8601 date - * @return {Date} JS Date - */ - this.isoToDate = function (isoDate) { - var re8601 = /([0-9]{4})(-([0-9]{2})(-([0-9]{2})(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?/; - var d = isoDate.match(re8601); - - var offset = 0; - var date = new Date(d[1], 0, 1); - - if (d[3]) { date.setMonth(d[3] - 1); } - if (d[5]) { date.setDate(d[5]); } - if (d[7]) { date.setHours(d[7]); } - if (d[8]) { date.setMinutes(d[8]); } - if (d[10]) { date.setSeconds(d[10]); } - if (d[12]) { date.setMilliseconds(Number("0." + d[12]) * 1000); } - if (d[14]) { - offset = (Number(d[16]) * 60) + Number(d[17]); - offset *= ((d[15] == '-') ? 1 : -1); - } - - offset -= date.getTimezoneOffset(); - var time = (Number(date) + (offset * 60 * 1000)); - return new Date(time); - } - - - /* - * converts a string to an object containing: - * day: integer form of the day - * month: integer form of the month (indexed from 0, not 1) - * year: 4 digit year (or, year + BC/AD/etc.) - * part: anything that does not fall under any of the above categories - * (e.g., "Summer," etc.) - * - * Note: the returned object is *not* a JS Date object - */ - var _slashRe = /^(.*?)\b([0-9]{1,4})(?:([\-\/\.\u5e74])([0-9]{1,2}))?(?:([\-\/\.\u6708])([0-9]{1,4}))?((?:\b|[^0-9]).*?)$/ - var _yearRe = /^(.*?)\b((?:circa |around |about |c\.? ?)?[0-9]{1,4}(?: ?B\.? ?C\.?(?: ?E\.?)?| ?C\.? ?E\.?| ?A\.? ?D\.?)|[0-9]{3,4})\b(.*?)$/i; - var _monthRe = null; - var _dayRe = null; - - function strToDate(string) { - // Parse 'yesterday'/'today'/'tomorrow' - var lc = (string + '').toLowerCase(); - if (lc == 'yesterday' || lc == Zotero.getString('date.yesterday')) { - string = Zotero.Date.dateToSQL(new Date(new Date().getTime() - 86400000)).substr(0, 10); - } - else if (lc == 'today' || lc == Zotero.getString('date.today')) { - string = Zotero.Date.dateToSQL(new Date()).substr(0, 10); - } - else if (lc == 'tomorrow' || lc == Zotero.getString('date.tomorrow')) { - string = Zotero.Date.dateToSQL(new Date(new Date().getTime() + 86400000)).substr(0, 10); - } - - var date = new Object(); - - // skip empty things - if(!string) { - return date; - } - - string = string.toString().replace(/^\s+/, "").replace(/\s+$/, "").replace(/\s+/, " "); - - // first, directly inspect the string - var m = _slashRe.exec(string); - if(m && - (!m[5] || m[3] == m[5] || (m[3] == "\u5e74" && m[5] == "\u6708")) && // require sane separators - ((m[2] && m[4] && m[6]) || (!m[1] && !m[7]))) { // require that either all parts are found, - // or else this is the entire date field - // figure out date based on parts - if(m[2].length == 3 || m[2].length == 4 || m[3] == "\u5e74") { - // ISO 8601 style date (big endian) - date.year = m[2]; - date.month = m[4]; - date.day = m[6]; - } else { - // local style date (middle or little endian) - date.year = m[6]; - var country = Zotero.locale.substr(3); - if(country == "US" || // The United States - country == "FM" || // The Federated States of Micronesia - country == "PW" || // Palau - country == "PH") { // The Philippines - date.month = m[2]; - date.day = m[4]; - } else { - date.month = m[4]; - date.day = m[2]; - } - } - - if(date.year) date.year = parseInt(date.year, 10); - if(date.day) date.day = parseInt(date.day, 10); - if(date.month) { - date.month = parseInt(date.month, 10); - - if(date.month > 12) { - // swap day and month - var tmp = date.day; - date.day = date.month - date.month = tmp; - } - } - - if((!date.month || date.month <= 12) && (!date.day || date.day <= 31)) { - if(date.year && date.year < 100) { // for two digit years, determine proper - // four digit year - var today = new Date(); - var year = today.getFullYear(); - var twoDigitYear = year % 100; - var century = year - twoDigitYear; - - if(date.year <= twoDigitYear) { - // assume this date is from our century - date.year = century + date.year; - } else { - // assume this date is from the previous century - date.year = century - 100 + date.year; - } - } - - if(date.month) date.month--; // subtract one for JS style - Zotero.debug("DATE: retrieved with algorithms: "+date.toSource()); - - date.part = m[1]+m[7]; - } else { - // give up; we failed the sanity check - Zotero.debug("DATE: algorithms failed sanity check"); - date = {"part":string}; - } - } else { - Zotero.debug("DATE: could not apply algorithms"); - date.part = string; - } - - // couldn't find something with the algorithms; use regexp - // YEAR - if(!date.year) { - var m = _yearRe.exec(date.part); - if(m) { - date.year = m[2]; - date.part = m[1]+m[3]; - Zotero.debug("DATE: got year ("+date.year+", "+date.part+")"); - } - } - - // MONTH - if(!date.month) { - // compile month regular expression - var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', - 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; - // If using a non-English bibliography locale, try those too - if (Zotero.locale != 'en-US') { - months = months.concat(Zotero.Cite.getMonthStrings("short")); - } - if(!_monthRe) { - _monthRe = new RegExp("^(.*)\\b("+months.join("|")+")[^ ]*(?: (.*)$|$)", "i"); - } - - var m = _monthRe.exec(date.part); - if(m) { - // Modulo 12 in case we have multiple languages - date.month = months.indexOf(m[2][0].toUpperCase()+m[2].substr(1).toLowerCase()) % 12; - date.part = m[1]+m[3]; - Zotero.debug("DATE: got month ("+date.month+", "+date.part+")"); - } - } - - // DAY - if(!date.day) { - // compile day regular expression - if(!_dayRe) { - var daySuffixes = Zotero.getString("date.daySuffixes").replace(/, ?/g, "|"); - _dayRe = new RegExp("\\b([0-9]{1,2})(?:"+daySuffixes+")?\\b(.*)", "i"); - } - - var m = _dayRe.exec(date.part); - if(m) { - var day = parseInt(m[1], 10); - // Sanity check - if (day <= 31) { - date.day = day; - if(m.index > 0) { - date.part = date.part.substr(0, m.index); - if(m[2]) { - date.part += " "+m[2];; - } - } else { - date.part = m[2]; - } - - Zotero.debug("DATE: got day ("+date.day+", "+date.part+")"); - } - } - } - - // clean up date part - if(date.part) { - date.part = date.part.replace(/^[^A-Za-z0-9]+/, "").replace(/[^A-Za-z0-9]+$/, ""); - } - - if(date.part === "" || date.part == undefined) { - delete date.part; - } - - return date; - } - - /** - * does pretty formatting of a date object returned by strToDate() - * - * @param {Object} date A date object, as returned from strToDate() - * @param {Boolean} shortFormat Whether to return a short (12/1/95) date - * @return A formatted date string - * @type String - **/ - function formatDate(date, shortFormat) { - if(shortFormat) { - var localeDateOrder = getLocaleDateOrder(); - var string = localeDateOrder[0]+"/"+localeDateOrder[1]+"/"+localeDateOrder[2]; - return string.replace("y", (date.year !== undefined ? date.year : "00")) - .replace("m", (date.month !== undefined ? 1+date.month : "0")) - .replace("d", (date.day !== undefined ? date.day : "0")); - } else { - var string = ""; - - if(date.part) { - string += date.part+" "; - } - - var months = Zotero.Cite.getMonthStrings("long"); - if(date.month != undefined && months[date.month]) { - // get short month strings from CSL interpreter - string += months[date.month]; - if(date.day) { - string += " "+date.day+", "; - } else { - string += " "; - } - } - - if(date.year) { - string += date.year; - } - } - - return string; - } - - function strToISO(str) { - var date = Zotero.Date.strToDate(str); - - if(date.year) { - var dateString = Zotero.Utilities.lpad(date.year, "0", 4); - if(date.month) { - dateString += "-"+Zotero.Utilities.lpad(date.month+1, "0", 2); - if(date.day) { - dateString += "-"+Zotero.Utilities.lpad(date.day, "0", 2); - } - } - return dateString; - } - return false; - } - - function strToMultipart(str){ - if (!str){ - return ''; - } - - var parts = strToDate(str); - - // FIXME: Until we have a better BCE date solution, - // remove year value if not between 1 and 9999 - if (parts.year) { - var year = parts.year + ''; - if (!year.match(/^[0-9]{1,4}$/)) { - delete parts.year; - } - } - - parts.month = typeof parts.month != "undefined" ? parts.month + 1 : ''; - - var multi = (parts.year ? Zotero.Utilities.lpad(parts.year, '0', 4) : '0000') + '-' - + Zotero.Utilities.lpad(parts.month, '0', 2) + '-' - + (parts.day ? Zotero.Utilities.lpad(parts.day, '0', 2) : '00') - + ' ' - + str; - return multi; - } - - // Regexes for multipart and SQL dates - // Allow zeroes in multipart dates - // TODO: Allow negative multipart in DB and here with \-? - var _multipartRE = /^[0-9]{4}\-(0[0-9]|10|11|12)\-(0[0-9]|[1-2][0-9]|30|31) /; - var _sqldateRE = /^\-?[0-9]{4}\-(0[1-9]|10|11|12)\-(0[1-9]|[1-2][0-9]|30|31)$/; - var _sqldateWithZeroesRE = /^\-?[0-9]{4}\-(0[0-9]|10|11|12)\-(0[0-9]|[1-2][0-9]|30|31)$/; - var _sqldatetimeRE = /^\-?[0-9]{4}\-(0[1-9]|10|11|12)\-(0[1-9]|[1-2][0-9]|30|31) ([0-1][0-9]|[2][0-3]):([0-5][0-9]):([0-5][0-9])$/; - - /** - * Tests if a string is a multipart date string - * e.g. '2006-11-03 November 3rd, 2006' - */ - function isMultipart(str){ - if (isSQLDateTime(str)) { - return false; - } - return _multipartRE.test(str); - } - - - /** - * Returns the SQL part of a multipart date string - * (e.g. '2006-11-03 November 3rd, 2006' returns '2006-11-03') - */ - function multipartToSQL(multi){ - if (!multi){ - return ''; - } - - if (!isMultipart(multi)){ - return '0000-00-00'; - } - - return multi.substr(0, 10); - } - - - /** - * Returns the user part of a multipart date string - * (e.g. '2006-11-03 November 3rd, 2006' returns 'November 3rd, 2006') - */ - function multipartToStr(multi){ - if (!multi){ - return ''; - } - - if (!isMultipart(multi)){ - return multi; - } - - return multi.substr(11); - } - - - function isSQLDate(str, allowZeroes) { - if (allowZeroes) { - return _sqldateWithZeroesRE.test(str); - } - return _sqldateRE.test(str); - } - - - function isSQLDateTime(str){ - return _sqldatetimeRE.test(str); - } - - - function sqlHasYear(sqldate){ - return isSQLDate(sqldate, true) && sqldate.substr(0,4)!='0000'; - } - - - function sqlHasMonth(sqldate){ - return isSQLDate(sqldate, true) && sqldate.substr(5,2)!='00'; - } - - - function sqlHasDay(sqldate){ - return isSQLDate(sqldate, true) && sqldate.substr(8,2)!='00'; - } - - - function getUnixTimestamp() { - return Math.round(Date.now() / 1000); - } - - - function toUnixTimestamp(date) { - if (date === null || typeof date != 'object' || - date.constructor.name != 'Date') { - throw ('Not a valid date in Zotero.Date.toUnixTimestamp()'); - } - return Math.round(date.getTime() / 1000); - } - - - /** - * Convert a JS Date to a relative date (e.g., "5 minutes ago") - * - * Adapted from http://snipplr.com/view/10290/javascript-parse-relative-date/ - * - * @param {Date} date - * @return {String} - */ - this.toRelativeDate = function (date) { - var str; - var now = new Date(); - var timeSince = now.getTime() - date; - var inSeconds = timeSince / 1000; - var inMinutes = timeSince / 1000 / 60; - var inHours = timeSince / 1000 / 60 / 60; - var inDays = timeSince / 1000 / 60 / 60 / 24; - var inYears = timeSince / 1000 / 60 / 60 / 24 / 365; - - var n; - - // in seconds - if (Math.round(inSeconds) == 1) { - var key = "secondsAgo"; - } - else if (inMinutes < 1.01) { - var key = "secondsAgo"; - n = Math.round(inSeconds); - } - - // in minutes - else if (Math.round(inMinutes) == 1) { - var key = "minutesAgo"; - } - else if (inHours < 1.01) { - var key = "minutesAgo"; - n = Math.round(inMinutes); - } - - // in hours - else if (Math.round(inHours) == 1) { - var key = "hoursAgo"; - } - else if (inDays < 1.01) { - var key = "hoursAgo"; - n = Math.round(inHours); - } - - // in days - else if (Math.round(inDays) == 1) { - var key = "daysAgo"; - } - else if (inYears < 1.01) { - var key = "daysAgo"; - n = Math.round(inDays); - } - - // in years - else if (Math.round(inYears) == 1) { - var key = "yearsAgo"; - } - else { - var key = "yearsAgo"; - var n = Math.round(inYears); - } - - return Zotero.getString("date.relative." + key + "." + (n ? "multiple" : "one"), n); - } - - - function getFileDateString(file){ - var date = new Date(); - date.setTime(file.lastModifiedTime); - return date.toLocaleDateString(); - } - - - function getFileTimeString(file){ - var date = new Date(); - date.setTime(file.lastModifiedTime); - return date.toLocaleTimeString(); - } - - /** - * Figure out the date order from the output of toLocaleDateString() - * - * Returns a string with y, m, and d (e.g. 'ymd', 'mdy') - */ - function getLocaleDateOrder(){ - if (_localeDateOrder) { - return _localeDateOrder; - } - - var date = new Date("October 5, 2006"); - var parts = date.toLocaleDateString().match(/([0-9]+)[^0-9]+([0-9]+)[^0-9]+([0-9]+)/); - - // The above only works on OS X and Linux, - // where toLocaleDateString() produces "10/05/2006" - if (!parts) { - var country = Zotero.locale.substr(3); - switch (country) { - // I don't know where this country list came from, but these - // are little-endian in Zotero.strToDate() - case 'US': // The United States - case 'FM': // The Federated States of Micronesia - case 'PW': // Palau - case 'PH': // The Philippines - return 'mdy'; - break; - - default: - return 'dmy'; - } - } - - switch (parseInt(parts[1])){ - case 2006: - var order = 'y'; - break; - case 10: - var order = 'm'; - break; - case 5: - var order = 'd'; - break; - } - switch (parseInt(parts[2])){ - case 2006: - order += 'y'; - break; - case 10: - order += 'm'; - break; - case 5: - order += 'd'; - break; - } - switch (parseInt(parts[3])){ - case 2006: - order += 'y'; - break; - case 10: - order += 'm'; - break; - case 5: - order += 'd'; - break; - } - - _localeDateOrder = order; - - return order; - } -} - - Zotero.DragDrop = { currentDataTransfer: null, diff --git a/components/zotero-service.js b/components/zotero-service.js index d5a41167a..20499c0e0 100644 --- a/components/zotero-service.js +++ b/components/zotero-service.js @@ -77,6 +77,7 @@ var xpcomFiles = [ 'data/relations', 'data/tag', 'data/tags', + 'date', 'db', 'debug', 'duplicate', @@ -86,13 +87,13 @@ var xpcomFiles = [ 'fulltext', 'http', 'id', - 'ingester', 'integration', 'integration_compat', 'itemTreeView', 'mime', 'mimeTypeHandler', 'notifier', + 'openurl', 'progressWindow', 'proxy', 'quickCopy',