You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
4.5 KiB

//>>excludeStart('excludeRequireCss', pragmas.excludeRequireCss)
/*
* 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:)/;
// given a URI, remove '..' if possible
function normalizeURI(uri) {
return removeDoubleSlashes(uri).split('/').reduce(function(prev, curr, idx) {
if (prev.length === 0 || curr !== '..') {
prev.push(curr);
} else {
prev.pop();
}
return prev;
}, []).join('/');
}
function convertURIBase(uri, fromBase, toBase) {
fromBase = normalizeURI(fromBase);
toBase = normalizeURI(toBase);
if (uri.match(absUrlRegEx) || uri.match(protocolRegEx))
return uri;
uri = normalizeURI(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) {
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;
});
//>>excludeEnd('excludeRequireCss')