1var path = require('path');
2var url = require('url');
3
4var DOUBLE_QUOTE = '"';
5var SINGLE_QUOTE = '\'';
6var URL_PREFIX = 'url(';
7var URL_SUFFIX = ')';
8
9var QUOTE_PREFIX_PATTERN = /^["']/;
10var QUOTE_SUFFIX_PATTERN = /["']$/;
11var ROUND_BRACKETS_PATTERN = /[\(\)]/;
12var URL_PREFIX_PATTERN = /^url\(/i;
13var URL_SUFFIX_PATTERN = /\)$/;
14var WHITESPACE_PATTERN = /\s/;
15
16var isWindows = process.platform == 'win32';
17
18function 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
44function isAbsolute(uri) {
45  return path.isAbsolute(uri);
46}
47
48function isSVGMarker(uri) {
49  return uri[0] == '#';
50}
51
52function isInternal(uri) {
53  return /^\w+:\w+/.test(uri);
54}
55
56function isRemote(uri) {
57  return /^[^:]+?:\/\//.test(uri) || uri.indexOf('//') === 0;
58}
59
60function isData(uri) {
61  return uri.indexOf('data:') === 0;
62}
63
64function absolute(uri, rebaseConfig) {
65  return path
66    .resolve(path.join(rebaseConfig.fromBase || '', uri))
67    .replace(rebaseConfig.toBase, '');
68}
69
70function relative(uri, rebaseConfig) {
71  return path.relative(rebaseConfig.toBase, path.join(rebaseConfig.fromBase || '', uri));
72}
73
74function normalize(uri) {
75  return isWindows ? uri.replace(/\\/g, '/') : uri;
76}
77
78function 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
90function hasWhitespace(url) {
91  return WHITESPACE_PATTERN.test(url);
92}
93
94function hasRoundBrackets(url) {
95  return ROUND_BRACKETS_PATTERN.test(url);
96}
97
98function 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
118module.exports = rewriteUrl;
119