Skip to content

Instantly share code, notes, and snippets.

Created June 1, 2015 03:53
Show Gist options
  • Save bfgeek/93408fe4182d87e92b7b to your computer and use it in GitHub Desktop.
Save bfgeek/93408fe4182d87e92b7b to your computer and use it in GitHub Desktop.

Properties of Custom Layout

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?

Required Properties of Custom Layout

Custom Layout should be able to fully participate in native layout

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.

Custom Layout is invalidated by Style

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 should be just as (call) efficient as native layout.

Custom Layout implementation of flexbox for example shouldn't need any more computation that native flexbox.

Nice to have properties of Custom Layout

Unable to create layout cycles (or have some amount of safety)

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).

Make it really hard in Custom Layout to "Do the wrong thing"™

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.

Not explicitly tied to a particular thread / number of threads in the browser

Similar to Custom Paint, we'd like Custom Layout to not have thread affinity.

Consistent with other Houdini APIs, e.g. Custom Paint, Custom Style Resolution.

Similar to Custom Paint, we'd like all of the Houdini APIs to be consistent with each other.

Copy link

[Commenting here as it's moslty editorial, look forward to more by email]

You need to place the child in a separate element (to simulate changes
in availibleWidth) to check what size it'll be.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment