1 /* 2 * Copyright (C) 2011 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 /** 32 * @constructor 33 * @extends {WebInspector.Object} 34 * @param {!WebInspector.Target} target 35 * @param {boolean} isMainFrontend 36 */ 37 WebInspector.WorkerManager = function(target, isMainFrontend) 38 { 39 this._reset(); 40 target.registerWorkerDispatcher(new WebInspector.WorkerDispatcher(this)); 41 if (isMainFrontend) { 42 target.workerAgent().enable(); 43 target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNavigated, this); 44 } 45 } 46 47 WebInspector.WorkerManager.Events = { 48 WorkerAdded: "WorkerAdded", 49 WorkerRemoved: "WorkerRemoved", 50 WorkersCleared: "WorkersCleared", 51 WorkerSelectionChanged: "WorkerSelectionChanged", 52 WorkerDisconnected: "WorkerDisconnected", 53 MessageFromWorker: "MessageFromWorker", 54 } 55 56 WebInspector.WorkerManager.MainThreadId = 0; 57 58 WebInspector.WorkerManager.prototype = { 59 60 _reset: function() 61 { 62 /** @type {!Object.<number, string>} */ 63 this._threadUrlByThreadId = {}; 64 this._threadUrlByThreadId[WebInspector.WorkerManager.MainThreadId] = WebInspector.UIString("Thread: Main"); 65 this._threadsList = [WebInspector.WorkerManager.MainThreadId]; 66 this._selectedThreadId = WebInspector.WorkerManager.MainThreadId; 67 }, 68 69 _workerCreated: function(workerId, url, inspectorConnected) 70 { 71 this._threadsList.push(workerId); 72 this._threadUrlByThreadId[workerId] = url; 73 this.dispatchEventToListeners(WebInspector.WorkerManager.Events.WorkerAdded, {workerId: workerId, url: url, inspectorConnected: inspectorConnected}); 74 }, 75 76 _workerTerminated: function(workerId) 77 { 78 this._threadsList.remove(workerId); 79 delete this._threadUrlByThreadId[workerId]; 80 this.dispatchEventToListeners(WebInspector.WorkerManager.Events.WorkerRemoved, workerId); 81 }, 82 83 _dispatchMessageFromWorker: function(workerId, message) 84 { 85 this.dispatchEventToListeners(WebInspector.WorkerManager.Events.MessageFromWorker, {workerId: workerId, message: message}) 86 }, 87 88 _disconnectedFromWorker: function() 89 { 90 this.dispatchEventToListeners(WebInspector.WorkerManager.Events.WorkerDisconnected) 91 }, 92 93 _mainFrameNavigated: function(event) 94 { 95 this._reset(); 96 this.dispatchEventToListeners(WebInspector.WorkerManager.Events.WorkersCleared); 97 }, 98 99 /** 100 * @return {!Array.<number>} 101 */ 102 threadsList: function() 103 { 104 return this._threadsList; 105 }, 106 107 /** 108 * @param {number} threadId 109 * @return {string} 110 */ 111 threadUrl: function(threadId) 112 { 113 return this._threadUrlByThreadId[threadId]; 114 }, 115 116 /** 117 * @param {number} threadId 118 */ 119 setSelectedThreadId: function(threadId) 120 { 121 this._selectedThreadId = threadId; 122 }, 123 124 /** 125 * @return {number} 126 */ 127 selectedThreadId: function() 128 { 129 return this._selectedThreadId; 130 }, 131 132 __proto__: WebInspector.Object.prototype 133 } 134 135 /** 136 * @constructor 137 * @implements {WorkerAgent.Dispatcher} 138 */ 139 WebInspector.WorkerDispatcher = function(workerManager) 140 { 141 this._workerManager = workerManager; 142 } 143 144 WebInspector.WorkerDispatcher.prototype = { 145 146 workerCreated: function(workerId, url, inspectorConnected) 147 { 148 this._workerManager._workerCreated(workerId, url, inspectorConnected); 149 }, 150 151 workerTerminated: function(workerId) 152 { 153 this._workerManager._workerTerminated(workerId); 154 }, 155 156 dispatchMessageFromWorker: function(workerId, message) 157 { 158 this._workerManager._dispatchMessageFromWorker(workerId, message); 159 }, 160 161 disconnectedFromWorker: function() 162 { 163 this._workerManager._disconnectedFromWorker(); 164 } 165 } 166 167 /** 168 * @type {!WebInspector.WorkerManager} 169 */ 170 WebInspector.workerManager; 171 172 /** 173 * @constructor 174 * @extends {InspectorBackendClass.Connection} 175 * @param {string} workerId 176 */ 177 WebInspector.ExternalWorkerConnection = function(workerId) 178 { 179 InspectorBackendClass.Connection.call(this); 180 this._workerId = workerId; 181 window.addEventListener("message", this._processMessage.bind(this), true); 182 } 183 184 WebInspector.ExternalWorkerConnection.prototype = { 185 186 /** 187 * @param {!Event} event 188 */ 189 _processMessage: function(event) 190 { 191 if (!event) 192 return; 193 194 var message = event.data; 195 this.dispatch(message); 196 }, 197 198 /** 199 * @param {!Object} messageObject 200 */ 201 sendMessage: function(messageObject) 202 { 203 window.opener.postMessage({workerId: this._workerId, command: "sendMessageToBackend", message: messageObject}, "*"); 204 }, 205 206 __proto__: InspectorBackendClass.Connection.prototype 207 } 208