diff --git a/lib/ace/worker/worker_client.js b/lib/ace/worker/worker_client.js index 798f1b4b..743bd0ed 100644 --- a/lib/ace/worker/worker_client.js +++ b/lib/ace/worker/worker_client.js @@ -35,7 +35,7 @@ var oop = require("../lib/oop"); var EventEmitter = require("../lib/event_emitter").EventEmitter; var config = require("../config"); -var WorkerClient = function(topLevelNamespaces, mod, classname) { +var WorkerClient = function(topLevelNamespaces, mod, classname, workerUrl) { this.$sendDeltaQueue = this.$sendDeltaQueue.bind(this); this.changeListener = this.changeListener.bind(this); this.onMessage = this.onMessage.bind(this); @@ -43,13 +43,12 @@ var WorkerClient = function(topLevelNamespaces, mod, classname) { // nameToUrl is renamed to toUrl in requirejs 2 if (require.nameToUrl && !require.toUrl) require.toUrl = require.nameToUrl; - - var workerUrl; + if (config.get("packaged") || !require.toUrl) { - workerUrl = config.moduleUrl(mod, "worker"); + workerUrl = workerUrl || config.moduleUrl(mod, "worker"); } else { var normalizePath = this.$normalizePath; - workerUrl = normalizePath(require.toUrl("ace/worker/worker.js", null, "_")); + workerUrl = workerUrl || normalizePath(require.toUrl("ace/worker/worker.js", null, "_")); var tlns = {}; topLevelNamespaces.forEach(function(ns) { @@ -57,12 +56,26 @@ var WorkerClient = function(topLevelNamespaces, mod, classname) { }); } - this.$worker = new Worker(workerUrl); + try { + this.$worker = new Worker(workerUrl); + } catch(e) { + if (e instanceof window.DOMException) { + // Likely same origin problem. Use importScripts from a shim Worker + var blob = this.$workerBlob(workerUrl); + var URL = window.URL || window.webkitURL; + var blobURL = URL.createObjectURL(blob); + + this.$worker = new Worker(blobURL); + URL.revokeObjectURL(blobURL); + } else { + throw e; + } + } this.$worker.postMessage({ init : true, - tlns: tlns, - module: mod, - classname: classname + tlns : tlns, + module : mod, + classname : classname }); this.callbackId = 1; @@ -163,7 +176,20 @@ var WorkerClient = function(topLevelNamespaces, mod, classname) { this.call("setValue", [this.$doc.getValue()]); } else this.emit("change", {data: q}); - } + }; + + this.$workerBlob = function(workerUrl) { + var script = 'importScripts("' + workerUrl + '");'; + try { + var blob = new Blob([script], {'type': 'application/javascript'}); + } catch (e) { // Backwards-compatibility + var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder; + var blobBuilder = new BlobBuilder(); + blobBuilder.append(script); + blob = blobBuilder.getBlob('application/javascript'); + } + return blob; + }; }).call(WorkerClient.prototype);