w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.5k stars 666 forks source link

[css-shared-element-transitions-1] Pseudo-element selectors for shared element transitions #7743

Closed khushalsagar closed 2 years ago

khushalsagar commented 2 years ago

We need to define the selector name and whether it takes an argument for each of the pseudo-elements that SET generates. For each tag on a DOM element via page-transition-tag (assuming its in both pages), the following tree is generated:

page-transition-container(foo)
|_page-transition-image-wrapper(foo)
  |_page-transition-incoming-image(foo)
  |_page-transition-outgoing-image(foo)

And all page-transition-container elements have the same ancestor, page-transition. If you write the full syntax, it would be something like this:

html::page-transition::page-transition-container(foo)::page-transition-image-wrapper(foo)::page-transition-incoming-image(foo) {
  ...
}

Which is a lot to type. #7346 will help with that but we want to avoid a dependency on that and make the chaining syntax easier to type. So one option is a shorter name and no arguments for everything except container, which would be something like:

html::page-transition::container(foo)::wrapper::incoming {
  ...
}

The names container, wrapper, incoming and outgoing might seem too generic but they'll only show up under page-transition so could be fine?

A caveat here is that once the descendant selector ships, you'll always need to reference the container to get to the images corresponding to a tag. Something like:

html::>> container(foo)::>> incoming {
  ...
}

If everything under container does keep the argument then the above could be this instead:

html::>> incoming(foo) {
  ...
}

But then the non-descendant selector would be:

html::page-transition::container(foo)::wrapper(foo)::incoming(foo) {
  ...
}

I'm not sure which is better. @tabatkins @vmpstr.

khushalsagar commented 2 years ago

Another option uses part which relies on using a shadow DOM rooted at the html element. We were concerned that this would disallow developers from attaching their shadow DOM to the root but the spec already disallows that.

The structure for the shadow DOM would be the same as with pseudo-elements above. It has part attributes to match selectors. So for the example above:

<div part="page-transition">
  <div part="container container-foo">
    <div part="wrapper wrapper-foo">
      <div part="incoming incoming-foo"></div>
      <div part="outgoing outgoing-foo"></div>
    </div>
  </div>
</div>

And then selectors to target them can be:

/* Matches all container elements. */
html::part(container) {
  ...
}

/* Matches container element for foo. */
html::part(container-foo) {
  ...
}

The comment here brought up a use-case to conditionally apply CSS based on whether one of the pseudo-element exists, for example we only have the incoming image, using has. This syntax would rely on adding additional part names for this. For example:

<div part="page-transition">
  <div part="container container-foo">
    <div part="wrapper wrapper-foo">
      <div part="incoming incoming-foo incoming-only-foo"></div>
    </div>
  </div>
</div>

Can use the following selector:

html::part(incoming-only-foo) {
  ...
}

The exact part names still up for bike-shedding.

tabatkins commented 2 years ago

Note that you can supply multiple part names in ::part(), and it selects only parts that match all of them (like they were multiple class names in a compound selector). So we don't need to mix the element tags into the part names, we can just use them as part names directly, and they'd be selected like ::part(container foo).

vmpstr commented 2 years ago

I have some questions about shadow DOM and this API:

  1. Special replaced elements: Currently in the pseudo element model, we have replaced elements that are specced to reflect either a captured snapshot or "live" dom, depending on the situation and that's just "magic" in the sense that particular pseudo element names are defined to be these elements. We're fairly safe in making these definitions because the developer has no way to also create these elements, they are limited to UA control. If we switch to shadow DOM, what elements would we use? I can see that the example above uses divs with some part attributes, but presumably that would mean that the developer can also create these divs with these attributes in the light dom or in their own shadow doms. Is there any way to preclude that? In other words, is it possible to have some "magic" element that the UA can add but that the developers can't, when it comes to shadow DOM? Just having a new element also seems insufficient since nothing is preventing the developers from creating new elements either

  2. Element references: if we use shadow DOM, we also want to make sure that the developer can't reparent these elements or in general get a reference to them, other than selecting them for style via CSS selectors. I assume there is precedence for that, but I just wanted to make sure that this is already an established practice.

  3. Scoped transitions: lastly, and this is outside of the scope of the current spec, but one future improvement that we've talked about for this API is scoping the transition to a subtree. Basically, since only one transition is allowed and that transition occupies the whole document, it makes it awkward to use in something like reusable components. For that, we'd like to work towards scoping the pseudo/shadow dom structure to be attached to an element other than html via some properties/js api calls and limit the transition to a subtree. Now, there are other technical challenges here, but if we switch to shadow dom it also adds another one: we wouldn't be able to attach this shadow dom to a custom element which already has a developer shadow dom attached. We would require something along the lines of a wrapper div right inside the shadow dom to act as a "root" for the purposes of this API. That seems like an ergonomics challenge for developers. I wonder if there are any elegant solutions here

