How To Convert Css String Into Array
Solution 1:
See this fiddle: http://jsfiddle.net/YrQ7B/3/
var arr = [".divd { bottom: 0px; height: 500px; }",
"#divk { font-size: 14px; }"];
var output = {};
for(var k in arr)
{
var value = arr[k], key;
// Get key
value.replace(/(\.|#)([a-z\s]+){/gi, function($1, $2, $3){
key = $3;
});
// Make object
output[key] = {};
// Replace First part
value = value.replace(/\.([a-z\s]+) {/gi, "");
value = value.replace("}", "");
value.replace(/([a-z\-]+)([^:]+)?:([^0-9a-z]+)?([^;]+)/g, function($1, $2, $3, $4, $5){
output[key][$2] = $5;
});
}
console.log(output);
The log:
Objectdivd: Objectbottom: "0px"height: "500px"divk: Object
font-size: "14px"
Solution 2:
Unfortunately parsing CSS tokens is not exactly as easy as splitting a string, in fact, you ideally will need a parser, and I would suggest the use of an existing CSS parser for your task:
Solution 3:
a no-RegExp method
var cssObj = {},
arr = [".divd { bottom: 0px; height: 500px; }", ".divk { font-size: 14px; }"],
arr_i = arr.length,
i, j, k, str,
sel, vals, val;
while(arr_i-- > 0){ // loop over array
str = arr[arr_i];
i = str.indexOf('{');
sel = str.slice(0,i); // get Selector
vals = str.slice(i+1,str.lastIndexOf('}')); // get valuesval = vals.slice(0,vals.lastIndexOf(';')).split(';'); // and put in array
cssObj[sel] = {};
k = val.length;
while(k-- > 0){
j = val[k].indexOf(':'); // get name-value pair
cssObj[sel][val[k].slice(0,j).trim()] = val[k].slice(j+1).trim();
}
}
console.log(cssObj); // see output
for use as function, pass arr
and change console.log
to return
. The .slice(0,vals.lastIndexOf(';'))
assumes you end the last entry before the }
with a semicolon. If you don't want to assume this, take it out and check last array item isn't blank/whitespace.
Solution 4:
I've used this in the past, but only when I knew exactly what I would be sending into the regexp - mainly because I'm sure there will be syntax out there that could break it (especially with the likes of mixins, css animations, css variables, and media queries). It's for these reasons why you should probably follow Mario's answer.
However, it has worked on the majority of my own css files that I've thrown at it and may help others out there... It isn't tailored to work with an array structure like you are using though, but that could be easily changed. Obivously you could optimise things by getting rid of RegExp
and just using indexOf
as shhac has done, but I find the expressiveness of RegExp far easier to work with and far easier to extend if and when you need to.
A few notes
- It assumes there are no comments in the CSS - you could always add a replace to strip comments.
- It relies on JSON.parse method being available - you could always include a non JSON fallback.
The code with comments:
window.onload = function(){
/// this is designed to find a <style> element in the page with id="css"var entireStylesheetString = document.getElementById('css').innerHTML;
var css = String('{'+entireStylesheetString+'}')
/// convert double quotes to single to avoid having to escape
.replace(/"/gi,"'")
/// replace all whitespace sequences with single space
.replace(/\s+/g,' ')
/// sort the first open brace so things are neat
.replace(/^{/,'{\n')
/// sort the newlines so each declaration is on own line
.replace(/\}/g,'}\n')
/// find the selectors and wrap them with quotes for JSON keys
.replace(/\n\s*([^\{]+)\s+?\{/g,'\n"$1":{')
/// find an attribute and wrap again with JSON key quotes
.replace(/([\{;])\s*([^:"\s]+)\s*:/g,'$1"$2":')
/// find values and wrap with JSON value quotes
.replace(/":\s*([^\}\{;]+)\s*(;|(\}))/g,'":"$1",$3')
/// add commas after each JSON object
.replace(/\}/g,'},')
/// make sure we don't have too many commas
.replace(/,\s*\}/g,'}');
/// remove the final end comma
css = css.substring(0,css.length-2);
try{
/// parse using JSONconsole.log(JSON.parse(css));
}catch(ee){
console.log(ee);
}
};
The code by it's lonesome:
window.onload = function(){
var entireStylesheetString = document.getElementById('css').innerHTML;
var css = String('{'+entireStylesheetString+'}')
.replace(/"/gi,"'")
.replace(/\s+/g,' ')
.replace(/^{/,'{\n')
.replace(/\}/g,'}\n')
.replace(/\n\s*([^\{]+)\s+?\{/g,'\n"$1":{')
.replace(/([\{;])\s*([^:"\s]+)\s*:/g,'$1"$2":')
.replace(/":\s*([^\}\{;]+)\s*(;|(\}))/g,'":"$1",$3')
.replace(/\}/g,'},')
.replace(/,\s*\}/g,'}');
css = css.substring(0,css.length-2);
try{console.log(JSON.parse(css));}catch(ee){console.log(ee);}
};
Solution 5:
I am not a proponent of eval, but if you convert
. to ["
first space to "]=
: to :"
; to ",
Then an eval will set the whole thing
Post a Comment for "How To Convert Css String Into Array"