UNPKG

3.65 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.default = void 0;
7
8var _path = _interopRequireDefault(require("path"));
9
10var _postcssValueParser = _interopRequireDefault(require("postcss-value-parser"));
11
12var _normalizeUrl = _interopRequireDefault(require("normalize-url"));
13
14function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
16const multiline = /\\[\r\n]/; // eslint-disable-next-line no-useless-escape
17
18const escapeChars = /([\s\(\)"'])/g; // Scheme: https://tools.ietf.org/html/rfc3986#section-3.1
19// Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3
20
21const ABSOLUTE_URL_REGEX = /^[a-zA-Z][a-zA-Z\d+\-.]*?:/; // Windows paths like `c:\`
22
23const WINDOWS_PATH_REGEX = /^[a-zA-Z]:\\/;
24/**
25 * Originally in sindresorhus/is-absolute-url
26 *
27 * @param {string} url
28 */
29
30function isAbsolute(url) {
31 if (WINDOWS_PATH_REGEX.test(url)) {
32 return false;
33 }
34
35 return ABSOLUTE_URL_REGEX.test(url);
36}
37
38function convert(url, options) {
39 if (isAbsolute(url) || url.startsWith('//')) {
40 let normalizedURL = null;
41
42 try {
43 normalizedURL = (0, _normalizeUrl.default)(url, options);
44 } catch (e) {
45 normalizedURL = url;
46 }
47
48 return normalizedURL;
49 } // `path.normalize` always returns backslashes on Windows, need replace in `/`
50
51
52 return _path.default.normalize(url).replace(new RegExp('\\' + _path.default.sep, 'g'), '/');
53}
54
55function transformNamespace(rule) {
56 rule.params = (0, _postcssValueParser.default)(rule.params).walk(node => {
57 if (node.type === 'function' && node.value.toLowerCase() === 'url' && node.nodes.length) {
58 node.type = 'string';
59 node.quote = node.nodes[0].quote || '"';
60 node.value = node.nodes[0].value;
61 }
62
63 if (node.type === 'string') {
64 node.value = node.value.trim();
65 }
66
67 return false;
68 }).toString();
69}
70
71function transformDecl(decl, opts) {
72 decl.value = (0, _postcssValueParser.default)(decl.value).walk(node => {
73 if (node.type !== 'function' || node.value.toLowerCase() !== 'url') {
74 return false;
75 }
76
77 node.before = node.after = '';
78
79 if (!node.nodes.length) {
80 return false;
81 }
82
83 let url = node.nodes[0];
84 let escaped;
85 url.value = url.value.trim().replace(multiline, ''); // Skip empty URLs
86 // Empty URL function equals request to current stylesheet where it is declared
87
88 if (url.value.length === 0) {
89 url.quote = '';
90 return false;
91 }
92
93 if (/^data:(.*)?,/i.test(url.value)) {
94 return false;
95 }
96
97 if (!/^.+-extension:\//i.test(url.value)) {
98 url.value = convert(url.value, opts);
99 }
100
101 if (escapeChars.test(url.value) && url.type === 'string') {
102 escaped = url.value.replace(escapeChars, '\\$1');
103
104 if (escaped.length < url.value.length + 2) {
105 url.value = escaped;
106 url.type = 'word';
107 }
108 } else {
109 url.type = 'word';
110 }
111
112 return false;
113 }).toString();
114}
115
116function pluginCreator(opts) {
117 opts = Object.assign({}, {
118 normalizeProtocol: false,
119 sortQueryParameters: false,
120 stripHash: false,
121 stripWWW: false,
122 stripTextFragment: false
123 }, opts);
124 return {
125 postcssPlugin: 'postcss-normalize-url',
126
127 OnceExit(css) {
128 css.walk(node => {
129 if (node.type === 'decl') {
130 return transformDecl(node, opts);
131 } else if (node.type === 'atrule' && node.name.toLowerCase() === 'namespace') {
132 return transformNamespace(node);
133 }
134 });
135 }
136
137 };
138}
139
140pluginCreator.postcss = true;
141var _default = pluginCreator;
142exports.default = _default;
143module.exports = exports.default;
\No newline at end of file