| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  | /* 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 {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); | 
					
						
							|  |  |  |     if (!jugglerFlag || isNaN(jugglerFlag)) | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     const port = parseInt(jugglerFlag, 10); | 
					
						
							|  |  |  |     const silent = cmdLine.preventDefault; | 
					
						
							|  |  |  |     if (silent) | 
					
						
							|  |  |  |       Services.startup.enterLastWindowClosingSurvivalArea(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const targetRegistry = new TargetRegistry(); | 
					
						
							|  |  |  |     new NetworkObserver(targetRegistry); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Force create hidden window here, otherwise its creation later closes the web socket!
 | 
					
						
							|  |  |  |     Services.appShell.hiddenDOMWindow; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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().registerHandler('Browser', browserHandler); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Services.mm.loadFrameScript(FRAME_SCRIPT, true /* aAllowDelayedLoad */); | 
					
						
							| 
									
										
										
										
											2020-06-08 15:54:47 -07:00
										 |  |  |     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); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |     dump(`Juggler listening on ws://127.0.0.1:${this._server.port}/${token}\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 = XPCOMUtils.generateNSGetFactory([CommandLineHandler]); |