aboutsummaryrefslogtreecommitdiff
path: root/point/libs/normalize/normalize.js
blob: e1733d6237ee67eabe2ab7d7f5ecd7cd6e343503 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
 * css.normalize.js
 *
 * CSS Normalization
 *
 * CSS paths are normalized based on an optional basePath and the RequireJS config
 *
 * Usage:
 *   normalize(css, fromBasePath, toBasePath);
 *
 * css: the stylesheet content to normalize
 * fromBasePath: the absolute base path of the css relative to any root (but without ../ backtracking)
 * toBasePath: the absolute new base path of the css relative to the same root
 * 
 * Absolute dependencies are left untouched.
 *
 * Urls in the CSS are picked up by regular expressions.
 * These will catch all statements of the form:
 *
 * url(*)
 * url('*')
 * url("*")
 * 
 * @import '*'
 * @import "*"
 *
 * (and so also @import url(*) variations)
 *
 * For urls needing normalization
 *
 */

define(function () {

	// regular expression for removing double slashes
	// eg http://www.example.com//my///url/here -> http://www.example.com/my/url/here
	var slashes = /([^:])\/+/g
	var removeDoubleSlashes = function (uri) {
		return uri.replace(slashes, '$1/');
	}

	// given a relative URI, and two absolute base URIs, convert it from one base to another
	var protocolRegEx = /[^\:\/]*:\/\/([^\/])*/;
	var absUrlRegEx = /^(\/|data:)/;

	function convertURIBase(uri, fromBase, toBase) {
		if (uri.match(absUrlRegEx) || uri.match(protocolRegEx))
			return uri;
		uri = removeDoubleSlashes(uri);
		// if toBase specifies a protocol path, ensure this is the same protocol as fromBase, if not
		// use absolute path at fromBase
		var toBaseProtocol = toBase.match(protocolRegEx);
		var fromBaseProtocol = fromBase.match(protocolRegEx);
		if (fromBaseProtocol && (!toBaseProtocol || toBaseProtocol[1] != fromBaseProtocol[1] || toBaseProtocol[2] != fromBaseProtocol[2]))
			return absoluteURI(uri, fromBase);

		else {
			return relativeURI(absoluteURI(uri, fromBase), toBase);
		}
	};

	// given a relative URI, calculate the absolute URI
	function absoluteURI(uri, base) {
		if (uri.substr(0, 2) == './')
			uri = uri.substr(2);

		// absolute urls are left in tact
		if (uri.match(absUrlRegEx) || uri.match(protocolRegEx))
			return uri;

		var baseParts = base.split('/');
		var uriParts = uri.split('/');

		baseParts.pop();

		while (curPart = uriParts.shift())
			if (curPart == '..')
				baseParts.pop();
			else
				baseParts.push(curPart);

		return baseParts.join('/');
	};


	// given an absolute URI, calculate the relative URI
	function relativeURI(uri, base) {

		// reduce base and uri strings to just their difference string
		var baseParts = base.split('/');
		baseParts.pop();
		base = baseParts.join('/') + '/';
		i = 0;
		while (base.substr(i, 1) == uri.substr(i, 1))
			i++;
		while (base.substr(i, 1) != '/')
			i--;
		base = base.substr(i + 1);
		uri = uri.substr(i + 1);

		// each base folder difference is thus a backtrack
		baseParts = base.split('/');
		var uriParts = uri.split('/');
		out = '';
		while (baseParts.shift())
			out += '../';

		// finally add uri parts
		while (curPart = uriParts.shift())
			out += curPart + '/';

		return out.substr(0, out.length - 1);
	};

	var normalizeCSS = function (source, fromBase, toBase) {

		fromBase = removeDoubleSlashes(fromBase);
		toBase = removeDoubleSlashes(toBase);

		var urlRegEx = /@import\s*("([^"]*)"|'([^']*)')|url\s*\(\s*(\s*"([^"]*)"|'([^']*)'|[^\)]*\s*)\s*\)/ig;
		var result, url, source;

		while (result = urlRegEx.exec(source)) {
			url = result[3] || result[2] || result[5] || result[6] || result[4];
			var newUrl;
			newUrl = convertURIBase(url, fromBase, toBase);
			var quoteLen = result[5] || result[6] ? 1 : 0;
			source = source.substr(0, urlRegEx.lastIndex - url.length - quoteLen - 1) + newUrl + source.substr(urlRegEx.lastIndex - quoteLen - 1);
			urlRegEx.lastIndex = urlRegEx.lastIndex + (newUrl.length - url.length);
		}

		return source;
	};

	normalizeCSS.convertURIBase = convertURIBase;
	normalizeCSS.absoluteURI = absoluteURI;
	normalizeCSS.relativeURI = relativeURI;

	return normalizeCSS;
});