Skip to main content

atmos/os_lib/web_engine/
selection_style.rs

1//! CSS `::selection` 疑似要素のスタイル解決モジュール。
2//!
3//! W3C CSS Pseudo-Elements Module Level 4 §3 に準拠し、
4//! `x-selection-background-color`, `x-selection-background`, `x-selection-color`
5//! から選択テキストの背景色・文字色を解決する。
6
7use alloc::collections::BTreeMap;
8use alloc::string::String;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub struct SelectionStyle {
12    /// 選択時背景色 (24bit RGB: 0x00RRGGBB)
13    pub bg_color: Option<u32>,
14    /// 選択時背景アルファ (0x00..=0xFF)
15    pub bg_alpha: u8,
16    /// 選択時テキスト色 (ARGB)
17    pub text_color: Option<u32>,
18}
19
20impl Default for SelectionStyle {
21    fn default() -> Self {
22        Self {
23            bg_color: Some(0x003399FF), // 既定のブラウザハイライト青
24            bg_alpha: 0x60,             // 半透明
25            text_color: None,
26        }
27    }
28}
29
30/// 指定スタイルマップから SelectionStyle を解決する。
31pub fn resolve_selection_style<F>(
32    values: &BTreeMap<String, String>,
33    mut color_parser: F,
34) -> SelectionStyle
35where
36    F: FnMut(&str) -> Option<u32>,
37{
38    let mut style = SelectionStyle::default();
39
40    // 背景色の解決(background-color または background)
41    let bg_val = values
42        .get("x-selection-background-color")
43        .or_else(|| values.get("x-selection-background"));
44
45    if let Some(bg_str) = bg_val {
46        if let Some(c) = color_parser(bg_str.trim()) {
47            style.bg_color = Some(c & 0x00FF_FFFF);
48            let alpha = ((c >> 24) & 0xFF) as u8;
49            style.bg_alpha = if alpha == 0 { 0x60 } else { alpha };
50        }
51    }
52
53    // 文字色の解決
54    if let Some(c_str) = values.get("x-selection-color") {
55        if let Some(c) = color_parser(c_str.trim()) {
56            style.text_color = Some(c);
57        }
58    }
59
60    style
61}