Skip to content

Commit 56bf52a

Browse files
committed
feat(templs): add js prop attr and svginfo
1 parent 0b26aba commit 56bf52a

File tree

10 files changed

+260
-42
lines changed

10 files changed

+260
-42
lines changed

Diff for: Cargo.lock

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: TODO.md

+1
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@
1010
- [ ] unify link rendering
1111
- [ ] locale compare for sidebar?!
1212
- [ ] l10n for jsref
13+
- [ ] deal with summary() in templs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use rari_l10n::l10n_json_data;
2+
use rari_templ_func::rari_f;
3+
4+
use crate::error::DocError;
5+
6+
#[rari_f]
7+
pub fn js_property_attributes(
8+
writable: i64,
9+
enumerable: i64,
10+
configurable: i64,
11+
) -> Result<String, DocError> {
12+
let writable = writable != 0;
13+
let enumerable = enumerable != 0;
14+
let configurable = configurable != 0;
15+
let yes = l10n_json_data("Template", "yes", env.locale)?;
16+
let no = l10n_json_data("Template", "no", env.locale)?;
17+
18+
let mut out = String::new();
19+
out.extend([
20+
r#"<table class="standard-table"><thead><tr><th class="header" colspan="2">"#,
21+
l10n_json_data(
22+
"Template",
23+
"js_property_attributes_header_prefix",
24+
env.locale,
25+
)?,
26+
"<code>",
27+
env.title,
28+
"</code>",
29+
l10n_json_data(
30+
"Template",
31+
"js_property_attributes_header_suffix",
32+
env.locale,
33+
)?,
34+
r#"</th></tr></thead><tbody><tr><td>"#,
35+
l10n_json_data("Template", "writable", env.locale)?,
36+
r#"</td><td>"#,
37+
if writable { yes } else { no },
38+
r#"</td></tr><tr><td>"#,
39+
l10n_json_data("Template", "enumerable", env.locale)?,
40+
r#"</td><td>"#,
41+
if enumerable { yes } else { no },
42+
r#"</td></tr><tr><td>"#,
43+
l10n_json_data("Template", "configurable", env.locale)?,
44+
r#"</td><td>"#,
45+
if configurable { yes } else { no },
46+
r#"</td></tr></tbody></table>"#,
47+
]);
48+
Ok(out)
49+
}

