UNPKG

5.58 kBJavaScriptView Raw
1'use strict';
2
3const fs = require('fs');
4const path = require('path');
5const _ = require('lodash');
6const Funnel = require('broccoli-funnel');
7const MergeTrees = require('broccoli-merge-trees');
8const SVGOptimizer = require('broccoli-svg-optimizer');
9const broccoliReplace = require('broccoli-string-replace');
10const Symbolizer = require('./symbolizer/symbolizer');
11const InlinePacker = require('./inline-packer');
12const ViewerAssetsBuilder = require('./viewer-assets-builder');
13const ViewerBuilder = require('./viewer-builder');
14const buildOptions = require('./build-options');
15const { toPosixPath, makeIDForPath } = require('./utils');
16
17const symbolsLoaderScript = fs.readFileSync(path.join(__dirname, '../symbols-loader.html'), 'utf8');
18
19function mergeTreesIfNeeded(trees, options) {
20 let mergedOptions = _.assign({ overwrite: true }, options);
21 return trees.length === 1 ? trees[0] : new MergeTrees(trees, mergedOptions);
22}
23
24module.exports = {
25 name: 'ember-svg-jar',
26
27 isDevelopingAddon() {
28 return false;
29 },
30
31 included(app) {
32 this._super.included.apply(this, arguments);
33 this.svgJarOptions = buildOptions(app);
34 },
35
36 treeForPublic() {
37 let trees = [];
38
39 if (this.svgJarOptions.viewer.enabled) {
40 // Add `svg-jar-viewer.json` to public dir
41 trees.push(this.getViewerTree());
42
43 // Add viewer assets to public dir
44 let svgJarPublicTree = this._super.treeForPublic.apply(this, arguments);
45
46 svgJarPublicTree = broccoliReplace(svgJarPublicTree, {
47 files: ['**/index.html'],
48 pattern: {
49 match: /\{\{ROOT_URL\}\}/g,
50 replacement: this.svgJarOptions.rootURL
51 }
52 });
53
54 trees.push(svgJarPublicTree);
55 }
56
57 if (this.hasSymbolStrategy()) {
58 trees.push(this.getSymbolStrategyTree());
59 }
60
61 return mergeTreesIfNeeded(trees);
62 },
63
64 treeForAddon(addonTree) {
65 let trees = [addonTree];
66
67 if (this.hasInlineStrategy()) {
68 trees.push(this.getInlineStrategyTree());
69 }
70
71 return this._super.treeForAddon.call(this, mergeTreesIfNeeded(trees));
72 },
73
74 contentFor(type) {
75 let includeLoader = this.hasSymbolStrategy() && this.optionFor('symbol', 'includeLoader');
76
77 if (type === 'body' && includeLoader) {
78 let symbolsURL = path.join(
79 this.svgJarOptions.rootURL,
80 this.optionFor('symbol', 'outputFile')
81 );
82 return symbolsLoaderScript.replace('{{SYMBOLS_URL}}', toPosixPath(symbolsURL));
83 }
84
85 return '';
86 },
87
88 optionFor(strategy, optionName) {
89 // globalOptions can be both root or strategy specific.
90 let globalOptions = ['sourceDirs', 'stripPath', 'optimizer'];
91
92 return _.isUndefined(this.svgJarOptions[strategy][optionName])
93 ? globalOptions.indexOf(optionName) !== -1 && this.svgJarOptions[optionName]
94 : this.svgJarOptions[strategy][optionName];
95 },
96
97 sourceDirsFor(strategy) {
98 return this.optionFor(strategy, 'sourceDirs').filter(
99 (sourceDir) => typeof sourceDir !== 'string' || fs.existsSync(sourceDir)
100 );
101 },
102
103 originalSvgsFor(strategy) {
104 let sourceDirs = this.sourceDirsFor(strategy);
105
106 return new Funnel(mergeTreesIfNeeded(sourceDirs), {
107 include: ['**/*.svg']
108 });
109 },
110
111 optimizedSvgsFor(strategy, originalSvgs) {
112 let optimizerConfig = this.optionFor(strategy, 'optimizer');
113
114 return new SVGOptimizer(originalSvgs, {
115 svgoConfig: _.omit(optimizerConfig, 'svgoModule'),
116 svgoModule: optimizerConfig.svgoModule,
117 persist: this.svgJarOptions.persist
118 });
119 },
120
121 svgsFor(strategy) {
122 let originalSvgs = this.originalSvgsFor(strategy);
123
124 return this.hasOptimizerFor(strategy)
125 ? this.optimizedSvgsFor(strategy, originalSvgs)
126 : originalSvgs;
127 },
128
129 getViewerTree() {
130 let viewerBuilderTrees = this.svgJarOptions.strategy.map((strategy) => {
131 let idGen = this.optionFor(strategy, 'idGen');
132 let stripPath = this.optionFor(strategy, 'stripPath');
133 let prefix = this.optionFor(strategy, 'prefix');
134
135 return new ViewerAssetsBuilder(this.svgsFor(strategy), {
136 strategy,
137 validationConfig: this.svgJarOptions.validations,
138 copypastaGen: this.optionFor(strategy, 'copypastaGen'),
139
140 makeAssetID(relativePath) {
141 return makeIDForPath(relativePath, { idGen, stripPath, prefix });
142 }
143 });
144 });
145
146 return new ViewerBuilder(mergeTreesIfNeeded(viewerBuilderTrees), {
147 outputFile: 'svg-jar-viewer.json'
148 });
149 },
150
151 getInlineStrategyTree() {
152 let idGen = this.optionFor('inline', 'idGen');
153 let stripPath = this.optionFor('inline', 'stripPath');
154
155 return new InlinePacker(this.svgsFor('inline'), {
156 makeAssetID(relativePath) {
157 return makeIDForPath(relativePath, { idGen, stripPath });
158 }
159 });
160 },
161
162 getSymbolStrategyTree() {
163 let idGen = this.optionFor('symbol', 'idGen');
164 let stripPath = this.optionFor('symbol', 'stripPath');
165 let prefix = this.optionFor('symbol', 'prefix');
166
167 return new Symbolizer(this.svgsFor('symbol'), {
168 outputFile: this.optionFor('symbol', 'outputFile'),
169 svgAttrs: this.optionFor('symbol', 'containerAttrs'),
170 persist: this.svgJarOptions.persist,
171
172 makeAssetID(relativePath) {
173 return makeIDForPath(relativePath, { idGen, stripPath, prefix });
174 }
175 });
176 },
177
178 hasOptimizerFor(strategy) {
179 return this.optionFor(strategy, 'optimizer');
180 },
181
182 hasInlineStrategy() {
183 return this.svgJarOptions.strategy.indexOf('inline') !== -1;
184 },
185
186 hasSymbolStrategy() {
187 return this.svgJarOptions.strategy.indexOf('symbol') !== -1;
188 }
189};