commit e61dd6002456543b26869da7030b49bb054d461b
parent a7f535ee85bd9772442ced64045007dbb6a8c747
Author: Simon Kornblith <simon@simonster.com>
Date: Wed, 27 Oct 2010 00:36:20 +0000
move Zotero.Date and Zotero.OpenURL to independent files
Diffstat:
8 files changed, 1212 insertions(+), 1184 deletions(-)
diff --git a/chrome/content/zotero/xpcom/date.js 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 <http://www.gnu.org/licenses/>.
+
+ ***** 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/ingester.js b/chrome/content/zotero/xpcom/ingester.js
@@ -1,501 +0,0 @@
-/*
- ***** 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 <http://www.gnu.org/licenses/>.
-
- ***** 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;
- this.createContextObject = createContextObject;
- this.parseContextObject = parseContextObject;
-
- /*
- * Returns a URL to look up an item in the OpenURL resolver
- */
- function resolve(itemObject) {
- var co = createContextObject(itemObject, Zotero.Prefs.get("openURL.version"));
- if(co) {
- var base = Zotero.Prefs.get("openURL.resolver");
- // Add & if there's already a ?
- var splice = base.indexOf("?") == -1 ? "?" : "&";
- return base + splice + co;
- }
- return false;
- }
-
- /*
- * Queries OCLC's OpenURL resolver registry and returns an address and version
- */
- function discoverResolvers() {
- var req = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance();
- req.open("GET", "http://worldcatlibraries.org/registry/lookup?IP=requestor", false);
- req.send(null);
-
- if(!req.responseXML) {
- throw "Could not access resolver registry";
- }
-
- var resolverArray = new Array();
- var resolvers = req.responseXML.getElementsByTagName("resolver");
- for(var i=0; i<resolvers.length; i++) {
- var resolver = resolvers[i];
-
- var name = resolver.parentNode.getElementsByTagName("institutionName");
- if(!name.length) {
- continue;
- }
- name = name[0].textContent;
-
- var url = resolver.getElementsByTagName("baseURL");
- if(!url.length) {
- continue;
- }
- url = url[0].textContent;
-
- if(resolver.getElementsByTagName("Z39.88-2004").length > 0) {
- var version = "1.0";
- } else if(resolver.getElementsByTagName("OpenUrl 0.1").length > 0) {
- var version = "0.1";
- } else {
- continue;
- }
-
- resolverArray.push({name:name, url:url, version:version});
- }
-
- return resolverArray;
- }
-
- /*
- * Generates an OpenURL ContextObject from an item
- */
- function createContextObject(item, version) {
- if(item.toArray) {
- item = item.toArray();
- }
-
- var identifiers = new Array();
- if(item.DOI) {
- identifiers.push("info:doi/"+item.DOI);
- }
- if(item.ISBN) {
- identifiers.push("urn:isbn:"+item.ISBN);
- }
-
- // encode ctx_ver (if available) and identifiers
- // TODO identifiers may need to be encoded as follows:
- // rft_id=info:doi/<the-url-encoded-doi>
- // rft_id=http://<the-rest-of-the-url-encoded-url>
- if(version == "0.1") {
- var co = "sid=Zotero:"+encodeURIComponent(Zotero.version);
-
- for each(identifier in identifiers) {
- co += "&id="+encodeURIComponent(identifier);
- }
- } else {
- var co = "url_ver=Z39.88-2004&ctx_ver=Z39.88-2004"+
- "&rfr_id="+encodeURIComponent("info:sid/zotero.org:"+Zotero.version);
-
- for each(identifier in identifiers) {
- co += "&rft_id="+encodeURIComponent(identifier)
- }
- }
-
- // encode genre and item-specific data
- if(item.itemType == "journalArticle") {
- if(version == "0.1") {
- co += "&genre=article";
- } else {
- co += "&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Ajournal&rft.genre=article";
- }
- if(item.title) co += _mapTag(item.title, "atitle", version)
- if(item.publicationTitle) co += _mapTag(item.publicationTitle, (version == "0.1" ? "title" : "jtitle"), version)
- if(item.journalAbbreviation) co += _mapTag(item.journalAbbreviation, "stitle", version);
- if(item.volume) co += _mapTag(item.volume, "volume", version);
- if(item.issue) co += _mapTag(item.issue, "issue", version);
- } else if(item.itemType == "book" || item.itemType == "bookSection") {
- if(version == "0.1") {
- co += "&genre=book";
- } else {
- co += "&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Abook";
- }
-
- if(item.itemType == "book") {
- co += "&rft.genre=book";
- if(item.title) co += _mapTag(item.title, (version == "0.1" ? "title" : "btitle"), version);
- } else {
- co += "&rft.genre=bookitem";
- if(item.title) co += _mapTag(item.title, "atitle", version)
- if(item.publicationTitle) co += _mapTag(item.publicationTitle, (version == "0.1" ? "title" : "btitle"), version);
- }
-
- if(item.place) co += _mapTag(item.place, "place", version);
- if(item.publisher) co += _mapTag(item.publisher, "publisher", version)
- if(item.edition) co += _mapTag(item.edition, "edition", version);
- if(item.series) co += _mapTag(item.series, "series", version);
- } else if(item.itemType == "thesis" && version == "1.0") {
- co += "&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adissertation";
-
- if(item.title) co += _mapTag(item.title, "title", version);
- if(item.publisher) co += _mapTag(item.publisher, "inst", version);
- if(item.type) co += _mapTag(item.type, "degree", version);
- } else if(item.itemType == "patent" && version == "1.0") {
- co += "&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Apatent";
-
- if(item.title) co += _mapTag(item.title, "title", version);
- if(item.assignee) co += _mapTag(item.assignee, "assignee", version);
- if(item.patentNumber) co += _mapTag(item.patentNumber, "number", version);
-
- if(item.issueDate) {
- co += _mapTag(Zotero.Date.strToISO(item.issueDate), "date", version);
- }
- } else {
- return false;
- }
-
- if(item.creators && item.creators.length) {
- // encode first author as first and last
- var firstCreator = item.creators[0];
- if(item.itemType == "patent") {
- co += _mapTag(firstCreator.firstName, "invfirst", version);
- co += _mapTag(firstCreator.lastName, "invlast", version);
- } else {
- if(firstCreator.isInstitution) {
- co += _mapTag(firstCreator.lastName, "aucorp", version);
- } else {
- co += _mapTag(firstCreator.firstName, "aufirst", version);
- co += _mapTag(firstCreator.lastName, "aulast", version);
- }
- }
-
- // encode subsequent creators as au
- for each(creator in item.creators) {
- co += _mapTag((creator.firstName ? creator.firstName+" " : "")+creator.lastName, (item.itemType == "patent" ? "inventor" : "au"), version);
- }
- }
-
- if(item.date) {
- co += _mapTag(Zotero.Date.strToISO(item.date), (item.itemType == "patent" ? "appldate" : "date"), version);
- }
- if(item.pages) co += _mapTag(item.pages, "pages", version);
- if(item.ISBN) co += _mapTag(item.ISBN, "isbn", version);
- if(item.ISSN) co += _mapTag(item.ISSN, "issn", version);
-
- return co;
- }
-
- /*
- * Generates an item in the format returned by item.fromArray() given an
- * OpenURL version 1.0 contextObject
- *
- * accepts an item array to fill, or creates and returns a new item array
- */
- function parseContextObject(co, item) {
- if(!item) {
- var item = new Array();
- item.creators = new Array();
- }
-
- var coParts = co.split("&");
-
- // get type
- for each(var part in coParts) {
- if(part.substr(0, 12) == "rft_val_fmt=") {
- var format = decodeURIComponent(part.substr(12));
- if(format == "info:ofi/fmt:kev:mtx:journal") {
- item.itemType = "journalArticle";
- break;
- } else if(format == "info:ofi/fmt:kev:mtx:book") {
- if(coParts.indexOf("rft.genre=bookitem") !== -1) {
- item.itemType = "bookSection";
- } else if(coParts.indexOf("rft.genre=conference") !== -1 || coParts.indexOf("rft.genre=proceeding") !== -1) {
- item.itemType = "conferencePaper";
- } else if(coParts.indexOf("rft.genre=report") !== -1) {
- item.itemType = "report";
- } else {
- item.itemType = "book";
- }
- break;
- } else if(format == "info:ofi/fmt:kev:mtx:dissertation") {
- item.itemType = "thesis";
- break;
- } else if(format == "info:ofi/fmt:kev:mtx:patent") {
- item.itemType = "patent";
- break;
- } else if(format == "info:ofi/fmt:kev:mtx:dc") {
- item.itemType = "webpage";
- break;
- }
- }
- }
- if(!item.itemType) {
- return false;
- }
-
- var pagesKey = "";
-
- // keep track of "aucorp," "aufirst," "aulast"
- var complexAu = new Array();
-
- for each(var part in coParts) {
- var keyVal = part.split("=");
- var key = keyVal[0];
- var value = decodeURIComponent(keyVal[1].replace(/\+|%2[bB]/g, " "));
- if(!value) {
- continue;
- }
-
- if(key == "rft_id") {
- var firstEight = value.substr(0, 8).toLowerCase();
- if(firstEight == "info:doi") {
- item.DOI = value.substr(9);
- } else if(firstEight == "urn:isbn") {
- item.ISBN = value.substr(9);
- } else if(value.match(/^https?:\/\//)) {
- item.url = value;
- item.accessDate = "";
- }
- } else if(key == "rft.btitle") {
- if(item.itemType == "book" || item.itemType == "conferencePaper" || item.itemType == "report") {
- item.title = value;
- } else if(item.itemType == "bookSection") {
- item.publicationTitle = value;
- }
- } else if(key == "rft.atitle" && (item.itemType == "journalArticle" ||
- item.itemType == "bookSection")) {
- item.title = value;
- } else if(key == "rft.jtitle" && item.itemType == "journalArticle") {
- item.publicationTitle = value;
- } else if(key == "rft.stitle" && item.itemType == "journalArticle") {
- item.journalAbbreviation = value;
- } else if(key == "rft.title") {
- if(item.itemType == "journalArticle" || item.itemType == "bookSection") {
- item.publicationTitle = value;
- } else {
- item.title = value;
- }
- } else if(key == "rft.date") {
- if(item.itemType == "patent") {
- item.issueDate = value;
- } else {
- item.date = value;
- }
- } else if(key == "rft.volume") {
- item.volume = value;
- } else if(key == "rft.issue") {
- item.issue = value;
- } else if(key == "rft.pages") {
- pagesKey = key;
- item.pages = value;
- } else if(key == "rft.spage") {
- if(pagesKey != "rft.pages") {
- // make pages look like start-end
- if(pagesKey == "rft.epage") {
- if(value != item.pages) {
- item.pages = value+"-"+item.pages;
- }
- } else {
- item.pages = value;
- }
- pagesKey = key;
- }
- } else if(key == "rft.epage") {
- if(pagesKey != "rft.pages") {
- // make pages look like start-end
- if(pagesKey == "rft.spage") {
- if(value != item.pages) {
- item.pages = item.pages+"-"+value;
- }
- } else {
- item.pages = value;
- }
- pagesKey = key;
- }
- } else if(key == "rft.issn" || (key == "rft.eissn" && !item.ISSN)) {
- item.ISSN = value;
- } else if(key == "rft.aulast" || key == "rft.invlast") {
- var lastCreator = complexAu[complexAu.length-1];
- if(complexAu.length && !lastCreator.lastName && !lastCreator.institutional) {
- lastCreator.lastName = value;
- } else {
- complexAu.push({lastName:value, creatorType:(key == "rft.aulast" ? "author" : "inventor")});
- }
- } else if(key == "rft.aufirst" || key == "rft.invfirst") {
- var lastCreator = complexAu[complexAu.length-1];
- if(complexAu.length && !lastCreator.firstName && !lastCreator.institutional) {
- lastCreator.firstName = value;
- } else {
- complexAu.push({firstName:value, creatorType:(key == "rft.aufirst" ? "author" : "inventor")});
- }
- } else if(key == "rft.au" || key == "rft.creator" || key == "rft.contributor" || key == "rft.inventor") {
- if(key == "rft.contributor") {
- var type = "contributor";
- } else if(key == "rft.inventor") {
- var type = "inventor";
- } else {
- var type = "author";
- }
-
- if(value.indexOf(",") !== -1) {
- item.creators.push(Zotero.Utilities.cleanAuthor(value, type, true));
- } else {
- item.creators.push(Zotero.Utilities.cleanAuthor(value, type, false));
- }
- } else if(key == "rft.aucorp") {
- complexAu.push({lastName:value, isInstitution:true});
- } else if(key == "rft.isbn" && !item.ISBN) {
- item.ISBN = value;
- } else if(key == "rft.pub" || key == "rft.publisher") {
- item.publisher = value;
- } else if(key == "rft.place") {
- item.place = value;
- } else if(key == "rft.edition") {
- item.edition = value;
- } else if(key == "rft.series") {
- item.series = value;
- } else if(item.itemType == "thesis") {
- if(key == "rft.inst") {
- item.publisher = value;
- } else if(key == "rft.degree") {
- item.type = value;
- }
- } else if(item.itemType == "patent") {
- if(key == "rft.assignee") {
- item.assignee = value;
- } else if(key == "rft.number") {
- item.patentNumber = value;
- } else if(key == "rft.appldate") {
- item.date = value;
- }
- } else if(format == "info:ofi/fmt:kev:mtx:dc") {
- if(key == "rft.identifier") {
- if(value.length > 8) { // we could check length separately for
- // each type, but all of these identifiers
- // must be > 8 characters
- if(value.substr(0, 5) == "ISBN ") {
- item.ISBN = value.substr(5);
- } else if(value.substr(0, 5) == "ISSN ") {
- item.ISSN = value.substr(5);
- } else if(value.substr(0, 8) == "urn:doi:") {
- item.DOI = value.substr(4);
- } else if(value.substr(0, 7) == "http://" || value.substr(0, 8) == "https://") {
- item.url = value;
- }
- }
- } else if(key == "rft.description") {
- item.abstractNote = value;
- } else if(key == "rft.rights") {
- item.rights = value;
- } else if(key == "rft.language") {
- item.language = value;
- } else if(key == "rft.subject") {
- item.tags.push(value);
- } else if(key == "rft.type") {
- if(Zotero.ItemTypes.getID(value)) item.itemType = value;
- } else if(key == "rft.source") {
- item.publicationTitle = value;
- }
- }
- }
-
- // combine two lists of authors, eliminating duplicates
- for each(var au in complexAu) {
- var pushMe = true;
- for each(var pAu in item.creators) {
- // if there's a plain author that is close to this author (the
- // same last name, and the same first name up to a point), keep
- // the plain author, since it might have a middle initial
- if(pAu.lastName == au.lastName &&
- (pAu.firstName == au.firstName == "" ||
- (pAu.firstName.length >= au.firstName.length &&
- pAu.firstName.substr(0, au.firstName.length) == au.firstName))) {
- pushMe = false;
- break;
- }
- }
- if(pushMe) item.creators.push(au);
- }
-
- return item;
- }
-
- /*
- * Used to map tags for generating OpenURL contextObjects
- */
- function _mapTag(data, tag, version) {
- if(data) {
- if(version == "0.1") {
- return "&"+tag+"="+encodeURIComponent(data);
- } else {
- return "&rft."+tag+"="+encodeURIComponent(data);
- }
- } else {
- return "";
- }
- }
-}
-\ No newline at end of file
diff --git 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/openurl.js b/chrome/content/zotero/xpcom/openurl.js
@@ -0,0 +1,456 @@
+/*
+ ***** 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 <http://www.gnu.org/licenses/>.
+
+ ***** END LICENSE BLOCK *****
+*/
+
+Zotero.OpenURL = new function() {
+ this.resolve = resolve;
+ this.discoverResolvers = discoverResolvers;
+ this.createContextObject = createContextObject;
+ this.parseContextObject = parseContextObject;
+
+ /*
+ * Returns a URL to look up an item in the OpenURL resolver
+ */
+ function resolve(itemObject) {
+ var co = createContextObject(itemObject, Zotero.Prefs.get("openURL.version"));
+ if(co) {
+ var base = Zotero.Prefs.get("openURL.resolver");
+ // Add & if there's already a ?
+ var splice = base.indexOf("?") == -1 ? "?" : "&";
+ return base + splice + co;
+ }
+ return false;
+ }
+
+ /*
+ * Queries OCLC's OpenURL resolver registry and returns an address and version
+ */
+ function discoverResolvers() {
+ var req = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance();
+ req.open("GET", "http://worldcatlibraries.org/registry/lookup?IP=requestor", false);
+ req.send(null);
+
+ if(!req.responseXML) {
+ throw "Could not access resolver registry";
+ }
+
+ var resolverArray = new Array();
+ var resolvers = req.responseXML.getElementsByTagName("resolver");
+ for(var i=0; i<resolvers.length; i++) {
+ var resolver = resolvers[i];
+
+ var name = resolver.parentNode.getElementsByTagName("institutionName");
+ if(!name.length) {
+ continue;
+ }
+ name = name[0].textContent;
+
+ var url = resolver.getElementsByTagName("baseURL");
+ if(!url.length) {
+ continue;
+ }
+ url = url[0].textContent;
+
+ if(resolver.getElementsByTagName("Z39.88-2004").length > 0) {
+ var version = "1.0";
+ } else if(resolver.getElementsByTagName("OpenUrl 0.1").length > 0) {
+ var version = "0.1";
+ } else {
+ continue;
+ }
+
+ resolverArray.push({name:name, url:url, version:version});
+ }
+
+ return resolverArray;
+ }
+
+ /*
+ * Generates an OpenURL ContextObject from an item
+ */
+ function createContextObject(item, version) {
+ if(item.toArray) {
+ item = item.toArray();
+ }
+
+ var identifiers = new Array();
+ if(item.DOI) {
+ identifiers.push("info:doi/"+item.DOI);
+ }
+ if(item.ISBN) {
+ identifiers.push("urn:isbn:"+item.ISBN);
+ }
+
+ // encode ctx_ver (if available) and identifiers
+ // TODO identifiers may need to be encoded as follows:
+ // rft_id=info:doi/<the-url-encoded-doi>
+ // rft_id=http://<the-rest-of-the-url-encoded-url>
+ if(version == "0.1") {
+ var co = "sid=Zotero:"+encodeURIComponent(Zotero.version);
+
+ for each(identifier in identifiers) {
+ co += "&id="+encodeURIComponent(identifier);
+ }
+ } else {
+ var co = "url_ver=Z39.88-2004&ctx_ver=Z39.88-2004"+
+ "&rfr_id="+encodeURIComponent("info:sid/zotero.org:"+Zotero.version);
+
+ for each(identifier in identifiers) {
+ co += "&rft_id="+encodeURIComponent(identifier)
+ }
+ }
+
+ // encode genre and item-specific data
+ if(item.itemType == "journalArticle") {
+ if(version == "0.1") {
+ co += "&genre=article";
+ } else {
+ co += "&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Ajournal&rft.genre=article";
+ }
+ if(item.title) co += _mapTag(item.title, "atitle", version)
+ if(item.publicationTitle) co += _mapTag(item.publicationTitle, (version == "0.1" ? "title" : "jtitle"), version)
+ if(item.journalAbbreviation) co += _mapTag(item.journalAbbreviation, "stitle", version);
+ if(item.volume) co += _mapTag(item.volume, "volume", version);
+ if(item.issue) co += _mapTag(item.issue, "issue", version);
+ } else if(item.itemType == "book" || item.itemType == "bookSection") {
+ if(version == "0.1") {
+ co += "&genre=book";
+ } else {
+ co += "&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Abook";
+ }
+
+ if(item.itemType == "book") {
+ co += "&rft.genre=book";
+ if(item.title) co += _mapTag(item.title, (version == "0.1" ? "title" : "btitle"), version);
+ } else {
+ co += "&rft.genre=bookitem";
+ if(item.title) co += _mapTag(item.title, "atitle", version)
+ if(item.publicationTitle) co += _mapTag(item.publicationTitle, (version == "0.1" ? "title" : "btitle"), version);
+ }
+
+ if(item.place) co += _mapTag(item.place, "place", version);
+ if(item.publisher) co += _mapTag(item.publisher, "publisher", version)
+ if(item.edition) co += _mapTag(item.edition, "edition", version);
+ if(item.series) co += _mapTag(item.series, "series", version);
+ } else if(item.itemType == "thesis" && version == "1.0") {
+ co += "&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adissertation";
+
+ if(item.title) co += _mapTag(item.title, "title", version);
+ if(item.publisher) co += _mapTag(item.publisher, "inst", version);
+ if(item.type) co += _mapTag(item.type, "degree", version);
+ } else if(item.itemType == "patent" && version == "1.0") {
+ co += "&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Apatent";
+
+ if(item.title) co += _mapTag(item.title, "title", version);
+ if(item.assignee) co += _mapTag(item.assignee, "assignee", version);
+ if(item.patentNumber) co += _mapTag(item.patentNumber, "number", version);
+
+ if(item.issueDate) {
+ co += _mapTag(Zotero.Date.strToISO(item.issueDate), "date", version);
+ }
+ } else {
+ return false;
+ }
+
+ if(item.creators && item.creators.length) {
+ // encode first author as first and last
+ var firstCreator = item.creators[0];
+ if(item.itemType == "patent") {
+ co += _mapTag(firstCreator.firstName, "invfirst", version);
+ co += _mapTag(firstCreator.lastName, "invlast", version);
+ } else {
+ if(firstCreator.isInstitution) {
+ co += _mapTag(firstCreator.lastName, "aucorp", version);
+ } else {
+ co += _mapTag(firstCreator.firstName, "aufirst", version);
+ co += _mapTag(firstCreator.lastName, "aulast", version);
+ }
+ }
+
+ // encode subsequent creators as au
+ for each(creator in item.creators) {
+ co += _mapTag((creator.firstName ? creator.firstName+" " : "")+creator.lastName, (item.itemType == "patent" ? "inventor" : "au"), version);
+ }
+ }
+
+ if(item.date) {
+ co += _mapTag(Zotero.Date.strToISO(item.date), (item.itemType == "patent" ? "appldate" : "date"), version);
+ }
+ if(item.pages) co += _mapTag(item.pages, "pages", version);
+ if(item.ISBN) co += _mapTag(item.ISBN, "isbn", version);
+ if(item.ISSN) co += _mapTag(item.ISSN, "issn", version);
+
+ return co;
+ }
+
+ /*
+ * Generates an item in the format returned by item.fromArray() given an
+ * OpenURL version 1.0 contextObject
+ *
+ * accepts an item array to fill, or creates and returns a new item array
+ */
+ function parseContextObject(co, item) {
+ if(!item) {
+ var item = new Array();
+ item.creators = new Array();
+ }
+
+ var coParts = co.split("&");
+
+ // get type
+ for each(var part in coParts) {
+ if(part.substr(0, 12) == "rft_val_fmt=") {
+ var format = decodeURIComponent(part.substr(12));
+ if(format == "info:ofi/fmt:kev:mtx:journal") {
+ item.itemType = "journalArticle";
+ break;
+ } else if(format == "info:ofi/fmt:kev:mtx:book") {
+ if(coParts.indexOf("rft.genre=bookitem") !== -1) {
+ item.itemType = "bookSection";
+ } else if(coParts.indexOf("rft.genre=conference") !== -1 || coParts.indexOf("rft.genre=proceeding") !== -1) {
+ item.itemType = "conferencePaper";
+ } else if(coParts.indexOf("rft.genre=report") !== -1) {
+ item.itemType = "report";
+ } else {
+ item.itemType = "book";
+ }
+ break;
+ } else if(format == "info:ofi/fmt:kev:mtx:dissertation") {
+ item.itemType = "thesis";
+ break;
+ } else if(format == "info:ofi/fmt:kev:mtx:patent") {
+ item.itemType = "patent";
+ break;
+ } else if(format == "info:ofi/fmt:kev:mtx:dc") {
+ item.itemType = "webpage";
+ break;
+ }
+ }
+ }
+ if(!item.itemType) {
+ return false;
+ }
+
+ var pagesKey = "";
+
+ // keep track of "aucorp," "aufirst," "aulast"
+ var complexAu = new Array();
+
+ for each(var part in coParts) {
+ var keyVal = part.split("=");
+ var key = keyVal[0];
+ var value = decodeURIComponent(keyVal[1].replace(/\+|%2[bB]/g, " "));
+ if(!value) {
+ continue;
+ }
+
+ if(key == "rft_id") {
+ var firstEight = value.substr(0, 8).toLowerCase();
+ if(firstEight == "info:doi") {
+ item.DOI = value.substr(9);
+ } else if(firstEight == "urn:isbn") {
+ item.ISBN = value.substr(9);
+ } else if(value.match(/^https?:\/\//)) {
+ item.url = value;
+ item.accessDate = "";
+ }
+ } else if(key == "rft.btitle") {
+ if(item.itemType == "book" || item.itemType == "conferencePaper" || item.itemType == "report") {
+ item.title = value;
+ } else if(item.itemType == "bookSection") {
+ item.publicationTitle = value;
+ }
+ } else if(key == "rft.atitle" && (item.itemType == "journalArticle" ||
+ item.itemType == "bookSection")) {
+ item.title = value;
+ } else if(key == "rft.jtitle" && item.itemType == "journalArticle") {
+ item.publicationTitle = value;
+ } else if(key == "rft.stitle" && item.itemType == "journalArticle") {
+ item.journalAbbreviation = value;
+ } else if(key == "rft.title") {
+ if(item.itemType == "journalArticle" || item.itemType == "bookSection") {
+ item.publicationTitle = value;
+ } else {
+ item.title = value;
+ }
+ } else if(key == "rft.date") {
+ if(item.itemType == "patent") {
+ item.issueDate = value;
+ } else {
+ item.date = value;
+ }
+ } else if(key == "rft.volume") {
+ item.volume = value;
+ } else if(key == "rft.issue") {
+ item.issue = value;
+ } else if(key == "rft.pages") {
+ pagesKey = key;
+ item.pages = value;
+ } else if(key == "rft.spage") {
+ if(pagesKey != "rft.pages") {
+ // make pages look like start-end
+ if(pagesKey == "rft.epage") {
+ if(value != item.pages) {
+ item.pages = value+"-"+item.pages;
+ }
+ } else {
+ item.pages = value;
+ }
+ pagesKey = key;
+ }
+ } else if(key == "rft.epage") {
+ if(pagesKey != "rft.pages") {
+ // make pages look like start-end
+ if(pagesKey == "rft.spage") {
+ if(value != item.pages) {
+ item.pages = item.pages+"-"+value;
+ }
+ } else {
+ item.pages = value;
+ }
+ pagesKey = key;
+ }
+ } else if(key == "rft.issn" || (key == "rft.eissn" && !item.ISSN)) {
+ item.ISSN = value;
+ } else if(key == "rft.aulast" || key == "rft.invlast") {
+ var lastCreator = complexAu[complexAu.length-1];
+ if(complexAu.length && !lastCreator.lastName && !lastCreator.institutional) {
+ lastCreator.lastName = value;
+ } else {
+ complexAu.push({lastName:value, creatorType:(key == "rft.aulast" ? "author" : "inventor")});
+ }
+ } else if(key == "rft.aufirst" || key == "rft.invfirst") {
+ var lastCreator = complexAu[complexAu.length-1];
+ if(complexAu.length && !lastCreator.firstName && !lastCreator.institutional) {
+ lastCreator.firstName = value;
+ } else {
+ complexAu.push({firstName:value, creatorType:(key == "rft.aufirst" ? "author" : "inventor")});
+ }
+ } else if(key == "rft.au" || key == "rft.creator" || key == "rft.contributor" || key == "rft.inventor") {
+ if(key == "rft.contributor") {
+ var type = "contributor";
+ } else if(key == "rft.inventor") {
+ var type = "inventor";
+ } else {
+ var type = "author";
+ }
+
+ if(value.indexOf(",") !== -1) {
+ item.creators.push(Zotero.Utilities.cleanAuthor(value, type, true));
+ } else {
+ item.creators.push(Zotero.Utilities.cleanAuthor(value, type, false));
+ }
+ } else if(key == "rft.aucorp") {
+ complexAu.push({lastName:value, isInstitution:true});
+ } else if(key == "rft.isbn" && !item.ISBN) {
+ item.ISBN = value;
+ } else if(key == "rft.pub" || key == "rft.publisher") {
+ item.publisher = value;
+ } else if(key == "rft.place") {
+ item.place = value;
+ } else if(key == "rft.edition") {
+ item.edition = value;
+ } else if(key == "rft.series") {
+ item.series = value;
+ } else if(item.itemType == "thesis") {
+ if(key == "rft.inst") {
+ item.publisher = value;
+ } else if(key == "rft.degree") {
+ item.type = value;
+ }
+ } else if(item.itemType == "patent") {
+ if(key == "rft.assignee") {
+ item.assignee = value;
+ } else if(key == "rft.number") {
+ item.patentNumber = value;
+ } else if(key == "rft.appldate") {
+ item.date = value;
+ }
+ } else if(format == "info:ofi/fmt:kev:mtx:dc") {
+ if(key == "rft.identifier") {
+ if(value.length > 8) { // we could check length separately for
+ // each type, but all of these identifiers
+ // must be > 8 characters
+ if(value.substr(0, 5) == "ISBN ") {
+ item.ISBN = value.substr(5);
+ } else if(value.substr(0, 5) == "ISSN ") {
+ item.ISSN = value.substr(5);
+ } else if(value.substr(0, 8) == "urn:doi:") {
+ item.DOI = value.substr(4);
+ } else if(value.substr(0, 7) == "http://" || value.substr(0, 8) == "https://") {
+ item.url = value;
+ }
+ }
+ } else if(key == "rft.description") {
+ item.abstractNote = value;
+ } else if(key == "rft.rights") {
+ item.rights = value;
+ } else if(key == "rft.language") {
+ item.language = value;
+ } else if(key == "rft.subject") {
+ item.tags.push(value);
+ } else if(key == "rft.type") {
+ if(Zotero.ItemTypes.getID(value)) item.itemType = value;
+ } else if(key == "rft.source") {
+ item.publicationTitle = value;
+ }
+ }
+ }
+
+ // combine two lists of authors, eliminating duplicates
+ for each(var au in complexAu) {
+ var pushMe = true;
+ for each(var pAu in item.creators) {
+ // if there's a plain author that is close to this author (the
+ // same last name, and the same first name up to a point), keep
+ // the plain author, since it might have a middle initial
+ if(pAu.lastName == au.lastName &&
+ (pAu.firstName == au.firstName == "" ||
+ (pAu.firstName.length >= au.firstName.length &&
+ pAu.firstName.substr(0, au.firstName.length) == au.firstName))) {
+ pushMe = false;
+ break;
+ }
+ }
+ if(pushMe) item.creators.push(au);
+ }
+
+ return item;
+ }
+
+ /*
+ * Used to map tags for generating OpenURL contextObjects
+ */
+ function _mapTag(data, tag, version) {
+ if(data) {
+ if(version == "0.1") {
+ return "&"+tag+"="+encodeURIComponent(data);
+ } else {
+ return "&rft."+tag+"="+encodeURIComponent(data);
+ }
+ } else {
+ return "";
+ }
+ }
+}
+\ No newline at end of file
diff --git 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
@@ -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
@@ -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
@@ -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',