Now it's way easier to understand.
+[3.3.0 / 2015-xx-xx](https://github.com/jakubpawlowicz/clean-css/compare/v3.2.0...HEAD)
+==================
+
+* Fixed issue [#436](https://github.com/jakubpawlowicz/clean-css/issues/436) - refactors URI rewriting.
+
[3.2.0 / 2015-04-19](https://github.com/jakubpawlowicz/clean-css/compare/v3.1.9...v3.2.0)
==================
--- /dev/null
+var path = require('path');
+var url = require('url');
+
+var UrlScanner = require('../utils/url-scanner');
+
+var isWindows = process.platform == 'win32';
+
+function isAbsolute(uri) {
+ return uri[0] == '/';
+}
+
+function isSVGMarker(uri) {
+ return uri[0] == '#';
+}
+
+function isEscaped(uri) {
+ return uri.indexOf('__ESCAPED_URL_CLEAN_CSS__') === 0;
+}
+
+function isRemote(uri) {
+ return uri.indexOf('http://') === 0 || uri.indexOf('https://') === 0;
+}
+
+function isImport(uri) {
+ return uri.lastIndexOf('.css') === uri.length - 4;
+}
+
+function isData(uri) {
+ return uri.indexOf('data:') === 0;
+}
+
+function absolute(uri, options) {
+ return path
+ .resolve(path.join(options.fromBase, uri))
+ .replace(options.toBase, '');
+}
+
+function relative(uri, options) {
+ return path.relative(options.toBase, path.join(options.fromBase, uri));
+}
+
+function normalize(uri) {
+ return isWindows ? uri.replace(/\\/g, '/') : uri;
+}
+
+function rebase(uri, options) {
+ if (isAbsolute(uri) || isSVGMarker(uri) || isEscaped(uri))
+ return uri;
+
+ if (options.rebase === false && !isImport(uri))
+ return uri;
+
+ if (!options.imports && isImport(uri))
+ return uri;
+
+ if (isData(uri))
+ return '\'' + uri + '\'';
+
+ if (isRemote(uri) || isRemote(options.toBase))
+ return url.resolve(options.toBase, uri);
+
+ return options.absolute ?
+ normalize(absolute(uri, options)) :
+ normalize(relative(uri, options));
+}
+
+function rewriteUrls(data, options, context) {
+ return new UrlScanner(data, context).reduce(function (url, tempData) {
+ url = url.replace(/^url\(\s*['"]?|['"]?\s*\)$/g, '');
+ tempData.push('url(' + rebase(url, options) + ')');
+ });
+}
+
+module.exports = rewriteUrls;
var path = require('path');
-var UrlRewriter = require('./url-rewriter');
+var rewriteUrls = require('./rewrite-urls');
function UrlRebase(outerContext) {
this.outerContext = outerContext;
if (!rebaseOpts.fromBase || !rebaseOpts.toBase)
return data;
- return new UrlRewriter(rebaseOpts).process(data);
+ return rewriteUrls(data, rebaseOpts, this.outerContext);
};
module.exports = UrlRebase;
+++ /dev/null
-var path = require('path');
-var url = require('url');
-
-var UrlScanner = require('../utils/url-scanner');
-
-function UrlRewriter(options, context) {
- this.options = options;
- this.context = context;
-}
-
-UrlRewriter.prototype.process = function (data) {
- var self = this;
-
- return new UrlScanner(data, this.context).reduce(function (url, tempData) {
- url = url.replace(/^url\(\s*['"]?|['"]?\s*\)$/g, '');
- tempData.push('url(' + rebase(url, self.options) + ')');
- });
-};
-
-function rebase(resource, options) {
- // TODO: this is getting insane now - pending refactor in #436
- var importUrl = resource.substring(resource.length - 4) == '.css';
- var dataUri = resource.indexOf('data:') === 0;
- var specialUrl = resource[0] == '/' ||
- resource[0] == '#' ||
- (!options.imports && importUrl) ||
- dataUri ||
- /^https?:\/\//.exec(resource) !== null ||
- /__\w+__/.exec(resource) !== null;
- var rebased;
-
- if (false === options.urls) {
- if (options.imports && importUrl)
- specialUrl = false;
- else
- specialUrl = true;
- }
-
- if (specialUrl)
- return dataUri ? '\'' + resource + '\'' : resource;
-
- if (/https?:\/\//.test(options.toBase))
- return url.resolve(options.toBase, resource);
-
- if (options.absolute) {
- rebased = path
- .resolve(path.join(options.fromBase, resource))
- .replace(options.toBase, '');
- } else {
- rebased = path.relative(options.toBase, path.join(options.fromBase, resource));
- }
-
- return process.platform == 'win32' ?
- rebased.replace(/\\/g, '/') :
- rebased;
-}
-
-module.exports = UrlRewriter;
var https = require('https');
var url = require('url');
-var UrlRewriter = require('../images/url-rewriter');
+var rewriteUrls = require('../images/rewrite-urls');
var Splitter = require('../utils/splitter.js');
var override = require('../utils/object.js').override;
res.on('end', function() {
var importedData = chunks.join('');
if (context.rebase)
- importedData = new UrlRewriter({ toBase: importedUrl }, context).process(importedData);
+ importedData = rewriteUrls(importedData, { toBase: importedUrl }, context);
context.sourceReader.trackSource(importedUrl, importedData);
importedData = context.sourceTracker.store(importedUrl, importedData);
importedData = rebaseMap(importedData, importedUrl);
var importRelativeTo = path.dirname(fullPath);
var importedData = fs.readFileSync(fullPath, 'utf8');
if (context.rebase) {
- var rewriter = new UrlRewriter({
+ var rewriteOptions = {
relative: true,
fromBase: importRelativeTo,
toBase: context.baseRelativeTo
- }, context);
- importedData = rewriter.process(importedData);
+ };
+ importedData = rewriteUrls(importedData, rewriteOptions, context);
}
var relativePath = path.relative(context.root, fullPath);
var path = require('path');
-var UrlRewriter = require('../images/url-rewriter');
+var rewriteUrls = require('../images/rewrite-urls');
var REMOTE_RESOURCE = /^(https?:)?\/\//;
var absoluteSource = isRemote ? source : path.resolve(source);
var absoluteSourcePath = path.dirname(absoluteSource);
- var rewriter = new UrlRewriter({
+ var rewriteOptions = {
absolute: self.outerContext.options.explicitRoot,
relative: !self.outerContext.options.explicitRoot,
imports: true,
- urls: self.outerContext.options.rebase,
+ rebase: self.outerContext.options.rebase,
fromBase: absoluteSourcePath,
toBase: isRemote ? absoluteSourcePath : toBase
- }, self.outerContext);
- styles = rewriter.process(styles);
+ };
+ styles = rewriteUrls(styles, rewriteOptions, self.outerContext);
self.trackSource(source, styles);