Diff for: crates/rari-doc/src/templ/templs/links/svgattr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::templ::api::RariApi;
66
#[rari_f]
77
pub fn svgattr(name: String) -> Result<String, DocError> {
88
let url = format!(
9-
"/{}/docs/Web/SVG/Atrribute/{}",
9+
"/{}/docs/Web/SVG/Attribute/{}",
1010
env.locale.as_url_str(),
1111
name,
1212
);

Diff for: crates/rari-doc/src/templ/templs/links/svgxref.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
use rari_templ_func::rari_f;
2+
use rari_types::locale::Locale;
23
use rari_types::AnyArg;
34

45
use crate::error::DocError;
56
use crate::templ::api::RariApi;
67

78
#[rari_f]
89
pub fn svgxref(element_name: String, _: Option<AnyArg>) -> Result<String, DocError> {
10+
svgxref_internal(&element_name, env.locale)
11+
}
12+
13+
pub fn svgxref_internal(element_name: &str, locale: Locale) -> Result<String, DocError> {
914
let display = format!("<{element_name}>");
1015
let url = format!(
1116
"/{}/docs/Web/SVG/Element/{}",
12-
env.locale.as_url_str(),
17+
locale.as_url_str(),
1318
element_name,
1419
);
1520

Diff for: crates/rari-doc/src/templ/templs/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ pub mod firefox_for_developers;
88
pub mod glossary;
99
pub mod inheritance_diagram;
1010
pub mod inline_labels;
11+
pub mod js_property_attributes;
1112
pub mod links;
1213
pub mod listsubpages;
1314
pub mod previous_menu_next;
1415
pub mod quick_links_with_subpages;
1516
pub mod sidebars;
1617
pub mod specification;
18+
pub mod svginfo;
1719
pub mod web_ext_examples;
1820

1921
use rari_types::globals::deny_warnings;
@@ -47,6 +49,8 @@ pub fn invoke(
4749
"inheritancediagram" => inheritance_diagram::inheritance_diagram_any,
4850
"webextexamples" => web_ext_examples::web_ext_examples_any,
4951
"firefox_for_developers" => firefox_for_developers::firefox_for_developers_any,
52+
"js_property_attributes" => js_property_attributes::js_property_attributes_any,
53+
"svginfo" => svginfo::svginfo_any,
5054

5155
// prev menu next
5256
"previousmenunext" => previous_menu_next::previous_next_menu_any,

Diff for: crates/rari-doc/src/templ/templs/svginfo.rs

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
use rari_l10n::l10n_json_data;
2+
use rari_templ_func::rari_f;
3+
use rari_types::globals::{json_svg_data_lookup, SVGDataDescription};
4+
5+
use super::links::svgxref::svgxref_internal;
6+
use crate::error::DocError;
7+
use crate::templ::api::RariApi;
8+
9+
#[rari_f]
10+
pub fn svginfo() -> Result<String, DocError> {
11+
let name = env
12+
.slug
13+
.rsplit_once('/')
14+
.map(|(_, name)| name)
15+
.ok_or_else(|| DocError::InvalidSlugForX(env.slug.to_string()))?;
16+
let info = json_svg_data_lookup().get(name);
17+
18+
let mut out = String::new();
19+
if let Some(info) = info {
20+
out.extend([
21+
r#"<table class="properties"><tbody><tr><th scope="row">"#,
22+
l10n_json_data("SVG", "categories", env.locale)?,
23+
r#"</th><td>"#,
24+
]);
25+
out.extend(itertools::intersperse(
26+
info.categories.iter().map(|category| {
27+
l10n_json_data("SVG", category, env.locale).unwrap_or(category.as_str())
28+
}),
29+
l10n_json_data("Common", "listSeparator", env.locale).unwrap_or(", "),
30+
));
31+
out.push_str(r#"</td></tr>"#);
32+
33+
let (element_groups, elements): (Vec<String>, Vec<String>) =
34+
info.content.elements.iter().try_fold(
35+
(vec![], vec![]),
36+
|(mut element_groups, mut elements), element| {
37+
if element.contains("&lt;") {
38+
let element_name = element.strip_prefix("&lt;").unwrap_or(element);
39+
let element_name =
40+
element_name.strip_suffix("&gt;").unwrap_or(element_name);
41+
elements.push(svgxref_internal(element_name, env.locale)?)
42+
} else {
43+
let anchor = to_snake_case(element);
44+
let url =
45+
format!("/{}/docs/Web/SVG/Element#{anchor}", env.locale.as_url_str());
46+
let display = l10n_json_data("SVG", element, env.locale).unwrap_or(element);
47+
let link = RariApi::link(&url, None, Some(display), false, None, false)?;
48+
element_groups.push(link);
49+
}
50+
Ok::<_, DocError>((element_groups, elements))
51+
},
52+
)?;
53+
54+
out.extend([
55+
r#"<tr><th scope="row">"#,
56+
l10n_json_data("SVG", "permittedContent", env.locale)?,
57+
r#"</th><td>"#,
58+
match info.content.description {
59+
SVGDataDescription::Copy(ref s) => l10n_json_data("SVG", s, env.locale)?,
60+
SVGDataDescription::L10n(ref map) => map
61+
.get(&env.locale)
62+
.or(map.get(&Default::default()))
63+
.map(|s| s.as_str())
64+
.unwrap_or_default(),
65+
},
66+
]);
67+
68+
if !element_groups.is_empty() {
69+
out.push_str("<br/>");
70+
out.extend(itertools::intersperse(
71+
element_groups.iter().map(|s| s.as_str()),
72+
"<br/>",
73+
))
74+
}
75+
if !elements.is_empty() {
76+
out.push_str("<br/>");
77+
out.extend(itertools::intersperse(
78+
elements.iter().map(|s| s.as_str()),
79+
l10n_json_data("Common", "listSeparator", env.locale).unwrap_or(", "),
80+
))
81+
}
82+
83+
out.push_str(r#"</td></tr></tbody></table>"#);
84+
} else {
85+
return Err(DocError::InvalidTempl(format!("No svginfor for {name}")));
86+
}
87+
88+
Ok(out)
89+
}
90+
91+
fn to_snake_case(s: &str) -> String {
92+
let underscore_count = s
93+
.chars()
94+
.skip(1)
95+
.filter(|&c| c.is_ascii_uppercase())
96+
.count();
97+
let mut result = String::with_capacity(s.len() + underscore_count);
98+
99+
for (i, c) in s.chars().enumerate() {
100+
if c.is_ascii_uppercase() {
101+
if i != 0 {
102+
result.push('_');
103+
}
104+
result.push(c.to_ascii_lowercase());
105+
} else {
106+
result.push(c);
107+
}
108+
}
109+
110+
result
111+
}

Diff for: crates/rari-l10n/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ license.workspace = true
88
[dependencies]
99
rari-types = { path = "../rari-types" }
1010
thiserror = "1"
11+
once_cell = "1"
12+
serde_json = { version = "1", features = ["preserve_order"] }

Diff for: crates/rari-l10n/src/lib.rs

+44-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use std::collections::HashMap;
2+
use std::fs;
23

3-
use rari_types::globals::json_l10n_files;
4+
use once_cell::sync::OnceCell;
5+
use rari_types::globals::content_root;
46
use rari_types::locale::Locale;
57
use thiserror::Error;
68

@@ -31,3 +33,44 @@ pub fn get_for_locale<T>(locale: Locale, lookup: &HashMap<String, T>) -> Option<
3133
None
3234
}
3335
}
36+
pub type JsonL10nFile = HashMap<String, HashMap<String, String>>;
37+
38+
pub static JSON_L10N_FILES: OnceCell<HashMap<String, JsonL10nFile>> = OnceCell::new();
39+
40+
pub fn json_l10n_files() -> &'static HashMap<String, JsonL10nFile> {
41+
JSON_L10N_FILES.get_or_init(|| {
42+
content_root()
43+
.join("jsondata")
44+
.read_dir()
45+
.expect("unable to read jsondata dir")
46+
.filter_map(|f| {
47+
if let Ok(f) = f {
48+
if f.path().is_file()
49+
&& f.path()
50+
.extension()
51+
.map_or(false, |ext| ext.eq_ignore_ascii_case("json"))
52+
&& f.path()
53+
.file_stem()
54+
.and_then(|s| s.to_str())
55+
.map_or(false, |s| s.starts_with("L10n-"))
56+
{
57+
return Some(f.path());
58+
}
59+
}
60+
None
61+
})
62+
.map(|f| {
63+
let typ = f
64+
.file_stem()
65+
.and_then(|s| s.to_str())
66+
.unwrap_or_default()
67+
.strip_prefix("L10n-")
68+
.unwrap_or_default();
69+
let json_str = fs::read_to_string(&f).expect("unable to read l10n json");
70+
let l10n_json: JsonL10nFile =
71+
serde_json::from_str(&json_str).expect("unable to parse l10n json");
72+
(typ.into(), l10n_json)
73+
})
74+
.collect()
75+
})
76+
}

Diff for: crates/rari-types/src/globals.rs

+40-39
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use once_cell::sync::{Lazy, OnceCell};
66
use serde::Deserialize;
77

88
use crate::error::EnvError;
9+
use crate::locale::Locale;
910
use crate::settings::Settings;
1011
use crate::{HistoryEntry, Popularities};
1112

@@ -83,47 +84,47 @@ pub fn json_spec_data_lookup() -> &'static JsonSpecDataLookup {
8384
})
8485
}
8586

