Merge branch '3.0'

Conflicts:
	chrome/content/zotero/xpcom/attachments.js
	chrome/content/zotero/xpcom/translation/translate_item.js
	install.rdf
	update.rdf
This commit is contained in:
Dan Stillman 2012-11-23 01:49:32 -05:00
commit 4caae896cf
14 changed files with 121 additions and 85 deletions

View File

@ -54,6 +54,8 @@ var WPD_DEFAULTHEIGHT = 768;
var WPD_MAXUIERRORCOUNT = 8; var WPD_MAXUIERRORCOUNT = 8;
// maximum character length for a valid file name (excluding extension)
var WPD_MAX_FILENAME_LENGTH = 100;
/*function wpdGetTopBrowserWindow() /*function wpdGetTopBrowserWindow()
{ {
@ -353,15 +355,10 @@ var wpdCommon = {
}, },
// replace illegal characters // replace illegal characters
// and shorten long file names
getValidFileName: function (aFileName) { getValidFileName: function (aFileName) {
aFileName = aFileName.replace(/[\"\?!~`]+/g, ""); aFileName = Zotero.File.getValidFileName(aFileName);
aFileName = aFileName.replace(/[\*\&]+/g, "+"); return Zotero.File.truncateFileName(aFileName, WPD_MAX_FILENAME_LENGTH);
aFileName = aFileName.replace(/[\\\/\|\:;]+/g, "-");
aFileName = aFileName.replace(/[\<]+/g, "(");
aFileName = aFileName.replace(/[\>]+/g, ")");
aFileName = aFileName.replace(/[\s]+/g, "_");
aFileName = aFileName.replace(/[%]+/g, "@");
return aFileName;
}, },
getURL: function () { getURL: function () {

View File

@ -164,7 +164,8 @@ var wpdDOMSaver = {
// Split fileName in Path and Name // Split fileName in Path and Name
this.name = wpdCommon.getFileLeafName(fileName); // extract fileName from filePath this.name = wpdCommon.getValidFileName(
wpdCommon.getFileLeafName(fileName)); // extract fileName from filePath
this.currentDir = wpdCommon.getFilePath(fileName); // only directory this.currentDir = wpdCommon.getFilePath(fileName); // only directory
this.name = wpdCommon.splitFileName(this.name)[0]; // no extension! this.name = wpdCommon.splitFileName(this.name)[0]; // no extension!
@ -221,7 +222,7 @@ var wpdDOMSaver = {
// resolve the javascript links inside the attributes (e.g. onclick,...) // resolve the javascript links inside the attributes (e.g. onclick,...)
normalizeJavaScriptLink: function (aNode, aAttr) { normalizeJavaScriptLink: function (aNode, aAttr) {
var val = aNode.getAttribute(aAttr); // get the attribute value and check for link stuff var val = aNode.getAttribute(aAttr); // get the attribute value and check for link stuff
if (!val.match(/\(\'([^\']+)\'/)) return aNode; if (!val || !val.match(/\(\'([^\']+)\'/)) return aNode;
val = RegExp.$1; val = RegExp.$1;
if (val.indexOf("/") == -1 && val.indexOf(".") == -1) return aNode; if (val.indexOf("/") == -1 && val.indexOf(".") == -1) return aNode;
val = wpdCommon.resolveURL(this.currentURL, val); // it is a link -> resolve and set the URL to the local URL val = wpdCommon.resolveURL(this.currentURL, val); // it is a link -> resolve and set the URL to the local URL
@ -409,9 +410,12 @@ var wpdDOMSaver = {
case "link": case "link":
// could containt urls (icon, stylesheet and fontdef) // could containt urls (icon, stylesheet and fontdef)
// We have to remove nodes with the stylesheet attribute because they will be added later // We have to remove nodes with the stylesheet attribute because they will be added later
if ((aNode.getAttribute("rel").toLowerCase() == "stylesheet") && (aNode.getAttribute("href").indexOf("chrome://") == -1)) { if(!aNode.hasAttribute("rel")) return aNode;
if (aNode.getAttribute("rel").toLowerCase() == "stylesheet"
&& (aNode.hasAttribute("href") && aNode.getAttribute("href").indexOf("chrome://") == -1)) {
return wpdCommon.removeNodeFromParent(aNode); return wpdCommon.removeNodeFromParent(aNode);
} else if ((aNode.getAttribute("rel").toLowerCase() == "shortcut icon") || (aNode.getAttribute("rel").toLowerCase() == "icon")) { } else if (aNode.getAttribute("rel").toLowerCase() == "shortcut icon"
|| aNode.getAttribute("rel").toLowerCase() == "icon") {
var aFileName = this.download(aNode.href, true); var aFileName = this.download(aNode.href, true);
// Changed by Dan S. for Zotero -- see this.repairRelativeLinks() // Changed by Dan S. for Zotero -- see this.repairRelativeLinks()
if (aFileName) aNode.setAttribute("href", this.relativeLinkFix(aFileName)); if (aFileName) aNode.setAttribute("href", this.relativeLinkFix(aFileName));
@ -671,7 +675,7 @@ var wpdDOMSaver = {
//returns a unique file name and registers it //returns a unique file name and registers it
getUniqueFileNameAndRegister: function(fileName, sourceURL, content) { getUniqueFileNameAndRegister: function(fileName, sourceURL, content) {
fileName = this.checkForEqualFilenames( fileName = this.checkForEqualFilenames(
wpdCommon.getValidFileName(fileName).toLowerCase(), wpdCommon.getValidFileName(fileName),
sourceURL); sourceURL);
this.registerFile(fileName, sourceURL, content); this.registerFile(fileName, sourceURL, content);
return fileName; return fileName;
@ -679,7 +683,7 @@ var wpdDOMSaver = {
//register filename, so we don't overwrite them later //register filename, so we don't overwrite them later
registerFile: function (newFileName, sourceURL, content) { registerFile: function (newFileName, sourceURL, content) {
this.fileInfo[newFileName] = { this.fileInfo[newFileName.toLowerCase()] = {
url: sourceURL, url: sourceURL,
downloaded: content downloaded: content
} }
@ -687,11 +691,12 @@ var wpdDOMSaver = {
// is the file registered (e.g. downloaded)? // is the file registered (e.g. downloaded)?
isFileRegistered: function (newFileName) { isFileRegistered: function (newFileName) {
if (this.fileInfo[newFileName] != undefined) return true; if (this.fileInfo[newFileName.toLowerCase()] != undefined) return true;
return false; return false;
}, },
isDownloaded: function(fileName) { isDownloaded: function(fileName) {
fileName = fileName.toLowerCase();
if(!this.fileInfo[fileName]) return; if(!this.fileInfo[fileName]) return;
return this.fileInfo[fileName].downloaded; return this.fileInfo[fileName].downloaded;
}, },
@ -701,16 +706,16 @@ var wpdDOMSaver = {
// if no aURLSpec is passed, this generates a unique file name // if no aURLSpec is passed, this generates a unique file name
checkForEqualFilenames: function (newFileName, aURLSpec) { checkForEqualFilenames: function (newFileName, aURLSpec) {
if (this.isFileRegistered(newFileName)) { if (this.isFileRegistered(newFileName)) {
if (!aURLSpec || this.fileInfo[newFileName]["url"] != aURLSpec) { if (!aURLSpec || this.fileInfo[newFileName.toLowerCase()]["url"] != aURLSpec) {
// the file is already registered but from a different location // the file is already registered but from a different location
// => probably not the same file, so we have to find a different name it (e.g. filename_001.ext) // => probably not the same file, so we have to find a different name it (e.g. filename_001.ext)
var seq = 1; var seq = 1;
var fileLR = wpdCommon.splitFileName(newFileName); var fileLR = wpdCommon.splitFileName(newFileName);
if (!fileLR[1]) fileLR[1] = "dat"; if (!fileLR[1]) fileLR[1] = "dat";
newFileName = fileLR[0] + "_" + wpdCommon.addLeftZeros(seq++, 3) + "." + fileLR[1]; newFileName = fileLR[0] + "_" + wpdCommon.addLeftZeros(seq++, 3) + "." + fileLR[1];
while (this.fileInfo[newFileName] != undefined) { while (this.fileInfo[newFileName.toLowerCase()] != undefined) {
// is the file already registered with the new name? // is the file already registered with the new name?
if (aURLSpec && this.fileInfo[newFileName]["url"] == aURLSpec) return newFileName; // Yes -> so it<EFBFBD>s already downloaded and we are finished if (aURLSpec && this.fileInfo[newFileName.toLowerCase()]["url"] == aURLSpec) return newFileName; // Yes -> so it's already downloaded and we are finished
newFileName = fileLR[0] + "_" + wpdCommon.addLeftZeros(seq++, 3) + "." + fileLR[1]; // No -> "increment" filename newFileName = fileLR[0] + "_" + wpdCommon.addLeftZeros(seq++, 3) + "." + fileLR[1]; // No -> "increment" filename
} }
} }
@ -730,9 +735,8 @@ var wpdDOMSaver = {
var aURL = wpdCommon.convertURLToObject(aURLSpec); var aURL = wpdCommon.convertURLToObject(aURLSpec);
// generate a filename // generate a filename
var newFileName = aURL.fileName.toLowerCase(); var newFileName = aURL.fileName;
if (!newFileName) newFileName = "untitled"; if (!newFileName) newFileName = "untitled";
newFileName = wpdCommon.getValidFileName(newFileName);
// same name but different location? // same name but different location?
newFileName = this.getUniqueFileNameAndRegister(newFileName, aURLSpec); newFileName = this.getUniqueFileNameAndRegister(newFileName, aURLSpec);
// is the file already registered (processed) ? // is the file already registered (processed) ?
@ -1076,7 +1080,7 @@ var wpdDOMSaver = {
// (be sure to call the init function at the top of this file before) // (be sure to call the init function at the top of this file before)
saveHTMLDocument: function () { saveHTMLDocument: function () {
try { try {
this.saveDocumentEx(this.document, this.name); return this.saveDocumentEx(this.document, this.name);
} catch (ex) { } catch (ex) {
wpdCommon.addError("[wpdDOMSaver.saveHTMLDocument]\n -> " + ex); wpdCommon.addError("[wpdDOMSaver.saveHTMLDocument]\n -> " + ex);
} }

View File

@ -234,7 +234,7 @@ Zotero.Attachments = new function(){
}; };
Zotero.Attachments.importFromDocument(browser.contentDocument, Zotero.Attachments.importFromDocument(browser.contentDocument,
sourceItemID, forceTitle, parentCollectionIDs, importCallback, libraryID); sourceItemID, forceTitle, parentCollectionIDs, importCallback, libraryID);
}, undefined, undefined, true); }, undefined, undefined, true, cookieSandbox);
}; };
// Save using remote web browser persist // Save using remote web browser persist
@ -550,10 +550,13 @@ Zotero.Attachments = new function(){
var file = Components.classes["@mozilla.org/file/local;1"]. var file = Components.classes["@mozilla.org/file/local;1"].
createInstance(Components.interfaces.nsILocalFile); createInstance(Components.interfaces.nsILocalFile);
file.initWithFile(destDir); file.initWithFile(destDir);
var fileName = _getFileNameFromURL(url, mimeType); var fileName = Zotero.File.truncateFileName(
file.append(fileName); _getFileNameFromURL(url, mimeType),
100 //make sure this matches WPD settings in webpagedump/common.js
);
file.append(fileName)
if (mimeType == 'application/pdf') { if (mimeType == 'application/pdf') {
var f = function() { var f = function() {
Zotero.Fulltext.indexPDF(file, itemID); Zotero.Fulltext.indexPDF(file, itemID);
@ -581,10 +584,10 @@ Zotero.Attachments = new function(){
Components.classes["@mozilla.org/moz/jssubscript-loader;1"] Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Components.interfaces.mozIJSSubScriptLoader) .getService(Components.interfaces.mozIJSSubScriptLoader)
.loadSubScript("chrome://zotero/content/webpagedump/domsaver.js", wpd); .loadSubScript("chrome://zotero/content/webpagedump/domsaver.js", wpd);
wpd.wpdDOMSaver.init(file.path, document); wpd.wpdDOMSaver.init(file.path, document);
wpd.wpdDOMSaver.saveHTMLDocument(); wpd.wpdDOMSaver.saveHTMLDocument();
attachmentItem.attachmentPath = this.getPath( attachmentItem.attachmentPath = this.getPath(
file, Zotero.Attachments.LINK_MODE_IMPORTED_URL file, Zotero.Attachments.LINK_MODE_IMPORTED_URL
); );
@ -1178,26 +1181,24 @@ Zotero.Attachments = new function(){
nsIURL.fileBaseName = nsIURL.fileBaseName + '.' + tld; nsIURL.fileBaseName = nsIURL.fileBaseName + '.' + tld;
} }
// Unencode fileBaseName // Test unencoding fileBaseName
var decodedFileBaseName;
try { try {
decodedFileBaseName = decodeURIComponent(nsIURL.fileBaseName); decodeURIComponent(nsIURL.fileBaseName);
} }
catch (e) { catch (e) {
if (e.name == 'URIError') { if (e.name == 'URIError') {
// If we got a 'malformed URI sequence' while decoding, // If we got a 'malformed URI sequence' while decoding,
// try MD5 (in hex string) of fileBaseName. // use MD5 of fileBaseName
decodedFileBaseName = Zotero.Utilities.Internal.md5(nsIURL.fileBaseName, false); nsIURL.fileBaseName = Zotero.Utilities.Internal.md5(nsIURL.fileBaseName, false);
} }
else { else {
throw e; throw e;
} }
} }
// Pass unencoded name to getValidFileName() so that '%20' isn't stripped to '20' // Pass unencoded name to getValidFileName() so that percent-encoded
nsIURL.fileBaseName = Zotero.File.getValidFileName(decodedFileBaseName); // characters aren't stripped to just numbers
return Zotero.File.getValidFileName(decodeURIComponent(nsIURL.fileName));
return decodeURIComponent(nsIURL.fileName);
} }

View File

@ -102,7 +102,8 @@ Zotero.CookieSandbox.prototype = {
* @param {nsIInterfaceRequestor} ir * @param {nsIInterfaceRequestor} ir
*/ */
"attachToInterfaceRequestor": function(ir) { "attachToInterfaceRequestor": function(ir) {
Zotero.CookieSandbox.Observer.trackedInterfaceRequestors.set(ir.QueryInterface(Components.interfaces.nsIInterfaceRequestor), this); Zotero.CookieSandbox.Observer.trackedInterfaceRequestors.push(Components.utils.getWeakReference(ir.QueryInterface(Components.interfaces.nsIInterfaceRequestor)));
Zotero.CookieSandbox.Observer.trackedInterfaceRequestorSandboxes.push(this);
} }
} }
@ -125,7 +126,8 @@ Zotero.CookieSandbox.Observer = new function() {
*/ */
this.register = function(CookieSandbox) { this.register = function(CookieSandbox) {
this.trackedBrowsers = new WeakMap(); this.trackedBrowsers = new WeakMap();
this.trackedInterfaceRequestors = new WeakMap(); this.trackedInterfaceRequestors = [];
this.trackedInterfaceRequestorSandboxes = [];
if(!observing) { if(!observing) {
Zotero.debug("CookieSandbox: Registering observers"); Zotero.debug("CookieSandbox: Registering observers");
@ -145,7 +147,21 @@ Zotero.CookieSandbox.Observer = new function() {
// try the notification callbacks // try the notification callbacks
if(notificationCallbacks) { if(notificationCallbacks) {
trackedBy = this.trackedInterfaceRequestors.get(notificationCallbacks); for(var i=0; i<this.trackedInterfaceRequestors.length; i++) {
// Interface requestors are stored as weak references, so we have to see
// if they still point to something
var ir = this.trackedInterfaceRequestors[i].get();
if(!ir) {
// The interface requestor is gone, so remove it from the list
this.trackedInterfaceRequestors.splice(i--, 1);
this.trackedInterfaceRequestorSandboxes.splice(i--, 1);
} else if(ir == notificationCallbacks) {
// We are tracking this interface requestor
trackedBy = this.trackedInterfaceRequestorSandboxes[i];
break;
}
}
if(trackedBy) { if(trackedBy) {
tested = true; tested = true;
} else { } else {

View File

@ -38,6 +38,7 @@ Zotero.File = new function(){
this.getContentsFromURL = getContentsFromURL; this.getContentsFromURL = getContentsFromURL;
this.putContents = putContents; this.putContents = putContents;
this.getValidFileName = getValidFileName; this.getValidFileName = getValidFileName;
this.truncateFileName = truncateFileName;
this.copyToUnique = this.copyToUnique; this.copyToUnique = this.copyToUnique;
this.getCharsetFromFile = getCharsetFromFile; this.getCharsetFromFile = getCharsetFromFile;
this.addCharsetListener = addCharsetListener; this.addCharsetListener = addCharsetListener;
@ -280,7 +281,7 @@ Zotero.File = new function(){
// URL encode when saving attachments that trigger this // 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 // Replace newlines and tabs (which shouldn't be in the string in the first place) with spaces
fileName = fileName.replace(/[\n\t]/g, ' '); fileName = fileName.replace(/[\r\n\t]+/g, ' ');
// Replace various thin spaces // Replace various thin spaces
fileName = fileName.replace(/[\u2000-\u200A]/g, ' '); fileName = fileName.replace(/[\u2000-\u200A]/g, ' ');
// Replace zero-width spaces // Replace zero-width spaces
@ -289,13 +290,44 @@ Zotero.File = new function(){
// Strip characters not valid in XML, since they won't sync and they're probably unwanted // Strip characters not valid in XML, since they won't sync and they're probably unwanted
fileName = fileName.replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\ud800-\udfff\ufffe\uffff]/g, ''); fileName = fileName.replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\ud800-\udfff\ufffe\uffff]/g, '');
} }
// Don't allow blank filename // Don't allow blank or illegal filenames
if (!fileName) { if (!fileName || fileName == '.' || fileName == '..') {
fileName = '_'; fileName = '_';
} }
return fileName; return fileName;
} }
/**
* Truncate a filename (excluding the extension) to the given total length
* If the "extension" is longer than 20 characters,
* it is treated as part of the file name
*/
function truncateFileName(fileName, maxLength) {
if(!fileName || (fileName + '').length <= maxLength) return fileName;
var parts = (fileName + '').split(/\.(?=[^\.]+$)/);
var fn = parts[0];
var ext = parts[1];
//if the file starts with a period , use the whole file
//the whole file name might also just be a period
if(!fn) {
fn = '.' + (ext || '');
}
//treat long extensions as part of the file name
if(ext && ext.length > 20) {
fn += '.' + ext;
ext = undefined;
}
if(ext === undefined) { //there was no period in the whole file name
ext = '';
} else {
ext = '.' + ext;
}
return fn.substr(0,maxLength-ext.length) + ext;
}
/* /*
* Not implemented, but it'd sure be great if it were * Not implemented, but it'd sure be great if it were

View File

@ -185,7 +185,7 @@ Zotero.HTTP = new function() {
_stateChange(xmlhttp, onDone, responseCharset); _stateChange(xmlhttp, onDone, responseCharset);
}; };
if(cookieSandbox) cookieSandbox.attachToInterfaceRequestor(xmlhttp); if(cookieSandbox) cookieSandbox.attachToInterfaceRequestor(xmlhttp.getInterface(Components.interfaces.nsIInterfaceRequestor));
xmlhttp.send(null); xmlhttp.send(null);
return xmlhttp; return xmlhttp;
@ -273,7 +273,7 @@ Zotero.HTTP = new function() {
_stateChange(xmlhttp, onDone, responseCharset); _stateChange(xmlhttp, onDone, responseCharset);
}; };
if(cookieSandbox) cookieSandbox.attachToInterfaceRequestor(xmlhttp); if(cookieSandbox) cookieSandbox.attachToInterfaceRequestor(xmlhttp.getInterface(Components.interfaces.nsIInterfaceRequestor));
xmlhttp.send(body); xmlhttp.send(body);
return xmlhttp; return xmlhttp;
@ -337,7 +337,7 @@ Zotero.HTTP = new function() {
_stateChange(xmlhttp, onDone); _stateChange(xmlhttp, onDone);
}; };
if(cookieSandbox) cookieSandbox.attachToInterfaceRequestor(xmlhttp); if(cookieSandbox) cookieSandbox.attachToInterfaceRequestor(xmlhttp.getInterface(Components.interfaces.nsIInterfaceRequestor));
xmlhttp.send(null); xmlhttp.send(null);
return xmlhttp; return xmlhttp;

View File

@ -35,9 +35,8 @@ Zotero.Report = new function() {
function generateHTMLDetails(items, combineChildItems) { function generateHTMLDetails(items, combineChildItems) {
var content = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" '; var content = '<!DOCTYPE html>\n';
content += '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n'; content += '<html>\n';
content += '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">\n';
content += '<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" />\n'; content += '<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" />\n';
content += '<title>' + Zotero.getString('report.title.default') + '</title>\n'; content += '<title>' + Zotero.getString('report.title.default') + '</title>\n';
content += '<link rel="stylesheet" type="text/css" href="zotero://report/detail.css"/>\n'; content += '<link rel="stylesheet" type="text/css" href="zotero://report/detail.css"/>\n';
@ -74,8 +73,9 @@ Zotero.Report = new function() {
// If not valid XML, display notes with entities encoded // If not valid XML, display notes with entities encoded
var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"] var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"]
.createInstance(Components.interfaces.nsIDOMParser); .createInstance(Components.interfaces.nsIDOMParser);
var doc = parser.parseFromString(arr.note, "application/xml"); var doc = parser.parseFromString('<div>' + arr.note.replace(/&nbsp;/g, "&#160;") + '</div>', "application/xml");
if (doc.documentElement.tagName == 'parsererror') { if (doc.documentElement.tagName == 'parsererror') {
Zotero.debug(doc.documentElement.textContent, 2);
content += '<p class="plaintext">' + escapeXML(arr.note) + '</p>\n'; content += '<p class="plaintext">' + escapeXML(arr.note) + '</p>\n';
} }
// Otherwise render markup normally // Otherwise render markup normally
@ -100,8 +100,9 @@ Zotero.Report = new function() {
// If not valid XML, display notes with entities encoded // If not valid XML, display notes with entities encoded
var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"] var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"]
.createInstance(Components.interfaces.nsIDOMParser); .createInstance(Components.interfaces.nsIDOMParser);
var doc = parser.parseFromString(note.note, "application/xml"); var doc = parser.parseFromString('<div>' + note.note.replace(/&nbsp;/g, "&#160;") + '</div>', "application/xml");
if (doc.documentElement.tagName == 'parsererror') { if (doc.documentElement.tagName == 'parsererror') {
Zotero.debug(doc.documentElement.textContent, 2);
content += '<p class="plaintext">' + escapeXML(note.note) + '</p>\n'; content += '<p class="plaintext">' + escapeXML(note.note) + '</p>\n';
} }
// Otherwise render markup normally // Otherwise render markup normally

View File

@ -434,7 +434,7 @@ Zotero.Translate.SandboxManager = function(sandboxLocation) {
}; };
}; };
this.sandbox.XMLSerializer.__exposedProps__ = {"prototype":"r"}; this.sandbox.XMLSerializer.__exposedProps__ = {"prototype":"r"};
this.sandbox.XMLSerializer.prototype = {}; this.sandbox.XMLSerializer.prototype = {"__exposedProps__":{"serializeToString":"r"}};
} }
Zotero.Translate.SandboxManager.prototype = { Zotero.Translate.SandboxManager.prototype = {

View File

@ -35,7 +35,7 @@ const ZOTERO_CONFIG = {
API_URL: 'https://api.zotero.org/', API_URL: 'https://api.zotero.org/',
PREF_BRANCH: 'extensions.zotero.', PREF_BRANCH: 'extensions.zotero.',
BOOKMARKLET_URL: 'https://www.zotero.org/bookmarklet/', BOOKMARKLET_URL: 'https://www.zotero.org/bookmarklet/',
VERSION: "3.0.10.SOURCE" VERSION: "3.0.11.SOURCE"
}; };
// Commonly used imports accessible anywhere // Commonly used imports accessible anywhere

View File

@ -2652,22 +2652,25 @@ var ZoteroPane = new function()
} }
} }
else if (tree.id == 'zotero-items-tree') { else if (tree.id == 'zotero-items-tree') {
// Expand/collapse on triple-click var viewOnDoubleClick = Zotero.Prefs.get('viewOnDoubleClick');
if (!Zotero.Prefs.get('viewOnDoubleClick')) { if (viewOnDoubleClick) {
return; // Expand/collapse on triple-click, though the double-click
// will still trigger
if (event.detail == 3) {
tree.view.toggleOpenState(tree.view.selection.currentIndex);
return;
}
// Don't expand/collapse on double-click
event.stopPropagation();
} }
if (event.detail == 3) {
tree.view.toggleOpenState(tree.view.selection.currentIndex);
return;
}
// Don't expand/collapse on double-click
event.stopPropagation();
if (tree.view && tree.view.selection.currentIndex > -1) { if (tree.view && tree.view.selection.currentIndex > -1) {
var item = ZoteroPane_Local.getSelectedItems()[0]; var item = ZoteroPane_Local.getSelectedItems()[0];
if (item) { if (item) {
if (!viewOnDoubleClick && item.isRegularItem()) {
return;
}
ZoteroPane_Local.viewItems([item], event); ZoteroPane_Local.viewItems([item], event);
} }
} }

View File

@ -479,21 +479,7 @@ function ChromeExtensionHandler() {
default: default:
var content = Zotero.Report.generateHTMLDetails(items, combineChildItems); var content = Zotero.Report.generateHTMLDetails(items, combineChildItems);
mimeType = 'text/html';
// Serve invalid XML as text/html
//
// This is a temporary workaround until we figure out
// something better.
try {
var xml = new XML(content.replace(/^<\!DOCTYPE [^>]+>\n/, '').trim());
mimeType = 'application/xhtml+xml';
}
catch (e) {
Zotero.debug(e);
mimeType = 'text/html';
}
format = 'html';
} }
} }
catch (e){ catch (e){

View File

@ -6,11 +6,7 @@
<em:id>zotero@chnm.gmu.edu</em:id> <em:id>zotero@chnm.gmu.edu</em:id>
<em:name>Zotero</em:name> <em:name>Zotero</em:name>
<<<<<<< HEAD
<em:version>3.5a1.SOURCE</em:version> <em:version>3.5a1.SOURCE</em:version>
=======
<em:version>3.0.10.SOURCE</em:version>
>>>>>>> 3.0
<em:creator>Center for History and New Media<br/>George Mason University</em:creator> <em:creator>Center for History and New Media<br/>George Mason University</em:creator>
<em:contributor>Dan Cohen</em:contributor> <em:contributor>Dan Cohen</em:contributor>
<em:contributor>Sean Takats</em:contributor> <em:contributor>Sean Takats</em:contributor>

View File

@ -1 +1 @@
2012-11-18 22:15:00 2012-11-22 19:15:00

@ -1 +1 @@
Subproject commit 14794d840b2476cca38cbcd7f17d8c3952a4536d Subproject commit 2c33d5d461cab0749702529e26686738e7a0b411