move Zotero.Date and Zotero.OpenURL to independent files
This commit is contained in:
parent
a7f535ee85
commit
e61dd60024
7 changed files with 754 additions and 727 deletions
695
chrome/content/zotero/xpcom/date.js
Normal file
695
chrome/content/zotero/xpcom/date.js
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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;
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -85,7 +85,6 @@ Zotero.Utilities = {
|
|||
*/
|
||||
"trim":function(/**String*/ s) {
|
||||
if (typeof(s) != "string") {
|
||||
Zotero.debug(s);
|
||||
throw "trim: argument must be a string";
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
||||
|
|
|
@ -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',
|
||||
|
|
Loading…
Add table
Reference in a new issue