Skip to main content

script/dom/
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::document_loader::DocumentLoader;
11use crate::dom::bindings::codegen::Bindings::DOMParserBinding;
12use crate::dom::bindings::codegen::Bindings::DOMParserBinding::DOMParserMethods;
13use crate::dom::bindings::codegen::Bindings::DOMParserBinding::SupportedType::{
14    Application_xhtml_xml, Application_xml, Image_svg_xml, Text_html, Text_xml,
15};
16use crate::dom::bindings::codegen::Bindings::DocumentBinding::DocumentReadyState;
17use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
18use crate::dom::bindings::codegen::UnionTypes::TrustedHTMLOrString;
19use crate::dom::bindings::error::Fallible;
20use crate::dom::bindings::root::{Dom, DomRoot};
21use crate::dom::document::{Document, DocumentSource, HasBrowsingContext, IsHTMLDocument};
22use crate::dom::servoparser::ServoParser;
23use crate::dom::trustedtypes::trustedhtml::TrustedHTML;
24use crate::dom::window::Window;
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                    DocumentSource::FromParser,
104                    loader,
105                    None,
106                    None,
107                    Default::default(),
108                    false,
109                    false,
110                    Some(doc.insecure_requests_policy()),
111                    doc.has_trustworthy_ancestor_or_current_origin(),
112                    doc.custom_element_reaction_stack(),
113                    doc.creation_sandboxing_flag_set(),
114                    doc.pipeline_id(),
115                    doc.image_cache(),
116                );
117                // Step switch-1. Parse HTML from a string given document and compliantString.
118                ServoParser::parse_html_document(
119                    cx,
120                    &document,
121                    Some(compliant_string),
122                    url,
123                    None,
124                    None,
125                );
126                document
127            },
128            Text_xml | Application_xml | Application_xhtml_xml | Image_svg_xml => {
129                // Step 2. Let document be a new Document, whose content type is type
130                // and URL is this's relevant global object's associated Document's URL.
131                let document = Document::new(
132                    cx,
133                    &self.window,
134                    HasBrowsingContext::No,
135                    Some(url.clone()),
136                    None,
137                    doc.origin().clone(),
138                    IsHTMLDocument::NonHTMLDocument,
139                    Some(content_type),
140                    None,
141                    DocumentActivity::Inactive,
142                    DocumentSource::FromParser,
143                    loader,
144                    None,
145                    None,
146                    Default::default(),
147                    false,
148                    false,
149                    Some(doc.insecure_requests_policy()),
150                    doc.has_trustworthy_ancestor_or_current_origin(),
151                    doc.custom_element_reaction_stack(),
152                    doc.creation_sandboxing_flag_set(),
153                    doc.pipeline_id(),
154                    doc.image_cache(),
155                );
156                // Step switch-1. Create an XML parser parser, associated with document,
157                // and with XML scripting support disabled.
158                ServoParser::parse_xml_document(cx, &document, Some(compliant_string), url, None);
159                document.set_ready_state(cx, DocumentReadyState::Complete);
160                document
161            },
162        };
163        // Step 4. Return document.
164        Ok(document)
165    }
166}