Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

General tidying, clearer adoptedStyleSheets, remove document restriction #60

Merged
merged 3 commits into from
Oct 26, 2018
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 39 additions & 44 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,36 @@ ED: https://wicg.github.io/construct-stylesheets/index.html
Editor: Tab Atkins Jr., Google, http://xanthir.com/contact/
Editor: Eric Willigers, Google, [email protected]
Editor: Rakina Zata Amni, Google, [email protected]
Abstract: This draft defines additions to CSSOM to make StyleSheet objects directly constructable, along with methods and APIs to make it easier to deal with stylesheets in the context of custom elements and similar.
Ignored Terms: ShadowRoot, create a medialist object, add a css style sheet, document css style sheets
Repository: https://github.com/WICG/construct-stylesheets/
Abstract: This draft defines additions to CSSOM to make {{CSSStyleSheet}} objects directly constructable, along with a way to use them in {{DocumentOrShadowRoot}}s.
Ignored Terms: create a medialist object, add a css style sheet, document css style sheets
</pre>

<pre class='link-defaults'>
spec:dom; type:interface; text:Document
</pre>

Motivation {#motivation}
============================

Most web components uses Shadow DOM. For a style sheet to take effect within the Shadow DOM, it currently must be specified using a style element within each shadow root.
As a web page may contain tens of thousands of web components, this can easily have a large time and memory cost if user agents force the style sheet rules to be parsed and stored once for every style element. However, the duplications are actually not needed as the web components will most likely use the same styling, perhaps one for each component library.

Some user agents might attempt to optimize by sharing internal style sheet representations across different instances of the style element. However, component libraries may use JavaScript to modify the style sheet rules, which will thwart style sheet sharing and have large costs in performance and memory.


Proposed Solution {#proposed-solution}
============================

We are proposing to provide an API for creating stylesheet objects from script, without needing style elements, and also a way to reuse them in multiple places. Script can optionally add or remove rules from a stylesheet object. Each stylesheet object can be added directly to any number of shadow roots (and/or the top level document).

Constructing Stylesheets {#constructing-stylesheets}
=================================

<pre class='idl'>
partial interface Document {
[NewObject] Promise&lt;CSSStyleSheet> createCSSStyleSheet(DOMString text, optional CSSStyleSheetInit options);
[NewObject] CSSStyleSheet createCSSStyleSheetSync(DOMString text, optional CSSStyleSheetInit options);
[NewObject] CSSStyleSheet createEmptyCSSStyleSheet(optional CSSStyleSheetInit options);
[NewObject] Promise&lt;CSSStyleSheet> createCSSStyleSheet(optional DOMString text = "", optional CSSStyleSheetInit options);
[NewObject] CSSStyleSheet createCSSStyleSheetSync(optional DOMString text = "", optional CSSStyleSheetInit options);
};

dictionary CSSStyleSheetInit {
Expand All @@ -43,6 +57,7 @@ dictionary CSSStyleSheetInit {
no parent CSS style sheet,
no owner node,
no owner CSS rule,
associated document to <var>this</var>,
and a title set to the {{CSSStyleSheetInit/title}} attribute of <var>options</var>.
Set <var>sheet’s</var> origin-clean flag.
2. If the {{CSSStyleSheetInit/media}} attribute of <var>options</var> is a string,
Expand All @@ -59,9 +74,8 @@ dictionary CSSStyleSheetInit {
otherwise,
set <var>sheet’s</var> CSS rules to an empty list.
6. Let <var>promise</var> be a promise.
7. Wait for loading of <a spec=css-cascade-4>@import</a> rules in <var>sheet</var>.
* If any of them resulted in a resource with a <a spec=html>Content-Type metadata</a> of anything other than <code>text/css</code>, reject <var>promise</var> with a {{TypeError}}.
* If any of them failed to load, reject <var>promise</var> with reason set to {{DOMException}} with the message "Loading import rules failed".
7. In parallel, wait for loading of <a spec=css-cascade-4>@import</a> rules in <var>sheet</var> and any nested <a spec=css-cascade-4>@import</a>s from those rules.
* If any of them failed to load or resulted in a resource with a <a spec=html>Content-Type metadata</a> of anything other than <code>text/css</code>, reject <var>promise</var> with reason set to {{NotAllowedError}} {{DOMException}}.
* Otherwise, resolve <var>promise</var> with <var>sheet</var> once all of them have finished loading.
8. Return <var>promise</var>.
</dd>
Expand All @@ -75,6 +89,7 @@ dictionary CSSStyleSheetInit {
no parent CSS style sheet,
no owner node,
no owner CSS rule,
associated document to <var>this</var>,
and a title set to the {{CSSStyleSheetInit/title}} attribute of <var>options</var>.
Set <var>sheet’s</var> origin-clean flag.
2. If the {{CSSStyleSheetInit/media}} attribute of <var>options</var> is a string,
Expand All @@ -90,60 +105,40 @@ dictionary CSSStyleSheetInit {
assign the list as <var>sheet’s</var> CSS rules;
otherwise,
set <var>sheet’s</var> CSS rules to an empty list.
6. If <var>sheet</var> contains one or more <a spec=css-cascade-4>@import</a> rules, throw a {{SyntaxError}}.
6. If <var>sheet</var> contains one or more <a spec=css-cascade-4>@import</a> rules, throw a {{NotAllowedError}} {{DOMException}}.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The convention is quotes around {{NotAllowedError}}

7. Return <var>sheet</var>.
</dd>

<dt><dfn method for=Document lt="createEmptyCSSStyleSheet()|createEmptyCSSStyleSheet(options)">createEmptyCSSStyleSheet(options)</dfn></dt>
<dd>
Synchronously creates an empty CSSStyleSheet object and returns it.

When called, execute these steps:

1. Construct a new {{CSSStyleSheet}} object <var>sheet</var>,
with location set to the {{Document}}'s <a spec=html>base URL</a>,
no parent CSS style sheet,
no owner node,
no owner CSS rule,
and a title set to the {{CSSStyleSheetInit/title}} attribute of <var>options</var>.
Set <var>sheet’s</var> origin-clean flag.
2. If the {{CSSStyleSheetInit/media}} attribute of <var>options</var> is a string,
<a>create a MediaList object</a> from the string
and assign it as <var>sheet’s</var> media.
Otherwise, assign a copy of the value of the attribute as <var>sheet’s</var> media.
3. If the {{CSSStyleSheetInit/alternate}} attribute of <var>options</var> is true,
set <var>sheet’s</var> alternate flag.
4. If the {{CSSStyleSheetInit/disabled}} attribute of <var>options</var> is true,
set <var>sheet’s</var> disabled flag.
5. Return <var>sheet</var>.
</dd>
</dl>

Using Constructed Stylesheets {#using-constructed-stylesheets}
=============================

A {{CSSStyleSheet}} can only be applied to the {{Document}} it is constructed on (e.g. the document on which the factory function is called on),
and any {{ShadowRoot}} in the {{Document}} it is constructed on, by assigning an array containing the sheet to their {{adoptedStyleSheets}}.
So, a stylesheet can be used in multiple {{DocumentOrShadowRoot}}s within the document it is constructed on.

Non-explicitly constructed stylesheets cannot be added to {{adoptedStyleSheets}}.
If {{adoptedStyleSheets}} got assigned an array that contains style sheets not made by {{createCSSStyleSheet(text)}}, {{createCSSStyleSheetSync(text)}} or {{createEmptyCSSStyleSheet}},
a {{TypeError}} will be thrown.

<pre class='idl'>
partial interface DocumentOrShadowRoot {
attribute FrozenArray&lt;CSSStyleSheet> adoptedStyleSheets;
};
</pre>


<dl>
<dt><dfn attribute for=DocumentOrShadowRoot lt="adoptedStyleSheets">adoptedStyleSheets</dfn></dt>
<dd>
Style sheets assigned to this attribute are part of the <a spec=cssom-1>document CSS style sheets</a>.
They are ordered after the stylesheets in {{Document/styleSheets}}.
On getting, {{adoptedStyleSheets}} returns this DocumentOrShadowRoot's [=adopted stylesheets=].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{{DocumentOrShadowRoot}}


On setting, {{adoptedStyleSheets}} performs the following steps:

1. Let <var>adopted</var> be the result of converting the given value to a FrozenArray&lt;CSSStyleSheet>
2. If any entry of <var>adopted</var> has no associated document (e.g. it's not made by factory methods to construct stylesheets), throw a {{NotAllowedError}} {{DOMException}}.
3. Set this {{DocumentOrShadowRoot}}'s adopted stylesheets to <var>adopted</var>.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[=adopted stylesheets=]

</dd>
</dl>

Applying Styles In All Contexts {#styles-in-all-contexts}
===================
Every {{DocumentOrShadowRoot}} has <dfn>adopted stylesheets</dfn>.

The user agent must include all style sheets in the {{DocumentOrShadowRoot}}'s
[=adopted stylesheets=] inside its <a spec=cssom-1>document CSS style sheets</a> collection if it is a {{Document}}, or shadow CSS style sheets collection if it is a {{ShadowRoot}}. The [=adopted stylesheets=] are ordered after all the other style sheets (i.e. those derived from {{DocumentOrShadowRoot/styleSheets}}).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, I figured out the solution. Just use <a>document or shadow root CSS style sheets</a> and it will link to https://drafts.csswg.org/cssom/#documentorshadowroot-document-or-shadow-root-css-style-sheets, which does what you want.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh it was right there! Thanks.





Loading