diff --git a/chrome/content/zotero/timelineInterface.js b/chrome/content/zotero/timelineInterface.js index 778f8ec86..ec1e38399 100644 --- a/chrome/content/zotero/timelineInterface.js +++ b/chrome/content/zotero/timelineInterface.js @@ -28,21 +28,17 @@ var Zotero_Timeline_Interface = new function() { * Load a timeline for the currently selected collection */ function loadTimeline() { - var today=Date(); - var dateParts=today.toString().split(' '); - today=dateParts[1]+'.'+dateParts[2]+'.'+dateParts[3]; - - var uri = 'zotero://timeline/mye/' + today + '/date'; + var uri = 'zotero://timeline/'; var id = ZoteroPane.getSelectedCollection(true); if (id) { - window.loadURI(uri + '/collection/' + id); + window.loadURI(uri + 'collection/' + id); return; } var id = ZoteroPane.getSelectedSavedSearch(true); if (id) { - window.loadURI(uri + '/search/' + id); + window.loadURI(uri + 'search/' + id); return; } diff --git a/chrome/locale/en-US/zotero/timeline.properties b/chrome/locale/en-US/zotero/timeline.properties index 843639711..2e41c88e7 100644 --- a/chrome/locale/en-US/zotero/timeline.properties +++ b/chrome/locale/en-US/zotero/timeline.properties @@ -8,7 +8,6 @@ general.secondBand = Second Band: general.thirdBand = Third Band: general.dateType = Date Type: general.timelineHeight = Timeline Height: -general.go = Go... general.fitToScreen = Fit to Screen interval.day = Day diff --git a/chrome/skin/default/zotero/timeline/timelineControls.js b/chrome/skin/default/zotero/timeline/timelineControls.js index 2890061f5..938af139e 100644 --- a/chrome/skin/default/zotero/timeline/timelineControls.js +++ b/chrome/skin/default/zotero/timeline/timelineControls.js @@ -1,4 +1,6 @@ var localeHash = getLocaleHash(); +var jumpToYearTimer; +var lastJumpToYearValue; function getLocaleHash() { var localeHash = new Object(); @@ -25,7 +27,7 @@ function getContentsFromURL(url) { function getTimeline() { var tt = getHeight(); - tt -= 180; + tt -= 165; if (tt < 100) { tt = 100; } @@ -46,12 +48,31 @@ function getHeight() { return 0; } -function doReturn(e) -{ - if(e.which) { - if(e.which == '13'){ - checkDate(document.getElementById('jumpYear').value); +function wasChanged(current) { + if (current != lastJumpToYearValue) { + lastJumpToYearValue = current; + var theYear = document.getElementById("jumpYear").value; + if(theYear.length == 0) { + centerTimeline(new Date()); } + else { + checkDate(theYear); + } + } +} + +function doTheKeyPress(e) +{ + clearTimeout(jumpToYearTimer); + lastJumpToYearValue = document.getElementById('jumpYear').value; + if((e.which == '8' || e.which == '0') && lastJumpToYearValue.length == 0) { + centerTimeline(new Date()); + } + else if(e.which == '13'){ + checkDate(lastJumpToYearValue); + } + else { + jumpToYearTimer = setTimeout('wasChanged(document.getElementById("jumpYear").value);', 1000) } } @@ -97,15 +118,18 @@ function checkDate(date) { } if (bc) { - centerTimeline(date + ' BC'); + if(date < 10000) { + centerTimeline(date + ' BC'); + } } else { - centerTimeline(date); + if(date < 275000) { + centerTimeline(date); + } } } -function changeBand(band, intervals, date, url, selectedIndex) { +function changeBand(path, queryString, band, intervals, selectedIndex) { var values = new Array('d', 'm', 'y', 'e', 'c', 'i'); - var temp = url.split('/'); var newIntervals = ''; for (var i = 0; i < intervals.length; i++) { @@ -116,17 +140,8 @@ function changeBand(band, intervals, date, url, selectedIndex) { newIntervals += intervals[i]; } } - temp[3] = newIntervals; - temp[4] = date; - window.location = temp.join('/'); -} - -function changeDateType(url, intervals, values, date, seletedIndex) { - var temp = url.split('/'); - temp[3] = intervals; - temp[4] = date; - temp[5] = values[seletedIndex]; - window.location = temp.join('/'); + + window.location = path + queryString + 'i=' + newIntervals; } function createOption(t, selected) { @@ -159,15 +174,65 @@ function getFull(a) { } } +function createQueryString(theQueryValue, except, timeline) { + var temp = '?'; + for(var i in theQueryValue) { + if(except != i) { + temp += i + '=' + theQueryValue[i] + '&'; + } + } + if(except != 'd') { + temp += 'd=' + getTimelineDate(timeline) + '&'; + } + //remove last & if no exceptions + if(!except) { + temp = temp.substr(0, temp.length -1) + } + return temp; +} + function setupOtherControls(div, timeline, url) { var table = document.createElement("table"); - // url= zotero://timeline/intervals/timelineDate/dateType/type/ids/ - var parts = url.split('/'); - var intervals = parts[3]; - if (intervals.length < 3) { - intervals += "mye".substr(intervals.length); + var [path, queryString] = url.split('?'); + if(path == 'zotero://timeline') { + path += '/'; } + if(path =='zotero://timeline/') { + path += 'library'; + } + var defaultQueryValue = new Object(); + defaultQueryValue['i'] = 'mye'; + defaultQueryValue['t'] = 'd'; + + var theQueryValue = new Object; + + if (queryString) { + var queryVars = queryString.split('&'); + for (var i in queryVars) { + var [key, val] = queryVars[i].split('='); + if(val) { + switch (key) { + case 'i': + theQueryValue['i'] = val; + break; + case 't': + theQueryValue['t'] = val; + break; + } + } + } + } + + var intervals = (theQueryValue['i']) ? theQueryValue['i'] : defaultQueryValue['i']; + if (intervals.length < 3) { + intervals += defaultQueryValue['i'].substr(intervals.length); + } + var dateType = (theQueryValue['t']) ? theQueryValue['t'] : defaultQueryValue['t']; + if(dateType != 'da' && dateType != 'dm') { + dateType = defaultQueryValue['t']; + } + var tr = table.insertRow(0); var td = tr.insertCell(0); @@ -190,8 +255,8 @@ function setupOtherControls(div, timeline, url) { var input = document.createElement("input"); input.type = "text"; input.size = "15"; - input.id="jumpYear"; - input.onkeypress=doReturn; + input.id = "jumpYear"; + input.onkeypress=doTheKeyPress; td.appendChild(input); var options = new Array(localeHash["interval.day"], localeHash["interval.month"], localeHash["interval.year"], @@ -207,7 +272,7 @@ function setupOtherControls(div, timeline, url) { select1.appendChild(createOption(options[i],(options[i] == selected))); } select1.onchange = function () { - changeBand(0, intervals, getTimelineDate(timeline), url, table.rows[1].cells[1].firstChild.selectedIndex); + changeBand(path, createQueryString(theQueryValue, 'i', timeline), 0, intervals, table.rows[1].cells[1].firstChild.selectedIndex); }; td.appendChild(select1); @@ -219,7 +284,7 @@ function setupOtherControls(div, timeline, url) { select2.appendChild(createOption(options[i],(options[i] == selected))); } select2.onchange = function () { - changeBand(1, intervals, getTimelineDate(timeline), url, table.rows[1].cells[2].firstChild.selectedIndex); + changeBand(path, createQueryString(theQueryValue, 'i', timeline), 1, intervals, table.rows[1].cells[2].firstChild.selectedIndex); }; td.appendChild(select2); @@ -231,27 +296,21 @@ function setupOtherControls(div, timeline, url) { select3.appendChild(createOption(options[i],(options[i] == selected))); } select3.onchange = function () { - changeBand(2, intervals, getTimelineDate(timeline), url, table.rows[1].cells[3].firstChild.selectedIndex); + changeBand(path, createQueryString(theQueryValue, 'i', timeline), 2, intervals, table.rows[1].cells[3].firstChild.selectedIndex); }; td.appendChild(select3); + td = tr.insertCell(tr.cells.length); options = new Array(localeHash["dateType.published"], localeHash["dateType.added"], localeHash["dateType.modified"]); - var values = new Array('date', 'dateAdded', 'dateModified'); + var values = new Array('d', 'da', 'dm'); var select4 = document.createElement("select"); - selected = 0; - if (parts[5]) { - selected = values.indexOf(parts[5]); - } - if (selected < 0) { - selected = 0; - } - + for (var i = 0; i < options.length; i++) { - select4.appendChild(createOption(options[i],(i == selected))); + select4.appendChild(createOption(options[i],(values[i] == dateType))); } select4.onchange = function () { - changeDateType(url, intervals, values, getTimelineDate(timeline), table.rows[1].cells[4].firstChild.selectedIndex); + window.location = path + createQueryString(theQueryValue, 't', timeline) + 't=' + values[table.rows[1].cells[4].firstChild.selectedIndex]; }; td.appendChild(select4); @@ -259,22 +318,9 @@ function setupOtherControls(div, timeline, url) { var fitToScreen = document.createElement("button"); fitToScreen.innerHTML = localeHash["general.fitToScreen"]; Timeline.DOM.registerEvent(fitToScreen, "click", function () { - var temp = url.split('/'); - temp[3] = intervals; - temp[4] = getTimelineDate(timeline); - window.location = temp.join('/'); + window.location = path + createQueryString(theQueryValue, false, timeline); }); td.appendChild(fitToScreen); - - tr = table.insertRow(2); - td = tr.insertCell(0); - - var button = document.createElement("button"); - button.innerHTML = localeHash["general.go"]; - Timeline.DOM.registerEvent(button, "click", function () { - checkDate(table.rows[1].cells[0].firstChild.value); - }); - td.appendChild(button); div.appendChild(table); } diff --git a/components/zotero-protocol-handler.js b/components/zotero-protocol-handler.js index 6fc9f1914..0ece0ab6f 100644 --- a/components/zotero-protocol-handler.js +++ b/components/zotero-protocol-handler.js @@ -226,30 +226,37 @@ function ChromeExtensionHandler() { var TimelineExtension = new function(){ this.newChannel = newChannel; - function getInterval(a){ - switch (a){ - case 'd': - return 'Timeline.DateTime.DAY'; - case 'm': - return 'Timeline.DateTime.MONTH'; - case 'y': - return 'Timeline.DateTime.YEAR'; - case 'e': - return 'Timeline.DateTime.DECADE'; - case 'c': - return 'Timeline.DateTime.CENTURY'; - case 'i': - return 'Timeline.DateTime.MILLENNIUM'; - default: - return false; - } - } - /* - zotero://timeline/intervals/timelineDate/dateType/type/ids/ ----->creates html for timeline - zotero://timeline/ ------> minimum needed (defaults: intervals = month, year, decade | - timelineDate = today's date | dateType = date | type = library) - zotero://timeline/data/dateType/type/ids ----->creates XML + queryString key abbreviations: intervals = i | dateType = t | timelineDate = d + + interval abbreviations: day = d | month = m | year = y | decade = e | century = c | millennium = i + dateType abbreviations: date = d | dateAdded = da | dateModified = dm + timelineDate format: shortMonthName.day.year (year is positive for A.D. and negative for B.C.) + + + + zotero://timeline -----> creates HTML for timeline + (defaults: type = library | intervals = month, year, decade | timelineDate = today's date | dateType = date) + + + Example URLs: + + zotero://timeline/library?i=yec + zotero://timeline/collection/12345?t=da&d=Jul.24.2008 + zotero://timeline/search/54321?d=Dec.1.-500&i=dmy&t=d + + + + zotero://timeline/data ----->creates XML file + (defaults: type = library | dateType = date) + + + Example URLs: + + zotero://timeline/data/library?t=da + zotero://timeline/data/collection/12345 + zotero://timeline/data/search/54321?t=dm + */ function newChannel(uri) { var ioService = Components.classes["@mozilla.org/network/io-service;1"] @@ -263,34 +270,74 @@ function ChromeExtensionHandler() { var mimeType, content = ''; var [path, queryString] = uri.path.substr(1).split('?'); + var [intervals, timelineDate, dateType] = ['','','']; + + if (queryString) { + var queryVars = queryString.split('&'); + for (var i in queryVars) { + var [key, val] = queryVars[i].split('='); + if(val) { + switch (key) { + case 'i': + intervals = val; + break; + case 'd': + timelineDate = val; + break; + case 't': + dateType = val; + break; + } + } + } + } + var pathParts = path.split('/'); if (pathParts[0] != 'data') { //creates HTML file - var intervals = pathParts[0]; - var timelineDate = pathParts[1]; content = Zotero.File.getContentsFromURL('chrome://zotero/skin/timeline/timeline.html'); mimeType = 'text/html'; - var theTemp = 'Timeline.loadXML("zotero://timeline/data/'; - + var [type, id] = pathParts; + if(!timelineDate){ timelineDate=Date(); var dateParts=timelineDate.toString().split(' '); timelineDate=dateParts[1]+'.'+dateParts[2]+'.'+dateParts[3]; } - else { - //passes information (dateType,type,ids) for when the XML is created - content = content.replace(theTemp, theTemp + pathParts.slice(2).join('/')); + if (intervals.length < 3) { + intervals += "mye".substr(intervals.length); } - + + var theIntervals = new Object(); + theIntervals['d'] = 'Timeline.DateTime.DAY'; + theIntervals['m'] = 'Timeline.DateTime.MONTH'; + theIntervals['y'] = 'Timeline.DateTime.YEAR'; + theIntervals['e'] = 'Timeline.DateTime.DECADE'; + theIntervals['c'] = 'Timeline.DateTime.CENTURY'; + theIntervals['i'] = 'Timeline.DateTime.MILLENNIUM'; + //sets the intervals of the timeline bands - theTemp = '