1 | var path = require('path');
|
2 | var url = require('url');
|
3 |
|
4 | var DOUBLE_QUOTE = '"';
|
5 | var SINGLE_QUOTE = '\'';
|
6 | var URL_PREFIX = 'url(';
|
7 | var URL_SUFFIX = ')';
|
8 |
|
9 | var QUOTE_PREFIX_PATTERN = /^["']/;
|
10 | var QUOTE_SUFFIX_PATTERN = /["']$/;
|
11 | var ROUND_BRACKETS_PATTERN = /[\(\)]/;
|
12 | var URL_PREFIX_PATTERN = /^url\(/i;
|
13 | var URL_SUFFIX_PATTERN = /\)$/;
|
14 | var WHITESPACE_PATTERN = /\s/;
|
15 |
|
16 | var isWindows = process.platform == 'win32';
|
17 |
|
18 | function rebase(uri, rebaseConfig) {
|
19 | if (!rebaseConfig) {
|
20 | return uri;
|
21 | }
|
22 |
|
23 | if (isAbsolute(uri) && !isRemote(rebaseConfig.toBase)) {
|
24 | return uri;
|
25 | }
|
26 |
|
27 | if (isRemote(uri) || isSVGMarker(uri) || isInternal(uri)) {
|
28 | return uri;
|
29 | }
|
30 |
|
31 | if (isData(uri)) {
|
32 | return '\'' + uri + '\'';
|
33 | }
|
34 |
|
35 | if (isRemote(rebaseConfig.toBase)) {
|
36 | return url.resolve(rebaseConfig.toBase, uri);
|
37 | }
|
38 |
|
39 | return rebaseConfig.absolute ?
|
40 | normalize(absolute(uri, rebaseConfig)) :
|
41 | normalize(relative(uri, rebaseConfig));
|
42 | }
|
43 |
|
44 | function isAbsolute(uri) {
|
45 | return path.isAbsolute(uri);
|
46 | }
|
47 |
|
48 | function isSVGMarker(uri) {
|
49 | return uri[0] == '#';
|
50 | }
|
51 |
|
52 | function isInternal(uri) {
|
53 | return /^\w+:\w+/.test(uri);
|
54 | }
|
55 |
|
56 | function isRemote(uri) {
|
57 | return /^[^:]+?:\/\//.test(uri) || uri.indexOf('//') === 0;
|
58 | }
|
59 |
|
60 | function isData(uri) {
|
61 | return uri.indexOf('data:') === 0;
|
62 | }
|
63 |
|
64 | function absolute(uri, rebaseConfig) {
|
65 | return path
|
66 | .resolve(path.join(rebaseConfig.fromBase || '', uri))
|
67 | .replace(rebaseConfig.toBase, '');
|
68 | }
|
69 |
|
70 | function relative(uri, rebaseConfig) {
|
71 | return path.relative(rebaseConfig.toBase, path.join(rebaseConfig.fromBase || '', uri));
|
72 | }
|
73 |
|
74 | function normalize(uri) {
|
75 | return isWindows ? uri.replace(/\\/g, '/') : uri;
|
76 | }
|
77 |
|
78 | function quoteFor(unquotedUrl) {
|
79 | if (unquotedUrl.indexOf(SINGLE_QUOTE) > -1) {
|
80 | return DOUBLE_QUOTE;
|
81 | } else if (unquotedUrl.indexOf(DOUBLE_QUOTE) > -1) {
|
82 | return SINGLE_QUOTE;
|
83 | } else if (hasWhitespace(unquotedUrl) || hasRoundBrackets(unquotedUrl)) {
|
84 | return SINGLE_QUOTE;
|
85 | } else {
|
86 | return '';
|
87 | }
|
88 | }
|
89 |
|
90 | function hasWhitespace(url) {
|
91 | return WHITESPACE_PATTERN.test(url);
|
92 | }
|
93 |
|
94 | function hasRoundBrackets(url) {
|
95 | return ROUND_BRACKETS_PATTERN.test(url);
|
96 | }
|
97 |
|
98 | function rewriteUrl(originalUrl, rebaseConfig, pathOnly) {
|
99 | var strippedUrl = originalUrl
|
100 | .replace(URL_PREFIX_PATTERN, '')
|
101 | .replace(URL_SUFFIX_PATTERN, '')
|
102 | .trim();
|
103 |
|
104 | var unquotedUrl = strippedUrl
|
105 | .replace(QUOTE_PREFIX_PATTERN, '')
|
106 | .replace(QUOTE_SUFFIX_PATTERN, '')
|
107 | .trim();
|
108 |
|
109 | var quote = strippedUrl[0] == SINGLE_QUOTE || strippedUrl[0] == DOUBLE_QUOTE ?
|
110 | strippedUrl[0] :
|
111 | quoteFor(unquotedUrl);
|
112 |
|
113 | return pathOnly ?
|
114 | rebase(unquotedUrl, rebaseConfig) :
|
115 | URL_PREFIX + quote + rebase(unquotedUrl, rebaseConfig) + quote + URL_SUFFIX;
|
116 | }
|
117 |
|
118 | module.exports = rewriteUrl;
|