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
|
package com.metaweb.lessen.tokenizers;
import com.metaweb.lessen.tokens.Token;
import com.metaweb.lessen.tokens.UriToken;
import com.metaweb.lessen.tokens.Token.Type;
public class UrlRewritingTokenizer implements Tokenizer {
final protected Tokenizer _tokenizer;
final protected String _relativePath;
final protected String[] _segments;
protected Token _token;
/**
* relativePath specifies how to get from the output CSS's URL to
* the input CSS's URL. For example, say the input CSS is served at
*
* some-path/modules/foo/styles/detail-page.css
*
* which is to be bundled with other CSS files to produce a CSS
* bundle to be served at
*
* some-path/bundles/foo.css
*
* then the relative path is
*
* ../modules/foo/styles/
*
* because from foo.css, we need to go up one directory level to
* some-path, and then down modules/foo/styles/ to get to
* detail-page.css. If detail-page.css contains
*
* url(../images/watermark.png)
*
* then it'll be resolved to
*
* url(../modules/foo/images/watermark.png)
*
* in foo.css so that foo.css effectively references the same image.
*
* @param tokenizer
* @param relativePath
*/
public UrlRewritingTokenizer(Tokenizer tokenizer, String relativePath) {
_tokenizer = tokenizer;
_relativePath = relativePath;
if (relativePath.endsWith("/")) {
relativePath = relativePath.substring(0, relativePath.length() - 1);
}
_segments = _relativePath.split("/");
_token = _tokenizer.getToken();
resolve();
}
@Override
public Token getToken() {
return _token;
}
@Override
public void next() {
_tokenizer.next();
_token = _tokenizer.getToken();
resolve();
}
protected void resolve() {
if (_token != null && _token.type == Type.Uri) {
UriToken t = (UriToken) _token;
if (t.prefix.equals("url")) {
String url = t.unquotedText;
if (url.indexOf("://") < 0 && !url.startsWith("/")) { // not absolute URLs
int lastSegment = _segments.length;
while (url.length() > 0) {
if (url.startsWith("./")) {
url = url.substring(2);
} else if (url.startsWith("../")) {
url = url.substring(3);
lastSegment--;
} else {
break;
}
}
StringBuffer sb = new StringBuffer();
if (lastSegment > 0) {
for (int i = 0; i < lastSegment; i++) {
sb.append(_segments[i]);
sb.append('/');
}
} else {
while (lastSegment < 0) {
sb.append("../");
lastSegment++;
}
}
String url2 = sb.toString() + url;
String text = t.prefix + "(\"" + url2 + "\")";
_token = new UriToken(
t.start,
t.end,
text,
t.prefix,
url2
);
}
}
}
}
}
|