function runWorkerJs_(js, params, callback) {
  var URL = window.URL || window.webkitURL || window.mozURL;
  var Worker = window.Worker;

  if (URL && Worker && hasBlobConstructor_()) {
    // The Blob constructor, Worker, and window.URL.createObjectURL are all available,
    // so we can use inline workers.
    var bb = new Blob([js], {type:'text/javascript'});
    var worker = new Worker(URL.createObjectURL(bb));
    worker.onmessage = function(event) {
      callback(event.data);
    };
    worker.postMessage(params);
    return worker;

  } else {
    // We can't use inline workers, so run the worker JS on the main thread.
    (function() {
      var __DUMMY_OBJECT__ = {};
      // Proxy to Worker.onmessage
      var postMessage = function(result) {
        callback(result);
      };
      // Bind the worker to this dummy object. The worker will run
      // in this scope.
      eval('var self=__DUMMY_OBJECT__;\n' + js);
      // Proxy to Worker.postMessage
      __DUMMY_OBJECT__.onmessage({
        data: params
      });
    })();

    // Return a dummy Worker.
    return {
      terminate: function(){}
    };
  }
}
Helper method for running inline Web Workers, if the browser can support
them. If the browser doesn't support inline Web Workers, run the script
on the main thread, with this function body's scope, using eval. Browsers
must provide BlobBuilder, URL.createObjectURL, and Worker support to use
inline Web Workers. Most features such as importScripts() are not
currently supported, so this only works for basic workers.
@param {String} js The inline Web Worker Javascript code to run. This code
    must use 'self' and not 'this' as the global context variable.
@param {Object} params The parameters object to pass to the worker.
    Equivalent to calling Worker.postMessage(params);
@param {Function} callback The callback to run when the worker calls
    postMessage. Equivalent to adding a 'message' event listener on a
    Worker object and running callback(event.data);