Bug 111281 - [Shadow] Siblings of a shadow host with the same tag name incorrectly inherit background color specified in @host rule
Summary: [Shadow] Siblings of a shadow host with the same tag name incorrectly inherit...
Alias: None
Product: WebKit
Classification: Unclassified
Component: CSS (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Dominic Cooney
: 112590 (view as bug list)
Depends on:
Blocks: 59827
  Show dependency treegraph
Reported: 2013-03-03 19:29 PST by Dominic Cooney
Modified: 2019-10-04 22:52 PDT (History)
6 users (show)

See Also:

Repro (591 bytes, text/html)
2013-03-03 19:30 PST, Dominic Cooney
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Dominic Cooney 2013-03-03 19:29:41 PST
See the attached repro.
Comment 1 Dominic Cooney 2013-03-03 19:30:24 PST
Created attachment 191160 [details]
Comment 2 Dominic Cooney 2013-03-05 00:30:47 PST
This is a style sharing bug. StyleResolver::styleSharingCandidateMatchesHostRules only matches whether one of the elements matches host rules. Hence shared styles won't bleed from an element that ISN'T targeted by @host rules to one that IS, but can bleed from an element that IS targeted by @host rules to one that ISN'T. This is what we're seeing here.
Comment 3 Dominic Cooney 2013-03-05 18:32:36 PST
Elements that have Shadow DOM and are targeted by @host rules should not share styles.

The reason is basically the same reason why elements with <style scoped> children should not share styles. Their styles may be different to their siblings/cousins/etc. due to rules set in the scoped style.

The question is how to trade off how precisely we compute which elements can share styles, and what extra resources it takes to do that.

At one extreme of using no extra resources (directly) we can conservatively turn off sharing for all elements with Shadow DOM. The most unfortunate side effect is that many form controls use Shadow DOM internally; those will no longer be able to share styles.

At another extreme we can add a bit to ElementRareData which tracks whether an element is targeted by an @host rule, like the "children affected by first child" bits.

To chew up more cycles but no more bytes we could broaden the meaning of Node::hasScopedHTMLStyleChild from <style scoped> elements to include Shadow DOM with <style> elements containing @host rules. In future if the syntax of @host rules is broadened to also style descendants of the host, there's strong overlap in semantics between these two: The @host rules are like a "virtual <style scoped>." It should also be straightforward to make it work with shared stylesheets added with the ShadowRoot::addStyleSheet API.

For now I am going to pursue this approach. Feedback or ideas welcome.
Comment 4 Dominic Cooney 2013-03-06 00:32:49 PST
My initial idea is complicated by the timing of calls: Style sharing resolves that the shadow host and ordinary div can share styles before the shadow host knows it bears a style element (via ShadowRoot::registerScopedHTMLStyleChild.)

I need to understand better the relationship between style sharing and style recalculation. It seems there is basically tension between wanting to share as many styles are possible, but having to use a conservative heuristic about which styles can be shared. I hope it is not necessary to go to such extremes as disabling style sharing for all shadow hosts, or reapplying styles to the sibling list of an element which becomes a shadow host.

I ran into some obviously smelly code: ShadowRoot uses the HasScopedHTMLStyleChild flag to mean "has a style element in the subtree" so it seems methods like (un)registerScopedHTMLStyleChild and hasScopedHTMLStyleChild need to be renamed, if not these responsibilities untangled. Maybe I should pick at that scab for a while as I contemplate this.
Comment 5 Takashi Sakamoto 2013-03-18 18:37:46 PDT
*** Bug 112590 has been marked as a duplicate of this bug. ***
Comment 6 Ryosuke Niwa 2019-10-04 22:52:49 PDT
@host isn't a thing anymore.