Skip to content

Commit 75d1e6e

Browse files
committed
[css-layout-api] Add section about ConstraintSpace
1 parent daef753 commit 75d1e6e

File tree

1 file changed

+105
-4
lines changed

1 file changed

+105
-4
lines changed

css-layout-api/README.md

+105-4
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,102 @@ interface Fragment {
8585
};
8686
```
8787

88+
#### The `ConstraintSpace`
89+
90+
A `ConstraintSpace` is a 2D representation of the layout space given to a layout. A constraint space
91+
has:
92+
- A `inlineSize` and `blockSize`. If present, these describe a fixed width in which the layout can
93+
produce a `Fragment`. The layout should produce a `Fragment` which fits inside these bounds. If
94+
it exceeds these bounds, the `Fragment` may be paint clipped, etc, as determined by its parent.
95+
96+
- A `inlineScrollOffset` and `blockScrollOffset`. If present, these describe that if the resulting
97+
`Fragment` exceeds these offsets, it must call `willInlineScroll()` / `willBlockScroll()`. This
98+
will result in the constraint space being updated (and also reset to its initial state?). These
99+
methods will potentially change the `inlineSize` or `blockSize` to allow room for a scrollbar.
100+
101+
- A `inlineFragmentOffset` and `blockFragmentingOffset`. If present, these describe that if the
102+
resulting `Fragment` must fragment at this particular point.
103+
104+
- A list of exclusions. Described more in-depth below.
105+
106+
The `ConstraintSpace` is represented as:
107+
108+
```webidl
109+
partial interface ConstraintSpace {
110+
readonly attribute double? inlineSize;
111+
readonly attribute double? blockSize;
112+
113+
readonly attribute double? inlineScrollOffset;
114+
readonly attribute double? blockScrollOffset;
115+
116+
readonly attribute double? inlineFragmentOffset; // Is inline fragment offset needed?
117+
readonly attribute double? blockFragmentOffset;
118+
119+
void willInlineScroll();
120+
void willBlockScroll();
121+
};
122+
```
123+
124+
This may be better represented as:
125+
126+
```webidl
127+
partial interface ConstraintSpace {
128+
readonly attribute ExtentConstraint inlineConstraint;
129+
readonly attribute ExtentConstraint inlineConstraint;
130+
131+
void willInlineScroll();
132+
void willBlockScroll();
133+
};
134+
135+
enum ExtentConstraintType = 'fixed' | 'scroll' | 'fragment';
136+
137+
interface ExtentConstraint {
138+
readonly attribute ExtentConstraintType type;
139+
readonly attribute double offset;
140+
};
141+
```
142+
143+
Actually this doesn't really work? As you can have an inlineSize, which also can overflow.
144+
145+
Exclusions can be added to the constraint space which children should avoid. E.g.
146+
147+
```webidl
148+
partial interface ConstraintSpace {
149+
void addExclusion(Fragment fragment, optional FlowEnum flow);
150+
void addExclusion(Exclusion fragment, optional FlowEnum flow);
151+
};
152+
```
153+
154+
The author can iterate through the available space via the `layoutOpportunities()` api.
155+
156+
```webidl
157+
partial interface ConstraintSpace {
158+
Generator<LayoutOpportunity> layoutOpportunities();
159+
};
160+
161+
interface LayoutOpportunity {
162+
readonly attribute double inlineSize;
163+
readonly attribute double blockSize;
164+
165+
readonly attribute double inlineStart;
166+
readonly attribute double blockStart;
167+
168+
readonly attribute double inlineEnd;
169+
readonly attribute double blockEnd;
170+
}
171+
```
172+
173+
Here is a cute little gif which shows the layout opportunities for a `ConstraintSpace` with two
174+
exclusions.
175+
176+
![layout opportunities](https://raw.githubusercontent.com/w3c/css-houdini-drafts/blob/master/images/layout_opp.gif)
177+
178+
The layoutOpportunities generator will return a series of max-rects for a given constraint space.
179+
These are ordered by `inlineStart`, `inlineSize` then `blockStart`.
180+
181+
How do we represent non-rect exclusions? Initial thought is to always jump by `1em` of author
182+
specified amount.
183+
88184
### Performing Layout
89185

90186
The Layout API is best described with a simple dummy example:
@@ -126,7 +222,15 @@ This is to allow two things:
126222
1. User agents implementing parallel layout.
127223
2. User agents implementing asynchronous layout.
128224

129-
A user agent could implement the logic driving the author defined layout as:
225+
The generator returns a `FragmentRequest`. Inside of the authors layout funciton, this object is
226+
completely opaque. This is a token for the user-agent to perform layout _at some stage_ for the
227+
particular box it was generated for.
228+
229+
When a `FragmentRequest` is returned from the generator, the user-agent needs to produce a
230+
`Fragment` for it, and return it via. the generator `next()` call.
231+
232+
As a concrete example, the user agent could implement the logic driving the author defined layout
233+
as:
130234

131235
```js
132236
function performLayout(constraintSpace, box) {
@@ -159,6 +263,3 @@ function performLayout(constraintSpace, box) {
159263
return new Fragment(fragmentDict);
160264
}
161265
```
162-
163-
164-
TODO finish writing this.

0 commit comments

Comments
 (0)