- From: Francois Daoust <fd@w3.org>
- Date: Mon, 08 Jun 2015 17:18:37 +0200
- To: public-webtiming@w3.org
Hi again, Looking at the TimingObject interface as defined in the spec [1], I'm wondering what would be the proper way to associate a TimingObject instance with an online timing service and to start using it. The spec currently currently defines an under-specified "src" attribute but I'm wondering whether it's of any use in the end: using a URL would probably require that we define a custom URL scheme to tell the user agent about the protocol to use. Since we want to leave some freedom for online timing services to define their own mechanisms, that does not seem to be a good approach and I would just drop it for now. I explored the possibility to use an "srcObject" attribute to associate a local instance with a TimingProvider instance connected to an online timing service in my prototype [2]. However, this means that, before being able to use the timing object, the code needs to listen to the "readystatechange" event, which is somewhat tedious. Also, "srcObject" could be re-assigned at any time, so the code needs to take that possibility into account. var runWhenReady = function () { [[...]] }; var provider = [[get timing provider instance]]; var alreadyRun = false; var timing = new TimingObject(); timing.srcObject = provider; timing.onreadystatechange = function (evt) { if (!alreadyRun && (evt.value === 'open')) { alreadyRun = true; run(); } }; To simplify the life of developers, it might be better to define a dedicated "open" event (as in the WebSockets API) instead of a "readystatechange" event and, assuming the TimingProvider has a simple (connecting, open, closing, closed) lifecycle, to prevent the timing object from being associated with more than one TimingProvider, e.g. by dropping the srcObject attribute and rather passing the TimingProvider instance as part of the constructor, as in: var timing = new TimingObject(provider); timing.onopen = runWhenReady; Perhaps more fashionable, there could be a ready() method that returns a Promise that resolves when the association is ready and rejects when connection goes wrong: var timing = new TimingObject(provider); timing.ready().then(runWhenReady); ... but I think I still prefer the "onopen" mechanism. Any thought? The "TimingProvider" interface would also need to be specified. In the end, all I needed was something pretty close to the TimingObject interface: interface TimingProvider : EventTarget { readonly attribute DOMString readyState; readonly attribute StateVector vector; readonly attribute Interval range; attribute EventHandler onreadystatechange; StateVector query(); void update(StateVector newVector); void close(); } I'm not entirely convinced that the "vector" attribute needs to be exposed in practice but that's a minor detail. The interface is so close to TimingObject that it begs the question as to whether a timing object associated with an online timing service should not be seen as a derived TimingObject class rather than as a TimingObject associated with a TimingProvider. The only real difference is the "timeupdate" event (and a few helper methods that could also be added to a TimingProvider). I guess it makes sense to keep a distinction if user agents implement the TimingObject interface natively whereas TimingProvider classes may be defined in regular JS libraries. Should I sketch some text along these lines for the TimingProvider interface? Francois. [1] http://webtiming.github.io/timingobject/ [2] https://github.com/tidoust/timingservice
Received on Monday, 8 June 2015 15:18:50 UTC