From a97aaab79f1d5e54b6c0d3db28323716f3dfbf6c Mon Sep 17 00:00:00 2001 From: ccd0 Date: Sun, 5 Jul 2015 02:32:44 -0700 Subject: [PATCH] Support cross-origin binary downloads in Safari. --- src/General/CrossOrigin.coffee | 16 ++++++++++++---- src/Posting/QR.coffee | 9 +++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/General/CrossOrigin.coffee b/src/General/CrossOrigin.coffee index 79ffe0399..0bb47a77f 100644 --- a/src/General/CrossOrigin.coffee +++ b/src/General/CrossOrigin.coffee @@ -31,8 +31,9 @@ CrossOrigin = do -> cb new Uint8Array(response), contentType, contentDisposition <% } %> <% if (type === 'userscript') { %> - # Use workaround for binary data in Greasemonkey versions < 3.2 + # Use workaround for binary data in Greasemonkey versions < 3.2 and in JS Blocker (Safari) workaround = $.engine is 'gecko' and GM_info? and /^[0-2]\.|^3\.[01](?!\d)/.test(GM_info.version) + workaround or= GM_info?.script?.includeJSB? options = method: "GET" url: url @@ -47,15 +48,19 @@ CrossOrigin = do -> i++ else data = new Uint8Array xhr.response - contentType = xhr.responseHeaders.match(/Content-Type:\s*(.*)/i)?[1] - contentDisposition = xhr.responseHeaders.match(/Content-Disposition:\s*(.*)/i)?[1] + if typeof xhr.responseHeaders is 'object' + contentType = xhr.responseHeaders['Content-Type'] + contentDisposition = xhr.responseHeaders['Content-Disposition'] + else + contentType = xhr.responseHeaders.match(/Content-Type:\s*(.*)/i)?[1] + contentDisposition = xhr.responseHeaders.match(/Content-Disposition:\s*(.*)/i)?[1] cb data, contentType, contentDisposition onerror: -> cb null onabort: -> cb null if workaround - options.overrideMimeType = 'text/plain; charset=x-user-defined' + options.overrideMimeType = options.mimeType = 'text/plain; charset=x-user-defined' else options.responseType = 'arraybuffer' GM_xmlhttpRequest options @@ -71,6 +76,9 @@ CrossOrigin = do -> contentType?.match(/\bname\s*=\s*"((\\"|[^"])+)"/i)?[1] if match name = match.replace /\\"/g, '"' + if GM_info?.script?.includeJSB? + # Content type comes back as 'text/plain; charset=x-user-defined'; guess from filename instead. + mime = QR.typeFromExtension[name.match(/[^.]*$/)[0].toLowerCase()] or 'application/octet-stream' blob = new Blob([data], {type: mime}) blob.name = name cb blob diff --git a/src/Posting/QR.coffee b/src/Posting/QR.coffee index 0e831b525..bda59843c 100644 --- a/src/Posting/QR.coffee +++ b/src/Posting/QR.coffee @@ -1,6 +1,15 @@ QR = mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'application/pdf', 'application/vnd.adobe.flash.movie', 'application/x-shockwave-flash', 'video/webm'] + typeFromExtension: + 'jpg': 'image/jpeg' + 'jpeg': 'image/jpeg' + 'png': 'image/png' + 'gif': 'image/gif' + 'pdf': 'application/pdf' + 'swf': 'application/vnd.adobe.flash.movie' + 'webm': 'video/webm' + init: -> return unless Conf['Quick Reply']