I've been writing a user-generated content system in PHP where users can upload CSS (and HTML) that will be shown in a DIV. Of course, I wanted to restrict their CSS to only be applied inside the DIV and not style the surrounding content (either accidentally or maliciously).
The first step was easy: create a class and assign it to the DIV.
<div class="user_content">
But how to restrict a CSS stylesheet with a bunch of random rules to that DIV?
Given something like this:
.block input, table td.money {
...
}
How do I turn it into this?
.user_content .block input, .user_content table td.money {
...
}
A long search finally ended when Stack Overflow revealed a way to insert my user_content class before every rule using a fancy regular expression ... but it broke down on comments with commas in them. It was a long search because it was very difficult to figure out what search terms to use and a real bummer that the solution broke down on something as common as comments.
So, I developed this code to handle block out the commas in comments, apply the fancy regular expression from Stack Overflow and then put the commas back.
function rewriteCss($css, $cssClazz) {
while (preg_match('/(\/\*.+?),(.+?\*\/)/', $css) === 1) {
$contents = preg_replace(
'/(\/\*.+?),(.+?\*\/)/', '$1:comma:$2', $css);
}
$css = preg_replace(
'/([^\r\n,{}]+)(,\s*(?=[^}]*{)|\s*{)/',
'.'.$cssClazz.' $1$2', $css);
while (preg_match('/(\/\*.+?):comma:(.+?\*\/)/', $css) === 1) {
$css = preg_replace(
'/(\/\*.+?):comma:(.+?\*\/)/', '$1,$2', $css);
}
return $css;
}
That did the trick. Each comma in a comment is blocked out by replacing it with :comma:. Then, a complicated preg_replace() call is made with the fancy regular expression from Stack Overflow. Finally, the :comma: in comments are restored to being literal commas.
Super.
No comments:
Post a Comment