html: Add support for mathematical messages
According to MSC2191 / Matrix 1.11
This commit is contained in:
parent
ba76e0ee3a
commit
002fe2fb3d
@ -1,5 +1,13 @@
|
|||||||
# [unreleased]
|
# [unreleased]
|
||||||
|
|
||||||
|
Breaking Changes:
|
||||||
|
|
||||||
|
- `MatrixElement::Div` is now a newtype variant.
|
||||||
|
|
||||||
|
Improvements:
|
||||||
|
|
||||||
|
- Add support for mathematical messages, according to MSC2191 / Matrix 1.11
|
||||||
|
|
||||||
# 0.2.0
|
# 0.2.0
|
||||||
|
|
||||||
Breaking Changes:
|
Breaking Changes:
|
||||||
|
@ -152,7 +152,7 @@ pub enum MatrixElement {
|
|||||||
/// [`<div>`], a content division element.
|
/// [`<div>`], a content division element.
|
||||||
///
|
///
|
||||||
/// [`<div>`]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div
|
/// [`<div>`]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div
|
||||||
Div,
|
Div(DivData),
|
||||||
|
|
||||||
/// [`<table>`], a table element.
|
/// [`<table>`], a table element.
|
||||||
///
|
///
|
||||||
@ -268,7 +268,10 @@ impl MatrixElement {
|
|||||||
}
|
}
|
||||||
b"hr" => (Self::Hr, attrs.clone()),
|
b"hr" => (Self::Hr, attrs.clone()),
|
||||||
b"br" => (Self::Br, attrs.clone()),
|
b"br" => (Self::Br, attrs.clone()),
|
||||||
b"div" => (Self::Div, attrs.clone()),
|
b"div" => {
|
||||||
|
let (data, attrs) = DivData::parse(attrs);
|
||||||
|
(Self::Div(data), attrs)
|
||||||
|
}
|
||||||
b"table" => (Self::Table, attrs.clone()),
|
b"table" => (Self::Table, attrs.clone()),
|
||||||
b"thead" => (Self::Thead, attrs.clone()),
|
b"thead" => (Self::Thead, attrs.clone()),
|
||||||
b"tbody" => (Self::Tbody, attrs.clone()),
|
b"tbody" => (Self::Tbody, attrs.clone()),
|
||||||
@ -599,12 +602,23 @@ pub struct SpanData {
|
|||||||
///
|
///
|
||||||
/// [spoiler message]: https://spec.matrix.org/latest/client-server-api/#spoiler-messages
|
/// [spoiler message]: https://spec.matrix.org/latest/client-server-api/#spoiler-messages
|
||||||
pub spoiler: Option<StrTendril>,
|
pub spoiler: Option<StrTendril>,
|
||||||
|
|
||||||
|
/// `data-mx-maths`, an inline Matrix [mathematical message].
|
||||||
|
///
|
||||||
|
/// The value is the mathematical notation in [LaTeX] format.
|
||||||
|
///
|
||||||
|
/// If this attribute is present, the content of the span is the fallback representation of the
|
||||||
|
/// mathematical notation.
|
||||||
|
///
|
||||||
|
/// [mathematical message]: https://spec.matrix.org/latest/client-server-api/#mathematical-messages
|
||||||
|
/// [LaTeX]: https://www.latex-project.org/
|
||||||
|
pub maths: Option<StrTendril>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SpanData {
|
impl SpanData {
|
||||||
/// Construct an empty `SpanData`.
|
/// Construct an empty `SpanData`.
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self { bg_color: None, color: None, spoiler: None }
|
Self { bg_color: None, color: None, spoiler: None, maths: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse the given attributes to construct a new `SpanData`.
|
/// Parse the given attributes to construct a new `SpanData`.
|
||||||
@ -629,6 +643,9 @@ impl SpanData {
|
|||||||
b"data-mx-spoiler" => {
|
b"data-mx-spoiler" => {
|
||||||
data.spoiler = Some(attr.value.clone());
|
data.spoiler = Some(attr.value.clone());
|
||||||
}
|
}
|
||||||
|
b"data-mx-maths" => {
|
||||||
|
data.maths = Some(attr.value.clone());
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
remaining_attrs.insert(attr.clone());
|
remaining_attrs.insert(attr.clone());
|
||||||
}
|
}
|
||||||
@ -722,3 +739,53 @@ impl ImageData {
|
|||||||
(data, remaining_attrs)
|
(data, remaining_attrs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The supported data of a `<div>` HTML element.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
#[non_exhaustive]
|
||||||
|
pub struct DivData {
|
||||||
|
/// `data-mx-maths`, a Matrix [mathematical message] block.
|
||||||
|
///
|
||||||
|
/// The value is the mathematical notation in [LaTeX] format.
|
||||||
|
///
|
||||||
|
/// If this attribute is present, the content of the div is the fallback representation of the
|
||||||
|
/// mathematical notation.
|
||||||
|
///
|
||||||
|
/// [mathematical message]: https://spec.matrix.org/latest/client-server-api/#mathematical-messages
|
||||||
|
/// [LaTeX]: https://www.latex-project.org/
|
||||||
|
pub maths: Option<StrTendril>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DivData {
|
||||||
|
/// Construct an empty `DivData`.
|
||||||
|
fn new() -> Self {
|
||||||
|
Self { maths: None }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse the given attributes to construct a new `SpanData`.
|
||||||
|
///
|
||||||
|
/// Returns a tuple containing the constructed data and the remaining unsupported attributes.
|
||||||
|
#[allow(clippy::mutable_key_type)]
|
||||||
|
fn parse(attrs: &BTreeSet<Attribute>) -> (Self, BTreeSet<Attribute>) {
|
||||||
|
let mut data = Self::new();
|
||||||
|
let mut remaining_attrs = BTreeSet::new();
|
||||||
|
|
||||||
|
for attr in attrs {
|
||||||
|
if attr.name.ns != ns!() {
|
||||||
|
remaining_attrs.insert(attr.clone());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
match attr.name.local.as_bytes() {
|
||||||
|
b"data-mx-maths" => {
|
||||||
|
data.maths = Some(attr.value.clone());
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
remaining_attrs.insert(attr.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(data, remaining_attrs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -28,14 +28,16 @@ static ALLOWED_ATTRIBUTES_STRICT: Map<&str, &Set<&str>> = phf_map! {
|
|||||||
"img" => &ALLOWED_ATTRIBUTES_IMG_STRICT,
|
"img" => &ALLOWED_ATTRIBUTES_IMG_STRICT,
|
||||||
"ol" => &ALLOWED_ATTRIBUTES_OL_STRICT,
|
"ol" => &ALLOWED_ATTRIBUTES_OL_STRICT,
|
||||||
"code" => &ALLOWED_ATTRIBUTES_CODE_STRICT,
|
"code" => &ALLOWED_ATTRIBUTES_CODE_STRICT,
|
||||||
|
"div" => &ALLOWED_ATTRIBUTES_DIV_STRICT,
|
||||||
};
|
};
|
||||||
static ALLOWED_ATTRIBUTES_SPAN_STRICT: Set<&str> =
|
static ALLOWED_ATTRIBUTES_SPAN_STRICT: Set<&str> =
|
||||||
phf_set! { "data-mx-bg-color", "data-mx-color", "data-mx-spoiler" };
|
phf_set! { "data-mx-bg-color", "data-mx-color", "data-mx-spoiler", "data-mx-maths" };
|
||||||
static ALLOWED_ATTRIBUTES_A_STRICT: Set<&str> = phf_set! { "name", "target", "href" };
|
static ALLOWED_ATTRIBUTES_A_STRICT: Set<&str> = phf_set! { "name", "target", "href" };
|
||||||
static ALLOWED_ATTRIBUTES_IMG_STRICT: Set<&str> =
|
static ALLOWED_ATTRIBUTES_IMG_STRICT: Set<&str> =
|
||||||
phf_set! { "width", "height", "alt", "title", "src" };
|
phf_set! { "width", "height", "alt", "title", "src" };
|
||||||
static ALLOWED_ATTRIBUTES_OL_STRICT: Set<&str> = phf_set! { "start" };
|
static ALLOWED_ATTRIBUTES_OL_STRICT: Set<&str> = phf_set! { "start" };
|
||||||
static ALLOWED_ATTRIBUTES_CODE_STRICT: Set<&str> = phf_set! { "class" };
|
static ALLOWED_ATTRIBUTES_CODE_STRICT: Set<&str> = phf_set! { "class" };
|
||||||
|
static ALLOWED_ATTRIBUTES_DIV_STRICT: Set<&str> = phf_set! { "data-mx-maths" };
|
||||||
|
|
||||||
/// Attributes that were previously allowed on HTML elements according to the Matrix specification,
|
/// Attributes that were previously allowed on HTML elements according to the Matrix specification,
|
||||||
/// with their replacement.
|
/// with their replacement.
|
||||||
|
@ -26,7 +26,8 @@ fn elements() {
|
|||||||
// `<div>` element.
|
// `<div>` element.
|
||||||
let div_node = html_children.next().unwrap();
|
let div_node = html_children.next().unwrap();
|
||||||
let div_element = div_node.as_element().unwrap().to_matrix();
|
let div_element = div_node.as_element().unwrap().to_matrix();
|
||||||
assert_matches!(div_element.element, MatrixElement::Div);
|
assert_matches!(div_element.element, MatrixElement::Div(div));
|
||||||
|
assert_eq!(div.maths, None);
|
||||||
// The `class` attribute is not supported.
|
// The `class` attribute is not supported.
|
||||||
assert_eq!(div_element.attrs.len(), 1);
|
assert_eq!(div_element.attrs.len(), 1);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user