jakearchibald commented 2 years ago

1. is it possible to have some "magic" element that the UA can add but that the developers can't

I think we can explain this via the cascade. The image stuff only works when it's in this particular shadow DOM.

2. we also want to make sure that the developer can't reparent these elements or in general get a reference to them

That seems bad. One of the advantages of using shadow DOM would be allowing developers to get regular element references. Without this, we'll still have to go down the path of creating pseudo-element references, and it's not even clear if that should work for ::part.

3. Scoped transitions: lastly, and this is outside of the scope of the current spec, but one future improvement that we've talked about for this API is scoping the transition to a subtree. Basically, since only one transition is allowed and that transition occupies the whole document, it makes it awkward to use in something like reusable components. For that, we'd like to work towards scoping the pseudo/shadow dom structure to be attached to an element other than html via some properties/js api calls and limit the transition to a subtree. Now, there are other technical challenges here, but if we switch to shadow dom it also adds another one: we wouldn't be able to attach this shadow dom to a custom element which already has a developer shadow dom attached.

Yeah, this is a huge issue. But similarly, it also seems weird that SET gets to claim the shadow DOM of the root element. Like, do we just get to own that space since we arrived first?

This is why, when I was thinking about doing this via shadow DOM, I suggested that the shadow root be attached to a pseudo-element. That's new and weird though.

khushalsagar commented 2 years ago

Without this, we'll still have to go down the path of creating pseudo-element references, and it's not even clear if that should work for ::part

Did you mean references for script? The CSS API can be the same in both approaches with the use of ::part.

For script access, we don't want to allow script to do everything that the Element API allows (like reparenting the element out of the shadow DOM). So the choices for adding that later would be:

I did want WA-API to be available to script in the initial version of this feature. And it looks like you can't target an element in a shadow DOM using the ::part selector with pseudoElement option, as opposed to selectors which target pseudo-elements. This example doesn't work in Chrome/Firefox/Safari.

The Scoped transitions aspect is what makes shadow DOM dealbreaker for me. The fact that developers lose the ability to use an element, which is a shadow host, as the root for a scoped transition. We'd be forcing developers to add nodes just so the browser has an element to attach the transition's shadow DOM to.

Pseudo-elements and shadow DOM could be made equivalent in functionality given that both can be targeted in CSS the same way. But the desire for exploring shadow DOM (from the discussion here) is to have a potentially simpler implementation. Shadow DOM seems to push complexity from the implementor to developer.

do we just get to own that space since we arrived first?

You don't miss what you didn't have? ^_^

I suggested that the shadow root be attached to a pseudo-element

This is a road I don't want to go down. It gets really weird if a pseudo-element becomes an ancestor for real elements.

jakearchibald commented 2 years ago

Did you mean references for script?

Yeah, sorry, I wasn't clear.

For script access, we don't want to allow script to do everything that the Element API allows (like reparenting the element out of the shadow DOM).

I think we could allow this. I'm assuming we could use the cascade to say the outgoing and incoming image elements don't 'work' outside of the shadow DOM.

I did want WA-API to be available to script in the initial version of this feature. And it looks like you can't target an element in a shadow DOM using the ::part selector with pseudoElement option

Oof, yeah, that's bad. It's an important part of the feature. I wonder if there's a good reason it doesn't work, and if it'd also cause issues with a CSSPseudoElement reference.

The Scoped transitions aspect is what makes shadow DOM dealbreaker for me.

+1

I suggested that the shadow root be attached to a pseudo-element

This is a road I don't want to go down. It gets really weird if a pseudo-element becomes an ancestor for real elements.

Yeah, I imagine there are a lot of reasons why it's a bad idea.

tabatkins commented 2 years ago

