UNPKG

ember-svg-jar

Version:

Best way to use SVG images in Ember applications

208 lines (154 loc) 5.66 kB
'use strict'; const fs = require('fs'); const _ = require('lodash'); const { makeIDForPath } = require('./utils'); function mergeTreesIfNeeded(trees, options) { if (trees.length === 1) { return trees[0]; } let mergedOptions = _.assign({ overwrite: true }, options); const MergeTrees = require('broccoli-merge-trees'); return new MergeTrees(trees, mergedOptions); } module.exports = { name: 'ember-svg-jar', isDevelopingAddon() { return false; }, included(app) { this._super.included.apply(this, arguments); const buildOptions = require('./build-options'); this.svgJarOptions = buildOptions(app); }, treeForPublic() { let trees = []; if (this.svgJarOptions.viewer.enabled) { // Add `svg-jar-viewer.json` to public dir trees.push(this.getViewerTree()); // Add viewer assets to public dir let svgJarPublicTree = this._super.treeForPublic.apply(this, arguments); const broccoliReplace = require('broccoli-replace'); svgJarPublicTree = broccoliReplace(svgJarPublicTree, { files: ['**/index.html'], patterns: [ { match: /\{\{ROOT_URL\}\}/g, replacement: this.svgJarOptions.rootURL, }, ], }); trees.push(svgJarPublicTree); } if (this.hasSymbolStrategy()) { trees.push(this.getSymbolStrategyTree()); } return mergeTreesIfNeeded(trees); }, treeForAddon(addonTree) { let trees = [addonTree]; if (this.hasInlineStrategy()) { trees.push(this.getInlineStrategyTree()); } return this._super.treeForAddon.call(this, mergeTreesIfNeeded(trees)); }, contentFor(type, app) { const includeLoader = this.hasSymbolStrategy() && this.optionFor('symbol', 'includeLoader'); if (type === 'body' && includeLoader) { const rootURL = this.svgJarOptions.rootURL; const outputFile = this.optionFor('symbol', 'outputFile'); const isTestEnv = app.environment === 'test'; const prepareSymbolLoaderScript = require('./prepare-symbol-loader-script'); return prepareSymbolLoaderScript(rootURL, outputFile, isTestEnv); } return ''; }, optionFor(strategy, optionName) { // globalOptions can be both root or strategy specific. let globalOptions = ['sourceDirs', 'stripPath', 'optimizer']; return _.isUndefined(this.svgJarOptions[strategy][optionName]) ? globalOptions.indexOf(optionName) !== -1 && this.svgJarOptions[optionName] : this.svgJarOptions[strategy][optionName]; }, sourceDirsFor(strategy) { return this.optionFor(strategy, 'sourceDirs').filter( sourceDir => typeof sourceDir !== 'string' || fs.existsSync(sourceDir) ); }, originalSvgsFor(strategy) { let sourceDirs = this.sourceDirsFor(strategy); const Funnel = require('broccoli-funnel'); return new Funnel(mergeTreesIfNeeded(sourceDirs), { include: ['**/*.svg'], }); }, optimizedSvgsFor(strategy, originalSvgs) { let optimizerConfig = this.optionFor(strategy, 'optimizer'); const SVGOptimizer = require('broccoli-svg-optimizer'); return new SVGOptimizer(originalSvgs, { svgoConfig: _.omit(optimizerConfig, 'svgoModule'), svgoModule: optimizerConfig.svgoModule, persist: this.svgJarOptions.persist, }); }, svgsFor(strategy) { let originalSvgs = this.originalSvgsFor(strategy); return this.hasOptimizerFor(strategy) ? this.optimizedSvgsFor(strategy, originalSvgs) : originalSvgs; }, getViewerTree() { let viewerBuilderTrees = this.svgJarOptions.strategy.map(strategy => { let idGen = this.optionFor(strategy, 'idGen'); let stripPath = this.optionFor(strategy, 'stripPath'); let prefix = this.optionFor(strategy, 'prefix'); const ViewerAssetsBuilder = require('./viewer-assets-builder'); return new ViewerAssetsBuilder(this.svgsFor(strategy), { strategy, validationConfig: this.svgJarOptions.validations, copypastaGen: this.optionFor(strategy, 'copypastaGen'), makeAssetID(relativePath) { return makeIDForPath(relativePath, { idGen, stripPath, prefix }); }, }); }); const ViewerBuilder = require('./viewer-builder'); return new ViewerBuilder(mergeTreesIfNeeded(viewerBuilderTrees), { outputFile: 'svg-jar-viewer.json', }); }, getInlineStrategyTree() { let idGen = this.optionFor('inline', 'idGen'); let stripPath = this.optionFor('inline', 'stripPath'); const InlinePacker = require('./inline-packer'); return new InlinePacker(this.svgsFor('inline'), { makeAssetID(relativePath) { return makeIDForPath(relativePath, { idGen, stripPath }); }, }); }, getSymbolStrategyTree() { let idGen = this.optionFor('symbol', 'idGen'); let stripPath = this.optionFor('symbol', 'stripPath'); let prefix = this.optionFor('symbol', 'prefix'); const Symbolizer = require('./symbolizer/symbolizer'); return new Symbolizer(this.svgsFor('symbol'), { outputFile: this.optionFor('symbol', 'outputFile'), svgAttrs: this.optionFor('symbol', 'containerAttrs'), persist: this.svgJarOptions.persist, makeAssetID(relativePath) { return makeIDForPath(relativePath, { idGen, stripPath, prefix }); }, }); }, hasOptimizerFor(strategy) { return this.optionFor(strategy, 'optimizer'); }, hasInlineStrategy() { return this.svgJarOptions.strategy.includes('inline'); }, hasSymbolStrategy() { return this.svgJarOptions.strategy.includes('symbol'); }, };