Skip to content

Commit e104938

Browse files
committed
fix css link processing
1 parent 8bfceb1 commit e104938

File tree

6 files changed

+100
-36
lines changed

6 files changed

+100
-36
lines changed

src/main/java/org/htmlunit/BrowserVersionFeatures.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,10 @@ public enum BrowserVersionFeatures {
180180
@BrowserFeature({FF, FF_ESR})
181181
HTMLLINK_CHECK_RESPONSE_TYPE_FOR_STYLESHEET,
182182

183+
/** If the type is present for a link only use if type is text/css. */
184+
@BrowserFeature({CHROME, EDGE})
185+
HTMLLINK_CHECK_TYPE_FOR_STYLESHEET,
186+
183187
/** willValidate does not check the readonly property. */
184188
@BrowserFeature({FF, FF_ESR})
185189
HTMLSELECT_WILL_VALIDATE_IGNORES_READONLY,

src/main/java/org/htmlunit/css/CssStyleSheet.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package org.htmlunit.css;
1616

1717
import static java.nio.charset.StandardCharsets.UTF_8;
18+
import static org.htmlunit.BrowserVersionFeatures.HTMLLINK_CHECK_TYPE_FOR_STYLESHEET;
1819
import static org.htmlunit.html.DomElement.ATTRIBUTE_NOT_DEFINED;
1920

2021
import java.io.IOException;
@@ -312,8 +313,10 @@ public static CssStyleSheet loadStylesheet(final HtmlElement element, final Html
312313
request = link.getWebRequest();
313314

314315
final String type = link.getTypeAttribute();
315-
if (StringUtils.isNotBlank(type) && !MimeType.TEXT_CSS.equals(type)) {
316-
return new CssStyleSheet(element, "", uri);
316+
if (client.getBrowserVersion().hasFeature(HTMLLINK_CHECK_TYPE_FOR_STYLESHEET)) {
317+
if (StringUtils.isNotBlank(type) && !MimeType.TEXT_CSS.equals(type)) {
318+
return new CssStyleSheet(element, "", uri);
319+
}
317320
}
318321

319322
if (request.getCharset() != null) {
@@ -327,7 +330,10 @@ public static CssStyleSheet loadStylesheet(final HtmlElement element, final Html
327330
// our cache is a bit strange;
328331
// loadWebResponse check the cache for the web response
329332
// AND also fixes the request url for the following cache lookups
330-
response = link.getWebResponse(true, request, true);
333+
response = link.getWebResponse(true, request, true, type);
334+
if (response == null) {
335+
return new CssStyleSheet(element, "", uri);
336+
}
331337
}
332338

333339
// now we can look into the cache with the fixed request for

src/main/java/org/htmlunit/html/HtmlLink.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ public final String getTargetAttribute() {
181181
* @throws IOException if an error occurs while downloading the content
182182
*/
183183
public WebResponse getWebResponse(final boolean downloadIfNeeded) throws IOException {
184-
return getWebResponse(downloadIfNeeded, null, false);
184+
return getWebResponse(downloadIfNeeded, null, false, null);
185185
}
186186

187187
/**
@@ -193,12 +193,13 @@ public WebResponse getWebResponse(final boolean downloadIfNeeded) throws IOExcep
193193
* @param downloadIfNeeded indicates if a request should be performed this hasn't been done previously
194194
* @param request the request; if null getWebRequest() is called to create one
195195
* @param isStylesheetRequest true if this should return a stylesheet
196+
* @param type the type definined for the stylesheet link
196197
* @return {@code null} if no download should be performed and when this wasn't already done; the response
197198
* received when performing a request for the content referenced by this tag otherwise
198199
* @throws IOException if an error occurs while downloading the content
199200
*/
200201
public WebResponse getWebResponse(final boolean downloadIfNeeded, WebRequest request,
201-
final boolean isStylesheetRequest) throws IOException {
202+
final boolean isStylesheetRequest, final String type) throws IOException {
202203
final WebClient webclient = getPage().getWebClient();
203204
if (null == request) {
204205
request = getWebRequest();
@@ -211,9 +212,15 @@ public WebResponse getWebResponse(final boolean downloadIfNeeded, WebRequest req
211212
if (isStylesheetRequest
212213
&& webclient.getBrowserVersion()
213214
.hasFeature(BrowserVersionFeatures.HTMLLINK_CHECK_RESPONSE_TYPE_FOR_STYLESHEET)) {
214-
final String type = response.getContentType();
215+
215216
if (org.apache.commons.lang3.StringUtils.isNotBlank(type)
216217
&& !MimeType.TEXT_CSS.equals(type)) {
218+
return null;
219+
}
220+
221+
final String respType = response.getContentType();
222+
if (org.apache.commons.lang3.StringUtils.isNotBlank(respType)
223+
&& !MimeType.TEXT_CSS.equals(respType)) {
217224
executeEvent(Event.TYPE_ERROR);
218225
return response;
219226
}

src/main/java/org/htmlunit/html/XmlSerializer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ protected Map<String, DomAttr> getAttributesFor(final HtmlLink link) throws IOEx
285285
final String protocol = link.getWebRequest().getUrl().getProtocol();
286286
if ("http".equals(protocol) || "https".equals(protocol)) {
287287
try {
288-
final WebResponse response = link.getWebResponse(true, null, false);
288+
final WebResponse response = link.getWebResponse(true, null, false, null);
289289

290290
final File file = createFile(hrefAttr.getValue(), ".css");
291291
FileUtils.writeStringToFile(file, response.getContentAsString(), ISO_8859_1);

src/test/java/org/htmlunit/html/HtmlLink2Test.java

Lines changed: 52 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import java.net.URL;
1818
import java.text.SimpleDateFormat;
1919
import java.util.ArrayList;
20+
import java.util.Arrays;
2021
import java.util.Date;
2122
import java.util.List;
2223
import java.util.Map;
@@ -121,7 +122,7 @@ public void isDisplayed() throws Exception {
121122
* @throws Exception if an error occurs
122123
*/
123124
@Test
124-
@Alerts({"onLoad", "body onLoad"})
125+
@Alerts({"2", "onLoad", "body onLoad"})
125126
public void onLoad() throws Exception {
126127
getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.css"), "", MimeType.TEXT_CSS);
127128
onLoadOnError("rel='stylesheet' href='simple.css'");
@@ -131,7 +132,7 @@ public void onLoad() throws Exception {
131132
* @throws Exception if an error occurs
132133
*/
133134
@Test
134-
@Alerts({"onLoad", "body onLoad"})
135+
@Alerts({"2", "onLoad", "body onLoad"})
135136
public void onLoadRelCase() throws Exception {
136137
getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.css"), "", MimeType.TEXT_CSS);
137138
onLoadOnError("rel='sTYLeSheet' href='simple.css'");
@@ -141,7 +142,7 @@ public void onLoadRelCase() throws Exception {
141142
* @throws Exception if an error occurs
142143
*/
143144
@Test
144-
@Alerts({"onLoad", "body onLoad"})
145+
@Alerts({"2", "onLoad", "body onLoad"})
145146
public void onLoadMediaScreen() throws Exception {
146147
getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.css"), "", MimeType.TEXT_CSS);
147148
onLoadOnError("rel='stylesheet' href='simple.css' media='screen'");
@@ -151,7 +152,7 @@ public void onLoadMediaScreen() throws Exception {
151152
* @throws Exception if an error occurs
152153
*/
153154
@Test
154-
@Alerts({"onLoad", "body onLoad"})
155+
@Alerts({"2", "onLoad", "body onLoad"})
155156
public void onLoadMediaPrint() throws Exception {
156157
getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.css"), "", MimeType.TEXT_CSS);
157158
onLoadOnError("rel='stylesheet' href='simple.css' media='print'");
@@ -161,7 +162,7 @@ public void onLoadMediaPrint() throws Exception {
161162
* @throws Exception if an error occurs
162163
*/
163164
@Test
164-
@Alerts({"onLoad", "body onLoad"})
165+
@Alerts({"2", "onLoad", "body onLoad"})
165166
public void onLoadMediaQueryMatch() throws Exception {
166167
getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.css"), "", MimeType.TEXT_CSS);
167168
onLoadOnError("rel='stylesheet' href='simple.css' media='(min-width: 100px)'");
@@ -171,7 +172,7 @@ public void onLoadMediaQueryMatch() throws Exception {
171172
* @throws Exception if an error occurs
172173
*/
173174
@Test
174-
@Alerts({"onLoad", "body onLoad"})
175+
@Alerts({"2", "onLoad", "body onLoad"})
175176
public void onLoadMediaQueryNotMatch() throws Exception {
176177
getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.css"), "", MimeType.TEXT_CSS);
177178
onLoadOnError("rel='stylesheet' href='simple.css' media='(max-width: 10px)'");
@@ -181,7 +182,7 @@ public void onLoadMediaQueryNotMatch() throws Exception {
181182
* @throws Exception if an error occurs
182183
*/
183184
@Test
184-
@Alerts({"onLoad", "body onLoad"})
185+
@Alerts({"2", "onLoad", "body onLoad"})
185186
public void onLoadRelWhitespace() throws Exception {
186187
getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.css"), "", MimeType.TEXT_CSS);
187188
onLoadOnError("rel='\t stylesheet ' href='simple.css'");
@@ -191,7 +192,7 @@ public void onLoadRelWhitespace() throws Exception {
191192
* @throws Exception if an error occurs
192193
*/
193194
@Test
194-
@Alerts({"onLoad", "body onLoad"})
195+
@Alerts({"2", "onLoad", "body onLoad"})
195196
public void onLoadTypeCss() throws Exception {
196197
getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.css"), "", MimeType.TEXT_CSS);
197198
onLoadOnError("rel='stylesheet' href='simple.css' type='" + MimeType.TEXT_CSS + "'");
@@ -201,7 +202,9 @@ public void onLoadTypeCss() throws Exception {
201202
* @throws Exception if an error occurs
202203
*/
203204
@Test
204-
@Alerts("body onLoad")
205+
@Alerts(DEFAULT = {"1", "body onLoad"},
206+
FF = {"2", "body onLoad"},
207+
FF_ESR = {"2", "body onLoad"})
205208
public void onLoadTypePlain() throws Exception {
206209
getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.css"), "", MimeType.TEXT_CSS);
207210
onLoadOnError("rel='stylesheet' href='simple.css' type='" + MimeType.TEXT_PLAIN + "'");
@@ -211,7 +214,9 @@ public void onLoadTypePlain() throws Exception {
211214
* @throws Exception if an error occurs
212215
*/
213216
@Test
214-
@Alerts("body onLoad")
217+
@Alerts(DEFAULT = {"1", "body onLoad"},
218+
FF = {"2", "body onLoad"},
219+
FF_ESR = {"2", "body onLoad"})
215220
public void onLoadTypeHtml() throws Exception {
216221
getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.css"), "", MimeType.TEXT_CSS);
217222
onLoadOnError("rel='stylesheet' href='simple.css' type='" + MimeType.TEXT_HTML + "'");
@@ -221,7 +226,9 @@ public void onLoadTypeHtml() throws Exception {
221226
* @throws Exception if an error occurs
222227
*/
223228
@Test
224-
@Alerts("body onLoad")
229+
@Alerts(DEFAULT = {"1", "body onLoad"},
230+
FF = {"2", "body onLoad"},
231+
FF_ESR = {"2", "body onLoad"})
225232
public void onLoadTypeJs() throws Exception {
226233
getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.css"), "", MimeType.TEXT_CSS);
227234
onLoadOnError("rel='stylesheet' href='simple.css' type='" + MimeType.TEXT_JAVASCRIPT + "'");
@@ -231,7 +238,9 @@ public void onLoadTypeJs() throws Exception {
231238
* @throws Exception if an error occurs
232239
*/
233240
@Test
234-
@Alerts("body onLoad")
241+
@Alerts(DEFAULT = {"1", "body onLoad"},
242+
FF = {"2", "body onLoad"},
243+
FF_ESR = {"2", "body onLoad"})
235244
public void onLoadTypeGif() throws Exception {
236245
getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.css"), "", MimeType.TEXT_CSS);
237246
onLoadOnError("rel='stylesheet' href='simple.css' type='" + MimeType.IMAGE_GIF + "'");
@@ -242,9 +251,9 @@ public void onLoadTypeGif() throws Exception {
242251
* @throws Exception if an error occurs
243252
*/
244253
@Test
245-
@Alerts(DEFAULT = {"onLoad", "body onLoad"},
246-
FF = {"onError", "body onLoad"},
247-
FF_ESR = {"onError", "body onLoad"})
254+
@Alerts(DEFAULT = {"2", "onLoad", "body onLoad"},
255+
FF = {"2", "onError", "body onLoad"},
256+
FF_ESR = {"2", "onError", "body onLoad"})
248257
public void onLoadResponseTypePlain() throws Exception {
249258
getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.css"), "", MimeType.TEXT_PLAIN);
250259
onLoadOnError("rel='stylesheet' href='simple.css'");
@@ -254,9 +263,9 @@ public void onLoadResponseTypePlain() throws Exception {
254263
* @throws Exception if an error occurs
255264
*/
256265
@Test
257-
@Alerts(DEFAULT = {"onLoad", "body onLoad"},
258-
FF = {"onError", "body onLoad"},
259-
FF_ESR = {"onError", "body onLoad"})
266+
@Alerts(DEFAULT = {"2", "onLoad", "body onLoad"},
267+
FF = {"2", "onError", "body onLoad"},
268+
FF_ESR = {"2", "onError", "body onLoad"})
260269
public void onLoadResponseTypeHtml() throws Exception {
261270
getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.css"), "", MimeType.TEXT_HTML);
262271
onLoadOnError("rel='stylesheet' href='simple.css'");
@@ -266,9 +275,9 @@ public void onLoadResponseTypeHtml() throws Exception {
266275
* @throws Exception if an error occurs
267276
*/
268277
@Test
269-
@Alerts(DEFAULT = {"onLoad", "body onLoad"},
270-
FF = {"onError", "body onLoad"},
271-
FF_ESR = {"onError", "body onLoad"})
278+
@Alerts(DEFAULT = {"2", "onLoad", "body onLoad"},
279+
FF = {"2", "onError", "body onLoad"},
280+
FF_ESR = {"2", "onError", "body onLoad"})
272281
public void onLoadResponseTypeJs() throws Exception {
273282
getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.css"), "", MimeType.TEXT_JAVASCRIPT);
274283
onLoadOnError("rel='stylesheet' href='simple.css'");
@@ -278,9 +287,9 @@ public void onLoadResponseTypeJs() throws Exception {
278287
* @throws Exception if an error occurs
279288
*/
280289
@Test
281-
@Alerts(DEFAULT = {"onLoad", "body onLoad"},
282-
FF = {"onError", "body onLoad"},
283-
FF_ESR = {"onError", "body onLoad"})
290+
@Alerts(DEFAULT = {"2", "onLoad", "body onLoad"},
291+
FF = {"2", "onError", "body onLoad"},
292+
FF_ESR = {"2", "onError", "body onLoad"})
284293
public void onLoadResponseTypeGif() throws Exception {
285294
getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.css"), "", MimeType.IMAGE_GIF);
286295
onLoadOnError("rel='stylesheet' href='simple.css'");
@@ -290,7 +299,7 @@ public void onLoadResponseTypeGif() throws Exception {
290299
* @throws Exception if an error occurs
291300
*/
292301
@Test
293-
@Alerts({"onError", "body onLoad"})
302+
@Alerts({"2", "onError", "body onLoad"})
294303
public void onError() throws Exception {
295304
onLoadOnError("rel='stylesheet' href='unknown.css'");
296305
}
@@ -299,7 +308,7 @@ public void onError() throws Exception {
299308
* @throws Exception if an error occurs
300309
*/
301310
@Test
302-
@Alerts("body onLoad")
311+
@Alerts({"1", "body onLoad"})
303312
public void onLoadOnErrorWithoutRel() throws Exception {
304313
onLoadOnError("href='unknown.css'");
305314
}
@@ -319,18 +328,26 @@ private void onLoadOnError(final String attribs) throws Exception {
319328
+ "</html>";
320329
getMockWebConnection().setDefaultResponse("Error: not found", 404, "Not Found", MimeType.TEXT_HTML);
321330

331+
final int requests = getMockWebConnection().getRequestCount();
332+
final String[] expected = getExpectedAlerts();
333+
setExpectedAlerts(Arrays.copyOfRange(expected, 1, expected.length));
322334
loadPageVerifyTitle2(html);
335+
336+
final int count = Integer.parseInt(expected[0]);
337+
assertEquals(count, getMockWebConnection().getRequestCount() - requests);
323338
}
324339

325340
/**
326341
* @throws Exception if an error occurs
327342
*/
328343
@Test
329-
@Alerts({"onLoad1", "onLoadJs1", "onLoad2", "body onLoad"})
344+
@Alerts(DEFAULT = {"4", "onLoad1", "onLoadJs1", "onLoad2", "body onLoad"},
345+
FF = {"4", "onLoadJs1", "onLoad2", "body onLoad"},
346+
FF_ESR = {"4", "onLoadJs1", "onLoad2", "body onLoad"})
330347
public void onLoadOrder() throws Exception {
331348
getMockWebConnection().setResponse(new URL(URL_FIRST, "simple1.css"), "");
332-
getMockWebConnection().setResponse(new URL(URL_FIRST, "simple2.css"), "");
333-
getMockWebConnection().setResponse(new URL(URL_FIRST, "simple1.js"), "var x=1;");
349+
getMockWebConnection().setResponse(new URL(URL_FIRST, "simple2.css"), "", MimeType.TEXT_CSS);
350+
getMockWebConnection().setResponse(new URL(URL_FIRST, "simple1.js"), "var x=1;", MimeType.TEXT_JAVASCRIPT);
334351

335352
final String html = DOCTYPE_HTML
336353
+ "<html>\n"
@@ -346,7 +363,13 @@ public void onLoadOrder() throws Exception {
346363
+ "</body>\n"
347364
+ "</html>";
348365

366+
final int requests = getMockWebConnection().getRequestCount();
367+
final String[] expected = getExpectedAlerts();
368+
setExpectedAlerts(Arrays.copyOfRange(expected, 1, expected.length));
349369
loadPageVerifyTitle2(html);
370+
371+
final int count = Integer.parseInt(expected[0]);
372+
assertEquals(count, getMockWebConnection().getRequestCount() - requests);
350373
}
351374

352375
/**

src/test/java/org/htmlunit/javascript/JavaScriptEngine2Test.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,4 +1247,28 @@ public void matchAll() throws Exception {
12471247

12481248
loadPageVerifyTitle2(html);
12491249
}
1250+
1251+
/**
1252+
* Make sure we use the TopScope, otherwise some GeneratorFunction stuff
1253+
* does not work.
1254+
* @throws Exception if the test fails
1255+
*/
1256+
@Test
1257+
@Alerts({"anonymous", "false", "false", "true"})
1258+
public void generatorFunction() throws Exception {
1259+
final String html = DOCTYPE_HTML
1260+
+ "<html><body>"
1261+
+ "<script>\n"
1262+
+ LOG_TITLE_FUNCTION
1263+
+ "var GeneratorFunction = Object.getPrototypeOf(function*() {}).constructor;\n"
1264+
1265+
+ "log(GeneratorFunction().name);\n"
1266+
+ "log(Object.getOwnPropertyDescriptor(GeneratorFunction(), 'name').enumerable);\n"
1267+
+ "log(Object.getOwnPropertyDescriptor(GeneratorFunction(), 'name').writable);\n"
1268+
+ "log(Object.getOwnPropertyDescriptor(GeneratorFunction(), 'name').configurable);\n"
1269+
+ "</script></body></html>";
1270+
1271+
loadPageVerifyTitle2(html);
1272+
}
1273+
12501274
}

0 commit comments

Comments
 (0)