Repository: servo/servo
File: components/script/dom/svg/svgsvgelement.rs (Rust)

Code before:
        prefix: Option<Prefix>,
        document: &Document,
        proto: Option<HandleObject>,
        can_gc: CanGc,
    ) -> DomRoot<SVGSVGElement> {
        Node::reflect_node_with_proto(
            Box::new(SVGSVGElement::new_inherited(local_name, prefix, document)),
            document,
            proto,
            can_gc,
        )
    }

    pub(crate) fn serialize_and_cache_subtree(&self) {
        let cloned_nodes = self.process_use_elements();

        let Ok(xml_source) = self
            .upcast::<Node>()
            .xml_serialize(TraversalScope::IncludeNode)
        else {
            self.cleanup_cloned_nodes(&cloned_nodes);
            *self.cached_serialized_data_url.borrow_mut() = Some(Err(()));
            return;
        };

        self.cleanup_cloned_nodes(&cloned_nodes);
        let xml_source: String = xml_source.into();
        let base64_encoded_source = base64::engine::general_purpose::STANDARD.encode(xml_source);
        let data_url = format!("data:image/svg+xml;base64,{}", base64_encoded_source);
        match ServoUrl::parse(&data_url) {
            Ok(url) => *self.cached_serialized_data_url.borrow_mut() = Some(Ok(url)),
            Err(error) => error!("Unable to parse serialized SVG data url: {error}"),
        };
    }

    fn process_use_elements(&self) -> Vec<DomRoot<Node>> {
        let mut cloned_nodes = Vec::new();
        let root_node = self.upcast::<Node>();

        for node in root_node.traverse_preorder(crate::dom::node::ShadowIncluding::No) {
            if let Some(element) = node.downcast::<Element>() {
                if element.local_name() == &local_name!("use") {
                    if let Some(cloned) = self.process_single_use_element(element) {
                        cloned_nodes.push(cloned);
                    }
                }
            }
        }

        cloned_nodes
    }

Review comment (suggestion):
One slight improvement:
```rust
let cloned_nodes = self.process_use_elements();
let serialize_result = self.upcast::<Node>().xml_serialize(TraversalScope::Include);
self.cleanup_clones(&cloned_nodes);

let Ok(xml_source) = serialize_result else {
    ...
};
```

Code after:
        prefix: Option<Prefix>,
        document: &Document,
        proto: Option<HandleObject>,
        can_gc: CanGc,
    ) -> DomRoot<SVGSVGElement> {
        Node::reflect_node_with_proto(
            Box::new(SVGSVGElement::new_inherited(local_name, prefix, document)),
            document,
            proto,
            can_gc,
        )
    }

    pub(crate) fn serialize_and_cache_subtree(&self) {
        let can_gc = CanGc::note();
        let cloned_nodes = self.process_use_elements(can_gc);

        let serialize_result = self
            .upcast::<Node>()
            .xml_serialize(TraversalScope::IncludeNode);

        self.cleanup_cloned_nodes(&cloned_nodes, can_gc);

        let Ok(xml_source) = serialize_result else {
            *self.cached_serialized_data_url.borrow_mut() = Some(Err(()));
            return;
        };

        let xml_source: String = xml_source.into();
        let base64_encoded_source = base64::engine::general_purpose::STANDARD.encode(xml_source);
        let data_url = format!("data:image/svg+xml;base64,{}", base64_encoded_source);
        match ServoUrl::parse(&data_url) {
            Ok(url) => *self.cached_serialized_data_url.borrow_mut() = Some(Ok(url)),
            Err(error) => error!("Unable to parse serialized SVG data url: {error}"),
        };
    }

    fn process_use_elements(&self, can_gc: CanGc) -> Vec<DomRoot<Node>> {
        let mut cloned_nodes = Vec::new();
        let root_node = self.upcast::<Node>();

        for node in root_node.traverse_preorder(ShadowIncluding::No) {
            if let Some(element) = node.downcast::<Element>() {
                if element.local_name() == &local_name!("use") {
                    if let Some(cloned) = self.process_single_use_element(element, can_gc) {
                        cloned_nodes.push(cloned);
                    }
                }
            }
        }