132 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			132 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
/* This Source Code Form is subject to the terms of the Mozilla Public
 | 
						|
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
						|
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | 
						|
 | 
						|
const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 | 
						|
const {ComponentUtils} = ChromeUtils.import("resource://gre/modules/ComponentUtils.jsm");
 | 
						|
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 | 
						|
const {Dispatcher} = ChromeUtils.import("chrome://juggler/content/protocol/Dispatcher.js");
 | 
						|
const {BrowserHandler} = ChromeUtils.import("chrome://juggler/content/protocol/BrowserHandler.js");
 | 
						|
const {NetworkObserver} = ChromeUtils.import("chrome://juggler/content/NetworkObserver.js");
 | 
						|
const {TargetRegistry} = ChromeUtils.import("chrome://juggler/content/TargetRegistry.js");
 | 
						|
const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
 | 
						|
const helper = new Helper();
 | 
						|
 | 
						|
const Cc = Components.classes;
 | 
						|
const Ci = Components.interfaces;
 | 
						|
 | 
						|
const FRAME_SCRIPT = "chrome://juggler/content/content/main.js";
 | 
						|
 | 
						|
// Command Line Handler
 | 
						|
function CommandLineHandler() {
 | 
						|
};
 | 
						|
 | 
						|
CommandLineHandler.prototype = {
 | 
						|
  classDescription: "Sample command-line handler",
 | 
						|
  classID: Components.ID('{f7a74a33-e2ab-422d-b022-4fb213dd2639}'),
 | 
						|
  contractID: "@mozilla.org/remote/juggler;1",
 | 
						|
  _xpcom_categories: [{
 | 
						|
    category: "command-line-handler",
 | 
						|
    entry: "m-juggler"
 | 
						|
  }],
 | 
						|
 | 
						|
  /* nsICommandLineHandler */
 | 
						|
  handle: async function(cmdLine) {
 | 
						|
    const jugglerFlag = cmdLine.handleFlagWithParam("juggler", false);
 | 
						|
    const jugglerPipeFlag = cmdLine.handleFlag("juggler-pipe", false);
 | 
						|
    if (!jugglerPipeFlag && (!jugglerFlag || isNaN(jugglerFlag)))
 | 
						|
      return;
 | 
						|
    const silent = cmdLine.preventDefault;
 | 
						|
    if (silent)
 | 
						|
      Services.startup.enterLastWindowClosingSurvivalArea();
 | 
						|
 | 
						|
    const targetRegistry = new TargetRegistry();
 | 
						|
    new NetworkObserver(targetRegistry);
 | 
						|
 | 
						|
    const loadFrameScript = () => {
 | 
						|
      Services.mm.loadFrameScript(FRAME_SCRIPT, true /* aAllowDelayedLoad */);
 | 
						|
      if (Cc["@mozilla.org/gfx/info;1"].getService(Ci.nsIGfxInfo).isHeadless) {
 | 
						|
        const styleSheetService = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Components.interfaces.nsIStyleSheetService);
 | 
						|
        const ioService = Cc["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
 | 
						|
        const uri = ioService.newURI('chrome://juggler/content/content/hidden-scrollbars.css', null, null);
 | 
						|
        styleSheetService.loadAndRegisterSheet(uri, styleSheetService.AGENT_SHEET);
 | 
						|
      }
 | 
						|
    };
 | 
						|
 | 
						|
    // Force create hidden window here, otherwise its creation later closes the web socket!
 | 
						|
    Services.appShell.hiddenDOMWindow;
 | 
						|
 | 
						|
    if (jugglerFlag) {
 | 
						|
      const port = parseInt(jugglerFlag, 10);
 | 
						|
      const { require } = ChromeUtils.import("resource://devtools/shared/Loader.jsm");
 | 
						|
      const WebSocketServer = require('devtools/server/socket/websocket-server');
 | 
						|
      this._server = Cc["@mozilla.org/network/server-socket;1"].createInstance(Ci.nsIServerSocket);
 | 
						|
      this._server.initSpecialConnection(port, Ci.nsIServerSocket.KeepWhenOffline | Ci.nsIServerSocket.LoopbackOnly, 4);
 | 
						|
      const token = helper.generateId();
 | 
						|
      this._server.asyncListen({
 | 
						|
        onSocketAccepted: async(socket, transport) => {
 | 
						|
          const input = transport.openInputStream(0, 0, 0);
 | 
						|
          const output = transport.openOutputStream(0, 0, 0);
 | 
						|
          const webSocket = await WebSocketServer.accept(transport, input, output, "/" + token);
 | 
						|
          const dispatcher = new Dispatcher(webSocket);
 | 
						|
          const browserHandler = new BrowserHandler(dispatcher.rootSession(), dispatcher, targetRegistry, () => {
 | 
						|
            if (silent)
 | 
						|
              Services.startup.exitLastWindowClosingSurvivalArea();
 | 
						|
          });
 | 
						|
          dispatcher.rootSession().setHandler(browserHandler);
 | 
						|
        }
 | 
						|
      });
 | 
						|
      loadFrameScript();
 | 
						|
      dump(`Juggler listening on ws://127.0.0.1:${this._server.port}/${token}\n`);
 | 
						|
    } else if (jugglerPipeFlag) {
 | 
						|
      let browserHandler;
 | 
						|
      let pipeStopped = false;
 | 
						|
      const pipe = Cc['@mozilla.org/juggler/remotedebuggingpipe;1'].getService(Ci.nsIRemoteDebuggingPipe);
 | 
						|
      const connection = {
 | 
						|
        QueryInterface: ChromeUtils.generateQI([Ci.nsIRemoteDebuggingPipeClient]),
 | 
						|
        receiveMessage(message) {
 | 
						|
          if (this.onmessage)
 | 
						|
            this.onmessage({ data: message });
 | 
						|
        },
 | 
						|
        disconnected() {
 | 
						|
          if (browserHandler)
 | 
						|
            browserHandler['Browser.close']();
 | 
						|
        },
 | 
						|
        send(message) {
 | 
						|
          if (pipeStopped) {
 | 
						|
            // We are missing the response to Browser.close,
 | 
						|
            // but everything works fine. Once we actually need it,
 | 
						|
            // we have to stop the pipe after the response is sent.
 | 
						|
            return;
 | 
						|
          }
 | 
						|
          pipe.sendMessage(message);
 | 
						|
        },
 | 
						|
      };
 | 
						|
      pipe.init(connection);
 | 
						|
      const dispatcher = new Dispatcher(connection);
 | 
						|
      browserHandler = new BrowserHandler(dispatcher.rootSession(), dispatcher, targetRegistry, () => {
 | 
						|
        if (silent)
 | 
						|
          Services.startup.exitLastWindowClosingSurvivalArea();
 | 
						|
        connection.onclose();
 | 
						|
        pipe.stop();
 | 
						|
        pipeStopped = true;
 | 
						|
      });
 | 
						|
      dispatcher.rootSession().setHandler(browserHandler);
 | 
						|
      loadFrameScript();
 | 
						|
      dump(`\nJuggler listening to the pipe\n`);
 | 
						|
    }
 | 
						|
  },
 | 
						|
 | 
						|
  QueryInterface: ChromeUtils.generateQI([ Ci.nsICommandLineHandler ]),
 | 
						|
 | 
						|
  // CHANGEME: change the help info as appropriate, but
 | 
						|
  // follow the guidelines in nsICommandLineHandler.idl
 | 
						|
  // specifically, flag descriptions should start at
 | 
						|
  // character 24, and lines should be wrapped at
 | 
						|
  // 72 characters with embedded newlines,
 | 
						|
  // and finally, the string should end with a newline
 | 
						|
  helpInfo : "  --juggler            Enable Juggler automation\n"
 | 
						|
};
 | 
						|
 | 
						|
var NSGetFactory = ComponentUtils.generateNSGetFactory([CommandLineHandler]);
 |