587 lines
No EOL
17 KiB
JavaScript
587 lines
No EOL
17 KiB
JavaScript
/*
|
|
***** 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 *****
|
|
*/
|
|
|
|
var Zotero_Citation_Dialog = new function () {
|
|
var _preserveData = {
|
|
"prefix":"value",
|
|
"suffix":"value",
|
|
"label":"selectedIndex",
|
|
"locator":"value",
|
|
"suppress-author":"checked"
|
|
};
|
|
|
|
var _itemData = new Object();
|
|
var _multipleSourcesOn = false;
|
|
var _lastSelected = null;
|
|
var _previewShown = false;
|
|
var _suppressNextTreeSelect = false;
|
|
var _locatorIndexArray = {};
|
|
var _locatorNameArray = {};
|
|
var _autoRegeneratePref;
|
|
var _acceptButton;
|
|
var _sortCheckbox;
|
|
var _citationList;
|
|
var _originalHTML;
|
|
var io;
|
|
|
|
this.load = load;
|
|
this.toggleMultipleSources = toggleMultipleSources;
|
|
this.toggleEditor = toggleEditor;
|
|
this.treeItemSelected = treeItemSelected;
|
|
this.listItemSelected = listItemSelected;
|
|
this.up = up;
|
|
this.down = down;
|
|
this.add = add;
|
|
this.remove = remove;
|
|
this.sortCitation = sortCitation;
|
|
this.confirmRegenerate = confirmRegenerate;
|
|
this.accept = accept;
|
|
this.cancel = cancel;
|
|
|
|
/*
|
|
* initialize add citation dialog
|
|
*/
|
|
function load() {
|
|
document.documentElement.getButton("extra1").label = Zotero.getString("citation.multipleSources");
|
|
document.documentElement.getButton("extra2").label = Zotero.getString("citation.showEditor");
|
|
|
|
io = window.arguments[0].wrappedJSObject;
|
|
|
|
// find accept button
|
|
_acceptButton = document.getElementById("zotero-add-citation-dialog").getButton("accept");
|
|
_autoRegeneratePref = Zotero.Prefs.get("integration.autoRegenerate");
|
|
_citationList = document.getElementById("citation-list");
|
|
|
|
// if a style with sortable citations, present checkbox
|
|
if(io.sortable) {
|
|
_sortCheckbox = document.getElementById("keepSorted");
|
|
_sortCheckbox.hidden = false;
|
|
_sortCheckbox.checked = !io.citation.properties.unsorted;
|
|
}
|
|
|
|
// load locators
|
|
var locators = Zotero.Cite.labels;
|
|
var menu = document.getElementById("label");
|
|
var popup = document.getElementById("locator-type-popup");
|
|
var i = 0;
|
|
for(var value in locators) {
|
|
var locator = locators[value];
|
|
var locatorLabel = locator[0].toUpperCase()+locator.substr(1);
|
|
// add to popup
|
|
var child = document.createElement("menuitem");
|
|
child.setAttribute("value", value);
|
|
child.setAttribute("label", locatorLabel);
|
|
popup.appendChild(child);
|
|
// add to array
|
|
_locatorIndexArray[locator] = i;
|
|
_locatorNameArray[i] = locator;
|
|
i++;
|
|
}
|
|
menu.selectedIndex = 0;
|
|
|
|
// load (from selectItemsDialog.js)
|
|
doLoad();
|
|
|
|
// if we already have a citation, load data from it
|
|
document.getElementById('editor').format = "RTF";
|
|
if(io.citation.citationItems.length) {
|
|
if(io.citation.citationItems.length == 1) {
|
|
// single citation
|
|
_suppressNextTreeSelect = true;
|
|
itemsView.selectItem(io.citation.citationItems[0].id); // treeview from selectItemsDialog.js
|
|
for(var property in _preserveData) {
|
|
if(io.citation.citationItems[0][property]) {
|
|
if(property == "label") {
|
|
document.getElementById(property)[_preserveData[property]] = _locatorIndexArray[io.citation.citationItems[0][property]];
|
|
} else {
|
|
document.getElementById(property)[_preserveData[property]] = io.citation.citationItems[0][property];
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// multiple citations
|
|
toggleMultipleSources();
|
|
for(var i=0; i<io.citation.citationItems.length; i++) {
|
|
var item = Zotero.Items.get(io.citation.citationItems[i].id);
|
|
if(item) {
|
|
_addItem(item);
|
|
_itemData[io.citation.citationItems[i].id] = io.citation.citationItems[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
// show user-editable edited citation
|
|
if(io.citation.properties.custom) {
|
|
toggleEditor(io.citation.properties.custom);
|
|
delete io.citation.properties.custom;
|
|
}
|
|
|
|
_updateAccept();
|
|
}
|
|
}
|
|
|
|
/*
|
|
* turn on/off multiple sources item list
|
|
*/
|
|
function toggleMultipleSources() {
|
|
_multipleSourcesOn = !_multipleSourcesOn;
|
|
if(_multipleSourcesOn) {
|
|
var items = itemsView.getSelectedItems(true);
|
|
var itemID = (items.length ? items[0] : false);
|
|
// var itemDataID = itemID+"::"+0;
|
|
document.getElementById("multiple-sources").hidden = undefined;
|
|
document.getElementById("zotero-add-citation-dialog").width = "750";
|
|
document.documentElement.getButton("extra1").label = Zotero.getString("citation.singleSource");
|
|
// move user field content to multiple before adding XXXXX
|
|
if (itemID) {
|
|
// _itemData[itemDataID] = new Object();
|
|
_itemData[itemID] = new Object();
|
|
var element;
|
|
for (var box in _preserveData) {
|
|
element = document.getElementById(box);
|
|
// _itemData[itemDataID][box] = element[_preserveData[box]];
|
|
_itemData[itemID][box] = element[_preserveData[box]];
|
|
}
|
|
}
|
|
treeItemSelected();
|
|
// disable adding info until citation added
|
|
_itemSelected(false);
|
|
// add current selection
|
|
if (itemID) {
|
|
this.add();
|
|
} else {
|
|
_updateAccept();
|
|
_updatePreview();
|
|
}
|
|
} else {
|
|
document.getElementById("multiple-sources").hidden = true;
|
|
document.getElementById("zotero-add-citation-dialog").width = "600";
|
|
document.documentElement.getButton("extra1").label = Zotero.getString("citation.multipleSources");
|
|
|
|
// enable all fields
|
|
for(var i in _preserveData) {
|
|
document.getElementById(i).disabled = false;
|
|
}
|
|
|
|
// delete item list
|
|
_itemData = new Object();
|
|
|
|
// delete all items
|
|
_clearCitationList();
|
|
_updateAccept();
|
|
_updatePreview();
|
|
}
|
|
}
|
|
|
|
/*
|
|
* called when an item in the item selection tree is clicked
|
|
*/
|
|
function treeItemSelected() {
|
|
if(_suppressNextTreeSelect) {
|
|
_suppressNextTreeSelect = false;
|
|
_updateAccept();
|
|
return;
|
|
}
|
|
var items = itemsView.getSelectedItems(true); // treeview from selectItemsDialog.js
|
|
var itemID = (items.length ? items[0] : false);
|
|
|
|
if(_multipleSourcesOn) {
|
|
// if item is also on right side, show info
|
|
var hasBeenAdded = itemID && _itemData[itemID] !== undefined;
|
|
// disable boxes if item not added; otherwise, enable
|
|
_itemSelected(hasBeenAdded ? itemID : false);
|
|
// disable adding nothing, or things already added
|
|
document.getElementById("add").disabled = !itemID || hasBeenAdded;
|
|
} else {
|
|
_updateAccept();
|
|
_updatePreview();
|
|
}
|
|
_configListPosition(true);
|
|
}
|
|
|
|
/*
|
|
* called when an item in the selected items list is clicked
|
|
*/
|
|
function listItemSelected() {
|
|
var selectedListItem = _citationList.getSelectedItem(0);
|
|
var itemID = (selectedListItem ? selectedListItem.value : false);
|
|
_itemSelected(itemID);
|
|
_configListPosition(!itemID);
|
|
|
|
document.getElementById("remove").disabled = !itemID;
|
|
}
|
|
|
|
function _configListPosition(flag) {
|
|
var selectedIndex = _citationList.selectedIndex;
|
|
if (selectedIndex > 0) {
|
|
document.getElementById("up").disabled = flag;
|
|
} else {
|
|
document.getElementById("up").disabled = true;
|
|
}
|
|
if (selectedIndex < (_citationList.getRowCount() - 1)) {
|
|
document.getElementById("down").disabled = flag;
|
|
} else {
|
|
document.getElementById("down").disabled = true;
|
|
}
|
|
}
|
|
|
|
function _move(direction) {
|
|
// automatically uncheck sorted checkbox if user is rearranging citation
|
|
if(_sortCheckbox && _sortCheckbox.checked) {
|
|
_sortCheckbox.checked = false;
|
|
sortCitation();
|
|
}
|
|
|
|
var insertBeforeItem;
|
|
var selectedListItem = _citationList.getSelectedItem(0);
|
|
var itemID = selectedListItem.value;
|
|
var selectedListIndex = _citationList.selectedIndex;
|
|
if (direction === -1) {
|
|
insertBeforeItem = selectedListItem.previousSibling;
|
|
} else {
|
|
insertBeforeItem = selectedListItem.nextSibling.nextSibling;
|
|
}
|
|
var listItem = _citationList.removeChild(selectedListItem);
|
|
_citationList.insertBefore(listItem, insertBeforeItem);
|
|
_citationList.selectedIndex = (selectedListIndex + direction);
|
|
_itemSelected(itemID);
|
|
_updatePreview();
|
|
_configListPosition(false);
|
|
}
|
|
|
|
function up() {
|
|
_move(-1);
|
|
}
|
|
|
|
function down() {
|
|
_move(1);
|
|
}
|
|
|
|
/*
|
|
* Adds a citation to the multipleSources list
|
|
*/
|
|
function add() {
|
|
var item = itemsView.getSelectedItems()[0]; // treeview from selectItemsDialog.js
|
|
_itemSelected(item.getID());
|
|
_addItem(item);
|
|
_citationList.focus();
|
|
_citationList.selectedIndex = _citationList.getRowCount()-1;
|
|
|
|
// don't let someone select it again
|
|
document.getElementById("add").disabled = true;
|
|
|
|
// allow user to press OK
|
|
_updateAccept();
|
|
_updatePreview();
|
|
sortCitation();
|
|
}
|
|
|
|
/*
|
|
* Deletes a citation from the multipleSources list
|
|
*/
|
|
function remove() {
|
|
var selectedListItem = _citationList.getSelectedItem(0);
|
|
var itemID = selectedListItem.value;
|
|
|
|
// remove from _itemData
|
|
delete _itemData[itemID];
|
|
_itemData[itemID] = undefined;
|
|
_lastSelected = null;
|
|
|
|
// re-select currently selected in left pane
|
|
var itemIDs = itemsView.getSelectedItems(true); // treeview from selectItemsDialog.js
|
|
if(itemIDs.length) {
|
|
document.getElementById("zotero-items-tree").focus();
|
|
treeItemSelected();
|
|
}
|
|
|
|
// remove from list
|
|
_citationList.removeChild(selectedListItem);
|
|
|
|
_updateAccept();
|
|
_updatePreview();
|
|
treeItemSelected();
|
|
}
|
|
|
|
/*
|
|
* Sorts the list of citations
|
|
*/
|
|
function sortCitation() {
|
|
if(!_sortCheckbox) return;
|
|
if(!_sortCheckbox.checked) {
|
|
io.citation.properties.unsorted = true;
|
|
return;
|
|
}
|
|
|
|
var selectedItemID = (_citationList.selectedItem ? _citationList.selectedItem.value : null);
|
|
Zotero.debug("item "+selectedItemID+" selected");
|
|
_getCitation();
|
|
|
|
// delete all existing items from list
|
|
_clearCitationList();
|
|
|
|
// run preview function to re-sort, if it hasn't already been
|
|
// run
|
|
io.previewFunction();
|
|
|
|
// add items back to list
|
|
for(var i=0; i<io.citation.sortedItems.length; i++) {
|
|
var itemID = io.citation.sortedItems[i][0].id;
|
|
var item = Zotero.Items.get(itemID);
|
|
_addItem(item);
|
|
if(itemID == selectedItemID) _citationList.selectedIndex = i;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Ask whether to modfiy the preview
|
|
*/
|
|
function confirmRegenerate(focusShifted) {
|
|
if(document.getElementById('editor').value == _originalHTML || _originalHTML === undefined) {
|
|
// no changes; just update without asking
|
|
_updatePreview();
|
|
return;
|
|
}
|
|
|
|
if(_autoRegeneratePref == -1) {
|
|
if(focusShifted) { // only ask after onchange event; oninput is too
|
|
// frequent for this to be worthwhile
|
|
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
|
|
.getService(Components.interfaces.nsIPromptService);
|
|
|
|
var saveBehavior = { value: false };
|
|
var regenerate = promptService.confirmEx(
|
|
this.window,
|
|
Zotero.getString('integration.regenerate.title'),
|
|
Zotero.getString('integration.regenerate.body'),
|
|
promptService.STD_YES_NO_BUTTONS,
|
|
null, null, null,
|
|
Zotero.getString('integration.regenerate.saveBehavior'),
|
|
saveBehavior
|
|
);
|
|
|
|
if(saveBehavior.value) {
|
|
_autoRegeneratePref = (regenerate == 0 ? 1 : 0);
|
|
Zotero.Prefs.set("integration.autoRegenerate", _autoRegeneratePref);
|
|
}
|
|
|
|
if(regenerate == 0) {
|
|
_updatePreview();
|
|
}
|
|
}
|
|
} else if(_autoRegeneratePref == 1) {
|
|
_updatePreview();
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Shows the edit pane
|
|
*/
|
|
function toggleEditor(text) {
|
|
var warning = document.getElementById('zotero-editor-warning');
|
|
var editor = document.getElementById('editor');
|
|
warning.hidden = _previewShown;
|
|
editor.hidden = _previewShown;
|
|
_previewShown = !_previewShown;
|
|
|
|
if(_previewShown) {
|
|
document.documentElement.getButton("extra2").label = Zotero.getString("citation.hideEditor");
|
|
if(text) {
|
|
editor.value = text;
|
|
} else {
|
|
_updatePreview();
|
|
}
|
|
} else {
|
|
document.documentElement.getButton("extra2").label = Zotero.getString("citation.showEditor");
|
|
}
|
|
}
|
|
|
|
/*
|
|
* called when accept button is clicked
|
|
*/
|
|
function accept() {
|
|
Zotero.debug("Trying to accept");
|
|
_getCitation();
|
|
Zotero.debug("got citation");
|
|
var isCustom = _previewShown && io.citation.citationItems.length // if a citation is selected
|
|
&& document.getElementById('editor').value != _originalHTML // and citation has been edited
|
|
|
|
if(isCustom) {
|
|
var citation = document.getElementById('editor').value;
|
|
} else {
|
|
var citation = (io.citation.citationItems.length ? io.previewFunction() : "");
|
|
}
|
|
Zotero.debug("verified not custom");
|
|
|
|
if(Zotero.Utilities.prototype.trim(citation) == "") {
|
|
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
|
|
.getService(Components.interfaces.nsIPromptService);
|
|
var insert = promptService.confirm(window,
|
|
Zotero.getString("integration.emptyCitationWarning.title"),
|
|
Zotero.getString("integration.emptyCitationWarning.body"));
|
|
if(!insert) return false;
|
|
}
|
|
Zotero.debug("verified not empty");
|
|
|
|
if(isCustom) io.citation.properties.custom = citation;
|
|
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
* called when cancel button is clicked
|
|
*/
|
|
function cancel() {
|
|
io.citation.citationItems = new Array();
|
|
}
|
|
|
|
/*
|
|
* Updates the contents of the preview pane
|
|
*/
|
|
function _updatePreview() {
|
|
if(_previewShown) {
|
|
var editor = document.getElementById('editor');
|
|
_getCitation();
|
|
|
|
editor.readonly = !io.citation.citationItems.length;
|
|
editor.value = (io.citation.citationItems.length ? io.previewFunction() : "");
|
|
_originalHTML = editor.value;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Controls whether the accept (OK) button should be enabled
|
|
*/
|
|
function _updateAccept(status) {
|
|
if(_multipleSourcesOn) {
|
|
_acceptButton.disabled = !_citationList.getRowCount();
|
|
} else {
|
|
_acceptButton.disabled = !itemsView.getSelectedItems().length; // treeview from selectItemsDialog.js
|
|
}
|
|
}
|
|
|
|
/*
|
|
* called when an item is selected; if itemID is false, disables fields; if
|
|
* itemID is undefined, only updates _itemData array
|
|
*/
|
|
function _itemSelected(itemID) {
|
|
if(_lastSelected && !_itemData[_lastSelected]) {
|
|
_itemData[_lastSelected] = new Object();
|
|
}
|
|
|
|
for(var box in _preserveData) {
|
|
var domBox = document.getElementById(box);
|
|
var property = _preserveData[box];
|
|
|
|
// save property
|
|
if(_lastSelected) {
|
|
if(property == "label") {
|
|
_itemData[_lastSelected][box] = _locatorNameArray[domBox.selectedIndex];
|
|
} else {
|
|
_itemData[_lastSelected][box] = domBox[property];
|
|
}
|
|
}
|
|
// restore previous property
|
|
if(itemID) {
|
|
domBox.disabled = false;
|
|
if(_itemData[itemID] && _itemData[itemID][box] !== undefined) {
|
|
if(property == "label") {
|
|
domBox[property] = _locatorIndexArray[_itemData[itemID][box]];
|
|
} else {
|
|
domBox[property] = _itemData[itemID][box];
|
|
}
|
|
}
|
|
} else if(itemID !== undefined) {
|
|
domBox.disabled = true;
|
|
domBox[property] = "";
|
|
}
|
|
}
|
|
|
|
if(itemID !== undefined) _lastSelected = itemID;
|
|
}
|
|
|
|
/*
|
|
* updates io.citation to reflect selected items
|
|
*/
|
|
function _getCitation() {
|
|
io.citation.citationItems = new Array();
|
|
|
|
// use to map selectedIndexes back to page/paragraph/line
|
|
var locatorTypeElements = document.getElementById("label").getElementsByTagName("menuitem");
|
|
if(_multipleSourcesOn) {
|
|
_itemSelected(); // store locator info
|
|
var listLength = _citationList.childNodes.length;
|
|
var citationItems = new Array();
|
|
if(listLength) {
|
|
// generate citationItems
|
|
for(var i=0; i<listLength; i++) {
|
|
var itemID = _citationList.childNodes[i].value;
|
|
|
|
var citationItem = _itemData[itemID];
|
|
citationItem.id = itemID;
|
|
io.citation.citationItems.push(citationItem);
|
|
}
|
|
}
|
|
} else {
|
|
var items = itemsView.getSelectedItems(true); // treeview from selectItemsDialog.js
|
|
|
|
var citationItem = {};
|
|
citationItem.id = items[0];
|
|
for(var property in _preserveData) {
|
|
if(property == "label") {
|
|
citationItem[property] = _locatorNameArray[document.getElementById(property).selectedIndex];
|
|
} else {
|
|
citationItem[property] = document.getElementById(property)[_preserveData[property]];
|
|
}
|
|
}
|
|
|
|
if(citationItem["locator"] == "") {
|
|
citationItem["locator"] = citationItem["label"] = undefined;
|
|
}
|
|
|
|
io.citation.citationItems = [citationItem];
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Add an item to the item list (multiple sources only)
|
|
*/
|
|
function _addItem(item) {
|
|
var itemNode = document.createElement("listitem");
|
|
itemNode.setAttribute("value", item.getID());
|
|
itemNode.setAttribute("label", item.getField("title"));
|
|
itemNode.setAttribute("class", "listitem-iconic");
|
|
itemNode.setAttribute("image", item.getImageSrc());
|
|
_citationList.appendChild(itemNode);
|
|
_configListPosition(false);
|
|
}
|
|
|
|
/*
|
|
* Removes all items from the multiple sources list
|
|
*/
|
|
function _clearCitationList() {
|
|
while(_citationList.firstChild) _citationList.removeChild(_citationList.firstChild);
|
|
}
|
|
} |