source: trip-planner-front/node_modules/postcss-minify-font-values/dist/lib/minify-family.js@ 8d391a1

Last change on this file since 8d391a1 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 5.6 KB
Line 
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.default = _default;
7
8var _postcssValueParser = require("postcss-value-parser");
9
10var _uniqs = _interopRequireDefault(require("./uniqs"));
11
12function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
14const uniqs = (0, _uniqs.default)('monospace');
15const globalKeywords = ['inherit', 'initial', 'unset'];
16const genericFontFamilykeywords = ['sans-serif', 'serif', 'fantasy', 'cursive', 'monospace', 'system-ui'];
17
18function makeArray(value, length) {
19 let array = [];
20
21 while (length--) {
22 array[length] = value;
23 }
24
25 return array;
26} // eslint-disable-next-line no-useless-escape
27
28
29const regexSimpleEscapeCharacters = /[ !"#$%&'()*+,.\/;<=>?@\[\\\]^`{|}~]/;
30
31function escape(string, escapeForString) {
32 let counter = 0;
33 let character = null;
34 let charCode = null;
35 let value = null;
36 let output = '';
37
38 while (counter < string.length) {
39 character = string.charAt(counter++);
40 charCode = character.charCodeAt(); // \r is already tokenized away at this point
41 // `:` can be escaped as `\:`, but that fails in IE < 8
42
43 if (!escapeForString && /[\t\n\v\f:]/.test(character)) {
44 value = '\\' + charCode.toString(16) + ' ';
45 } else if (!escapeForString && regexSimpleEscapeCharacters.test(character)) {
46 value = '\\' + character;
47 } else {
48 value = character;
49 }
50
51 output += value;
52 }
53
54 if (!escapeForString) {
55 if (/^-[-\d]/.test(output)) {
56 output = '\\-' + output.slice(1);
57 }
58
59 const firstChar = string.charAt(0);
60
61 if (/\d/.test(firstChar)) {
62 output = '\\3' + firstChar + ' ' + output.slice(1);
63 }
64 }
65
66 return output;
67}
68
69const regexKeyword = new RegExp(genericFontFamilykeywords.concat(globalKeywords).join('|'), 'i');
70const regexInvalidIdentifier = /^(-?\d|--)/;
71const regexSpaceAtStart = /^\x20/;
72const regexWhitespace = /[\t\n\f\r\x20]/g;
73const regexIdentifierCharacter = /^[a-zA-Z\d\xa0-\uffff_-]+$/;
74const regexConsecutiveSpaces = /(\\(?:[a-fA-F0-9]{1,6}\x20|\x20))?(\x20{2,})/g;
75const regexTrailingEscape = /\\[a-fA-F0-9]{0,6}\x20$/;
76const regexTrailingSpace = /\x20$/;
77
78function escapeIdentifierSequence(string) {
79 let identifiers = string.split(regexWhitespace);
80 let index = 0;
81 let result = [];
82 let escapeResult;
83
84 while (index < identifiers.length) {
85 let subString = identifiers[index++];
86
87 if (subString === '') {
88 result.push(subString);
89 continue;
90 }
91
92 escapeResult = escape(subString, false);
93
94 if (regexIdentifierCharacter.test(subString)) {
95 // the font family name part consists of allowed characters exclusively
96 if (regexInvalidIdentifier.test(subString)) {
97 // the font family name part starts with two hyphens, a digit, or a
98 // hyphen followed by a digit
99 if (index === 1) {
100 // if this is the first item
101 result.push(escapeResult);
102 } else {
103 // if it’s not the first item, we can simply escape the space
104 // between the two identifiers to merge them into a single
105 // identifier rather than escaping the start characters of the
106 // second identifier
107 result[index - 2] += '\\';
108 result.push(escape(subString, true));
109 }
110 } else {
111 // the font family name part doesn’t start with two hyphens, a digit,
112 // or a hyphen followed by a digit
113 result.push(escapeResult);
114 }
115 } else {
116 // the font family name part contains invalid identifier characters
117 result.push(escapeResult);
118 }
119 }
120
121 result = result.join(' ').replace(regexConsecutiveSpaces, ($0, $1, $2) => {
122 const spaceCount = $2.length;
123 const escapesNeeded = Math.floor(spaceCount / 2);
124 const array = makeArray('\\ ', escapesNeeded);
125
126 if (spaceCount % 2) {
127 array[escapesNeeded - 1] += '\\ ';
128 }
129
130 return ($1 || '') + ' ' + array.join(' ');
131 }); // Escape trailing spaces unless they’re already part of an escape
132
133 if (regexTrailingSpace.test(result) && !regexTrailingEscape.test(result)) {
134 result = result.replace(regexTrailingSpace, '\\ ');
135 }
136
137 if (regexSpaceAtStart.test(result)) {
138 result = '\\ ' + result.slice(1);
139 }
140
141 return result;
142}
143
144function _default(nodes, opts) {
145 let family = [];
146 let last = null;
147 let i, max;
148 nodes.forEach((node, index, arr) => {
149 if (node.type === 'string' || node.type === 'function') {
150 family.push(node);
151 } else if (node.type === 'word') {
152 if (!last) {
153 last = {
154 type: 'word',
155 value: ''
156 };
157 family.push(last);
158 }
159
160 last.value += node.value;
161 } else if (node.type === 'space') {
162 if (last && index !== arr.length - 1) {
163 last.value += ' ';
164 }
165 } else {
166 last = null;
167 }
168 });
169 family = family.map(node => {
170 if (node.type === 'string') {
171 const isKeyword = regexKeyword.test(node.value);
172
173 if (!opts.removeQuotes || isKeyword || /[0-9]/.test(node.value.slice(0, 1))) {
174 return (0, _postcssValueParser.stringify)(node);
175 }
176
177 let escaped = escapeIdentifierSequence(node.value);
178
179 if (escaped.length < node.value.length + 2) {
180 return escaped;
181 }
182 }
183
184 return (0, _postcssValueParser.stringify)(node);
185 });
186
187 if (opts.removeAfterKeyword) {
188 for (i = 0, max = family.length; i < max; i += 1) {
189 if (~genericFontFamilykeywords.indexOf(family[i].toLowerCase())) {
190 family = family.slice(0, i + 1);
191 break;
192 }
193 }
194 }
195
196 if (opts.removeDuplicates) {
197 family = uniqs(family);
198 }
199
200 return [{
201 type: 'word',
202 value: family.join()
203 }];
204}
205
206module.exports = exports.default;
Note: See TracBrowser for help on using the repository browser.