Skip to content

Instantly share code, notes, and snippets.

@Infocatcher
Last active December 20, 2015 21:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Infocatcher/6201658 to your computer and use it in GitHub Desktop.
Save Infocatcher/6201658 to your computer and use it in GitHub Desktop.
Download with callback example for DragIt Firefox extension https://addons.mozilla.org/addon/dragit-formerly-drag-de-go/downloadSelectionWithCallback.js also works with Custom Buttons https://addons.mozilla.org/addon/custom-buttons/
// Download images from selection example for Custom Buttons or DragIt Firefox extension
// https://addons.mozilla.org/addon/custom-buttons/
// https://addons.mozilla.org/addon/dragit-formerly-drag-de-go/
// Options:
var program = "%ProgramFiles%\\XnView\\xnview.exe";
var args = []; // Additional arguments, paths to temp files will be added after them
var tmpFilePrefix = this && this instanceof XULElement && this.localName == "toolbarbutton" // Looks like Custom Buttons
? "cb_tmp"
: "DragIt_tmp";
var selection = document.commandDispatcher.focusedWindow.getSelection();
var sourceNodes = [];
for(var i = 0, l = selection.rangeCount; i < l; ++i) {
var range = selection.getRangeAt(i);
var doc = range.startContainer.ownerDocument;
var tmpNode = doc.createElementNS("http://www.w3.org/1999/xhtml", "div");
tmpNode.appendChild(range.cloneContents());
sourceNodes.push.apply(sourceNodes, tmpNode.getElementsByTagName("img"));
}
function openInProgram() {
program = expandEnvironmentVariables(program);
var exeFile = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile || Components.interfaces.nsIFile);
exeFile.initWithPath(program);
var process = Components.classes["@mozilla.org/process/util;1"]
.createInstance(Components.interfaces.nsIProcess);
process.init(exeFile);
if("runw" in process) // Gecko 2.0+
process.runw(false, args, args.length);
else
process.run(false, args, args.length);
}
function download(targetURL, sourceWindow) {
var persist = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
.createInstance(Components.interfaces.nsIWebBrowserPersist);
var fileName = targetURL.replace(/^.*\/|[?&#].*$/g, "");
if(fileName.length > 30)
fileName = fileName.substr(0, 15) + "_" + fileName.substr(-15);
var tmpFileName = tmpFilePrefix + (fileName ? "_" + fileName : "");
var tmpFile = Services.dirsvc.get("TmpD", Components.interfaces.nsIFile);
tmpFile.append(tmpFileName);
tmpFile.createUnique(tmpFile.NORMAL_FILE_TYPE, parseInt("0644", 8));
Components.classes["@mozilla.org/uriloader/external-helper-app-service;1"]
.getService(Components.interfaces.nsPIExternalAppLauncher)
.deleteTemporaryFileOnExit(tmpFile);
args.push(tmpFile.path);
var targetURI = Services.io.newURI(targetURL, null, null);
var privacyContext = "PrivateBrowsingUtils" in window
? PrivateBrowsingUtils.privacyContextFromWindow(sourceWindow)
: null;
var wpl = Components.interfaces.nsIWebProgressListener;
persist.progressListener = {
onStateChange: function(webProgress, request, stateFlags, status) {
if(!(stateFlags & wpl.STATE_STOP && stateFlags & wpl.STATE_IS_NETWORK))
return;
if(++done == count)
openInProgram();
},
onLocationChange: function(webProgress, request, uri, flags) {
},
onProgressChange: function(webProgress, request, curProgress, maxProgress, curTotalProgress, maxTotalProgress) {
},
onSecurityChange: function(webProgress, request, state) {
},
onStatusChange: function(webProgress, request, status, message) {
}
};
if(persist.saveURI.length <= 7)
persist.saveURI(targetURI, null, null, null, null, tmpFile, privacyContext);
else // Firefox 36+, see https://bugzilla.mozilla.org/show_bug.cgi?id=704320
persist.saveURI(targetURI, null, null, null, null, null, tmpFile, privacyContext);
}
function expandEnvironmentVariables(str) {
var env = Components.classes["@mozilla.org/process/environment;1"]
.getService(Components.interfaces.nsIEnvironment);
return str.replace(
/%([^%]+)%/g,
function(s, alias) {
return env.exists(alias) ? env.get(alias) : s;
}
);
}
// Should be after declaration of all functions to work in DragIt
var count = sourceNodes.length;
var done = 0;
sourceNodes.forEach(function(sourceNode) {
download(sourceNode.src, sourceNode.ownerDocument.defaultView);
});
// Download with callback example for DragIt Firefox extension
// https://addons.mozilla.org/addon/dragit-formerly-drag-de-go/
// Options:
var program = "%ProgramFiles%\\XnView\\xnview.exe";
var args = ["%f"]; // %f will be replaced with path to temp file
var tmpFilePrefix = "DragIt_tmp";
// Get source node (supported only images and links),
// correct this to work not only with DragIt
var sourceNode = DragIt.dndParams.Source;
var targetURL = sourceNode.src || sourceNode.href;
var sourceWindow = sourceNode.ownerDocument.defaultView;
var persist = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
.createInstance(Components.interfaces.nsIWebBrowserPersist);
var fileName = targetURL.replace(/^.*\/|[?&#].*$/g, "");
if(fileName.length > 30)
fileName = fileName.substr(0, 15) + "_" + fileName.substr(-15);
var tmpFileName = tmpFilePrefix + (fileName ? "_" + fileName : "");
var tmpFile = Services.dirsvc.get("TmpD", Components.interfaces.nsIFile);
tmpFile.append(tmpFileName);
tmpFile.createUnique(tmpFile.NORMAL_FILE_TYPE, parseInt("0644", 8));
Components.classes["@mozilla.org/uriloader/external-helper-app-service;1"]
.getService(Components.interfaces.nsPIExternalAppLauncher)
.deleteTemporaryFileOnExit(tmpFile);
var targetURI = Services.io.newURI(targetURL, null, null);
var privacyContext = "PrivateBrowsingUtils" in window
? PrivateBrowsingUtils.privacyContextFromWindow(sourceWindow)
: null;
function openInProgram() {
program = expandEnvironmentVariables(program);
args = args.map(function(arg) {
return arg == "%f"
? tmpFile.path
: arg.replace(/%f/g, '"' + tmpFile.path + '"');
});
var exeFile = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile || Components.interfaces.nsIFile);
exeFile.initWithPath(program);
var process = Components.classes["@mozilla.org/process/util;1"]
.createInstance(Components.interfaces.nsIProcess);
process.init(exeFile);
if("runw" in process) // Gecko 2.0+
process.runw(false, args, args.length);
else
process.run(false, args, args.length);
}
var wpl = Components.interfaces.nsIWebProgressListener;
persist.progressListener = {
onStateChange: function(webProgress, request, stateFlags, status) {
if(!(stateFlags & wpl.STATE_STOP && stateFlags & wpl.STATE_IS_NETWORK))
return;
openInProgram();
},
onLocationChange: function(webProgress, request, uri, flags) {
},
onProgressChange: function(webProgress, request, curProgress, maxProgress, curTotalProgress, maxTotalProgress) {
},
onSecurityChange: function(webProgress, request, state) {
},
onStatusChange: function(webProgress, request, status, message) {
}
};
if(persist.saveURI.length <= 7)
persist.saveURI(targetURI, null, null, null, null, tmpFile, privacyContext);
else // Firefox 36+, see https://bugzilla.mozilla.org/show_bug.cgi?id=704320
persist.saveURI(targetURI, null, null, null, null, null, tmpFile, privacyContext);
function expandEnvironmentVariables(str) {
var env = Components.classes["@mozilla.org/process/environment;1"]
.getService(Components.interfaces.nsIEnvironment);
return str.replace(
/%([^%]+)%/g,
function(s, alias) {
return env.exists(alias) ? env.get(alias) : s;
}
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment