2012-05-17 14 views
6

ho analizzato un dato file CSS/stringa in un oggetto JSON in questo modo:Order CSS sulla base di selettore Specificità

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

Quello che voglio fare ora è ri-ordinare loro sulla base di Specificty. In questo caso, lo #header h1 dovrebbe venire dopo lo h1 nell'oggetto JSON poiché questo è il modo in cui verranno applicati nel browser.

Come posso fare questo? Ci sono delle librerie esistenti per questo? O qualche utile libreria per aiutarti?

Posso usare sia Javascript/jQuery o PHP per fare questo. Sto cercando consigli sull'implementazione e spero che questo sia già stato fatto!

+0

Per JavaScript, ho impostato un punto di partenza in pseudo-codice qui: [Ordinamento di un set di selettori CSS sulla base della specificità] (http://stackoverflow.com/questions/5158631/sorting-a-set- of-css-selectors-on-the-base-of-specificity) ma non c'è ancora alcuna implementazione. Se non hai ancora scritto una libreria JS per farlo, suppongo che potrei raccogliere la sfida! – BoltClock

risposta

3

risposte brevi:

ci sono delle librerie esistenti per questo?

No, nessuno dei quali sono a conoscenza di questo "out-of-the-box" per te.

O qualche utile libreria per aiutare con questo?

Sì, c'è json_decode e 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); 

Come questo esempio di codice mostra, spiega solo come calcolare la specificità in un commento e non contiene il codice. Questo è solo perché non ho quel codice a portata di mano, ma ho inserito le specifiche su come è fatto (almeno per CSS 3).

Se stai cercando un parser di selettori CSS, so di XDOM (perché l'ho scritto). È disponibile su github: https://github.com/hakre/XDOM - È un parser al selettore CSS compatibile con CSS 3 al 100%.

Per quanto ne so, questo è ciò che più di oggi si ottiene in termini di soluzioni già pronte. Tutti gli altri parser di selettori CSS che conosco non sono pienamente compatibili con lo standard CSS 3 perché non seguono la specifica W3C. Quale potrebbe essere un bene per te: se non hai bisogno di una stretta compatibilità CSS3, potresti trovare alcuni altri pezzi di codice che soddisfano già le tue esigenze.

+0

Ok, sono riuscito a mettere insieme qualcosa che ho trovato online. Come ti sembra? https://gist.github.com/2719627 - Penso che segua tutte le regole che hai menzionato per specificità. – Abs

+0

@Abs: potrei guardarci sopra, vedere la mia forchetta: https://gist.github.com/2724460 - Ho lasciato alcuni commenti lì e puoi vedere alcune modifiche che potrebbero essere utili.In genere è necessario aggiungere test a tale funzione, altrimenti direi che sembra molto fragile. Alcuni valori di input test dovrebbero farlo funzionare molto meglio. – hakre

+0

grazie per dargli un'occhiata, il ritorno è nel posto sbagliato! Risolvendolo! Inoltre resetto il punteggio perché uso questa funzione con un set di selettori alla volta, penso che dovrebbe andare bene. – Abs

0

In realtà c'è un algoritmo standard per ordinare per specificità, penso che potresti volerlo dare un'occhiata.

CSS Specificity

Inoltre può essere utile una sorta di formula euristica, ad esempio, verificare se v'è un leader # o contare la quantità di spazi e punti.