Bug 24756 - [imports]: Cascading order for stylesheets of imported documents should be stated more clearly
Summary: [imports]: Cascading order for stylesheets of imported documents should be st...
Status: RESOLVED MOVED
Alias: None
Product: WebAppsWG
Classification: Unclassified
Component: HISTORICAL - Component Model (show other bugs)
Version: unspecified
Hardware: PC Linux
: P2 normal
Target Milestone: ---
Assignee: Dimitri Glazkov
QA Contact: public-webapps-bugzilla
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 20683
  Show dependency treegraph
 
Reported: 2014-02-20 22:51 UTC by Morrita Hajime
Modified: 2015-07-06 08:06 UTC (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Morrita Hajime 2014-02-20 22:51:41 UTC
This is follow-up for Bug 24616.

The spec states how it should be ordered [1] but it should be clearer.
Basically,

A) The imported style has tree order, 
   The tree order in the import referrer is defined by the location
   of <link rel=import>.
B) If there are multiple link to the same document, the first one should win.

A) is for developer ergonomics. <link rel=stylesheet> works in this way,
   so import is better to follow the same pattern
B) is for eliminating duplication. The "first wins" rule is same as
   what it does for <script>

[1] https://github.com/w3c/webcomponents/commit/600f7bf2f06b2cb5f712fc5dc928085682502941
Comment 1 Gabor Krizsanits 2014-07-23 09:52:25 UTC
I'm trying to wrap my head around this part of the spec, but there are a few things that are not clear.

- I don't see the definition for ordering style sheets that are directly in the importing document (or master) vs the imported ones.

