Skip to content

Instantly share code, notes, and snippets.

@lindsayevans
Created December 21, 2010 23:40
Show Gist options
  • Save lindsayevans/750826 to your computer and use it in GitHub Desktop.
Save lindsayevans/750826 to your computer and use it in GitHub Desktop.
Optimise CSS rules for HTTP compression
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>CSS Compression Optimiser</title>
<style type="text/css">
.col {
float: left;
clear: none;
width: 300px;
margin-right: 10px;
padding: 0 10px;
border: 1px solid #333;
background: #e3e3e3;
}
</style>
</head>
<body>
<h1>CSS Compression Optimiser</h1>
<div class="col">
<h3>Input:</h3>
<textarea rows="25" cols="35" id="unoptimised-css">
foo {
position: relative;
width: 100px;
float: left;
display: block;
clear: none;
height: 100px;
color: #c00;
}
xyz {
clear: none;
float: left;
width: 110px;
height: 110px;
color: #0c0;
}
bar {
position: relative;
display: block;
float: left;
clear: none;
width: 120px;
height: 120px;
color: #00c;
}
</textarea>
<button>Optimise!</button>
</div>
<div class="col">
<h3>Output:</h3>
<code><pre id="output"></pre></code>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script src="js/css-compression-optimiser.js"></script>
<script>
$(function(){
$('button').bind('click now', function(){
$('#output').html(CSSCompressionOptimiser.optimise($('#unoptimised-css').val()));
}).trigger('now');
});
</script>
</body>
var CSSCompressionOptimiser = (function(_this){
// Metadata
_this.type = 'library';
_this.name = 'CSS Compression Optimiser';
_this.major_version = 0;
_this.minor_version = 0;
_this.patch_version = 1;
_this.special_version = '';
_this.version = '0.0.1';
_this.globals = ['CSSCompressionOptimiser'];
// Public properties
_this.ruleset_chunker = /([^{]+){([^}]+)}/gi;
_this.rule_chunker = /([^:]+:[^;]+;)/gi;
// Constructor
_this.initialise = function(){
return _this;
};
// Public methods
_this.optimise = function(C){
var OC = '',
ruleset_chunker = _this.ruleset_chunker, ruleset,
rule_chunker = _this.rule_chunker, rule,
m
;
// Determine number of occurences of rules in stylesheet
while(ruleset = ruleset_chunker.exec(C)){
while(rule = rule_chunker.exec(ruleset[2])){
if(!num_matches[rule[1]]){
m = C.match(new RegExp(regexp_escape(rule[1]), 'gi'));
num_matches[rule[1]] = m ? m.length : 0;
}
}
}
// Rewrite stylesheet, grouping most used rules together
while(ruleset = ruleset_chunker.exec(C)){
var rules_match = ruleset[2].match(rule_chunker);
OC += ruleset[1] + '{';
if(rules_match){
OC += rules_match.sort(match_sorter).join('');
}
OC += '}';
}
return OC;
};
// Private properties
var num_matches = {};
// Private methods
// Array.sort function to sort based on number of occurences, falling back to alpha for ties
var match_sorter = function(a, b){
var ma = num_matches[a], mb = num_matches[b];
if(ma < mb){
return 1;
}
if(ma > mb){
return -1;
}
return a < b ? 0 : 1;
};
// Escape a string for use in new RegExp()
var regexp_escape = function(str){
return str.replace(new RegExp("[.*+?|()\\[\\]{}\\\\]", "g"), "\\$&");
};
return _this.initialise();
}(CSSCompressionOptimiser || {}));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment