Re: [font-load-events] comments on new promises-based draft

On Wed, Sep 11, 2013 at 12:24 AM, John Daggett <jdaggett@mozilla.com> wrote:
> Tab Atkins wrote:
>> CSSFontFaceRule objects represent the @font-face syntax construct,
>> nothing more.  The actual font face denoted by the @font-face rule is
>> represented by the FontFace object instead.  This seems like a decent
>> separation of concerns, at least to me.
>
> Ok, I think I understand the model you want to spec - adding an
> @font-face rule automatically constructs a FontFace object and adds it
> to document.fonts but a newly constructed FontFace object is *not*
> added to document.fonts (or whatever the worker equivalent is).
>
> For each of the code examples below, the initial state is that of a
> page containing a single stylesheet with a single @font-face rule and
> no other declarations:

All of these are actually answered in the spec, though some of them
are of the "the spec says nothing because you *do* nothing" variety.

>   // initial state for all examples below:
>   @font-face { font-family: test; src: url(test.woff); }
>
>   // 1. new @font-face rule ==> new FontFace added to document.fonts
>   var s = document.styleSheets[0];
>   assert(document.fonts.size == 1);
>   assert(s.cssRules.length == 1);
>   s.insertRule("@font-face { font-family: foo; src: url(bar.woff); }", 1);
>   assert(s.cssRules.length == 2);
>   assert(document.fonts.size == 2);

Yes.

>   // 2. new FontFace rule ==> no change to CSS OM
>   var s = document.styleSheets[0];
>   document.fonts.add(new FontFace("foo", "url(bar.woff)"));
>   assert(documents.fonts.size == 2);
>   assert(s.cssRules.length == 1);  // FontFace above *not* added

Yes.

>   // 3. changes to one size are reflected in the other side
>   var s = document.styleSheets[0];
>   var fontFaceRule = s.cssRules[0];
>   var f = document.fonts[0];  // Set doesn't have this access but assume something equivalent
>   f.variant = "small-caps";
>   fontFaceRule.weight = "bold";
>   assert(f.variant == fontFaceRule.variant);
>   assert(f.weight == fontFaceRule.weight);

Yes.  (To get the first one, iterate the set and extract it into an
outside variable.)

>   // 4. deleting a font in document.fonts does what ???
>   var s = document.styleSheets[0];
>   document.fonts.delete(document.fonts[0]);
>   assert(s.cssRules.length == 0??? 1???);

It equals 1.  Deleting from document.fonts has no effect on the stylesheet.

>   // 5. clearing out document.fonts does what ???
>   var s = document.styleSheets[0];
>   document.fonts.clear();
>   assert(s.cssRules == ??? 0? 1?);

Same.

>   // 6. modifying order of document.fonts does what?
>   var s = document.styleSheets[0];
>   s.insertRule("@font-face { font-family: foo; src: url(bar.woff); }", 1);
>   var fontArr = [f for (f of document.fonts)];
>   document.fonts.delete(fontArr[0]);
>   document.fonts.add(fontArr[0]);
>   assert(s.cssRules[0].fontFamily == ??? "test"? "foo"?);

The iteration order of FontFaceSet is defined such that all
css-connected FontFace objects are first, in document order, then the
rest of the manually inserted ones are in insertion order.  This
happens even if you manually remove/re-add like this.

(Hmm, though, I have a missing case where you remove a css-connected
FontFace but hold a reference to it, remove the @font-face rule it
correspond to, then re-insert it.  I think I need to just make that
kill the connection, so it reverts to being a "manual" FontFace.)

> I think you probably can see what I'm getting at.  Reflecting the
> state of FontFaceSet and the individual rule sets that automatically
> induce entries in it is complicated and needs to be spelled out.  I
> think the sections of the spec that cover this need more details.

Already fully spelled out, except for the case I caught at the end there.  ^_^

> From section 4.1:
>
> # The set entries for a document’s font source must be initially
> # populated with all the CSS-connected FontFace objects from all of
> # the CSS @font-face rules in the document’s stylesheets, in document
> # order. This ordering must be maintained regardless of how the
> # FontFace object is added; if a script manually removes and then
> # re-adds one of them, it returns to its appropriate document-order
> # position in the initial segment of the set entries. All
> # non-CSS-connected FontFace objects must be sorted after the
> # CSS-connected ones, in insertion order.
>
> I think here you need to not declare this but specify in detail how
> this ordering is achieved.  I don't see how you can preserve the
> ordering you're talking about since the ordering within document.fonts
> is mutable by script.

Nope, ordering is observable (via iteration) but not directly mutable.
 It's perfectly allowed for the iteration order to have no relation to
insertion order, though we should of course keep it close as much as
possible.

~TJ

Received on Wednesday, 11 September 2013 08:59:29 UTC