ruby-clean-css 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitmodules +3 -0
- data/EXAMPLE.md +25 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +30 -0
- data/LICENSE +19 -0
- data/README.md +106 -0
- data/lib/javascript/clean-css/.gitignore +4 -0
- data/lib/javascript/clean-css/.jshintignore +3 -0
- data/lib/javascript/clean-css/.jshintrc +14 -0
- data/lib/javascript/clean-css/.travis.yml +11 -0
- data/lib/javascript/clean-css/History.md +556 -0
- data/lib/javascript/clean-css/LICENSE +19 -0
- data/lib/javascript/clean-css/README.md +218 -0
- data/lib/javascript/clean-css/bin/cleancss +157 -0
- data/lib/javascript/clean-css/index.js +1 -0
- data/lib/javascript/clean-css/lib/clean.js +426 -0
- data/lib/javascript/clean-css/lib/colors/hsl-to-hex.js +64 -0
- data/lib/javascript/clean-css/lib/colors/long-to-short-hex.js +12 -0
- data/lib/javascript/clean-css/lib/colors/rgb-to-hex.js +14 -0
- data/lib/javascript/clean-css/lib/colors/shortener.js +174 -0
- data/lib/javascript/clean-css/lib/images/url-rebase.js +32 -0
- data/lib/javascript/clean-css/lib/images/url-rewriter.js +60 -0
- data/lib/javascript/clean-css/lib/imports/inliner.js +319 -0
- data/lib/javascript/clean-css/lib/properties/optimizer.js +276 -0
- data/lib/javascript/clean-css/lib/properties/override-compactor.js +116 -0
- data/lib/javascript/clean-css/lib/properties/processable.js +859 -0
- data/lib/javascript/clean-css/lib/properties/scanner.js +20 -0
- data/lib/javascript/clean-css/lib/properties/shorthand-compactor.js +244 -0
- data/lib/javascript/clean-css/lib/properties/token.js +184 -0
- data/lib/javascript/clean-css/lib/properties/validator.js +140 -0
- data/lib/javascript/clean-css/lib/selectors/empty-removal.js +30 -0
- data/lib/javascript/clean-css/lib/selectors/optimizer.js +341 -0
- data/lib/javascript/clean-css/lib/selectors/tokenizer.js +168 -0
- data/lib/javascript/clean-css/lib/text/comments.js +83 -0
- data/lib/javascript/clean-css/lib/text/escape-store.js +32 -0
- data/lib/javascript/clean-css/lib/text/expressions.js +73 -0
- data/lib/javascript/clean-css/lib/text/free.js +26 -0
- data/lib/javascript/clean-css/lib/text/name-quotes.js +37 -0
- data/lib/javascript/clean-css/lib/text/quote-scanner.js +91 -0
- data/lib/javascript/clean-css/lib/text/splitter.js +35 -0
- data/lib/javascript/clean-css/lib/text/urls.js +41 -0
- data/lib/javascript/clean-css/package.json +50 -0
- data/lib/javascript/clean-css/test/batch-test.js +56 -0
- data/lib/javascript/clean-css/test/bench.js +11 -0
- data/lib/javascript/clean-css/test/binary-test.js +323 -0
- data/lib/javascript/clean-css/test/data-bench/_partial.css +1 -0
- data/lib/javascript/clean-css/test/data-bench/complex.css +4 -0
- data/lib/javascript/clean-css/test/data/129-assets/assets/ui.css +2 -0
- data/lib/javascript/clean-css/test/data/129-assets/components/bootstrap/css/bootstrap.css +3 -0
- data/lib/javascript/clean-css/test/data/129-assets/components/bootstrap/images/glyphs.gif +0 -0
- data/lib/javascript/clean-css/test/data/129-assets/components/jquery-ui/css/style.css +6 -0
- data/lib/javascript/clean-css/test/data/129-assets/components/jquery-ui/images/next.gif +0 -0
- data/lib/javascript/clean-css/test/data/129-assets/components/jquery-ui/images/prev.gif +0 -0
- data/lib/javascript/clean-css/test/data/960-min.css +125 -0
- data/lib/javascript/clean-css/test/data/960.css +602 -0
- data/lib/javascript/clean-css/test/data/big-min.css +2984 -0
- data/lib/javascript/clean-css/test/data/big.css +13794 -0
- data/lib/javascript/clean-css/test/data/blueprint-min.css +245 -0
- data/lib/javascript/clean-css/test/data/blueprint.css +556 -0
- data/lib/javascript/clean-css/test/data/charset-mixed-with-fonts-min.css +3 -0
- data/lib/javascript/clean-css/test/data/charset-mixed-with-fonts.css +14 -0
- data/lib/javascript/clean-css/test/data/font-awesome-ie7-min.css +392 -0
- data/lib/javascript/clean-css/test/data/font-awesome-ie7.css +1203 -0
- data/lib/javascript/clean-css/test/data/font-awesome-min.css +319 -0
- data/lib/javascript/clean-css/test/data/font-awesome.css +540 -0
- data/lib/javascript/clean-css/test/data/imports-min.css +5 -0
- data/lib/javascript/clean-css/test/data/imports.css +4 -0
- data/lib/javascript/clean-css/test/data/issue-117-snippet-min.css +3 -0
- data/lib/javascript/clean-css/test/data/issue-117-snippet.css +19 -0
- data/lib/javascript/clean-css/test/data/issue-159-snippet-min.css +7 -0
- data/lib/javascript/clean-css/test/data/issue-159-snippet.css +7 -0
- data/lib/javascript/clean-css/test/data/issue-192-min.css +1 -0
- data/lib/javascript/clean-css/test/data/issue-192.css +8 -0
- data/lib/javascript/clean-css/test/data/issue-198-min.css +3 -0
- data/lib/javascript/clean-css/test/data/issue-198.css +4 -0
- data/lib/javascript/clean-css/test/data/issue-232-min.css +2 -0
- data/lib/javascript/clean-css/test/data/issue-232.css +17 -0
- data/lib/javascript/clean-css/test/data/issue-241-min.css +2 -0
- data/lib/javascript/clean-css/test/data/issue-241.css +2 -0
- data/lib/javascript/clean-css/test/data/issue-304-min.css +1 -0
- data/lib/javascript/clean-css/test/data/issue-304.css +4 -0
- data/lib/javascript/clean-css/test/data/issue-305-min.css +1 -0
- data/lib/javascript/clean-css/test/data/issue-305.css +3 -0
- data/lib/javascript/clean-css/test/data/issue-308-min.css +1 -0
- data/lib/javascript/clean-css/test/data/issue-308.css +5 -0
- data/lib/javascript/clean-css/test/data/issue-312-min.css +1 -0
- data/lib/javascript/clean-css/test/data/issue-312.css +7 -0
- data/lib/javascript/clean-css/test/data/issue-337-min.css +1 -0
- data/lib/javascript/clean-css/test/data/issue-337.css +4 -0
- data/lib/javascript/clean-css/test/data/line-breaks-in-attributes-min.css +2 -0
- data/lib/javascript/clean-css/test/data/line-breaks-in-attributes.css +8 -0
- data/lib/javascript/clean-css/test/data/partials-absolute/base.css +3 -0
- data/lib/javascript/clean-css/test/data/partials-absolute/base2.css +1 -0
- data/lib/javascript/clean-css/test/data/partials-absolute/extra/sub.css +3 -0
- data/lib/javascript/clean-css/test/data/partials-relative/base.css +3 -0
- data/lib/javascript/clean-css/test/data/partials-relative/extra/included.css +1 -0
- data/lib/javascript/clean-css/test/data/partials/comment.css +2 -0
- data/lib/javascript/clean-css/test/data/partials/extra/down.gif +0 -0
- data/lib/javascript/clean-css/test/data/partials/extra/four.css +3 -0
- data/lib/javascript/clean-css/test/data/partials/extra/three.css +1 -0
- data/lib/javascript/clean-css/test/data/partials/five.css +1 -0
- data/lib/javascript/clean-css/test/data/partials/four.css +1 -0
- data/lib/javascript/clean-css/test/data/partials/one.css +1 -0
- data/lib/javascript/clean-css/test/data/partials/three.css +1 -0
- data/lib/javascript/clean-css/test/data/partials/two.css +5 -0
- data/lib/javascript/clean-css/test/data/reset-min.css +12 -0
- data/lib/javascript/clean-css/test/data/reset.css +64 -0
- data/lib/javascript/clean-css/test/data/sample1-min.css +4 -0
- data/lib/javascript/clean-css/test/data/sample1.css +12 -0
- data/lib/javascript/clean-css/test/data/unsupported/selectors-ie7.css +20 -0
- data/lib/javascript/clean-css/test/data/unsupported/selectors-ie8.css +17 -0
- data/lib/javascript/clean-css/test/module-test.js +185 -0
- data/lib/javascript/clean-css/test/protocol-imports-test.js +409 -0
- data/lib/javascript/clean-css/test/text/splitter-test.js +20 -0
- data/lib/javascript/clean-css/test/unit-test.js +2071 -0
- data/lib/ruby-clean-css.rb +6 -0
- data/lib/ruby-clean-css/compressor.rb +142 -0
- data/lib/ruby-clean-css/exports.rb +258 -0
- data/lib/ruby-clean-css/railtie.rb +27 -0
- data/lib/ruby-clean-css/sprockets.rb +19 -0
- data/lib/ruby-clean-css/version.rb +5 -0
- data/ruby-clean-css.gemspec +30 -0
- data/test/test_compressor.rb +84 -0
- metadata +203 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
var EscapeStore = require('./escape-store');
|
|
2
|
+
var QuoteScanner = require('./quote-scanner');
|
|
3
|
+
|
|
4
|
+
module.exports = function Comments(keepSpecialComments, keepBreaks, lineBreak) {
|
|
5
|
+
var comments = new EscapeStore('COMMENT');
|
|
6
|
+
|
|
7
|
+
return {
|
|
8
|
+
// Strip special comments (/*! ... */) by replacing them by a special marker
|
|
9
|
+
// for further restoring. Plain comments are removed. It's done by scanning data using
|
|
10
|
+
// String#indexOf scanning instead of regexps to speed up the process.
|
|
11
|
+
escape: function(data) {
|
|
12
|
+
var tempData = [];
|
|
13
|
+
var nextStart = 0;
|
|
14
|
+
var nextEnd = 0;
|
|
15
|
+
var cursor = 0;
|
|
16
|
+
var isQuotedAt = (function () {
|
|
17
|
+
var quoteMap = [];
|
|
18
|
+
new QuoteScanner(data).each(function (quotedString, _, startsAt) {
|
|
19
|
+
quoteMap.push([startsAt, startsAt + quotedString.length]);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
return function (position) {
|
|
23
|
+
for (var i = 0, l = quoteMap.length; i < l; i++) {
|
|
24
|
+
if (quoteMap[i][0] < position && quoteMap[i][1] > position)
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return false;
|
|
29
|
+
};
|
|
30
|
+
})();
|
|
31
|
+
|
|
32
|
+
for (; nextEnd < data.length;) {
|
|
33
|
+
nextStart = data.indexOf('/*', cursor);
|
|
34
|
+
if (nextStart == -1)
|
|
35
|
+
break;
|
|
36
|
+
if (isQuotedAt(nextStart)) {
|
|
37
|
+
tempData.push(data.substring(cursor, nextStart + 2));
|
|
38
|
+
cursor = nextStart + 2;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
nextEnd = data.indexOf('*/', nextStart + 2);
|
|
43
|
+
if (nextEnd == -1)
|
|
44
|
+
break;
|
|
45
|
+
|
|
46
|
+
tempData.push(data.substring(cursor, nextStart));
|
|
47
|
+
if (data[nextStart + 2] == '!') {
|
|
48
|
+
// in case of special comments, replace them with a placeholder
|
|
49
|
+
var comment = data.substring(nextStart, nextEnd + 2);
|
|
50
|
+
var placeholder = comments.store(comment);
|
|
51
|
+
tempData.push(placeholder);
|
|
52
|
+
}
|
|
53
|
+
cursor = nextEnd + 2;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return tempData.length > 0 ?
|
|
57
|
+
tempData.join('') + data.substring(cursor, data.length) :
|
|
58
|
+
data;
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
restore: function(data) {
|
|
62
|
+
var restored = 0;
|
|
63
|
+
var breakSuffix = keepBreaks ? lineBreak : '';
|
|
64
|
+
|
|
65
|
+
return data.replace(new RegExp(comments.placeholderPattern + '(' + lineBreak + '| )?', 'g'), function(match, placeholder) {
|
|
66
|
+
restored++;
|
|
67
|
+
|
|
68
|
+
switch (keepSpecialComments) {
|
|
69
|
+
case '*':
|
|
70
|
+
return comments.restore(placeholder) + breakSuffix;
|
|
71
|
+
case 1:
|
|
72
|
+
case '1':
|
|
73
|
+
return restored == 1 ?
|
|
74
|
+
comments.restore(placeholder) + breakSuffix :
|
|
75
|
+
'';
|
|
76
|
+
case 0:
|
|
77
|
+
case '0':
|
|
78
|
+
return '';
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module.exports = function EscapeStore(placeholderRoot) {
|
|
2
|
+
placeholderRoot = 'ESCAPED_' + placeholderRoot + '_CLEAN_CSS';
|
|
3
|
+
|
|
4
|
+
var placeholderToData = {};
|
|
5
|
+
var dataToPlaceholder = {};
|
|
6
|
+
var count = 0;
|
|
7
|
+
var nextPlaceholder = function() {
|
|
8
|
+
return '__' + placeholderRoot + (count++) + '__';
|
|
9
|
+
};
|
|
10
|
+
var pattern = '(__' + placeholderRoot + '\\d{1,}__)';
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
placeholderPattern: pattern,
|
|
14
|
+
|
|
15
|
+
placeholderRegExp: new RegExp(pattern, 'g'),
|
|
16
|
+
|
|
17
|
+
store: function(data) {
|
|
18
|
+
var placeholder = dataToPlaceholder[data];
|
|
19
|
+
if (!placeholder) {
|
|
20
|
+
placeholder = nextPlaceholder();
|
|
21
|
+
placeholderToData[placeholder] = data;
|
|
22
|
+
dataToPlaceholder[data] = placeholder;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return placeholder;
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
restore: function(placeholder) {
|
|
29
|
+
return placeholderToData[placeholder];
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
var EscapeStore = require('./escape-store');
|
|
2
|
+
|
|
3
|
+
module.exports = function Expressions() {
|
|
4
|
+
var expressions = new EscapeStore('EXPRESSION');
|
|
5
|
+
|
|
6
|
+
var findEnd = function(data, start) {
|
|
7
|
+
var end = start + 'expression'.length;
|
|
8
|
+
var level = 0;
|
|
9
|
+
var quoted = false;
|
|
10
|
+
|
|
11
|
+
while (true) {
|
|
12
|
+
var next = data[end++];
|
|
13
|
+
|
|
14
|
+
if (quoted) {
|
|
15
|
+
quoted = next != '\'' && next != '"';
|
|
16
|
+
} else {
|
|
17
|
+
quoted = next == '\'' || next == '"';
|
|
18
|
+
|
|
19
|
+
if (next == '(')
|
|
20
|
+
level++;
|
|
21
|
+
if (next == ')')
|
|
22
|
+
level--;
|
|
23
|
+
if (next == '}' && level == 1) {
|
|
24
|
+
end--;
|
|
25
|
+
level--;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (level === 0 && next == ')')
|
|
30
|
+
break;
|
|
31
|
+
if (!next) {
|
|
32
|
+
end = data.substring(0, end).lastIndexOf('}');
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return end;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
return {
|
|
41
|
+
// Escapes expressions by replacing them by a special
|
|
42
|
+
// marker for further restoring. It's done via string scanning
|
|
43
|
+
// instead of regexps to speed up the process.
|
|
44
|
+
escape: function(data) {
|
|
45
|
+
var nextStart = 0;
|
|
46
|
+
var nextEnd = 0;
|
|
47
|
+
var cursor = 0;
|
|
48
|
+
var tempData = [];
|
|
49
|
+
|
|
50
|
+
for (; nextEnd < data.length;) {
|
|
51
|
+
nextStart = data.indexOf('expression(', nextEnd);
|
|
52
|
+
if (nextStart == -1)
|
|
53
|
+
break;
|
|
54
|
+
|
|
55
|
+
nextEnd = findEnd(data, nextStart);
|
|
56
|
+
|
|
57
|
+
var expression = data.substring(nextStart, nextEnd);
|
|
58
|
+
var placeholder = expressions.store(expression);
|
|
59
|
+
tempData.push(data.substring(cursor, nextStart));
|
|
60
|
+
tempData.push(placeholder);
|
|
61
|
+
cursor = nextEnd;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return tempData.length > 0 ?
|
|
65
|
+
tempData.join('') + data.substring(cursor, data.length) :
|
|
66
|
+
data;
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
restore: function(data) {
|
|
70
|
+
return data.replace(expressions.placeholderRegExp, expressions.restore);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
(function() {
|
|
2
|
+
var EscapeStore = require('./escape-store');
|
|
3
|
+
var QuoteScanner = require('./quote-scanner');
|
|
4
|
+
|
|
5
|
+
var Free = function Free() {
|
|
6
|
+
this.matches = new EscapeStore('FREE_TEXT');
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
// Strip content tags by replacing them by the a special
|
|
10
|
+
// marker for further restoring. It's done via string scanning
|
|
11
|
+
// instead of regexps to speed up the process.
|
|
12
|
+
Free.prototype.escape = function(data) {
|
|
13
|
+
var self = this;
|
|
14
|
+
|
|
15
|
+
return new QuoteScanner(data).each(function(match, store) {
|
|
16
|
+
var placeholder = self.matches.store(match);
|
|
17
|
+
store.push(placeholder);
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
Free.prototype.restore = function(data) {
|
|
22
|
+
return data.replace(this.matches.placeholderRegExp, this.matches.restore);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
module.exports = Free;
|
|
26
|
+
})();
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
(function() {
|
|
2
|
+
var QuoteScanner = require('./quote-scanner');
|
|
3
|
+
var PropertyScanner = require('../properties/scanner');
|
|
4
|
+
|
|
5
|
+
var NameQuotes = function NameQuotes() {};
|
|
6
|
+
|
|
7
|
+
var STRIPPABLE = /^['"][a-zA-Z][a-zA-Z\d\-_]+['"]$/;
|
|
8
|
+
|
|
9
|
+
var properties = [
|
|
10
|
+
'animation',
|
|
11
|
+
'-moz-animation',
|
|
12
|
+
'-o-animation',
|
|
13
|
+
'-webkit-animation',
|
|
14
|
+
'animation-name',
|
|
15
|
+
'-moz-animation-name',
|
|
16
|
+
'-o-animation-name',
|
|
17
|
+
'-webkit-animation-name',
|
|
18
|
+
'font',
|
|
19
|
+
'font-family'
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
NameQuotes.prototype.process = function(data) {
|
|
23
|
+
var scanner = new PropertyScanner(data);
|
|
24
|
+
|
|
25
|
+
return new QuoteScanner(data).each(function(match, store, cursor) {
|
|
26
|
+
var lastProperty = scanner.nextAt(cursor);
|
|
27
|
+
if (properties.indexOf(lastProperty) > -1) {
|
|
28
|
+
if (STRIPPABLE.test(match))
|
|
29
|
+
match = match.substring(1, match.length - 1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
store.push(match);
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
module.exports = NameQuotes;
|
|
37
|
+
})();
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
(function() {
|
|
2
|
+
var QuoteScanner = function QuoteScanner(data) {
|
|
3
|
+
this.data = data;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
var findQuoteEnd = function(data, matched, cursor, oldCursor) {
|
|
7
|
+
var commentStartMark = '/*';
|
|
8
|
+
var commentEndMark = '*/';
|
|
9
|
+
var escapeMark = '\\';
|
|
10
|
+
var blockEndMark = '}';
|
|
11
|
+
var dataPrefix = data.substring(oldCursor, cursor);
|
|
12
|
+
var commentEndedAt = dataPrefix.lastIndexOf(commentEndMark, cursor);
|
|
13
|
+
var commentStartedAt = dataPrefix.lastIndexOf(commentStartMark, cursor);
|
|
14
|
+
var commentStarted = false;
|
|
15
|
+
|
|
16
|
+
if (commentEndedAt >= cursor && commentStartedAt > -1)
|
|
17
|
+
commentStarted = true;
|
|
18
|
+
if (commentStartedAt < cursor && commentStartedAt > commentEndedAt)
|
|
19
|
+
commentStarted = true;
|
|
20
|
+
|
|
21
|
+
if (commentStarted) {
|
|
22
|
+
var commentEndsAt = data.indexOf(commentEndMark, cursor);
|
|
23
|
+
if (commentEndsAt > -1)
|
|
24
|
+
return commentEndsAt;
|
|
25
|
+
|
|
26
|
+
commentEndsAt = data.indexOf(blockEndMark, cursor);
|
|
27
|
+
return commentEndsAt > -1 ? commentEndsAt - 1 : data.length;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
while (true) {
|
|
31
|
+
if (data[cursor] === undefined)
|
|
32
|
+
break;
|
|
33
|
+
if (data[cursor] == matched && data[cursor - 1] != escapeMark)
|
|
34
|
+
break;
|
|
35
|
+
|
|
36
|
+
cursor++;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return cursor;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
QuoteScanner.prototype.each = function(callback) {
|
|
43
|
+
var data = this.data;
|
|
44
|
+
var tempData = [];
|
|
45
|
+
var nextStart = 0;
|
|
46
|
+
var nextEnd = 0;
|
|
47
|
+
var cursor = 0;
|
|
48
|
+
var matchedMark = null;
|
|
49
|
+
var singleMark = '\'';
|
|
50
|
+
var doubleMark = '"';
|
|
51
|
+
var dataLength = data.length;
|
|
52
|
+
|
|
53
|
+
for (; nextEnd < data.length;) {
|
|
54
|
+
var nextStartSingle = data.indexOf(singleMark, nextEnd + 1);
|
|
55
|
+
var nextStartDouble = data.indexOf(doubleMark, nextEnd + 1);
|
|
56
|
+
|
|
57
|
+
if (nextStartSingle == -1)
|
|
58
|
+
nextStartSingle = dataLength;
|
|
59
|
+
if (nextStartDouble == -1)
|
|
60
|
+
nextStartDouble = dataLength;
|
|
61
|
+
|
|
62
|
+
if (nextStartSingle < nextStartDouble) {
|
|
63
|
+
nextStart = nextStartSingle;
|
|
64
|
+
matchedMark = singleMark;
|
|
65
|
+
} else {
|
|
66
|
+
nextStart = nextStartDouble;
|
|
67
|
+
matchedMark = doubleMark;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (nextStart == -1)
|
|
71
|
+
break;
|
|
72
|
+
|
|
73
|
+
nextEnd = findQuoteEnd(data, matchedMark, nextStart + 1, cursor);
|
|
74
|
+
if (nextEnd == -1)
|
|
75
|
+
break;
|
|
76
|
+
|
|
77
|
+
var text = data.substring(nextStart, nextEnd + 1);
|
|
78
|
+
tempData.push(data.substring(cursor, nextStart));
|
|
79
|
+
if (text.length > 0)
|
|
80
|
+
callback(text, tempData, nextStart);
|
|
81
|
+
|
|
82
|
+
cursor = nextEnd + 1;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return tempData.length > 0 ?
|
|
86
|
+
tempData.join('') + data.substring(cursor, data.length) :
|
|
87
|
+
data;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
module.exports = QuoteScanner;
|
|
91
|
+
})();
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
var Splitter = function Splitter (separator) {
|
|
2
|
+
this.separator = separator;
|
|
3
|
+
};
|
|
4
|
+
|
|
5
|
+
Splitter.prototype.split = function (value) {
|
|
6
|
+
if (value.indexOf(this.separator) === -1)
|
|
7
|
+
return [value];
|
|
8
|
+
|
|
9
|
+
if (value.indexOf('(') === -1)
|
|
10
|
+
return value.split(this.separator);
|
|
11
|
+
|
|
12
|
+
var level = 0;
|
|
13
|
+
var cursor = 0;
|
|
14
|
+
var lastStart = 0;
|
|
15
|
+
var len = value.length;
|
|
16
|
+
var tokens = [];
|
|
17
|
+
|
|
18
|
+
while (cursor++ < len) {
|
|
19
|
+
if (value[cursor] == '(') {
|
|
20
|
+
level++;
|
|
21
|
+
} else if (value[cursor] == ')') {
|
|
22
|
+
level--;
|
|
23
|
+
} else if (value[cursor] == this.separator && level === 0) {
|
|
24
|
+
tokens.push(value.substring(lastStart, cursor));
|
|
25
|
+
lastStart = cursor + 1;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (lastStart < cursor + 1)
|
|
30
|
+
tokens.push(value.substring(lastStart));
|
|
31
|
+
|
|
32
|
+
return tokens;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
module.exports = Splitter;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
var EscapeStore = require('./escape-store');
|
|
2
|
+
|
|
3
|
+
module.exports = function Urls() {
|
|
4
|
+
var urls = new EscapeStore('URL');
|
|
5
|
+
|
|
6
|
+
return {
|
|
7
|
+
// Strip urls by replacing them by a special
|
|
8
|
+
// marker for further restoring. It's done via string scanning
|
|
9
|
+
// instead of regexps to speed up the process.
|
|
10
|
+
escape: function(data) {
|
|
11
|
+
var nextStart = 0;
|
|
12
|
+
var nextEnd = 0;
|
|
13
|
+
var cursor = 0;
|
|
14
|
+
var tempData = [];
|
|
15
|
+
|
|
16
|
+
for (; nextEnd < data.length;) {
|
|
17
|
+
nextStart = data.indexOf('url(', nextEnd);
|
|
18
|
+
if (nextStart == -1)
|
|
19
|
+
break;
|
|
20
|
+
|
|
21
|
+
nextEnd = data.indexOf(')', nextStart);
|
|
22
|
+
|
|
23
|
+
var url = data.substring(nextStart, nextEnd + 1);
|
|
24
|
+
var placeholder = urls.store(url);
|
|
25
|
+
tempData.push(data.substring(cursor, nextStart));
|
|
26
|
+
tempData.push(placeholder);
|
|
27
|
+
cursor = nextEnd + 1;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return tempData.length > 0 ?
|
|
31
|
+
tempData.join('') + data.substring(cursor, data.length) :
|
|
32
|
+
data;
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
restore: function(data) {
|
|
36
|
+
return data.replace(urls.placeholderRegExp, function(placeholder) {
|
|
37
|
+
return urls.restore(placeholder).replace(/\s/g, '');
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "clean-css",
|
|
3
|
+
"version": "2.2.13",
|
|
4
|
+
"author": "Jakub Pawlowicz <jakub@goalsmashers.com> (http://twitter.com/GoalSmashers)",
|
|
5
|
+
"description": "A well-tested CSS minifier",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"css",
|
|
9
|
+
"minifier"
|
|
10
|
+
],
|
|
11
|
+
"homepage": "https://github.com/GoalSmashers/clean-css",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/GoalSmashers/clean-css.git"
|
|
15
|
+
},
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/GoalSmashers/clean-css/issues"
|
|
18
|
+
},
|
|
19
|
+
"bin": {
|
|
20
|
+
"cleancss": "./bin/cleancss"
|
|
21
|
+
},
|
|
22
|
+
"main": "index.js",
|
|
23
|
+
"files": [
|
|
24
|
+
"bin",
|
|
25
|
+
"lib",
|
|
26
|
+
"History.md",
|
|
27
|
+
"index.js",
|
|
28
|
+
"LICENSE"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"browserify": "browserify --standalone CleanCSS index.js | uglifyjs --compress --mangle -o cleancss-browser.js",
|
|
32
|
+
"bench": "node ./test/bench.js",
|
|
33
|
+
"check": "jshint ./bin/cleancss .",
|
|
34
|
+
"prepublish": "jshint .",
|
|
35
|
+
"test": "vows"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"commander": "2.3.x"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"browserify": "5.x",
|
|
42
|
+
"jshint": "2.5.x",
|
|
43
|
+
"nock": "0.28.x",
|
|
44
|
+
"uglify-js": "2.4.x",
|
|
45
|
+
"vows": "0.7.x"
|
|
46
|
+
},
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=0.8.0"
|
|
49
|
+
}
|
|
50
|
+
}
|