Skip to content

Commit

Permalink
feat(icon): added optional favicon generation
Browse files Browse the repository at this point in the history
Added an option to generate favicon images and associated meta

fix #47
  • Loading branch information
onderceylan committed Oct 25, 2019
1 parent 351a3cc commit 699686a
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 31 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ $ pwa-asset-generator --help
-q --quality Image quality: 0...100 (Only for JPEG) [default: 100]
-h --splash-only Only generate splash screens [default: false]
-c --icon-only Only generate icons [default: false]
-f --favicon Generate favicon [default: false]
-l --landscape-only Only generate landscape splash screens [default: false]
-r --portrait-only Only generate portrait splash screens [default: false]
-u --single-quotes Generate HTML meta tags with single quotes [default: false]
Expand All @@ -84,6 +85,7 @@ $ pwa-asset-generator --help
$ pwa-asset-generator logo.svg -i ./index.html -m ./manifest.json
$ pwa-asset-generator https://your-cdn-server.com/assets/logo.png ./ -t jpeg -q 90 --splash-only --portrait-only
$ pwa-asset-generator logo.svg ./assets --scrape false --icon-only --path "%PUBLIC_URL%"
$ pwa-asset-generator logo.svg ./assets --icon-only --favicon
$ pwa-asset-generator https://raw.githubusercontent.com/onderceylan/pwa-asset-generator/HEAD/static/logo.png ./temp -p "15%" -b "linear-gradient(to right, #fa709a 0%, #fee140 100%)"
Flag examples
Expand All @@ -98,6 +100,7 @@ $ pwa-asset-generator --help
--quality 80
--splash-only
--icon-only
--favicon
--landscape-only
--portrait-only
--single-quotes
Expand Down
3 changes: 3 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ $ pwa-asset-generator --help
-q --quality Image quality: 0...100 (Only for JPEG) [default: 100]
-h --splash-only Only generate splash screens [default: false]
-c --icon-only Only generate icons [default: false]
-f --favicon Generate favicon [default: false]
-l --landscape-only Only generate landscape splash screens [default: false]
-r --portrait-only Only generate portrait splash screens [default: false]
-u --single-quotes Generate HTML meta tags with single quotes [default: false]
Expand All @@ -34,6 +35,7 @@ $ pwa-asset-generator --help
$ pwa-asset-generator logo.svg -i ./index.html -m ./manifest.json
$ pwa-asset-generator https://your-cdn-server.com/assets/logo.png ./ -t jpeg -q 90 --splash-only --portrait-only
$ pwa-asset-generator logo.svg ./assets --scrape false --icon-only --path "%PUBLIC_URL%"
$ pwa-asset-generator logo.svg ./assets --icon-only --favicon
$ pwa-asset-generator https://raw.githubusercontent.com/onderceylan/pwa-asset-generator/HEAD/static/logo.png ./temp -p "15%" -b "linear-gradient(to right, #fa709a 0%, #fee140 100%)"
Flag examples
Expand All @@ -48,6 +50,7 @@ $ pwa-asset-generator --help
--quality 80
--splash-only
--icon-only
--favicon
--landscape-only
--portrait-only
--single-quotes
Expand Down
12 changes: 12 additions & 0 deletions src/config/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ export default {
alias: 'u',
default: false,
},
favicon: {
type: 'boolean',
alias: 'f',
default: false,
},
},