is it possible to have some "magic" element that the UA can add but that the developers can't

I think we can explain this via the cascade. The image stuff only works when it's in this particular shadow DOM.

Yeah, magic is the way to go. They have to be in the proper tree and the proper structure, and we can determine that via magic (UA-only inherited CSS properties, for example, which is set on the elements via UA stylesheet and checked via internal code).

And it looks like you can't target an element in a shadow DOM using the ::part selector with pseudoElement option, as opposed to selectors which target pseudo-elements. This example doesn't work in Chrome/Firefox/Safari.

This is probably just a browser bug? The spec mentions ::part() when discussing target elements.

css-meeting-bot commented 2 years ago

The CSS Working Group just discussed Pseudo-element Selectors for shared element transitions.

The full IRC log of that discussion <fantasai> Subtopic: Pseudo-element Selectors for shared element transitions
<fantasai> github: https://github.com/w3c/csswg-drafts/issues/7743
<fantasai> JakeA: what you see here is the default cross-fade
<fantasai> ... DOM change underneath is just one change
<fantasai> ... illusion of both bits of content on the screen at the same time is done through this pseudo-element
<fantasai> ... tree
<fantasai> ... These represent the two visual states
<fantasai> ... there's a wrapper around them, which applies isolation
<fantasai> ... and container there is what changes size and position
<fantasai> ... (not seen for root, but for sub-elements will see it)
<fantasai> JakeA: Developers can use these pseudo-elements to customize their stuff
<fantasai> ... e.g. change from cross-fade to sliding images from left to right
<fantasai> ... also have this page-transition-tag property
<fantasai> s/... also/JakeA: also
<fantasai> ... allows to capture page in separate parts, animate separately
<fantasai> ... so page slides and heading text cross-fades
<fantasai> JakeA: This creates a bigger pseudo-tree
<fantasai> ... each piece gets its own ::page-transition-container
<fantasai> ... and underneath it a wrapper around the two incoming/outgoing images
<fantasai> JakeA: Although it's a pseudo-tree, currently attached to root element
<fantasai> ... feels like cheating, because it doesn't really represent the structure of the pseudo-tree
<fantasai> ... but alternative would be [writes out a chain of pseudo-elements]
<fantasai> ... It's uncomfortable even with shortened names
<fantasai> JakeA: Tab came up with idea of using a pseudo-descendant combinator
<fantasai> JakeA: one question to group is, would it be appropriate to do something with function-liek syntax can be used on each piece of it
<fantasai> ... html :>> outgoing-image(header-text)
<fantasai> JakeA: I like this because it makes use of nesting
<fantasai> ... makes syntax simpler and nicer
<fantasai> JakeA: one alternative suggested to structure is what if we used shadow DOM instead
<fantasai> ... here we've got a shadow-root
<fantasai> ... and it's got basically same structure, using parts attribute for access into the tree
<fantasai> emilio: Bigger pro is, you avoid all this nested pseudo-elements for a particular feature
<fantasai> ... also a lot of new features are using shadow parts
<fantasai> ... I don't think of a use case that, well, shadow DOM is already restricted on root eleent
<fantasai> ... so can use it for UA features
<fantasai> ... if you replae with script the HTML element with something else, some of it wouldn't work
<fantasai> ... but all in all, it seems a bit better to re-use what the platform already has
<fantasai> ... I don't think there's anything that you can't do with pseudo-elements that you can't do with parts
<fantasai> JakeA: syntax of using parts, haven't seen for shipped feature yet
<fantasai> ... but we're happy with it?
<fantasai> emilio: THat's where all the new OpenUI stuff is going
<fantasai> ... I think it's reasonable
<fantasai> ... I'd rather do that than having 4 nested pseudo-elements
<fantasai> JakeA: I'd seen that in their proposal, unsure about feelings in this group
<fantasai> emilio: Tab designed parts so that authors and UA could have common mechanism to expose this kind of thing
<heycam> q+
<fantasai> TabAtkins: wasn't designed with intent of UA using it, but it was left open as a possibility
<khush> q+
<chrishtr> q+
<fantasai> JakeA: One of the things missing right now is ability drive animations with JS
<fantasai> ... or call things like getBoundingClientRect() on these things
<fantasai> ... and so our plan was, there was a stub bit of spec in the CSS Pseudo-element Spec to say maybe we'll expose these to JS at some point
<fantasai> ... but if we had a shadow root, we could just give devs access to the elements
<fantasai> ... and not do all that
<fantasai> emilio: That seems a bit trickier, in the sense that some of these elements, if I understand correctly, need some magic attached to them
<fantasai> ... rendering a texture that [missed]
<fantasai> ... not supposed to be moved around
<fantasai> ... so seems a bit tricky, fact that you can shuffle them around etc.
<heycam> s/[missed]/the compositor has taken a snapshot of/
<fantasai> JakeA: definitely don't want devs to take the elements out of the shadow root and have them continue to work
<fantasai> ... but can explain that if extracted the element, no longer...
<fantasai> emilio: nice thing about shadow parts, is also used elsewhere
<emilio> q+
<Rossen_> ack heycam
<fantasai> heycam: One thought about shadow root, gievn HTML element can't have one currently
<fantasai> ... could mechanism be that some new element is created which has this shadow tree structure, and placed in top layer
<fantasai> ... not attached to the root element
<fantasai> ... don't know where it would live in the document
<fantasai> JakeA: I floated a similar idea earlier
<fantasai> ... but your idea is simpler
<Rossen_> ack khush
<fantasai> khush: I had a thought, curious to get a bit more understanding about heycam was proposing
<fantasai> ... were you proposing a new tag that lives somewhere in the DOM that only exists to host a shadow root?
<fantasai> heycam: thinking that when the element transition is triggered, that would cause a new element to be inserted into the document
<fantasai> ... which has this structure behind it
<fantasai> ... its only purpose is to render the transition image, and it lives in the DOM
<fantasai> khush: idk what computations would run into... would be a shared-element-transition tag?
<fantasai> ... generally does UA create elements that have a temporary lifetime, and is node inserted by browser
<fantasai> ... was trying that we create pseudo-element, but ran into multiple issues because don't expect real DOM elements to have pseudo-elements as their ancestors
<fantasai> heycam: it just feels like it's not really part of the root HTML element either
<fantasai> JakeA: it's a "topper layer"
<fantasai> khush: One reason it has lin kto document is so that it has a way to do style resolution and layout
<fantasai> ... it needs a document to be associated with
<miriam> q+
<fantasai> ... otherwise it's using output of actual document to generate content
<fantasai> khush: Wanted to add, might be a weak arguemnt because need to be more clear
<fantasai> ... but one use case is multiple independent transitions on the page
<fantasai> ... currently it's global, works for the whole document, captures the entire page
<fantasai> ... but some cases where a developer can have 2 widgets on their page
<fantasai> ... 2 different DOM subtrees, would be nice to transitions on those subtrees independently
<fantasai> ... if shadow tree, can scope to each subtree
<fantasai> ... attach to root of that subtree
<fantasai> ... so using shadow DOM on the root for this
<fantasai> ... would not be able to do that on subtrees
<Rossen_> ack chrishtr
<fantasai> ... because only HTML can have this work
<fantasai> s/HTML/HTML element/
<fantasai> ... but using pseudo-elements, can expand in that direction
<fantasai> chrishtr: Question is what can authors use to style these elements
<fantasai> ... one is using pseudo-element syntax
<fantasai> ... or use shadow DOM syntax
<fantasai> ... not necessary to ???
<fantasai> chrishtr: so that's the choice: is there a pseudo-element or not, and if not it's implementation detail
<fantasai> ... maybe something exposed to devs in the future
<fantasai> ... need to think about what choice we make, how it impacts that
<fantasai> ... but it's really choice of syntax A or B
<fantasai> ... and 2 dimensions to weigh are, which has better ergonomics for devs
<fantasai> ... and which is easier to implement for implementers
<fantasai> emilio: My concern was not so much about difficult, but pseudo-elements, there are a lot of them
<fantasai> ... new names specific to this feature
<fantasai> ... to me feels we should avoid it
<fantasai> chrishtr: by analogy, components in OpenUI have a parts syntax on them, but doesn't mean can access the elements. Closed shadow DOM
<fantasai> ... web-components-like syntax
<heycam> q+
<fantasai> ... afaict, some devs are used to pseudo-elements
<fantasai> ... find the one they need and put it in their stylesheet
<fantasai> ... others that know about components might think ::parts one makes more sense
<fantasai> ... Further down can explain with conceptual shadow DOM
<fantasai> ... but to me it's really about that tradeoff
<fantasai> ... even if we expose shadow DOM
<JakeA> q+
<fantasai> ... there are UA features that are [missed]
<fantasai> ... I think you mentioned <input> as an example
<Rossen_> ack emilio
<fantasai> emilio: To that regard, my point for using parts is
<fantasai> ... if you need to learn one of these things
<fantasai> ... shadow parts is something you'll learn once, and it'll be useful every time you use it
<fantasai> ... whether as an author or something else
<fantasai> chrishtr: The concept of parts yes, but still have to memorize the names of the parts
<fantasai> chrishtr: I personally don't have a strong opinion
<fantasai> ... I feel like the tradeoff should be more about which is easiest for developers
<fantasai> khush: Part which has not been clear to me, whether syntax implies shadow DOM or not
<fantasai> ... if we go with part syntax, is it still pseudo-elements?
<fantasai> ... wasn't clear if this syntax forces us to use a particular approach
<Rossen_> ack miriam
<fantasai> miriam: As an author, I've interacted with pseudo-elements more
<fantasai> ... but when I read the syntax here, the part syntax reads much simpler to me
<fantasai> ... it is a pseudo-element, and doesn't require special combinator syntax
<fantasai> ... looks cleaner to me, makes sense, I like it
<astearns> +1 to miriam
<TabAtkins> q+
<fantasai> ... I am also one of the ppl who will feel strongly about having multiple sub
<fantasai> ... don't want to take an approach that makes that impossible
<fantasai> s/sub/subtree
<emilio> q+
<fantasai> chrishtr: important your point that we don't need additoinal syntax for pseudo-element trees
<fantasai> JakeA: if we use the part syntax, you will not get nesting
<fantasai> miriam: will I need it?
<fantasai> fantasai: You had that proposal about nesting
<fantasai> JakeA: could maybe put more classes in the part
<fantasai> ... but you lose the strucutre this gets you
<Rossen_> ack heycam
<vmpstr> would the part syntax also prevent attaching this structure to an element that has a shadow dom (since part would select the shadow dom?)
<fantasai> heycam: proposal is for transitions in the document, but idea is to go later to entire document transitions?
<fantasai> JakeA: other way around, right now it's one transition that covers the whole document
<fantasai> ... but it's same document transition
<fantasai> ... but intention is to go to cross-document transitions in the near future
<fantasai> heycam: for cross-document, seems like the shadow DOM mechanism wouldn't be appropraite
<fantasai> ... because they would go away when you switch documents
<fantasai> ... so can't describe the state across the transition
<fantasai> JakeA: it would be the same tree that we would use with pseudo-elements
<fantasai> ... screenshots from previous page would be in the shadow DOM of the new document
<fantasai> chrishtr: would certainly require special code
<fantasai> JakeA: would only be same-origin, btw
<fantasai> heycam: all the pseudo-elements, need to live in both old and new document
<fantasai> JakeA: only new one
<fantasai> fremy: you take a photo of old document, and then swithc to new one
<fantasai> ... only one document active
<fantasai> heycam: so in old document, no pseudos get created
<fantasai> fremy: right
<fantasai> chrishtr: but during animation, new document is inert
<Rossen_> ack JakeA
<fantasai> JakeA: One thing I'm worried about is, we want devs to have references to things they can call getBoundingClientREct, to control inline styles
<fantasai> ... to increase the proposal for a reference to a pseudo-element and put these on them
<fantasai> ... add .animate, .style
<fantasai> ... I'm slightly worried we get trouble if using parts, because getting pseudo-eelemnt reference for something that is an element
<fantasai> heycam: animations?
<fantasai> JakeA: .style.whatever
<fantasai> ... if we create pseudo-element object, will it make sense if the underlying thing is an actual element?
<fantasai> heycam: internally, this kind of thing will be ....
<fantasai> ... more a matter of making sure API exposes the right things
<Rossen_> ack TabAtkins
<fantasai> TabAtkins: A little bit ago, Miriam said she preferred look of the parts API, more simple naming
<fantasai> ... I'll note that if that's what we care about, we can do that with pseudo-elements, too
<fantasai> ... if that's a significant plus, we can make the tarnsition API work like that with pseudo-element sor with parts
<fantasai> ... we don't ahve to bring one or the other based on that specific issue
<fantasai> JakeA: current API in canary is simlilar, everything hangs off root eleent
<fantasai> ... change something like this to ::part() with same text inside
<fantasai> ... here we've put page-transition to separate from other features
<fantasai> ... would need to do same with aprt syntax
<fantasai> ... to crate a namespace for our feature
<fantasai> s/crate/create/
<TabAtkins> ahhhh
<fantasai> emilio: regarding .style etc.
<Rossen_> ack emilio
<fantasai> ... right now I don't think we expose either parts or pseudo-elements as things you can change style of
<fantasai> ... but if we did, I thin you'd get more chances for that with parts than pseudo-elements
<fantasai> ... because pseudos don't have attributes
<fantasai> ... not all speudos can have attributes
<heycam> fantasai: trying to think through how much of this is feeling awkward because it's really long, or how much because of the structure of it
<heycam> ... if there's way to use pseudo element syntax that's more compact, maybe then it would feel more comfortable
<emilio> q+
<fantasai> fantasai: also wrt khush's point about subtrees, I think leaving that possibility open is important
<heycam> khush: I think the conclusion I'm hearing is to go with part for now, which leaves it open for each engine to decide, whether it's backed with pseudos or shadow DOM, and when we hit implementation, we decide at that point
<vmpstr> q+
<fantasai> JakeA: I tihnk we need to write up both proposals possible
<emeyer> A question: Will it be possible for cross-document transitions to also animate shared elements? (Similar to Magic Move in Keynote, where an element can scale and move and change opacity as part of the slide transition.) If not, should we design syntax such that it could be possible in the future?
<fantasai> ... used shorter syntax for parts examples, but in reality would need to be longer
<fantasai> emeyer, yes
<Rossen_> ack emilio
<fantasai> emeyer: I think maybe ??? is a non-issue with parts
<fantasai> s/emeyer/emilio/
<fantasai> ... because doesn't interact with rest of page
<fantasai> emilio: if we go with parts, most realistic way to implement is using shadow DOM
<Rossen_> ack vmpstr
<fantasai> vmpstr: if we go with the part syntax, wouldn't that still run into issue of backed by pseudo-element but scoped to an element that has a shadow DOM attached by developer
<emilio> s/???/animations in ua sheets
<fantasai> ... wouldn't part syntax then be ambiguous?
<fantasai> JakeA: are you talking about a scoped transition?
<fantasai> vmpstr: yes
<fantasai> JakeA: yeah that's a big issue
<emilio> q+
<fantasai> vmpstr: unclear whether to look in shadow DOM or pseudo-tree
<fantasai> emilio: it's true
<Rossen_> ack emilio
<fantasai> ... but to be honest, this scoped transition thing raises more questions than answers
<fantasai> ... be good to have a concrete proposal of how that would look like
<fantasai> ... before deciding to use or not use one approach
<fantasai> ... at the point where root of transition can mutate
<fantasai> ... right now proposla is only for docuemnt transition. You know document is not going away
<fantasai> ... various things not changing
<fantasai> ... if you scope the transition to the element, need to define what happens when authors hide or move the element
<fantasai> ... or whatnot
<fantasai> ... raises a lot more complications than I'm comfortable with
<fantasai> Rossen_: I want to see if we can close the discussion
<fantasai> Rossen_: quite a bit of feedback here, what should we do next?
<fantasai> JakeA: I think our action items are to draw up pros and cons of each approach, and maybe also mid-approach where implemented with shadow DOM but use pseudo-elements to access it
<fantasai> ... and sketch out scoped transitoins to figure out how it works
<fantasai> TabAtkins: coming up with half-reasonable short names with each would also be helpful
<fantasai> ACTION: JakeA and khush to draw up pros and cons for shadow DOM vs pseudo-elements vs mixed approaches
<astearns> so I am dreading s/transition-container/trainer/
<fantasai> ACTION: JakeA and khush to sketch out scoped transitions to see how they work
<fantasai> ACTIOn: JakeA and khush to find shorter names for things
khushalsagar commented 2 years ago

I'm closing this issue in favour of resolving as 2 separate issues based on the TPAC discussion: #7928 and #7788.