Some (silly) questions about lifetimes of style and layout objects

13 views
Skip to first unread message

Daniel Cheng

unread,
Aug 27, 2018, 9:13:23 PM8/27/18
to style-dev

The comments on Node::GetComputedStyle() implies that this can return a non-null pointer, even when there is no LayoutObject for the Node.
  • Does this mean that GetComputedStyle() should be generally preferred to GetLayoutObject()->Style()?
  • Can LayoutObject::Style() be null? I'm guessing the answer to this one is yes, given the amount of checks for style_ sprinkled through layout_object.cc, but what scenarios does this happen?
  • When *can* GetComputedStyle() return null?  Is this basically something that always needs to be null-checked, or can we assert that an element that has a LayoutObject always has a ComputedStyle? (I'm guessing not based on the previous question)
  • Does GetComputedStyle() map to a web-exposed IDL attribute/method?
  • Can IntersectionObserver fire for elements with no layout object (if the object is no longer intersecting)? What if the element is removed from the DOM with something like ChildNode.remove()?
Daniel

Rune Lillesveen

unread,
Aug 28, 2018, 4:34:54 AM8/28/18
to Daniel Cheng, Stefan Zager, style-dev
Stefan, there's a question for you at the bottom.

On Tue, Aug 28, 2018 at 3:13 AM Daniel Cheng <dch...@chromium.org> wrote:

The comments on Node::GetComputedStyle() implies that this can return a non-null pointer, even when there is no LayoutObject for the Node.
  • Does this mean that GetComputedStyle() should be generally preferred to GetLayoutObject()->Style()?
Currently, if a node has a LayoutObject, we don't store ComputedStyle on node, so Node::GetComputedStyle will have to go via the LayoutObject anyway. This will change, but currently if you have a LayoutObject, use StyleRef() on that to avoid the extra indirection.

Elements with display:contents does not have a LayoutObject, so their ComputedStyle is stored on ElementRareData where also the ComputedStyle for getComputedStyle() in display:none subtrees is stored when queried. Historically we have mixed style recalc and layout tree attachment in the same pass. In the Squad project we have separated style recalc from layout tree building. One reason for that is for preparing for LayoutNG not having a LayoutObject tree but generating a fragment tree during layout instead. There is one remaining step in that project which is to get rid of storing ComputedStyle in two different places on node depending on the use. This is a stretch OKR for me this quarted. This probably looks confusing now, but the end state is supposed to be:

* Store ComputedStyle on node in NodeRenderingData in what is now called non_attached_style_, rename it to computed_style_. non_attached_style_ is currently cleared when we attach the LayoutObject, but we should stop doing that.
* Remove ComputedStyle from ElementRareData and use the one in NodeRenderingData also for ComputedStyle in display:none subtrees when queried by getComputedStyle.
* Make Node::GetComputedStyle return ComputedStyle from NodeRenderingData::computed_style_, not go via LayoutObject.
  • Can LayoutObject::Style() be null? I'm guessing the answer to this one is yes, given the amount of checks for style_ sprinkled through layout_object.cc, but what scenarios does this happen?
It shouldn't be null. If there are null-checks, it's because of historical reasons, or crash avoidance because of bugs we don't know the source of. I haven't looked at the null checks, but it might be that we can remove a few of them. In theory, you should always use StyleRef() (which has a DCHECK).
  • When *can* GetComputedStyle() return null?  Is this basically something that always needs to be null-checked, or can we assert that an element that has a LayoutObject always has a ComputedStyle? (I'm guessing not based on the previous question)
Style recalc will create a ComputedStyle on every node rendered, including display:contents elements. Nodes in a display:none subtree return null for GetComputedStyle. Window.getComputedStyle() can compute style on demand if computed style inside display:none subtrees are queried, but they will be nuked on the next style recalc. See next question.
  • Does GetComputedStyle() map to a web-exposed IDL attribute/method?
The getComputedStyle() API calls Element::EnsureComputedStyle() to create a ComputedStyle inside display:none subtrees (including ancestors for inheritance) if the script queries inside a display:none subtree.
  • Can IntersectionObserver fire for elements with no layout object (if the object is no longer intersecting)? What if the element is removed from the DOM with something like ChildNode.remove()?
I don't know. Stefan?

Stefan Zager

unread,
Aug 28, 2018, 1:22:25 PM8/28/18
to fut...@chromium.org, Daniel Cheng, Stefan Zager, styl...@chromium.org
On Tue, Aug 28, 2018 at 3:13 AM Daniel Cheng <dch...@chromium.org> wrote:
  • Can IntersectionObserver fire for elements with no layout object (if the object is no longer intersecting)? What if the element is removed from the DOM with something like ChildNode.remove()?
"Fire" is a bit misleading here. It could mean "run the steps to generate notifications", or it could mean "run the registered javascript callback with pending notifications."

Assuming you mean the second one, the answer is: yes, the callback can run at a time when the target element has no LayoutObject. 
Reply all
Reply to author
Forward
0 new messages