Ok so lets say I have a variable $css
that contains some CSS code. What I want to do is to add a certain text in front of each selector. So for example, the following code:
好吧,假设我有一个包含一些CSS代码的变量$ css。我想要做的是在每个选择器前面添加一个特定的文本。例如,以下代码:
#hello, .class{width:1px;height:1px;background-color:#AAA;}
div{font-size:1px}
input, a, span{padding:4px}
Would be converted into:
将被转换为:
#someId #hello, #someId .class{ ... }
#someId div{ ... }
#someId input, #someId a, #someId span{ ... }
I have been trying to use several explode()
s. However, I haven't been able to accomplish the task effectively. Any thoughts?
我一直试图使用几个explode()。但是,我无法有效地完成任务。有什么想法吗?
Thanks! JCOC611
5 个解决方案
#1
4
Based on Jon's suggestion I wrote the following code:
根据Jon的建议,我写了以下代码:
<?php
$prefix = '#someId';
$css = '#hello, .class{width:1px;height:1px;background-color:#AAA;}
div{font-size:1px}
input, a, span{padding:4px}';
$parts = explode('}', $css);
foreach ($parts as &$part) {
if (empty($part)) {
continue;
}
$subParts = explode(',', $part);
foreach ($subParts as &$subPart) {
$subPart = $prefix . ' ' . trim($subPart);
}
$part = implode(', ', $subParts);
}
$prefixedCss = implode("}\n", $parts);
echo $prefixedCss;
To see that it works see http://codepad.org/bqRd83gu
要查看它的工作原理,请参阅http://codepad.org/bqRd83gu
#2
3
I wrote improved version because I also need media query. This is my function based on Jan's answer:
我写了改进版,因为我还需要媒体查询。这是我根据Jan的答案的功能:
function getPrefixedCss($css,$prefix){
$parts = explode('}', $css);
$mediaQueryStarted = false;
foreach ($parts as &$part) {
if (empty($part)) {
continue;
}
$partDetails = explode('{',$part);
if(substr_count($part,"{")==2){
$mediaQuery = $partDetails[0]."{";
$partDetails[0] = $partDetails[1];
$mediaQueryStarted = true;
}
$subParts = explode(',', $partDetails[0]);
foreach ($subParts as &$subPart) {
if(trim($subPart)=="@font-face") continue;
$subPart = $prefix . ' ' . trim($subPart);
}
if(substr_count($part,"{")==2){
$part = $mediaQuery."\n".implode(', ', $subParts)."{".$partDetails[2];
}elseif(empty($part[0]) && $mediaQueryStarted){
$mediaQueryStarted = false;
$part = implode(', ', $subParts)."{".$partDetails[2]."}\n"; //finish media query
}else{
$part = implode(', ', $subParts)."{".$partDetails[1];
}
}
$prefixedCss = implode("}\n", $parts);
return $prefixedCss;
}
It works with media query and also @font-face.
它适用于媒体查询和@ font-face。
#3
1
This is more advanced JohnyFree's variant, with few dirty
modifications.
这是更高级的JohnyFree的变种,几乎没有任何肮脏的修改。
This variant packs whole css into a single line, removes all css comments as well, and checks if $partDetails[1]
is actually isset at the end, and than goes the imploding *(last else
)
这个变量将整个css打包成一行,同时删除所有的css注释,并检查$ partDetails [1]是否实际上是在最后设置,而不是内爆*(最后一个)
Give JohnyFree more reputation folks, he deserves it.
给予JohnyFree更多声誉的人,他应得的。
ps: I have added # shell style comments
on places where modifications were performed by me.
ps:我已经在我执行修改的地方添加了#hell样式注释。
function getPrefixedCss($css,$prefix)
{
# Wipe all block comments
$css = preg_replace('!/\*.*?\*/!s', '', $css);
$parts = explode('}', $css);
$mediaQueryStarted = false;
foreach($parts as &$part)
{
$part = trim($part); # Wht not trim immediately .. ?
if(empty($part)) continue;
else # This else is also required
{
$partDetails = explode('{', $part);
if(substr_count($part, "{")==2)
{
$mediaQuery = $partDetails[0]."{";
$partDetails[0] = $partDetails[1];
$mediaQueryStarted = true;
}
$subParts = explode(',', $partDetails[0]);
foreach($subParts as &$subPart)
{
if(trim($subPart)==="@font-face") continue;
else $subPart = $prefix . ' ' . trim($subPart);
}
if(substr_count($part,"{")==2)
{
$part = $mediaQuery."\n".implode(', ', $subParts)."{".$partDetails[2];
}
elseif(empty($part[0]) && $mediaQueryStarted)
{
$mediaQueryStarted = false;
$part = implode(', ', $subParts)."{".$partDetails[2]."}\n"; //finish media query
}
else
{
if(isset($partDetails[1]))
{ # Sometimes, without this check,
# there is an error-notice, we don't need that..
$part = implode(', ', $subParts)."{".$partDetails[1];
}
}
unset($partDetails, $mediaQuery, $subParts); # Kill those three ..
} unset($part); # Kill this one as well
}
# Finish with the whole new prefixed string/file in one line
return(preg_replace('/\s+/',' ',implode("} ", $parts)));
}
#4
0
It looks like you need a proper CSS parser in order to be able to tell where is the start of each selector.
看起来你需要一个合适的CSS解析器才能分辨出每个选择器的起点。
However, you might be able to get away with a quick and dirty solution by considering that }
signals the end of each selector, and inserting the necessary text after each occurrence of the closing brace except the last one.
但是,您可以通过考虑}}发出信号来指示每个选择器的结尾,并在每次出现结束括号(最后一个除外)之后插入必要的文本,从而逃脱快速而肮脏的解决方案。
#5
0
This method will add prefixes to all selectors.
此方法将为所有选择器添加前缀。
/**
* Prefix CSS code.
*
* @param $prefix prefix to add to all selectors.
* @param $css CSS code to prefix.
* @return CSS the prefixed CSS
*/
function prefixCSS($prefix, $css) {
$parts = explode('}', $css);
foreach ($parts as &$part) {
if (empty($part)) {
continue;
}
$firstPart = substr($part, 0, strpos($part, '{') + 1);
$lastPart = substr($part, strpos($part, '{') + 2);
$subParts = explode(',', $firstPart);
foreach ($subParts as &$subPart) {
$subPart = str_replace("\n", '', $subPart);
$subPart = $prefix . ' ' . trim($subPart);
}
$part = implode(', ', $subParts) . $lastPart;
}
$prefixedCSS = implode("}\n", $parts);
return $prefixedCSS;
}
#1
4
Based on Jon's suggestion I wrote the following code:
根据Jon的建议,我写了以下代码:
<?php
$prefix = '#someId';
$css = '#hello, .class{width:1px;height:1px;background-color:#AAA;}
div{font-size:1px}
input, a, span{padding:4px}';
$parts = explode('}', $css);
foreach ($parts as &$part) {
if (empty($part)) {
continue;
}
$subParts = explode(',', $part);
foreach ($subParts as &$subPart) {
$subPart = $prefix . ' ' . trim($subPart);
}
$part = implode(', ', $subParts);
}
$prefixedCss = implode("}\n", $parts);
echo $prefixedCss;
To see that it works see http://codepad.org/bqRd83gu
要查看它的工作原理,请参阅http://codepad.org/bqRd83gu
#2
3
I wrote improved version because I also need media query. This is my function based on Jan's answer:
我写了改进版,因为我还需要媒体查询。这是我根据Jan的答案的功能:
function getPrefixedCss($css,$prefix){
$parts = explode('}', $css);
$mediaQueryStarted = false;
foreach ($parts as &$part) {
if (empty($part)) {
continue;
}
$partDetails = explode('{',$part);
if(substr_count($part,"{")==2){
$mediaQuery = $partDetails[0]."{";
$partDetails[0] = $partDetails[1];
$mediaQueryStarted = true;
}
$subParts = explode(',', $partDetails[0]);
foreach ($subParts as &$subPart) {
if(trim($subPart)=="@font-face") continue;
$subPart = $prefix . ' ' . trim($subPart);
}
if(substr_count($part,"{")==2){
$part = $mediaQuery."\n".implode(', ', $subParts)."{".$partDetails[2];
}elseif(empty($part[0]) && $mediaQueryStarted){
$mediaQueryStarted = false;
$part = implode(', ', $subParts)."{".$partDetails[2]."}\n"; //finish media query
}else{
$part = implode(', ', $subParts)."{".$partDetails[1];
}
}
$prefixedCss = implode("}\n", $parts);
return $prefixedCss;
}
It works with media query and also @font-face.
它适用于媒体查询和@ font-face。
#3
1
This is more advanced JohnyFree's variant, with few dirty
modifications.
这是更高级的JohnyFree的变种,几乎没有任何肮脏的修改。
This variant packs whole css into a single line, removes all css comments as well, and checks if $partDetails[1]
is actually isset at the end, and than goes the imploding *(last else
)
这个变量将整个css打包成一行,同时删除所有的css注释,并检查$ partDetails [1]是否实际上是在最后设置,而不是内爆*(最后一个)
Give JohnyFree more reputation folks, he deserves it.
给予JohnyFree更多声誉的人,他应得的。
ps: I have added # shell style comments
on places where modifications were performed by me.
ps:我已经在我执行修改的地方添加了#hell样式注释。
function getPrefixedCss($css,$prefix)
{
# Wipe all block comments
$css = preg_replace('!/\*.*?\*/!s', '', $css);
$parts = explode('}', $css);
$mediaQueryStarted = false;
foreach($parts as &$part)
{
$part = trim($part); # Wht not trim immediately .. ?
if(empty($part)) continue;
else # This else is also required
{
$partDetails = explode('{', $part);
if(substr_count($part, "{")==2)
{
$mediaQuery = $partDetails[0]."{";
$partDetails[0] = $partDetails[1];
$mediaQueryStarted = true;
}
$subParts = explode(',', $partDetails[0]);
foreach($subParts as &$subPart)
{
if(trim($subPart)==="@font-face") continue;
else $subPart = $prefix . ' ' . trim($subPart);
}
if(substr_count($part,"{")==2)
{
$part = $mediaQuery."\n".implode(', ', $subParts)."{".$partDetails[2];
}
elseif(empty($part[0]) && $mediaQueryStarted)
{
$mediaQueryStarted = false;
$part = implode(', ', $subParts)."{".$partDetails[2]."}\n"; //finish media query
}
else
{
if(isset($partDetails[1]))
{ # Sometimes, without this check,
# there is an error-notice, we don't need that..
$part = implode(', ', $subParts)."{".$partDetails[1];
}
}
unset($partDetails, $mediaQuery, $subParts); # Kill those three ..
} unset($part); # Kill this one as well
}
# Finish with the whole new prefixed string/file in one line
return(preg_replace('/\s+/',' ',implode("} ", $parts)));
}
#4
0
It looks like you need a proper CSS parser in order to be able to tell where is the start of each selector.
看起来你需要一个合适的CSS解析器才能分辨出每个选择器的起点。
However, you might be able to get away with a quick and dirty solution by considering that }
signals the end of each selector, and inserting the necessary text after each occurrence of the closing brace except the last one.
但是,您可以通过考虑}}发出信号来指示每个选择器的结尾,并在每次出现结束括号(最后一个除外)之后插入必要的文本,从而逃脱快速而肮脏的解决方案。
#5
0
This method will add prefixes to all selectors.
此方法将为所有选择器添加前缀。
/**
* Prefix CSS code.
*
* @param $prefix prefix to add to all selectors.
* @param $css CSS code to prefix.
* @return CSS the prefixed CSS
*/
function prefixCSS($prefix, $css) {
$parts = explode('}', $css);
foreach ($parts as &$part) {
if (empty($part)) {
continue;
}
$firstPart = substr($part, 0, strpos($part, '{') + 1);
$lastPart = substr($part, strpos($part, '{') + 2);
$subParts = explode(',', $firstPart);
foreach ($subParts as &$subPart) {
$subPart = str_replace("\n", '', $subPart);
$subPart = $prefix . ' ' . trim($subPart);
}
$part = implode(', ', $subParts) . $lastPart;
}
$prefixedCSS = implode("}\n", $parts);
return $prefixedCSS;
}