86-
pub type JsonL10nFile = HashMap<String, HashMap<String, String>>;
87-
88-
pub static JSON_L10N_FILES: OnceCell<HashMap<String, JsonL10nFile>> = OnceCell::new();
89-
90-
pub fn json_l10n_files() -> &'static HashMap<String, JsonL10nFile> {
91-
JSON_L10N_FILES.get_or_init(|| {
92-
content_root()
93-
.join("jsondata")
94-
.read_dir()
95-
.expect("unable to read jsondata dir")
96-
.filter_map(|f| {
97-
if let Ok(f) = f {
98-
if f.path().is_file()
99-
&& f.path()
100-
.extension()
101-
.map_or(false, |ext| ext.eq_ignore_ascii_case("json"))
102-
&& f.path()
103-
.file_stem()
104-
.and_then(|s| s.to_str())
105-
.map_or(false, |s| s.starts_with("L10n-"))
106-
{
107-
return Some(f.path());
108-
}
109-
}
110-
None
111-
})
112-
.map(|f| {
113-
let typ = f
114-
.file_stem()
115-
.and_then(|s| s.to_str())
116-
.unwrap_or_default()
117-
.strip_prefix("L10n-")
118-
.unwrap_or_default();
119-
let json_str = fs::read_to_string(&f).expect("unable to read l10n json");
120-
let l10n_json: JsonL10nFile =
121-
serde_json::from_str(&json_str).expect("unable to parse l10n json");
122-
(typ.into(), l10n_json)
123-
})
124-
.collect()
87+
#[derive(Debug, Deserialize)]
88+
#[serde(untagged)]
89+
pub enum SVGDataDescription {
90+
Copy(String),
91+
L10n(HashMap<Locale, String>),
92+
}
93+
94+
#[derive(Debug, Deserialize)]
95+
pub struct SVGDataContent {
96+
pub description: SVGDataDescription,
97+
#[serde(default)]
98+
pub elements: Vec<String>,
99+
}
100+
101+
#[derive(Debug, Deserialize)]
102+
pub struct SVGData {
103+
pub categories: Vec<String>,
104+
pub content: SVGDataContent,
105+
pub attributes: Vec<String>,
106+
pub interfaces: Vec<String>,
107+
}
108+
109+
#[derive(Debug, Deserialize)]
110+
struct SVGDataContainer {
111+
elements: HashMap<String, SVGData>,
112+
}
113+
114+
pub type JsonSVGDataLookup = HashMap<String, SVGData>;
115+
116+
pub static JSON_SVG_DATA_FILE: OnceCell<JsonSVGDataLookup> = OnceCell::new();
117+
118+
pub fn json_svg_data_lookup() -> &'static JsonSVGDataLookup {
119+
JSON_SVG_DATA_FILE.get_or_init(|| {
120+
let json_str = fs::read_to_string(content_root().join("jsondata/SVGData.json"))
121+
.expect("unable to read SVGData.json");
122+
let data: SVGDataContainer =
123+
serde_json::from_str(&json_str).expect("unabeld to parse SVGData.json");
124+
data.elements
125125
})
126126
}
127+
127128
pub static GIT_HISTORY: Lazy<HashMap<PathBuf, HistoryEntry>> = Lazy::new(|| {
128129
let f = content_root().join("en-US").join("_history.json");
129130
if let Ok(json_str) = fs::read_to_string(f) {

0 commit comments

Comments
 (0)