Skip to main content

oxvg_optimiser/jobs/
remove_x_m_l_proc_inst.rs

1use oxvg_ast::{
2    element::Element,
3    node::Node,
4    visitor::{Context, PrepareOutcome, Visitor},
5};
6#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize};
8
9#[cfg(feature = "wasm")]
10use tsify::Tsify;
11
12use crate::error::JobsError;
13
14#[cfg_attr(feature = "wasm", derive(Tsify))]
15#[cfg_attr(feature = "napi", napi(object))]
16#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
17#[derive(Debug, Clone)]
18#[cfg_attr(feature = "serde", serde(transparent))]
19/// Removes the xml declaration from the document.
20///
21/// # Correctness
22///
23/// This job may affect clients which expect XML (not SVG) and can't detect the MIME-type
24/// as `image/svg+xml`
25///
26/// # Errors
27///
28/// Never.
29///
30/// If this job produces an error or panic, please raise an [issue](https://github.com/noahbald/oxvg/issues)
31pub struct RemoveXMLProcInst(pub bool);
32
33impl<'input, 'arena> Visitor<'input, 'arena> for RemoveXMLProcInst {
34    type Error = JobsError<'input>;
35
36    fn prepare(
37        &self,
38        _document: &Element<'input, 'arena>,
39        _context: &mut Context<'input, 'arena, '_>,
40    ) -> Result<PrepareOutcome, Self::Error> {
41        Ok(if self.0 {
42            PrepareOutcome::none
43        } else {
44            PrepareOutcome::skip
45        })
46    }
47
48    fn processing_instruction(
49        &self,
50        processing_instruction: &Node<'input, 'arena>,
51        _context: &Context<'input, 'arena, '_>,
52    ) -> Result<(), Self::Error> {
53        if &*processing_instruction.node_name() == "xml" {
54            processing_instruction.remove();
55        }
56        Ok(())
57    }
58}
59
60impl Default for RemoveXMLProcInst {
61    fn default() -> Self {
62        Self(true)
63    }
64}
65
66#[test]
67fn remove_x_m_l_proc_inst() -> anyhow::Result<()> {
68    use crate::test_config;
69
70    insta::assert_snapshot!(test_config(
71        r#"{ "removeXmlProcInst": true }"#,
72        Some(
73            r#"<?xml version="1.0" standalone="no"?>
74<svg xmlns="http://www.w3.org/2000/svg">
75    test
76</svg>"#
77        ),
78    )?);
79
80    // FIXME: Correctly retained, but serializer uses default PI
81    insta::assert_snapshot!(test_config(
82        r#"{ "removeXmlProcInst": true }"#,
83        Some(
84            r#"<?xml-stylesheet href="style.css" type="text/css"?>
85<svg xmlns="http://www.w3.org/2000/svg">
86    test
87</svg>"#
88        ),
89    )?);
90
91    Ok(())
92}