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:
Dan Stillman 2006-12-07 13:39:30 +00:00
parent 507efb4758
commit 0d145cd47b
7 changed files with 87 additions and 44 deletions

View File

@ -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)

View File

@ -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">

View File

@ -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();

View File

@ -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);

View File

@ -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

View File

@ -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() {}
}

View File

@ -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">