W3C home > Mailing lists > Public > public-fx@w3.org > July to September 2014

Re: [web-animations] Readonly interfaces and inheritance: seeking advice

From: Brian Birtles <bbirtles@mozilla.com>
Date: Fri, 11 Jul 2014 11:11:56 +0900
Message-ID: <53BF47EC.50704@mozilla.com>
To: Domenic Denicola <domenic@domenicdenicola.com>, "public-fx@w3.org" <public-fx@w3.org>
CC: Cameron McCormack <cam@mcc.id.au>, Boris Zbarsky <bzbarsky@MIT.EDU>
Hi Domenic,

Thanks for all your help here. It is much appreciated.

On 2014/07/10 5:36, Domenic Denicola wrote:
>> What do you think of this hierarchy? Is there a better way of
>> keeping AnimationTiming and ComputedAnimationTiming in sync without
>> introducing AnimationTimingReadOnly?
> I can't really see the benefits of the hierarchy as-is. In
> particular, I don't see any concrete uses of the
> AnimationTimingReadOnly interface in the API: no properties expose
> it, for example. It doesn't even seem that helpful as a spec device,
> since AnimationTiming has to duplicate all the members of
> AnimationTimingReadOnly anyway, so you have to synchronize those.
> At the very least, I would make AnimationTimingReadOnly into e.g.
> `[NoInterfaceObject] SharedAnimationTimingProperties` and use
> `implements` instead of `:`, so that it becomes a spec-device mixin
> instead of an exposed-to-JavaScript inheritance hierarchy. But there
> may be better options.

We discussed this in our telcon yesterday and decided on the arrangement 
described in point 2 from the following minutes:


However, I've since encountered one reason we might want the 
AnimationTimingReadOnly interface after all.

In order to allow exposing animations representing CSS animations as 
read-only objects we were looking at doing something like this:

   interface AnimationPlayer {
     attribute AnimationNodeReadOnly? source;

   interface AnimationNodeReadOnly {
     readonly attribute AnimationTimingReadOnly timing;
     ComputedAnimationTiming getComputedTiming();

     readonly attribute AnimationGroupReadOnly? parent;
     readonly attribute AnimationNodeReadOnly?  previousSibling;
     readonly attribute AnimationNodeReadOnly?  nextSibling;

     AnimationNode clone();

   // cf.
   interface AnimationNode {
     attribute AnimationTiming timing;
     ComputedAnimationTiming getComputedTiming();

     readonly attribute AnimationGroup? parent;
     readonly attribute AnimationNode?  previousSibling;
     readonly attribute AnimationNode?  nextSibling;

     // These methods don't appear on the ReadOnly version
     void before (AnimationNode... nodes);
     void after (AnimationNode... nodes);
     void replace (AnimationNode... nodes);
     void remove ();

     AnimationNode clone();

   // Similarly for:
   // AnimationTiming(ReadOnly)
   // AnimationGroup(ReadOnly)
   // Animation(ReadOnly)

The idea is that when you inspect CSS animations/transitions:

* You get back a player whose source content (the definition of the 
animation) is completely read-only.

* The player itself, however, is still modifiable so you can 
pause/rewind the animation etc.

* If you want to make changes to the source content you clone the 
read-only object, get a writeable copy, then set the source of the 
player to the new writeable version. That way you break any association 
with the CSS markup and avoid weird situations where the object is 
partially live, partially overwritten.

Obviously the above definition doesn't work since AnimationNode doesn't 
inherit/implement AnimationNodeReadOnly so you can't set your cloned 
copy on the player.

Inheritance seems to work. I think AnimationNode would become:

   interface AnimationNode : AnimationNodeReadOnly {
     inherit attribute AnimationTimingReadOnly timing;

     void before (AnimationNode... nodes);
     void after (AnimationNode... nodes);
     void replace (AnimationNode... nodes);
     void remove ();


   interface AnimationTimingReadOnly : AnimationTiming { ... };

Note that we would actually have concrete *ReadOnly objects 
corresponding to objects representing CSS animations.

"Implements" doesn't work in this case since, as I understand it, we 
can't currently have:

   interface A {
     readonly attribute Foo foo;

   interface B {
     attribute Foo foo;

   B implements A;

i.e. the "inherits its getter" behavior is only available for 
inheritance, not implements.

I tried using unions as well but didn't get any further.

I've incorporated the rest of your feedback into the summary linked to 

Best regards,


[1] http://lists.w3.org/Archives/Public/public-fx/2014JulSep/0013.html, 
item 2.
Received on Friday, 11 July 2014 02:12:13 UTC

This archive was generated by hypermail 2.4.0 : Friday, 17 January 2020 19:49:50 UTC