[css-font-loading] src parsing of FontFace constructor

We've been working on writing testcases for the Gecko implementation of
the CSS Font Loading spec and I think we should simplify the handling of
parse errors in the FontFace constructor.

The current spec definition of the FontFace constructor takes three
parameters, the family name, the source, and an optional dictionary of
descriptors:

  var f = new FontFace("test", "url(test.woff)", { weight: "bold" });

  // errors
  var f1 = new FontFace("x,y", "url(x)"); // invalid family name
  var f2 = new FontFace("test", "x");     // invalid src argument

The error handling of these two constructor calls is different. For
invalid family names and descriptors, the parse is rejected but a
FontFace object is returned with invalid values set to the empty string
and status set to "error".

But for invalid src values, there's a more complicated sequence of steps
that occur, such that the status of the returned FontFace starts as
"unloaded" and then to switches to "error".  The spec states:

  If it fails to parse correctly, queue a task to set font face’s
  status attribute to "error" and reject font face’s
  [[FontStatusPromise]] with a DOMException named "SyntaxError"
  exception, and abort these steps.

I think it's much simpler to handle the src argument, when it's a
DOMSstring, just as the family and descriptors arguments are handled --
parse the string and immediately set the status to "error" if a parse
error occurs. This is better for authors and eliminates an extra, odd
set of state changes for implementations.

Suggested spec change --

Old wording ======================

1. Let font face be a fresh FontFace object. Set font face’s status
   attribute to   "unloaded", Set its internal [[FontStatusPromise]]
   slot to a fresh pending Promise object.

   Parse the family argument, and the members of the descriptors
   argument, according to the grammars of the corresponding descriptors
   of the CSS @font-face rule. If any of them fail to parse correctly,
   reject font face’s [[FontStatusPromise]] with a DOMException named
   "SyntaxError", set font face’s corresponding attributes to the empty
   string, and set font face’s status attribute to "error". Otherwise,
   set font face’s corresponding attributes to the serialization of the
   parsed values.

   Return font face. If font face’s status is "error", terminate this
   algorithm; otherwise, complete the rest of these steps asynchronously.

2. If the source argument was a DOMString, parse it according to the
   grammar of the src descriptor of the CSS @font-face rule. If it fails
   to parse correctly, queue a task to set font face’s status attribute
   to "error" and reject font face’s [[FontStatusPromise]] with a
   DOMException named "SyntaxError" exception, and abort these steps;
   otherwise, set font face’s internal [[Urls]] slot to the string.

   If the source argument was a BinaryData, set font face’s internal
   [[Data]] slot to the passed argument.

New wording ======================

1. Let font face be a fresh FontFace object. Set font face’s status
   attribute to   "unloaded", Set its internal [[FontStatusPromise]]
   slot to a fresh pending Promise object.

   Parse the family argument, and the members of the descriptors
   argument, according to the grammars of the corresponding descriptors
   of the CSS @font-face rule. If any of them fail to parse correctly,
   reject font face’s [[FontStatusPromise]] with a DOMException named
   "SyntaxError", set font face’s corresponding attributes to the empty
   string, and set font face’s status attribute to "error". Otherwise,
   set font face’s corresponding attributes to the serialization of the
   parsed values.

   If the source argument was a DOMString, parse it according to the
   grammar of the src descriptor of the CSS @font-face rule. If it fails
   to parse correctly, set font face’s status attribute to "error" and
   reject font face’s [[FontStatusPromise]] with a DOMException named
   "SyntaxError" exception; otherwise, set font face’s internal [[Urls]]
   slot to the string.

   Return font face. If font face’s status is "error", terminate this
   algorithm; otherwise, complete the rest of these steps asynchronously.

2. If the source argument was a BinaryData, set font face’s internal
   [[Data]] slot to the passed argument.

I should note here that the Chrome implementation already follows the
*new* wording. :)

Regards,

John Daggett

Received on Thursday, 26 March 2015 06:42:48 UTC