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.html;
16  
17  import java.io.IOException;
18  import java.io.StringReader;
19  import java.util.Map;
20  
21  import org.apache.commons.logging.Log;
22  import org.apache.commons.logging.LogFactory;
23  import org.htmlunit.Cache;
24  import org.htmlunit.SgmlPage;
25  import org.htmlunit.css.CssStyleSheet;
26  import org.htmlunit.cssparser.dom.CSSStyleSheetImpl;
27  import org.htmlunit.cssparser.parser.InputSource;
28  
29  /**
30   * Wrapper for the HTML element "style".
31   *
32   * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
33   * @author <a href="mailto:cse@dynabean.de">Christian Sell</a>
34   * @author Marc Guillemot
35   * @author Ahmed Ashour
36   * @author Frank Danek
37   */
38  public class HtmlStyle extends HtmlElement {
39  
40      private static final Log LOG = LogFactory.getLog(HtmlStyle.class);
41  
42      /** The HTML tag represented by this element. */
43      public static final String TAG_NAME = "style";
44  
45      private CssStyleSheet sheet_;
46  
47      /**
48       * Creates an instance of HtmlStyle
49       *
50       * @param qualifiedName the qualified name of the element type to instantiate
51       * @param page the HtmlPage that contains this element
52       * @param attributes the initial attributes
53       */
54      HtmlStyle(final String qualifiedName, final SgmlPage page,
55              final Map<String, DomAttr> attributes) {
56          super(qualifiedName, page, attributes);
57      }
58  
59      /**
60       * Returns the value of the attribute {@code type}. Refer to the
61       * <a href="http://www.w3.org/TR/html401/">HTML 4.01</a>
62       * documentation for details on the use of this attribute.
63       *
64       * @return the value of the attribute {@code type} or an empty string if that attribute isn't defined
65       */
66      public final String getTypeAttribute() {
67          return getAttributeDirect(TYPE_ATTRIBUTE);
68      }
69  
70      /**
71       * Sets the value of the attribute {@code type}.
72       *
73       * @param type the new type
74       */
75      public final void setTypeAttribute(final String type) {
76          setAttribute(TYPE_ATTRIBUTE, type);
77      }
78  
79      /**
80       * Returns the value of the attribute {@code media}. Refer to the
81       * <a href="http://www.w3.org/TR/html401/">HTML 4.01</a>
82       * documentation for details on the use of this attribute.
83       *
84       * @return the value of the attribute {@code media} or an empty string if that attribute isn't defined
85       */
86      public final String getMediaAttribute() {
87          return getAttributeDirect("media");
88      }
89  
90      /**
91       * Returns the value of the attribute {@code title}. Refer to the
92       * <a href="http://www.w3.org/TR/html401/">HTML 4.01</a>
93       * documentation for details on the use of this attribute.
94       *
95       * @return the value of the attribute {@code title} or an empty string if that attribute isn't defined
96       */
97      public final String getTitleAttribute() {
98          return getAttributeDirect("title");
99      }
100 
101     /**
102      * {@inheritDoc}
103      * @return {@code true} to make generated XML readable as HTML on Firefox 3 for instance.
104      */
105     @Override
106     protected boolean isEmptyXmlTagExpanded() {
107         return true;
108     }
109 
110     /**
111      * {@inheritDoc}
112      */
113     @Override
114     public DisplayStyle getDefaultStyleDisplay() {
115         return DisplayStyle.NONE;
116     }
117 
118     /**
119      * {@inheritDoc}
120      */
121     @Override
122     public boolean mayBeDisplayed() {
123         return false;
124     }
125 
126     /**
127      * @return the referenced style sheet
128      */
129     public CssStyleSheet getSheet() {
130         if (sheet_ != null) {
131             return sheet_;
132         }
133 
134         final Cache cache = getPage().getWebClient().getCache();
135         final CSSStyleSheetImpl cached = cache.getCachedStyleSheet(getTextContent());
136         final String uri = getPage().getWebResponse().getWebRequest().getUrl().toExternalForm();
137 
138         if (cached != null) {
139             sheet_ = new CssStyleSheet(this, cached, uri);
140         }
141         else {
142             final String css = getTextContent();
143             try (InputSource source = new InputSource(new StringReader(css))) {
144                 sheet_ = new CssStyleSheet(this, source, uri);
145                 cache.cache(css, sheet_.getWrappedSheet());
146             }
147             catch (final IOException e) {
148                 LOG.error(e.getMessage(), e);
149             }
150         }
151 
152         return sheet_;
153     }
154 }