Re: [CSSOM] Revisiting transforms and getBoundingClientRect()

On Thu, 19 Sep 2013 22:09:43 +0200, Robert O'Callahan  
<> wrote:

> No, I think it's simpler if DOMQuad is pure geometry --- just four  
> points.
> Then we can, for example, provide a method that transforms a DOMQuad by a
> DOMMatrix to produce another DOMQuad. And because DOMPoints can be in 3D
> space, we can also support APIs that treat DOMQuads as 3D objects.


We might want to expose the CSS boxes in the future so that it's possible  
to get the used style of each box of an element, but we could use separate  
objects for that I guess. In any case, we can wait with this until the  
current GetStyleUtils has some implementation experience.

>>> [Constructor(CSSPoint, CSSPoint, CSSPoint, CSSPoint),
>>>  Constructor(ClientRect)]
>> What's the use case for this constructor?
> Which one?

Well, both.

> I guess I don'thave a use-case for these right now. Let's drop
> them and we can add them later if they turn out to be useful.

On Fri, 20 Sep 2013 05:30:27 +0200, Robert O'Callahan  
<> wrote:

> On Fri, Sep 20, 2013 at 8:41 AM, Tab Atkins Jr.  
> <>wrote:
>> I prefer going the other way - having constructable interfaces unless
>> there's a reason not to do so.

> Actually yes, for writing tests for convertRectFromNode and
> convertQuadFromNode I need constructors that let me construct arbitrary
> DOMRects and DOMQuads. Is that a valid use-case? I think so :-).

The testing use case was used for adding a constructor for File, so it can  
be, yeah.

>>  interface Quad {
>>>   readonly attribute CSSPoint p1; // 2D only (z,w not present)
>>>   readonly attribute CSSPoint p2;
>>>   readonly attribute CSSPoint p3;
>>>   readonly attribute CSSPoint p4;
>>>   readonly attribute CSSRect bounds;
>>> };
>>> [Constructor(sequence<Quad>)]
>> What's the use case for this constructor?
>>  interface QuadList {
>>>   readonly attribute unsigned long length;
>>>   getter Quad item(unsigned long index);
>>>   readonly attribute CSSRect bounds;
>>> };
> Never mind, let's get rid of QuadList since getBoxQuads can just return
> sequence<DOMQuad>.


>>> enum BoxType { "margin", "border", "padding", "content" };
>>> dictionary BoxQuadOptions {
>>>   attribute BoxType box; // defaults to "border"
>>>   attribute Node relativeTo; // defaults to viewport
>> Which object gets to represent the viewport? Since the type is Node, the
>> closest fit is Document, but we don't have to use that. We could use  
>> Window
>> instead if we want.
> A Window is not a Node. I think we should use Document.

That it's not a Node doesn't actually matter. I think it's more important  
to have the API be intiutive for Web developers -- do they think of the  
document as mapping to the viewport, or the window? (I guess some think of  
<body> as mapping to the viewport, or the root element, but clearly it's  
useful to distinguish the viewport from those elements.)

Apart from the intiutiveness, another consideration is whether we want to  
expose the methods on the global or on document.

>> Also, should we restrict the set of Nodes that participate in the API to
>> Element and Text (and Window or Document for the viewport)? Does it make
>> sense to have the methods below on DocumentFragment, DocumentType,
>> ProcessingInstruction and Comment?
> I don't believe it does, so we should restrict the set of nodes to  
> Element,
> Text, and Document.


> Do we want PseudoElement to participate in this API?
> Hmm. Where is PseduoElement specified? I'm not familiar with it.

What Tab said:

On Thu, 19 Sep 2013 22:41:19 +0200, Tab Atkins Jr. <>  

> <>. Right
> now it's just something to hang the style APIs off of, but it's a
> great thing to use for everything else pseudo-element-ish.

So, taking everything so far into consideration (let me know if I missed  
something), API-wise, I have this:

dictionary DOMPointLiteral {
   double w = 1;
   double x = 0;
   double y = 0;
   double z = 0;

interface DOMPoint {
   readonly attribute double w;
   readonly attribute double x;
   readonly attribute double y;
   readonly attribute double z;

[Constructor(DOMPointLiteral p1, DOMPointLiteral p2, DOMPointLiteral p3,  
DOMPointLiteral p4),
  Constructor(DOMRect rect)]
interface DOMQuad {
   readonly attribute DOMPoint p1;
   readonly attribute DOMPoint p2;
   readonly attribute DOMPoint p3;
   readonly attribute DOMPoint p4;
   readonly attribute DOMRect bounds;

enum CSSBoxType { "margin", "border", "padding", "content" };
dictionary BoxQuadOptions {
   CSSBoxType box; // defaults to "border"
   GeometryNode relativeTo; // defaults to viewport

dictionary ConvertCoordinateOptions {
   CSSBoxType fromBox; // defaults to "border"
   CSSBoxType toBox; // defaults to "border"

interface GetGeometryUtils {
   sequence<DOMQuad> getBoxQuads(BoxQuadOptions options);
   DOMQuad convertQuadFromNode(DOMQuad quad, GeometryNode from, optional  
ConvertCoordinateOptions options);
   DOMQuad convertRectFromNode(DOMRect rect, GeometryNode from, optional  
ConvertCoordinateOptions options);
   DOMPoint convertPointFromNode(DOMPointLiteral point, GeometryNode from,  
optional ConvertCoordinateOptions options);

Text implements GetGeometryUtils;
Element implements GetGeometryUtils;
PseudoElement implements GetGeometryUtils;
Document implements GetGeometryUtils;

typedef (Text or Element or PseudoElement or Document) GeometryNode;

[Constructor(double left, double top, double width, double height)]
interface DOMRect : DOMQuad {
   // same members as currently in cssom-view

The Point dictionary in uses  
unrestricted double rather than double. Why? Does it make sense to allow  

Simon Pieters
Opera Software

Received on Friday, 20 September 2013 09:56:16 UTC