-
Notifications
You must be signed in to change notification settings - Fork 9.4k
/
icons.js
82 lines (77 loc) · 2.76 KB
/
icons.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/**
* @license
* Copyright 2016 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @param {NonNullable<LH.Artifacts.Manifest['value']>} manifest
* @return {boolean} Does the manifest have any icons?
*/
function doExist(manifest) {
if (!manifest || !manifest.icons) {
return false;
}
if (manifest.icons.value.length === 0) {
return false;
}
return true;
}
/**
* @param {number} sizeRequirement
* @param {NonNullable<LH.Artifacts.Manifest['value']>} manifest
* @return {Array<string>} Value of satisfactory sizes (eg. ['192x192', '256x256'])
*/
function pngSizedAtLeast(sizeRequirement, manifest) {
// An icon can be provided for a single size, or for multiple sizes.
// To handle both, we flatten all found sizes into a single array.
const iconValues = manifest.icons.value;
/** @type {Array<string>} */
const flattenedSizes = [];
iconValues
.filter(icon => {
const typeHint = icon.value.type.value;
if (typeHint) {
// If a type hint is present, filter out icons that are not 'image/png'.
return typeHint === 'image/png';
}
// Otherwise, fall back to filtering on the icons' extension.
const src = icon.value.src.value;
return src && new URL(src).pathname.endsWith('.png');
})
.forEach(icon => {
// check that the icon has a size
if (icon.value.sizes.value) {
flattenedSizes.push(...icon.value.sizes.value);
}
});
return flattenedSizes
// discard sizes that are not AAxBB (eg. "any")
.filter(size => /\d+x\d+/.test(size))
.filter(size => {
// Split the '24x24' strings into ['24','24'] arrays
const sizeStrs = size.split(/x/i);
// Cast the ['24','24'] strings into [24,24] numbers
const sizeNums = [parseFloat(sizeStrs[0]), parseFloat(sizeStrs[1])];
// Only keep sizes that are as big as our required size
const areIconsBigEnough = sizeNums[0] >= sizeRequirement && sizeNums[1] >= sizeRequirement;
// Square is required: https://code.google.com/p/chromium/codesearch#chromium/src/chrome/browser/manifest/manifest_icon_selector.cc&q=ManifestIconSelector::IconSizesContainsBiggerThanMinimumSize&sq=package:chromium
const areIconsSquare = sizeNums[0] === sizeNums[1];
return areIconsBigEnough && areIconsSquare;
});
}
/**
* @param {NonNullable<LH.Artifacts.Manifest['value']>} manifest
* @return {boolean} Does the manifest icons value contain at least one icon with purpose including "maskable"
*/
function containsMaskableIcon(manifest) {
const iconValues = manifest.icons.value;
return iconValues.some(icon => {
return icon.value.purpose?.value &&
icon.value.purpose.value.includes('maskable');
});
}
export {
doExist,
pngSizedAtLeast,
containsMaskableIcon,
};