Repository: servo/servo
File: components/script/dom/html/htmlelement.rs (Rust)

Code before:
        if !node.is::<Text>() {
            return;
        }

        // Step 1: Let next be node's next sibling.
        let next = match node.GetNextSibling() {
            Some(next) => next,
            None => return,
        };

        // Step 2: If next is not a Text node, then return.
        if !next.is::<Text>() {
            return;
        }
        // Step 3: Replace data with node, node's data's length, 0, and next's data.
        let node_chars = node.downcast::<CharacterData>().expect("Node is Text");
        let next_chars = next.downcast::<CharacterData>().expect("Next node is Text");
        node_chars
            .ReplaceData(node_chars.Length(), 0, next_chars.Data())
            .expect("Got chars from Text");

        // Step 4:Remove next.
        next.remove_self(can_gc);
    }

    pub(crate) fn is_affected_by_legacy_background_presentational_hint(&self) -> bool {
        let element = self.upcast::<Element>();

        *element.namespace() == ns!(html) &&
            matches!(
                *element.local_name(),
                local_name!("body") |
                    local_name!("table") |
                    local_name!("thead") |
                    local_name!("tbody") |
                    local_name!("tfoot") |
                    local_name!("tr") |
                    local_name!("td") |
                    local_name!("th")
            )
    }
}

impl VirtualMethods for HTMLElement {
    fn super_type(&self) -> Option<&dyn VirtualMethods> {
        Some(self.as_element() as &dyn VirtualMethods)
    }

    fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) {
        self.super_type()
            .unwrap()

Review comment (refactor):
Nit: move this into element so you can dedupe the implementation in `Element::synthesize_presentational_hints_for_legacy_attributes`

Code after:
    /// <https://html.spec.whatwg.org/multipage/#merge-with-the-next-text-node>
    fn merge_with_the_next_text_node(node: DomRoot<Node>, can_gc: CanGc) {
        // Make sure node is a Text node
        if !node.is::<Text>() {
            return;
        }

        // Step 1: Let next be node's next sibling.
        let next = match node.GetNextSibling() {
            Some(next) => next,
            None => return,
        };

        // Step 2: If next is not a Text node, then return.
        if !next.is::<Text>() {
            return;
        }
        // Step 3: Replace data with node, node's data's length, 0, and next's data.
        let node_chars = node.downcast::<CharacterData>().expect("Node is Text");
        let next_chars = next.downcast::<CharacterData>().expect("Next node is Text");
        node_chars
            .ReplaceData(node_chars.Length(), 0, next_chars.Data())
            .expect("Got chars from Text");

        // Step 4:Remove next.
        next.remove_self(can_gc);
    }
}

impl VirtualMethods for HTMLElement {
    fn super_type(&self) -> Option<&dyn VirtualMethods> {
        Some(self.as_element() as &dyn VirtualMethods)
    }

    fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) {
        self.super_type()
            .unwrap()
            .attribute_mutated(attr, mutation, can_gc);
        let element = self.as_element();
        match (attr.local_name(), mutation) {
            // https://html.spec.whatwg.org/multipage/#event-handler-attributes:event-handler-content-attributes-3
            (name, mutation)
                if name.starts_with("on") && EventTarget::is_content_event_handler(name) =>
            {
                let evtarget = self.upcast::<EventTarget>();
                let event_name = &name[2..];
                match mutation {
                    // https://html.spec.whatwg.org/multipage/#activate-an-event-handler
                    AttributeMutation::Set(..) => {
                        let source = &**attr.value();
                        let source_line = 1; // TODO(#9604) get current JS execution line