# 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.