The example in https://w3c.github.io/manifest/#icons-member says
The developer wants to use an SVG for greater than or equal to 257x257px.
and shows
{ "src": "icon/hd_hi.svg", "sizes": "257x257" }
to accomplish this, but the normative definitions of sizes don't appear to support this use.
icons" but doesn't define what's appropriate.Yep, I think this is unclear.
However, I don't think we want to make normative text that says that sizes means it can be used for greater than or equal to that size. User agents should be able to use any icon size wherever they want; the sizes should just be used as a hint (i.e., it should have no normative description of how it's to be used).
We definitely shouldn't say that sizes is only for bitmap images. It should represent the ideal logical size in pixels of an image, so it's relevant on an SVG to say "this is the best image to use if you have a space to draw the icon that's about 257 logical pixels". You may have multiple SVGs that, while they can be scaled to any size, some have more detail than others, and are designed for different logical sizes.
@phoglenix also recently noted the normative term "appropriate" which seemingly has no definition, and should be clarified.
The intent of sizes members is to say what sizes are inside an .ico or other file format that embeds multiple icons. It's not related to anything else. We might need to rework this text indeed.
Interesting. So is it not intended to be used for single-image formats like PNG and SVG? Several examples throughout the spec disagree...
I think it is useful to have it mean what I said above, since that way, you can have a manifest with 12 icons of various sizes, and the UA can just download the one that it needs for a particular surface, based on the sizes hint, and not have to download all the icons to check their internal size.
Interesting. So is it not intended to be used for single-image formats like PNG and SVG? Several examples throughout the spec disagree...
I know... "semantic drift". That's ok, we can adapt. @NotWoods tells me that Fenix also uses sizes in the way you suggested above.
and the UA can just download the one that it needs for a particular surface, based on the sizes hint, and not have to download all the icons to check their internal size.
Yes, that would be good to clarify.
@marcoscaceres wrote:
I know... "semantic drift". That's ok, we can adapt. @NotWoods tells me that Fenix also uses sizes in the way you suggested above.
FWIW, apart from the examples in the specification (and MDN), the specification of the sizes member says "The sizes member is equivalent to a link element's sizes attribute, and is processed in the same manner. ". The examples in the HTML specification for an icon link relation show a single sizes entry being provided for single image formats and MDN says "Most icon formats are only able to store one single icon; therefore most of the time the sizes attribute contains only one entry".
When I implemented this part of the specification it was certainly my interpretation that single-image formats would have a single sizes entry and that the size was meant to be the exact size and not a minimum size (unless "any" is specified as the value). I used the sizes member in an algorithm to pick the best available icon based on these assumptions ("best available" in this case meaning the smallest icon that is larger than or equal to a requested size).
@benfrancis :
size was meant to be the exact size and not a minimum size (unless "any" is specified as the value)
But you do allow icons of size X to be used where Quick (unrelated) drive-by code review on @benfrancis 's algorithm: You might want to update The second of these is critical: I've seen real-world sites that only have Also: I think you forgot ("best available" in this case meaning the smallest icon that is larger than or equal to a requested size). It doesn't look like that's exactly what this algorithm does. It seems to look for _either_ the smallest icon >= target size, _or_ the largest icon <= target size, biased by whichever it sees first of smaller or larger. For instance, if your target size is 100, if your sizes are [2, 110, 105], it will choose 2 (once it sees 2, it will only ever choose icons smaller than the target), but if your sizes are [110, 2, 105], it will choose 105 (once it sees 110, it will only ever choose icons larger than the target). (That's just my interpretation from reading the code; I didn't actually run it.) // filter out badge and maskable icons and those without a src
if(!icon.src ||
icon.purpose.has('badge') ||
icon.purpose.has('maskable')) {
return;
}
'badge' to 'monochrome' as we've changed that in the spec. But really the intent of this check seems to be "if an icon is being used for some other special purpose, ignore it". Really, then, the check should be "if the icon has an explicit purpose and does not include "any"". That has two benefits:
monochrome). You're required to do this (e.g., ignore any icon with purpose "fizzbuzz")."any maskable" should be treated exactly the same as an icon without a purpose, except that it can also be used as a maskable icon."any maskable" icons, which means they're happy to use their maskable-formatted icon as a regular icon as well. You should allow this. var size = sizeString.split('x')[0];
Number(). This will store size and bestSize as a string, so they will compare lexicographically, not numerically (e.g., "32" < "256" is false).
@mgiuca wrote:
But you do allow icons of size X to be used where
That's correct. My assumption was that the size specified in the manifest is exact, but for the purposes of my algorithm (not part of the manifest processing algorithm but rather a helper for the UI) the match with the target size doesn't need to be exact. Its purpose is to find the closest match possible.
Thanks for the drive-by review. I miss having a team who can do code reviews and catch my silly mistakes!
You might want to update 'badge' to 'monochrome' as we've changed that in the spec.
Yeah thanks for the heads up, I had seen the discussion. Quite a lot has changed in the spec since I implemented this in October last year!
But really the intent of this check seems to be "if an icon is being used for some other special purpose, ignore it". Really, then, the check should be "if the icon has an explicit purpose and does not include "any"".
Good catch. I hadn't realised it was common for icons to specify more than one purpose.
I think you forgot Number().
Oops.
It seems to look for either the smallest icon >= target size, or the largest icon <= target size, biased by whichever it sees first of smaller or larger.
Good catch.
I think I've fixed all these issues in https://github.com/webianproject/shell/pull/230 but really I need to add some unit tests to make sure all the corner cases are covered! I'm also pretty sure this algorithm could be optimised by just sorting the list first...
Feel free to file any further issues you find. (I'm not actively working on that repo as it's a bit of a side project, but am planning to use that code in another one so these issues are all relevant.)
I'm also pretty sure this algorithm could be optimised by just sorting the list first.
I think the spec requires that the last-declared icon of "equally-appropriate" icons is used, so you have to be a little careful about sorting the list (make sure it's stable relative to whatever "appropriate" means).
Maybe we should add normative text:
馃
@phoglenix wrote:
I think the spec requires that the last-declared icon of "equally-appropriate" icons is used, so you have to be a little careful about sorting the list (make sure it's stable relative to whatever "appropriate" means).
Hmm, interesting.
@mgiuca wrote:
Maybe we should add normative text:
Sort the list of icons by appropriateness.
Remove any inappropriate icons from the list.
Choose the most appropriate.
"Appropriateness" is perhaps a little bit subjective, but yes I do wonder whether sorting by size might help.
Another thing that isn't clear from the specification (and I'm not sure there's really a normative answer to) is what to do about icons which have different width and height dimensions. My algorithm only compares one dimension and really assumes the icon is square, so if a developer provided a very tall or wide icon this would all fall apart.
"Appropriateness" is perhaps a little bit subjective, but yes I do wonder whether sorting by size might help.
Sorry @benfrancis I was being facetious, making a joke on the normative use of the word "appropriate" in the spec without any definition of what "appropriate" means.
As of right now, I consider the correct order to choose icons to be user-agent-defined. Maybe we'll keep it that way, but then we should remove this paragraph and just state that it's user-agent-defined. Otherwise, we should be much clearer about the order, either by rewriting this paragraph, or by actually defining "appropriateness" as a total order.
what to do about icons which have different width and height dimensions
I'm not sure where this is used in Chrome these days, but a long long time ago, I wrote this algorithm in Chrome for choosing the best out of a set of arbitrarily-shaped rectangular icons: GetBest. How it seems to work is that it first sorts all the icons by _aspect ratio_, and chooses the one with the closest aspect ratio to the desired size (which I suppose in most cases will be simply the closest icon to square). Then it breaks ties based on the closest width (or height; doesn't matter since we know they all have the same aspect ratio). This means if you have any square icons, all other icons will always be ignored, no matter their size.
In practice, thinking about this isn't very important because almost every icon ever created is square, and we can just say, if it's not square, meh (we shouldn't crash but we also don't need to worry particularly about choosing the right icon).