Skip to main content

script/dom/document/
domparser.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 dom_struct::dom_struct;
6use js::rust::HandleObject;
7use script_bindings::reflector::{Reflector, reflect_dom_object_with_proto};
8use script_traits::DocumentActivity;
9
10use crate::dom::bindings::codegen::Bindings::DOMParserBinding;
11use crate::dom::bindings::codegen::Bindings::DOMParserBinding::DOMParserMethods;
12use crate::dom::bindings::codegen::Bindings::DOMParserBinding::SupportedType::{
13    Application_xhtml_xml, Application_xml, Image_svg_xml, Text_html, Text_xml,
14};
15use crate::dom::bindings::codegen::Bindings::DocumentBinding::DocumentReadyState;
16use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
17use crate::dom::bindings::codegen::UnionTypes::TrustedHTMLOrString;
18use crate::dom::bindings::error::Fallible;
19use crate::dom::bindings::root::{Dom, DomRoot};
20use crate::dom::document::{Document, HasBrowsingContext, IsHTMLDocument};
21use crate::dom::servoparser::ServoParser;
22use crate::dom::trustedtypes::trustedhtml::TrustedHTML;
23use crate::dom::window::Window;
24use crate::event_loop::document_loader::DocumentLoader;
25
26#[dom_struct]
27pub(crate) struct DOMParser {
28    reflector_: Reflector,
29    window: Dom<Window>, // XXXjdm Document instead?
30}
31
32impl DOMParser {
33    fn new_inherited(window: &Window) -> DOMParser {
34        DOMParser {
35            reflector_: Reflector::new(),
36            window: Dom::from_ref(window),
37        }
38    }
39
40    fn new(
41        cx: &mut js::context::JSContext,
42        window: &Window,
43        proto: Option<HandleObject>,
44    ) -> DomRoot<DOMParser> {
45        reflect_dom_object_with_proto(
46            cx,
47            Box::new(DOMParser::new_inherited(window)),
48            window,
49            proto,
50        )
51    }
52}
53
54impl DOMParserMethods<crate::DomTypeHolder> for DOMParser {
55    /// <https://html.spec.whatwg.org/multipage/#dom-domparser-constructor>
56    fn Constructor(
57        cx: &mut js::context::JSContext,
58        window: &Window,
59        proto: Option<HandleObject>,
60    ) -> Fallible<DomRoot<DOMParser>> {
61        Ok(DOMParser::new(cx, window, proto))
62    }
63
64    /// <https://html.spec.whatwg.org/multipage/#dom-domparser-parsefromstring>
65    fn ParseFromString(
66        &self,
67        cx: &mut js::context::JSContext,
68        s: TrustedHTMLOrString,
69        ty: DOMParserBinding::SupportedType,
70    ) -> Fallible<DomRoot<Document>> {
71        // Step 1. Let compliantString be the result of invoking the
72        // Get Trusted Type compliant string algorithm with TrustedHTML,
73        // this's relevant global object, string, "DOMParser parseFromString", and "script".
74        let compliant_string = TrustedHTML::get_trusted_type_compliant_string(
75            cx,
76            self.window.as_global_scope(),
77            s,
78            "DOMParser parseFromString",
79        )?;
80        let url = self.window.get_url();
81        let content_type = ty
82            .as_str()
83            .parse()
84            .expect("Supported type is not a MIME type");
85        let doc = self.window.Document();
86        let loader = DocumentLoader::new(&doc.loader());
87        // Step 3. Switch on type:
88        let document = match ty {
89            Text_html => {
90                // Step 2. Let document be a new Document, whose content type is type
91                // and URL is this's relevant global object's associated Document's URL.
92                let document = Document::new(
93                    cx,
94                    &self.window,
95                    HasBrowsingContext::No,
96                    Some(url.clone()),
97                    None,
98                    doc.origin().clone(),
99                    IsHTMLDocument::HTMLDocument,
100                    Some(content_type),
101                    None,
102                    DocumentActivity::Inactive,
103                    loader,
104                    None,
105                    None,
106                    Default::default(),
107                    false,
108                    false,
109                    Some(doc.insecure_requests_policy()),
110                    doc.has_trustworthy_ancestor_or_current_origin(),
111                    doc.custom_element_reaction_stack(),
112                    doc.creation_sandboxing_flag_set(),
113                    doc.pipeline_id(),
114                    doc.image_cache(),
115                );
116                // Step switch-1. Parse HTML from a string given document and compliantString.
117                ServoParser::parse_html_document(
118                    cx,
119                    &document,
120                    Some(compliant_string),
121                    url,
122                    None,
123                    None,
124                );
125                document
126            },
127            Text_xml | Application_xml | Application_xhtml_xml | Image_svg_xml => {
128                // Step 2. Let document be a new Document, whose content type is type
129                // and URL is this's relevant global object's associated Document's URL.
130                let document = Document::new(
131                    cx,
132                    &self.window,
133                    HasBrowsingContext::No,
134                    Some(url.clone()),
135                    None,
136                    doc.origin().clone(),
137                    IsHTMLDocument::NonHTMLDocument,
138                    Some(content_type),
139                    None,
140                    DocumentActivity::Inactive,
141                    loader,
142                    None,
143                    None,
144                    Default::default(),
145                    false,
146                    false,
147                    Some(doc.insecure_requests_policy()),
148                    doc.has_trustworthy_ancestor_or_current_origin(),
149                    doc.custom_element_reaction_stack(),
150                    doc.creation_sandboxing_flag_set(),
151                    doc.pipeline_id(),
152                    doc.image_cache(),
153                );
154                // Step switch-1. Create an XML parser parser, associated with document,
155                // and with XML scripting support disabled.
156                ServoParser::parse_xml_document(cx, &document, Some(compliant_string), url, None);
157                document.update_the_current_document_readiness(cx, DocumentReadyState::Complete);
158                document
159            },
160        };
161        // Step 4. Return document.
162        Ok(document)
163    }
164}