Merge branch '4.0'
Conflicts: chrome/content/zotero/xpcom/zotero.js install.rdf update.rdf
This commit is contained in:
commit
db313abc73
41 changed files with 1431 additions and 925 deletions
|
@ -47,7 +47,6 @@ locale zotero zh-TW chrome/locale/zh-TW/zotero/
|
|||
|
||||
skin zotero default chrome/skin/default/zotero/
|
||||
|
||||
overlay chrome://browser/content/browser.xul chrome://zotero/content/statusBarOverlay.xul appversion<4.0
|
||||
overlay chrome://browser/content/browser.xul chrome://zotero/content/overlay.xul
|
||||
|
||||
overlay chrome://zotero/content/preferences/preferences.xul chrome://zotero/content/preferences/preferences_firefox.xul application={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
|
||||
|
@ -55,6 +54,7 @@ overlay chrome://zotero/content/preferences/preferences.xul#cite chrome://zotero
|
|||
overlay chrome://zotero/content/preferences/preferences_general.xul chrome://zotero/content/preferences/preferences_general_firefox.xul application={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
|
||||
overlay chrome://zotero/content/preferences/preferences_export.xul chrome://zotero/content/preferences/preferences_export_firefox.xul application={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
|
||||
overlay chrome://zotero/content/preferences/preferences_advanced.xul chrome://zotero/content/preferences/preferences_advanced_firefox.xul application={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
|
||||
overlay chrome://zotero/content/preferences/preferences_advanced.xul chrome://zotero/content/preferences/preferences_advanced_standalone.xul application=zotero@chnm.gmu.edu
|
||||
|
||||
overlay chrome://mozapps/content/downloads/unknownContentType.xul chrome://zotero/content/downloadOverlay.xul
|
||||
|
||||
|
|
|
@ -88,10 +88,10 @@ var Zotero_File_Interface_Bibliography = new function() {
|
|||
}
|
||||
|
||||
// Has to be async to work properly
|
||||
setTimeout(function () {
|
||||
window.setTimeout(function () {
|
||||
listbox.ensureIndexIsVisible(selectIndex);
|
||||
listbox.selectedIndex = selectIndex;
|
||||
});
|
||||
}, 0);
|
||||
|
||||
// ONLY FOR bibliography.xul: export options
|
||||
if(document.getElementById("save-as-rtf")) {
|
||||
|
@ -119,8 +119,7 @@ var Zotero_File_Interface_Bibliography = new function() {
|
|||
// bookmarks text
|
||||
if(document.getElementById("displayAs")) {
|
||||
if(_io.useEndnotes && _io.useEndnotes == 1) document.getElementById("displayAs").selectedIndex = 1;
|
||||
styleChanged(selectIndex);
|
||||
}
|
||||
}
|
||||
if(document.getElementById("formatUsing")) {
|
||||
if(_io.fieldType == "Bookmark") document.getElementById("formatUsing").selectedIndex = 1;
|
||||
var formatOption = (_io.primaryFieldType == "ReferenceMark" ? "referenceMarks" : "fields");
|
||||
|
|
|
@ -552,7 +552,7 @@
|
|||
this._displayAllCreators = true;
|
||||
|
||||
if (this._addCreatorRow) {
|
||||
this.addCreatorRow(false, false, true);
|
||||
this.addCreatorRow(false, this.item.getCreator(max-1).creatorTypeID, true);
|
||||
this._addCreatorRow = false;
|
||||
this.disableCreatorAddButtons();
|
||||
}
|
||||
|
@ -1416,11 +1416,17 @@
|
|||
|| fieldName == 'creator') {
|
||||
t.setAttribute('type', 'autocomplete');
|
||||
t.setAttribute('autocompletesearch', 'zotero');
|
||||
var suffix = itemID ? itemID : '';
|
||||
if (field=='creator') {
|
||||
suffix = elem.getAttribute('fieldMode') + '-' + suffix;
|
||||
}
|
||||
t.setAttribute('autocompletesearchparam', fieldName + '/' + suffix);
|
||||
let params = {
|
||||
fieldName: fieldName,
|
||||
libraryID: this.item.libraryID
|
||||
};
|
||||
if (field == 'creator') {
|
||||
params.fieldMode = parseInt(elem.getAttribute('fieldMode'));
|
||||
params.itemID = itemID ? itemID : '';
|
||||
};
|
||||
t.setAttribute(
|
||||
'autocompletesearchparam', JSON.stringify(params)
|
||||
);
|
||||
t.setAttribute('ontextentered',
|
||||
'document.getBindingParent(this).handleCreatorAutoCompleteSelect(this)');
|
||||
}
|
||||
|
@ -1555,8 +1561,8 @@
|
|||
this._focusNextField(this._dynamicFields, this._lastTabIndex, false);
|
||||
}
|
||||
else {
|
||||
// TODO: should use current creator type
|
||||
this.addCreatorRow(false, false, true);
|
||||
var creatorFields = this.getCreatorFields(Zotero.getAncestorByTagName(target, 'row'));
|
||||
this.addCreatorRow(false, creatorFields.creatorTypeID, true);
|
||||
}
|
||||
}
|
||||
// Value has changed
|
||||
|
|
|
@ -437,8 +437,14 @@
|
|||
else {
|
||||
t.setAttribute('type', 'autocomplete');
|
||||
t.setAttribute('autocompletesearch', 'zotero');
|
||||
var suffix = itemID ? itemID : '';
|
||||
t.setAttribute('autocompletesearchparam', fieldName + '/' + suffix);
|
||||
let params = {
|
||||
fieldName: fieldName,
|
||||
libraryID: this.item.libraryID
|
||||
};
|
||||
params.itemID = itemID ? itemID : '';
|
||||
t.setAttribute(
|
||||
'autocompletesearchparam', JSON.stringify(params)
|
||||
);
|
||||
}
|
||||
|
||||
var box = elem.parentNode;
|
||||
|
|
|
@ -813,22 +813,20 @@
|
|||
textbox.setAttribute('autocompletesearch', 'zotero');
|
||||
textbox.setAttribute('timeout', '250');
|
||||
|
||||
if (condition=='creator')
|
||||
{
|
||||
// 2 searches both single- and double-field creators
|
||||
var autocompleteCondition = condition + '/2'
|
||||
var autocompleteParams = {
|
||||
fieldName: condition
|
||||
};
|
||||
if (condition == 'creator') {
|
||||
autocompleteParams.fieldMode = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
var autocompleteCondition = condition;
|
||||
}
|
||||
|
||||
textbox.setAttribute('autocompletesearchparam', autocompleteCondition);
|
||||
textbox.setAttribute(
|
||||
'autocompletesearchparam',
|
||||
JSON.stringify(autocompleteParams)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!autocompleteCondition)
|
||||
{
|
||||
if (!autocompleteParams) {
|
||||
var textbox = document.getAnonymousNodes(this)[0];
|
||||
textbox.removeAttribute('type');
|
||||
}
|
||||
|
|
|
@ -804,16 +804,23 @@ Zotero_Browser.Tab.prototype._selectItems = function(obj, itemList, callback) {
|
|||
*/
|
||||
Zotero_Browser.Tab.prototype._translatorsAvailable = function(translate, translators) {
|
||||
if(translators && translators.length) {
|
||||
// if there's already a scrapable page in the browser window, and it's
|
||||
// still there, ensure it is actually part of the page, then return
|
||||
if(this.page.translators && this.page.translators.length && this.page.document.location) {
|
||||
if(this.page.document.defaultView && !this.page.document.defaultView.closed
|
||||
&& this.page.document.location.href != translate.document.location.href) {
|
||||
// if it is still there, switch translation to take place on
|
||||
if(!translators.length || this.page.translators[0].priority <= translators[0].priority) return;
|
||||
} else {
|
||||
this.clear();
|
||||
}
|
||||
//see if we should keep the previous set of translators
|
||||
if(//we already have a translator for part of this page
|
||||
this.page.translators && this.page.translators.length && this.page.document.location
|
||||
//and the page is still there
|
||||
&& this.page.document.defaultView && !this.page.document.defaultView.closed
|
||||
//this set of translators is not targeting the same URL as a previous set of translators,
|
||||
// because otherwise we want to use the newer set
|
||||
&& this.page.document.location.href != translate.document.location.href
|
||||
//the previous set of translators targets the top frame or the current one does not either
|
||||
&& (this.page.document.defaultView == this.page.document.defaultView.top
|
||||
|| translate.document.defaultView !== this.page.document.defaultView.top)
|
||||
//the best translator we had was of higher priority than the new set
|
||||
&& this.page.translators[0].priority <= translators[0].priority
|
||||
) {
|
||||
return; //keep what we had
|
||||
} else {
|
||||
this.clear(); //clear URL bar icon
|
||||
}
|
||||
|
||||
this.page.translate = translate;
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 5b7a687df6464af87eaacc4088bd136ec1039d1b
|
||||
Subproject commit 007de1a82c0359e897610d67edd11e0086f48689
|
|
@ -364,22 +364,30 @@ Zotero_Preferences.Attachment_Base_Directory = {
|
|||
.createInstance(Components.interfaces.nsILocalFile);
|
||||
for (let i=0; i<allAttachments.length; i++) {
|
||||
let attachmentID = allAttachments[i];
|
||||
let relPath = false
|
||||
|
||||
try {
|
||||
let attachment = Zotero.Items.get(attachmentID);
|
||||
attachmentFile.persistentDescriptor = attachment.attachmentPath;
|
||||
// This will return FALSE for relative paths if base directory
|
||||
// isn't currently set
|
||||
attachmentFile = attachment.getFile(false, true);
|
||||
// Get existing relative path
|
||||
let path = attachment.attachmentPath;
|
||||
if (path.indexOf(Zotero.Attachments.BASE_PATH_PLACEHOLDER) == 0) {
|
||||
relPath = path.substr(Zotero.Attachments.BASE_PATH_PLACEHOLDER.length);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
// Don't deal with bad attachment paths. Just skip them.
|
||||
Zotero.debug(e, 2);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If a file with the same relative path exists within the new base directory,
|
||||
// don't touch the attachment, since it will continue to work
|
||||
let isExistingRelativeAttachment = oldRelativeAttachmentIDs.indexOf(attachmentID) != -1;
|
||||
if (isExistingRelativeAttachment && oldBasePathFile) {
|
||||
let relFile = attachmentFile.clone();
|
||||
let relPath = attachmentFile.getRelativeDescriptor(oldBasePathFile);
|
||||
if (relPath) {
|
||||
let relFile = Components.classes["@mozilla.org/file/local;1"]
|
||||
.createInstance(Components.interfaces.nsILocalFile);
|
||||
relFile.setRelativeDescriptor(newBasePathFile, relPath);
|
||||
if (relFile.exists()) {
|
||||
numNewAttachments++;
|
||||
|
@ -390,14 +398,14 @@ Zotero_Preferences.Attachment_Base_Directory = {
|
|||
// Files within the new base directory need to be updated to use
|
||||
// relative paths (or, if the new base directory is an ancestor or
|
||||
// descendant of the old one, new relative paths)
|
||||
if (Zotero.File.directoryContains(newBasePathFile, attachmentFile)) {
|
||||
newAttachmentPaths[attachmentID] = isExistingRelativeAttachment
|
||||
if (attachmentFile && Zotero.File.directoryContains(newBasePathFile, attachmentFile)) {
|
||||
newAttachmentPaths[attachmentID] = relPath
|
||||
? attachmentFile.persistentDescriptor : null;
|
||||
numNewAttachments++;
|
||||
}
|
||||
// Existing relative attachments not within the new base directory
|
||||
// will be converted to absolute paths
|
||||
else if (isExistingRelativeAttachment && oldBasePathFile) {
|
||||
else if (relPath && oldBasePathFile) {
|
||||
newAttachmentPaths[attachmentID] = attachmentFile.persistentDescriptor;
|
||||
numOldAttachments++;
|
||||
}
|
||||
|
@ -464,7 +472,9 @@ Zotero_Preferences.Attachment_Base_Directory = {
|
|||
let attachment = Zotero.Items.get(id);
|
||||
if (newAttachmentPaths[id]) {
|
||||
attachment.attachmentPath = newAttachmentPaths[id];
|
||||
attachment.save();
|
||||
attachment.save({
|
||||
skipDateModifiedUpdate: true
|
||||
});
|
||||
}
|
||||
else {
|
||||
attachment.updateAttachmentPath();
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
|
||||
Copyright © 2013 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 Affero 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 Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with Zotero. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***** END LICENSE BLOCK *****
|
||||
-->
|
||||
<!DOCTYPE prefwindow SYSTEM "chrome://zotero/locale/preferences.dtd">
|
||||
|
||||
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<groupbox id="zotero-prefpane-advanced-miscellaneous">
|
||||
<hbox id="zotero-standalone-buttons">
|
||||
<button id="openAboutMemory"
|
||||
label="&zotero.preferences.openAboutMemory;"
|
||||
oncommand="Zotero_Preferences.openInViewer('about:memory')"/>
|
||||
</hbox>
|
||||
</groupbox>
|
||||
</overlay>
|
|
@ -72,7 +72,7 @@ Zotero_Preferences.Sync = {
|
|||
}
|
||||
|
||||
if (oldProtocol == 'zotero' && protocol == 'webdav') {
|
||||
var sql = "SELECT COUNT(*) FROM version WHERE schema='storage_zfs'";
|
||||
var sql = "SELECT COUNT(*) FROM version WHERE schema LIKE 'storage_zfs%'";
|
||||
if (Zotero.DB.valueQuery(sql)) {
|
||||
var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
|
||||
.getService(Components.interfaces.nsIPromptService);
|
||||
|
|
|
@ -529,13 +529,15 @@ var Zotero_RTFScan = new function() {
|
|||
|
||||
itemIDs = [itemID for(itemID in itemIDs)];
|
||||
Zotero.debug(itemIDs);
|
||||
style.updateItems(itemIDs);
|
||||
|
||||
// prepare the list of rendered citations
|
||||
var citationResults = style.rebuildProcessorState(cslCitations, "rtf");
|
||||
|
||||
// format citations
|
||||
var contentArray = [];
|
||||
var lastEnd = 0;
|
||||
for(var i=0; i<citations.length; i++) {
|
||||
var citation = style.appendCitationCluster(cslCitations[i], true)[0][1];
|
||||
var citation = citationResults[i][2];
|
||||
Zotero.debug("Formatted "+citation);
|
||||
|
||||
// if using notes, we might have to move the note after the punctuation
|
||||
|
|
|
@ -334,7 +334,9 @@ Zotero_TranslatorTester.prototype._runTestsRecursively = function(testDoneCallba
|
|||
if(this.type === "web") {
|
||||
this.fetchPageAndRunTest(test, callback);
|
||||
} else {
|
||||
this.runTest(test, null, callback);
|
||||
(Zotero.setTimeout ? Zotero : window).setTimeout(function() {
|
||||
me.runTest(test, null, callback);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
(Zotero.setTimeout ? Zotero : window).setTimeout(function() {
|
||||
|
|
|
@ -50,13 +50,7 @@ Zotero.Attachments = new function(){
|
|||
function importFromFile(file, sourceItemID, libraryID) {
|
||||
Zotero.debug('Importing attachment from file');
|
||||
|
||||
// Try decoding URI entities, since we're going to strip '%'
|
||||
var newName = file.leafName;
|
||||
try {
|
||||
newName = decodeURIComponent(file.leafName);
|
||||
}
|
||||
catch (e) {}
|
||||
newName = Zotero.File.getValidFileName(newName);
|
||||
var newName = Zotero.File.getValidFileName(file.leafName);
|
||||
|
||||
if (!file.isFile()) {
|
||||
throw ("'" + file.leafName + "' must be a file in Zotero.Attachments.importFromFile()");
|
||||
|
@ -82,14 +76,15 @@ Zotero.Attachments = new function(){
|
|||
|
||||
// Create directory for attachment files within storage directory
|
||||
var destDir = this.createDirectoryForItem(itemID);
|
||||
file.copyTo(destDir, newName);
|
||||
|
||||
// Point to copied file
|
||||
var newFile = destDir.clone();
|
||||
newFile.append(newName);
|
||||
|
||||
var mimeType = Zotero.MIME.getMIMETypeFromFile(newFile);
|
||||
// Copy file to unique filename, which automatically shortens long filenames
|
||||
newFile = Zotero.File.copyToUnique(file, newFile);
|
||||
|
||||
var mimeType = Zotero.MIME.getMIMETypeFromFile(newFile);
|
||||
|
||||
attachmentItem.attachmentMIMEType = mimeType;
|
||||
attachmentItem.attachmentPath = this.getPath(newFile, this.LINK_MODE_IMPORTED_FILE);
|
||||
|
@ -1018,6 +1013,104 @@ Zotero.Attachments = new function(){
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* If file is within the attachment base directory, return a relative
|
||||
* path prefixed by BASE_PATH_PLACEHOLDER. Otherwise, return unchanged.
|
||||
*/
|
||||
this.getBaseDirectoryRelativePath = function (path) {
|
||||
if (!path || path.indexOf(this.BASE_PATH_PLACEHOLDER) == 0) {
|
||||
return path;
|
||||
}
|
||||
|
||||
var basePath = Zotero.Prefs.get('baseAttachmentPath');
|
||||
if (!basePath) {
|
||||
return path;
|
||||
}
|
||||
|
||||
// Get nsIFile for base directory
|
||||
var baseDir = Components.classes["@mozilla.org/file/local;1"]
|
||||
.createInstance(Components.interfaces.nsILocalFile);
|
||||
try {
|
||||
baseDir.persistentDescriptor = basePath;
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.debug(e, 1);
|
||||
Components.utils.reportError(e);
|
||||
return path;
|
||||
}
|
||||
|
||||
// Get nsIFile for file
|
||||
var attachmentFile = Components.classes["@mozilla.org/file/local;1"]
|
||||
.createInstance(Components.interfaces.nsILocalFile);
|
||||
try {
|
||||
attachmentFile.persistentDescriptor = path;
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.debug(e, 1);
|
||||
Components.utils.reportError(e);
|
||||
return path;
|
||||
}
|
||||
|
||||
if (Zotero.File.directoryContains(baseDir, attachmentFile)) {
|
||||
path = this.BASE_PATH_PLACEHOLDER
|
||||
+ attachmentFile.getRelativeDescriptor(baseDir);
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a file from this path, if we can
|
||||
*
|
||||
* @param {String} path Absolute path or relative path prefixed
|
||||
* by BASE_PATH_PLACEHOLDER
|
||||
* @param {Boolean} asFile Return nsIFile instead of path
|
||||
* @return {String|nsIFile|FALSE} Persistent descriptor string, file,
|
||||
* of FALSE if no path
|
||||
*/
|
||||
this.resolveRelativePath = function (path) {
|
||||
if (path.indexOf(Zotero.Attachments.BASE_PATH_PLACEHOLDER) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var basePath = Zotero.Prefs.get('baseAttachmentPath');
|
||||
if (!basePath) {
|
||||
Zotero.debug("No base attachment path set -- can't resolve '" + path + "'", 2);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get file from base directory
|
||||
var baseDir = Components.classes["@mozilla.org/file/local;1"]
|
||||
.createInstance(Components.interfaces.nsILocalFile);
|
||||
try {
|
||||
baseDir.persistentDescriptor = basePath;
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.debug(e, 1);
|
||||
Components.utils.reportError(e);
|
||||
Zotero.debug("Invalid base attachment path -- can't resolve'" + row.path + "'", 2);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get file from relative path
|
||||
var relativePath = path.substr(
|
||||
Zotero.Attachments.BASE_PATH_PLACEHOLDER.length
|
||||
);
|
||||
var file = Components.classes["@mozilla.org/file/local;1"]
|
||||
.createInstance(Components.interfaces.nsILocalFile);
|
||||
try {
|
||||
file.setRelativeDescriptor(baseDir, relativePath);
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.debug("Invalid relative descriptor '" + relativePath + "'", 2);
|
||||
return false;
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the number of files in the attachment directory
|
||||
*
|
||||
|
@ -1394,6 +1487,7 @@ Zotero.Attachments = new function(){
|
|||
*/
|
||||
this.isPDFJS = function(doc) {
|
||||
// pdf.js HACK
|
||||
// This may no longer be necessary (as of Fx 23)
|
||||
if(doc.contentType === "text/html") {
|
||||
var win = doc.defaultView;
|
||||
if(win) {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -59,7 +59,14 @@ Zotero.Connector = new function() {
|
|||
var xdr = new XDomainRequest();
|
||||
xdr.timeout = 700;
|
||||
xdr.open("POST", "http://127.0.0.1:23119/connector/ping", true);
|
||||
xdr.onerror = xdr.ontimeout = fail
|
||||
xdr.onerror = function() {
|
||||
Zotero.debug("Connector: XDomainRequest to Zotero Standalone experienced an error");
|
||||
fail();
|
||||
};
|
||||
xdr.ontimeout = function() {
|
||||
Zotero.debug("Connector: XDomainRequest to Zotero Standalone timed out");
|
||||
fail();
|
||||
};
|
||||
xdr.onload = function() {
|
||||
if(me.isOnline !== null) return;
|
||||
me.isOnline = true;
|
||||
|
@ -67,7 +74,8 @@ Zotero.Connector = new function() {
|
|||
|
||||
_ieConnectorCallbacks = [];
|
||||
var listener = function(event) {
|
||||
if(event.origin !== "http://127.0.0.1:23119") return;
|
||||
if(event.origin !== "http://127.0.0.1:23119"
|
||||
|| event.source !== iframe.contentWindow) return;
|
||||
if(event.stopPropagation) {
|
||||
event.stopPropagation();
|
||||
} else {
|
||||
|
|
|
@ -76,7 +76,6 @@ Zotero.Item.prototype._init = function () {
|
|||
this._changedSource = false;
|
||||
this._changedAttachmentData = false;
|
||||
|
||||
this._skipModTimeUpdate = false;
|
||||
this._previousData = {};
|
||||
|
||||
this._bestAttachmentState = null;
|
||||
|
@ -1251,7 +1250,11 @@ Zotero.Item.prototype.removeRelatedItem = function (itemID) {
|
|||
*
|
||||
* Returns true on item update or itemID of new item
|
||||
*/
|
||||
Zotero.Item.prototype.save = function() {
|
||||
Zotero.Item.prototype.save = function(options) {
|
||||
if (!options) {
|
||||
options = {};
|
||||
}
|
||||
|
||||
Zotero.Items.editCheck(this);
|
||||
|
||||
if (!this.hasChanged()) {
|
||||
|
@ -1527,37 +1530,16 @@ Zotero.Item.prototype.save = function() {
|
|||
var path = this.attachmentPath;
|
||||
var syncState = this.attachmentSyncState;
|
||||
|
||||
// Save attachment within attachment base directory as relative path
|
||||
if (this.attachmentLinkMode == Zotero.Attachments.LINK_MODE_LINKED_FILE && path) {
|
||||
let basePath = Zotero.Prefs.get('baseAttachmentPath');
|
||||
if (basePath != '' && Zotero.Prefs.get('saveRelativeAttachmentPath')) {
|
||||
let baseDir = Components.classes["@mozilla.org/file/local;1"]
|
||||
.createInstance(Components.interfaces.nsILocalFile);
|
||||
try {
|
||||
baseDir.persistentDescriptor = basePath;
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.debug(e, 1);
|
||||
Components.utils.reportError(e);
|
||||
baseDir = null;
|
||||
}
|
||||
|
||||
if (baseDir) {
|
||||
let attachmentFile = Components.classes["@mozilla.org/file/local;1"]
|
||||
.createInstance(Components.interfaces.nsILocalFile);
|
||||
try {
|
||||
attachmentFile.persistentDescriptor = path;
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.debug(e, 1);
|
||||
Components.utils.reportError(e);
|
||||
attachmentFile = null;
|
||||
}
|
||||
|
||||
if (attachmentFile && Zotero.File.directoryContains(baseDir, attachmentFile)) {
|
||||
path = Zotero.Attachments.BASE_PATH_PLACEHOLDER
|
||||
+ attachmentFile.getRelativeDescriptor(baseDir);
|
||||
}
|
||||
if (this.attachmentLinkMode == Zotero.Attachments.LINK_MODE_LINKED_FILE) {
|
||||
// Save attachment within attachment base directory as relative path
|
||||
if (Zotero.Prefs.get('saveRelativeAttachmentPath')) {
|
||||
path = Zotero.Attachments.getBaseDirectoryRelativePath(path);
|
||||
}
|
||||
// If possible, convert relative path to absolute
|
||||
else {
|
||||
let file = Zotero.Attachments.resolveRelativePath(path);
|
||||
if (file) {
|
||||
path = file.persistentDescriptor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1669,8 +1651,11 @@ Zotero.Item.prototype.save = function() {
|
|||
sql += field + '=?, ';
|
||||
sqlValues.push(this.getField(field));
|
||||
}
|
||||
else if ((field == 'dateModified' || field == 'clientDateModified')
|
||||
&& !this._skipModTimeUpdate) {
|
||||
else if (field == 'dateModified' && !options.skipDateModifiedUpdate) {
|
||||
sql += field + '=?, ';
|
||||
sqlValues.push(Zotero.DB.transactionDateTime);
|
||||
}
|
||||
else if (field == 'clientDateModified' && !options.skipClientDateModifiedUpdate) {
|
||||
sql += field + '=?, ';
|
||||
sqlValues.push(Zotero.DB.transactionDateTime);
|
||||
}
|
||||
|
@ -1962,37 +1947,16 @@ Zotero.Item.prototype.save = function() {
|
|||
var path = this.attachmentPath;
|
||||
var syncState = this.attachmentSyncState;
|
||||
|
||||
// Save attachment within attachment base directory as relative path
|
||||
if (this.attachmentLinkMode == Zotero.Attachments.LINK_MODE_LINKED_FILE && path) {
|
||||
let basePath = Zotero.Prefs.get('baseAttachmentPath');
|
||||
if (basePath != '' && Zotero.Prefs.get('saveRelativeAttachmentPath')) {
|
||||
let baseDir = Components.classes["@mozilla.org/file/local;1"]
|
||||
.createInstance(Components.interfaces.nsILocalFile);
|
||||
try {
|
||||
baseDir.persistentDescriptor = basePath;
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.debug(e, 1);
|
||||
Components.utils.reportError(e);
|
||||
baseDir = null;
|
||||
}
|
||||
|
||||
if (baseDir) {
|
||||
let attachmentFile = Components.classes["@mozilla.org/file/local;1"]
|
||||
.createInstance(Components.interfaces.nsILocalFile);
|
||||
try {
|
||||
attachmentFile.persistentDescriptor = path;
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.debug(e, 1);
|
||||
Components.utils.reportError(e);
|
||||
attachmentFile = null;
|
||||
}
|
||||
|
||||
if (attachmentFile && Zotero.File.directoryContains(baseDir, attachmentFile)) {
|
||||
path = Zotero.Attachments.BASE_PATH_PLACEHOLDER
|
||||
+ attachmentFile.getRelativeDescriptor(baseDir);
|
||||
}
|
||||
if (this.attachmentLinkMode == Zotero.Attachments.LINK_MODE_LINKED_FILE) {
|
||||
// Save attachment within attachment base directory as relative path
|
||||
if (Zotero.Prefs.get('saveRelativeAttachmentPath')) {
|
||||
path = Zotero.Attachments.getBaseDirectoryRelativePath(path);
|
||||
}
|
||||
// If possible, convert relative path to absolute
|
||||
else {
|
||||
let file = Zotero.Attachments.resolveRelativePath(path);
|
||||
if (file) {
|
||||
path = file.persistentDescriptor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2864,6 +2828,7 @@ Zotero.Item.prototype.getFile = function(row, skipExistsCheck) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Imported file with relative path
|
||||
if (row.linkMode == Zotero.Attachments.LINK_MODE_IMPORTED_URL ||
|
||||
row.linkMode == Zotero.Attachments.LINK_MODE_IMPORTED_FILE) {
|
||||
try {
|
||||
|
@ -2913,6 +2878,15 @@ Zotero.Item.prototype.getFile = function(row, skipExistsCheck) {
|
|||
}
|
||||
}
|
||||
}
|
||||
// Linked file with relative path
|
||||
else if (row.linkMode == Zotero.Attachments.LINK_MODE_LINKED_FILE &&
|
||||
row.path.indexOf(Zotero.Attachments.BASE_PATH_PLACEHOLDER) == 0) {
|
||||
var file = Zotero.Attachments.resolveRelativePath(row.path);
|
||||
if (!file) {
|
||||
updateAttachmentStates(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
var file = Components.classes["@mozilla.org/file/local;1"].
|
||||
createInstance(Components.interfaces.nsILocalFile);
|
||||
|
@ -3073,11 +3047,10 @@ Zotero.Item.prototype.relinkAttachmentFile = function(file, skipItemUpdate) {
|
|||
var path = Zotero.Attachments.getPath(file, linkMode);
|
||||
this.attachmentPath = path;
|
||||
|
||||
if (skipItemUpdate) {
|
||||
this._skipModTimeUpdate = true;
|
||||
}
|
||||
this.save();
|
||||
this._skipModTimeUpdate = false;
|
||||
this.save({
|
||||
skipDateModifiedUpdate: true,
|
||||
skipClientDateModifiedUpdate: skipItemUpdate
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -3274,58 +3247,20 @@ Zotero.Item.prototype.__defineGetter__('attachmentPath', function () {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
var pathIsRelative = false;
|
||||
|
||||
if (this._attachmentPath !== null) {
|
||||
pathIsRelative = this._attachmentPath.indexOf(Zotero.Attachments.BASE_PATH_PLACEHOLDER) == 0
|
||||
&& this.attachmentLinkMode == Zotero.Attachments.LINK_MODE_LINKED_FILE;
|
||||
if (!pathIsRelative) {
|
||||
return this._attachmentPath;
|
||||
}
|
||||
}
|
||||
else if (!this.id) {
|
||||
return this._attachmentPath;
|
||||
}
|
||||
|
||||
if (!this.id) {
|
||||
return '';
|
||||
}
|
||||
else {
|
||||
var sql = "SELECT path FROM itemAttachments WHERE itemID=?";
|
||||
var path = Zotero.DB.valueQuery(sql, this.id);
|
||||
if (!path) {
|
||||
this._attachmentPath = '';
|
||||
return this._attachmentPath;
|
||||
}
|
||||
|
||||
this._attachmentPath = path;
|
||||
|
||||
pathIsRelative = path.indexOf(Zotero.Attachments.BASE_PATH_PLACEHOLDER) == 0
|
||||
&& this.attachmentLinkMode == Zotero.Attachments.LINK_MODE_LINKED_FILE;
|
||||
}
|
||||
|
||||
if (pathIsRelative) {
|
||||
var basePath = Zotero.Prefs.get('baseAttachmentPath');
|
||||
// If the base path has been cleared, don't try to recreate the full attachment path
|
||||
if (basePath == '') {
|
||||
return '';
|
||||
}
|
||||
var baseDir = Components.classes["@mozilla.org/file/local;1"]
|
||||
.createInstance(Components.interfaces.nsILocalFile);
|
||||
try {
|
||||
baseDir.persistentDescriptor = basePath;
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.debug(e, 1);
|
||||
Components.utils.reportError(e);
|
||||
return '';
|
||||
}
|
||||
|
||||
var relativePath = this._attachmentPath.substr(
|
||||
Zotero.Attachments.BASE_PATH_PLACEHOLDER.length
|
||||
);
|
||||
var attachmentFile = Components.classes["@mozilla.org/file/local;1"]
|
||||
.createInstance(Components.interfaces.nsILocalFile);
|
||||
attachmentFile.setRelativeDescriptor(baseDir,relativePath);
|
||||
return attachmentFile.persistentDescriptor;
|
||||
var sql = "SELECT path FROM itemAttachments WHERE itemID=?";
|
||||
var path = Zotero.DB.valueQuery(sql, this.id);
|
||||
if (!path) {
|
||||
path = '';
|
||||
}
|
||||
|
||||
this._attachmentPath = path;
|
||||
return path;
|
||||
});
|
||||
|
||||
|
@ -3366,7 +3301,9 @@ Zotero.Item.prototype.updateAttachmentPath = function () {
|
|||
this._changedAttachmentData = {};
|
||||
}
|
||||
this._changedAttachmentData.path = true;
|
||||
this.save();
|
||||
this.save({
|
||||
skipDateModifiedUpdate: true
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
Zotero.Notes = new function() {
|
||||
this.noteToTitle = noteToTitle;
|
||||
|
||||
this.__defineGetter__("MAX_TITLE_LENGTH", function() { return 80; });
|
||||
this.__defineGetter__("MAX_TITLE_LENGTH", function() { return 120; });
|
||||
this.__defineGetter__("defaultNote", function () '<div class="zotero-note znv1"></div>');
|
||||
this.__defineGetter__("notePrefix", function () '<div class="zotero-note znv1">');
|
||||
this.__defineGetter__("noteSuffix", function () '</div>');
|
||||
|
|
|
@ -39,7 +39,6 @@ Zotero.File = new function(){
|
|||
this.putContents = putContents;
|
||||
this.getValidFileName = getValidFileName;
|
||||
this.truncateFileName = truncateFileName;
|
||||
this.copyToUnique = this.copyToUnique;
|
||||
this.getCharsetFromFile = getCharsetFromFile;
|
||||
this.addCharsetListener = addCharsetListener;
|
||||
|
||||
|
@ -287,14 +286,14 @@ Zotero.File = new function(){
|
|||
}
|
||||
|
||||
|
||||
function copyToUnique(file, newFile) {
|
||||
this.copyToUnique = function (file, newFile) {
|
||||
newFile.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0644);
|
||||
var newName = newFile.leafName;
|
||||
newFile.remove(null);
|
||||
|
||||
// Copy file to unique name
|
||||
file.copyTo(newFile.parent, newName);
|
||||
return file;
|
||||
return newFile;
|
||||
}
|
||||
|
||||
|
||||
|
@ -361,7 +360,7 @@ Zotero.File = new function(){
|
|||
function getValidFileName(fileName, skipXML) {
|
||||
// TODO: use space instead, and figure out what's doing extra
|
||||
// URL encode when saving attachments that trigger this
|
||||
fileName = fileName.replace(/[\/\\\?%\*:|"<>]/g, '');
|
||||
fileName = fileName.replace(/[\/\\\?\*:|"<>]/g, '');
|
||||
// Replace newlines and tabs (which shouldn't be in the string in the first place) with spaces
|
||||
fileName = fileName.replace(/[\r\n\t]+/g, ' ');
|
||||
// Replace various thin spaces
|
||||
|
|
|
@ -575,8 +575,14 @@ Zotero.Fulltext = new function(){
|
|||
flags += 'i';
|
||||
}
|
||||
|
||||
var re = new RegExp(searchText, flags);
|
||||
var matches = re(str);
|
||||
try {
|
||||
var re = new RegExp(searchText, flags);
|
||||
var matches = re.exec(str);
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.debug(e, 1);
|
||||
Components.utils.reportError(e);
|
||||
}
|
||||
if (matches){
|
||||
Zotero.debug("Text found");
|
||||
return str.substr(matches.index, 50);
|
||||
|
|
|
@ -57,8 +57,11 @@ Zotero.MIMETypeHandler = new function () {
|
|||
if(Zotero.Prefs.get("parseEndNoteMIMETypes")) {
|
||||
this.addHandler("application/x-endnote-refer", _importHandler, true);
|
||||
this.addHandler("application/x-research-info-systems", _importHandler, true);
|
||||
// Add ISI
|
||||
this.addHandler("application/x-inst-for-scientific-info", _importHandler, true);
|
||||
|
||||
this.addHandler("text/x-bibtex", _importHandler, true);
|
||||
this.addHandler("application/x-bibtex", _importHandler, true);
|
||||
|
||||
//
|
||||
// And some non-standard ones
|
||||
//
|
||||
|
|
|
@ -31,8 +31,8 @@ Zotero.Schema = new function(){
|
|||
var _dbVersions = [];
|
||||
var _schemaVersions = [];
|
||||
var _repositoryTimer;
|
||||
var _remoteUpdateInProgress = false,
|
||||
_localUpdateInProgress = false;
|
||||
var _remoteUpdateInProgress = false, _localUpdateInProgress = false;
|
||||
var _renamedStylesByNew = null;
|
||||
|
||||
var self = this;
|
||||
|
||||
|
@ -597,6 +597,8 @@ Zotero.Schema = new function(){
|
|||
// Delete renamed/obsolete files
|
||||
case 'chicago-note.csl':
|
||||
case 'mhra_note_without_bibliography.csl':
|
||||
case 'mhra.csl':
|
||||
case 'mla.csl':
|
||||
toDelete.push(file);
|
||||
continue;
|
||||
|
||||
|
@ -1714,6 +1716,7 @@ Zotero.Schema = new function(){
|
|||
xmlnode.normalize();
|
||||
|
||||
var uri = xmlnode.getAttribute('id');
|
||||
var shortName = uri.replace("http://www.zotero.org/styles/", "");
|
||||
|
||||
// Delete local style if CSL code is empty
|
||||
if (!xmlnode.firstChild) {
|
||||
|
@ -1724,18 +1727,10 @@ Zotero.Schema = new function(){
|
|||
return;
|
||||
}
|
||||
|
||||
// Remove renamed styles
|
||||
if (uri == 'http://www.zotero.org/styles/american-medical-association') {
|
||||
var oldID = 'http://www.zotero.org/styles/ama';
|
||||
var style = Zotero.Styles.get(oldID);
|
||||
if (style && style.file.exists()) {
|
||||
Zotero.debug("Deleting renamed style '" + oldID + "'");
|
||||
style.file.remove(false);
|
||||
}
|
||||
}
|
||||
else if (uri == 'http://www.zotero.org/styles/national-library-of-medicine') {
|
||||
var oldID = 'http://www.zotero.org/styles/nlm';
|
||||
var style = Zotero.Styles.get(oldID);
|
||||
// Remove renamed styles, as instructed by the server
|
||||
var oldID = xmlnode.getAttribute('oldID');
|
||||
if (oldID) {
|
||||
var style = Zotero.Styles.get(oldID, true);
|
||||
if (style && style.file.exists()) {
|
||||
Zotero.debug("Deleting renamed style '" + oldID + "'");
|
||||
style.file.remove(false);
|
||||
|
|
|
@ -306,7 +306,8 @@ Zotero.Server.DataListener.prototype._generateResponse = function(status, conten
|
|||
if(!Zotero.isServer) {
|
||||
response += "X-Zotero-Version: "+Zotero.version+"\r\n";
|
||||
response += "X-Zotero-Connector-API-Version: "+CONNECTOR_API_VERSION+"\r\n";
|
||||
if(this.origin === "https://www.zotero.org" || this.origin === "http://www.zotero.org") {
|
||||
if(this.origin === ZOTERO_CONFIG.BOOKMARKLET_ORIGIN ||
|
||||
this.origin === ZOTERO_CONFIG.HTTP_BOOKMARKLET_ORIGIN) {
|
||||
response += "Access-Control-Allow-Origin: "+this.origin+"\r\n";
|
||||
response += "Access-Control-Allow-Methods: POST, GET, OPTIONS\r\n";
|
||||
response += "Access-Control-Allow-Headers: Content-Type,X-Zotero-Connector-API-Version,X-Zotero-Version\r\n";
|
||||
|
|
|
@ -55,6 +55,14 @@ Zotero.Server.Connector.AttachmentProgressManager = new function() {
|
|||
this.getProgressForID = function(progressID) {
|
||||
return progressID in attachmentProgress ? attachmentProgress[progressID] : 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if we have received progress for a given attachment
|
||||
*/
|
||||
this.has = function(attachment) {
|
||||
return attachmentsInProgress.has(attachment)
|
||||
&& attachmentsInProgress.get(attachment) in attachmentProgress;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -285,7 +293,6 @@ Zotero.Server.Connector.SavePage.prototype = {
|
|||
Zotero.Server.Connector.AttachmentProgressManager.onProgress(attachment, progress, error);
|
||||
});
|
||||
translate.setHandler("itemsDone", function(obj, item) {
|
||||
Zotero.Server.Connector.AttachmentProgressManager.add(item.attachments);
|
||||
Zotero.Browser.deleteHiddenBrowser(me._browser);
|
||||
if(jsonItems.length || me.selectedItems === false) {
|
||||
me.sendResponse(201, "application/json", JSON.stringify({"items":jsonItems}));
|
||||
|
@ -340,11 +347,21 @@ Zotero.Server.Connector.SaveItem.prototype = {
|
|||
// save items
|
||||
var itemSaver = new Zotero.Translate.ItemSaver(libraryID,
|
||||
Zotero.Translate.ItemSaver.ATTACHMENT_MODE_DOWNLOAD, 1, undefined, cookieSandbox);
|
||||
itemSaver.saveItems(data.items, function(returnValue, newItems) {
|
||||
itemSaver.saveItems(data.items, function(returnValue, items) {
|
||||
if(returnValue) {
|
||||
try {
|
||||
for each(var item in newItems) {
|
||||
if(collection) collection.addItem(item.id);
|
||||
// Remove attachments not being saved from item.attachments
|
||||
for(var i=0; i<data.items.length; i++) {
|
||||
var item = data.items[i];
|
||||
for(var j=0; j<item.attachments.length; j++) {
|
||||
if(!Zotero.Server.Connector.AttachmentProgressManager.has(item.attachments[j])) {
|
||||
item.attachments.splice(j--, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(var i=0; i<items.length; i++) {
|
||||
if(collection) collection.addItem(items[i].id);
|
||||
}
|
||||
|
||||
sendResponseCallback(201, "application/json", JSON.stringify({"items":data.items}));
|
||||
|
|
|
@ -242,7 +242,7 @@ Zotero.Sync.Storage = new function () {
|
|||
);
|
||||
if (version == lastSyncTime) {
|
||||
Zotero.debug("Last " + libraryModes[libraryID].name
|
||||
+ " sync time hasn't changed for library "
|
||||
+ " sync id hasn't changed for library "
|
||||
+ libraryID + " -- skipping file downloads");
|
||||
downloadAll = false;
|
||||
}
|
||||
|
|
|
@ -314,7 +314,7 @@ Zotero.Sync.Storage.Request.prototype.stop = function (force) {
|
|||
this._forceFinish = true;
|
||||
}
|
||||
|
||||
if (this.channel) {
|
||||
if (this.channel && this.channel.isPending()) {
|
||||
this._stopping = true;
|
||||
|
||||
try {
|
||||
|
|
|
@ -33,6 +33,8 @@ Zotero.Sync.Storage.WebDAV = (function () {
|
|||
var _loginManagerHost = 'chrome://zotero';
|
||||
var _loginManagerURL = 'Zotero Storage Server';
|
||||
|
||||
var _lastSyncIDLength = 30;
|
||||
|
||||
//
|
||||
// Private methods
|
||||
//
|
||||
|
@ -983,89 +985,116 @@ Zotero.Sync.Storage.WebDAV = (function () {
|
|||
|
||||
|
||||
obj._getLastSyncTime = function () {
|
||||
var lastSyncURI = this.rootURI;
|
||||
lastSyncURI.spec += "lastsync.txt";
|
||||
|
||||
// Cache the credentials at the root URI
|
||||
var self = this;
|
||||
return Q.fcall(function () {
|
||||
return self._cacheCredentials();
|
||||
})
|
||||
.then(function () {
|
||||
var lastSyncURI = self.rootURI;
|
||||
.then(function () {
|
||||
return Zotero.HTTP.promise("GET", lastSyncURI,
|
||||
{ debug: true, successCodes: [200, 404] });
|
||||
})
|
||||
.then(function (req) {
|
||||
if (req.status == 404) {
|
||||
Zotero.debug("No last WebDAV sync file");
|
||||
|
||||
// If no lastsync.txt, check previously used 'lastsync',
|
||||
// and then delete it
|
||||
let lastSyncURI = self.rootURI;
|
||||
lastSyncURI.spec += "lastsync";
|
||||
return Zotero.HTTP.promise("GET", lastSyncURI,
|
||||
{ debug: true, successCodes: [200, 404] });
|
||||
})
|
||||
.then(function (req) {
|
||||
if (req.status == 404) {
|
||||
Zotero.debug("No last WebDAV sync time");
|
||||
return null;
|
||||
}
|
||||
|
||||
var lastModified = req.getResponseHeader("Last-Modified");
|
||||
var date = new Date(lastModified);
|
||||
Zotero.debug("Last successful WebDAV sync was " + date);
|
||||
return Zotero.Date.toUnixTimestamp(date);
|
||||
})
|
||||
.fail(function (e) {
|
||||
if (e instanceof Zotero.HTTP.UnexpectedStatusException) {
|
||||
if (e.status == 403) {
|
||||
Zotero.debug("Clearing WebDAV authentication credentials", 2);
|
||||
_cachedCredentials = false;
|
||||
}
|
||||
else {
|
||||
throw("HTTP " + e.status + " error from WebDAV server "
|
||||
+ "for GET request");
|
||||
{ debug: true, successCodes: [200, 404] })
|
||||
.then(function (req) {
|
||||
if (req.status == 404) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Q.reject(e);
|
||||
Zotero.HTTP.promise("DELETE", lastSyncURI,
|
||||
{ debug: true, successCodes: [200, 204, 404] })
|
||||
.done();
|
||||
|
||||
var lastModified = req.getResponseHeader("Last-Modified");
|
||||
var date = new Date(lastModified);
|
||||
Zotero.debug("Last successful WebDAV sync was " + date);
|
||||
return Zotero.Date.toUnixTimestamp(date);
|
||||
});
|
||||
}
|
||||
|
||||
var lastModified = req.getResponseHeader("Last-Modified");
|
||||
var date = new Date(lastModified);
|
||||
Zotero.debug("Last successful WebDAV sync was " + date);
|
||||
|
||||
var re = new RegExp("^[a-zA-Z0-9]{" + _lastSyncIDLength + "}$");
|
||||
if (!re.test(req.responseText)) {
|
||||
Zotero.HTTP.promise("DELETE", lastSyncURI,
|
||||
{ debug: true, successCodes: [200, 204, 404] })
|
||||
.done();
|
||||
|
||||
throw new Error("Invalid last sync id '" + req.responseText+ "'")
|
||||
}
|
||||
|
||||
return req.responseText;
|
||||
})
|
||||
.catch(function (e) {
|
||||
if (e instanceof Zotero.HTTP.UnexpectedStatusException) {
|
||||
if (e.status == 403) {
|
||||
Zotero.debug("Clearing WebDAV authentication credentials", 2);
|
||||
_cachedCredentials = false;
|
||||
}
|
||||
// TODO: handle browser offline exception
|
||||
else {
|
||||
throw (e);
|
||||
throw("HTTP " + e.status + " error from WebDAV server "
|
||||
+ "for GET request");
|
||||
}
|
||||
});
|
||||
|
||||
return Q.reject(e);
|
||||
}
|
||||
// TODO: handle browser offline exception
|
||||
else {
|
||||
throw (e);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
obj._setLastSyncTime = function (libraryID, localLastSyncTime) {
|
||||
obj._setLastSyncTime = function (libraryID, localLastSyncID) {
|
||||
if (libraryID) {
|
||||
throw new Error("libraryID must be 0");
|
||||
}
|
||||
|
||||
// DEBUG: is this necessary for WebDAV?
|
||||
if (localLastSyncTime) {
|
||||
if (localLastSyncID) {
|
||||
var sql = "REPLACE INTO version VALUES (?, ?)";
|
||||
Zotero.DB.query(
|
||||
sql, ['storage_webdav_' + libraryID, { int: localLastSyncTime }]
|
||||
sql, ['storage_webdav_' + libraryID, localLastSyncID]
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
var uri = this.rootURI;
|
||||
var successFileURI = uri.clone();
|
||||
successFileURI.spec += "lastsync";
|
||||
successFileURI.spec += "lastsync.txt";
|
||||
|
||||
var self = this;
|
||||
// Generate a random id for the last-sync id
|
||||
var id = Zotero.Utilities.randomString(_lastSyncIDLength);
|
||||
|
||||
return Zotero.HTTP.promise("PUT", successFileURI, " ",
|
||||
{ debug: true, successCodes: [200, 201, 204] })
|
||||
.then(function () {
|
||||
return self._getLastSyncTime()
|
||||
.then(function (ts) {
|
||||
if (ts) {
|
||||
var sql = "REPLACE INTO version VALUES (?, ?)";
|
||||
Zotero.DB.query(
|
||||
sql, ['storage_webdav_' + libraryID, { int: ts }]
|
||||
);
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(function (e) {
|
||||
var msg = "HTTP " + req.status + " error from WebDAV server "
|
||||
+ "for PUT request";
|
||||
Zotero.debug(msg, 2);
|
||||
Components.utils.reportError(msg);
|
||||
throw Zotero.Sync.Storage.WebDAV.defaultError;
|
||||
});
|
||||
return Zotero.HTTP.promise("PUT", successFileURI,
|
||||
{ body: id, debug: true, successCodes: [200, 201, 204] })
|
||||
.then(function () {
|
||||
var sql = "REPLACE INTO version VALUES (?, ?)";
|
||||
Zotero.DB.query(
|
||||
sql, ['storage_webdav_' + libraryID, id]
|
||||
);
|
||||
})
|
||||
.catch(function (e) {
|
||||
var msg = "HTTP " + req.status + " error from WebDAV server "
|
||||
+ "for PUT request";
|
||||
Zotero.debug(msg, 2);
|
||||
Components.utils.reportError(msg);
|
||||
throw Zotero.Sync.Storage.WebDAV.defaultError;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
@ -1182,7 +1211,7 @@ Zotero.Sync.Storage.WebDAV = (function () {
|
|||
case 207:
|
||||
// Test if Zotero directory is writable
|
||||
var testFileURI = uri.clone();
|
||||
testFileURI.spec += "zotero-test-file";
|
||||
testFileURI.spec += "zotero-test-file.prop";
|
||||
Zotero.HTTP.WebDAV.doPut(testFileURI, " ", function (req) {
|
||||
Zotero.debug(req.responseText);
|
||||
Zotero.debug(req.status);
|
||||
|
@ -1235,7 +1264,7 @@ Zotero.Sync.Storage.WebDAV = (function () {
|
|||
// data stores.
|
||||
//
|
||||
// This can also be from IIS 6+, which is configured
|
||||
// not to serve extensionless files or .prop files
|
||||
// not to serve .prop files.
|
||||
// http://support.microsoft.com/kb/326965
|
||||
case 404:
|
||||
return deferred.resolve([uri, Zotero.Sync.Storage.ERROR_FILE_MISSING_AFTER_UPLOAD]);
|
||||
|
|
|
@ -1043,6 +1043,10 @@ Zotero.Sync.Storage.ZFS = (function () {
|
|||
*/
|
||||
obj._purgeDeletedStorageFiles = function () {
|
||||
return Q.fcall(function () {
|
||||
// Cache the credentials at the root
|
||||
return this._cacheCredentials();
|
||||
}.bind(this))
|
||||
then(function () {
|
||||
// If we don't have a user id we've never synced and don't need to bother
|
||||
if (!Zotero.userID) {
|
||||
return false;
|
||||
|
|
|
@ -32,6 +32,8 @@ Zotero.Styles = new function() {
|
|||
var _initialized = false;
|
||||
var _styles, _visibleStyles, _cacheTranslatorData;
|
||||
|
||||
var _renamedStyles = null;
|
||||
|
||||
Components.utils.import("resource://zotero/q.js");
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
|
@ -116,22 +118,26 @@ Zotero.Styles = new function() {
|
|||
/**
|
||||
* Gets a style with a given ID
|
||||
* @param {String} id
|
||||
* @param {Boolean} skipMappings Don't automatically return renamed style
|
||||
*/
|
||||
this.get = function(id) {
|
||||
// Map some obsolete styles to current ones
|
||||
const MAPPINGS = {
|
||||
"http://www.zotero.org/styles/chicago-note": "http://www.zotero.org/styles/chicago-note-bibliography",
|
||||
"http://www.zotero.org/styles/mhra_note_without_bibliography": "http://www.zotero.org/styles/mhra",
|
||||
"http://www.zotero.org/styles/aaa": "http://www.zotero.org/styles/american-anthropological-association",
|
||||
"http://www.zotero.org/styles/ama": "http://www.zotero.org/styles/american-medical-association",
|
||||
"http://www.zotero.org/styles/nlm": "http://www.zotero.org/styles/national-library-of-medicine"
|
||||
};
|
||||
|
||||
this.get = function(id, skipMappings) {
|
||||
if(!_initialized) this.init();
|
||||
|
||||
if(MAPPINGS.hasOwnProperty(id) && _styles[MAPPINGS[id]]) {
|
||||
Zotero.debug("Mapping " + id + " to " + MAPPINGS[id]);
|
||||
return _styles[MAPPINGS[id]];
|
||||
|
||||
// Map some obsolete styles to current ones
|
||||
if(!_renamedStyles) {
|
||||
_renamedStyles = JSON.parse(Zotero.File.getContentsFromURL(
|
||||
"resource://zotero/schema/renamed-styles.json"
|
||||
));
|
||||
}
|
||||
|
||||
if(!skipMappings) {
|
||||
var prefix = "http://www.zotero.org/styles/";
|
||||
var shortName = id.replace(prefix, "");
|
||||
if(_renamedStyles.hasOwnProperty(shortName) && _styles[prefix + _renamedStyles[shortName]]) {
|
||||
let newID = prefix + _renamedStyles[shortName];
|
||||
Zotero.debug("Mapping " + id + " to " + newID);
|
||||
return _styles[newID];
|
||||
}
|
||||
}
|
||||
|
||||
return _styles[id] || false;
|
||||
|
|
|
@ -4019,7 +4019,9 @@ Zotero.Sync.Server.Data = new function() {
|
|||
var msg = Zotero.getString('sync.error.invalidCharsFilename', filename);
|
||||
var e = new Zotero.Error(msg, 0, { dialogButtonText: null });
|
||||
throw (e);
|
||||
|
||||
}
|
||||
if (item.attachment.linkMode == Zotero.Attachments.LINK_MODE_LINKED_FILE) {
|
||||
path = Zotero.Attachments.getBaseDirectoryRelativePath(path);
|
||||
}
|
||||
var pathElem = doc.createElement('path');
|
||||
pathElem.appendChild(doc.createTextNode(path));
|
||||
|
|
|
@ -2307,7 +2307,7 @@ Zotero.Translate.IO = {
|
|||
throw "DOMParser error: loading data into data store failed";
|
||||
}
|
||||
|
||||
nodes.normalize();
|
||||
if("normalize" in nodes) nodes.normalize();
|
||||
|
||||
return nodes;
|
||||
},
|
||||
|
|
|
@ -285,45 +285,93 @@ Zotero.Translate.ItemSaver.prototype = {
|
|||
|
||||
return newItem;
|
||||
},
|
||||
|
||||
"_parsePath":function(path) {
|
||||
// generate nsIFile
|
||||
var IOService = Components.classes["@mozilla.org/network/io-service;1"].
|
||||
getService(Components.interfaces.nsIIOService);
|
||||
|
||||
"_parsePathURI":function(path) {
|
||||
try {
|
||||
var uri = IOService.newURI(Zotero.File.encodeFilePath(path), "", this._baseURI);
|
||||
var uri = Services.io.newURI(path, "", this._baseURI);
|
||||
var file = uri.QueryInterface(Components.interfaces.nsIFileURL).file;
|
||||
if(file.path != '/' && file.exists()) return file;
|
||||
}
|
||||
catch (e) {
|
||||
var msg = "Error parsing attachment path: " + path + "\n" + e.message;
|
||||
Zotero.logError(msg);
|
||||
Zotero.debug("Translate: " + msg, 2);
|
||||
return false;
|
||||
Zotero.logError(e);
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
"_parseAbsolutePath":function(path) {
|
||||
try {
|
||||
var file = uri.QueryInterface(Components.interfaces.nsIFileURL).file;
|
||||
if (file.path == '/') {
|
||||
var msg = "Error parsing attachment path: " + path + "\nRoot path returned.";
|
||||
Zotero.logError(msg);
|
||||
Zotero.debug("Translate: " + msg, 2);
|
||||
return false;
|
||||
// First, try to parse absolute paths using initWithPath
|
||||
var file = Components.classes["@mozilla.org/file/local;1"].
|
||||
createInstance(Components.interfaces.nsILocalFile);
|
||||
file.initWithPath(path);
|
||||
if(file.exists()) return file;
|
||||
} catch(e) {
|
||||
Zotero.logError(e);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
"_parseRelativePath":function(path) {
|
||||
try {
|
||||
var file = this._baseURI.QueryInterface(Components.interfaces.nsIFileURL).file.parent;
|
||||
var splitPath = path.split(/\//g);
|
||||
for(var i=0; i<splitPath.length; i++) {
|
||||
if(splitPath[i] !== "") file.append(splitPath[i]);
|
||||
}
|
||||
if(file.exists()) return file;
|
||||
} catch(e) {
|
||||
Zotero.logError(e);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
"_parsePath":function(path) {
|
||||
var file;
|
||||
|
||||
// First, try to parse as absolute path
|
||||
if(((/[a-zA-Z]:\\/.test(path) && Zotero.isWin) || (path[0] === "/" && !Zotero.isWin))
|
||||
&& (file = this._parseAbsolutePath(path))) {
|
||||
Zotero.debug("Translate: Got file "+path+" as absolute path");
|
||||
return file;
|
||||
}
|
||||
|
||||
// Next, try to parse as URI
|
||||
if((file = this._parsePathURI(path))) {
|
||||
Zotero.debug("Translate: Got "+path+" as URI")
|
||||
return file;
|
||||
} else if(path.substr(0, 7) !== "file://") {
|
||||
// If it was a fully qualified file URI, we can give up now
|
||||
|
||||
// Next, try to parse as relative path, replacing backslashes with slashes
|
||||
if((file = this._parseRelativePath(path.replace(/\\/g, "/")))) {
|
||||
Zotero.debug("Translate: Got file "+path+" as relative path");
|
||||
return file;
|
||||
}
|
||||
|
||||
// Next, try to parse as relative path, without replacing backslashes with slashes
|
||||
if((file = this._parseRelativePath(path))) {
|
||||
Zotero.debug("Translate: Got file "+path+" as relative path");
|
||||
return file;
|
||||
}
|
||||
|
||||
if(path[0] !== "/") {
|
||||
// Next, try to parse a path with no / as an absolute URI or path
|
||||
if((file = this._parsePathURI("/"+path))) {
|
||||
Zotero.debug("Translate: Got file "+path+" as broken URI");
|
||||
return file;
|
||||
}
|
||||
|
||||
if((file = this._parseAbsolutePath("/"+path))) {
|
||||
Zotero.debug("Translate: Got file "+path+" as broken absolute path");
|
||||
return file;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
var msg = "Error getting file from attachment path: " + path + "\n" + e.message;
|
||||
Zotero.logError(msg);
|
||||
Zotero.debug("Translate: " + msg, 2);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(file.exists()) {
|
||||
return file;
|
||||
} else if(path[0] !== "/" && path.substr(0, 5).toLowerCase() !== "file:") {
|
||||
// This looks like a relative path, but it might actually be an absolute path, because
|
||||
// some people are not quite there.
|
||||
var newFile = this._parsePath("/"+path);
|
||||
if(newFile && newFile.exists()) return newFile;
|
||||
}
|
||||
|
||||
// Give up
|
||||
Zotero.debug("Translate: Could not find file "+path)
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
|
|
|
@ -35,6 +35,8 @@ const ZOTERO_CONFIG = {
|
|||
API_URL: 'https://api.zotero.org/',
|
||||
API_VERSION: 2,
|
||||
PREF_BRANCH: 'extensions.zotero.',
|
||||
BOOKMARKLET_ORIGIN : 'https://www.zotero.org',
|
||||
HTTP_BOOKMARKLET_ORIGIN : 'http://www.zotero.org',
|
||||
BOOKMARKLET_URL: 'https://www.zotero.org/bookmarklet/',
|
||||
VERSION: "4.1a1.SOURCE"
|
||||
};
|
||||
|
|
|
@ -3087,7 +3087,8 @@ var ZoteroPane = new function()
|
|||
if (itemType == 'temporaryPDFHack') {
|
||||
itemType = null;
|
||||
var isPDF = false;
|
||||
if (doc.title.indexOf('application/pdf') != -1 || Zotero.Attachments.isPDFJS(doc)) {
|
||||
if (doc.title.indexOf('application/pdf') != -1 || Zotero.Attachments.isPDFJS(doc)
|
||||
|| doc.contentType == 'application/pdf') {
|
||||
isPDF = true;
|
||||
}
|
||||
else {
|
||||
|
@ -3444,8 +3445,9 @@ var ZoteroPane = new function()
|
|||
}
|
||||
|
||||
var file = item.getFile();
|
||||
Zotero.debug("Opening " + file.path);
|
||||
if (file) {
|
||||
Zotero.debug("Opening " + file.path);
|
||||
|
||||
if(forceExternalViewer !== undefined) {
|
||||
var externalViewer = forceExternalViewer;
|
||||
} else {
|
||||
|
|
|
@ -203,4 +203,5 @@
|
|||
|
||||
<!ENTITY zotero.preferences.openAboutConfig "Open about:config">
|
||||
<!ENTITY zotero.preferences.openCSLEdit "Open CSL Editor">
|
||||
<!ENTITY zotero.preferences.openCSLPreview "Open CSL Preview">
|
||||
<!ENTITY zotero.preferences.openCSLPreview "Open CSL Preview">
|
||||
<!ENTITY zotero.preferences.openAboutMemory "Open about:memory">
|
|
@ -107,7 +107,6 @@
|
|||
}
|
||||
|
||||
.quick-format-bubble {
|
||||
-moz-border-radius: 8px;
|
||||
border-radius: 8px;
|
||||
background-color: #dee7f8;
|
||||
border-style: solid;
|
||||
|
@ -124,7 +123,6 @@
|
|||
}
|
||||
|
||||
.quick-format-bubble[selected="true"] {
|
||||
-moz-border-radius: 8px !important;
|
||||
border-radius: 8px !important;
|
||||
background-color: #598bec;
|
||||
color: #fff;
|
||||
|
|
|
@ -179,7 +179,6 @@ label.zotero-text-link {
|
|||
|
||||
.zotero-clicky
|
||||
{
|
||||
-moz-border-radius: 6px;
|
||||
border-radius: 6px;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ function ZoteroAutoComplete() {
|
|||
}
|
||||
|
||||
|
||||
ZoteroAutoComplete.prototype.startSearch = function(searchString, searchParam, previousResult, listener) {
|
||||
ZoteroAutoComplete.prototype.startSearch = function(searchString, searchParams, previousResult, listener) {
|
||||
var result = Cc["@mozilla.org/autocomplete/simple-result;1"]
|
||||
.createInstance(Ci.nsIAutoCompleteSimpleResult);
|
||||
result.setSearchString(searchString);
|
||||
|
@ -54,35 +54,35 @@ ZoteroAutoComplete.prototype.startSearch = function(searchString, searchParam, p
|
|||
this._listener = listener;
|
||||
this._cancelled = false;
|
||||
|
||||
this._zotero.debug("Starting autocomplete search of type '"
|
||||
+ searchParam + "'" + " with string '" + searchString + "'");
|
||||
this._zotero.debug("Starting autocomplete search with data '"
|
||||
+ searchParams + "'" + " and string '" + searchString + "'");
|
||||
|
||||
searchParams = JSON.parse(searchParams);
|
||||
if (!searchParams) {
|
||||
throw new Error("Invalid JSON passed to autocomplete");
|
||||
}
|
||||
var [fieldName, , subField] = searchParams.fieldName.split("-");
|
||||
|
||||
this.stopSearch();
|
||||
|
||||
var self = this;
|
||||
var statement;
|
||||
|
||||
// Allow extra parameters to be passed in
|
||||
var pos = searchParam.indexOf('/');
|
||||
if (pos!=-1){
|
||||
var extra = searchParam.substr(pos + 1);
|
||||
var searchParam = searchParam.substr(0, pos);
|
||||
}
|
||||
|
||||
var searchParts = searchParam.split('-');
|
||||
searchParam = searchParts[0];
|
||||
|
||||
switch (searchParam) {
|
||||
switch (fieldName) {
|
||||
case '':
|
||||
break;
|
||||
|
||||
case 'tag':
|
||||
var sql = "SELECT DISTINCT name AS val, NULL AS comment FROM tags WHERE name LIKE ?";
|
||||
var sqlParams = [searchString + '%'];
|
||||
if (extra){
|
||||
if (typeof searchParams.libraryID != 'undefined') {
|
||||
sql += " AND libraryID=?";
|
||||
sqlParams.push(searchParams.libraryID);
|
||||
}
|
||||
if (searchParams.itemID) {
|
||||
sql += " AND name NOT IN (SELECT name FROM tags WHERE tagID IN ("
|
||||
+ "SELECT tagID FROM itemTags WHERE itemID = ?))";
|
||||
sqlParams.push(extra);
|
||||
sqlParams.push(searchParams.itemID);
|
||||
}
|
||||
|
||||
statement = this._zotero.DB.getStatement(sql, sqlParams);
|
||||
|
@ -103,22 +103,24 @@ ZoteroAutoComplete.prototype.startSearch = function(searchString, searchParam, p
|
|||
// 0 == search two-field creators
|
||||
// 1 == search single-field creators
|
||||
// 2 == search both
|
||||
var [fieldMode, itemID] = extra.split('-');
|
||||
|
||||
if (fieldMode==2)
|
||||
{
|
||||
if (searchParams.fieldMode == 2) {
|
||||
var sql = "SELECT DISTINCT CASE fieldMode WHEN 1 THEN lastName "
|
||||
+ "WHEN 0 THEN firstName || ' ' || lastName END AS val, NULL AS comment "
|
||||
+ "FROM creators NATURAL JOIN creatorData WHERE CASE fieldMode "
|
||||
+ "WHEN 1 THEN lastName "
|
||||
+ "WHEN 0 THEN firstName || ' ' || lastName END "
|
||||
+ "LIKE ? ORDER BY val";
|
||||
var sqlParams = searchString + '%';
|
||||
+ "LIKE ? ";
|
||||
var sqlParams = [searchString + '%'];
|
||||
if (typeof searchParams.libraryID != 'undefined') {
|
||||
sql += " AND libraryID=?";
|
||||
sqlParams.push(searchParams.libraryID);
|
||||
}
|
||||
sql += "ORDER BY val";
|
||||
}
|
||||
else
|
||||
{
|
||||
var sql = "SELECT DISTINCT ";
|
||||
if (fieldMode==1){
|
||||
if (searchParams.fieldMode == 1) {
|
||||
sql += "lastName AS val, creatorID || '-1' AS comment";
|
||||
}
|
||||
// Retrieve the matches in the specified field
|
||||
|
@ -138,22 +140,35 @@ ZoteroAutoComplete.prototype.startSearch = function(searchString, searchParam, p
|
|||
}
|
||||
|
||||
var fromSQL = " FROM creators NATURAL JOIN creatorData "
|
||||
+ "WHERE " + searchParts[2] + " LIKE ?1 " + "AND fieldMode=?2";
|
||||
var sqlParams = [searchString + '%',
|
||||
fieldMode ? parseInt(fieldMode) : 0];
|
||||
if (itemID){
|
||||
+ "WHERE " + subField + " LIKE ?1 " + "AND fieldMode=?2";
|
||||
var sqlParams = [
|
||||
searchString + '%',
|
||||
searchParams.fieldMode ? searchParams.fieldMode : 0
|
||||
];
|
||||
if (searchParams.itemID) {
|
||||
fromSQL += " AND creatorID NOT IN (SELECT creatorID FROM "
|
||||
+ "itemCreators WHERE itemID=?3)";
|
||||
sqlParams.push(itemID);
|
||||
sqlParams.push(searchParams.itemID);
|
||||
}
|
||||
if (typeof searchParams.libraryID != 'undefined') {
|
||||
if (searchParams.libraryID) {
|
||||
fromSQL += " AND libraryID=?4";
|
||||
sqlParams.push(searchParams.libraryID);
|
||||
}
|
||||
// The db query code doesn't properly replace numbered
|
||||
// parameters with "IS NULL"
|
||||
else {
|
||||
fromSQL += " AND libraryID IS NULL";
|
||||
}
|
||||
}
|
||||
|
||||
sql += fromSQL;
|
||||
|
||||
// If double-field mode, include matches for just this field
|
||||
// as well (i.e. "Shakespeare"), and group to collapse repeats
|
||||
if (fieldMode!=1){
|
||||
if (searchParams.fieldMode != 1) {
|
||||
sql = "SELECT * FROM (" + sql + " UNION SELECT DISTINCT "
|
||||
+ searchParts[2] + " AS val, creatorID || '-1' AS comment"
|
||||
+ subField + " AS val, creatorID || '-1' AS comment"
|
||||
+ fromSQL + ") GROUP BY val";
|
||||
}
|
||||
|
||||
|
@ -165,8 +180,8 @@ ZoteroAutoComplete.prototype.startSearch = function(searchString, searchParam, p
|
|||
|
||||
case 'dateModified':
|
||||
case 'dateAdded':
|
||||
var sql = "SELECT DISTINCT DATE(" + searchParam + ", 'localtime') AS val, NULL AS comment FROM items "
|
||||
+ "WHERE " + searchParam + " LIKE ? ORDER BY " + searchParam;
|
||||
var sql = "SELECT DISTINCT DATE(" + fieldName + ", 'localtime') AS val, NULL AS comment FROM items "
|
||||
+ "WHERE " + fieldName + " LIKE ? ORDER BY " + fieldName;
|
||||
var sqlParams = [searchString + '%'];
|
||||
statement = this._zotero.DB.getStatement(sql, sqlParams);
|
||||
break;
|
||||
|
@ -181,9 +196,9 @@ ZoteroAutoComplete.prototype.startSearch = function(searchString, searchParam, p
|
|||
break;
|
||||
|
||||
default:
|
||||
var fieldID = this._zotero.ItemFields.getID(searchParam);
|
||||
var fieldID = this._zotero.ItemFields.getID(fieldName);
|
||||
if (!fieldID) {
|
||||
this._zotero.debug("'" + searchParam + "' is not a valid autocomplete scope", 1);
|
||||
this._zotero.debug("'" + fieldName + "' is not a valid autocomplete scope", 1);
|
||||
this.updateResults([], false, Ci.nsIAutoCompleteResult.RESULT_IGNORED);
|
||||
return;
|
||||
}
|
||||
|
@ -191,7 +206,7 @@ ZoteroAutoComplete.prototype.startSearch = function(searchString, searchParam, p
|
|||
// We don't use date autocomplete anywhere, but if we're not
|
||||
// disallowing it altogether, we should at least do it right and
|
||||
// use the user part of the multipart field
|
||||
var valueField = searchParam=='date' ? 'SUBSTR(value, 12, 100)' : 'value';
|
||||
var valueField = fieldName == 'date' ? 'SUBSTR(value, 12, 100)' : 'value';
|
||||
|
||||
var sql = "SELECT DISTINCT " + valueField + " AS val, NULL AS comment "
|
||||
+ "FROM itemData NATURAL JOIN itemDataValues "
|
||||
|
@ -199,10 +214,10 @@ ZoteroAutoComplete.prototype.startSearch = function(searchString, searchParam, p
|
|||
+ " LIKE ?2 "
|
||||
|
||||
var sqlParams = [fieldID, searchString + '%'];
|
||||
if (extra){
|
||||
if (searchParams.itemID) {
|
||||
sql += "AND value NOT IN (SELECT value FROM itemData "
|
||||
+ "NATURAL JOIN itemDataValues WHERE fieldID=?1 AND itemID=?3) ";
|
||||
sqlParams.push(extra);
|
||||
sqlParams.push(searchParams.itemID);
|
||||
}
|
||||
sql += "ORDER BY value";
|
||||
statement = this._zotero.DB.getStatement(sql, sqlParams);
|
||||
|
|
162
resource/schema/renamed-styles.json
Normal file
162
resource/schema/renamed-styles.json
Normal file
|
@ -0,0 +1,162 @@
|
|||
{
|
||||
"aaa": "american-anthropological-association",
|
||||
"advances-physiology-education": "advances-in-physiology-education",
|
||||
"agriculture-ecosystems-environment": "agriculture-ecosystems-and-environment",
|
||||
"ajp-heart-circulatory-physiology": "ajp-heart-and-circulatory-physiology",
|
||||
"ajp-regulatory-integrative-comparative-physiology": "ajp-regulatory-integrative-and-comparative-physiology",
|
||||
"ama": "american-medical-association",
|
||||
"american-journal-of-cardiology": "the-american-journal-of-cardiology",
|
||||
"american-journal-of-clinical-nutrition": "the-american-journal-of-clinical-nutrition",
|
||||
"american-journal-of-emergency-medicine": "the-american-journal-of-emergency-medicine",
|
||||
"american-journal-of-medicine": "the-american-journal-of-medicine",
|
||||
"american-journal-of-pathology": "the-american-journal-of-pathology",
|
||||
"american-journal-of-sports-medicine": "the-american-journal-of-sports-medicine",
|
||||
"american-journal-of-surgery": "the-american-journal-of-surgery",
|
||||
"american-journal-of-tropical-medicine-and-hygiene": "the-american-journal-of-tropical-medicine-and-hygiene",
|
||||
"american-medical-writers-association": "american-medical-writers-association-journal",
|
||||
"american-surgeon": " the-american-surgeon",
|
||||
"amiens": "universite-de-picardie-jules-verne-ufr-de-medecine",
|
||||
"annalen-des-naturhistorischen-museums-wien": "annalen-des-naturhistorischen-museums-in-wien",
|
||||
"annals-of-allergy": "annals-of-allergy-asthma-and-immunology",
|
||||
"annals-of-thoracic-surgery": "the-annals-of-thoracic-surgery",
|
||||
"annual-reviews-alphabetically": "annual-reviews-alphabetical",
|
||||
"annual-reviews-by-appearance": "annual-reviews",
|
||||
"apa5th": "apa-5th-edition",
|
||||
"apsa": "american-political-science-association",
|
||||
"asa": "american-sociological-association",
|
||||
"bba-biochimica-et-biophysica-acta": "biochimica-et-biophysica-acta",
|
||||
"bio-medical-reviews": "biomedical-reviews",
|
||||
"bmc-pharmacology": "bmc-pharmacology-and-toxicology",
|
||||
"bmj-supportive-palliative-care": "bmj-supportive-and-palliative-care",
|
||||
"brain-and-development-english-language": "brain-and-development",
|
||||
"british-journal-of-medical-economics": "journal-of-medical-economics",
|
||||
"british-volume-of-the-journal-of-bone-and-joint-surgery": "the-journal-of-bone-and-joint-surgery",
|
||||
"bulletin-of-the-medical-library-association": "journal-of-the-medical-library-association",
|
||||
"canadian-journal-of-anaesthesia": "canadian-journal-of-anesthesia",
|
||||
"canadian-journal-of-hospital-pharmacy": "the-canadian-journal-of-hospital-pharmacy",
|
||||
"canadian-medical-association-journal": "cmaj",
|
||||
"canadian-veterinary-journal": "the-canadian-veterinary-journal",
|
||||
"cancer-epidemiology-biomarkers-prevention": "cancer-epidemiology-biomarkers-and-prevention",
|
||||
"cardiovascular-pharmacology-and-therapeutics": "journal-of-cardiovascular-pharmacology-and-therapeutics",
|
||||
"central-african-journal-of-medicine": "the-central-african-journal-of-medicine",
|
||||
"ceylon-journal-of-medical-science": "the-ceylon-journal-of-medical-science",
|
||||
"ceylon-medical-journal": "the-ceylon-medical-journal",
|
||||
"chicago-note": "chicago-note-bibliography",
|
||||
"chronic-diseases-in-canada": "chronic-diseases-and-injuries-in-canada",
|
||||
"college-of-physicians-and-surgeons-pakistan": "journal-of-the-college-of-physicians-and-surgeons-pakistan",
|
||||
"cuadernos-filologia-clasica": "cuadernos-de-filologia-clasica",
|
||||
"current-opinion-biotechnology": "current-opinion-in-biotechnology",
|
||||
"current-opinion-cell-biology": "current-opinion-in-cell-biology",
|
||||
"current-opinion-chemical-biology": "current-opinion-in-chemical-biology",
|
||||
"current-opinion-environmental-sustainability": "current-opinion-in-environmental-sustainability",
|
||||
"current-opinion-genetics-development": "current-opinion-in-genetics-development",
|
||||
"current-opinion-immunology": "current-opinion-in-immunology",
|
||||
"current-opinion-microbiology": "current-opinion-in-microbiology",
|
||||
"current-opinion-neurobiology": "current-opinion-in-neurobiology",
|
||||
"current-opinion-pharmacology": "current-opinion-in-pharmacology",
|
||||
"current-opinion-plant-biology": "current-opinion-in-plant-biology",
|
||||
"current-opinion-structural-biology": "current-opinion-in-structural-biology",
|
||||
"danish-dental-journal": "tandlaegebladet",
|
||||
"diabetes-vascular-disease-research": "diabetes-and-vascular-disease-research",
|
||||
"disease-models-mechanisms": "disease-models-and-mechanisms",
|
||||
"diseases-aquatic-organisms": "diseases-of-aquatic-organisms",
|
||||
"edizioni-minerva-medica": "minerva-medica",
|
||||
"ethics-science-environmental-politics": "ethics-in-science-and-environmental-politics",
|
||||
"f1000-research": "f1000research",
|
||||
"febs-journal": "the-febs-journal",
|
||||
"fems": "federation-of-european-microbiological-societies",
|
||||
"firstmonday": "first-monday",
|
||||
"future-science": "future-science-journals",
|
||||
"geological-society-america-bulletin": "geological-society-of-america-bulletin",
|
||||
"geological-society-of-america": "the-geological-society-of-america",
|
||||
"gost-r-7-0-5-2008-csl-1-0": "gost-r-7-0-5-2008",
|
||||
"graefes-archive-and-experimental-ophthalmology": "graefes-archive-for-clinical-and-experimental-ophthalmology",
|
||||
"harvard-anglia-ruskin": "harvard-anglia-ruskin-university",
|
||||
"harvard-sheffield": "harvard-the-university-of-sheffield-town-and-regional-planning",
|
||||
"harvard-sheffield1": "harvard-the-university-of-sheffield-school-of-east-asian-studies",
|
||||
"harvard-university-of-northampton": "harvard-the-university-of-northampton",
|
||||
"harvard-university-west-london": "harvard-university-of-west-london",
|
||||
"harvard1-unisa-gbfe": "harvard-gesellschaft-fur-bildung-und-forschung-in-europa",
|
||||
"harvard3": "harvard-swinburne-university-of-technology",
|
||||
"hbp": "hpb",
|
||||
"hwr-berlin": "hochschule-fur-wirtschaft-und-recht-berlin",
|
||||
"ices-jms": "ices-journal-of-marine-science",
|
||||
"ieee-w-url": "ieee-with-url",
|
||||
"institute-of-electronics-information-and-communication-engineers": "the-institute-of-electronics-information-and-communication-engineers",
|
||||
"international-journal-cross-cultural-management": "international-journal-of-cross-cultural-management",
|
||||
"international-journal-of-psychiatry-in-medicine": "the-international-journal-of-psychiatry-in-medicine",
|
||||
"international-journal-of-psychoanalysis": "the-international-journal-of-psychoanalysis",
|
||||
"international-journal-of-tropical-biology-and-conservation": "revista-de-biologia-tropical",
|
||||
"iso690-author-date-fr-without-abstract": "iso690-author-date-fr-no-abstract",
|
||||
"jid-symposium-proceedings": "journal-of-investigative-dermatology-symposium-proceedings",
|
||||
"journal-of-aapos": "journal-of-american-association-for-pediatric-ophthalmology-and-strabismus",
|
||||
"journal-of-allergy-and-clinical-immunology": "the-journal-of-allergy-and-clinical-immunology",
|
||||
"journal-of-bone-and-joint-surgery": "the-journal-of-bone-and-joint-surgery",
|
||||
"journal-of-cardiovascular-surgery": "the-journal-of-cardiovascular-surgery",
|
||||
"journal-of-cell-biology": "the-journal-of-cell-biology",
|
||||
"journal-of-chemical-physics": "the-journal-of-chemical-physics",
|
||||
"journal-of-clinical-endocrinology-and-metabolism": "the-journal-of-clinical-endocrinology-and-metabolism",
|
||||
"journal-of-clinical-investigation": "the-journal-of-clinical-investigation",
|
||||
"journal-of-clinical-psychiatry": "the-journal-of-clinical-psychiatry",
|
||||
"journal-of-experimental-medicine": "the-journal-of-experimental-medicine",
|
||||
"journal-of-general-physiology": "the-journal-of-general-physiology",
|
||||
"journal-of-hand-surgery": "the-journal-of-hand-surgery",
|
||||
"journal-of-heart-and-lung-transplantation": "the-journal-of-heart-and-lung-transplantation",
|
||||
"journal-of-hellenic-studies": "the-journal-of-hellenic-studies",
|
||||
"journal-of-hong-kong-medical-association": "hong-kong-medical-journal",
|
||||
"journal-of-indian-prosthodontic-society": "the-journal-of-indian-prosthodontic-society",
|
||||
"journal-of-juristic-papyrology": "the-journal-of-juristic-papyrology",
|
||||
"journal-of-medieval-and-early-modern-studies": "the-journal-of-medieval-and-early-modern-studies",
|
||||
"journal-of-modern-history": "the-journal-of-modern-history",
|
||||
"journal-of-nuclear-medicine": "the-journal-of-nuclear-medicine",
|
||||
"journal-of-organic-chemistry": "the-journal-of-organic-chemistry",
|
||||
"journal-of-pediatrics": "the-journal-of-pediatrics",
|
||||
"journal-of-pharmacology-and-experimental-therapeutics": "the-journal-of-pharmacology-and-experimental-therapeutics",
|
||||
"journal-of-pharmacy-technology": "the-journal-of-pharmacy-technology",
|
||||
"journal-of-physical-chemistry": "the-journal-of-physical-chemistry-a",
|
||||
"journal-of-prosthetic-dentistry": "the-journal-of-prosthetic-dentistry",
|
||||
"journal-of-the-american-academy-of-physician-assistants": "jaapa",
|
||||
"journal-of-the-american-dental-association": "the-journal-of-the-american-dental-association",
|
||||
"journal-of-the-american-medical-association": "jama",
|
||||
"journal-of-the-american-osteopathic-association": "the-journal-of-the-american-osteopathic-association",
|
||||
"journal-of-the-indian-society-of-pedodontics-and-preventative-dentistry": "journal-of-the-indian-society-of-pedodontics-and-preventive-dentistry",
|
||||
"journal-of-the-institute-of-medicine": "journal-of-institute-of-medicine",
|
||||
"journal-of-the-torrey-botanical-society": "the-journal-of-the-torrey-botanical-society",
|
||||
"journal-of-thoracic-and-cardiovascular-surgery": "the-journal-of-thoracic-and-cardiovascular-surgery",
|
||||
"journal-of-wildlife-management": "the-journal-of-wildlife-management",
|
||||
"juristische-zitierweise-deutsch": "juristische-zitierweise",
|
||||
"korean-journal-of-gynecologic-oncology": "journal-of-gynecologic-oncology",
|
||||
"lancet-infectious-diseases": "the-lancet-infectious-diseases",
|
||||
"lancet-neurology": "the-lancet-neurology",
|
||||
"lancet-oncology": "the-lancet-oncology",
|
||||
"lancet": "the-lancet",
|
||||
"lichenologist": "the-lichenologist",
|
||||
"lncs": "springer-lecture-notes-in-computer-science",
|
||||
"lncs2": "springer-lecture-notes-in-computer-science-alphabetical",
|
||||
"malaysian-journal-of-pathology": "the-malaysian-journal-of-pathology",
|
||||
"manedsskrift-for-praktk-laegegerning": "manedsskrift-for-almen-praksis",
|
||||
"medical-journal-of-australia": "the-medical-journal-of-australia",
|
||||
"medicina-militar": "sanidad-militar",
|
||||
"methods-information-medicine": "methods-of-information-in-medicine",
|
||||
"mhra_note_without_bibliography": "modern-humanities-research-association",
|
||||
"mhra-author-date": "modern-humanities-research-association-author-date",
|
||||
"mhra": "modern-humanities-research-association",
|
||||
"mla-notes": "modern-language-association-note",
|
||||
"mla-underline": "modern-language-association-underline",
|
||||
"mla-url": "modern-language-association-with-url",
|
||||
"mla": "modern-language-association",
|
||||
"molecular-biochemical-parasitology": "molecular-and-biochemical-parasitology",
|
||||
"netherlands-journal-of-medicine": "the-netherlands-journal-of-medicine",
|
||||
"neumologica-y-cirugia-de-torax-neurofibromatosis": "neumologia-y-cirugia-de-torax",
|
||||
"new-iraqi-journal-of-medicine": "the-new-iraqi-journal-of-medicine",
|
||||
"new-zealand-journal-of-medical-laboratory-technology": "new-zealand-journal-of-medical-laboratory-science",
|
||||
"new-zealand-medical-journal": "the-new-zealand-medical-journal",
|
||||
"nlm": "national-library-of-medicine",
|
||||
"physiological-biochemical-zoology": "physiological-and-biochemical-zoology",
|
||||
"quaderni-avogadro-colloquia": "quaderni-degli-avogadro-colloquia",
|
||||
"taylor-and-francis-reference-style-f": "taylor-and-francis-chicago-f",
|
||||
"ulster-medical-journal": "the-ulster-medical-journal",
|
||||
"uni-freiburg-geschichte-autor-jahr": "universitat-freiburg-geschichte",
|
||||
"uqam-universite-du-quebec-a-montreal": "universite-du-quebec-a-montreal",
|
||||
"world-health-organization-journals": "world-health-organization"
|
||||
}
|
|
@ -1 +1 @@
|
|||
2013-04-07 18:45:00
|
||||
2013-04-15 18:15:00
|
||||
|
|
2
styles
2
styles
|
@ -1 +1 @@
|
|||
Subproject commit b53019e1e601c6e843c58ad12c8149afc29ce4d6
|
||||
Subproject commit e136c9f0b4cd82fcd1bed4b4a35bb7139a40d9ea
|
|
@ -1 +1 @@
|
|||
Subproject commit c70b413c796b294f98a19667d48081ba4d042e0c
|
||||
Subproject commit 95d2177e3e3500b7c05e3a4c6608e0b55a1c5ad3
|
Loading…
Reference in a new issue