我有一个css数组要合并


I have a css array that I want to merge

我有一个用来创建模板的HTML类。我的课是这样的:

<?php
$page = 'TEST'HTML::dispense(':html');
$page->mainWrapper(':div') //creates a child object by using __call() and sets the "div" model
->id('mainWrapper') //sets id
->style('background','red') //adds a style
->text('blah') //adds a text
->addClass('someClass'); //adds a class
->someSpan(':span')
->addClass('spanClass')->addClass('someClass')
->style('font-size','12pt')
->style('border-bottom','1pt dashed black')
->style('background','red');
?>

这允许我快速开发html标记,而不用担心缺少字符或错误引用属性。所有东西都被缓存,我没有性能问题。

现在我想更进一步。在生产模式下,一切都工作得很好,但对于最终的输出,我想剥离所有内联的"样式"属性,并最小化它们,并将它们缓存在css文件中。现在,我有了一个函数,它循环遍历所有HTML对象,并根据标记、id和类聚合数据。我的问题是,一旦我有了整洁的css数组

$style['tag']['.class']['#id']['styleKey'] = styleValue

我如何修剪冗余的值,所以我留下了一个相关的css文件?缩小和压缩可以在后期进行。我现在想要的是比较值,并在转储它之前优化数组,以便所有具有相同标签/id/类的所有元素共同的'styleKeys'被分组在一起。

因此,在上面的例子中,例如,由于两个元素(div和span)共享样式为"background:red"和类为"someClass",我将使用"background:red"为"someClass"CSS规则

如果你感兴趣的话,下面是我的"extractstyles"函数:

<?php
public static function extractStyles($element, array &$styles=array()){
    if($element instanceof 'TEST'HTML){$element = $element->htmlData();}
    $tag = isset($element['#acronym']) ? $element['#acronym'] : NULL;
    $id = isset($element['#id']) ? '#'.$element['#id'] : NULL;
    $classes = isset($element['#class']) ? $element['#class'] : NULL;
    if(isset($element['#style']) && ($tag || $id || $class)){
        $ref = &$styles;
        if($id){if(!isset($ref[$id])){$ref[$id] = array();};$ref = &$ref[$id];}
        if($classes){
            if('is_array($classes)){$classes = '.'.implode('.',$classes);}
            if(!isset($ref[$classes])){$ref[$classes] = array();};$ref = &$ref[$classes];
        }
        if($tag){if(!isset($ref[$tag])){$ref[$tag] = array();};$ref = &$ref[$tag];}
        foreach($element[self::ATTRIBUTES]['#style'] as $style=>$value){
            $ref[$style] = $value;
        }
    }
    if(isset($element[self::CHILDREN]) && count($element[self::CHILDREN])){
        foreach($element[self::CHILDREN] as $child){
            self::extractStyles($child, $styles);
        }
    }
    return $styles;
}
?>

任何指针都是非常受欢迎的…我真的迷路了。我甚至不知道我在寻找的东西是否可行。

如上所述,性能现在不是问题。如果可行,我会想办法优化它。此外,请不要链接到xCSS和其他框架,因为他们的工作对字符串和我的CSS创建为一个数组。提前感谢你能给我的任何帮助!

一阶优化是建立一个层次树。这个树中的父子关系是子关系是父关系的超集。此树的根节点是一个空样式(您不会显示它)。

因此如果你有

.parent {
    background: red;
}
.childA {
    background: red;
    border: 1px solid black;
}
.childB {
    background: red;
    font-weight: 800;
}

父节点被设置为树中最小公分母。然后可以将其压缩为3个具有更少文本的类。子元素将包含路径中的所有类,如果你最初有<span class="childA">,那么你将得到<span class="parent childA">

压缩后的类如下:

.parent {
    background: red;
}
.childA {
    border: 1px solid black;
}
.childB {
    font-weight: 800;
}

关于id的说明,id总是最合适类的子类。因此如果你有

#menu {
    background: red;
    border: 1px solid black;
    margin: 15px 40px;
    color: white;
}

它将成为childda的子元素,并且它的css将缩减为

#menu {
    margin: 15px 40px;
    color: white;
}
并显示为<ul id="menu" class="parent childA">

要创建树,您需要一个对象来存储相同子对象的数组(递归地)和一个函数,当给定两个对象时,该函数可以确定它们的css是子集,相等还是超集,差异的数量,或者是否没有共性。

如果你不熟悉二叉搜索树,这将是一个很好的时间来钻研它,即使这将比那更复杂,这将是一个正确方向的良好开端。


第二级优化是确定嵌套子元素是否可以进一步减少对类的需求。例如,如果<ul id="#menu">中的所有<li>样式相似,那么您可以为#menu li创建规则 要做到这一点,您需要转到每个节点,并分析它的子节点。如果同一节点类型的所有子节点共享一个公共样式元素(使用上面的集合比较器),则提取公共集合元素作为父元素。差异变成了孩子。

让我们假设你有这样一个例子(注意它已经通过了第1步):

<ul id="menu" class="parent childA">
    <li class="top menuli">Item</li>
    <li class="menuli">Item</li>
    <li class="menuli">Item</li>
    <li class="menuli">Item</li>
    <li class="bottom menuli">Item</li>
</ul>

我们注意到所有的<li>都有一个共同的元素。menuli,这意味着我们可以消除这个在第1步中创建的类,并用#menu li的平面规则代替它。为此,我们从每个子li中删除menuli类,并用#menu li规则替换.menuli规则。

我们的css改变如下:

#menu {
    margin: 15px 40px;
    color: white;
}
.menuli {
    font-size: 30px;
    font-weight: 800;
    margin: 8px 0;
}

#menu {
    margin: 15px 40px;
    color: white;
}
#menu li {
    font-size: 30px;
    font-weight: 800;
    margin: 8px 0;
}

html失去了类menuli

<ul id="menu" class="parent childA">
    <li class="top">Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li class="bottom">Item</li>
</ul>

请记住,在搜索节点树时使用广度优先搜索,而不是深度优先搜索。如果你是激进的,你可以继续检查类似的标签在许多路径的第二级,一个常见的第二级搜索可能会发现类似的类#menu li a#container div p等。如果你允许无限深度搜索,这就变成了NP困难问题。

希望这对你有帮助。如果这是你想要去的方向,我很乐意帮助更多关于集合比较器和可能的树搜索器的代码,尽管这要复杂得多。