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

Glad I could help! Looking over the new proposal, it seems complicated, but as far as I can tell sound, assuming everything gets constructors. Only a few minor things:

> interface AnimationTimingReadOnly : AnimationTiming { ... };

I assume this was supposed to be the other way around?

>From the notes:

> I've gone with a method for getComputedTiming since we're returning a dictionary. (Is that right? Can't use a dictionary as an attribute right?)

This is currently true in WebIDL, but is a dumb limitation that we are exploring ways of fixing. In fact there's a rather lively discussion going on over on the web crypto list in this regard. Trying to bypass it requires thinking through a few tricky things, though; we hope to eventually make it easy, but for now we are still struggling. In your case is likely not worth it for just one method; in web crypto's case it is worth diving into because it avoids a pretty bad alternative. But if you're interested anyway, let me know and we can explore that.

________________________________________
From: Brian Birtles <bbirtles@mozilla.com>
Sent: Thursday, July 10, 2014 22:11
To: Domenic Denicola; public-fx@w3.org
Cc: Cameron McCormack; Boris Zbarsky
Subject: Re: [web-animations] Readonly interfaces and inheritance: seeking  advice

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:

   http://lists.w3.org/Archives/Public/public-fx/2014JulSep/0013.html

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 ();
   };

Assuming:

   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
above.[1]

Best regards,

Brian

[1] http://lists.w3.org/Archives/Public/public-fx/2014JulSep/0013.html,
item 2.

Received on Monday, 14 July 2014 20:45:28 UTC