Bug 223569 - [css-contain] Support contain: layout
Summary: [css-contain] Support contain: layout
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: CSS (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Rob Buis
URL:
Keywords: InRadar
Depends on:
Blocks: 172026
  Show dependency treegraph
 
Reported: 2021-03-22 02:11 PDT by Rob Buis
Modified: 2021-04-22 13:38 PDT (History)
23 users (show)

See Also:


Attachments
Patch (126.58 KB, patch)
2021-03-22 04:02 PDT, Rob Buis
no flags Details | Formatted Diff | Diff
Patch (15.88 KB, patch)
2021-03-23 02:40 PDT, Rob Buis
no flags Details | Formatted Diff | Diff
Patch (20.24 KB, patch)
2021-03-24 01:45 PDT, Rob Buis
no flags Details | Formatted Diff | Diff
Patch (21.62 KB, patch)
2021-03-31 01:18 PDT, Rob Buis
no flags Details | Formatted Diff | Diff
Patch (22.16 KB, patch)
2021-03-31 06:19 PDT, Rob Buis
no flags Details | Formatted Diff | Diff
Patch (21.48 KB, patch)
2021-04-02 02:55 PDT, Rob Buis
no flags Details | Formatted Diff | Diff
Patch (21.61 KB, patch)
2021-04-02 03:18 PDT, Rob Buis
no flags Details | Formatted Diff | Diff
Patch (23.42 KB, patch)
2021-04-05 08:18 PDT, Rob Buis
no flags Details | Formatted Diff | Diff
Patch (22.11 KB, patch)
2021-04-06 05:20 PDT, Rob Buis
no flags Details | Formatted Diff | Diff
Patch (22.32 KB, patch)
2021-04-13 01:40 PDT, Rob Buis
no flags Details | Formatted Diff | Diff
Patch (22.20 KB, patch)
2021-04-13 08:43 PDT, Rob Buis
no flags Details | Formatted Diff | Diff
Patch (22.78 KB, patch)
2021-04-18 04:02 PDT, Rob Buis
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Rob Buis 2021-03-22 02:11:36 PDT
Support contain: layout.
Comment 1 Rob Buis 2021-03-22 04:02:48 PDT
Created attachment 423869 [details]
Patch
Comment 2 Rob Buis 2021-03-23 02:40:18 PDT
Created attachment 424002 [details]
Patch
Comment 3 Simon Fraser (smfr) 2021-03-23 09:32:28 PDT
Since all the 'contain' implementations are likely to be somewhat involved, I think you should write up a page on the wiki describing your plans, and to solicit pre-patch feedback.
Comment 4 Rob Buis 2021-03-24 01:45:35 PDT
Created attachment 424106 [details]
Patch
Comment 5 EWS Watchlist 2021-03-24 01:46:31 PDT
This patch modifies the imported WPT tests. Please ensure that any changes on the tests (not coming from a WPT import) are exported to WPT. Please see https://trac.webkit.org/wiki/WPTExportProcess
Comment 6 Radar WebKit Bug Importer 2021-03-29 09:14:39 PDT
<rdar://problem/75956829>
Comment 7 Rob Buis 2021-03-31 01:18:38 PDT
Created attachment 424744 [details]
Patch
Comment 8 Rob Buis 2021-03-31 06:19:56 PDT
Created attachment 424765 [details]
Patch
Comment 9 Simon Fraser (smfr) 2021-03-31 09:52:11 PDT
(In reply to Simon Fraser (smfr) from comment #3)
> Since all the 'contain' implementations are likely to be somewhat involved,
> I think you should write up a page on the wiki describing your plans, and to
> solicit pre-patch feedback.

Did this happen?
Comment 10 Rob Buis 2021-03-31 09:54:12 PDT
(In reply to Simon Fraser (smfr) from comment #9)
> (In reply to Simon Fraser (smfr) from comment #3)
> > Since all the 'contain' implementations are likely to be somewhat involved,
> > I think you should write up a page on the wiki describing your plans, and to
> > solicit pre-patch feedback.
> 
> Did this happen?

Yes, sorry, here it is https://trac.webkit.org/wiki/CSSContainment. We plan to add more for the remaining features (like contain: paint) once we start prototyping.
Comment 11 Rob Buis 2021-04-02 02:55:37 PDT
Created attachment 425001 [details]
Patch
Comment 12 Rob Buis 2021-04-02 03:18:50 PDT
Created attachment 425004 [details]
Patch
Comment 13 Rob Buis 2021-04-05 08:18:42 PDT
Created attachment 425152 [details]
Patch
Comment 14 Rob Buis 2021-04-06 05:20:02 PDT
Created attachment 425265 [details]
Patch
Comment 15 Rob Buis 2021-04-08 08:52:31 PDT
This is ready for review :)
Comment 16 Simon Fraser (smfr) 2021-04-12 14:31:58 PDT
Comment on attachment 425265 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=425265&action=review

> Source/WebCore/rendering/RenderLayer.cpp:584
> -    return !renderer().style().hasAutoUsedZIndex() || isRenderViewLayer();
> +    return renderer().shouldApplyLayoutContainment() || !renderer().style().hasAutoUsedZIndex() || isRenderViewLayer();

This isn't the right way to do this. You should d this in Style::Adjuster::adjust()
Comment 17 Rob Buis 2021-04-13 01:40:08 PDT
Created attachment 425847 [details]
Patch
Comment 18 Rob Buis 2021-04-13 08:43:19 PDT
Created attachment 425874 [details]
Patch
Comment 19 Rob Buis 2021-04-13 11:57:25 PDT
Comment on attachment 425265 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=425265&action=review

>> Source/WebCore/rendering/RenderLayer.cpp:584
>> +    return renderer().shouldApplyLayoutContainment() || !renderer().style().hasAutoUsedZIndex() || isRenderViewLayer();
> 
> This isn't the right way to do this. You should d this in Style::Adjuster::adjust()

I see, I moved the logic there in the latest patch.
Comment 20 Darin Adler 2021-04-17 22:00:16 PDT
Comment on attachment 425874 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=425874&action=review

No need for a feature flag?

> Source/WebCore/rendering/RenderBlock.cpp:2578
> +        return Optional<LayoutUnit>();

WTF::nullopt is the way we normally write this; not sure why we’re using something different here

> Source/WebCore/rendering/RenderBlock.cpp:2596
> +        return Optional<LayoutUnit>(synthesizedBaselineFromBorderBox(*this, lineDirection) + (lineDirection == HorizontalLine ? marginBottom(): marginLeft()));

We normally put a space before the ":".

Also, is the Optional<LayoutUnit> really needed? Can we just write LayoutUnit instead? Or nothing at all?

> Source/WebCore/rendering/RenderObject.h:189
> +    bool isAtomicInlineLevelBox() const
> +    {
> +        return style().isDisplayInlineType() && !(style().display() == DisplayType::Inline && !isReplaced());
> +    }

In a large class like this, it’s best to keep multi-line function bodies (even if only one line has code) out of the class definition so we can see an overview of what’s in the class rather than have it interspersed with code. Instead we can just put an inline implementation after the class. See RenderObject::isBeforeContent for an example.

> Source/WebCore/rendering/RenderObject.h:191
> +    inline bool shouldApplyLayoutContainment() const

The inline here is unneeded and redundant if we are putting the function body inside the class.

Or we can move this out.

I’m a bit uncomfortable adding more operations to RenderObject itself. Seems like the class is getting out of hand. Other options include putting this in some derived class, or writing it as a free function that takes a const RenderObject& argument, since nothing in these two functions requires access to anything private.
Comment 21 Rob Buis 2021-04-18 04:02:23 PDT
Created attachment 426377 [details]
Patch
Comment 22 Rob Buis 2021-04-18 05:31:36 PDT
Comment on attachment 425874 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=425874&action=review

>> Source/WebCore/rendering/RenderBlock.cpp:2578
>> +        return Optional<LayoutUnit>();
> 
> WTF::nullopt is the way we normally write this; not sure why we’re using something different here

Done.

>> Source/WebCore/rendering/RenderBlock.cpp:2596
>> +        return Optional<LayoutUnit>(synthesizedBaselineFromBorderBox(*this, lineDirection) + (lineDirection == HorizontalLine ? marginBottom(): marginLeft()));
> 
> We normally put a space before the ":".
> 
> Also, is the Optional<LayoutUnit> really needed? Can we just write LayoutUnit instead? Or nothing at all?

Right that was a typo. I agree it is nice to not explicitly state the return type, fixed.

>> Source/WebCore/rendering/RenderObject.h:189
>> +    }
> 
> In a large class like this, it’s best to keep multi-line function bodies (even if only one line has code) out of the class definition so we can see an overview of what’s in the class rather than have it interspersed with code. Instead we can just put an inline implementation after the class. See RenderObject::isBeforeContent for an example.

Fixed.

>> Source/WebCore/rendering/RenderObject.h:191
>> +    inline bool shouldApplyLayoutContainment() const
> 
> The inline here is unneeded and redundant if we are putting the function body inside the class.
> 
> Or we can move this out.
> 
> I’m a bit uncomfortable adding more operations to RenderObject itself. Seems like the class is getting out of hand. Other options include putting this in some derived class, or writing it as a free function that takes a const RenderObject& argument, since nothing in these two functions requires access to anything private.

Understood, I moved it out.
Comment 23 Rob Buis 2021-04-18 05:33:07 PDT
(In reply to Darin Adler from comment #20)
> Comment on attachment 425874 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=425874&action=review
> 
> No need for a feature flag?

It is implied by RenderStyle::containsLayout().
Comment 24 EWS 2021-04-18 23:13:44 PDT
Committed r276235 (236717@main): <https://commits.webkit.org/236717@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 426377 [details].
Comment 25 Darin Adler 2021-04-19 14:51:47 PDT
Comment on attachment 426377 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=426377&action=review

> Source/WebCore/rendering/RenderObject.h:206
> +    inline bool isAtomicInlineLevelBox() const;

This isn’t quite right. We should leave out the inline keyword here.

> Source/WebCore/rendering/RenderObject.h:1180
> +bool RenderObject::isAtomicInlineLevelBox() const

We need to put the inline keyword here.
Comment 26 Rob Buis 2021-04-20 02:16:36 PDT
Comment on attachment 426377 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=426377&action=review

>> Source/WebCore/rendering/RenderObject.h:206
>> +    inline bool isAtomicInlineLevelBox() const;
> 
> This isn’t quite right. We should leave out the inline keyword here.

Right, I was a bit hasty there.

>> Source/WebCore/rendering/RenderObject.h:1180
>> +bool RenderObject::isAtomicInlineLevelBox() const
> 
> We need to put the inline keyword here.

Cathie will fix both in this patch which also relies on isAtomicInlineLevelBox (https://bugs.webkit.org/show_bug.cgi?id=223570).
Comment 27 cathiechen 2021-04-20 04:32:02 PDT
(In reply to Rob Buis from comment #26)
> Comment on attachment 426377 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=426377&action=review
> 
> >> Source/WebCore/rendering/RenderObject.h:206
> >> +    inline bool isAtomicInlineLevelBox() const;
> > 
> > This isn’t quite right. We should leave out the inline keyword here.
> 
> Right, I was a bit hasty there.
> 
> >> Source/WebCore/rendering/RenderObject.h:1180
> >> +bool RenderObject::isAtomicInlineLevelBox() const
> > 
> > We need to put the inline keyword here.
> 
> Cathie will fix both in this patch which also relies on
> isAtomicInlineLevelBox (https://bugs.webkit.org/show_bug.cgi?id=223570).

Done:)
Comment 28 zalan 2021-04-22 13:24:51 PDT
Unfortunately this won't work with inline level boxes where the containment render is a type of RenderInline. The rendering code assumes the containing block always being a RenderBlock type. (there's a workaround for similar problem where the relatively positioned inline box (e.g. <span style="position: relative">) has an absolutely positioned block level box descendant. In such cases, we propagate the containing block functionality to the nearest non-anonymous containing block on the ancestor chain). However this is not a problem in LFC codebase where the layout nodes (renderer) are not typed heavily (no RenderInline vs RenderBlock) so the containingBlock() just returns a ContainerBox&.
Comment 29 zalan 2021-04-22 13:25:36 PDT
(In reply to zalan from comment #28)
> Unfortunately this won't work with inline level boxes where the containment
> render is a type of RenderInline. The rendering code assumes the containing
> block always being a RenderBlock type. (there's a workaround for similar
> problem where the relatively positioned inline box (e.g. <span
> style="position: relative">) has an absolutely positioned block level box
> descendant. In such cases, we propagate the containing block functionality
> to the nearest non-anonymous containing block on the ancestor chain).
> However this is not a problem in LFC codebase where the layout nodes
> (renderer) are not typed heavily (no RenderInline vs RenderBlock) so the
> containingBlock() just returns a ContainerBox&.
I need to think about this a bit.
Comment 30 Rob Buis 2021-04-22 13:38:01 PDT
(In reply to zalan from comment #28)
> Unfortunately this won't work with inline level boxes where the containment
> render is a type of RenderInline. The rendering code assumes the containing
> block always being a RenderBlock type. (there's a workaround for similar
> problem where the relatively positioned inline box (e.g. <span
> style="position: relative">) has an absolutely positioned block level box
> descendant. In such cases, we propagate the containing block functionality
> to the nearest non-anonymous containing block on the ancestor chain).
> However this is not a problem in LFC codebase where the layout nodes
> (renderer) are not typed heavily (no RenderInline vs RenderBlock) so the
> containingBlock() just returns a ContainerBox&.

Do you mean the landed patch will try to apply layout containment to those inline level boxes you described and there will be no effect? Or mistakenly not even bother trying? A (WPT) test may be a good idea if we currently do the wrong thing (and then we can compare to the other implementations).