From bc12d9263991f064a3bc35e5ed898554dbed1127 Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Fri, 11 Jan 2013 22:27:59 -0500 Subject: [PATCH] Make date parts indicator match order in date itself This may not work properly for all inputs, but it worked with everything I tried. (This need unit tests once we have a functional unit-testing framework again.) --- chrome/content/zotero/bindings/itembox.xml | 27 +--- chrome/content/zotero/xpcom/date.js | 142 ++++++++++++++---- .../skin/default/zotero/bindings/itembox.css | 10 +- 3 files changed, 122 insertions(+), 57 deletions(-) diff --git a/chrome/content/zotero/bindings/itembox.xml b/chrome/content/zotero/bindings/itembox.xml index 474606659e..c4468a03c7 100644 --- a/chrome/content/zotero/bindings/itembox.xml +++ b/chrome/content/zotero/bindings/itembox.xml @@ -847,30 +847,19 @@ elem.setAttribute('flex', 1); // y-m-d status indicator - var datebox = document.createElement('hbox'); - datebox.className = 'zotero-date-field-status'; - var year = document.createElement('label'); - var month = document.createElement('label'); - var day = document.createElement('label'); - year.setAttribute('value', Zotero.getString('date.abbreviation.year')); - month.setAttribute('value', Zotero.getString('date.abbreviation.month')); - day.setAttribute('value', Zotero.getString('date.abbreviation.day')); - - // Display the date parts we have and hide the others - var sqldate = Zotero.Date.multipartToSQL(value); - year.setAttribute('hidden', !Zotero.Date.sqlHasYear(sqldate)); - month.setAttribute('hidden', !Zotero.Date.sqlHasMonth(sqldate)); - day.setAttribute('hidden', !Zotero.Date.sqlHasDay(sqldate)); - - datebox.appendChild(year); - datebox.appendChild(month); - datebox.appendChild(day); + var ymd = document.createElement('label'); + ymd.id = 'zotero-date-field-status'; + ymd.setAttribute( + 'value', + Zotero.Date.strToDate(Zotero.Date.multipartToStr(value)) + .order.split('').join(' ') + ); var hbox = document.createElement('hbox'); hbox.setAttribute('flex', 1); hbox.className = "date-box"; hbox.appendChild(elem); - hbox.appendChild(datebox); + hbox.appendChild(ymd); this.addDynamicRow(label, hbox); ]]> diff --git a/chrome/content/zotero/xpcom/date.js b/chrome/content/zotero/xpcom/date.js index c6be728e61..2d407cd8a0 100644 --- a/chrome/content/zotero/xpcom/date.js +++ b/chrome/content/zotero/xpcom/date.js @@ -240,7 +240,10 @@ Zotero.Date = new function(){ string = Zotero.Date.dateToSQL(new Date(new Date().getTime() + 86400000)).substr(0, 10); } - var date = new Object(); + var date = { + order: '' + }; + var parts = []; // skip empty things if(!string) { @@ -261,12 +264,16 @@ Zotero.Date = new function(){ date.year = m[2]; date.month = m[4]; date.day = m[6]; + date.order += m[2] ? 'y' : ''; + date.order += m[4] ? 'm' : ''; + date.order += m[6] ? 'd' : ''; } else if(m[2] && !m[4] && m[6]) { date.month = m[2]; date.year = m[6]; + date.order += m[2] ? 'm' : ''; + date.order += m[6] ? 'y' : ''; } else { // local style date (middle or little endian) - date.year = m[6]; var country = Zotero.locale ? Zotero.locale.substr(3) : "US"; if(country == "US" || // The United States country == "FM" || // The Federated States of Micronesia @@ -274,10 +281,16 @@ Zotero.Date = new function(){ country == "PH") { // The Philippines date.month = m[2]; date.day = m[4]; + date.order += m[2] ? 'm' : ''; + date.order += m[4] ? 'd' : ''; } else { date.month = m[4]; date.day = m[2]; + date.order += m[2] ? 'd' : ''; + date.order += m[4] ? 'm' : ''; } + date.year = m[6]; + date.order += 'y'; } if(date.year) date.year = parseInt(date.year, 10); @@ -290,6 +303,10 @@ Zotero.Date = new function(){ var tmp = date.day; date.day = date.month date.month = tmp; + date.order = date.order.replace('m', 'D') + .replace('d', 'M') + .replace('D', 'd') + .replace('M', 'm'); } } @@ -313,25 +330,39 @@ Zotero.Date = new function(){ if(date.month) date.month--; // subtract one for JS style Zotero.debug("DATE: retrieved with algorithms: "+JSON.stringify(date)); - date.part = m[1]+m[7]; + parts.push( + { part: m[1], before: true }, + { part: m[7] } + ); } else { // give up; we failed the sanity check Zotero.debug("DATE: algorithms failed sanity check"); - date = {"part":string}; + var date = { + order: '' + }; + parts.push({ part: string }); } } else { Zotero.debug("DATE: could not apply algorithms"); - date.part = string; + parts.push({ 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+")"); + for (var i in parts) { + var m = _yearRe.exec(parts[i].part); + if (m) { + date.year = m[2]; + date.order = _insertDateOrderPart(date.order, 'y', parts[i]); + parts.splice( + i, 1, + { part: m[1], before: true }, + { part: m[3] } + ); + Zotero.debug("DATE: got year (" + date.year + ", " + JSON.stringify(parts) + ")"); + break; + } } } @@ -351,12 +382,20 @@ Zotero.Date = new function(){ _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].toLowerCase()) % 12; - date.part = m[1]+m[3]; - Zotero.debug("DATE: got month ("+date.month+", "+date.part+")"); + for (var i in parts) { + var m = _monthRe.exec(parts[i].part); + if (m) { + // Modulo 12 in case we have multiple languages + date.month = months.indexOf(m[2].toLowerCase()) % 12; + date.order = _insertDateOrderPart(date.order, 'm', parts[i]); + parts.splice( + i, 1, + { part: m[1], before: "m" }, + { part: m[3], after: "m" } + ); + Zotero.debug("DATE: got month (" + date.month + ", " + JSON.stringify(parts) + ")"); + break; + } } } @@ -368,26 +407,39 @@ Zotero.Date = new function(){ _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];; + for (var i in parts) { + var m = _dayRe.exec(parts[i].part); + if (m) { + var day = parseInt(m[1], 10); + // Sanity check + if (day <= 31) { + date.day = day; + date.order = _insertDateOrderPart(date.order, 'd', parts[i]); + if(m.index > 0) { + var part = parts[i].part.substr(0, m.index); + if(m[2]) { + part += " " + m[2];; + } + } else { + var part = m[2]; } - } else { - date.part = m[2]; + parts.splice( + i, 1, + { part: part } + ); + Zotero.debug("DATE: got day (" + date.day + ", " + JSON.stringify(parts) + ")"); + break; } - - Zotero.debug("DATE: got day ("+date.day+", "+date.part+")"); } } } + // Concatenate date parts + date.part = ''; + for (var i in parts) { + date.part += parts[i].part + ' '; + } + // clean up date part if(date.part) { date.part = date.part.replace(/^[^A-Za-z0-9]+/, "").replace(/[^A-Za-z0-9]+$/, ""); @@ -400,6 +452,36 @@ Zotero.Date = new function(){ return date; } + + function _insertDateOrderPart(dateOrder, part, partOrder) { + if (!dateOrder) { + return part; + } + if (partOrder.before === true) { + return part + dateOrder; + } + if (partOrder.after === true) { + return dateOrder + part; + } + if (partOrder.before) { + var pos = dateOrder.indexOf(partOrder.before); + if (pos == -1) { + return dateOrder; + } + return dateOrder.replace(new RegExp("(" + partOrder.before + ")"), part + '$1'); + } + if (partOrder.after) { + var pos = dateOrder.indexOf(partOrder.after); + if (pos == -1) { + return dateOrder + part; + } + return dateOrder.replace(new RegExp("(" + partOrder.after + ")"), '$1' + part); + } + return dateOrder + part; + } + + + /** * does pretty formatting of a date object returned by strToDate() * diff --git a/chrome/skin/default/zotero/bindings/itembox.css b/chrome/skin/default/zotero/bindings/itembox.css index aa608e7e95..bb1232ea5f 100644 --- a/chrome/skin/default/zotero/bindings/itembox.css +++ b/chrome/skin/default/zotero/bindings/itembox.css @@ -96,17 +96,11 @@ row > vbox > description margin: 0 !important; } -hbox.zotero-date-field-status -{ - margin-right: 7px !important; -} - -hbox.zotero-date-field-status > label +#zotero-date-field-status { font-weight: bold; color: #666; - margin: 0 0 0 1px !important; - padding: 0 1px 0 1px !important; + padding: 0 10px 0 1px !important; } #item-type-menu