owned this note
owned this note
Published
Linked with GitHub
# AdoptedStylesheet
## Context
DOM `Stylesheet` is a representation of CSS that has been parsed.
Stylesheets are present in `Document` and `ShadowDOM`, where it could be used to style the respected scope of the DOM. At present, In Servo, stylesheet that affects a `Document` is stored within `DocumentStylesheetSet`, and the one that affects a `ShadowDOM` is stored within `AuthorStylesheetSet`. With the main difference that `DocumentStylesheetSet` could stores stylesheets for each `Origin`, meanwhile `AuthorStylesheetSet` is intended only for `Origin::Authors` styles.
```rs
/// The set of stylesheets effective for a given document.
#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
pub struct DocumentStylesheetSet<S>
where
S: StylesheetInDocument + PartialEq + 'static,
{
/// The collections of sheets per each origin.
collections: PerOrigin<SheetCollection<S>>,
/// The invalidations for stylesheets added or removed from this document.
invalidations: StylesheetInvalidationSet,
}
```
```rs
/// The set of stylesheets effective for a given Shadow Root.
#[derive(MallocSizeOf)]
pub struct AuthorStylesheetSet<S>
where
S: StylesheetInDocument + PartialEq + 'static,
{
/// The actual style sheets.
collection: SheetCollection<S>,
/// The set of invalidations scheduled for this collection.
invalidations: StylesheetInvalidationSet,
}
```
The kind of stylesheet that was stored within a `StylesheetSet` is also crucial for the implementation of `AdoptedStylesheet`. Where it would be stored as `dom::DocumentOrShadowRoot::StyleSheetInDocument` for Servo.
```rs
#[derive(Clone, JSTraceable, MallocSizeOf)]
#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)]
pub(crate) struct StyleSheetInDocument {
#[ignore_malloc_size_of = "Arc"]
#[no_trace]
pub(crate) sheet: Arc<Stylesheet>,
pub(crate) owner: Dom<Element>,
}
```
> [!Note]
> This present a quite unique quirks, where we need to reconstruct `CSSStylesheet` from `StyleSheetInDocument` whenever we need to access it within JS.
>
> Note that Firefox are storing a wrapper to `Stylesheet` DOM object, thus preventing this problem.
> [!Important]
> Need to rename this into `ServoStylesheetInDocument` as it have an identical name to Stylo traits `StylesheetInDocument`.
Generally, stylesheets are managed by two elements `<link>` and `<style>`. Whenever the element is modified so that the stylesheet is changed, a `style::stylesheet::Stylesheet` is parsed, and then it would be inserted into relevant `Document` or `ShadowDOM`'s `StylesheetSet`.
> [!Important]
> This means that all stylesheet within a `Document` is `ShadowDOM` is unique and are not shared. So we will need to check whether it will causes an issue if we do that.
> [!Important]
> This also means that there are no way to associate a constructable stylesheet to a `Document` or `ShadowDOM` right now.
## Implementation Steps
Possible implementations steps for this API is as follow:
1. Allow `documentorshadowroot::StyleSheetInDocument` to have nullable owner, since constructable CSSStylesheet does not have owning node.
2. Implement minimal `AdoptedStylesheet` workflow that will push the stylesheet into the `StyleSet` of `Document` and `ShadowRoot`, with correct invalidations, ordering, and without the steps below.
- Implement it wil `FrozenArray`.
- Invalidate all relevant StyleSet whenever the stylesheet is modified.
- Correctly handle stylesheet styleset ordering according to https://drafts.csswg.org/cssom/#documentorshadowroot-final-css-style-sheets.
3. Correctly handle `AdoptedStylesheet` in case of shadow root re-attaching.
4. Optimize Stylesheet setting if necessary.
5. Implement observable array.
> [!Note]
> We need pref flag for this feature.