UNPKG

apple-touch-icons-webpack-plugin

Version:

a webpack plugin for automatically creating apple touch icons and launch screens

187 lines (136 loc) 4.4 kB
const fs = require('fs') const imagemagick = require('imagemagick-convert') const default_image_icon = "apple-touch-icon.png" const default_launch_screens = ["launch-screen-portrait.png","launch-screen-landscape.png"] const default_image_ipad = "ipad.png" class AppleTouchIconsPlugin { constructor({ icon = null, launch_screen = null, ipad = null, resize = "crop", icon_sizes = [[57, 57],[72, 72],[76, 76],[114, 114],[120, 120],[144, 144],[152, 152],[167, 167],[180, 180], [1024,1024]], launch_screen_sizes = [[1024,481],[1024,481]], ipad_sizes = [[568,320],[667,375],[736,414],[812,375],[1024,768],[834,834], [1024,1024] ] } = {}) { this.icon = icon; this.launch_screen = launch_screen; this.ipad = ipad; this.resize = resize; this.icon_sizes = icon_sizes; this.launch_screen_sizes = launch_screen_sizes; this.ipad_sizes = ipad_sizes; // handlers this.process = this.process.bind(this) } compile(compilation,filename, data, size) { const filenameWithExtension = filename.replace(/^.*[\\\/]/, ''); const name = filenameWithExtension.split('.')[0]; const ext = filenameWithExtension.split('.').pop(); const [height, ...width] = size const new_file_path = name + "-" + height + "x" + width + "." + ext compilation.assets[new_file_path] = { source: () => data, size: () => data.length }; return filenameWithExtension; } async processImage(filename, size, options = {resize: this.resize}) { let format = filename.split('.').pop(); let srcFormat; switch(format.toLowerCase()) { case 'jpg': srcFormat = 'JPEG' break; case 'jpeg': srcFormat = 'JPEG' break; default: srcFormat = 'PNG' } const [height, ...width] = size; return await imagemagick.convert({ srcData: fs.readFileSync(filename), srcFormat: srcFormat, width: width, height: height, resize: options.resize, format: 'PNG' }); } processFile(compilation,filename, options) { const that = this return options.icon_sizes.map(size => { that.processImage( filename, size,options).then(image_data => { return this.compile(compilation, image_data, filename, size); })}); } processIpad(compilation, filename, options) { let that = this return options.ipad_sizes.map(size => { that.processImage( filename, size,options).then(image_data => { return this.compile(compilation, image_data, filename, size); })}); } processScreen(compilation, filename, options) { let that = this return options.launch_screen_sizes.map(size => { that.processImage( filename, size,options).then(image_data => { return this.compile(compilation, image_data, filename, size); })}); } process(compilation, callback) { let assetNames = Object.keys(compilation.assets); Promise.all( assetNames.map(name => { if(this.icon == null) { if(name === default_image_icon){ let currentAsset = compilation.assets[name]; let source = currentAsset.source() this.processFile(compilation, source, this.options) } }else{ if(name === this.icon){ let currentAsset = compilation.assets[name]; let source = currentAsset.source() this.processFile(compilation, source, this.options) } } if(this.launch_screen == null) { if(default_launch_screens.includes(name)){ let currentAsset = compilation.assets[name]; let source = currentAsset.source() this.processScreen(source, this.options) } }else { if (name === this.launch_screen) { let currentAsset = compilation.assets[name]; let source = currentAsset.source() this.processScreen(compilation, source, this.options) } } if(this.ipad == null) { if(name === default_image_ipad){ let currentAsset = compilation.assets[name]; let source = currentAsset.source() this.processIpad(source, this.options) } }else{ if(name === this.ipad ){ let currentAsset = compilation.assets[name]; let source = currentAsset.source() this.processIpad(compilation, source, this.options) } } return Promise.resolve(0); }) ).then(args => { callback() }); } apply(compiler) { this.compiler = compiler compiler.hooks.emit.tapAsync('AppleTouchIconsPlugin', this.process) } } module.exports = AppleTouchIconsPlugin;