View Javadoc
1   /*
2    * Copyright (c) 2002-2017 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    * http://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 com.gargoylesoftware.htmlunit.javascript.host.html;
16  
17  import static com.gargoylesoftware.htmlunit.html.DomElement.ATTRIBUTE_NOT_DEFINED;
18  import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
19  import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
20  import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
21  import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
22  
23  import java.net.MalformedURLException;
24  import java.net.URL;
25  
26  import com.gargoylesoftware.htmlunit.html.DomNode;
27  import com.gargoylesoftware.htmlunit.html.DomText;
28  import com.gargoylesoftware.htmlunit.html.HtmlElement;
29  import com.gargoylesoftware.htmlunit.html.HtmlPage;
30  import com.gargoylesoftware.htmlunit.html.HtmlScript;
31  import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
32  import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
33  import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter;
34  import com.gargoylesoftware.htmlunit.javascript.configuration.JsxSetter;
35  
36  import net.sourceforge.htmlunit.corejs.javascript.Undefined;
37  
38  /**
39   * The JavaScript object that represents an {@code HTMLScriptElement}.
40   *
41   * @author Daniel Gredler
42   * @author Marc Guillemot
43   * @author Ahmed Ashour
44   * @author Ronald Brill
45   * @author Frank Danek
46   */
47  @JsxClass(domClass = HtmlScript.class)
48  public class HTMLScriptElement extends HTMLElement {
49  
50      /**
51       * Creates an instance.
52       */
53      @JsxConstructor({CHROME, FF, EDGE})
54      public HTMLScriptElement() {
55      }
56  
57      /**
58       * Returns the {@code src} property.
59       * @return the {@code src} property
60       */
61      @JsxGetter
62      public String getSrc() {
63          final HtmlScript tmpScript = (HtmlScript) getDomNodeOrDie();
64          String src = tmpScript.getSrcAttribute();
65          if (ATTRIBUTE_NOT_DEFINED == src) {
66              return src;
67          }
68          try {
69              final URL expandedSrc = ((HtmlPage) tmpScript.getPage()).getFullyQualifiedUrl(src);
70              src = expandedSrc.toString();
71          }
72          catch (final MalformedURLException e) {
73              // ignore
74          }
75          return src;
76      }
77  
78      /**
79       * Sets the {@code src} property.
80       * @param src the {@code src} property
81       */
82      @JsxSetter
83      public void setSrc(final String src) {
84          getDomNodeOrDie().setAttribute("src", src);
85      }
86  
87      /**
88       * Returns the {@code text} property.
89       * @return the {@code text} property
90       */
91      @JsxGetter
92      public String getText() {
93          final StringBuilder scriptCode = new StringBuilder();
94          for (final DomNode node : getDomNodeOrDie().getChildren()) {
95              if (node instanceof DomText) {
96                  final DomText domText = (DomText) node;
97                  scriptCode.append(domText.getData());
98              }
99          }
100         return scriptCode.toString();
101     }
102 
103     /**
104      * Sets the {@code text} property.
105      * @param text the {@code text} property
106      */
107     @JsxSetter
108     public void setText(final String text) {
109         final HtmlElement htmlElement = getDomNodeOrDie();
110         htmlElement.removeAllChildren();
111         final DomNode textChild = new DomText(htmlElement.getPage(), text);
112         htmlElement.appendChild(textChild);
113 
114         final HtmlScript tmpScript = (HtmlScript) htmlElement;
115         tmpScript.executeScriptIfNeeded();
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().getAttribute("type");
125     }
126 
127     /**
128      * Sets the {@code type} property.
129      * @param type the {@code type} property
130      */
131     @JsxSetter
132     public void setType(final String type) {
133         getDomNodeOrDie().setAttribute("type", type);
134     }
135 
136     /**
137      * Returns the event handler that fires on every state change.
138      * @return the event handler that fires on every state change
139      */
140     @JsxGetter(IE)
141     public Object getOnreadystatechange() {
142         return getEventHandler("readystatechange");
143     }
144 
145     /**
146      * Sets the event handler that fires on every state change.
147      * @param handler the event handler that fires on every state change
148      */
149     @JsxSetter(IE)
150     public void setOnreadystatechange(final Object handler) {
151         setEventHandler("readystatechange", handler);
152     }
153 
154     /**
155      * Returns the ready state of the script. This is an IE-only property.
156      * @return the ready state of the script
157      * @see DomNode#READY_STATE_UNINITIALIZED
158      * @see DomNode#READY_STATE_LOADING
159      * @see DomNode#READY_STATE_LOADED
160      * @see DomNode#READY_STATE_INTERACTIVE
161      * @see DomNode#READY_STATE_COMPLETE
162      */
163     @JsxGetter(IE)
164     public Object getReadyState() {
165         final HtmlScript tmpScript = (HtmlScript) getDomNodeOrDie();
166         if (tmpScript.wasCreatedByJavascript()) {
167             return Undefined.instance;
168         }
169         return tmpScript.getReadyState();
170     }
171 
172     /**
173      * Overwritten for special IE handling.
174      *
175      * @param childObject the node to add to this node
176      * @return the newly added child node
177      */
178     @Override
179     public Object appendChild(final Object childObject) {
180         final HtmlScript tmpScript = (HtmlScript) getDomNodeOrDie();
181         final boolean wasEmpty = tmpScript.getFirstChild() == null;
182         final Object result = super.appendChild(childObject);
183 
184         if (wasEmpty) {
185             tmpScript.executeScriptIfNeeded();
186         }
187         return result;
188     }
189 
190     /**
191      * Returns the {@code async} property.
192      * @return the {@code async} property
193      */
194     @JsxGetter
195     public boolean isAsync() {
196         return getDomNodeOrDie().hasAttribute("async");
197     }
198 
199     /**
200      * Sets the {@code async} property.
201      * @param async the {@code async} property
202      */
203     @JsxSetter
204     public void setAsync(final boolean async) {
205         if (async) {
206             getDomNodeOrDie().setAttribute("async", "");
207         }
208         else {
209             getDomNodeOrDie().removeAttribute("async");
210         }
211     }
212 }