- From: Bjoern Hoehrmann <derhoermi@gmx.net>
- Date: Fri, 05 Apr 2013 02:29:25 +0200
- To: "Tab Atkins Jr." <jackalmage@gmail.com>
- Cc: www-style list <www-style@w3.org>, Anne van Kesteren <annevk@annevk.nl>
* Tab Atkins Jr. wrote: >[...] (Some gut reactions:) >1. Sites that are going to do some type of DOM measurement that will >depend on the loaded font (such as the size/position of an inline, or >the height of a block), would like to be able to check if all fonts >are loaded, and be notified when any currently-loading fonts are done. The dependency would be on the font that is "ultimately" used, not on any loaded font, otherwise web pages would break when users disable the use of illegible fonts in their browser... >[http://gitbug.com/slightlyoff/DOMFuture] http://github.com/slightlyoff/DOMFuture >Here's my proposed new API (explanations/justifications will follow): > >partial interface document { > readonly attribute FontList fonts; >} > >interface FontList : EventTarget { > /* whatever idl magic you need to make this an array-like filled >with Font objects */ > Future ready() > boolean checkFont(DOMString font, optional DOMString text = " "); > Future loadFont(DOMString font, optional DOMString text = " "); > attribute EventHandler onloading; > attribute EventHandler onloadingdone; >} Having event listener attributes on the object strikes me as a bad idea. It is likely that several separate components would want to listen for them, but having the attributes encourages code that would override the listeners of one component in another, leading to bugs that are annoying to debug (only happens on high latency networks, only with empty cache). >First of all, I'm replacing document.fontLoader with document.fonts, >an array-like of Font objects. Each Font object is a readonly version >of a CSSFontFaceRule object, without any links into the CSSOM. This >seems like a useful convenience API all by itself, but it's also >something that can be safely exposed to Workers, as there's no >DOM/CSSOM link to make it unsafe. The FontList contains Font objects >for all the @font-face rules in all the stylesheets for the document, >in document order. That sounds more like `document.styleSheets.fontFaceRules` to me. It's rather unclear to me that this filtered and read-only view is a good idea. >The FontList.ready() function returns a Future. This is initially >unresolved, and resolves when the browser has loaded all stylesheets >and has finished loading all the fonts it chooses to initially load. >It must return the same future across multiple calls. If, after >resolving the future, the browser beings loading more fonts, it must >create a new future to return from .ready(), and again resolve it when >the browser stops loading fonts. This addresses use-case #1, >replacing notifyWhenFontsReady(). It's not clear to me whether "same future" refers to object identity and if it does, why this would not return a new object on each invocation. I am not sure from your proposal what the object would be "resolved" with, and when. >The loadFont() function has had its API reverted to be identical to >checkFont, and it just returns a future which is resolved as soon as >all the necessary requested fonts have loaded (which may be >immediately, if all necessary fonts are already loaded). This >addresses use-case #2. It seems you mean that you propose `checkFont` and `loadFont` to have the same prototype (argument list), but otherwise they are not identical at all. >checkFont() is unchanged. > >To address use-case #3, the API has two pieces. If you care about the >loading status of individual fonts, look for the relevant Font object >and call its ready() function to obtain a Future which is resolved >when the font is done loading, or cancelled when the font load has an >error. This replaces the loadstart/load/error events. The >loading/loadingDone events are unchanged - they're useful for >providing UI indicating whether fonts are loading or not, rather than >a one-off "tell me when fonts are ready", which is what the .ready() >future is for. This sounds like you are proposing that load failures cannot be observed through the Event APIs. If so, I am not sure what motivates that. Overall, I think it would be good to have a common protocol for similar APIs, and if "Futures" are such a protocol I think it makes sense to use them for `loadFont`, but beyond that I am not really a fan of your pro- posal, or the `FontLoader` so far. One worry is that when you actually want to take measurements only when, as far as the browser knows, final layout no longer depends on unknowns, you have to wait for more than just fonts, there may also be images or web components or other things that are not yet "ready", so binding to font loads would be incorrect. Another worry is the liveness of the FontList you propose; a "Future" that encapsulates multiple "Future" objects is a common idiom, but you usually would know what you are waiting for, and the typical libraries do not appear to support "live" semantics; as an example, it bothers me that `X.all(Array.from(document.fonts).map(x => x.ready()))` is quite different from `document.fonts.ready()`, where `X.all` creates a Future out of a list of Futures. Yet another problem I see is that currently components tend to be poorly isolated. You might have a third party script on your site that attempts to use a font that fails to load, but you do not want your own code to break because of that, so using `document.fonts.ready()` is a bad idea for robust code. That is a problem that might go away if and when compo- nents become better isolated, but right now it is a concern. -- Björn Höhrmann · mailto:bjoern@hoehrmann.de · http://bjoern.hoehrmann.de Am Badedeich 7 · Telefon: +49(0)160/4415681 · http://www.bjoernsworld.de 25899 Dagebüll · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/
Received on Friday, 5 April 2013 00:29:54 UTC