loro_internal/container/richtext/
config.rs

1use fxhash::FxHashMap;
2use loro_common::InternalString;
3
4use super::{ExpandType, TextStyleInfoFlag};
5
6#[derive(Debug, Default, Clone)]
7pub struct StyleConfigMap {
8    pub(crate) map: FxHashMap<InternalString, StyleConfig>,
9    pub(crate) default_style: Option<StyleConfig>,
10}
11
12impl StyleConfigMap {
13    pub fn new() -> Self {
14        Self {
15            map: FxHashMap::default(),
16            default_style: None,
17        }
18    }
19
20    pub fn insert(&mut self, key: InternalString, value: StyleConfig) {
21        if key.contains(':') {
22            panic!("style key should not contain ':'");
23        }
24
25        self.map.insert(key, value);
26    }
27
28    pub fn get(&self, key: &InternalString) -> Option<StyleConfig> {
29        self.map.get(key).copied().or(self.default_style)
30    }
31
32    pub fn get_style_flag(&self, key: &InternalString) -> Option<TextStyleInfoFlag> {
33        self._get_style_flag(key, false)
34    }
35
36    pub fn get_style_flag_for_unmark(&self, key: &InternalString) -> Option<TextStyleInfoFlag> {
37        self._get_style_flag(key, true)
38    }
39
40    fn _get_style_flag(&self, key: &InternalString, is_del: bool) -> Option<TextStyleInfoFlag> {
41        let f = |x: StyleConfig| {
42            TextStyleInfoFlag::new(if is_del { x.expand.reverse() } else { x.expand })
43        };
44        if let Some(index) = key.find(':') {
45            let key = key[..index].into();
46            self.map.get(&key).copied().or(self.default_style).map(f)
47        } else {
48            self.map.get(key).copied().or(self.default_style).map(f)
49        }
50    }
51
52    pub fn default_rich_text_config() -> Self {
53        let mut map = Self {
54            map: FxHashMap::default(),
55            default_style: None,
56        };
57
58        map.map.insert(
59            "bold".into(),
60            StyleConfig {
61                expand: ExpandType::After,
62            },
63        );
64
65        map.map.insert(
66            "italic".into(),
67            StyleConfig {
68                expand: ExpandType::After,
69            },
70        );
71
72        map.map.insert(
73            "underline".into(),
74            StyleConfig {
75                expand: ExpandType::After,
76            },
77        );
78
79        map.map.insert(
80            "link".into(),
81            StyleConfig {
82                expand: ExpandType::None,
83            },
84        );
85
86        map.map.insert(
87            "highlight".into(),
88            StyleConfig {
89                expand: ExpandType::None,
90            },
91        );
92
93        map.map.insert(
94            "comment".into(),
95            StyleConfig {
96                expand: ExpandType::None,
97            },
98        );
99
100        map.map.insert(
101            "code".into(),
102            StyleConfig {
103                expand: ExpandType::None,
104            },
105        );
106
107        map
108    }
109}
110
111#[derive(Debug, Clone, Copy, PartialEq, Eq)]
112pub struct StyleConfig {
113    pub expand: ExpandType,
114}
115
116impl StyleConfig {
117    pub fn new() -> Self {
118        Self {
119            expand: ExpandType::None,
120        }
121    }
122
123    pub fn expand(mut self, expand: ExpandType) -> Self {
124        self.expand = expand;
125        self
126    }
127}
128
129impl Default for StyleConfig {
130    fn default() -> Self {
131        Self::new()
132    }
133}