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