View Javadoc
1   /*
2    * Copyright (c) 2002-2026 Gargoyle Software Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * https://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  package org.htmlunit.javascript.host.dom;
16  
17  import java.io.IOException;
18  
19  import org.htmlunit.StringWebResponse;
20  import org.htmlunit.WebClient;
21  import org.htmlunit.WebResponse;
22  import org.htmlunit.WebWindow;
23  import org.htmlunit.html.HtmlPage;
24  import org.htmlunit.html.parser.HTMLParser;
25  import org.htmlunit.javascript.HtmlUnitScriptable;
26  import org.htmlunit.javascript.JavaScriptEngine;
27  import org.htmlunit.javascript.configuration.JsxClass;
28  import org.htmlunit.javascript.configuration.JsxConstructor;
29  import org.htmlunit.javascript.configuration.JsxFunction;
30  import org.htmlunit.javascript.host.Window;
31  import org.htmlunit.javascript.host.html.HTMLDocument;
32  import org.htmlunit.javascript.host.xml.XMLDocument;
33  import org.htmlunit.util.MimeType;
34  
35  /**
36   * A JavaScript object for {@code DOMParser}.
37   *
38   * @author Ahmed Ashour
39   * @author Frank Danek
40   * @author Ronald Brill
41   *
42   * @see <a href="http://www.w3.org/TR/DOM-Parsing/">W3C Spec</a>
43   * @see <a href="http://domparsing.spec.whatwg.org/">WhatWG Spec</a>
44   * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/DOMParser">MDN Documentation</a>
45   */
46  @JsxClass
47  public class DOMParser extends HtmlUnitScriptable {
48  
49      /**
50       * JavaScript constructor.
51       */
52      @JsxConstructor
53      public void jsConstructor() {
54          // nothing to do
55      }
56  
57      /**
58       * Parses the given Unicode string into a DOM document.
59       * @param str the Unicode string to be parsed
60       * @param type the MIME type of the string -
61       *        <code>text/html</code>, <code>text/xml</code>, <code>application/xml</code>,
62       *        <code>application/xhtml+xml</code>, <code>image/svg+xml</code>. Must not be {@code null}.
63       * @return the generated document
64       */
65      @JsxFunction
66      public Document parseFromString(final String str, final Object type) {
67          try {
68              final Document document = parseFromString(this, str, type);
69              if (document == null) {
70                  throw JavaScriptEngine.typeError("Invalid 'type' parameter: " + type);
71              }
72              return document;
73          }
74          catch (final IOException e) {
75              throw JavaScriptEngine.syntaxError("Parsing failed" + e.getMessage());
76          }
77      }
78  
79      /**
80       * <span style="color:red">INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.</span><br>
81       *
82       * Parses the given Unicode string into a DOM document.
83       * @param scriptable the ScriptableObject this belongs to
84       * @param str the Unicode string to be parsed
85       * @param type the MIME type of the string -
86       *        <code>text/html</code>, <code>text/xml</code>, <code>application/xml</code>,
87       *        <code>application/xhtml+xml</code>, <code>image/svg+xml</code>. Must not be {@code null}.
88       * @return the generated document
89       * @throws IOException in case of error
90       */
91      public static Document parseFromString(final HtmlUnitScriptable scriptable, final String str, final Object type)
92                  throws IOException {
93          if (type == null || JavaScriptEngine.isUndefined(type)) {
94              throw JavaScriptEngine.typeError("Missing 'type' parameter");
95          }
96  
97          if (MimeType.TEXT_XML.equals(type)
98                  || MimeType.APPLICATION_XML.equals(type)
99                  || MimeType.APPLICATION_XHTML.equals(type)
100                 || "image/svg+xml".equals(type)) {
101             final XMLDocument document = new XMLDocument();
102             document.setParentScope(scriptable.getParentScope());
103             document.setPrototype(scriptable.getPrototype(XMLDocument.class));
104             document.loadXML(str);
105             return document;
106         }
107 
108         if (MimeType.TEXT_HTML.equals(type)) {
109             final WebWindow webWindow = scriptable.getWindow().getWebWindow();
110             final WebResponse webResponse = new StringWebResponse(str, webWindow.getEnclosedPage().getUrl());
111 
112             return parseHtmlDocument(scriptable, webResponse, webWindow);
113         }
114 
115         return null;
116     }
117 
118     /**
119      * <span style="color:red">INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.</span><br>
120      *
121      * Parses the given Unicode string into a DOM document.
122      * @param scriptable the ScriptableObject this belongs to
123      * @param webResponse the response to be parsed
124      * @param webWindow the window
125      * @return the generated document
126      * @throws IOException in case of error
127      */
128     public static Document parseHtmlDocument(final HtmlUnitScriptable scriptable, final WebResponse webResponse,
129                                 final WebWindow webWindow)
130                 throws IOException {
131         // a similar impl is in
132         // org.htmlunit.javascript.host.dom.DOMImplementation.createHTMLDocument(Object)
133         final HtmlPage page = new HtmlPage(webResponse, webWindow);
134         page.setEnclosingWindow(null);
135         final Window window = webWindow.getScriptableObject();
136 
137         // document knows the window but is not the windows document
138         final HTMLDocument document = new HTMLDocument();
139         document.setParentScope(getTopLevelScope(scriptable.getParentScope()));
140         document.setPrototype(window.getPrototype(document.getClass()));
141         // document.setWindow(window);
142         document.setDomNode(page);
143 
144         final WebClient webClient = webWindow.getWebClient();
145         final HTMLParser htmlParser = webClient.getPageCreator().getHtmlParser();
146         htmlParser.parse(webClient, webResponse, page, false, true);
147         return page.getScriptableObject();
148     }
149 }