WICG / local-font-access

Web API for enumerating fonts on the local system
https://wicg.github.io/local-font-access
Apache License 2.0
75 stars 16 forks source link

Extra FontManager indirection seems unnecessary #33

Closed domenic closed 2 years ago

domenic commented 3 years ago

Why is the following necessary:

const fontManager = navigator.fonts;
const fonts = await fontManager.query();
const fontIterator = fontIterator[Symbol.asyncIterator]();

instead of the following?

const fonts = await navigator.queryFonts();
const fontIterator = fonts[Symbol.asyncIterator]();
domenic commented 3 years ago

An alternative is, perhaps, just

const fontIterator = navigator.fonts[Symbol.asyncIterator]();

In the original post I was assuming that you needed an await in between, but it looks to me like in the current Chromium implementation, you can get the font iterator synchronously.

domenic commented 3 years ago

Note that per testing in Chromium and https://github.com/WICG/local-font-access/issues/31#issuecomment-703885252 it looks like the current API is

const fontIterator = navigator.fonts.query()[Symbol.asyncIterator]();
jakearchibald commented 3 years ago

@domenic what's the rule when it comes to navigator these days? Like, why should it be on navigator rather than the global?

Unfortunately we already have document.fonts and self.fonts in a worker. If it was self.fonts everywhere I'd argue putting the APIs there, but it doesn't make sense to provide system font access via document.fonts.

Maybe that's why navigator is the best place here?

jakearchibald commented 3 years ago

In https://github.com/WICG/local-font-access/issues/27 I proposed match and matchAll which would warrant some kind of namespace. self.systemFonts maybe?

jakearchibald commented 3 years ago

There are also requests to provide a change event which details what has changed, so that'd need a namespace too.

domenic commented 3 years ago

what's the rule when it comes to navigator these days? Like, why should it be on navigator rather than the global?

Fair question. I've never really found this to be consistent, and prefer using the global. But, the fact that there are already document.fonts and self.fonts means that yeah, navigator.fonts, or self.systemFonts, both seem reasonable.

I lean slightly toward self.systemFonts to distinguish from document.fonts and self.fonts.

inexorabletash commented 2 years ago

@jyasskin since you've reviewed this recently too, any opinion on where to plug this in?

jyasskin commented 2 years ago

[Noting that the current spec API is await navigator.fonts.query() without the Symbol.asyncIterator bit.]

Or self.localFonts to match the fact that you use src:local() to make CSS use one of these. I don't feel strongly about systemFonts vs localFonts, but the facts that 1) we'd like to eventually support this in Workers (presumably after the main Window has gotten permission) and 2) both document.fonts and self.fonts exist

make me think that we shouldn't add navigator.fonts with a significantly different meaning. I defer to Domenic and Jake's sense of what fits in with the web platform if they turn out to disagree with me.

domenic commented 2 years ago

Or self.localFonts to match the fact that you use src:local() to make CSS use one of these.

I like this consistency idea.

  • both document.fonts and self.fonts exist

I think you are referring to the CSS Font Loading spec, which defines the same capabilities as document.fonts in document contexts, and self.fonts in worker contexts. This is an annoying pattern because to write code that works in both contexts you have to do self.fonts || document.fonts.

Given this I can think of a few ideas that seem reasonable:

  1. Add self.fonts.queryLocal(...) / document.fonts.queryLocal(...). Or maybe loadLocal(...) for symmetry with the existing load(...). (I'm not sure if "loading" is semantically correct though.)

  2. Add self.queryLocalFonts(...). It lives alongside the existing document.fonts / self.fonts.

  3. Add self.localFonts.query(...). It lives alongside the existing document.fonts / self.fonts.

In all cases we should investigate aliasing document.fonts to window.fonts to avoid the annoyance mentioned above, but that can be pursued orthogonally from this spec. (I filed https://github.com/w3c/csswg-drafts/issues/7178.)

(1) seems appealing from the perspective of a naive web developer. All "font stuff" is centralized on self.fonts / document.fonts. However, fonts would be a FontFaceSet object, which seems in general very FontFace-centric. I wonder if it would be confusing to have a bunch of properties on fonts for dealing with FontFace objects, plus one method for dealing with FontData. So it's possible (1) is too naive. Maybe @tabatkins has some opinions here.

Deciding between (2) and (3) is a question as to whether you ever envision adding more local/system font operations in the future. If you do, then adding a container object like self.localFonts seems worthwhile. If not, then keeping it simple as a single function would be ideal.

inexorabletash commented 2 years ago

FWIW, self.queryLocalFonts(...) is appealing to me, as I work to overcome my reflex to namespace everything.