Revision: 13664
Initial Code
Initial URL
Initial Description
Initial Title
Initial Tags
Initial Language
at May 1, 2009 11:30 by dom111
Initial Code
/**
* JSS
*
* Nested CSS via JavaScript
**/
var JSS = function(o, options) {
// set up the base options
this.options = {
minified: true,
apply: true
}
// set up the data hash
this.data = {};
// m()
//
// Merges properties of s into o and returns o
//
this.m = function(o, s) {
for (var p in s) {
o[p] = s[p];
}
return o;
}
// parse()
//
// Parses the object o and stores the information in this.data{}
//
this.parse = function(o, p) {
if (typeof o != 'object') {
throw new Error('CSS::parse: No valid CSS object passed.');
}
if (!p) {
p = '';
}
for (var prop in o) {
if (typeof o[prop] == 'object') {
var rule = getPrefix(p) + prop;
if (!this.data[rule]) {
this.data[rule] = [];
}
this.parse(o[prop], this.getPrefix(p) + prop);
} else {
this.data[p][this.data[p].length] = (this.options.minified) ? prop + ':' + this.minify(o[prop]) + ';' : ' ' + prop + ': ' + o[prop] + ';\n';
}
}
}
// build()
//
// Builds the information stored in this.data{} into valid CSS text
//
this.build = function() {
var css = '';
for (var rule in this.data) {
if (this.data[rule] != []) {
css += (this.options.minified) ? rule + '{' : rule + ' {\n';
css += this.data[rule].join('');
css += (this.options.minified) ? '}' : '}\n\n';
}
}
return css;
}
// getPrefix()
//
// Shortcut to return the prefix for stacking
//
this.getPrefix = function(p) {
if (p) {
return p + ' ';
} else {
return '';
}
}
// minify()
//
// Minifies the string passed
//
this.minify = function(s) {
// html/css colour names that can be replaced by shorter hex codes
var colours = [
[
/black/,
'#000'
],
[
/white/,
'#fff'
],
[
/fuchsia/,
'#f0f'
],
[
/yellow/,
'#ff0'
]
];
// loop through taking out any long colour names
for (var i = colours.length - 1; i >= 0; i--){
s = s.replace(colours[i][0], colours[i][1]);
}
// if we've got any 6 char hex codes
if (s.match(/#[0-9a-f]{6}/)) {
// see if we can shrink them
var matches = s.match(/#([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])/);
if ((matches[1] == matches[2]) && (matches[3] == matches[4]) && (matches[5] == matches[6])) {
s = s.replace(matches[0], '#' + matches[1] + matches[3] + matches[5]);
}
}
return s;
}
// addToPage()
//
// Applies the generated stylesheet to the page
//
this.addToPage = function(s) {
// create a style element
var style = document.createElement('style');
// set it to a text/css block
style.setAttribute('type', 'text/css');
// append the style to the body
if (style.styleSheet) {
// in IE
style.styleSheet.cssText = s;
} else {
// in the other browsers
style.appendChild(document.createTextNode(s));
}
// put it in the document
document.getElementsByTagName('head')[0].appendChild(style);
}
// set the options
this.options = this.m(this.options, options || {});
// start parsing the object
this.parse(o);
if (this.options.apply) {
// if we're supposed to apply the stylesheet, do it!
this.addToPage(this.build());
} else {
// just return the text
return this.build();
}
}
Initial URL
http://www.dom111.co.uk/blog/coding/jss-nested-css-using-javascript/94
Initial Description
Ever wanted nested stylesheets?
I have!
Now you can have them! If you code your stylesheets as JSON and parse them using JSS 0.1. You could have the following:
JSS({
'html': {
'body': {
background: '#fff',
'div#header': {
height: '100px',
background: '#00f'
},
'div#footer': {
height: '40px',
'span#copyright': {
color: '#0f0'
},
'span#testing': {
color: 'black',
background: '#eeccff'
}
}
},
width: '800px'
}
});
Turned into:
html {
width: 800px;
}
html body {
background: #fff;
}
html body div#header {
height: 100px;
background: #00f;
}
html body div#footer {
height: 40px;
}
html body div#footer span#copyright {
color: #0f0;
}
html body div#footer span#testing {
color: black;
background: #eeccff;
}
Check out the blog post for a demo and a zip file containing the demo, full version and minified version.
Initial Title
JSS 0.1 - Nested CSS using Javascript
Initial Tags
css, javascript
Initial Language
JavaScript