html_languageservice/language_facts/
data_manager.rs1use lazy_static::lazy_static;
2use serde_json::{json, Value};
3
4use super::{
5 data_provider::{HTMLDataProvider, IHTMLDataProvider},
6 web_custom_data::HTML_DATA,
7};
8
9pub struct HTMLDataManager {
13 data_providers: Vec<Box<dyn IHTMLDataProvider>>,
14}
15
16impl HTMLDataManager {
17 pub fn new(
18 use_default_data_provider: bool,
19 custom_data_providers: Option<Vec<Box<dyn IHTMLDataProvider>>>,
20 ) -> HTMLDataManager {
21 let mut data_manager = HTMLDataManager {
22 data_providers: vec![],
23 };
24 data_manager.set_data_providers(
25 use_default_data_provider,
26 custom_data_providers.unwrap_or(vec![]),
27 );
28 data_manager
29 }
30
31 pub fn set_data_providers(
33 &mut self,
34 built_in: bool,
35 mut providers: Vec<Box<dyn IHTMLDataProvider>>,
36 ) {
37 self.data_providers.clear();
38 if built_in {
39 let data = serde_json::from_str(HTML_DATA).unwrap();
40 self.data_providers
41 .push(Box::new(HTMLDataProvider::new("html5".to_string(), data)));
42 }
43 self.data_providers.append(&mut providers);
44 }
45
46 pub fn get_data_providers(&self) -> &Vec<Box<dyn IHTMLDataProvider>> {
47 &self.data_providers
48 }
49
50 pub fn is_void_element(&self, tag: &str, void_elements: &Vec<String>) -> bool {
54 void_elements.contains(&tag.to_string())
55 }
56
57 pub fn get_void_elements(&self, language_id: &str) -> Vec<String> {
59 let mut void_tags: Vec<String> = vec![];
60 for provider in &self.data_providers {
61 if provider.is_applicable(language_id) {
62 provider
63 .provide_tags()
64 .iter()
65 .filter(|tag| tag.void.is_some_and(|v| v))
66 .for_each(|tag| void_tags.push(tag.name.clone()))
67 }
68 }
69 void_tags.sort();
70 void_tags
71 }
72
73 pub fn is_path_attribute(&self, tag: &str, attr: &str) -> bool {
75 if ["src", "href"].contains(&attr) {
76 return true;
77 }
78 let value = PATH_TAG_AND_ATTR.as_object().unwrap().get(tag);
79 if let Some(value) = value {
80 if value.is_array() {
81 value
82 .as_array()
83 .unwrap()
84 .contains(&Value::String(attr.to_string()))
85 } else {
86 value.as_str().unwrap() == attr
87 }
88 } else {
89 false
90 }
91 }
92}
93
94impl Default for HTMLDataManager {
95 fn default() -> Self {
96 HTMLDataManager::new(true, None)
97 }
98}
99
100lazy_static! {
101 static ref PATH_TAG_AND_ATTR: Value = json!({
102 "a": "href",
104 "area": "href",
105 "body": "background",
106 "blockquote": "cite",
107 "del": "cite",
108 "form": "action",
109 "frame": ["src", "longdesc"],
110 "img": ["src", "longdesc"],
111 "ins": "cite",
112 "link": "href",
113 "object": "data",
114 "q": "cite",
115 "script": "src",
116 "audio": "src",
118 "button": "formaction",
119 "command": "icon",
120 "embed": "src",
121 "html": "manifest",
122 "input": ["src", "formaction"],
123 "source": "src",
124 "track": "src",
125 "video": ["src", "poster"]
126 });
127}