Changeset 56780 in webkit
- Timestamp:
- Mar 30, 2010 6:08:22 AM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r56778 r56780 1 2010-03-30 Andrey Kosyakov <caseq@chromium.org> 2 3 Reviewed by Pavel Feldman. 4 5 Support EventTarget interface in fake workers (both for Worker object 6 and WorkerContext). Use MessagePort to implement message passing to 7 support passing ports in PostMessage. 8 https://bugs.webkit.org/show_bug.cgi?id=36763 9 10 * inspector/front-end/InjectedFakeWorker.js: 11 (InjectedFakeWorker.Worker.onmessageGetter): 12 (InjectedFakeWorker.Worker.onmessageSetter): 13 (InjectedFakeWorker.Worker): 14 (InjectedFakeWorker.FakeWorker): 15 (InjectedFakeWorker.FakeWorker.prototype.postMessage): 16 (InjectedFakeWorker.FakeWorker.prototype.terminate): 17 (InjectedFakeWorker.FakeWorker.prototype._onWorkerFrameLoaded): 18 (InjectedFakeWorker.FakeWorker.prototype._setupWorkerContext.onmessageGetter): 19 (InjectedFakeWorker.FakeWorker.prototype._setupWorkerContext.onmessageSetter): 20 (InjectedFakeWorker.FakeWorker.prototype._setupWorkerContext): 21 (InjectedFakeWorker.FakeWorker.prototype._addEventListener): 22 (InjectedFakeWorker.FakeWorker.prototype._removeEventListener): 23 (InjectedFakeWorker.FakeWorker.prototype._callbackWrapper): 24 (InjectedFakeWorker.FakeWorker.prototype._handleException): 25 1 26 2010-03-30 Kristian Monsen <kristianm@google.com> 2 27 -
trunk/WebCore/inspector/front-end/InjectedFakeWorker.js
r56404 r56780 41 41 this.postMessage = bind(impl.postMessage, impl); 42 42 this.terminate = bind(impl.terminate, impl); 43 this.onmessage = noop; 43 44 function onmessageGetter() 45 { 46 return impl.channel.port1.onmessage; 47 } 48 function onmessageSetter(callback) 49 { 50 impl.channel.port1.onmessage = callback; 51 } 52 this.__defineGetter__("onmessage", onmessageGetter); 53 this.__defineSetter__("onmessage", onmessageSetter); 54 this.addEventListener = bind(impl.channel.port1.addEventListener, impl.channel.port1); 55 this.removeEventListener = bind(impl.channel.port1.removeEventListener, impl.channel.port1); 56 this.dispatchEvent = bind(impl.channel.port1.dispatchEvent, impl.channel.port1); 44 57 } 45 58 … … 49 62 50 63 this._worker = worker; 64 this._id = InjectedScriptHost.nextWorkerId(); 65 this.channel = new MessageChannel(); 66 this._listeners = []; 51 67 this._buildWorker(scriptURL); 52 this._id = InjectedScriptHost.nextWorkerId();53 68 54 69 InjectedScriptHost.didCreateWorker(this._id, scriptURL.url, false); … … 56 71 57 72 FakeWorker.prototype = { 58 postMessage: function(msg )73 postMessage: function(msg, opt_ports) 59 74 { 60 75 if (this._frame != null) 61 this. _dispatchMessage(this._frame, bind(this._onmessageWrapper, this), msg);76 this.channel.port1.postMessage.apply(this.channel.port1, arguments); 62 77 else if (this._pendingMessages) 63 this._pendingMessages.push( msg)78 this._pendingMessages.push(arguments) 64 79 else 65 this._pendingMessages = [ msg];80 this._pendingMessages = [ arguments ]; 66 81 }, 67 82 … … 70 85 InjectedScriptHost.didDestroyWorker(this._id); 71 86 72 if (this._frame != null) { 73 this._frame.onmessage = this._worker.onmessage = noop; 87 this.channel.port1.close(); 88 this.channel.port2.close(); 89 if (this._frame != null) 74 90 this._frame.frameElement.parentNode.removeChild(this._frame.frameElement); 75 }76 91 this._frame = null; 77 92 this._worker = null; // Break reference loop. 78 93 }, 79 94 80 _onmessageWrapper: function(msg) 95 _buildWorker: function(url) 96 { 97 var code = this._loadScript(url.url); 98 var iframeElement = document.createElement("iframe"); 99 iframeElement.style.display = "none"; 100 101 this._document = document; 102 iframeElement.onload = bind(this._onWorkerFrameLoaded, this, iframeElement, url, code); 103 104 if (document.body) 105 this._attachWorkerFrameToDocument(iframeElement, url, code); 106 else 107 window.addEventListener("load", bind(this._attachWorkerFrameToDocument, this, iframeElement), false); 108 }, 109 110 _attachWorkerFrameToDocument: function(iframeElement) 111 { 112 document.body.appendChild(iframeElement); 113 }, 114 115 _onWorkerFrameLoaded: function(iframeElement, url, code) 116 { 117 var frame = iframeElement.contentWindow; 118 this._frame = frame; 119 this._setupWorkerContext(frame, url); 120 121 var frameContents = '(function() { var location = __devtools.location; var window; ' + code + '})();\n' + '//@ sourceURL=' + url.url; 122 123 frame.eval(frameContents); 124 if (this._pendingMessages) { 125 for (var msg = 0; msg < this._pendingMessages.length; ++msg) 126 this.postMessage.apply(this, this._pendingMessages[msg]); 127 delete this._pendingMessages; 128 } 129 }, 130 131 _setupWorkerContext: function(workerFrame, url) 132 { 133 workerFrame.__devtools = { 134 handleException: bind(this._handleException, this), 135 location: url.mockLocation() 136 }; 137 138 var self = this; 139 140 function onmessageGetter() 141 { 142 return self.channel.port2.onmessage ? self.channel.port2.onmessage.originalCallback : null; 143 } 144 145 function onmessageSetter(callback) 146 { 147 var wrappedCallback = bind(self._callbackWrapper, self, callback); 148 wrappedCallback.originalCallback = callback; 149 self.channel.port2.onmessage = wrappedCallback; 150 } 151 152 workerFrame.__defineGetter__("onmessage", onmessageGetter); 153 workerFrame.__defineSetter__("onmessage", onmessageSetter); 154 workerFrame.addEventListener = bind(this._addEventListener, this); 155 workerFrame.removeEventListener = bind(this._removeEventListener, this); 156 workerFrame.dispatchEvent = bind(this.channel.port2.dispatchEvent, this.channel.port2); 157 workerFrame.postMessage = bind(this.channel.port2.postMessage, this.channel.port2); 158 workerFrame.importScripts = bind(this._importScripts, this, workerFrame); 159 workerFrame.close = bind(this.terminate, this); 160 }, 161 162 _addEventListener: function(type, callback, useCapture) 163 { 164 var wrappedCallback = bind(this._callbackWrapper, this, callback); 165 wrappedCallback.originalCallback = callback; 166 wrappedCallback.type = type; 167 wrappedCallback.useCapture = Boolean(useCapture); 168 169 this.channel.port2.addEventListener(type, wrappedCallback, useCapture); 170 this._listeners.push(wrappedCallback); 171 }, 172 173 _removeEventListener: function(type, callback, useCapture) 174 { 175 var listeners = this._listeners; 176 for (var i = 0; i < listeners.length; ++i) { 177 if (listeners[i].originalCallback === callback && 178 listeners[i].type === type && 179 listeners[i].useCapture === Boolean(useCapture)) { 180 this.channel.port2.removeEventListener(type, listeners[i], useCapture); 181 listeners[i] = listeners[listeners.length - 1]; 182 listeners.pop(); 183 break; 184 } 185 } 186 }, 187 188 _callbackWrapper: function(callback, msg) 81 189 { 82 190 // Shortcut -- if no exception handlers installed, avoid try/catch so as not to obscure line number. 83 191 if (!this._frame.onerror && !this._worker.onerror) { 84 this._frame.onmessage(msg);192 callback(msg); 85 193 return; 86 194 } 87 195 88 196 try { 89 this._frame.onmessage(msg);197 callback(msg); 90 198 } catch (e) { 91 199 this._handleException(e, this._frame.onerror, this._worker.onerror); 92 200 } 93 },94 95 _dispatchMessage: function(targetWindow, handler, msg)96 {97 var event = this._document.createEvent("MessageEvent");98 event.initMessageEvent("MessageEvent", false, false, msg);99 targetWindow.setTimeout(handler, 0, event);100 201 }, 101 202 … … 114 215 115 216 throw e; 116 },117 118 _buildWorker: function(url)119 {120 var code = this._loadScript(url.url);121 var iframeElement = document.createElement("iframe");122 iframeElement.style.display = "none";123 124 this._document = document;125 iframeElement.onload = bind(this._onWorkerFrameLoaded, this, iframeElement, url, code);126 127 if (document.body)128 this._attachWorkerFrameToDocument(iframeElement, url, code);129 else130 window.addEventListener("load", bind(this._attachWorkerFrameToDocument, this, iframeElement), false);131 },132 133 _attachWorkerFrameToDocument: function(iframeElement)134 {135 document.body.appendChild(iframeElement);136 },137 138 _onWorkerFrameLoaded: function(iframeElement, url, code)139 {140 var frame = iframeElement.contentWindow;141 this._frame = frame;142 this._setupWorkerContext(frame, url);143 144 var frameContents = '(function(location, window) { ' + code + '})(__devtools.location, undefined);\n' + '//@ sourceURL=' + url.url;145 146 frame.eval(frameContents);147 if (this._pendingMessages) {148 for (var msg in this._pendingMessages)149 this.postMessage(this._pendingMessages[msg]);150 delete this._pendingMessages;151 }152 },153 154 _setupWorkerContext: function(workerFrame, url)155 {156 workerFrame.__devtools = {157 handleException: bind(this._handleException, this),158 location: url.mockLocation()159 };160 var worker = this._worker;161 162 function handler(event) // Late binding to onmessage desired, so no bind() here.163 {164 worker.onmessage(event);165 }166 167 workerFrame.onmessage = noop;168 workerFrame.postMessage = bind(this._dispatchMessage, this, window, handler);169 workerFrame.importScripts = bind(this._importScripts, this, workerFrame);170 workerFrame.close = bind(this.terminate, this);171 217 }, 172 218
Note: See TracChangeset
for help on using the changeset viewer.