Firefox, Opera and Safari (at least) provide a rule.style.length and an indexor which enables enumerating the styles in a rule. IE6 and 7 do not, however it is not difficult to split the cssText and enumerate through the styles. Firefox (2.0.0.6 at least) seems to have a bug where it breaks on styles like padding and margin. For example, if you have padding: 6px; all the other browsers will return values for padding-top, padding-left, padding-bottom and padding-right. Firefox (at least in this test) returns padding-top and padding-bottom with the correct values, and then padding-right-value, padding-right-ltr-source, padding-right-rtl-source, padding-left-value, padding-left-ltr-source and padding-left-rtl-source, all with undefined values. The same thing happens for margin, and other properties I'm sure. The script includes a work around for this where it checks for style names that end with -value and trims that off and uses that. It then ignores all styles whose values are undefined. This seems to work for all the browsers tested.
<style type='text/css'>
.rule_0_0 {
font-family: fantasy;
font-style: italic;
font-size: 24px;
color: red;
padding: 6px;
}
.rule_0_1 {
padding: 6px;
}
.rule_0_2 {
margin-bottom: 2px;
margin-right: 2px;
padding: 6px;
}
</style>
<style type='text/css'>
.rule_1_0 {
font-family: fantasy;
font-style: italic;
font-size: 24px;
color: red;
}
.rule_1_1 {
padding: 6px;
}
.rule_1_2 {
margin-bottom: 2px;
margin-right: 2px;
padding: 6px;
}
</style>
<script type='text/javascript'>
function getRule(styleSheetIndex, ruleIndex) {
var ss = document.styleSheets[styleSheetIndex];
var rules = ss.rules || ss.cssRules;
var rule = rules[ruleIndex];
var res = { selector: rule.selectorText, styles: [] };
if(Prototype.Browser.IE) {
var styles = rule.style.cssText.split(";");
for(var i = 0; i < styles.length; ++i) {
var style = styles[i].split(":");
res.styles.push({ name: style[0].strip().toLowerCase(), value: style[1].strip().toLowerCase() });
}
} else {
for(var i = 0; i < rule.style.length; ++i) {
var name = rule.style[i];
var value = rule.style[name.camelize()];
if(name.slice(-6) == "-value") { //Work around for Firefox bug
name = name.slice(0, -6);
value = rule.style[name.camelize()];
}
if(value) {
res.styles.push({ name: name, value: value });
}
}
}
return res;
}
function makeRuleOutput(styleSheetIndex, ruleIndex) {
var rule = getRule(styleSheetIndex, ruleIndex);
var res = rule.selector + "
";
for(var i = 0; i < rule.styles.length; ++i) {
res += (i + 1) + ". " + rule.styles[i].name + ": " + rule.styles[i].value + "
";
}
return res
}
Event.observe(window, "load", function() {
document.getElementById("rule_0_0").innerHTML = makeRuleOutput(0, 0);
document.getElementById("rule_0_2").innerHTML = makeRuleOutput(0, 2);
document.getElementById("rule_1_0").innerHTML = makeRuleOutput(1, 0);
document.getElementById("rule_1_2").innerHTML = makeRuleOutput(1, 2);
});
</script>