2012-05-17 19 views
6

he analizado un archivo CSS/cadena dada en un objeto JSON de este modo:orden basado en la especificidad del selector

{ 
    "#header": { 
     "color": "#000000" 
    }, 
    "#header h1": { 
     "color": "#000" 
    }, 
    "h1": { 
     "color": "#4fb6e5" 
    } 
} 

Lo que quiero hacer ahora es volver a ordenarlos según una especificidad. En este caso, el #header h1 debe venir después del h1 en el objeto JSON, ya que así es como se aplicarán en el navegador.

¿Cómo puedo hacer esto? ¿Hay alguna biblioteca existente para esto? ¿O alguna biblioteca útil para ayudar con esto?

Puedo usar tanto Javascript/jQuery o PHP para hacer esto. Estoy buscando consejos de implementación y espero que esto ya se haya hecho.

+0

Para JavaScript, configuré un punto de partida en pseudocódigo aquí: [Ordenando un conjunto de selectores de CSS en función de la especificidad] (http://stackoverflow.com/questions/5158631/sorting-a-set- of-css-selectores-en-la-base-de-especificidad) pero aún no hay implementación. Si aún no has escrito una biblioteca JS para hacer esto, ¡supongo que podría aceptar el desafío! – BoltClock

Respuesta

3

respuestas cortas:

¿Hay alguna bibliotecas existentes para esto?

No, ninguno de los que conozco lo hace "out-of-the-box" para usted.

¿Alguna biblioteca útil para ayudar con esto?

sí, hay json_decode y uksort:

$specificity = function($selector) { 

    /* 
    * @link http://www.w3.org/TR/selectors/#specificity 
    * 
    * 9. Calculating a selector's specificity 
    * 
    * A selector's specificity is calculated as follows: 
    * 
    * * count the number of ID selectors in the selector (= a) 
    * * count the number of class selectors, attributes selectors, and 
    * pseudo-classes in the selector (= b) 
    * * count the number of type selectors and pseudo-elements in the 
    * selector (= c) 
    * * ignore the universal selector 
    * 
    * Selectors inside the negation pseudo-class are counted like any other, 
    * but the negation itself does not count as a pseudo-class. 
    * 
    * Concatenating the three numbers a-b-c (in a number system with a large 
    * base) gives the specificity. 
    */ 
    ... 
    return (int) $result; 
} 

$compare = function($a, $b) use ($specificity) { 
    return $specificity($a) - $specificity($b) 
}; 

$array = json_decode('{"yours" : "json"}', true); 

uksort($array, $compare); 

echo json_encode((object) $array); 

Como este ejemplo de código se muestra, sólo se explica cómo calcular la especificidad en un comentario y que no contiene el código. Eso es solo porque no tengo ese código a mano, pero he puesto allí la especificación de cómo se hace esto (al menos para CSS 3).

Si está buscando un analizador de selector de CSS, conozco el XDOM (porque lo escribí). Está disponible en github: https://github.com/hakre/XDOM - Es un analizador de selector de CSS 100% compatible con CSS 3.

Que yo sepa, esa es la mayor parte de lo que obtiene a partir de hoy en términos de soluciones ya preparadas. Todos los demás analizadores de selector de CSS que conozco no son totalmente compatibles con el estándar CSS 3 porque no cumplen con la especificación W3C. Lo cual puede ser bueno para usted: si no necesita una compatibilidad estricta con CSS3, puede encontrar algunos otros fragmentos de código que ya se adapten a sus necesidades.

+0

Ok logré improvisar algo que encontré en línea. ¿Cómo te parece esto? https://gist.github.com/2719627 - Creo que sigue todas las reglas que mencionaste para la especificidad. – Abs

+0

@Abs: podría verlo, ver mi tenedor: https://gist.github.com/2724460 - He dejado algunos comentarios allí y puede ver algunos cambios que pueden ser útiles.En general, necesitas agregar pruebas a esa función; de lo contrario, diría que se ve muy frágil. Algunos valores de entrada de prueba deberían hacer que funcione mucho mejor. – hakre

+0

gracias por echarle un vistazo, ¡la devolución está en el lugar equivocado! ¡Arreglando eso! También reinicié el puntaje porque utilizo esta función con un grupo de selectores a la vez, creo que debería estar bien. – Abs

0

En realidad, hay un algoritmo estándar para ordenar por especificidad, creo que es posible que desee ver eso.

CSS Specificity

también puede ser útil algún tipo de fórmula heurística, por ejemplo, comprobar si hay una # delante o contar la cantidad de espacios y puntos.

Cuestiones relacionadas