1 OSM.downloadBlob = function (blob, filename) {
 
   2   const url = URL.createObjectURL(blob);
 
   3   const a = document.createElement("a");
 
   6   document.body.appendChild(a);
 
   8   document.body.removeChild(a);
 
   9   URL.revokeObjectURL(url);
 
  12 OSM.getTurboBlobHandler = function (filename) {
 
  13   function handleExportSuccess({ fetchResponse }) {
 
  14     fetchResponse.response.blob()
 
  15       .then(blob => OSM.downloadBlob(blob, filename))
 
  16       .catch(() => notifyExportFailure("(blob error)"));
 
  19   function handleExportError({ error, fetchResponse }) {
 
  22       fetchResponse.responseText.then(extractTextFromHTML)
 
  24       .then(notifyExportFailure)
 
  25       .catch(() => notifyExportFailure("(unknown)"));
 
  28   function extractTextFromHTML(htmlString) {
 
  29     const parser = new DOMParser();
 
  30     const doc = parser.parseFromString(htmlString, "text/html");
 
  31     return doc.body ? doc.body.textContent.trim() : "(unknown)";
 
  34   function notifyExportFailure(reason) {
 
  35     OSM.showAlert(OSM.i18n.t("javascripts.share.export_failed_title"), reason);
 
  38   return function ({ detail }) {
 
  40       handleExportSuccess(detail);
 
  42       handleExportError(detail);
 
  47 OSM.turboHtmlResponseHandler = function (event) {
 
  48   const response = event.detail.fetchResponse.response;
 
  49   const contentType = response.headers.get("content-type");
 
  50   if (!response.ok && contentType?.includes("text/html")) {
 
  51     // Prevent Turbo from replacing the current page with an error HTML response
 
  52     // from the export endpoint
 
  53     event.preventDefault();
 
  54     event.stopPropagation();
 
  58 OSM.displayLoadError = function (message, close) {
 
  59   $("#browse_status").html(
 
  60     $("<div class='p-3'>").append(
 
  61       $("<div class='d-flex'>").append(
 
  62         $("<h2 class='flex-grow-1 text-break'>")
 
  63           .text(OSM.i18n.t("browse.start_rjs.load_data")),
 
  65           $("<button type='button' class='btn-close'>")
 
  66             .attr("aria-label", OSM.i18n.t("javascripts.close"))
 
  67             .on("click", close))),
 
  68       $("<p class='alert alert-warning'>")
 
  69         .text(OSM.i18n.t("browse.start_rjs.feature_error", { message: message }))));