Hitung kekhususan pemilih CSS

8

Hari ini, tugas Anda adalah menulis sebuah program (atau fungsi) yang menerima string dan menghasilkan (atau mengembalikan) empat bilangan bulat.


Memasukkan

String input adalah pemilih CSS3 , dan pada dasarnya dapat berisi karakter Unicode.


Keluaran

Outputnya mewakili kekhususan CSS dari pemilih ini.

  • Angka pertama selalu 0 (karena digunakan untuk gaya inline, dan latihan ini tidak berlaku untuk gaya inline)

  • Angka kedua adalah jumlah id ( #foo) yang ada di pemilih.

  • Angka ketiga adalah jumlah kelas ( .foo), atribut ( [bar]) dan pseudo-kelas yang ada di pemilih.

  • Angka keempat adalah jumlah elemen ( biz) dan elemen semu yang ada dalam pemilih.


Catatan:

  • Selektor universal (*) tidak dihitung di mana pun

  • Elemen semu ::beforedan ::afterdapat juga ditulis dengan satu ":" (notasi warisan)

  • Input dapat menggunakan :not(selector)pseudo-class. Pemilih di dalam tidak masuk hitungan, meskipun mengandung id, kelas, elemen, ...)

  • The "batu bata" dari pemilih dipisahkan oleh combinators (spasi / tab, +, >, ~, ex: body > div+a ~*), tetapi mereka juga dapat terakumulasi (ex: div#foo.bar[baz]:hover::before)

  • Anda juga harus menangani urutan pelarian CSS ( \diikuti oleh 1 hingga 6 angka heksadesimal, diikuti spasi), dan keluar dari karakter khusus ( \diikuti oleh salah satu dari ini !"#$%&'()*+,-./:;<=>?@[\]^`{|}~:) dengan benar. Mereka yang lolos dapat menjadi bagian dari batu bata pemilih (id, kelas, dll).

  • Anda tidak perlu melakukan hal tertentu jika Anda menerima pemilih yang tidak valid atau pemilih CSS4. Jangan repot-repot menerapkan validator pemilih CSS3.

  • Berikut adalah beberapa tautan untuk mempelajari lebih lanjut tentang CSS spesifik:


Contohnya

// Universal

* => 0,0,0,0

// INDO

#id => 0,1,0,0

// Kelas

.class => 0,0,1,0

// Atribut

[foo] => 0,0,1,0
[foo = "bar"] => 0,0,1,0
[foo ~ = "bar"] => 0,0,1,0
[foo ^ = "bar"] => 0,0,1,0
[foo $ = "bar"] => 0,0,1,0
[foo * = "bar"] => 0,0,1,0
[foo | = "bar"] => 0,0,1,0
[foo = bar] => 0,0,1,0
[foo = 'bar'] => 0,0,1,0

(NB: tanda kurung [] dapat berisi apa pun kecuali "]" yang tidak terhapuskan)

// Pseudo-class

: root => 0,0,1,0
: nth-child (n) => 0,0,1,0
: nth-last-child (n) => 0,0,1,0
: n-of-type (n) => 0,0,1,0
: nth-last-of-type (n) => 0,0,1,0
: first-child => 0,0,1,0
: anak terakhir => 0,0,1,0
: first-of-type => 0,0,1,0
: tipe terakhir => 0,0,1,0
: only-child => 0,0,1,0
: only-of-type => 0,0,1,0
: kosong => 0,0,1,0
: tautan => 0,0,1,0
: dikunjungi => 0,0,1,0
: aktif => 0,0,1,0
: arahkan => 0,0,1,0
: fokus => 0,0,1,0
: target => 0,0,1,0
: lang (fr) => 0,0,1,0
: diaktifkan => 0,0,1,0
: dinonaktifkan => 0,0,1,0
: checked => 0,0,1,0
: not (selector) => 0,0,1,0

(NB: kata kunci setelah ":" dapat berupa apa saja kecuali elemen pseudo)


// Elemen

tubuh => 0,0,0,1

// Elemen semu

: before => 0,0,0,1
: setelah => 0,0,0,1
:: before => 0,0,0,1
:: after => 0,0,0,1
:: baris pertama => 0,0,0,1
:: huruf pertama => 0,0,0,1

(NB: tanda kurung () dapat berisi apa pun kecuali ")" yang tidak terhapus

(bersambung)


Jika Anda memiliki pertanyaan atau membutuhkan contoh atau data uji, silakan tanyakan di komentar.

Kode terpendek (dalam byte) menang.

Semoga berhasil!

xem
sumber
3
Silakan tambahkan contoh (idealnya mencakup semua kebiasaan dalam catatan).
Martin Ender
2
Daftar tes terlihat sangat bagus, tetapi beberapa contoh yang melampaui satu 1akan lebih bagus. (Btw, saya pikir ini sebenarnya tantangan yang cukup bagus, tetapi daftar kasus uji yang lengkap sepertinya sangat penting untuk membuatnya bekerja dengan baik.)
Martin Ender

Jawaban:

1

Javascript ES6 453 430 byte

Ini bidikan saya!

a=>(s){var n=z=[],c=[0,0,0,0],e=s.split(/[\s\+\>\~]+/);return e.forEach((s)=>{n=n.concat(s.replace(/\((.*)\)/,"").split(/(?=\[|::|\.)/))}),n.forEach((s)=>{if(0==s.indexOf("::"))return z.push(s);var n=s.split(/(?=:)/);z=z.concat(n[0].split(/(?=[\#])/)),/before|after/.test(n[1])?z.push(":"+n[1]):n[1]&&z.push(n[1])}),z.forEach((s)=>{/^[a-z]+$/gi.test(s)||"::"==s[0]+s[1]?c[3]++:-1!=":.[".indexOf(s[0])?c[2]++:"#"==s[0]&&c[1]++}),c}

@UPDATE kode yang ditingkatkan, sekarang menangani: tidak dan: sebelum /: setelah penyeleksi yang lebih baik, namun belum menguji urutan pelarian CSS.

josegomezr
sumber