PUPPETEER_LAUNCH_ARGS: [
Expand Down Expand Up @@ -114,13 +119,20 @@ export default {
// Windows platform specs: https://docs.microsoft.com/en-us/microsoft-edge/progressive-web-apps/get-started
MANIFEST_ICON_SIZES: [192, 512],

FAVICON_SIZES: [196],

FAVICON_FILENAME_PREFIX: 'favicon',
APPLE_ICON_FILENAME_PREFIX: 'apple-icon',
APPLE_SPLASH_FILENAME_PREFIX: 'apple-splash',
MANIFEST_ICON_FILENAME_PREFIX: 'manifest-icon',
APPLE_HIG_SPLASH_SCR_SPECS_DATA_GRID_SELECTOR: 'table tbody tr',
WAIT_FOR_SELECTOR_TIMEOUT: 1000,
BROWSER_SHELL_TIMEOUT: 60000,

FAVICON_META_HTML: (size: number, url: string, mimeType: string): string => `\
<link rel="icon" type="${mimeType}" sizes="${size}x${size}" href="${url}">
`,

SHELL_HTML_FOR_LOGO: (
imgPath: string,
backgroundColor = 'transparent',
Expand Down
6 changes: 2 additions & 4 deletions src/helpers/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ import {
import { get } from 'http';
import constants from '../config/constants';
import installer from './installer';
import preLogger from './logger';

const logger = preLogger('browser');

interface BrowserVersionInfo {
Browser: string;
Expand Down Expand Up @@ -106,7 +103,8 @@ const getSystemBrowserInstance = async (
});

browser.on('disconnected', () => {
chrome.kill().catch(e => logger.error(e.message));
// Silently try killing chrome
chrome.kill().catch();
});

return browser;
Expand Down
29 changes: 18 additions & 11 deletions src/helpers/images.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,25 @@ const mapToImageFileObj = (
orientation,
});

const getIconImages = (): Image[] => {
return uniqWith(
[
...constants.APPLE_ICON_SIZES.map(size =>
mapToSqImageFileObj(constants.APPLE_ICON_FILENAME_PREFIX, size),
),
...constants.MANIFEST_ICON_SIZES.map(size =>
mapToSqImageFileObj(constants.MANIFEST_ICON_FILENAME_PREFIX, size),
const getIconImages = (options: Options): Image[] => {
let icons = [
...constants.APPLE_ICON_SIZES.map(size =>
mapToSqImageFileObj(constants.APPLE_ICON_FILENAME_PREFIX, size),
),
...constants.MANIFEST_ICON_SIZES.map(size =>
mapToSqImageFileObj(constants.MANIFEST_ICON_FILENAME_PREFIX, size),
),
];

if (options.favicon) {
icons = [
...icons,
...constants.FAVICON_SIZES.map(size =>
mapToSqImageFileObj(constants.FAVICON_FILENAME_PREFIX, size),
),
],
isEqual,
);
];
}
return uniqWith(icons, isEqual);
};

const getSplashScreenImages = (
Expand Down
36 changes: 31 additions & 5 deletions src/helpers/pwa.ts → src/helpers/meta.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import cheerio from 'cheerio';
import { lookup } from 'mime-types';
import constants from '../config/constants';
import file from './file';
import { SavedImage } from '../models/image';
import { ManifestJsonIcon } from '../models/result';
import { Options } from '../models/options';

const generateIconsContentForManifest = (
savedImages: SavedImage[],
Expand Down Expand Up @@ -37,6 +39,23 @@ const generateAppleTouchIconHtml = (
.join('');
};

const generateFaviconHtml = (
savedImages: SavedImage[],
indexHtmlPath: string,
pathPrefix = '',
): string => {
return savedImages
.filter(image => image.name.startsWith(constants.FAVICON_FILENAME_PREFIX))
.map(({ width, path }) =>
constants.FAVICON_META_HTML(
width,
pathPrefix + file.getRelativeImagePath(indexHtmlPath, path),
lookup(path) as string,
),
)
.join('');
};

const generateAppleLaunchImageHtml = (
savedImages: SavedImage[],
indexHtmlPath: string,
Expand Down Expand Up @@ -67,17 +86,24 @@ const getPathPrefix = (pathPrefix: string): string => {

const generateHtmlForIndexPage = (
savedImages: SavedImage[],
indexHtmlPath = '',
pathPrefix = '',
singleQuotes: boolean,
options: Options,
): string => {
const indexHtmlPath = options.index || '';
const pathPrefix = options.path || '';
const prependPath = getPathPrefix(pathPrefix);
const html = `\
let html = '';

if (options.favicon) {
html += `${generateFaviconHtml(savedImages, indexHtmlPath, prependPath)}
`;
}

html += `\
${generateAppleTouchIconHtml(savedImages, indexHtmlPath, prependPath)}
<meta name="apple-mobile-web-app-capable" content="yes">
${generateAppleLaunchImageHtml(savedImages, indexHtmlPath, prependPath)}`;

if (singleQuotes) {
if (options.singleQuotes) {
return html.replace(/"/gm, "'");
}

Expand Down
2 changes: 1 addition & 1 deletion src/helpers/puppets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ const generateImages = async (
...(!options.iconOnly
? images.getSplashScreenImages(splashScreenMetaData, options)
: []),
...(!options.splashOnly ? images.getIconImages() : []),
...(!options.splashOnly ? images.getIconImages(options) : []),
];

if (!(await file.pathExists(output, file.WRITE_ACCESS))) {
Expand Down
15 changes: 5 additions & 10 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pwa from './helpers/pwa';
import meta from './helpers/meta';
import puppets from './helpers/puppets';
import flags from './helpers/flags';
import preLogger from './helpers/logger';
Expand Down Expand Up @@ -72,20 +72,15 @@ async function generateImages(
const output = flags.normalizeOutput(outputFolderPath);

const savedImages = await puppets.generateImages(source, output, modOptions);
const manifestJsonContent = pwa.generateIconsContentForManifest(
const manifestJsonContent = meta.generateIconsContentForManifest(
savedImages,
modOptions.manifest,
);
const htmlContent = pwa.generateHtmlForIndexPage(
savedImages,
modOptions.index,
modOptions.path,
modOptions.singleQuotes,
);
const htmlContent = meta.generateHtmlForIndexPage(savedImages, modOptions);

if (!modOptions.splashOnly) {
if (modOptions.manifest) {
await pwa.addIconsToManifest(manifestJsonContent, modOptions.manifest);
await meta.addIconsToManifest(manifestJsonContent, modOptions.manifest);
logger.success(
`Icons are saved to Web App Manifest file ${modOptions.manifest}`,
);
Expand All @@ -101,7 +96,7 @@ async function generateImages(
}

if (modOptions.index) {
await pwa.addMetaTagsToIndexPage(htmlContent, modOptions.index);
await meta.addMetaTagsToIndexPage(htmlContent, modOptions.index);
logger.success(
`iOS meta tags are saved to index html file ${modOptions.index}`,
);
Expand Down
7 changes: 7 additions & 0 deletions src/models/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,13 @@ export interface Options {
@default false
*/
readonly singleQuotes: boolean;

/**
Generates favicon images and HTML meta tags
@default false
*/
readonly favicon: boolean;
}

export type CLIOptions = Partial<Options>;

0 comments on commit 699686a

Please sign in to comment.