FontFaceSet should be a setlike

NEW
Unassigned

Status

()

Core
DOM
P3
normal
a year ago
a year ago

People

(Reporter: bz, Unassigned)

Tracking

Trunk
Points:
---

Firefox Tracking Flags

(firefox52 affected)

Details

It has some hacks around lack of setlike support and comments in the interface, etc.  Any reason it can't just be converted, offhand, since we support setlike?
Flags: needinfo?(cam)
No reason I can think of we can't use setlike now that we support it.
Flags: needinfo?(cam)
Well, I guess I would have to investigate what the setlike C++ interface is since I haven't used it so far, to give a more definitive answer.  Does the interface we use allow responding to add() and remove() calls with custom behaviour?

When I tried to comment out all of those IDL methods that are emulating it, and replace it with setlike<FontFaceSet>, I get this:

WebIDL.WebIDLError: error: Member 'addEventListener' conflicts with reserved setlike method., /z/moz/b/dom/webidl/FontFaceSet.webidl line 47:2
  setlike<FontFace>;
  ^
/z/moz/b/dom/webidl/EventTarget.webidl line 33:2
  void addEventListener(DOMString type,
  ^
(In reply to Cameron McCormack (:heycam) from comment #2)
> When I tried to comment out all of those IDL methods that are emulating it,
> and replace it with setlike<FontFaceSet>, I get this:

Er, replace it with setlike<FontFace>, which the error messages show I did actually type. :-)
> Does the interface we use allow responding to add() and remove() calls with custom behaviour?

Yes, if you define them yourself, as the spec does.  So for example you would do this:

  setlike<FontFace>;
  [Throws] void add(FontFace font);

and this will generate the following things:

1)  A JS add() method which will call the Add() method on your underlying
    C++ FontFaceSet object, so you can do whatever custom behavior you need.
2)  A C++ mozilla::dom::FontFaceSetBinding::SetlikeHelpers::Add method with this signature:

      void
      Add(mozilla::dom::FontFaceSet* self, FontFace& aKey, ErrorResult& aRv);

    which your Add() method is responsible for calling to actually add the FontFace to the set.

Similar for Delete() and Clear(); those have these signatures:

      void
      Clear(mozilla::dom::FontFaceSet* self, ErrorResult& aRv);
      bool
      Delete(mozilla::dom::FontFaceSet* self, FontFace& aKey, ErrorResult& aRv);

We should really get this documented at <https://developer.mozilla.org/en-US/docs/Mozilla/WebIDL_bindings>.  qdot, do you have time to do that, by any chance?

> When I tried to comment out all of those IDL methods that are 
> emulating it, and replace it with setlike<FontFaceSet>, I get this:

Codegen bug.  Filed bug 1311362 with patch.
Depends on: 1311362
Flags: needinfo?(kyle)
Priority: -- → P3
Yeah, there's currently no documentation about generated *like/iterable stuff on the bindings page, and 2 outstanding bugs on that otherwise (bug 1255247, bug 1289611). I'll try to sit down and just get most of the documentation done later this week if I can.
So I looked at this a bit.  FontFaceSet currently does work not just on modification but also on queries (has() and the iterator bits); specifically it does some sort of flushing.  Is that flushing actually needed there?

Note that the iterator thing doesn't make sense to me, since it doesn't flush on calls to next() and whatever is being flushed can presumably become dirty between those calls...
Oh, good point about not flushing on next().  We have this wording in the spec:

  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. As @font-face rules are added or removed from a
  stylesheet, or stylesheets containing @font-face rules are added or removed, the
  corresponding CSS-connected FontFace objects must be added or removed from the
  document’s font source, and maintain this ordering.

  https://drafts.csswg.org/css-font-loading-3/#document-font-face-set

which I take to mean the FontFaceSet should appear live to script, in terms of which FontFace objects for @font-face rules are in it.

Flushing inside next() is not really compatible with what https://heycam.github.io/webidl/#es-iterator says to do for setlike iterators (i.e., defer to the backing set's @@iterator).  And there's no way to override it with an |iterator;| declaration like you can for individual setlike methods...
(In reply to Cameron McCormack (:heycam) from comment #7)
> which I take to mean the FontFaceSet should appear live to script, in terms
> of which FontFace objects for @font-face rules are in it.

i.e. it would be consistent with that requirement to flush inside next().
So we don't add font-face rules to the set until the flush happens?  How viable is just changing that?

Note that flushing in has() is also not compatible with the IDL spec's description of how setlike works...
Documentation done, clearing ni?.
Flags: needinfo?(kyle)
(In reply to Boris Zbarsky [:bz] (still a bit busy) from comment #9)
> So we don't add font-face rules to the set until the flush happens?  How
> viable is just changing that?

Right.  Well, it would be mean doing this work in response to any style sheet change.  We already eagerly parse style sheets when <style> element contents change, but the gathering of @font-face rules is currently done as part of updating the cascade in nsCSSRuleProcessor::RefreshRuleCascade, and I guess we don't want to do the majority of that work until we flush style.

> Note that flushing in has() is also not compatible with the IDL spec's
> description of how setlike works...

Erk. :(
You need to log in before you can comment on or make changes to this bug.