[Bug 23231] New: [Custom]: Custom Element order isn't well defined for imported documents

https://www.w3.org/Bugs/Public/show_bug.cgi?id=23231

            Bug ID: 23231
           Summary: [Custom]: Custom Element order isn't well defined for
                    imported documents
           Product: WebAppsWG
           Version: unspecified
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Component Model
          Assignee: dglazkov@chromium.org
          Reporter: dominicc@chromium.org
        QA Contact: public-webapps-bugzilla@w3.org
            Blocks: 14968

Here are a few observations that I think are suggestive of problems:

CUSTOM ELEMENT ORDER is defined imperatively (a parser encounters a close tag)
but later the definition of HIGHEST STABLE ORDER uses CUSTOM ELEMENT ORDER to
define a total order across imported documents. This doesn't seem right, since
the order in which those parsers respectively encounter close tags isn't
defined.

HIGHEST STABLE ORDER refers to link tags and flattened trees, but that is
fraught because a given link tag can move around, or be removed entirely.
There's a mantra that "imperatively inserting a link tag is synchronous" but
it's really not for Custom Element upgrade. Just for script tags. (I note the
way script tags are blocked is very imperative--by checking a flag.)

HIGHEST STABLE ORDER refers to CUSTOM ELEMENT UPGRADE ORDER in an imported
document, which isn't defined if the imported document hasn't parsed a custom
element.

CUSTOM ELEMENT ORDER is defined for elements created with means other than a
parser. What is that? Would those ever end up in the BASE ELEMENT QUEUE? Maybe
that should be removed.

I think the solution needs to be something more imperative, and it needs to put
imports in the base element queue as insertion points. There's also a critical
object, the IMPORT, which *is not* a link tag. It's the placeholder for the
document that may be parsed when processing an import. If a link tag is removed
and reinserted, I think there's a new IMPORT happening.

I'm going to try prototyping something along these lines:

When an IMPORT happens, add it to the BEQ. If the parent document isn't an
import, add it to the end; if the parent document is an import, insert the new
IMPORT in the BEQ at the position right before the parent document's IMPORT.
(Not sure what to do if the parent document's IMPORT has already expired from
the queue. Maybe we only care about the operation of the parser, in which case
we just clarify the algorithm to only do this insertion as a result of the
parser. But maybe imperative should be isomorphic to parsing--which makes
document.write more consistent I guess--in which case we need to specify
walking the parent tree of imports or something.)

So this means that the base element queue now also contains a model of the
imports tree. Note that the imports tree is very different to the flattened
tree of link elements, etc. It's very imperative, defined by when an import is
kicked off, etc. We need to model the imports tree in the base element queue
because that is the goal of the whole exercise--providing a consistent model of
both of these things to order them.

Next, when the parser encounters a Custom Element close tag, it adds it to the
BEQ. This is defined similarly: If the document is not an import, add it to the
end; if the document is an import, insert it right before the IMPORT marker in
the BEQ for this document. This means that the IMPORT for a given document
comes right after the elements in that document (if any).

When processing the BEQ, on encountering an IMPORT, if the import is not ready,
leave it in the queue and stop processing the queue (new elements might be
inserted in front of it. Processing restarts from the front each time.)

Here's a worked example for a trivial case:

m.html:
1: <x-a>
2: <link rel="import" href="p.html">
3: <x-b>

p.html:
1: <link rel="import" href="q.html">
2: <x-c>

q.html:
1: <x-d>
2: <x-e>

We basically have three concurrent actors parsing m (main), p and q. The only
constraint is that an actors starts when the parent encounters the link tag. So
imagine we have an interleaving like:

m1, m2, p1, q1, m3, q2, p2

This ordering would build a queue like:

m1: A
m2: AP
p1: AQP
q1: ADQP
m3: ADQPB
q2: ADEQPB
p2: ADEQCPB

You could imagine another possible ordering like:

m1, m2, p1, q1, q2, p2, m3

This would build a queue like:

m1: A
m2: AP
p1: AQP
q1: ADQP
q2: ADEQP
p2: ADEQCP
m3: ADEQCPB

Of course we could encounter microtask checkpoints at basically any point, but
the total order will be the same and consistent because an import never drops
out of the queue until its READY flag is set. So P and Q act as gates to the
processing of the queue.

This is basically an imperatively constructed serialization of the "tree of
trees". I think that would also be an OK formulation.

-- 
You are receiving this mail because:
You are the QA Contact for the bug.

Received on Friday, 13 September 2013 03:14:20 UTC