diff options
Diffstat (limited to 'point/libs/normalize')
-rw-r--r-- | point/libs/normalize/normalize.js | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/point/libs/normalize/normalize.js b/point/libs/normalize/normalize.js new file mode 100644 index 0000000..e1733d6 --- /dev/null +++ b/point/libs/normalize/normalize.js | |||
@@ -0,0 +1,140 @@ | |||
1 | /* | ||
2 | * css.normalize.js | ||
3 | * | ||
4 | * CSS Normalization | ||
5 | * | ||
6 | * CSS paths are normalized based on an optional basePath and the RequireJS config | ||
7 | * | ||
8 | * Usage: | ||
9 | * normalize(css, fromBasePath, toBasePath); | ||
10 | * | ||
11 | * css: the stylesheet content to normalize | ||
12 | * fromBasePath: the absolute base path of the css relative to any root (but without ../ backtracking) | ||
13 | * toBasePath: the absolute new base path of the css relative to the same root | ||
14 | * | ||
15 | * Absolute dependencies are left untouched. | ||
16 | * | ||
17 | * Urls in the CSS are picked up by regular expressions. | ||
18 | * These will catch all statements of the form: | ||
19 | * | ||
20 | * url(*) | ||
21 | * url('*') | ||
22 | * url("*") | ||
23 | * | ||
24 | * @import '*' | ||
25 | * @import "*" | ||
26 | * | ||
27 | * (and so also @import url(*) variations) | ||
28 | * | ||
29 | * For urls needing normalization | ||
30 | * | ||
31 | */ | ||
32 | |||
33 | define(function () { | ||
34 | |||
35 | // regular expression for removing double slashes | ||
36 | // eg http://www.example.com//my///url/here -> http://www.example.com/my/url/here | ||
37 | var slashes = /([^:])\/+/g | ||
38 | var removeDoubleSlashes = function (uri) { | ||
39 | return uri.replace(slashes, '$1/'); | ||
40 | } | ||
41 | |||
42 | // given a relative URI, and two absolute base URIs, convert it from one base to another | ||
43 | var protocolRegEx = /[^\:\/]*:\/\/([^\/])*/; | ||
44 | var absUrlRegEx = /^(\/|data:)/; | ||
45 | |||
46 | function convertURIBase(uri, fromBase, toBase) { | ||
47 | if (uri.match(absUrlRegEx) || uri.match(protocolRegEx)) | ||
48 | return uri; | ||
49 | uri = removeDoubleSlashes(uri); | ||
50 | // if toBase specifies a protocol path, ensure this is the same protocol as fromBase, if not | ||
51 | // use absolute path at fromBase | ||
52 | var toBaseProtocol = toBase.match(protocolRegEx); | ||
53 | var fromBaseProtocol = fromBase.match(protocolRegEx); | ||
54 | if (fromBaseProtocol && (!toBaseProtocol || toBaseProtocol[1] != fromBaseProtocol[1] || toBaseProtocol[2] != fromBaseProtocol[2])) | ||
55 | return absoluteURI(uri, fromBase); | ||
56 | |||
57 | else { | ||
58 | return relativeURI(absoluteURI(uri, fromBase), toBase); | ||
59 | } | ||
60 | }; | ||
61 | |||
62 | // given a relative URI, calculate the absolute URI | ||
63 | function absoluteURI(uri, base) { | ||
64 | if (uri.substr(0, 2) == './') | ||
65 | uri = uri.substr(2); | ||
66 | |||
67 | // absolute urls are left in tact | ||
68 | if (uri.match(absUrlRegEx) || uri.match(protocolRegEx)) | ||
69 | return uri; | ||
70 | |||
71 | var baseParts = base.split('/'); | ||
72 | var uriParts = uri.split('/'); | ||
73 | |||
74 | baseParts.pop(); | ||
75 | |||
76 | while (curPart = uriParts.shift()) | ||
77 | if (curPart == '..') | ||
78 | baseParts.pop(); | ||
79 | else | ||
80 | baseParts.push(curPart); | ||
81 | |||
82 | return baseParts.join('/'); | ||
83 | }; | ||
84 | |||
85 | |||
86 | // given an absolute URI, calculate the relative URI | ||
87 | function relativeURI(uri, base) { | ||
88 | |||
89 | // reduce base and uri strings to just their difference string | ||
90 | var baseParts = base.split('/'); | ||
91 | baseParts.pop(); | ||
92 | base = baseParts.join('/') + '/'; | ||
93 | i = 0; | ||
94 | while (base.substr(i, 1) == uri.substr(i, 1)) | ||
95 | i++; | ||
96 | while (base.substr(i, 1) != '/') | ||
97 | i--; | ||
98 | base = base.substr(i + 1); | ||
99 | uri = uri.substr(i + 1); | ||
100 | |||
101 | // each base folder difference is thus a backtrack | ||
102 | baseParts = base.split('/'); | ||
103 | var uriParts = uri.split('/'); | ||
104 | out = ''; | ||
105 | while (baseParts.shift()) | ||
106 | out += '../'; | ||
107 | |||
108 | // finally add uri parts | ||
109 | while (curPart = uriParts.shift()) | ||
110 | out += curPart + '/'; | ||
111 | |||
112 | return out.substr(0, out.length - 1); | ||
113 | }; | ||
114 | |||
115 | var normalizeCSS = function (source, fromBase, toBase) { | ||
116 | |||
117 | fromBase = removeDoubleSlashes(fromBase); | ||
118 | toBase = removeDoubleSlashes(toBase); | ||
119 | |||
120 | var urlRegEx = /@import\s*("([^"]*)"|'([^']*)')|url\s*\(\s*(\s*"([^"]*)"|'([^']*)'|[^\)]*\s*)\s*\)/ig; | ||
121 | var result, url, source; | ||
122 | |||
123 | while (result = urlRegEx.exec(source)) { | ||
124 | url = result[3] || result[2] || result[5] || result[6] || result[4]; | ||
125 | var newUrl; | ||
126 | newUrl = convertURIBase(url, fromBase, toBase); | ||
127 | var quoteLen = result[5] || result[6] ? 1 : 0; | ||
128 | source = source.substr(0, urlRegEx.lastIndex - url.length - quoteLen - 1) + newUrl + source.substr(urlRegEx.lastIndex - quoteLen - 1); | ||
129 | urlRegEx.lastIndex = urlRegEx.lastIndex + (newUrl.length - url.length); | ||
130 | } | ||
131 | |||
132 | return source; | ||
133 | }; | ||
134 | |||
135 | normalizeCSS.convertURIBase = convertURIBase; | ||
136 | normalizeCSS.absoluteURI = absoluteURI; | ||
137 | normalizeCSS.relativeURI = relativeURI; | ||
138 | |||
139 | return normalizeCSS; | ||
140 | }); | ||