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.html;
16  
17  import static org.htmlunit.html.DomElement.ATTRIBUTE_NOT_DEFINED;
18  
19  import java.net.MalformedURLException;
20  import java.net.URL;
21  
22  import org.htmlunit.html.DomElement;
23  import org.htmlunit.html.DomNode;
24  import org.htmlunit.html.DomText;
25  import org.htmlunit.html.HtmlElement;
26  import org.htmlunit.html.HtmlPage;
27  import org.htmlunit.html.HtmlScript;
28  import org.htmlunit.html.ScriptElement;
29  import org.htmlunit.html.ScriptElementSupport;
30  import org.htmlunit.javascript.configuration.JsxClass;
31  import org.htmlunit.javascript.configuration.JsxConstructor;
32  import org.htmlunit.javascript.configuration.JsxGetter;
33  import org.htmlunit.javascript.configuration.JsxSetter;
34  import org.htmlunit.javascript.host.dom.Node;
35  
36  /**
37   * The JavaScript object that represents an {@code HTMLScriptElement}.
38   *
39   * @author Daniel Gredler
40   * @author Marc Guillemot
41   * @author Ahmed Ashour
42   * @author Ronald Brill
43   * @author Frank Danek
44   *
45   * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLScriptElement">MDN Documentation</a>
46   */
47  @JsxClass(domClass = HtmlScript.class)
48  public class HTMLScriptElement extends HTMLElement {
49  
50      /**
51       * JavaScript constructor.
52       */
53      @Override
54      @JsxConstructor
55      public void jsConstructor() {
56          super.jsConstructor();
57      }
58  
59      /**
60       * Returns the {@code src} property.
61       * @return the {@code src} property
62       */
63      @JsxGetter
64      public String getSrc() {
65          final HtmlScript tmpScript = (HtmlScript) getDomNodeOrDie();
66          String src = tmpScript.getSrcAttribute();
67          if (ATTRIBUTE_NOT_DEFINED == src) {
68              return src;
69          }
70          try {
71              final URL expandedSrc = ((HtmlPage) tmpScript.getPage()).getFullyQualifiedUrl(src);
72              src = expandedSrc.toString();
73          }
74          catch (final MalformedURLException ignored) {
75              // ignore
76          }
77          return src;
78      }
79  
80      /**
81       * Sets the {@code src} property.
82       * @param src the {@code src} property value
83       */
84      @JsxSetter
85      public void setSrc(final String src) {
86          getDomNodeOrDie().setAttribute(DomElement.SRC_ATTRIBUTE, src);
87      }
88  
89      /**
90       * Returns the {@code text} property.
91       * @return the {@code text} property
92       */
93      @JsxGetter
94      public String getText() {
95          final StringBuilder scriptCode = new StringBuilder();
96          for (final DomNode node : getDomNodeOrDie().getChildren()) {
97              if (node instanceof DomText domText) {
98                  scriptCode.append(domText.getData());
99              }
100         }
101         return scriptCode.toString();
102     }
103 
104     /**
105      * Sets the {@code text} property.
106      * @param text the {@code text} property value
107      */
108     @JsxSetter
109     public void setText(final String text) {
110         final HtmlElement htmlElement = getDomNodeOrDie();
111         htmlElement.removeAllChildren();
112         final DomNode textChild = new DomText(htmlElement.getPage(), text);
113         htmlElement.appendChild(textChild);
114 
115         ScriptElementSupport.executeScriptIfNeeded((ScriptElement) htmlElement, false, false);
116     }
117 
118     /**
119      * Returns the {@code type} property.
120      * @return the {@code type} property
121      */
122     @JsxGetter
123     public String getType() {
124         return getDomNodeOrDie().getAttributeDirect(DomElement.TYPE_ATTRIBUTE);
125     }
126 
127     /**
128      * Sets the {@code type} property.
129      * @param type the {@code type} property value
130      */
131     @JsxSetter
132     public void setType(final String type) {
133         getDomNodeOrDie().setAttribute(DomElement.TYPE_ATTRIBUTE, type);
134     }
135 
136     /**
137      * Overwritten for special handling.
138      *
139      * @param childObject the node to add to this node
140      * @return the newly added child node
141      */
142     @Override
143     public Node appendChild(final Object childObject) {
144         final HtmlElement tmpScript = getDomNodeOrDie();
145         final boolean wasEmpty = tmpScript.getFirstChild() == null;
146         final Node node = super.appendChild(childObject);
147 
148         if (wasEmpty) {
149             ScriptElementSupport.executeScriptIfNeeded((ScriptElement) tmpScript, false, false);
150         }
151         return node;
152     }
153 
154     /**
155      * Returns the {@code async} property.
156      * @return the {@code async} property
157      */
158     @JsxGetter
159     public boolean isAsync() {
160         return getDomNodeOrDie().hasAttribute("async");
161     }
162 
163     /**
164      * Sets the {@code async} property.
165      * @param async the {@code async} property value
166      */
167     @JsxSetter
168     public void setAsync(final boolean async) {
169         if (async) {
170             getDomNodeOrDie().setAttribute("async", "");
171         }
172         else {
173             getDomNodeOrDie().removeAttribute("async");
174         }
175     }
176 }