1 | 'use strict';
|
2 |
|
3 | var fs = require('fs');
|
4 | var path = require('path');
|
5 | var _ = require('lodash');
|
6 | var Funnel = require('broccoli-funnel');
|
7 | var MergeTrees = require('broccoli-merge-trees');
|
8 | var SVGOptimizer = require('broccoli-svg-optimizer');
|
9 | var Symbolizer = require('broccoli-symbolizer');
|
10 | var InlinePacker = require('./inline-packer');
|
11 | var ViewerAssetsBuilder = require('./viewer-assets-builder');
|
12 | var ViewerBuilder = require('./viewer-builder');
|
13 | var validateOptions = require('./validate-options');
|
14 | var defaultGenerators = require('./default-generators');
|
15 |
|
16 |
|
17 | var GLOBAL_OPTIONS = ['sourceDirs', 'stripPath', 'optimizer'];
|
18 |
|
19 | var symbolsLoaderScript = fs.readFileSync(path.join(__dirname, '../symbols-loader.html'), 'utf8');
|
20 |
|
21 | function mergeTreesIfNeeded(trees, options) {
|
22 | return trees.length === 1 ? trees[0] : new MergeTrees(trees, options);
|
23 | }
|
24 |
|
25 | function memoize(fn) {
|
26 | var cache = {};
|
27 |
|
28 | return function () {
|
29 | var cacheKey = JSON.stringify(arguments);
|
30 | cache[cacheKey] = cache[cacheKey] || fn.apply(this, arguments);
|
31 | return cache[cacheKey];
|
32 | };
|
33 | }
|
34 |
|
35 | module.exports = {
|
36 | name: 'ember-svg-jar',
|
37 |
|
38 | isDevelopingAddon: function isDevelopingAddon() {
|
39 | return false;
|
40 | },
|
41 | included: function included(app) {
|
42 | this._super.included.apply(this, arguments);
|
43 |
|
44 |
|
45 | if (typeof app.import !== 'function' && app.app) {
|
46 |
|
47 | app = app.app;
|
48 | }
|
49 |
|
50 | this.initializeOptions(app.options.svgJar, app.env);
|
51 | },
|
52 | treeForPublic: function treeForPublic() {
|
53 | var trees = [];
|
54 |
|
55 | if (this.options.viewer.enabled) {
|
56 | trees.push(this.getViewerTree());
|
57 |
|
58 | if (this.options.viewer.embed) {
|
59 | trees.push(this._super.treeForPublic.apply(this, arguments));
|
60 | }
|
61 | }
|
62 |
|
63 | if (this.hasSymbolStrategy()) {
|
64 | trees.push(this.getSymbolStrategyTree());
|
65 | }
|
66 |
|
67 | return mergeTreesIfNeeded(trees);
|
68 | },
|
69 | treeForApp: function treeForApp(appTree) {
|
70 | var trees = [appTree];
|
71 |
|
72 | if (this.hasInlineStrategy()) {
|
73 | trees.push(this.getInlineStrategyTree());
|
74 | }
|
75 |
|
76 | return mergeTreesIfNeeded(trees, { overwrite: true });
|
77 | },
|
78 | contentFor: function contentFor(type) {
|
79 | var includeLoader = this.hasSymbolStrategy() && this.optionFor('symbol', 'includeLoader');
|
80 |
|
81 | if (type === 'body' && includeLoader) {
|
82 | return symbolsLoaderScript.replace('{{FILE_PATH}}', this.optionFor('symbol', 'outputFile'));
|
83 | }
|
84 |
|
85 | return '';
|
86 | },
|
87 | initializeOptions: function initializeOptions(options, env) {
|
88 | this.options = _.merge({
|
89 | sourceDirs: ['public'],
|
90 | strategy: 'inline',
|
91 | stripPath: true,
|
92 | optimizer: {},
|
93 | persist: true,
|
94 |
|
95 | viewer: {
|
96 | enabled: env === 'development',
|
97 | embed: env === 'development'
|
98 | },
|
99 |
|
100 | inline: {
|
101 | idGen: defaultGenerators.inlineIdGen,
|
102 | copypastaGen: defaultGenerators.inlineCopypastaGen
|
103 | },
|
104 |
|
105 | symbol: {
|
106 | idGen: defaultGenerators.symbolIdGen,
|
107 | copypastaGen: defaultGenerators.symbolCopypastaGen,
|
108 | outputFile: '/assets/symbols.svg',
|
109 | prefix: '',
|
110 | includeLoader: true
|
111 | }
|
112 | }, options || {});
|
113 |
|
114 | validateOptions(this.options);
|
115 | this.options.strategy = _.castArray(this.options.strategy);
|
116 | },
|
117 | optionFor: function optionFor(strategy, optionName) {
|
118 | return _.isUndefined(this.options[strategy][optionName]) ? GLOBAL_OPTIONS.indexOf(optionName) !== -1 && this.options[optionName] : this.options[strategy][optionName];
|
119 | },
|
120 | sourceDirsFor: function sourceDirsFor(strategy) {
|
121 | return this.optionFor(strategy, 'sourceDirs').filter(function (sourceDir) {
|
122 | return fs.existsSync(sourceDir);
|
123 | });
|
124 | },
|
125 |
|
126 |
|
127 | optimizedSvgsFor: memoize(function (strategy) {
|
128 | var sourceDirs = this.sourceDirsFor(strategy);
|
129 | var svgFiles = new Funnel(mergeTreesIfNeeded(sourceDirs), {
|
130 | include: ['**/*.svg']
|
131 | });
|
132 |
|
133 | var svgoConfig = this.optionFor(strategy, 'optimizer');
|
134 | if (svgoConfig) {
|
135 | svgFiles = new SVGOptimizer(svgFiles, {
|
136 | svgoConfig: svgoConfig,
|
137 | persist: this.options.persist
|
138 | });
|
139 | }
|
140 |
|
141 | return svgFiles;
|
142 | }),
|
143 |
|
144 | originalSvgsFor: function originalSvgsFor(strategy) {
|
145 | var sourceDirs = this.sourceDirsFor(strategy);
|
146 |
|
147 | return new Funnel(mergeTreesIfNeeded(sourceDirs), {
|
148 | include: ['**/*.svg'],
|
149 | destDir: '__original__'
|
150 | });
|
151 | },
|
152 | getViewerTree: function getViewerTree() {
|
153 | var _this = this;
|
154 |
|
155 | var idGenOpts = {
|
156 | symbol: {
|
157 | prefix: this.optionFor('symbol', 'prefix')
|
158 | }
|
159 | };
|
160 |
|
161 | var viewerBuilderNodes = this.options.strategy.map(function (strategy) {
|
162 | var inputNode = new MergeTrees([_this.optimizedSvgsFor(strategy), _this.originalSvgsFor(strategy)]);
|
163 |
|
164 | return new ViewerAssetsBuilder(inputNode, {
|
165 | strategy: strategy,
|
166 | idGen: _this.optionFor(strategy, 'idGen'),
|
167 | idGenOpts: idGenOpts[strategy],
|
168 | copypastaGen: _this.optionFor(strategy, 'copypastaGen'),
|
169 | stripPath: _this.optionFor(strategy, 'stripPath'),
|
170 | outputFile: strategy + '.json',
|
171 | ui: _this.ui
|
172 | });
|
173 | });
|
174 |
|
175 | return new ViewerBuilder(mergeTreesIfNeeded(viewerBuilderNodes), {
|
176 | outputFile: 'svg-jar.json',
|
177 | hasManyStrategies: this.options.strategy.length > 1
|
178 | });
|
179 | },
|
180 | getInlineStrategyTree: function getInlineStrategyTree() {
|
181 | return new InlinePacker(this.optimizedSvgsFor('inline'), {
|
182 | idGen: this.optionFor('inline', 'idGen'),
|
183 | stripPath: this.optionFor('inline', 'stripPath'),
|
184 | outputFile: 'inline-assets.js'
|
185 | });
|
186 | },
|
187 | getSymbolStrategyTree: function getSymbolStrategyTree() {
|
188 | return new Symbolizer(this.optimizedSvgsFor('symbol'), {
|
189 | idGen: this.optionFor('symbol', 'idGen'),
|
190 | stripPath: this.optionFor('symbol', 'stripPath'),
|
191 | outputFile: this.optionFor('symbol', 'outputFile'),
|
192 | prefix: this.optionFor('symbol', 'prefix'),
|
193 | persist: this.options.persist
|
194 | });
|
195 | },
|
196 | hasInlineStrategy: function hasInlineStrategy() {
|
197 | return this.options.strategy.indexOf('inline') !== -1;
|
198 | },
|
199 | hasSymbolStrategy: function hasSymbolStrategy() {
|
200 | return this.options.strategy.indexOf('symbol') !== -1;
|
201 | }
|
202 | }; |
\ | No newline at end of file |