Similar to Custom Paint, we wanted to capture some of the properties of a Custom Layout API to agree on goals before heading into implementation details.
Note: "Custom Layout" is used here for both Line & Box Layout.
Anything we should change, remove, or add?
One issue that polyfills cope poorly with today is responding to changes from their parent element, and responding to changes form their child elements.
For example: if a polyfill wants to respond to changes from their parent element, they need to query getBoundingClientRect on every frame & position their children with abs-pos. This gets trickier in the reverse if you need to respond to changes from your child. You need to place the child in a separate element (to simulate changes in availibleWidth) to check what size it'll be.
It’s horrible. Trying to do this properly in a polyfill is really hard. Hence, Custom Layout needs to be a first class citizen in layout, and fully participate in the native layout process.
Similar to Custom Paint, Custom Layout should be explaining the platform, and should be invalidated by Style changes.
Custom Layout code should be invalidated, not required to layout on every frame (if it doesn’t need it)
We want to end up in a situation where we don't need to layout nodes if they aren't required yet. For example if something is known to be in a Layout Root and off the current viewport, the browser should be able to not be required to layout that node.
Custom Layout implementation of flexbox for example shouldn't need any more computation that native flexbox.
It’d be nice to have a guarantee that a particular layout (or combination of layouts) cannot cause layout cycles to occur. Or at least have an amount of safety provided which means that a layout will not have an assigned size if it doesn't stabilize after N layouts or something (just as an example).
We should make sure that Custom Layout doesn’t introduce access to 'strange' or 'dangerous' JavaScript objects, which behave oddly or could cause errors if used incorrectly.
For example, in Custom Layout we'll need an object (let's call it FragmentNode) to perform layout. Keeping this FragmentNode around between calls to layout is dangerous as the engine may have swapped it for a different one, or reusing it between invocations is dangerous as it may not even be attached to the render tree, etc.
To prevent developers from storing a reference to this object, we could neuter the object after each callback. I.e. all methods will throw / return default values.
Similar to Custom Paint, we'd like Custom Layout to not have thread affinity.
Similar to Custom Paint, we'd like all of the Houdini APIs to be consistent with each other.
[Commenting here as it's moslty editorial, look forward to more by email]
This isn't entirely accurate. Since you're abs-posing your children, you can instead override your own width directly, force a layout, and get the min- (width: 0) and max-prefered-width (width: huge) of all child elements in only two extra layouts. That's still bad, I'll admit, but that's not as bad as you depict it.