View Javadoc
1   /*
2    * Copyright (c) 2002-2025 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 java.net.MalformedURLException;
18  
19  import org.apache.commons.logging.Log;
20  import org.apache.commons.logging.LogFactory;
21  import org.htmlunit.css.CssStyleSheet;
22  import org.htmlunit.html.HtmlLink;
23  import org.htmlunit.html.HtmlPage;
24  import org.htmlunit.javascript.JavaScriptEngine;
25  import org.htmlunit.javascript.configuration.JsxClass;
26  import org.htmlunit.javascript.configuration.JsxConstructor;
27  import org.htmlunit.javascript.configuration.JsxGetter;
28  import org.htmlunit.javascript.configuration.JsxSetter;
29  import org.htmlunit.javascript.host.css.CSSStyleSheet;
30  import org.htmlunit.javascript.host.dom.DOMTokenList;
31  
32  /**
33   * The JavaScript object {@code HTMLLinkElement}.
34   *
35   * @author Ahmed Ashour
36   * @author Ronald Brill
37   * @author Sven Strickroth
38   */
39  @JsxClass(domClass = HtmlLink.class)
40  public class HTMLLinkElement extends HTMLElement {
41  
42      private static final Log LOG = LogFactory.getLog(HTMLLinkElement.class);
43  
44      /**
45       * The associated style sheet (only valid for links of type
46       * <code>&lt;link rel="stylesheet" type="text/css" href="..." /&gt;</code>).
47       */
48      private CSSStyleSheet sheet_;
49  
50      /**
51       * JavaScript constructor.
52       */
53      @Override
54      @JsxConstructor
55      public void jsConstructor() {
56          super.jsConstructor();
57      }
58  
59      /**
60       * {@inheritDoc}
61       */
62      @Override
63      public HtmlLink getDomNodeOrDie() {
64          return (HtmlLink) super.getDomNodeOrDie();
65      }
66  
67      /**
68       * Sets the href property.
69       * @param href href attribute value
70       */
71      @JsxSetter
72      public void setHref(final String href) {
73          getDomNodeOrDie().setAttribute("href", href);
74      }
75  
76      /**
77       * Returns the value of the href property.
78       * @return the href property
79       */
80      @JsxGetter
81      public String getHref() {
82          final HtmlLink link = getDomNodeOrDie();
83          final String href = link.getHrefAttribute();
84          if (href.isEmpty()) {
85              return href;
86          }
87          try {
88              return ((HtmlPage) link.getPage()).getFullyQualifiedUrl(href).toString();
89          }
90          catch (final MalformedURLException e) {
91              return href;
92          }
93      }
94  
95      /**
96       * Sets the rel property.
97       * @param rel rel attribute value
98       */
99      @JsxSetter
100     public void setRel(final String rel) {
101         getDomNodeOrDie().setAttribute("rel", rel);
102     }
103 
104     /**
105      * Returns the value of the rel property.
106      * @return the rel property
107      */
108     @JsxGetter
109     public String getRel() {
110         return getDomNodeOrDie().getRelAttribute();
111     }
112 
113     /**
114      * Sets the rev property.
115      * @param rel rev attribute value
116      */
117     @JsxSetter
118     public void setRev(final String rel) {
119         getDomNodeOrDie().setAttribute("rev", rel);
120     }
121 
122     /**
123      * Returns the value of the rev property.
124      * @return the rev property
125      */
126     @JsxGetter
127     public String getRev() {
128         return getDomNodeOrDie().getRevAttribute();
129     }
130 
131     /**
132      * Sets the type property.
133      * @param type type attribute value
134      */
135     @JsxSetter
136     public void setType(final String type) {
137         getDomNodeOrDie().setAttribute("type", type);
138     }
139 
140     /**
141      * Returns the value of the type property.
142      * @return the type property
143      */
144     @JsxGetter
145     public String getType() {
146         return getDomNodeOrDie().getTypeAttribute();
147     }
148 
149     /**
150      * Returns the associated style sheet (only valid for links of type
151      * <code>&lt;link rel="stylesheet" type="text/css" href="..." /&gt;</code>).
152      * @return the associated style sheet
153      */
154     public CSSStyleSheet getSheet() {
155         if (sheet_ == null) {
156             try {
157                 final CssStyleSheet sheet = getDomNodeOrDie().getSheet();
158                 sheet_ = new CSSStyleSheet(this, getWindow(), sheet);
159             }
160             catch (final RuntimeException e) {
161                 // Got something unexpected; we can throw an exception in this case.
162                 LOG.error("RuntimeException loading stylesheet", e);
163                 throw JavaScriptEngine.reportRuntimeError("Exception: " + e);
164             }
165             catch (final Exception e) {
166                 // Got something unexpected; we can throw an exception in this case.
167                 LOG.error("Exception loading stylesheet", e);
168                 throw JavaScriptEngine.reportRuntimeError("Exception: " + e);
169             }
170         }
171         return sheet_;
172     }
173 
174     /**
175      * {@inheritDoc}
176      */
177     @Override
178     protected boolean isEndTagForbidden() {
179         return true;
180     }
181 
182     /**
183      * Returns the {@code relList} attribute.
184      * @return the {@code relList} attribute
185      */
186     @JsxGetter
187     public DOMTokenList getRelList() {
188         return new DOMTokenList(this, "rel");
189     }
190 
191     /**
192      * Sets the relList property.
193      * @param rel attribute value
194      */
195     @JsxSetter
196     public void setRelList(final Object rel) {
197         if (JavaScriptEngine.isUndefined(rel)) {
198             setRel("undefined");
199             return;
200         }
201         setRel(JavaScriptEngine.toString(rel));
202     }
203 
204     /**
205      * {@inheritDoc} Overridden to modify browser configurations.
206      */
207     @Override
208     @JsxGetter
209     public boolean isDisabled() {
210         return super.isDisabled();
211     }
212 
213     /**
214      * {@inheritDoc} Overridden to modify browser configurations.
215      */
216     @Override
217     @JsxSetter
218     public void setDisabled(final boolean disabled) {
219         super.setDisabled(disabled);
220     }
221 }