Closes #416, Right-click to add attachment
Added "Save Link As Zotero Snapshot" and "Save Image As Zotero Snapshot" options to the browser content context menu where appropriate Other fixes: - Implemented standalone image and plugin snapshots the right way (as opposed to the fairly broken way from yesterday) - Only natively handled files are loaded into a hidden browser when using importFromURL() -- plugin files are now saved directly with saveURI() - indexDocument() doesn't try to index non-text files Notes: - There's no feedback when saving large files, which will likely be a bit confusing for users -- one option would be to put the transfer into the downloads window, though that's a little weird. - I suspect this will fix the reported JSTOR PDF download issue (http://forums.zotero.org/discussion/217/), though I don't currently have a way of testing it.
This commit is contained in:
parent
507efb4758
commit
0d145cd47b
|
@ -874,10 +874,35 @@ var ZoteroPane = new function()
|
|||
}
|
||||
}
|
||||
|
||||
var menuitem = document.getElementById("zotero-context-save-link-as-snapshot");
|
||||
if (menuitem) {
|
||||
if (window.gContextMenu.onLink) {
|
||||
menuitem.hidden = false;
|
||||
showing = true;
|
||||
}
|
||||
else {
|
||||
menuitem.hidden = true;
|
||||
}
|
||||
}
|
||||
|
||||
var menuitem = document.getElementById("zotero-context-save-image-as-snapshot");
|
||||
if (menuitem) {
|
||||
// Not using window.gContextMenu.hasBGImage -- if the user wants it,
|
||||
// they can use the Firefox option to view and then import from there
|
||||
if (window.gContextMenu.onImage) {
|
||||
menuitem.hidden = false;
|
||||
showing = true;
|
||||
}
|
||||
else {
|
||||
menuitem.hidden = true;
|
||||
}
|
||||
}
|
||||
|
||||
var separator = document.getElementById("zotero-context-separator");
|
||||
separator.hidden = !showing;
|
||||
}
|
||||
|
||||
|
||||
function newNote(popup, parent, text)
|
||||
{
|
||||
if (!popup)
|
||||
|
|
|
@ -52,6 +52,12 @@
|
|||
<menuitem id="zotero-context-add-to-new-note" class="menu-iconic"
|
||||
label="&zotero.contextMenu.addTextToNewNote;"
|
||||
oncommand="ZoteroPane.newNote(false, false, window.content.getSelection().toString())"/>
|
||||
<menuitem id="zotero-context-save-link-as-snapshot" class="menu-iconic"
|
||||
label="&zotero.contextMenu.saveLinkAsSnapshot;"
|
||||
oncommand="Zotero.Attachments.importFromURL(window.gContextMenu.linkURL)"/>
|
||||
<menuitem id="zotero-context-save-image-as-snapshot" class="menu-iconic"
|
||||
label="&zotero.contextMenu.saveImageAsSnapshot;"
|
||||
oncommand="Zotero.Attachments.importFromURL(window.gContextMenu.onImage ? window.gContextMenu.imageURL : window.gContextMenu.bgImageURL)"/>
|
||||
</popup>
|
||||
|
||||
<vbox id="appcontent">
|
||||
|
|
|
@ -178,9 +178,9 @@ Zotero.Attachments = new function(){
|
|||
nsIURL.spec = url;
|
||||
var ext = nsIURL.fileExtension;
|
||||
|
||||
// If we can load this internally, use a hidden browser (so we can
|
||||
// get the charset and title)
|
||||
if (Zotero.MIME.hasInternalHandler(mimeType, ext)){
|
||||
// If we can load this natively, use a hidden browser (so we can
|
||||
// get the charset and title and index the document)
|
||||
if (Zotero.MIME.hasNativeHandler(mimeType, ext)){
|
||||
var browser = Zotero.Browser.createHiddenBrowser();
|
||||
browser.addEventListener("pageshow", function(){
|
||||
Zotero.Attachments.importFromDocument(browser.contentDocument, sourceItemID);
|
||||
|
@ -254,7 +254,7 @@ Zotero.Attachments = new function(){
|
|||
// leaving the transaction open if the callback never triggers
|
||||
Zotero.DB.commitTransaction();
|
||||
|
||||
wbp.saveURI(nsIURL, null, null, null, null, file);
|
||||
wbp.saveURI(nsIURL, null, null, null, null, file);
|
||||
}
|
||||
catch (e){
|
||||
Zotero.DB.rollbackTransaction();
|
||||
|
@ -340,15 +340,17 @@ Zotero.Attachments = new function(){
|
|||
var title = forceTitle ? forceTitle : document.title;
|
||||
var mimeType = document.contentType;
|
||||
var charsetID = Zotero.CharacterSets.getID(document.characterSet);
|
||||
var hasNativeHandler = Zotero.MIME.hasNativeHandler(mimeType, _getExtensionFromURL(url))
|
||||
|
||||
// TODO: make this work -- with local plugin files, onStateChange in the
|
||||
// nsIWebBrowserPersist's nsIWebProgressListener never completes and
|
||||
// onProgressChange returns -1 for maxTotal, which prevents it from
|
||||
// triggering the callback.
|
||||
if (!hasNativeHandler && url.substr(0, 4) == 'file') {
|
||||
Zotero.debug('Import of loaded files from plugins is not supported');
|
||||
return false;
|
||||
if (!forceTitle) {
|
||||
// Remove e.g. " - Scaled (-17%)" from end of images saved from links,
|
||||
// though I'm not sure why it's getting added to begin with
|
||||
if (mimeType.indexOf('image/') === 0) {
|
||||
title = title.replace(/(.+ \([^,]+, [0-9]+x[0-9]+[^\)]+\)) - .+/, "$1" );
|
||||
}
|
||||
// If not native type, strip mime type data in parens
|
||||
else if (!Zotero.MIME.hasNativeHandler(mimeType, _getExtensionFromURL(url))) {
|
||||
title = title.replace(/(.+) \([a-z]+\/[^\)]+\)/, "$1" );
|
||||
}
|
||||
}
|
||||
|
||||
const nsIWBP = Components.interfaces.nsIWebBrowserPersist;
|
||||
|
@ -434,13 +436,23 @@ Zotero.Attachments = new function(){
|
|||
}
|
||||
|
||||
Zotero.Fulltext.indexDocument(document, itemID);
|
||||
}, !hasNativeHandler);
|
||||
});
|
||||
|
||||
// The attachment is still incomplete here, but we can't risk
|
||||
// leaving the transaction open if the callback never triggers
|
||||
Zotero.DB.commitTransaction();
|
||||
|
||||
wbp.saveDocument(document, file, destDir, mimeType, encodingFlags, false);
|
||||
if (Zotero.MIME.isDocumentType(mimeType)) {
|
||||
Zotero.debug('Saving with saveDocument()');
|
||||
wbp.saveDocument(document, file, destDir, mimeType, encodingFlags, false);
|
||||
}
|
||||
else {
|
||||
Zotero.debug('Saving with saveURI()');
|
||||
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
|
||||
.getService(Components.interfaces.nsIIOService);
|
||||
var nsIURL = ioService.newURI(url, null, null);
|
||||
wbp.saveURI(nsIURL, null, null, null, null, file);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.DB.rollbackTransaction();
|
||||
|
|
|
@ -159,6 +159,16 @@ Zotero.Fulltext = new function(){
|
|||
|
||||
Zotero.debug("Indexing document '" + document.title + "'");
|
||||
|
||||
if (document.contentType.indexOf('text/') !== 0) {
|
||||
Zotero.debug('File is not text in indexDocument()', 2);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!document.characterSet){
|
||||
Zotero.debug("Text file didn't have charset in indexFile()", 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
var text = document.body.innerHTML.replace(/(>)/g, '$1 ');
|
||||
text = HTMLToText(text);
|
||||
indexString(text, document.characterSet, itemID);
|
||||
|
|
|
@ -26,6 +26,7 @@ Zotero.MIME = new function(){
|
|||
this.sniffForBinary = sniffForBinary;
|
||||
this.getMIMETypeFromData = getMIMETypeFromData;
|
||||
this.getMIMETypeFromFile = getMIMETypeFromFile;
|
||||
this.isDocumentType = isDocumentType;
|
||||
this.hasNativeHandler = hasNativeHandler;
|
||||
this.hasInternalHandler = hasInternalHandler;
|
||||
this.fileHasInternalHandler = fileHasInternalHandler;
|
||||
|
@ -41,6 +42,14 @@ Zotero.MIME = new function(){
|
|||
["<?xml", 'text/xml']
|
||||
];
|
||||
|
||||
// MIME types to be saved as documents
|
||||
var _documentMIMETypes = {
|
||||
'text/html': true,
|
||||
'application/xhtml+xml': true,
|
||||
'text/xml': true,
|
||||
'application/xml': true
|
||||
};
|
||||
|
||||
// MIME types handled natively by Gecko
|
||||
// DEBUG: There's definitely a better way of getting these
|
||||
var _nativeMIMETypes = {
|
||||
|
@ -137,6 +146,11 @@ Zotero.MIME = new function(){
|
|||
}
|
||||
|
||||
|
||||
function isDocumentType(mimeType) {
|
||||
return _documentMIMETypes[mimeType] ? true : false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Determine if a MIME type can be handled natively
|
||||
* or if it needs to be passed off to a plugin or external helper app
|
||||
|
|
|
@ -1150,44 +1150,18 @@ Zotero.Browser = new function() {
|
|||
|
||||
/*
|
||||
* Implements nsIWebProgressListener
|
||||
*
|
||||
* For plugin content, onStateChange doesn't seem to be called after the document
|
||||
* finishes loading, so the useProgress flag can be used to run onFinish()
|
||||
* when all the content of the request has been loaded -- this should only be
|
||||
* used for single file requests (generally, things handled by plugins)
|
||||
*/
|
||||
Zotero.WebProgressFinishListener = function(onFinish, useProgress, wbp) {
|
||||
var _finished = false;
|
||||
|
||||
Zotero.WebProgressFinishListener = function(onFinish) {
|
||||
this.onStateChange = function(wp, req, stateFlags, status) {
|
||||
//Zotero.debug('onStageChange: ' + stateFlags);
|
||||
if ((stateFlags & Components.interfaces.nsIWebProgressListener.STATE_STOP)
|
||||
&& (stateFlags & Components.interfaces.nsIWebProgressListener.STATE_IS_NETWORK)) {
|
||||
if (useProgress) {
|
||||
Zotero.debug('WebProgressFinishListener: useProgress set but STOP_STOP and STATE_IS_NETWORK were reached', 2);
|
||||
if (_finished) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
_finished = true;
|
||||
}
|
||||
}
|
||||
onFinish();
|
||||
}
|
||||
}
|
||||
|
||||
this.onLocationChange = function() {}
|
||||
|
||||
this.onProgressChange = function(wp, req, cur, max, curTotal, maxTotal) {
|
||||
// DEBUG: This will never complete if the file size (maxTotal) isn't
|
||||
// available, which seems to be the case with local files and is
|
||||
// presumably the case with remote servers that don't send the file size.
|
||||
//Zotero.debug('Current total: ' + curTotal + ' Max total: ' + maxTotal);
|
||||
if (!_finished && useProgress && (curTotal == maxTotal)) {
|
||||
_finished = true;
|
||||
onFinish();
|
||||
}
|
||||
}
|
||||
|
||||
this.onProgressChange = function() {}
|
||||
this.onSecurityChange = function() {}
|
||||
this.onStatusChange = function(wp, req, st, msg) {}
|
||||
this.onStatusChange = function() {}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
<!ENTITY zotero.contextMenu.addTextToCurrentNote "Add Selection to Zotero Note">
|
||||
<!ENTITY zotero.contextMenu.addTextToNewNote "Create Zotero Note from Selection">
|
||||
<!ENTITY zotero.contextMenu.saveLinkAsSnapshot "Save Link As Zotero Snapshot">
|
||||
<!ENTITY zotero.contextMenu.saveImageAsSnapshot "Save Image As Zotero Snapshot">
|
||||
|
||||
<!ENTITY zotero.tabs.info.label "Info">
|
||||
<!ENTITY zotero.tabs.notes.label "Notes">
|
||||
|
|
Loading…
Reference in New Issue
Block a user