Andaikan saya mempunyai objek kunci rentetan dan nilai rentetan, dan saya mahu menulisnya sebagai sifat tersuai CSS ke dalam beberapa HTML yang dijana pelayan. Bagaimanakah saya boleh melakukan ini dengan selamat?
Apa yang saya maksudkan dengan keselamatan
Untuk memudahkan, saya akan mengehadkan kekunci untuk membenarkan aksara sahaja dalam kelas [a-zA-Z0-9_-]
.
Daripada membaca spesifikasi CSS dan beberapa ujian peribadi, saya rasa anda boleh membuat banyak kemajuan mendapatkan nilai dengan mengikuti langkah berikut:
{([字符串外部的
di luar rentetan mempunyai pendakap penutup yang sepadan. Jika tidak, buang pasangan nilai kunci ini. 3C
转义 <
的所有实例,以及使用 3E
转义 >
. 3B
对 ;
untuk melarikan diri. Saya membuat langkah di atas berdasarkan spesifikasi sintaks CSS ini
Untuk konteks, sifat ini boleh digunakan oleh gaya yang ditentukan pengguna yang kami sisipkan di tempat lain, tetapi objek yang sama juga digunakan sebagai data templat dalam templat, jadi ia mungkin mengandungi campuran rentetan yang dimaksudkan sebagai kandungan dan rentetan yang dijangkakan sebagai pembolehubah CSS . Saya rasa algoritma di atas mencapai keseimbangan yang baik kerana menjadi sangat mudah tanpa menghadapi risiko membuang terlalu banyak pasangan nilai kunci yang mungkin berguna dalam CSS (malah membenarkan penambahan CSS pada masa hadapan, tetapi saya ingin memastikan saya tidak 't Rindu sesuatu
Berikut ialah beberapa kod JS yang menunjukkan perkara yang saya ingin capai. obj
是有问题的对象,而 preprocessPairs
ialah fungsi yang mengambil objek dan memprosesnya terlebih dahulu, mengalih keluar/memformat semula nilai seperti yang diterangkan dalam langkah di atas.
function generateThemePropertiesTag(obj) { obj = preprocessPairs(obj); return `<style> :root { ${Object.entries(obj).map(([key, value]) => { return `--theme-${key}: ${value};` }).join("\n")} } </style>` }
Jadi bila diberi objek seperti ini
{ "color": "#D3A", "title": "The quick brown fox" }
Saya mahu CSS kelihatan seperti ini:
:root { --theme-color: #D3A; --theme-title: The quick brown fox; }
Walaupun --theme-title
ialah pembolehubah tersuai yang tidak berguna apabila digunakan dalam CSS, ia sebenarnya tidak memecahkan lembaran gaya kerana CSS mengabaikan sifat yang tidak difahaminya.
Kami sebenarnya mungkin hanya menggunakan ungkapan biasa dan beberapa algoritma lain tanpa perlu bergantung pada bahasa tertentu, mudah-mudahan itulah yang anda perlukan.
Dengan mengisytiharkan bahawa kunci objek berada di dalam
[a-zA-Z0-9_-]
kita perlu menghuraikan nilai entah bagaimana.Model Nilai
Jadi kita boleh memecahkannya ke dalam kategori dan melihat perkara yang kita temui (ia mungkin dipermudahkan sedikit untuk kejelasan):
'.*'
(rentetan yang dikelilingi oleh tanda kutip; tamak)".*"
(Rentetan yang disertakan dalam petikan berganda; tamak)[+-]?d+(.d+)?(%|[A-z]+)?
(integer dan perpuluhan, peratusan pilihan atau dengan unit)#[0-9A-f]{3,6}
(warna)[A-z0-9_-]+
(Kata kunci, menamakan warna, "mudah masuk", dll.)([w-]+)([^)]+)
(类似url()
、calc()
fungsi > dsb.)Penapis pertama
Saya boleh bayangkan anda boleh melakukan beberapa penapisan sebelum cuba mengenal pasti corak ini. Mungkin kita memangkas rentetan nilai dahulu. Seperti yang anda nyatakan,
和
>
可以在preprocessPairs()
terlepas pada permulaan fungsi kerana ia tidak akan muncul seperti mana-mana corak yang kami ada di atas. Jika anda tidak mahu koma bertitik yang tidak dilepaskan muncul di mana-mana, anda juga boleh melarikan diri daripadanya.Corak pengecaman
Kita kemudian boleh cuba mengenal pasti corak ini dalam nilai, dan untuk setiap corak kita mungkin perlu menjalankan penapisan sekali lagi. Kami menjangkakan corak ini akan dipisahkan oleh beberapa (atau dua) aksara ruang putih.
Tidak mengapa untuk menyertakan sokongan untuk rentetan berbilang baris, yang merupakan baris baharu yang terlepas.
Tempatan
Kita perlu sedar bahawa kita mempunyai sekurang-kurangnya dua konteks untuk ditapis - HTML dan CSS. Apabila kita berada dalam atribut
元素中包含样式时,输入必须是安全的,同时它必须是有效的 CSS。幸运的是,您没有将 CSS 包含在元素的
style
, jadi ini lebih mudah sedikit.Penapisan berasaskan corak nilai
Jadi mata 1-5 akan menjadi sangat mudah dan kebanyakan nilai akan dilindungi oleh penapisan dan pemangkasan mudah dari hadapan. Dengan beberapa penambahan (tidak tahu apa impak pada prestasi) ia mungkin melakukan semakan tambahan untuk unit, kata kunci, dsb.
Tetapi berbanding mata lain, saya rasa cabaran yang agak besar ialah mata 6. Anda mungkin memutuskan untuk melumpuhkan sahaja
url()
,让您检查函数的输入,因此例如您可能想要转义分号,甚至可能通过微小的调整再次检查函数内的模式例如对于calc()
dalam gaya tersuai ini.Kesimpulan
Secara keseluruhan, ini adalah pendapat saya. Dengan beberapa tweak pada ungkapan biasa ini, ia sepatutnya melengkapkan perkara yang anda sudah lakukan dan memberikan anda sebanyak mungkin fleksibiliti dalam menaip CSS sambil menyelamatkan anda daripada perlu mengubah suai kod anda setiap kali anda mengubah suai ciri CSS.
Contoh
Sila ulas, bincang, kritik dan beritahu saya jika saya terlupa menyentuh topik yang menarik minat anda.
Sumber
Penafian: Saya bukan pengarang, pemilik, pelabur atau penyumbang sumber yang dinyatakan di bawah. Saya kebetulan menggunakannya untuk mendapatkan beberapa maklumat.