script/dom/html/
htmltitleelement.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use std::cell::Cell;
6
7use dom_struct::dom_struct;
8use html5ever::{LocalName, Prefix};
9use js::rust::HandleObject;
10
11use crate::dom::bindings::codegen::Bindings::HTMLTitleElementBinding::HTMLTitleElementMethods;
12use crate::dom::bindings::inheritance::Castable;
13use crate::dom::bindings::root::DomRoot;
14use crate::dom::bindings::str::DOMString;
15use crate::dom::document::Document;
16use crate::dom::html::htmlelement::HTMLElement;
17use crate::dom::node::{BindContext, ChildrenMutation, Node};
18use crate::dom::virtualmethods::VirtualMethods;
19use crate::script_runtime::CanGc;
20
21#[dom_struct]
22pub(crate) struct HTMLTitleElement {
23    htmlelement: HTMLElement,
24    popped: Cell<bool>,
25}
26
27impl HTMLTitleElement {
28    fn new_inherited(
29        local_name: LocalName,
30        prefix: Option<Prefix>,
31        document: &Document,
32    ) -> HTMLTitleElement {
33        HTMLTitleElement {
34            htmlelement: HTMLElement::new_inherited(local_name, prefix, document),
35            popped: Cell::new(false),
36        }
37    }
38
39    pub(crate) fn new(
40        local_name: LocalName,
41        prefix: Option<Prefix>,
42        document: &Document,
43        proto: Option<HandleObject>,
44        can_gc: CanGc,
45    ) -> DomRoot<HTMLTitleElement> {
46        Node::reflect_node_with_proto(
47            Box::new(HTMLTitleElement::new_inherited(
48                local_name, prefix, document,
49            )),
50            document,
51            proto,
52            can_gc,
53        )
54    }
55
56    fn notify_title_changed(&self) {
57        let node = self.upcast::<Node>();
58        if node.is_in_a_document_tree() {
59            node.owner_doc().title_changed();
60        }
61    }
62}
63
64impl HTMLTitleElementMethods<crate::DomTypeHolder> for HTMLTitleElement {
65    /// <https://html.spec.whatwg.org/multipage/#dom-title-text>
66    fn Text(&self) -> DOMString {
67        self.upcast::<Node>().child_text_content()
68    }
69
70    /// <https://html.spec.whatwg.org/multipage/#dom-title-text>
71    fn SetText(&self, value: DOMString, can_gc: CanGc) {
72        self.upcast::<Node>()
73            .set_text_content_for_element(Some(value), can_gc)
74    }
75}
76
77impl VirtualMethods for HTMLTitleElement {
78    fn super_type(&self) -> Option<&dyn VirtualMethods> {
79        Some(self.upcast::<HTMLElement>() as &dyn VirtualMethods)
80    }
81
82    fn children_changed(&self, mutation: &ChildrenMutation, can_gc: CanGc) {
83        if let Some(s) = self.super_type() {
84            s.children_changed(mutation, can_gc);
85        }
86
87        // Notify of title changes only after the initial full parsing
88        // of the element.
89        if self.popped.get() {
90            self.notify_title_changed();
91        }
92    }
93
94    fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) {
95        if let Some(s) = self.super_type() {
96            s.bind_to_tree(context, can_gc);
97        }
98        let node = self.upcast::<Node>();
99        if context.tree_is_in_a_document_tree {
100            node.owner_doc().title_changed();
101        }
102    }
103
104    fn pop(&self) {
105        if let Some(s) = self.super_type() {
106            s.pop();
107        }
108
109        self.popped.set(true);
110
111        // Initial notification of title change, once the full text
112        // is available.
113        self.notify_title_changed();
114    }
115}