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