commit b7e9b40e32e7eec1c6cabc33bdc403c1f5f66eba
parent 35bee36cb9f2e46d182189574c9afa87cad4ac3f
Author: Luxferre <lux@ferre>
Date:   Sat, 25 Mar 2023 18:52:38 +0200
fixed blob loading
Diffstat:
3 files changed, 32 insertions(+), 35 deletions(-)
diff --git a/js/app.js b/js/app.js
@@ -27,21 +27,15 @@ function openURL(url, successCb, errorCb) {
     if(resource.length > 4) input = resource[4]
     Hi01379.load(resource, input, function(res) {
       if(res.content && res.content instanceof Blob) { // handle the download here
-        var opener = new MozActivity({name: 'open', data: {type: res.contentType, blob: res.content, filename: res.contentName}})
-        opener.onsuccess = function() {
-          successCb({content: null, serviceMsg: 'Opening a downloaded file ' + contentName, updateAddr: false})
-        }
-        opener.onerror = errorCb
+        successCb({content: null, serviceMsg: 'Opening a downloaded file ' + res.contentName, updateAddr: false})
+        window.open(URL.createObjectURL(res.content))
       }
       else successCb(res) // proceed to UI with non-downloads
     }, errorCb)
   }
   else { // handle non-Gopher URLs with the Web Activities
     var opener = new MozActivity({name: 'view', data: {type: 'url', url: url}})
-    opener.onsuccess = function() {
-      successCb({content: null, serviceMsg: 'Opening an external resource ' + url, updateAddr: false})
-    }
-    opener.onerror = errorCb
+    successCb({content: null, serviceMsg: 'Opening an external resource ' + url, updateAddr: false})
   }
 }
 
diff --git a/js/hi01379.js b/js/hi01379.js
@@ -64,33 +64,31 @@ Hi01379 = (function(psGopherRequest) {
 
   // resource format: [type, selector, host, port]
   function loadHole(resource, input, successCb, errorCb) {
+    var fname = resource[1].split('/').pop(), // as the most intelligent guess
+        ext = fname.split('.').pop().toLowerCase(), // presumed extension
+        extMappings = { // not including AVIF here because they aren't supported by Gecko 48 anyway
+          'gif': 'image/gif', // including GIF though because nothing prevents using I instead of g
+          'png': 'image/png',
+          'svg': 'image/svg+xml',
+          'webp': 'image/webp',
+          'apng': 'image/apng',
+          'jpg': 'image/jpeg',
+          'jpeg': 'image/jpeg',
+          'jfif': 'image/jpeg',
+          'pjpeg': 'image/jpeg',
+          'pjp': 'image/jpeg'
+        }
     psGopherRequest(resource, input, function(rawdata, type) {
       if(type == '5' || type == 's' || type == ';' || type == 'd')
         type = '9' // remap unknown binary types to 9
       if(type == '9' || type == 'g' || type == 'I') { // binary file
         var ctype = 'application/octet-stream' // the default one if everything else fails
-        var datablob = new Blob([rawdata], {type: ctype}),
-            fname = resource[1].split('/').pop() // as the most intelligent guess
         // update content type
         if(type == 'g') // GIF-only resource type
           ctype = 'image/gif'
-        else if(type == 'I') { // attempt to guess the image MIME type by the extension
-          var ext = fname.split('.').pop().toLowerCase(),
-              extMappings = { // not including AVIF here because they aren't supported by Gecko 48 anyway
-                'gif': 'image/gif', // including GIF though because nothing prevents using I instead of g
-                'png': 'image/png',
-                'svg': 'image/svg+xml',
-                'webp': 'image/webp',
-                'apng': 'image/apng',
-                'jpg': 'image/jpeg',
-                'jpeg': 'image/jpeg',
-                'jfif': 'image/jpeg',
-                'pjpeg': 'image/jpeg',
-                'pjp': 'image/jpeg'
-              }
-          if(ext in extMappings)
-            ctype = extMappings(ext)
-        }
+        else if(type == 'I') // attempt to guess the image MIME type by the extension
+          ctype = extMappings[ext]
+        var datablob = new Blob([rawdata], {type: ctype})
         successCb({
           content: datablob,
           contentType: ctype,
@@ -100,7 +98,7 @@ Hi01379 = (function(psGopherRequest) {
         })
       }
       else { // assuming text content otherwise
-        var output = decodeURIComponent(escape(rawdata)), ctype = 'text/plain' // defaulting to type 0
+        var output = (new TextDecoder).decode(rawdata), ctype = 'text/plain' // defaulting to type 0
         if(type == '1' || type == '7') { // gophermap
           output = gophermapToHTML(output, resource[2], resource[3])
           ctype = 'text/html'
diff --git a/js/transport.js b/js/transport.js
@@ -6,19 +6,24 @@
 // input is optional and only considered for resource type 7
 
 function gopherRequest(resource, input, successCb, errorCb) {
-  var xsock = navigator.mozTCPSocket.open(resource[2], (resource[3]||70) | 0, {binaryType: 'string'}),
-      type = resource[0][0], databuf = ''
-  xsock.ondata = function(data) {
-    databuf += data.data
+  var xsock = navigator.mozTCPSocket.open(resource[2], (resource[3]||70) | 0, {binaryType: 'arraybuffer'}),
+      type = resource[0][0], databuf = []
+  xsock.ondata = function(e) {
+    var i = 0, db = new Uint8Array(e.data), l = db.length
+    for(;i<l;i++)
+      databuf.push(db[i])
   }
   xsock.onclose = function() {
-    successCb(databuf, type)
+    var res = new Uint8Array(databuf)
+    successCb(res, type)
+    databuf = []
   }
   xsock.onerror = errorCb
   xsock.onopen = function() {
     var selpath = resource[1]
     if(type == '7' && input)
       selpath += '\t' + input
-    xsock.send(selpath + '\r\n') // send CRLF-terminated selector path and optionally the search string
+    var reqbuf = (new TextEncoder).encode(selpath + '\r\n').buffer
+    xsock.send(reqbuf) // send CRLF-terminated selector path and optionally the search string
   }
 }