- I'm not sure WHEN should the stylesheet of the imports be applied on the master (when the sheet is loaded? or when the import is loaded?)
Comment 2 Morrita Hajime 2014-07-23 22:30:13 UTC
(In reply to Gabor Krizsanits from comment #1)
> I'm trying to wrap my head around this part of the spec, but there are a few
> things that are not clear.
> 
> - I don't see the definition for ordering style sheets that are directly in
> the importing document (or master) vs the imported ones.
Right. I added some clarification:
https://github.com/w3c/webcomponents/commit/d74015c77b109bb19eb464063d0a59e905704a0c


> 
> - I'm not sure WHEN should the stylesheet of the imports be applied on the
> master (when the sheet is loaded? or when the import is loaded?)

This is also true. However, I suspect that web standard doesn't say
anything about style loading timing even before HTML Imports.
So I'm not sure how/if I should write it down in the spec.

Just FYI in Blink, styles are applied as each style is loaded.
This doesn't matter in many case though because import loading blocks rendering.
Comment 3 Gabor Krizsanits 2014-07-30 12:49:11 UTC
Right, now I have a little concern about this definition, although I could not come up with anything better yet. So the problem is that we let's say parsing/building two imports in sort of parallel. We determine their position to each other in the import graph, and adding their stylesheets to the document accordingly. Then when we find a link import that changes their order in the import graph, we will have to look up all their sheets from the document and reorder them. This is kind of suboptimal...

It is also a bit concerning that if someone sees <link rel=import id=A><link rel=import id=B> in a document, one would think that style sheets of A will come before the ones of B, while this can be totally change any time one imports B in some other part of the import tree... This is not just a bit counter-intuitive but also hurts encapsulation somewhat. Then again I could not find a better definition yet, just want to put my concerns out there for now. Thoughts?
Comment 4 Boris Zbarsky 2014-07-30 13:30:09 UTC
> I suspect that web standard doesn't say anything about style loading timing
> even before HTML Imports.

It does in various ways.  For example, it defines the ordering of style and script loading.
Comment 5 Morrita Hajime 2014-07-30 16:57:20 UTC
(In reply to Boris Zbarsky from comment #4)

> It does in various ways.  For example, it defines the ordering of style and
> script loading.

Yes, that is what I covered in my change. 
Difference between styles and scripts is:

- For scripts, execution order is everything. So there is less uncertainty here.
- For stylesheets, it is possible that a sheet loaded later can supersedes
  ones that are loaded earlier if the document order of new one wins
  over older ones. So loading order and application order is orthogonal.

And I don't think the spec says about loading order, although it covers 
application order. My feeling is that is is OK because we don't render things
until all imports are loaded. 

Async case might be trickier, but I yet to see real problem there.
Comment 6 Boris Zbarsky 2014-07-30 17:12:45 UTC
> we don't render things until all imports are loaded. 

Where is that specified?

What happens if a <link rel="import"> is encountered after rendering has started?
Comment 7 Morrita Hajime 2014-07-30 17:20:33 UTC
(In reply to Gabor Krizsanits from comment #3)
> Right, now I have a little concern about this definition, although I could
> not come up with anything better yet. So the problem is that we let's say
> parsing/building two imports in sort of parallel. We determine their
> position to each other in the import graph, and adding their stylesheets to
> the document accordingly. Then when we find a link import that changes their
> order in the import graph, we will have to look up all their sheets from the
> document and reorder them. This is kind of suboptimal...

Yeah, I see your point. I first prototyped fixed order version in Blink but
got complaint that the order of <link> should be considered as rel=stylesheet.
So I gave it up and changed it to pay some complexity for developer ergonomics.

> 
> It is also a bit concerning that if someone sees <link rel=import id=A><link
> rel=import id=B> in a document, one would think that style sheets of A will
> come before the ones of B, while this can be totally change any time one
> imports B in some other part of the import tree... This is not just a bit
> counter-intuitive but also hurts encapsulation somewhat. Then again I could
> not find a better definition yet, just want to put my concerns out there for
> now. Thoughts?

Well, right. This is another story how de-dup complicates things and
I don't have good answer for this either :-(
Actually same things can be said for <script>.
So I don't think this is style specific problem.

Just a random idea: UAs could emit some warning if an import has a stylesheet link
that is de-duped in some unexpected way.

For example:

- index.html
  <link href=a.html>
  <link href=b.html>

- a.html
  <link href=x.html>
  <link href=y.html>
- b.tml
  <link href=z.html>
  <link href=x.html> <!-- This can be confusing -->

Then UA can probably warn that a.html and b.html disagree about the position of x.html.
Talking more abstractly, 

- We can give each import an "order" based on import tree.
- The "orders" of imports of a document should be increasing.

In example above, The order is a=0, x=1, y=2, b=3, z=4.
Because b.html has imports {z(order=4), x(order=1)}, it violates the "no-surprise" rule.

Well, it's kinda like how good #include should be formed in C++...

I'm not sure if this is practical or not.
Probably this is better done by preprocessors like grunt tasks.
Comment 8 Morrita Hajime 2014-07-30 17:26:42 UTC
> > we don't render things until all imports are loaded. 
> 
> Where is that specified?
> 

In my understanding, this is a consequence of how <link rel=style> is handled.
<link rel=import> behaves in same way as it can have <link rel=stylesheet> in it.

> What happens if a <link rel="import"> is encountered after rendering has
> started?

This is same as how <link rel=stylesheet> works as well.

Do you have any idea how HTML/CSS specifies these?
It'd be great if imports spec can extend that definition to cover these cases.
I don't want to invent notions like "blocking rendering" here.
It should be part of more fundamental standards, IMO.
Comment 9 Boris Zbarsky 2014-07-30 18:16:59 UTC
> In my understanding, this is a consequence of how <link rel=style> is handled.

I think you misunderstand how those are handled, then.

UAs make a good-faith effort to not render while stylesheets are loading, because it looks ugly, but they make no guarantees about it at all.

Can we please separate the concerns of avoiding flashes of unstyled content (which is a purely visual/performance thing and is done best-effort) and providing correct style information to scripts (which is handled by not running the scripts until the stylesheets have been loaded)?
Comment 10 Morrita Hajime 2014-07-30 18:34:01 UTC
(In reply to Boris Zbarsky from comment #9)
> > In my understanding, this is a consequence of how <link rel=style> is handled.
> 
> I think you misunderstand how those are handled, then.
> 
> UAs make a good-faith effort to not render while stylesheets are loading,
> because it looks ugly, but they make no guarantees about it at all.
> 
> Can we please separate the concerns of avoiding flashes of unstyled content
> (which is a purely visual/performance thing and is done best-effort) and
> providing correct style information to scripts (which is handled by not
> running the scripts until the stylesheets have been loaded)?

Got it. 

There is section 8.1 "Additions to Prepare A Script Algorithm" which
addresses later. Probably we should elaborate that section.
Let me see.
Comment 11 Morrita Hajime 2014-08-05 02:37:10 UTC
(In reply to Morrita Hajime from comment #10)
> (In reply to Boris Zbarsky from comment #9)
> There is section 8.1 "Additions to Prepare A Script Algorithm" which
> addresses later. Probably we should elaborate that section.
> Let me see.
OK, I re-read what I wrote there. It says:

> ... and the Document of the HTML parser or XML parser that created the script element has a style sheet that is blocking scripts or has an import that is blocking scripts

I think this is sufficient.

Note that 
- "An import that is blocking scripts" is defined in section 5.
  The gist is that the script should be able to see everything preceding it as
  such predecessors block the script execution.
- An import is considered being loaded after all of its stylesheets are loaded
  (as defined in HTML standard) and its imports are loaded.
  I agree that later isn't super clear. Here is an attempt for the clarification.
  https://github.com/w3c/webcomponents/commit/3180b07749ff7a1f8d60460fd27538a6f7bbc674

Probably I overlook some cases that aren't clear.
Please let me know if you see any.
Comment 12 Gabor Krizsanits 2014-08-06 12:40:37 UTC
(In reply to Morrita Hajime from comment #7)
> (In reply to Gabor Krizsanits from comment #3)
> Well, right. This is another story how de-dup complicates things and
> I don't have good answer for this either :-(
> Actually same things can be said for <script>.
> So I don't think this is style specific problem.

Could you elaborate on this? I don't see what you mean here...

> 
> Just a random idea: UAs could emit some warning if an import has a
> stylesheet link
> that is de-duped in some unexpected way.

Hmm... this might be a good idea actually, regardless of what we do about style-sheets! But does not seem to fix all the variation of the problem:

<link href=style.css>
<link href=a.html>

Who comes first? We don't know for sure... Same for inline styles or scripts. But yeah this is indeed a generic problem for de-duping. (And maybe that's what you were referring to...) Would it be a stupid idea to introduce/define an extended version of CompareDocumentPosition and use that to answer all these questions?
Comment 13 Morrita Hajime 2014-08-06 22:05:31 UTC
(In reply to Gabor Krizsanits from comment #12)
> (In reply to Morrita Hajime from comment #7)
> > (In reply to Gabor Krizsanits from comment #3)
> > Well, right. This is another story how de-dup complicates things and
> > I don't have good answer for this either :-(
> > Actually same things can be said for <script>.
> > So I don't think this is style specific problem.
> 
> Could you elaborate on this? I don't see what you mean here...
> 

If you have: (Think all <link>s are imports)

- index.html
  <link href=a.html>
  <link href=b.html>

- a.html
  <link id=ac href=c.html>
  <link id=ad href=d.html>

- b.html
  <link id=bd href=d.html>
  <link id=bc href=c.html>

- c.html
  <script id=cs>...</script>

- d.html
  <script id=ds>...</script>

Even b.html expect script ds to run before cs, it doesn't because a.html
let c.html be imported before d.html. This sample might appear irrelevant
but the point is that different import can disagree the order of its dependency
and that can be problem for both script and stylesheets.
Having such disagreements is undesirable and developers should avoid that,
but that could happen. Does this make sense?

> > 
> > Just a random idea: UAs could emit some warning if an import has a
> > stylesheet link
> > that is de-duped in some unexpected way.
> 
> Hmm... this might be a good idea actually, regardless of what we do about
> style-sheets! But does not seem to fix all the variation of the problem:
> 
> <link href=style.css>
> <link href=a.html>
> 
> Who comes first? We don't know for sure... Same for inline styles or
> scripts. But yeah this is indeed a generic problem for de-duping. (And maybe
> that's what you were referring to...) Would it be a stupid idea to
> introduce/define an extended version of CompareDocumentPosition and use that
> to answer all these questions?

Yeah, that's exactly what I meant in the spec - It'd be ideal to have cross-import 
document order comparison between nodes, and use it to define style ordering.
I tried to do that in less annoying way, avoiding copy-and-patch the "document order" definition[1]
but apparently I haven't done good job there :-/

Probably we should have that extended ordering after all. Let me try to write it down.


[1] http://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-document-order
Comment 14 Morrita Hajime 2014-08-12 00:43:43 UTC
OK, here is another attempt:
https://github.com/w3c/webcomponents/commit/93fe676c7a2f6ad8901240cdfc6ce9f51c1be2e1
Comment 15 Hayato Ito 2015-07-06 08:06:29 UTC
Moved to https://github.com/w3c/webcomponents/issues/203