Address silent failure of unrecognized URIs in Attach Link to URI
Generated files for a more robust attached-link-dialog and localized strings * AttachLink.js * AttachLink.xul zotero/xpcom/attachments.js * created function cleanAttachmentURI * in function linkFromURL, removed the regex constraints and the comment list of valid protocols * removed outdated function declaration from beginning of script * Improved automatic title generation mechanism
This commit is contained in:
		
					parent
					
						
							
								67f28eada3
							
						
					
				
			
			
				commit
				
					
						849803473a
					
				
			
		
					 9 changed files with 232 additions and 73 deletions
				
			
		
							
								
								
									
										60
									
								
								chrome/content/zotero/attachLink.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								chrome/content/zotero/attachLink.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,60 @@
 | 
			
		|||
/*
 | 
			
		||||
    ***** BEGIN LICENSE BLOCK *****
 | 
			
		||||
    
 | 
			
		||||
    Copyright © 2014 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 *****
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
var Zotero_AttachLink = new function() {
 | 
			
		||||
	function getAttachFileLabel() {
 | 
			
		||||
		return window.opener.document
 | 
			
		||||
			.getElementById('zotero-tb-attachment-add-file-link')
 | 
			
		||||
			.label;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	this.submit = function() {
 | 
			
		||||
		var link = document.getElementById('zotero-attach-uri-input').value;
 | 
			
		||||
		var message = document.getElementById('zotero-attach-uri-message');
 | 
			
		||||
		var cleanURI = Zotero.Attachments.cleanAttachmentURI(link, true);
 | 
			
		||||
		
 | 
			
		||||
		if (!cleanURI) {
 | 
			
		||||
			message.textContent = Zotero.getString('pane.items.attach.link.uri.unrecognized');
 | 
			
		||||
			window.sizeToContent();
 | 
			
		||||
			document.getElementById('zotero-attach-uri-input').select();
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		// Don't allow "file:" links, because using "Attach link to file" is the right way
 | 
			
		||||
		else if (cleanURI.toLowerCase().indexOf('file:') == 0) {
 | 
			
		||||
			message.textContent = Zotero.getString('pane.items.attach.link.uri.file',
 | 
			
		||||
				[getAttachFileLabel()]);
 | 
			
		||||
			window.sizeToContent();
 | 
			
		||||
			document.getElementById('zotero-attach-uri-input').select();
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			window.arguments[0].out = {
 | 
			
		||||
				link:	cleanURI,
 | 
			
		||||
				title:	document.getElementById('zotero-attach-uri-title').value
 | 
			
		||||
			};
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										32
									
								
								chrome/content/zotero/attachLink.xul
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								chrome/content/zotero/attachLink.xul
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,32 @@
 | 
			
		|||
<?xml version="1.0"?>
 | 
			
		||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
 | 
			
		||||
<?xml-stylesheet href="chrome://zotero/skin/zotero.css" type="text/css"?>
 | 
			
		||||
 | 
			
		||||
<!DOCTYPE window SYSTEM "chrome://zotero/locale/zotero.dtd">
 | 
			
		||||
 | 
			
		||||
<dialog
 | 
			
		||||
	xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
 | 
			
		||||
	buttons="accept,cancel"
 | 
			
		||||
	ondialogaccept="return Zotero_AttachLink.submit();"
 | 
			
		||||
	
 | 
			
		||||
	id="zotero-attach-uri-dialog"
 | 
			
		||||
	title="&zotero.attachLink.title;"
 | 
			
		||||
	>
 | 
			
		||||
	
 | 
			
		||||
	<script src="include.js"/>
 | 
			
		||||
	<script src="AttachLink.js"/>
 | 
			
		||||
	
 | 
			
		||||
	<vbox id="zotero-attach-uri-container">
 | 
			
		||||
		<hbox>
 | 
			
		||||
			<description id="zotero-attach-uri-message" class="zotero-message-error"></description>
 | 
			
		||||
		</hbox>
 | 
			
		||||
		<hbox align="center">
 | 
			
		||||
			<label id="zotero-attach-uri-label-input" value="&zotero.attachLink.label.link;" control="zotero-attach-uri-input"></label>
 | 
			
		||||
			<textbox id="zotero-attach-uri-input" flex="1"/>
 | 
			
		||||
		</hbox>
 | 
			
		||||
		<hbox align="center">
 | 
			
		||||
			<label id="zotero-attach-uri-label-title" value="&zotero.attachLink.label.title;" control="zotero-attach-uri-title"></label>
 | 
			
		||||
			<textbox id="zotero-attach-uri-title" flex="1" placeholder="&zotero.general.optional;"/>
 | 
			
		||||
		</hbox>
 | 
			
		||||
	</vbox>
 | 
			
		||||
</dialog>
 | 
			
		||||
| 
						 | 
				
			
			@ -34,7 +34,6 @@ Zotero.Attachments = new function(){
 | 
			
		|||
	this.linkFromFile = linkFromFile;
 | 
			
		||||
	this.importSnapshotFromFile = importSnapshotFromFile;
 | 
			
		||||
	this.importFromURL = importFromURL;
 | 
			
		||||
	this.linkFromURL = linkFromURL;
 | 
			
		||||
	this.linkFromDocument = linkFromDocument;
 | 
			
		||||
	this.importFromDocument = importFromDocument;
 | 
			
		||||
	this.createMissingAttachment = createMissingAttachment;
 | 
			
		||||
| 
						 | 
				
			
			@ -399,38 +398,68 @@ Zotero.Attachments = new function(){
 | 
			
		|||
	}
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	this.cleanAttachmentURI = function (uri, tryHttp) {
 | 
			
		||||
		uri = uri.trim();
 | 
			
		||||
		if (!uri) return false;
 | 
			
		||||
		
 | 
			
		||||
		var ios = Components.classes["@mozilla.org/network/io-service;1"]
 | 
			
		||||
			.getService(Components.interfaces.nsIIOService);
 | 
			
		||||
		try {
 | 
			
		||||
			return ios.newURI(uri, null, null).spec // Valid URI if succeeds
 | 
			
		||||
		} catch (e) {
 | 
			
		||||
			if (e instanceof Components.Exception
 | 
			
		||||
				&& e.result == Components.results.NS_ERROR_MALFORMED_URI
 | 
			
		||||
			) {
 | 
			
		||||
				if (tryHttp && /\w\.\w/.test(uri)) {
 | 
			
		||||
					// Assume it's a URL missing "http://" part
 | 
			
		||||
					try {
 | 
			
		||||
						return ios.newURI('http://' + uri, null, null).spec;
 | 
			
		||||
					} catch (e) {}
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				Zotero.debug('cleanAttachmentURI: Invalid URI: ' + uri, 2);
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
			throw e;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	/*
 | 
			
		||||
	 * Create a link attachment from a URL
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param	{String}		url
 | 
			
		||||
	 * @param	{String}		url Validated URI
 | 
			
		||||
	 * @param	{Integer}		sourceItemID	Parent item
 | 
			
		||||
	 * @param	{String}		[mimeType]		MIME type of page
 | 
			
		||||
	 * @param	{String}		[title]			Title to use for attachment
 | 
			
		||||
	 */
 | 
			
		||||
	function linkFromURL(url, sourceItemID, mimeType, title){
 | 
			
		||||
		Zotero.debug('Linking attachment from URL');
 | 
			
		||||
	    
 | 
			
		||||
		/* Throw error on invalid URLs
 | 
			
		||||
		   We currently accept the following protocols:
 | 
			
		||||
		   PersonalBrain (brain://)
 | 
			
		||||
		   DevonThink (x-devonthink-item://)
 | 
			
		||||
		   Notational Velocity (nv://)
 | 
			
		||||
		   MyLife Organized (mlo://)
 | 
			
		||||
		   Evernote (evernote://)
 | 
			
		||||
		   OneNote (onenote://)
 | 
			
		||||
		   Kindle (kindle://) 
 | 
			
		||||
		   Logos (logosres:) 
 | 
			
		||||
		   Zotero (zotero://) */
 | 
			
		||||
 | 
			
		||||
		var urlRe = /^((https?|zotero|evernote|onenote|brain|nv|mlo|kindle|x-devonthink-item|ftp):\/\/|logosres:)[^\s]*$/;
 | 
			
		||||
		var matches = urlRe.exec(url);
 | 
			
		||||
		if (!matches) {
 | 
			
		||||
			throw ("Invalid URL '" + url + "' in Zotero.Attachments.linkFromURL()");
 | 
			
		||||
		}
 | 
			
		||||
	this.linkFromURL = function (url, sourceItemID, mimeType, title) {
 | 
			
		||||
		Zotero.debug('Linking attachment from ' + url);
 | 
			
		||||
		
 | 
			
		||||
		// If no title provided, figure it out from the URL
 | 
			
		||||
		if (!title){
 | 
			
		||||
			title = url.substring(url.lastIndexOf('/')+1);
 | 
			
		||||
		// Web addresses with paths will be whittled to the last element
 | 
			
		||||
		// excluding references and queries. All others are the full string
 | 
			
		||||
		if (!title) {
 | 
			
		||||
			var ioService = Components.classes["@mozilla.org/network/io-service;1"]
 | 
			
		||||
				.getService(Components.interfaces.nsIIOService);
 | 
			
		||||
			var titleURL = ioService.newURI(url, null, null);
 | 
			
		||||
 | 
			
		||||
			if (titleURL.scheme == 'http' || titleURL.scheme == 'https') {
 | 
			
		||||
				titleURL = titleURL.QueryInterface(Components.interfaces.nsIURL);
 | 
			
		||||
				if (titleURL.path == '/') {
 | 
			
		||||
					title = titleURL.host;
 | 
			
		||||
				}
 | 
			
		||||
				else if (titleURL.fileName) {
 | 
			
		||||
					title = titleURL.fileName;
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					var dir = titleURL.directory.split('/');
 | 
			
		||||
					title = dir[dir.length - 2];
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				title = url;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// Override MIME type to application/pdf if extension is .pdf --
 | 
			
		||||
| 
						 | 
				
			
			@ -446,7 +475,6 @@ Zotero.Attachments = new function(){
 | 
			
		|||
		return itemID;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	// TODO: what if called on file:// document?
 | 
			
		||||
	function linkFromDocument(document, sourceItemID, parentCollectionIDs){
 | 
			
		||||
		Zotero.debug('Linking attachment from document');
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -217,29 +217,42 @@ Zotero.Translate.ItemSaver.prototype = {
 | 
			
		|||
	},
 | 
			
		||||
	
 | 
			
		||||
	"_saveAttachmentFile":function(attachment, parentID, attachmentCallback) {
 | 
			
		||||
		const urlRe = /(([a-z][-+\.a-z0-9]*):\/\/[^\s]*)/i; //according to RFC3986
 | 
			
		||||
		Zotero.debug("Translate: Adding attachment", 4);
 | 
			
		||||
			
 | 
			
		||||
		if(!attachment.url && !attachment.path) {
 | 
			
		||||
			Zotero.debug("Translate: Ignoring attachment: no path or URL specified", 2);
 | 
			
		||||
			let e = "Translate: Ignoring attachment: no path or URL specified";
 | 
			
		||||
			Zotero.debug(e, 2);
 | 
			
		||||
			attachmentCallback(attachment, false, e);
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if(!attachment.path) {
 | 
			
		||||
			let url = Zotero.Attachments.cleanAttachmentURI(attachment.url);
 | 
			
		||||
			if (!url) {
 | 
			
		||||
				let e = "Translate: Invalid attachment URL specified <" + attachment.url + ">";
 | 
			
		||||
				Zotero.debug(e, 2);
 | 
			
		||||
				attachmentCallback(attachment, false, e);
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
			attachment.url = url;
 | 
			
		||||
			url = Components.classes["@mozilla.org/network/io-service;1"]
 | 
			
		||||
				.getService(Components.interfaces.nsIIOService)
 | 
			
		||||
				.newURI(url, null, null); // This cannot fail, since we check above
 | 
			
		||||
			
 | 
			
		||||
			// see if this is actually a file URL
 | 
			
		||||
			var m = urlRe.exec(attachment.url);
 | 
			
		||||
			var protocol = m ? m[2].toLowerCase() : "file";
 | 
			
		||||
			if(protocol == "file") {
 | 
			
		||||
			if(url.scheme == "file") {
 | 
			
		||||
				attachment.path = attachment.url;
 | 
			
		||||
				attachment.url = false;
 | 
			
		||||
			} else if(protocol != "http" && protocol != "https") {
 | 
			
		||||
				Zotero.debug("Translate: Unrecognized protocol "+protocol, 2);
 | 
			
		||||
			} else if(url.scheme != "http" && url.scheme != "https") {
 | 
			
		||||
				let e = "Translate: " + url.scheme + " protocol is not allowed for attachments from translators.";
 | 
			
		||||
				Zotero.debug(e, 2);
 | 
			
		||||
				attachmentCallback(attachment, false, e);
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if(!attachment.path) {
 | 
			
		||||
			// create from URL
 | 
			
		||||
			// At this point, must be a valid HTTP/HTTPS url
 | 
			
		||||
			attachment.linkMode = "linked_file";
 | 
			
		||||
			try {
 | 
			
		||||
				var myID = Zotero.Attachments.linkFromURL(attachment.url, parentID,
 | 
			
		||||
| 
						 | 
				
			
			@ -412,33 +425,43 @@ Zotero.Translate.ItemSaver.prototype = {
 | 
			
		|||
			if(attachment.snapshot === false || !this._saveFiles) {
 | 
			
		||||
				// if snapshot is explicitly set to false, attach as link
 | 
			
		||||
				attachment.linkMode = "linked_url";
 | 
			
		||||
				let url, mimeType;
 | 
			
		||||
				if(attachment.document) {
 | 
			
		||||
					try {
 | 
			
		||||
						Zotero.Attachments.linkFromURL(attachment.document.location.href, parentID,
 | 
			
		||||
								(attachment.mimeType ? attachment.mimeType : attachment.document.contentType),
 | 
			
		||||
								title);
 | 
			
		||||
						attachmentCallback(attachment, 100);
 | 
			
		||||
					} catch(e) {
 | 
			
		||||
						Zotero.debug("Translate: Error adding attachment "+attachment.url, 2);
 | 
			
		||||
						attachmentCallback(attachment, false, e);
 | 
			
		||||
					}
 | 
			
		||||
					return true;
 | 
			
		||||
					url = attachment.document.location.href;
 | 
			
		||||
					mimeType = attachment.mimeType ? attachment.mimeType : attachment.document.contentType;
 | 
			
		||||
				} else {
 | 
			
		||||
					if(!attachment.mimeType || !title) {
 | 
			
		||||
						Zotero.debug("Translate: Either mimeType or title is missing; attaching file will be slower", 3);
 | 
			
		||||
					}
 | 
			
		||||
					
 | 
			
		||||
					try {
 | 
			
		||||
						Zotero.Attachments.linkFromURL(attachment.url, parentID,
 | 
			
		||||
								(attachment.mimeType ? attachment.mimeType : undefined),
 | 
			
		||||
								title);
 | 
			
		||||
						attachmentCallback(attachment, 100);
 | 
			
		||||
					} catch(e) {
 | 
			
		||||
						Zotero.debug("Translate: Error adding attachment "+attachment.url, 2);
 | 
			
		||||
						attachmentCallback(attachment, false, e);
 | 
			
		||||
					}
 | 
			
		||||
					return true;
 | 
			
		||||
					url = attachment.url
 | 
			
		||||
					mimeType = attachment.mimeType ? attachment.mimeType : undefined;
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				let cleanURI = Zotero.Attachments.cleanAttachmentURI(url);
 | 
			
		||||
				if (!cleanURI) {
 | 
			
		||||
					let e = "Translate: Invalid attachment URL specified <" + url + ">";
 | 
			
		||||
					Zotero.debug(e, 2);
 | 
			
		||||
					attachmentCallback(attachment, false, e);
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
				url = Components.classes["@mozilla.org/network/io-service;1"]
 | 
			
		||||
					.getService(Components.interfaces.nsIIOService)
 | 
			
		||||
					.newURI(cleanURI, null, null); // This cannot fail, since we check above
 | 
			
		||||
				
 | 
			
		||||
				// Only HTTP/HTTPS links are allowed
 | 
			
		||||
				if(url.scheme != "http" && url.scheme != "https") {
 | 
			
		||||
					let e = "Translate: " + url.scheme + " protocol is not allowed for attachments from translators.";
 | 
			
		||||
					Zotero.debug(e, 2);
 | 
			
		||||
					attachmentCallback(attachment, false, e);
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				try {
 | 
			
		||||
					Zotero.Attachments.linkFromURL(cleanURI, parentID, mimeType, title);
 | 
			
		||||
					attachmentCallback(attachment, 100);
 | 
			
		||||
				} catch(e) {
 | 
			
		||||
					Zotero.debug("Translate: Error adding attachment "+attachment.url, 2);
 | 
			
		||||
					attachmentCallback(attachment, false, e);
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
				return true;
 | 
			
		||||
			} else {
 | 
			
		||||
				// if snapshot is not explicitly set to false, retrieve snapshot
 | 
			
		||||
				if(attachment.document) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3038,19 +3038,13 @@ var ZoteroPane = new function()
 | 
			
		|||
			this.displayCannotEditLibraryMessage();
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
 | 
			
		||||
					.getService(Components.interfaces.nsIPromptService);
 | 
			
		||||
		
 | 
			
		||||
		var input = {};
 | 
			
		||||
		var check = {value : false};
 | 
			
		||||
		
 | 
			
		||||
		// TODO: Allow title to be specified?
 | 
			
		||||
		var result = ps.prompt(null, Zotero.getString('pane.items.attach.link.uri.title'),
 | 
			
		||||
			Zotero.getString('pane.items.attach.link.uri'), input, "", {});
 | 
			
		||||
		if (!result || !input.value) return false;
 | 
			
		||||
		
 | 
			
		||||
		// Create a new attachment
 | 
			
		||||
		Zotero.Attachments.linkFromURL(input.value, itemID);
 | 
			
		||||
		var io = {};
 | 
			
		||||
		window.openDialog('chrome://zotero/content/attachLink.xul', 
 | 
			
		||||
			'zotero-attach-uri-dialog', 'centerscreen, modal', io);
 | 
			
		||||
		if (io.out) {
 | 
			
		||||
			Zotero.Attachments.linkFromURL(io.out.link, itemID, null, io.out.title);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -174,7 +174,7 @@
 | 
			
		|||
							<menuitem class="menuitem-iconic zotero-menuitem-attachments-web-link standalone-no-display" label="&zotero.items.menu.attach.link;" oncommand="var itemID = ZoteroPane_Local.getSelectedItems()[0].id; ZoteroPane_Local.addAttachmentFromPage(true, itemID)"/>
 | 
			
		||||
							<menuitem class="menuitem-iconic zotero-menuitem-attachments-web-link" label="&zotero.items.menu.attach.link.uri;" oncommand="var itemID = ZoteroPane_Local.getSelectedItems()[0].id; ZoteroPane_Local.addAttachmentFromURI(true, itemID);"/>
 | 
			
		||||
							<menuitem class="menuitem-iconic zotero-menuitem-attachments-file" label="&zotero.items.menu.attach.file;" oncommand="var itemID = ZoteroPane_Local.getSelectedItems()[0].id; ZoteroPane_Local.addAttachmentFromDialog(false, itemID);"/>
 | 
			
		||||
							<menuitem class="menuitem-iconic zotero-menuitem-attachments-link" label="&zotero.items.menu.attach.fileLink;" oncommand="var itemID = ZoteroPane_Local.getSelectedItems()[0].id; ZoteroPane_Local.addAttachmentFromDialog(true, itemID);"/>
 | 
			
		||||
							<menuitem class="menuitem-iconic zotero-menuitem-attachments-link" label="&zotero.items.menu.attach.fileLink;" oncommand="var itemID = ZoteroPane_Local.getSelectedItems()[0].id; ZoteroPane_Local.addAttachmentFromDialog(true, itemID);" id="zotero-tb-attachment-add-file-link"/>
 | 
			
		||||
						</menupopup>
 | 
			
		||||
					</toolbarbutton>
 | 
			
		||||
					<toolbarseparator/>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -283,4 +283,10 @@
 | 
			
		|||
 | 
			
		||||
<!ENTITY zotero.downloadManager.label			"Save to Zotero">
 | 
			
		||||
<!ENTITY zotero.downloadManager.saveToLibrary.description	"Attachments cannot be saved to the currently selected library. This item will be saved to your library instead.">
 | 
			
		||||
<!ENTITY zotero.downloadManager.noPDFTools.description	"To use this feature, you must first install the PDF tools in the Search pane of the Zotero preferences.">
 | 
			
		||||
<!ENTITY zotero.downloadManager.noPDFTools.description	"To use this feature, you must first install the PDF tools in the Search pane of the Zotero preferences.">
 | 
			
		||||
 | 
			
		||||
<!ENTITY zotero.attachLink.title                     "Attach Link to URI">
 | 
			
		||||
<!ENTITY zotero.attachLink.label.link                "Link:">
 | 
			
		||||
<!ENTITY zotero.attachLink.label.title               "Title:">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -195,8 +195,8 @@ tagColorChooser.maxTags                        = Up to %S tags in each library c
 | 
			
		|||
pane.items.loading				= Loading items list…
 | 
			
		||||
pane.items.columnChooser.moreColumns = More Columns
 | 
			
		||||
pane.items.columnChooser.secondarySort = Secondary Sort (%S)
 | 
			
		||||
pane.items.attach.link.uri.title	 	= Attach Link to URI
 | 
			
		||||
pane.items.attach.link.uri		= Enter a URI:
 | 
			
		||||
pane.items.attach.link.uri.unrecognized	      = Zotero did not recognize the URI you entered. Please check the address and try again.
 | 
			
		||||
pane.items.attach.link.uri.file               = To attach a link to a file, please use “%S”.
 | 
			
		||||
pane.items.trash.title			= Move to Trash
 | 
			
		||||
pane.items.trash				= Are you sure you want to move the selected item to the Trash?
 | 
			
		||||
pane.items.trash.multiple		= Are you sure you want to move the selected items to the Trash?
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -242,6 +242,10 @@ label.zotero-text-link {
 | 
			
		|||
	background: rgb(89, 139, 236);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.zotero-message-error
 | 
			
		||||
{
 | 
			
		||||
	font-weight: bold;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#zotero-progress-box
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -354,4 +358,16 @@ label.zotero-text-link {
 | 
			
		|||
#zotero-advanced-search-dialog #zotero-search-buttons
 | 
			
		||||
{
 | 
			
		||||
	margin: 3px 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#zotero-attach-uri-container
 | 
			
		||||
{
 | 
			
		||||
	width: 30em;
 | 
			
		||||
	max-width: 30em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#zotero-attach-uri-message
 | 
			
		||||
{
 | 
			
		||||
	width: 29.5em;
 | 
			
		||||
	max-width: 29.5em;
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue