Skip to content

Commit 1df9846

Browse files
Copilotemilio
authored andcommitted
Initial plan
Address Emilio's review feedback on GeometryUtils spec definitions Rewrite getCompleteTransform, getBoxQuads, convertQuadFromNode, convertRectFromNode, and convertPointFromNode algorithm definitions using proper bikeshed markup: - Use <div algorithm> block with <dfn> for getCompleteTransform - Use <var> tags for all variables throughout - Use {{}} bikeshed notation for DOM types (DOMQuad, DOMMatrix, etc.) - Reference css-transforms-1 CTM definition properly - Handle Document (layout viewport) vs Element/Text (box fragments) - Use proper <a spec=css-break>box fragment</a> references - Reference margin/padding/border/content edges correctly - Fix relativeTo (not realtiveTo) and use layout viewport as fallback - Give meaningful variable names (thisTransformToViewport, etc.) - Link convertQuadFromNode to convertPointFromNode explicitly - Reference used values of CSS properties for box adjustments Co-authored-by: jogibear9988 <364896+jogibear9988@users.noreply.github.com> Address code review: add detailed box adjustment steps and non-invertible matrix note - Spell out how margin/padding/content box adjustments work using specific CSS property used values - Add note about non-invertible transformation matrices - Add link-defaults for border-right-width and border-bottom-width Co-authored-by: jogibear9988 <364896+jogibear9988@users.noreply.github.com> Initial plan Fix bikeshed reference: use [=list=] in getBoxQuads algorithm Co-authored-by: jogibear9988 <364896+jogibear9988@users.noreply.github.com> Agent-Logs-Url: https://github.com/jogibear9988/csswg-drafts/sessions/2cc807ab-9305-4dd8-b0f7-dafb7f3c6be2 Work on description of getBoxQuads API Update Overview.bs Update Overview.bs fix duplicated ol fixes fixes adjust spec Initial plan I updated the GeometryUtils section to address the review feedback. The main changes are: - rewrote getBoxQuads() in terms of nodes and box fragments, with layout-viewport coordinates as the default when relativeTo is omitted - added explicit Document and Text handling - moved the box-space wording to helper algorithms and removed the margin/padding/content edge arithmetic based on used values - reused convertQuadFromNode()/convertPointFromNode() for the actual coordinate conversion path I also validated the edited file locally. A remote Bikeshed run still hits unrelated existing markdown errors later in cssom-view-1, but it did not report new fatal issues in the GeometryUtils block. fixes after review
1 parent 169b434 commit 1df9846

1 file changed

Lines changed: 174 additions & 25 deletions

File tree

‎cssom-view-1/Overview.bs‎

Lines changed: 174 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ spec:dom; type:dfn; text:element
5353
spec:dom; type:dfn; for:Attr; text:element
5454
spec:css-borders-4; type:property; text:border-top-width
5555
spec:css-borders-4; type:property; text:border-left-width
56+
spec:css-borders-4; type:property; text:border-right-width
57+
spec:css-borders-4; type:property; text:border-bottom-width
5658
spec:cssom-view-1; type:dictionary; text:MouseEventInit
5759
spec:cssom-view-1; type:dfn; for:MediaQueryList; text:media
5860
spec:webdriver-bidi; type:dfn;
@@ -2196,7 +2198,7 @@ The <dfn attribute for=MouseEvent>offsetY</dfn> attribute must follow these step
21962198
enum CSSBoxType { "margin", "border", "padding", "content" };
21972199
dictionary BoxQuadOptions {
21982200
CSSBoxType box = "border";
2199-
GeometryNode relativeTo; // XXX default document (i.e. viewport)
2201+
GeometryNode relativeTo;
22002202
};
22012203

22022204
dictionary ConvertCoordinateOptions {
@@ -2208,7 +2210,7 @@ interface mixin GeometryUtils {
22082210
sequence&lt;DOMQuad> getBoxQuads(optional BoxQuadOptions options = {});
22092211
DOMQuad convertQuadFromNode(DOMQuadInit quad, GeometryNode from, optional ConvertCoordinateOptions options = {});
22102212
DOMQuad convertRectFromNode(DOMRectReadOnly rect, GeometryNode from, optional ConvertCoordinateOptions options = {});
2211-
DOMPoint convertPointFromNode(DOMPointInit point, GeometryNode from, optional ConvertCoordinateOptions options = {}); // XXX z,w turns into 0
2213+
DOMPoint convertPointFromNode(DOMPointInit point, GeometryNode from, optional ConvertCoordinateOptions options = {});
22122214
};
22132215

22142216
Text includes GeometryUtils; // like Range
@@ -2219,26 +2221,158 @@ Document includes GeometryUtils;
22192221
typedef (Text or Element or CSSPseudoElement or Document) GeometryNode;
22202222
</pre>
22212223

2222-
The <dfn method for=GeometryUtils lt="getBoxQuads(options)|getBoxQuads()">getBoxQuads(<var>options</var>)</dfn> method must run the following steps:
2223-
2224-
<ol>
2225-
<li class=issue>
2226-
DOM order
2227-
2228-
p1 = top left even in RTL
2229-
2230-
scale to 0 means divide by zero, return 0x0
2231-
2232-
cross-frames not allowed, throw WrongDocumentError?
2224+
The {{GeometryUtils}} methods operate on a node's local box geometry.
2225+
The {{GeometryUtils/getBoxQuads()}} method returns one {{DOMQuad}} per relevant
2226+
box fragment, in <a>flat tree</a> order.
2227+
Unless {{BoxQuadOptions/relativeTo}} is specified,
2228+
the returned coordinates are expressed relative to the <a>layout viewport</a>.
2229+
2230+
<div algorithm="get the complete transform">
2231+
To <dfn export>get the complete transform</dfn> of a {{GeometryNode}} <var>node</var>
2232+
relative to a {{GeometryNode}} <var>ancestor</var>,
2233+
run the following steps:
2234+
2235+
1. Let <var>current</var> be <var>node</var>.
2236+
1. Let <var>transformationMatrix</var> be a new {{DOMMatrix}}.
2237+
1. While <var>current</var> is not null:
2238+
1. If <var>current</var> is <var>ancestor</var>, return <var>transformationMatrix</var>.
2239+
1. Let <var>nextAncestor</var> be null.
2240+
1. If <var>current</var> is an {{Element}}, then:
2241+
1. Let <var>currentTransformationMatrix</var> be a new {{DOMMatrix}}
2242+
representing the [=current transformation matrix=] of <var>current</var>. [[!CSS-TRANSFORMS-1]]
2243+
1. Set <var>transformationMatrix</var> to the result of multiplying
2244+
<var>currentTransformationMatrix</var> by <var>transformationMatrix</var>.
2245+
1. If there is an element that establishes the [=containing block=] of <var>current</var>,
2246+
let <var>nextAncestor</var> be that element.
2247+
Otherwise, let <var>nextAncestor</var> be <var>current</var>'s <a>node document</a>.
2248+
1. If <var>nextAncestor</var> is a {{Document}},
2249+
let <var>offsetX</var> be the horizontal offset and <var>offsetY</var>
2250+
be the vertical offset from the <a>border edge</a> of <var>current</var>
2251+
to the origin of the <a>initial containing block</a>,
2252+
ignoring any <a>transforms</a> that apply to <var>current</var> and its ancestors.
2253+
Otherwise, let <var>offsetX</var> be the horizontal offset and <var>offsetY</var>
2254+
be the vertical offset from the <a>border edge</a> of <var>current</var>
2255+
to the <a>border edge</a> of <var>nextAncestor</var>,
2256+
ignoring any <a>transforms</a> that apply to <var>current</var> and its ancestors.
2257+
1. Let <var>translationMatrix</var> be a new {{DOMMatrix}} representing a
2258+
translation by <var>offsetX</var> and <var>offsetY</var>.
2259+
1. Set <var>transformationMatrix</var> to the result of multiplying
2260+
<var>translationMatrix</var> by <var>transformationMatrix</var>.
2261+
1. Otherwise, if <var>current</var> is a {{Text}}, set <var>nextAncestor</var> to <var>current</var>'s <a>parent element</a>.
2262+
1. Otherwise, if <var>current</var> is a {{CSSPseudoElement}}, set <var>nextAncestor</var> to <var>current</var>'s <a>originating element</a>.
2263+
1. Set <var>current</var> to <var>nextAncestor</var>.
2264+
1. Return <var>transformationMatrix</var>.
2265+
</div>
22332266

2234-
points are flattened (3d transform), z=0. like getClientRect
2267+
<div algorithm="adjust a point to the border box">
2268+
To <dfn export>adjust a point to the border box</dfn> given a {{DOMPoint}} <var>point</var>,
2269+
a {{GeometryNode}} <var>node</var>, and a {{CSSBoxType}} <var>box</var>,
2270+
run the following steps:
2271+
2272+
1. Let <var>adjustedPoint</var> be a new {{DOMPoint}} with the same
2273+
{{DOMPoint/x}} and {{DOMPoint/y}} as <var>point</var>.
2274+
1. If <var>node</var> is a {{Document}} or a {{Text}}, return <var>adjustedPoint</var>.
2275+
1. If <var>box</var> is {{CSSBoxType/"margin"}},
2276+
adjust <var>adjustedPoint</var> so that it refers to the same physical point
2277+
in <var>node</var>'s local coordinate space,
2278+
but with coordinates measured from the top-left corner of <var>node</var>'s
2279+
[=border box=] rather than the top-left corner of its [=margin box=].
2280+
1. If <var>box</var> is {{CSSBoxType/"padding"}},
2281+
adjust <var>adjustedPoint</var> so that it refers to the same physical point
2282+
in <var>node</var>'s local coordinate space,
2283+
but with coordinates measured from the top-left corner of <var>node</var>'s
2284+
[=border box=] rather than the top-left corner of its [=padding box=].
2285+
1. If <var>box</var> is {{CSSBoxType/"content"}},
2286+
adjust <var>adjustedPoint</var> so that it refers to the same physical point
2287+
in <var>node</var>'s local coordinate space,
2288+
but with coordinates measured from the top-left corner of <var>node</var>'s
2289+
[=border box=] rather than the top-left corner of its [=content box=].
2290+
1. Return <var>adjustedPoint</var>.
2291+
</div>
22352292

2236-
test block in inline
2293+
<div algorithm="adjust a point from the border box">
2294+
To <dfn export>adjust a point from the border box</dfn> given a {{DOMPoint}} <var>point</var>,
2295+
a {{GeometryNode}} <var>node</var>, and a {{CSSBoxType}} <var>box</var>,
2296+
run the following steps:
2297+
2298+
1. Let <var>adjustedPoint</var> be a new {{DOMPoint}} with the same
2299+
{{DOMPoint/x}} and {{DOMPoint/y}} as <var>point</var>.
2300+
1. If <var>node</var> is a {{Document}} or a {{Text}}, return <var>adjustedPoint</var>.
2301+
1. If <var>box</var> is {{CSSBoxType/"margin"}},
2302+
adjust <var>adjustedPoint</var> so that it refers to the same physical point
2303+
in <var>node</var>'s local coordinate space,
2304+
but with coordinates measured from the top-left corner of <var>node</var>'s
2305+
[=margin box=] rather than the top-left corner of its [=border box=].
2306+
1. If <var>box</var> is {{CSSBoxType/"padding"}},
2307+
adjust <var>adjustedPoint</var> so that it refers to the same physical point
2308+
in <var>node</var>'s local coordinate space,
2309+
but with coordinates measured from the top-left corner of <var>node</var>'s
2310+
[=padding box=] rather than the top-left corner of its [=border box=].
2311+
1. If <var>box</var> is {{CSSBoxType/"content"}},
2312+
adjust <var>adjustedPoint</var> so that it refers to the same physical point
2313+
in <var>node</var>'s local coordinate space,
2314+
but with coordinates measured from the top-left corner of <var>node</var>'s
2315+
[=content box=] rather than the top-left corner of its [=border box=].
2316+
1. Return <var>adjustedPoint</var>.
2317+
</div>
22372318

2238-
pseudo-elements before/after are children of the element
2319+
The <dfn method for=GeometryUtils lt="getBoxQuads(options)|getBoxQuads()">getBoxQuads(<var>options</var>)</dfn> method must run the following steps:
22392320

2240-
viewport boxes are all the same
2241-
</ol>
2321+
1. Let <var>node</var> be [=this=].
2322+
1. If <var>node</var> is a {{Document}}, let <var>document</var> be <var>node</var>.
2323+
1. Otherwise, if <var>node</var> is a {{CSSPseudoElement}}, let <var>document</var> be <var>node</var>'s <a>originating element</a>'s <a>node document</a>.
2324+
1. Otherwise, let <var>document</var> be <var>node</var>'s <a>node document</a>.
2325+
1. If <var>options</var>.{{BoxQuadOptions/relativeTo}} is specified,
2326+
let <var>relativeTo</var> be <var>options</var>.{{BoxQuadOptions/relativeTo}}.
2327+
Otherwise, let <var>relativeTo</var> be <var>document</var>.
2328+
1. Let <var>result</var> be an empty [=list=] of {{DOMQuad}} objects.
2329+
1. If <var>node</var> is a {{Document}}, then:
2330+
1. Let <var>rect</var> be a {{DOMRect}} whose {{DOMRect/x}} and {{DOMRect/y}} are 0,
2331+
and whose {{DOMRect/width}} and {{DOMRect/height}} are the width and height
2332+
of the <a>layout viewport</a>.
2333+
1. Let <var>quad</var> be the result of invoking {{DOMQuad/fromRect()}} with <var>rect</var>.
2334+
1. [=list/Append=] the result of invoking the {{GeometryUtils/convertQuadFromNode()}} method on <var>relativeTo</var>
2335+
with <var>quad</var> and <var>document</var> to <var>result</var>.
2336+
1. Otherwise, if <var>node</var> is a {{Text}}, then:
2337+
1. For each {{DOMRect}} <var>rect</var> returned by invoking the {{Range/getClientRects()}} method
2338+
on a {{Range}} whose boundary-points select exactly <var>node</var>, in content order:
2339+
1. Let <var>quad</var> be the result of invoking {{DOMQuad/fromRect()}} with <var>rect</var>.
2340+
1. [=list/Append=] the result of invoking the {{GeometryUtils/convertQuadFromNode()}} method on <var>relativeTo</var>
2341+
with <var>quad</var> and <var>document</var> to <var>result</var>.
2342+
1. Otherwise, for each <a spec=css-break>box fragment</a> of <var>node</var>,
2343+
in content order, run the following steps:
2344+
1. Let <var>rect</var> be a {{DOMRect}} describing the <a>border area</a> of
2345+
the <a spec=css-break>box fragment</a>, positioned in the fragment's local coordinate space
2346+
with its <a>border edge</a> at {{DOMRect/x}} = 0 and {{DOMRect/y}} = 0.
2347+
1. If <var>options</var>.{{BoxQuadOptions/box}} is
2348+
{{CSSBoxType/"margin"}},
2349+
let <var>rect</var> instead be a {{DOMRect}} describing the fragment's <a>margin area</a>
2350+
in the same local coordinate space,
2351+
with the fragment's <a>border edge</a> still at {{DOMRect/x}} = 0 and {{DOMRect/y}} = 0.
2352+
1. If <var>options</var>.{{BoxQuadOptions/box}} is
2353+
{{CSSBoxType/"padding"}},
2354+
let <var>rect</var> instead be a {{DOMRect}} describing the fragment's <a>padding area</a>
2355+
in the same local coordinate space,
2356+
with the fragment's <a>border edge</a> still at {{DOMRect/x}} = 0 and {{DOMRect/y}} = 0.
2357+
1. If <var>options</var>.{{BoxQuadOptions/box}} is
2358+
{{CSSBoxType/"content"}},
2359+
let <var>rect</var> instead be a {{DOMRect}} describing the fragment's <a>content area</a>
2360+
in the same local coordinate space,
2361+
with the fragment's <a>border edge</a> still at {{DOMRect/x}} = 0 and {{DOMRect/y}} = 0.
2362+
1. Let <var>quad</var> be the result of invoking {{DOMQuad/fromRect()}} with <var>rect</var>.
2363+
1. [=list/Append=] the result of invoking the {{GeometryUtils/convertQuadFromNode()}} method on <var>relativeTo</var>
2364+
with <var>quad</var> and <var>node</var> to <var>result</var>.
2365+
1. Return <var>result</var>.
2366+
2367+
Note: The points are flattened (3D transforms project to z=0),
2368+
similar to {{Element/getClientRects()}}.
2369+
{{DOMQuad/p1}} is always the physical top-left corner of the box,
2370+
even in right-to-left writing modes.
2371+
For {{Document}} and {{Text}} nodes,
2372+
all four values of {{BoxQuadOptions/box}} return the same geometry.
2373+
If a transformation matrix is not invertible
2374+
(e.g. due to a ''transform/scale()'' of 0),
2375+
the resulting coordinates are implementation-defined.
22422376

22432377
<wpt>
22442378
cssom-getBoxQuads-001.html
@@ -2249,22 +2383,37 @@ The <dfn method for=GeometryUtils lt="convertQuadFromNode(quad, from, options)|c
22492383
must run the following steps:
22502384

22512385
<ol>
2252-
<li><p class=issue>...
2386+
1. transform each point of the DOMQuad via convertPointFromNode
22532387
</ol>
22542388

22552389
The <dfn method for=GeometryUtils lt="convertRectFromNode(rect, from, options)|convertRectFromNode(rect, from)">convertRectFromNode(<var>rect</var>, <var>from</var>, <var>options</var>)</dfn> method
22562390
must run the following steps:
22572391

22582392
<ol>
2259-
<li><p class=issue>...
2393+
1. create a DOMQuad from the rect via DOMQuad.fromRect
2394+
2. transform each point of the DOMQuad from 1. via convertPointFromNode
22602395
</ol>
22612396

22622397
The <dfn method for=GeometryUtils lt="convertPointFromNode(point, from, options)|convertPointFromNode(point, from)">convertPointFromNode(<var>point</var>, <var>from</var>, <var>options</var>)</dfn>
2263-
method must run the following steps:
2264-
2265-
<ol>
2266-
<li><p class=issue>...
2267-
</ol>
2398+
method returns a point flattened to 2D and must run the following steps:
2399+
2400+
1. Let <var>node</var> be [=this=].
2401+
1. Let <var>thisTransformToViewport</var> be the result of
2402+
<a>getting the complete transform</a> of <var>node</var>
2403+
relative to null.
2404+
1. Let <var>fromTransformToViewport</var> be the result of
2405+
<a>getting the complete transform</a> of <var>from</var>
2406+
relative to null.
2407+
1. Let <var>adjustedPoint</var> be the result of
2408+
<a>adjusting a point to the border box</a> given <var>point</var>,
2409+
<var>from</var>, and <var>options</var>.{{ConvertCoordinateOptions/fromBox}}.
2410+
1. Set <var>adjustedPoint</var> to the result of transforming
2411+
<var>adjustedPoint</var> by <var>fromTransformToViewport</var>.
2412+
1. Set <var>adjustedPoint</var> to the result of transforming
2413+
<var>adjustedPoint</var> by the inverse of <var>thisTransformToViewport</var>.
2414+
1. Return the result of <a>adjusting a point from the border box</a>
2415+
given <var>adjustedPoint</var>, <var>node</var>,
2416+
and <var>options</var>.{{ConvertCoordinateOptions/toBox}}.
22682417

22692418
<h2 id=visualViewport>VisualViewport</h2>
22702419

0 commit comments

Comments
 (0)