initial import
[vuplus_webkit] / Source / WebCore / inspector / front-end / WorkerManager.js
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 WebInspector.WorkerManager = function()
32 {
33     this._workerIdToWindow = {};
34     InspectorBackend.registerWorkerDispatcher(new WebInspector.DedicatedWorkerMessageForwarder(this));
35 }
36
37 WebInspector.WorkerManager.isWorkerFrontend = function()
38 {
39     return !!WebInspector.queryParamsObject["dedicatedWorkerId"] ||
40            !!WebInspector.queryParamsObject["isSharedWorker"];
41 }
42
43 WebInspector.WorkerManager.loaded = function()
44 {
45     var workerId = WebInspector.queryParamsObject["dedicatedWorkerId"];
46     if (!workerId) {
47         WebInspector.workerManager = new WebInspector.WorkerManager();
48         return;
49     }
50
51     function receiveMessage(event)
52     {
53         var message = event.data;
54         InspectorBackend.dispatch(message);
55     }
56     window.addEventListener("message", receiveMessage, true);
57
58
59     InspectorBackend.sendMessageObjectToBackend = function(message)
60     {
61         window.opener.postMessage({workerId: workerId, command: "sendMessageToBackend", message: message}, "*");
62     }
63
64     InspectorFrontendHost.loaded = function()
65     {
66         window.opener.postMessage({workerId: workerId, command: "loaded"}, "*");
67     }
68 }
69
70 WebInspector.WorkerManager.Events = {
71     WorkerAdded: "worker-added",
72     WorkerRemoved: "worker-removed",
73     WorkersCleared: "workers-cleared",
74     WorkerInspectorClosed: "worker-inspector-closed"
75 }
76
77 WebInspector.WorkerManager.prototype = {
78     _workerCreated: function(workerId, url, inspectorConnected)
79      {
80         if (inspectorConnected)
81             this._openInspectorWindow(workerId);
82         this.dispatchEventToListeners(WebInspector.WorkerManager.Events.WorkerAdded, {workerId: workerId, url: url, inspectorConnected: inspectorConnected});
83      },
84
85     _workerTerminated: function(workerId)
86      {
87         this.closeWorkerInspector(workerId);
88         this.dispatchEventToListeners(WebInspector.WorkerManager.Events.WorkerRemoved, workerId);
89      },
90
91     _sendMessageToWorkerInspector: function(workerId, message)
92     {
93         var workerInspectorWindow = this._workerIdToWindow[workerId];
94         if (workerInspectorWindow)
95             workerInspectorWindow.postMessage(message, "*");
96     },
97
98     openWorkerInspector: function(workerId)
99     {
100         this._openInspectorWindow(workerId);
101         WorkerAgent.connectToWorker(workerId);
102     },
103
104     _openInspectorWindow: function(workerId)
105     {
106         var url = location.href + "&dedicatedWorkerId=" + workerId;
107         url = url.replace("docked=true&", "");
108         // Set location=0 just to make sure the front-end will be opened in a separate window, not in new tab.
109         var workerInspectorWindow = window.open(url, undefined, "location=0");
110         this._workerIdToWindow[workerId] = workerInspectorWindow;
111         workerInspectorWindow.addEventListener("beforeunload", this._workerInspectorClosing.bind(this, workerId), true);
112
113         // Listen to beforeunload in detached state and to the InspectorClosing event in case of attached inspector.
114         window.addEventListener("beforeunload", this._pageInspectorClosing.bind(this), true);
115         WebInspector.notifications.addEventListener(WebInspector.Events.InspectorClosing, this._pageInspectorClosing, this);
116     },
117
118     closeWorkerInspector: function(workerId)
119     {
120         var workerInspectorWindow = this._workerIdToWindow[workerId];
121         if (workerInspectorWindow)
122             workerInspectorWindow.close();
123     },
124
125     reset: function()
126     {
127         for (var workerId in this._workerIdToWindow)
128             this.closeWorkerInspector(workerId);
129         this.dispatchEventToListeners(WebInspector.WorkerManager.Events.WorkersCleared);
130     },
131
132     _pageInspectorClosing: function()
133     {
134         this._ignoreWorkerInspectorClosing = true;
135         for (var workerId in this._workerIdToWindow) {
136             this._workerIdToWindow[workerId].close();
137             WorkerAgent.disconnectFromWorker(workerId);
138         }
139     },
140
141     _workerInspectorClosing: function(workerId, event)
142     {
143         if (this._ignoreWorkerInspectorClosing)
144             return;
145         delete this._workerIdToWindow[workerId];
146         WorkerAgent.disconnectFromWorker(workerId);
147         this.dispatchEventToListeners(WebInspector.WorkerManager.Events.WorkerInspectorClosed, workerId);
148     }
149 }
150
151 WebInspector.WorkerManager.prototype.__proto__ = WebInspector.Object.prototype;
152
153 WebInspector.DedicatedWorkerMessageForwarder = function(workerManager)
154 {
155     this._workerManager = workerManager;
156     window.addEventListener("message", this._receiveMessage.bind(this), true);
157 }
158
159 WebInspector.DedicatedWorkerMessageForwarder.prototype = {
160     _receiveMessage: function(event)
161     {
162         var workerId = event.data.workerId;
163         workerId = parseInt(workerId);
164         var command = event.data.command;
165         var message = event.data.message;
166
167         if (command == "sendMessageToBackend")
168             WorkerAgent.sendMessageToWorker(workerId, message);
169     },
170
171     workerCreated: function(workerId, url, inspectorConnected)
172     {
173         this._workerManager._workerCreated(workerId, url, inspectorConnected);
174     },
175
176     workerTerminated: function(workerId)
177     {
178         this._workerManager._workerTerminated(workerId);
179     },
180
181     dispatchMessageFromWorker: function(workerId, message)
182     {
183         this._workerManager._sendMessageToWorkerInspector(workerId, message);
184     }
185 }