source: frontend/node_modules/svgo/plugins/prefixIds.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 5.4 KB
Line 
1'use strict';
2
3exports.type = 'perItem';
4
5exports.active = false;
6
7exports.params = {
8 delim: '__',
9 prefixIds: true,
10 prefixClassNames: true,
11};
12
13exports.description = 'prefix IDs';
14
15
16var path = require('path'),
17 csstree = require('css-tree'),
18 unquote = require('unquote'),
19 collections = require('./_collections.js'),
20 referencesProps = collections.referencesProps,
21 rxId = /^#(.*)$/, // regular expression for matching an ID + extracing its name
22 addPrefix = null;
23
24
25// Escapes a string for being used as ID
26var escapeIdentifierName = function(str) {
27 return str.replace(/[\. ]/g, '_');
28};
29
30// Matches an #ID value, captures the ID name
31var matchId = function(urlVal) {
32 var idUrlMatches = urlVal.match(rxId);
33 if (idUrlMatches === null) {
34 return false;
35 }
36 return idUrlMatches[1];
37};
38
39// Matches an url(...) value, captures the URL
40var matchUrl = function(val) {
41 var urlMatches = /url\((.*?)\)/gi.exec(val);
42 if (urlMatches === null) {
43 return false;
44 }
45 return urlMatches[1];
46};
47
48// Checks if attribute is empty
49var attrNotEmpty = function(attr) {
50 return (attr && attr.value && attr.value.length > 0);
51};
52
53// prefixes an #ID
54var prefixId = function(val) {
55 var idName = matchId(val);
56 if (!idName) {
57 return false;
58 }
59 return '#' + addPrefix(idName);
60};
61
62
63// attr.value helper methods
64
65// prefixes a class attribute value
66var addPrefixToClassAttr = function(attr) {
67 if (!attrNotEmpty(attr)) {
68 return;
69 }
70
71 attr.value = attr.value.split(/\s+/).map(addPrefix).join(' ');
72};
73
74// prefixes an ID attribute value
75var addPrefixToIdAttr = function(attr) {
76 if (!attrNotEmpty(attr)) {
77 return;
78 }
79
80 attr.value = addPrefix(attr.value);
81};
82
83// prefixes a href attribute value
84var addPrefixToHrefAttr = function(attr) {
85 if (!attrNotEmpty(attr)) {
86 return;
87 }
88
89 var idPrefixed = prefixId(attr.value);
90 if (!idPrefixed) {
91 return;
92 }
93 attr.value = idPrefixed;
94};
95
96// prefixes an URL attribute value
97var addPrefixToUrlAttr = function(attr) {
98 if (!attrNotEmpty(attr)) {
99 return;
100 }
101
102 // url(...) in value
103 var urlVal = matchUrl(attr.value);
104 if (!urlVal) {
105 return;
106 }
107
108 var idPrefixed = prefixId(urlVal);
109 if (!idPrefixed) {
110 return;
111 }
112
113 attr.value = 'url(' + idPrefixed + ')';
114};
115
116
117/**
118 * Prefixes identifiers
119 *
120 * @param {Object} node node
121 * @param {Object} opts plugin params
122 * @param {Object} extra plugin extra information
123 *
124 * @author strarsis <strarsis@gmail.com>
125 */
126exports.fn = function(node, opts, extra) {
127
128 // skip subsequent passes when multipass is used
129 if(extra.multipassCount && extra.multipassCount > 0) {
130 return node;
131 }
132
133 // prefix, from file name or option
134 var prefix = 'prefix';
135 if (opts.prefix) {
136 if (typeof opts.prefix === 'function') {
137 prefix = opts.prefix(node, extra);
138 } else {
139 prefix = opts.prefix;
140 }
141 } else if (opts.prefix === false) {
142 prefix = false;
143 } else if (extra && extra.path && extra.path.length > 0) {
144 var filename = path.basename(extra.path);
145 prefix = filename;
146 }
147
148
149 // prefixes a normal value
150 addPrefix = function(name) {
151 if(prefix === false){
152 return escapeIdentifierName(name);
153 }
154 return escapeIdentifierName(prefix + opts.delim + name);
155 };
156
157
158 // <style/> property values
159
160 if (node.elem === 'style') {
161 if (node.isEmpty()) {
162 // skip empty <style/>s
163 return node;
164 }
165
166 var cssStr = node.content[0].text || node.content[0].cdata || [];
167
168 var cssAst = {};
169 try {
170 cssAst = csstree.parse(cssStr, {
171 parseValue: true,
172 parseCustomProperty: false
173 });
174 } catch (parseError) {
175 console.warn('Warning: Parse error of styles of <style/> element, skipped. Error details: ' + parseError);
176 return node;
177 }
178
179 var idPrefixed = '';
180 csstree.walk(cssAst, function(node) {
181
182 // #ID, .class
183 if (((opts.prefixIds && node.type === 'IdSelector') ||
184 (opts.prefixClassNames && node.type === 'ClassSelector')) &&
185 node.name) {
186 node.name = addPrefix(node.name);
187 return;
188 }
189
190 // url(...) in value
191 if (node.type === 'Url' &&
192 node.value.value && node.value.value.length > 0) {
193 idPrefixed = prefixId(unquote(node.value.value));
194 if (!idPrefixed) {
195 return;
196 }
197 node.value.value = idPrefixed;
198 }
199
200 });
201
202 // update <style>s
203 node.content[0].text = csstree.generate(cssAst);
204 return node;
205 }
206
207
208 // element attributes
209
210 if (!node.attrs) {
211 return node;
212 }
213
214
215 // Nodes
216
217 if(opts.prefixIds) {
218 // ID
219 addPrefixToIdAttr(node.attrs.id);
220 }
221
222 if(opts.prefixClassNames) {
223 // Class
224 addPrefixToClassAttr(node.attrs.class);
225 }
226
227
228 // References
229
230 // href
231 addPrefixToHrefAttr(node.attrs.href);
232
233 // (xlink:)href (deprecated, must be still supported)
234 addPrefixToHrefAttr(node.attrs['xlink:href']);
235
236 // (referenceable) properties
237 for (var referencesProp of referencesProps) {
238 addPrefixToUrlAttr(node.attrs[referencesProp]);
239 }
240
241
242 return node;
243};
Note: See TracBrowser for help on using the repository browser.