diff --git a/Gruntfile.coffee b/Gruntfile.coffee index 663de9df3..a5c74fd04 100755 --- a/Gruntfile.coffee +++ b/Gruntfile.coffee @@ -80,6 +80,7 @@ module.exports = (grunt) -> 'src/General/meta/usestrict.js' 'tmp-<%= pkg.type %>/script.js' ] + 'testbuilds/crx<%= pkg.meta.suffix[pkg.channel] %>/eventPage.js': 'tmp-<%= pkg.type %>/eventPage.js' userscript: files: 'testbuilds/<%= pkg.name %><%= pkg.meta.suffix[pkg.channel] %>.meta.js': 'src/General/meta/metadata.js' @@ -108,6 +109,9 @@ module.exports = (grunt) -> script: src: 'tmp-<%= pkg.type %>/script.coffee' dest: 'tmp-<%= pkg.type %>/script.js' + eventPage: + src: 'src/General/eventPage/eventPage.coffee' + dest: 'tmp-<%= pkg.type %>/eventPage.js' concurrent: build: [ @@ -219,6 +223,7 @@ module.exports = (grunt) -> 'set-build:crx' 'concat:coffee' 'coffee:script' + 'coffee:eventPage' 'set-channel:stable' 'build-crx-channel' 'set-channel:beta' diff --git a/src/General/CrossOrigin.coffee b/src/General/CrossOrigin.coffee index 1e5d49729..6042eb047 100644 --- a/src/General/CrossOrigin.coffee +++ b/src/General/CrossOrigin.coffee @@ -1,4 +1,15 @@ -CrossOrigin = +CrossOrigin = do -> + <% if (type === 'crx') { %> + eventPageRequest = do -> + callbacks = [] + chrome.runtime.onMessage.addListener (data) -> + callbacks[data.id] data + delete callbacks[data.id] + (url, responseType, cb) -> + chrome.runtime.sendMessage {url, responseType}, (id) -> + callbacks[id] = cb + <% } %> + file: do -> makeBlob = (urlBlob, contentType, contentDisposition, url) -> name = url.match(/([^\/]+)\/*$/)?[1] @@ -14,15 +25,20 @@ CrossOrigin = (url, cb) -> <% if (type === 'crx') { %> - $.ajax url, - responseType: 'blob' - onload: -> - return cb null unless @readyState is @DONE and @status is 200 - contentType = @getResponseHeader 'Content-Type' - contentDisposition = @getResponseHeader 'Content-Disposition' - cb (makeBlob @response, contentType, contentDisposition, url) - onerror: -> - cb null + if /^https:\/\//.test(url) or location.protocol is 'http:' + $.ajax url, + responseType: 'blob' + onload: -> + return cb null unless @readyState is @DONE and @status is 200 + contentType = @getResponseHeader 'Content-Type' + contentDisposition = @getResponseHeader 'Content-Disposition' + cb (makeBlob @response, contentType, contentDisposition, url) + onerror: -> + cb null + else + eventPageRequest url, 'arraybuffer', ({response, contentType, contentDisposition, error}) -> + return cb null if error + cb (makeBlob new Uint8Array(response), contentType, contentDisposition, url) <% } %> <% if (type === 'userscript') { %> GM_xmlhttpRequest @@ -48,9 +64,9 @@ CrossOrigin = responses = {} (url, cb) -> <% if (type === 'crx') { %> - $.cache url, (-> cb @response), responseType: 'json' + if /^https:\/\//.test(url) or location.protocol is 'http:' + return $.cache url, (-> cb @response), responseType: 'json' <% } %> - <% if (type === 'userscript') { %> if responses[url] cb responses[url] return @@ -58,6 +74,7 @@ CrossOrigin = callbacks[url].push cb return callbacks[url] = [cb] + <% if (type === 'userscript') { %> GM_xmlhttpRequest method: "GET" url: url @@ -71,3 +88,12 @@ CrossOrigin = onabort: -> delete callbacks[url] <% } %> + <% if (type === 'crx') { %> + eventPageRequest url, 'json', ({response, error}) -> + if error + delete callbacks[url] + else + cb response for cb in callbacks[url] + delete callbacks[url] + responses[url] = response + <% } %> diff --git a/src/General/eventPage/eventPage.coffee b/src/General/eventPage/eventPage.coffee new file mode 100644 index 000000000..e5a107dc0 --- /dev/null +++ b/src/General/eventPage/eventPage.coffee @@ -0,0 +1,28 @@ +requestID = 0 + +chrome.runtime.onMessage.addListener (request, sender, sendResponse) -> + id = requestID + requestID++ + sendResponse id + + xhr = new XMLHttpRequest() + xhr.open 'GET', request.url, true + xhr.responseType = request.responseType + xhr.addEventListener 'load', -> + if @readyState is @DONE && xhr.status is 200 + contentType = @getResponseHeader 'Content-Type' + contentDisposition = @getResponseHeader 'Content-Disposition' + {response} = @ + if request.responseType is 'arraybuffer' + response = [new Uint8Array(response)...] + chrome.tabs.sendMessage sender.tab.id, {id, response, contentType, contentDisposition} + else + chrome.tabs.sendMessage sender.tab.id, {id, error: true} + , false + xhr.addEventListener 'error', -> + chrome.tabs.sendMessage sender.tab.id, {id, error: true} + , false + xhr.addEventListener 'abort', -> + chrome.tabs.sendMessage sender.tab.id, {id, error: true} + , false + xhr.send() diff --git a/src/General/meta/manifest.json b/src/General/meta/manifest.json index 6c6dbd67f..c47701e71 100755 --- a/src/General/meta/manifest.json +++ b/src/General/meta/manifest.json @@ -14,6 +14,10 @@ "all_frames": true, "run_at": "document_start" }], + "background": { + "scripts": ["eventPage.js"], + "persistent": false + }, "homepage_url": "<%= meta.page %>", <% if (channel !== 'noupdate') { %> "update_url": "<%= meta.downloads %>updates<%= meta.suffix[channel] %>.xml", <% } %> "minimum_chrome_version": "<%= meta.min.chrome %>",