B2G/gecko/testing/marionette/marionette-server.js
/**
   * This function is used by executeAsync and executeJSScript to execute a script
   * in a sandbox. 
   * 
   * For executeJSScript, it will return a message only when the finish() method is called.
   * For executeAsync, it will return a response when marionetteScriptFinished/arguments[arguments.length-1] 
   * method is called, or if it times out.
   *
   * @param object aRequest
   *        'value' member holds the script to execute
   *        'args' member holds the arguments for the script
   * @param boolean directInject
   *        if true, it will be run directly and not as a 
   *        function body
   */
This function is used by executeAsync and executeJSScript to execute a script
in a sandbox.

For executeJSScript, it will return a message only when the finish() method is called.
For executeAsync, it will return a response when marionetteScriptFinished/arguments[arguments.length-1]
method is called, or if it times out.

@param object aRequest
'value' member holds the script to execute
'args' member holds the arguments for the script
@param boolean directInject
if true, it will be run directly and not as a
function body
This function is used by executeAsync and executeJSScript to execute a script in a sandbox . For executeJSScript it will return a message only when the finish () method is called . For executeAsync it will return a response when marionetteScriptFinished / arguments [ arguments . length - 1 ] method is called or if it times out . @param object aRequest ' value ' member holds the script to execute ' args ' member holds the arguments for the script @param boolean directInject if true it will be run directly and not as a function body
function MDA_executeWithCallback(aRequest, directInject) {
    let timeout = aRequest.scriptTimeout ? aRequest.scriptTimeout : this.scriptTimeout;
    let command_id = this.command_id = this.getCommandId();
    let script;
    this.logRequest("executeWithCallback", aRequest);
    if (aRequest.newSandbox == undefined) {
      aRequest.newSandbox = true;
    }
    if (this.context == "content") {
      this.sendAsync("executeAsyncScript",
                     {
                       value: aRequest.value,
                       args: aRequest.args,
                       id: this.command_id,
                       newSandbox: aRequest.newSandbox,
                       timeout: timeout,
                       specialPowers: aRequest.specialPowers,
                       filename: aRequest.filename,
                       line: aRequest.line
                     },
                     command_id);
      return;
    }
    let curWindow = this.getCurrentWindow();
    let original_onerror = curWindow.onerror;
    let that = this;
    that.timeout = timeout;
    let marionette = new Marionette(this, curWindow, "chrome",
                                    this.marionetteLog,
                                    timeout, this.testName);
    marionette.command_id = this.command_id;
    function chromeAsyncReturnFunc(value, status, stacktrace) {
      if (that._emu_cbs && Object.keys(that._emu_cbs).length) {
        value = "Emulator callback still pending when finish() called";
        status = 500;
        that._emu_cbs = null;
      }
      if (value == undefined)
        value = null;
      if (that.command_id == marionette.command_id) {
        if (that.timer != null) {
          that.timer.cancel();
          that.timer = null;
        }
        curWindow.onerror = original_onerror;
        if (status == 0 || status == undefined) {
          that.sendToClient({from: that.actorID, value: that.curBrowser.elementManager.wrapValue(value), status: status},
                            marionette.command_id);
        }
        else {
          let error_msg = {message: value, status: status, stacktrace: stacktrace};
          that.sendToClient({from: that.actorID, error: error_msg},
                            marionette.command_id);
        }
      }
    }
    curWindow.onerror = function (errorMsg, url, lineNumber) {
      chromeAsyncReturnFunc(errorMsg + " at: " + url + " line: " + lineNumber, 17);
      return true;
    };
    function chromeAsyncFinish() {
      chromeAsyncReturnFunc(marionette.generate_results(), 0);
    }
    let _chromeSandbox = this.createExecuteSandbox(curWindow,
                                                   marionette,
                                                   aRequest.args,
                                                   aRequest.specialPowers,
                                                   command_id);
    if (!_chromeSandbox)
      return;
    try {
      this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
      if (this.timer != null) {
        this.timer.initWithCallback(function() {
          chromeAsyncReturnFunc("timed out", 28);
        }, that.timeout, Ci.nsITimer.TYPE_ONESHOT);
      }
      _chromeSandbox.returnFunc = chromeAsyncReturnFunc;
      _chromeSandbox.finish = chromeAsyncFinish;
      if (directInject) {
        script = aRequest.value;
      }
      else {
        script =  '__marionetteParams.push(returnFunc);'
                + 'let marionetteScriptFinished = returnFunc;'
                + 'let __marionetteFunc = function() {' + aRequest.value + '};'
                + '__marionetteFunc.apply(null, __marionetteParams);';
      }
      this.executeScriptInSandbox(_chromeSandbox, script, directInject,
                                  true, command_id, timeout);
    } catch (e) {
      let error = createStackMessage(e,
                                     "execute_async_script",
                                     aRequest.filename,
                                     aRequest.line,
                                     script);
      chromeAsyncReturnFunc(error[0], 17, error[1]);
    }
  }
