| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 | const fs = require('fs');const path = require('path');const sass = require('node-sass');let iconsIndex = [];// Merge a `source` object to a `target` recursivelyconst merge = (target, source) => {  // Check if font name is changed  if (source['font-name']) {    target['font-name'] = source['font-name'];  }  // Check if root dir is changed  if (source['root-dir']) {    target['root-dir'] = source['root-dir'];  }  // Check for icon changes  if (source.icons) {    for (let icon of source['icons']) {      let index = iconsIndex.indexOf(icon.name);      // Icon is replaced      if (index !== -1) {        target.icons[index] = icon;      }      // New icon is added      else {        target.icons.push(icon);        iconsIndex.push(icon.name);      }    }  }  return target;}module.exports = function(grunt) {  grunt.initConfig({    sass: {      options: {        implementation: sass      },      dist: {        files: {          'css/videojs-icons.css': 'scss/videojs-icons.scss'        }      }    },    watch: {      all: {        files: ['**/*.hbs', '**/*.js', './icons.json'],        tasks: ['default']      }    }  });  grunt.registerTask('generate-font', function() {    const done = this.async();    let webfontsGenerator = require('webfonts-generator');    let iconConfig = grunt.file.readJSON(path.join(__dirname, '..', 'icons.json'));    let svgRootDir = iconConfig['root-dir'];    if (grunt.option('exclude-default')) {      // Exclude default video.js icons      iconConfig.icons = [];    }    let icons = iconConfig.icons;    // Index default icons    icons.forEach(icon => iconsIndex.push(icon.name));    // Merge custom icons    const customPaths = (grunt.option('custom-json') || '').split(',').filter(Boolean);    customPaths.forEach(customPath => {      const customConfig = grunt.file.readJSON(path.resolve(process.cwd(), customPath));      iconConfig = merge(iconConfig, customConfig);    });    icons = iconConfig.icons;    let iconFiles = icons.map(icon => {      // If root-dir is specified for a specific icon, use that.      if (icon['root-dir']) {        return icon['root-dir'] + icon.svg;      }      // Otherwise, use the default root-dir.      return svgRootDir + icon.svg;    });    webfontsGenerator({      files: iconFiles,      dest: 'fonts/',      fontName: iconConfig['font-name'],      cssDest: 'scss/_icons.scss',      cssTemplate: './templates/scss.hbs',      htmlDest: 'index.html',      htmlTemplate: './templates/html.hbs',      html: true,      rename: iconPath => {        const fileName = path.basename(iconPath);        const iconName = icons.find(icon => path.basename(icon.svg) === fileName).name;        return iconName;      },      types: ['svg', 'woff', 'ttf']    }, error => {      if (error) {        console.error(error);        done(false);      }      done();    });  });  grunt.registerTask('update-base64', function() {    const iconScssFile = './scss/_icons.scss';    const iconConfig = grunt.option('custom-json') ?      grunt.file.readJSON(path.resolve(process.cwd(), grunt.option('custom-json'))) :      grunt.file.readJSON(path.join(__dirname, '..', 'icons.json'));    const fontName = iconConfig['font-name'];    const fontFiles = {      woff: './fonts/' + fontName + '.woff'    };    let scssContents = fs.readFileSync(iconScssFile).toString();    Object.keys(fontFiles).forEach(font => {      const fontFile = fontFiles[font];      const fontContent = fs.readFileSync(fontFile);      const regex = new RegExp(`(url.*font-${font}.*base64,)([^\\s]+)(\\).*)`);      scssContents = scssContents.replace(regex, `$1${fontContent.toString('base64')}$3`);    });    fs.writeFileSync(iconScssFile, scssContents);  });  grunt.registerTask('default', ['generate-font', 'update-base64', 'sass']);};
 |