Changeset 56780 in webkit


Ignore:
Timestamp:
Mar 30, 2010 6:08:22 AM (14 years ago)
Author:
eric@webkit.org
Message:

2010-03-30 Andrey Kosyakov <caseq@chromium.org>

Reviewed by Pavel Feldman.

Support EventTarget interface in fake workers (both for Worker object
and WorkerContext). Use MessagePort to implement message passing to
support passing ports in PostMessage.
https://bugs.webkit.org/show_bug.cgi?id=36763

  • inspector/front-end/InjectedFakeWorker.js: (InjectedFakeWorker.Worker.onmessageGetter): (InjectedFakeWorker.Worker.onmessageSetter): (InjectedFakeWorker.Worker): (InjectedFakeWorker.FakeWorker): (InjectedFakeWorker.FakeWorker.prototype.postMessage): (InjectedFakeWorker.FakeWorker.prototype.terminate): (InjectedFakeWorker.FakeWorker.prototype._onWorkerFrameLoaded): (InjectedFakeWorker.FakeWorker.prototype._setupWorkerContext.onmessageGetter): (InjectedFakeWorker.FakeWorker.prototype._setupWorkerContext.onmessageSetter): (InjectedFakeWorker.FakeWorker.prototype._setupWorkerContext): (InjectedFakeWorker.FakeWorker.prototype._addEventListener): (InjectedFakeWorker.FakeWorker.prototype._removeEventListener): (InjectedFakeWorker.FakeWorker.prototype._callbackWrapper): (InjectedFakeWorker.FakeWorker.prototype._handleException):
Location:
trunk/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r56778 r56780  
     12010-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
    1262010-03-30  Kristian Monsen  <kristianm@google.com>
    227
  • trunk/WebCore/inspector/front-end/InjectedFakeWorker.js

    r56404 r56780  
    4141    this.postMessage = bind(impl.postMessage, impl);
    4242    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);
    4457}
    4558
     
    4962
    5063    this._worker = worker;
     64    this._id = InjectedScriptHost.nextWorkerId();
     65    this.channel = new MessageChannel();
     66    this._listeners = [];
    5167    this._buildWorker(scriptURL);
    52     this._id = InjectedScriptHost.nextWorkerId();
    5368
    5469    InjectedScriptHost.didCreateWorker(this._id, scriptURL.url, false);
     
    5671
    5772FakeWorker.prototype = {
    58     postMessage: function(msg)
     73    postMessage: function(msg, opt_ports)
    5974    {
    6075        if (this._frame != null)
    61             this._dispatchMessage(this._frame, bind(this._onmessageWrapper, this), msg);
     76            this.channel.port1.postMessage.apply(this.channel.port1, arguments);
    6277        else if (this._pendingMessages)
    63             this._pendingMessages.push(msg)
     78            this._pendingMessages.push(arguments)
    6479        else
    65             this._pendingMessages = [ msg ];
     80            this._pendingMessages = [ arguments ];
    6681    },
    6782
     
    7085        InjectedScriptHost.didDestroyWorker(this._id);
    7186
    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)
    7490            this._frame.frameElement.parentNode.removeChild(this._frame.frameElement);
    75         }
    7691        this._frame = null;
    7792        this._worker = null; // Break reference loop.
    7893    },
    7994
    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)
    81189    {
    82190        // Shortcut -- if no exception handlers installed, avoid try/catch so as not to obscure line number.
    83191        if (!this._frame.onerror && !this._worker.onerror) {
    84             this._frame.onmessage(msg);
     192            callback(msg);
    85193            return;
    86194        }
    87195
    88196        try {
    89             this._frame.onmessage(msg);
     197            callback(msg);
    90198        } catch (e) {
    91199            this._handleException(e, this._frame.onerror, this._worker.onerror);
    92200        }
    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);
    100201    },
    101202
     
    114215
    115216        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         else
    130             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);
    171217    },
    172218
Note: See TracChangeset for help on using the changeset viewer.