function MDA_executeWithCallback ( aRequest , directInject ) { let timeout = aRequest . scriptTimeout ? aRequest . scriptTimeout : this . scriptTimeout ; let command_id = this . command_id = this . getCommandId ( ) ; let script ; this . logRequest ( "executeWithCallback" , aRequest ) ; if ( aRequest . newSandbox == undefined ) { aRequest . newSandbox = true ; } if ( this . context == "content" ) { this . sendAsync ( "executeAsyncScript" , { value : aRequest . value , args : aRequest . args , id : this . command_id , newSandbox : aRequest . newSandbox , timeout : timeout , specialPowers : aRequest . specialPowers , filename : aRequest . filename , line : aRequest . line } , command_id ) ; return ; } let curWindow = this . getCurrentWindow ( ) ; let original_onerror = curWindow . onerror ; let that = this ; that . timeout = timeout ; let marionette = new Marionette ( this , curWindow , "chrome" , this . marionetteLog , timeout , this . testName ) ; marionette . command_id = this . command_id ; function chromeAsyncReturnFunc ( value , status , stacktrace ) { if ( that . _emu_cbs && Object . keys ( that . _emu_cbs ) . length ) { value = "Emulator callback still pending when finish() called" ; status = 500 ; that . _emu_cbs = null ; } if ( value == undefined ) value = null ; if ( that . command_id == marionette . command_id ) { if ( that . timer != null ) { that . timer . cancel ( ) ; that . timer = null ; } curWindow . onerror = original_onerror ; if ( status == 0 || status == undefined ) { that . sendToClient ( { from : that . actorID , value : that . curBrowser . elementManager . wrapValue ( value ) , status : status } , marionette . command_id ) ; } else { let error_msg = { message : value , status : status , stacktrace : stacktrace } ; that . sendToClient ( { from : that . actorID , error : error_msg } , marionette . command_id ) ; } } } curWindow . onerror = function ( errorMsg , url , lineNumber ) { chromeAsyncReturnFunc ( errorMsg + " at: " + url + " line: " + lineNumber , 17 ) ; return true ; } ; function chromeAsyncFinish ( ) { chromeAsyncReturnFunc ( marionette . generate_results ( ) , 0 ) ; } let _chromeSandbox = this . createExecuteSandbox ( curWindow , marionette , aRequest . args , aRequest . specialPowers , command_id ) ; if ( ! _chromeSandbox ) return ; try { this . timer = Cc [ "@mozilla.org/timer;1" ] . createInstance ( Ci . nsITimer ) ; if ( this . timer != null ) { this . timer . initWithCallback ( function ( ) { chromeAsyncReturnFunc ( "timed out" , 28 ) ; } , that . timeout , Ci . nsITimer . TYPE_ONESHOT ) ; } _chromeSandbox . returnFunc = chromeAsyncReturnFunc ; _chromeSandbox . finish = chromeAsyncFinish ; if ( directInject ) { script = aRequest . value ; } else { script = '__marionetteParams.push(returnFunc);' + 'let marionetteScriptFinished = returnFunc;' + 'let __marionetteFunc = function() {' + aRequest . value + '};' + '__marionetteFunc.apply(null, __marionetteParams);' ; } this . executeScriptInSandbox ( _chromeSandbox , script , directInject , true , command_id , timeout ) ; } catch ( e ) { let error = createStackMessage ( e , "execute_async_script" , aRequest . filename , aRequest . line , script ) ; chromeAsyncReturnFunc ( error [ 0 ] , 17 , error [ 1 ] ) ; } }
This function is used by executeAsync and executeJSScript to execute a script
 in a sandbox.
This function is used by executeAsync and executeJSScript to execute a script in a sandbox .
//if client does not send a value in newSandbox,  //then they expect the same behaviour as webdriver