Timeline Update:
- Changed the URL format to use query strings in order to make URLs more flexible - Changed the "Jump to Year" option... 1) goes to the typed year 1 second after a change to the text field or when the user pushes the return key 2) deleting everything in the text field returns the timeline to today's date 3) removed the "Go..." button
This commit is contained in:
parent
f054f41519
commit
3491798be2
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 = '<body onload="onLoad(';
|
||||
var a = (getInterval(intervals[0])) ? getInterval(intervals[0]) : 'Timeline.DateTime.MONTH';
|
||||
var b = (getInterval(intervals[1])) ? getInterval(intervals[1]) : 'Timeline.DateTime.YEAR';
|
||||
var c = (getInterval(intervals[2])) ? getInterval(intervals[2]) : 'Timeline.DateTime.DECADE';
|
||||
var theTemp = '<body onload="onLoad(';
|
||||
var a = (theIntervals[intervals[0]]) ? theIntervals[intervals[0]] : 'Timeline.DateTime.MONTH';
|
||||
var b = (theIntervals[intervals[1]]) ? theIntervals[intervals[1]] : 'Timeline.DateTime.YEAR';
|
||||
var c = (theIntervals[intervals[2]]) ? theIntervals[intervals[2]] : 'Timeline.DateTime.DECADE';
|
||||
content = content.replace(theTemp, theTemp + a + ',' + b + ',' + c + ',\'' + timelineDate + '\'');
|
||||
|
||||
|
||||
theTemp = 'Timeline.loadXML("zotero://timeline/data/';
|
||||
var d = '';
|
||||
//passes information (type,ids, dateType) for when the XML is created
|
||||
if(!type || (type != 'collection' && type != 'search')) {
|
||||
d += 'library?t=' + dateType;
|
||||
}
|
||||
else {
|
||||
d += type + '/' + id + '?t=' + dateType;
|
||||
}
|
||||
content = content.replace(theTemp, theTemp + d);
|
||||
|
||||
|
||||
var uri_str = 'data:' + (mimeType ? mimeType + ',' : '') + encodeURIComponent(content);
|
||||
var ext_uri = ioService.newURI(uri_str, null, null);
|
||||
var extChannel = ioService.newChannelFromURI(ext_uri);
|
||||
|
@ -298,72 +345,75 @@ function ChromeExtensionHandler() {
|
|||
return extChannel;
|
||||
}
|
||||
else {
|
||||
var [data, dateType, type, ids] = pathParts;
|
||||
}
|
||||
//creates XML file
|
||||
switch (type){
|
||||
case 'collection':
|
||||
var results = Zotero.getItems(ids);
|
||||
break;
|
||||
//creates XML file
|
||||
var [, type, ids] = pathParts;
|
||||
|
||||
switch (type){
|
||||
case 'collection':
|
||||
var results = Zotero.getItems(ids);
|
||||
break;
|
||||
|
||||
case 'search':
|
||||
var s = new Zotero.Search(ids);
|
||||
var ids = s.search();
|
||||
break;
|
||||
case 'search':
|
||||
var s = new Zotero.Search(ids);
|
||||
var ids = s.search();
|
||||
break;
|
||||
|
||||
case 'items':
|
||||
case 'item':
|
||||
var ids = ids.split('-');
|
||||
break;
|
||||
|
||||
default:
|
||||
var type = 'library';
|
||||
var s = new Zotero.Search();
|
||||
s.addCondition('noChildren', 'true');
|
||||
var ids = s.search();
|
||||
}
|
||||
|
||||
if (!results) {
|
||||
var results = Zotero.Items.get(ids);
|
||||
}
|
||||
var items = [];
|
||||
// Only include parent items
|
||||
for (var i = 0; i < results.length; i++) {
|
||||
if (!results[i].getSource()) {
|
||||
items.push(results[i]);
|
||||
default:
|
||||
type = 'library';
|
||||
var s = new Zotero.Search();
|
||||
s.addCondition('noChildren', 'true');
|
||||
var ids = s.search();
|
||||
}
|
||||
|
||||
if (!results) {
|
||||
var results = Zotero.Items.get(ids);
|
||||
}
|
||||
var items = [];
|
||||
// Only include parent items
|
||||
for (var i = 0; i < results.length; i++) {
|
||||
if (!results[i].getSource()) {
|
||||
items.push(results[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!items) {
|
||||
mimeType = 'text/html';
|
||||
content = 'Invalid ID';
|
||||
break generateContent;
|
||||
}
|
||||
|
||||
// Convert item objects to export arrays
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
items[i] = items[i].toArray();
|
||||
}
|
||||
|
||||
mimeType = 'application/xml';
|
||||
|
||||
|
||||
var theDateTypes = new Object();
|
||||
theDateTypes['d'] = 'date';
|
||||
theDateTypes['da'] = 'dateAdded';
|
||||
theDateTypes['dm'] = 'dateModified';
|
||||
|
||||
//default dateType = date
|
||||
if (!dateType || !theDateTypes[dateType]) {
|
||||
dateType = 'd';
|
||||
}
|
||||
|
||||
content = Zotero.Timeline.generateXMLDetails(items, theDateTypes[dateType]);
|
||||
|
||||
}
|
||||
|
||||
var uri_str = 'data:' + (mimeType ? mimeType + ',' : '') + encodeURIComponent(content);
|
||||
var ext_uri = ioService.newURI(uri_str, null, null);
|
||||
var extChannel = ioService.newChannelFromURI(ext_uri);
|
||||
|
||||
if (!items) {
|
||||
mimeType = 'text/html';
|
||||
content = 'Invalid ID';
|
||||
break generateContent;
|
||||
}
|
||||
|
||||
// Convert item objects to export arrays
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
items[i] = items[i].toArray();
|
||||
}
|
||||
|
||||
mimeType = 'application/xml';
|
||||
|
||||
//default dateType = date (publication date)
|
||||
if (!dateType) {
|
||||
dateType = 'date';
|
||||
}
|
||||
content = Zotero.Timeline.generateXMLDetails(items, dateType);
|
||||
|
||||
return extChannel;
|
||||
}
|
||||
catch (e){
|
||||
Zotero.debug(e);
|
||||
throw (e);
|
||||
}
|
||||
|
||||
var uri_str = 'data:' + (mimeType ? mimeType + ',' : '') + encodeURIComponent(content);
|
||||
var ext_uri = ioService.newURI(uri_str, null, null);
|
||||
var extChannel = ioService.newChannelFromURI(ext_uri);
|
||||
|
||||
return extChannel;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user