English

検査しない値

いくつかの書き方は検査を受けずにブラウザへ渡ります。どの書き方にも決まった名前があるので、その名前で検索すれば、検査なしの値を使う箇所をすべて見つけられます。

use hypersig::html::{Stylesheet, div};
use hypersig::style::Style;
use hypersig::style::value::raw;
use hypersig::{Page, Signals};
use serde::{Deserialize, Serialize};

#[derive(Signals, Serialize, Deserialize)]
struct Legacy {
    open: bool,
}

// A value with several parts goes through `raw`, which the browser checks.
let card = Style::new()
    .margin(raw("0 auto"))
    .box_shadow(raw("0 1px 3px rgb(0 0 0 / 0.1)"))
    .width(raw("calc(100% - 2rem)"));

// An existing stylesheet keeps working. `class` fails to compile unless the
// CSS has a selector for the class.
const LEGACY: Stylesheet = Stylesheet::new(".panel { padding: 1rem } .open { display: block }");
const PANEL: hypersig::html::Class = LEGACY.class("panel");
const OPEN: hypersig::html::Class = LEGACY.class("open");

let html = Page::new("Legacy", Legacy { open: false })
    .style(LEGACY)
    .child(div().css(card).class(PANEL).class_when(OPEN, Legacy::open()))
    .render();
assert!(html.contains("panel"));
  • raw(css) は値を渡されたとおりに書きます。margin: 0 auto、影、calc() のように、プロパティの生成された型に含まれない書き方に使います。ブラウザが受け付けない値なら、ブラウザはその宣言を無視します。;、{、}、< は宣言やルールを終わらせたり <style> 要素を閉じたりするので、raw はこれらを受け取るとパニックします。
  • Stylesheet::new(css) は手元にある CSS から Stylesheet を作り、Page::style でそれをページに追加します。Stylesheet::class("name") は、その CSS にクラスのセレクタがあるかをコンパイル時に確かめます。Class::new はその確認をせずにクラス名を指定します。
  • El::bind_style と El::bind_token はシグナルから作る文字列の式でプロパティを設定します。この式は検査されません。