diff --git a/modules/deployment.xq b/modules/deployment.xq
index c8cad1cb..457bcd6f 100644
--- a/modules/deployment.xq
+++ b/modules/deployment.xq
@@ -585,12 +585,8 @@ declare function deploy:package($collection as xs:string, $expathConf as element
xmldb:store("/db/system/repo", $name, $xar, "application/zip")
};
-declare function deploy:download($collection as xs:string, $expathConf as element()?, $expand-xincludes as xs:boolean, $indent as xs:boolean, $omit-xml-declaration as xs:boolean) {
- let $name :=
- if ($expathConf) then
- concat($expathConf/@abbrev, "-", $expathConf/@version, ".xar")
- else
- replace($collection, "^.+/([^/]+)$", "$1") || ".zip"
+declare function deploy:download($collection as xs:string, $expathConf as element(), $expand-xincludes as xs:boolean, $indent as xs:boolean, $omit-xml-declaration as xs:boolean) {
+ let $name := concat($expathConf/@abbrev, "-", $expathConf/@version, ".xar")
let $entries :=
(: compression:zip uses default serialization parameters, so we'll construct entries manually :)
dbutil:scan(xs:anyURI($collection), function($coll as xs:anyURI, $res as xs:anyURI?) {
@@ -602,7 +598,6 @@ declare function deploy:download($collection as xs:string, $expathConf as elemen
{$res}
else
{
- (: workaround until https://github.com/eXist-db/exist/issues/2394 is resolved :)
util:declare-option(
"exist:serialize",
"expand-xincludes="
diff --git a/modules/load.xq b/modules/load.xq
index 36f77cb9..860f39e0 100644
--- a/modules/load.xq
+++ b/modules/load.xq
@@ -19,6 +19,7 @@
xquery version "3.0";
import module namespace config="http://exist-db.org/xquery/apps/config" at "config.xqm";
+import module namespace dbutil="http://exist-db.org/xquery/dbutil" at "dbutils.xqm";
declare function local:get-run-path($path) {
let $appRoot := repo:get-root()
@@ -34,43 +35,78 @@ declare function local:get-run-path($path) {
};
let $path := request:get-parameter("path", ())
-let $download := request:get-parameter("download", ())
+let $download := request:get-parameter("download", false()) cast as xs:boolean
let $indent := request:get-parameter("indent", true()) cast as xs:boolean
let $expand-xincludes := request:get-parameter("expand-xincludes", false()) cast as xs:boolean
let $omit-xml-declaration := request:get-parameter("omit-xml-decl", true()) cast as xs:boolean
-let $mime := xmldb:get-mime-type($path)
-let $isBinary := util:is-binary-doc($path)
+let $isBinary := util:binary-doc-available($path)
+let $isCollection := xmldb:collection-available($path)
+let $name := replace($path, "^.+/([^/]+)$", "$1")
(: Disable betterFORM filter :)
let $attribute := request:set-attribute("betterform.filter.ignoreResponseBody", "true")
-let $header := response:set-header("Content-Type", if ($mime) then $mime else "application/binary")
-let $header := response:set-header("X-Link", local:get-run-path($path))
-let $header2 :=
- if ($download) then
- response:set-header("Content-Disposition", concat("attachment; filename=", replace($path, "^.*/([^/]+)$", "$1")))
- else
- ()
return
- if (config:access-allowed($path, sm:id()//sm:real/sm:username/string())) then
- if ($isBinary) then
- let $data := util:binary-doc($path)
- return
- response:stream-binary($data, $mime, ())
+ if (config:access-allowed($path, sm:id()//sm:real/sm:username)) then
+ if ($isCollection and $download) then
+ let $entries :=
+ (: compression:zip uses default serialization parameters, so we'll construct entries manually :)
+ dbutil:scan(xs:anyURI($path), function($coll as xs:anyURI, $res as xs:anyURI?) {
+ (: compression:zip doesn't seem to store empty collections, so we'll scan for only resources :)
+ if (exists($res)) then
+ let $relative-path := $name || "/" || substring-after($res, $path || "/")
+ return
+ if (util:binary-doc-available($res)) then
+ {$res}
+ else
+ {
+ util:declare-option(
+ "exist:serialize",
+ "expand-xincludes="
+ || (if ($expand-xincludes) then "yes" else "no")
+ || " indent="
+ || (if ($indent) then "yes" else "no")
+ || " omit-xml-declaration="
+ || (if ($omit-xml-declaration) then "yes" else "no")
+ ),
+ doc($res)
+ }
+ else
+ ()
+ })
+ let $archive := compression:zip($entries, true())
+ let $archive-name := $name || ".zip"
+ return
+ (
+ response:set-header("Content-Disposition", concat("attachment; filename=", $archive-name)),
+ response:stream-binary($archive, "application/zip", $archive-name)
+ )
else
- if (doc-available($path)) then
+ let $mime := xmldb:get-mime-type($path)
+ let $headers :=
(
- (: workaround until https://github.com/eXist-db/exist/issues/2394 is resolved :)
- util:declare-option(
- "exist:serialize",
- "indent="
- || (if ($indent) then "yes" else "no")
- || " expand-xincludes="
+ response:set-header("Content-Type", if (exists($mime)) then $mime else "application/binary"),
+ response:set-header("X-Link", local:get-run-path($path)),
+ if ($download) then
+ response:set-header("Content-Disposition", concat("attachment; filename=", $name))
+ else
+ ()
+ )
+ return
+ if ($isBinary) then
+ let $data := util:binary-doc($path)
+ return
+ response:stream-binary($data, $mime, $name)
+ else
+ (
+ util:declare-option(
+ "exist:serialize",
+ "expand-xincludes="
|| (if ($expand-xincludes) then "yes" else "no")
+ || " indent="
+ || (if ($indent) then "yes" else "no")
|| " omit-xml-declaration="
|| (if ($omit-xml-declaration) then "yes" else "no")
- ),
- doc($path)
- )
- else
- response:set-status-code(404)
+ ),
+ doc($path)
+ )
else
response:set-status-code(404)
diff --git a/src/deployment.js b/src/deployment.js
index 7f529ea5..e5360c41 100644
--- a/src/deployment.js
+++ b/src/deployment.js
@@ -230,19 +230,7 @@ eXide.edit.PackageEditor = (function () {
var indentOnDownloadPackage = $("#indent-on-download-package").is(":checked");
var expandXIncludesOnDownloadPackage = $("#expand-xincludes-on-download-package").is(":checked");
var omitXMLDeclatarionOnDownloadPackage = $("#omit-xml-declaration-on-download-package").is(":checked");
- const url = "modules/deployment.xq?download=true&collection=" + encodeURIComponent(collection) + "&indent=" + indentOnDownloadPackage + "&expand-xincludes=" + expandXIncludesOnDownloadPackage + "&omit-xml-declaration=" + omitXMLDeclatarionOnDownloadPackage;
- fetch(url)
- .then(resp => resp.blob())
- .then(blob => {
- const url = window.URL.createObjectURL(blob);
- const a = document.createElement('a');
- a.style.display = 'none';
- a.href = url;
- a.download = decodeURI(collection.split("/").slice(-1)[0]);
- document.body.appendChild(a);
- a.click();
- window.URL.revokeObjectURL(url);
- })
+ window.location.href = "modules/deployment.xq?download=true&collection=" + encodeURIComponent(collection) + "&indent=" + indentOnDownloadPackage + "&expand-xincludes=" + expandXIncludesOnDownloadPackage + "&omit-xml-decl=" + omitXMLDeclatarionOnDownloadPackage;
};
/**
diff --git a/src/eXide.js b/src/eXide.js
index 1ea37762..0e427e17 100644
--- a/src/eXide.js
+++ b/src/eXide.js
@@ -290,19 +290,13 @@ eXide.app = (function(util) {
$("#open-dialog").dialog("close");
},
- downloadSelectedDocument: function(docs, close) {
- var resources = docs;
+ downloadSelectedResources: function(resources, close) {
if (resources) {
- resources.filter(res => res.isCollection).forEach(collection => {
- deploymentEditor.download(collection.key);
- });
-
- resources.filter(res => !res.isCollection).forEach(resource => {
+ resources.forEach(resource => {
app.download(resource.key);
})
-
}else {
- util.Dialog.warning("Invalid selection","The Download Selected command requires that resources be selected. Please select a resources for download.")
+ util.Dialog.warning("Invalid selection","The Download Selected command requires that resources be selected. Please select resources for download.")
}
if (close == undefined || close)
$("#open-dialog").dialog("close");
diff --git a/src/resources.js b/src/resources.js
index b5d401e5..c162a184 100644
--- a/src/resources.js
+++ b/src/resources.js
@@ -780,7 +780,7 @@ eXide.browse.Browser = (function () {
$(button).click(function (ev) {
ev.preventDefault();
const selected = $this.resources.getSelected();
- eXide.app.downloadSelectedDocument(selected, false);
+ eXide.app.downloadSelectedResources(selected, false);
});
this.btnCopy = createButton(toolbar, "Copy", "copy", 7, "copy");