[css-font-loading] “whenever” algorithms

In §3.1 Events, there are three “whenever” algorithms.  The first two
are keyed off state changes that happen as part of “queue a task to
set status” steps, so it is reasonably clear when those algorithms must
be invoked – although I still think it would be clearer to explicitly
call out to this algorithm from the other ones where the status is
updated.

The third “whenever” algorithm is:

  Whenever a FontFaceSet goes from having possibly pending font loads to
  having no pending font loads, …

This is something that can happen as part of JS calls to methods on a
FontFaceObject.  For example, if we start with a single FontFace in
document.fonts that is loading, and then call document.fonts.clear(),
we will immediately have “no pending font loads” (assuming the document
has finished loading, there are no style sheet requests, and no pending
layout operations).

“No pending font loads” is implicitly defined in terms of the
FontFaceSet object’s “set entries” (where that is a Web IDL term).  That
leads me to conclude that the exact moment that we move to a “no pending 
font loads” state is just after http://heycam.github.io/webidl/#es-set-clear
calls in to clear() on the internal set object.  Well, that is an
optimistic reading, as I don’t think it would make sense to transition
to “no pending font loads” somewhere in the middle of
https://people.mozilla.org/~jorendorff/es6-draft.html#sec-set.prototype.clear
(say after a particular iteration of its step 5).

I don’t like how loose this is.  I think the best solution would be as
follows.

You override add, clear and delete on FontFaceSet so that there is a
well defined point where you can call into a “check whether we now have
no pending font loads” algorithm, and then also call into that
explicitly from the other algorithms in the spec that update the status
member of FontFace objects.

For the overrides, it would look like this:

  interface FontFaceSet {
    setlike<FontFace>;
    FontFaceSet add(FontFace font);
    boolean delete(FontFace font);
    void clear();
    …
  };

  The add function runs these steps:

    1. Forward the add call to the FontFaceSet’s internal set object.
    2. Check whether we now have no pending font loads.
    3. Return the FontFaceSet object.

  The delete function runs these steps:

    1. Let deleted be the result of Forwarding the delete call to the
       FontFaceSet’s internal set object.
    2. Check whether we now have no pending font loads.
    3. Return deleted.

  The clear function runs these steps:

    1. Forward the add call to the FontFaceSet’s internal set object.
    2. Check whether we now have no pending font loads.

-- 
Cameron McCormack ≝ http://mcc.id.au/

Received on Wednesday, 18 March 2015 06:54:00 UTC