2012-05-17 14 views
6

Mam analizowany danego pliku CSS/string do obiektu JSON tak:Zamówienie na podstawie Selector Specyfika

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

co chcę teraz zrobić, to zmienić kolejność ich podstawie swoistości. W takim przypadku obiekt #header h1 powinien znajdować się po obiekcie h1 w obiekcie JSON, ponieważ jest to sposób jego zastosowania w przeglądarce.

Jak mogę to zrobić? Czy istnieją do tego jakieś biblioteki? Lub przydatne biblioteki, które mogą pomóc w tym?

Do tego celu mogę użyć zarówno JavaScript/jQuery, jak i PHP. Szukam porady dotyczącej wdrożenia i mam nadzieję, że już to zrobiono!

+0

Dla kodu JavaScript ustawiam tutaj punkt początkowy w pseudokodzie: [Sortowanie zestawu selektorów CSS na podstawie specyficzności] (http://stackoverflow.com/questions/5158631/sorting-a-set- of-css-selectors-on-the-basis-of-specificity), ale nie ma jeszcze implementacji. Jeśli jeszcze nie napisałeś biblioteki JS, aby to zrobić, przypuszczam, że mógłbym podjąć wyzwanie! – BoltClock

Odpowiedz

3

Krótkie odpowiedzi:

czy są jakieś istniejące biblioteki dla tego?

Nie, nikt, o czym wiem, nie robi tego za ciebie "od razu po wyjęciu z pudełka".

Lub przydatne biblioteki pomocne w tym?

Tak, jest json_decode i 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); 

Jak to przykład kodu pokazuje, że tylko wyjaśnia w jaki sposób obliczyć swoistość w komentarzu i nie zawiera kodu. To dlatego, że nie mam tego kodu pod ręką, ale umieściłem tam specyfikację jak to się robi (przynajmniej dla CSS 3).

Jeśli szukasz parsera selektora CSS, wiem o XDOM (ponieważ go napisałem). Jest dostępny na github: https://github.com/hakre/XDOM - Jest to 100-procentowy parser selektora CSS zgodny z CSS.

Według mojej najlepszej wiedzy jest to większość tego, co otrzymujesz od dzisiaj w zakresie gotowych rozwiązań. Wszystkie inne parsery selektora CSS, które znam, nie są w pełni zgodne ze standardem CSS 3, ponieważ nie są zgodne ze specyfikacją W3C. Co może być dla Ciebie dobre: ​​Jeśli nie potrzebujesz ścisłej kompatybilności CSS3, możesz znaleźć inne fragmenty kodu, które pasują już do twoich potrzeb.

+0

Ok udało mi się spleść coś razem znalazłem online. Jak to wygląda dla ciebie? https://gist.github.com/2719627 - Myślę, że działa zgodnie ze wszystkimi regułami, które wymieniłeś dla specyfiki. – Abs

+0

@Abs: Mogę to przejrzeć, zobaczyć mój widelec: https://gist.github.com/2724460 - Zostawiłem tam kilka komentarzy i możesz zobaczyć kilka zmian, które mogą być przydatne.Generalnie musisz dodać testy do tej funkcji, inaczej powiedziałbym, że wygląda bardzo krucho. Niektóre wartości testowe powinny sprawić, że będzie działał znacznie lepiej. – hakre

+0

dziękuję za obejrzenie, zwrot jest w niewłaściwym miejscu! Napraw to! Również zresetowałem wynik, ponieważ używam tej funkcji z jednym zestawem selektorów naraz, myślę, że powinno być dobrze. – Abs

0

W rzeczywistości istnieje standardowy algorytm do zamawiania według specyfiki, myślę, że warto na to spojrzeć.

CSS Specificity

może być również użyteczny jakiś heurystycznego wzoru, na przykład sprawdzić, czy jest wiodącym # lub policzyć ilość spacji i kropek.