From: <rb...@us...> - 2017-10-24 19:05:21
|
Revision: 14878 http://sourceforge.net/p/htmlunit/code/14878 Author: rbri Date: 2017-10-24 19:05:18 +0000 (Tue, 24 Oct 2017) Log Message: ----------- trigger load/error event when loading stylesheets Modified Paths: -------------- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlLink.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/StyleSheetList.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/html/HtmlLink2Test.java Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlLink.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlLink.java 2017-10-22 08:18:05 UTC (rev 14877) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlLink.java 2017-10-24 19:05:18 UTC (rev 14878) @@ -21,10 +21,16 @@ import java.net.URL; import java.util.Map; +import org.apache.http.HttpStatus; + import com.gargoylesoftware.htmlunit.SgmlPage; import com.gargoylesoftware.htmlunit.WebClient; import com.gargoylesoftware.htmlunit.WebRequest; import com.gargoylesoftware.htmlunit.WebResponse; +import com.gargoylesoftware.htmlunit.javascript.host.event.Event; +import com.gargoylesoftware.htmlunit.javascript.host.event.Event2; +import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLLinkElement; +import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLLinkElement2; /** * Wrapper for the HTML element "link". <b>Note:</b> This is not a clickable link, @@ -165,15 +171,28 @@ * received when performing a request for the content referenced by this tag otherwise * @throws IOException if an error occurs while downloading the content */ - public WebResponse getWebResponse(final boolean downloadIfNeeded, final WebRequest request) throws IOException { + public WebResponse getWebResponse(final boolean downloadIfNeeded, WebRequest request) throws IOException { if (downloadIfNeeded && cachedWebResponse_ == null) { final WebClient webclient = getPage().getWebClient(); if (null == request) { - cachedWebResponse_ = webclient.loadWebResponse(getWebRequest()); + request = getWebRequest(); } - else { + try { cachedWebResponse_ = webclient.loadWebResponse(request); + final int statusCode = cachedWebResponse_.getStatusCode(); + final boolean successful = statusCode >= HttpStatus.SC_OK + && statusCode < HttpStatus.SC_MULTIPLE_CHOICES; + if (successful) { + executeEvent(Event.TYPE_LOAD); + } + else { + executeEvent(Event.TYPE_ERROR); + } } + catch (final IOException e) { + executeEvent(Event.TYPE_ERROR); + throw e; + } } return cachedWebResponse_; } @@ -215,4 +234,53 @@ public boolean mayBeDisplayed() { return false; } + + private void executeEvent(final String type) { + final Object scriptable = getScriptableObject(); + if (scriptable instanceof HTMLLinkElement2) { + final HTMLLinkElement2 script = (HTMLLinkElement2) scriptable; + final Event2 event = new Event2(this, type); + script.executeEventLocally(event); + } + else { + final HTMLLinkElement link = (HTMLLinkElement) scriptable; + final Event event = new Event(this, type); + link.executeEventLocally(event); + } + } + +// /** +// * {@inheritDoc} +// */ +// @Override +// protected void onAllChildrenAddedToPage(final boolean postponed) { +// if (getOwnerDocument() instanceof XmlPage) { +// return; +// } +// if (LOG.isDebugEnabled()) { +// LOG.debug("Link node added: " + asXml()); +// } +// +// final PostponedAction action = new PostponedAction(getPage(), "Loading of link " + this) { +// @Override +// public void execute() { +// } +// }; +// +// final AbstractJavaScriptEngine<?> engine = getPage().getWebClient().getJavaScriptEngine(); +// if (postponed) { +// engine.addPostponedAction(action); +// } +// else { +// try { +// action.execute(); +// } +// catch (final RuntimeException e) { +// throw e; +// } +// catch (final Exception e) { +// throw new RuntimeException(e); +// } +// } +// } } Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/StyleSheetList.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/StyleSheetList.java 2017-10-22 08:18:05 UTC (rev 14877) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/StyleSheetList.java 2017-10-24 19:05:18 UTC (rev 14878) @@ -74,8 +74,15 @@ * @return true if the provided node is a stylesheet link */ public static boolean isStyleSheetLink(final DomNode domNode) { - return domNode instanceof HtmlLink - && "stylesheet".equalsIgnoreCase(((HtmlLink) domNode).getRelAttribute()); + if (domNode instanceof HtmlLink) { + final HtmlLink link = (HtmlLink) domNode; + String rel = link.getRelAttribute(); + if (rel != null) { + rel = rel.trim(); + } + return "stylesheet".equalsIgnoreCase(rel); + } + return false; } /** @@ -87,7 +94,11 @@ public boolean isActiveStyleSheetLink(final DomNode domNode) { if (domNode instanceof HtmlLink) { final HtmlLink link = (HtmlLink) domNode; - if ("stylesheet".equalsIgnoreCase(link.getRelAttribute())) { + String rel = link.getRelAttribute(); + if (rel != null) { + rel = rel.trim(); + } + if ("stylesheet".equalsIgnoreCase(rel)) { final String media = link.getMediaAttribute(); if (StringUtils.isBlank(media)) { return true; Modified: trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/html/HtmlLink2Test.java =================================================================== --- trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/html/HtmlLink2Test.java 2017-10-22 08:18:05 UTC (rev 14877) +++ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/html/HtmlLink2Test.java 2017-10-24 19:05:18 UTC (rev 14878) @@ -14,6 +14,11 @@ */ package com.gargoylesoftware.htmlunit.html; +import static com.gargoylesoftware.htmlunit.BrowserRunner.TestedBrowser.CHROME; +import static com.gargoylesoftware.htmlunit.BrowserRunner.TestedBrowser.IE; + +import java.net.URL; + import org.junit.Test; import org.junit.runner.RunWith; import org.openqa.selenium.By; @@ -22,6 +27,7 @@ import com.gargoylesoftware.htmlunit.BrowserRunner; import com.gargoylesoftware.htmlunit.BrowserRunner.Alerts; +import com.gargoylesoftware.htmlunit.BrowserRunner.NotYetImplemented; import com.gargoylesoftware.htmlunit.WebDriverTestCase; /** @@ -94,4 +100,110 @@ final boolean displayed = driver.findElement(By.id("l")).isDisplayed(); assertFalse(displayed); } + + /** + * @throws Exception if an error occurs + */ + @Test + @Alerts({"onLoad", "body onLoad"}) + public void onLoad() throws Exception { + getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.css"), ""); + onLoadOnError("rel='stylesheet' href='simple.css'"); + } + + /** + * @throws Exception if an error occurs + */ + @Test + @Alerts({"onLoad", "body onLoad"}) + public void onLoadRelCase() throws Exception { + getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.css"), ""); + onLoadOnError("rel='sTYLeSheet' href='simple.css'"); + } + + /** + * @throws Exception if an error occurs + */ + @Test + @Alerts({"onLoad", "body onLoad"}) + public void onLoadMediaScreen() throws Exception { + getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.css"), ""); + onLoadOnError("rel='stylesheet' href='simple.css' media='screen'"); + } + + /** + * @throws Exception if an error occurs + */ + @Test + @Alerts({"onLoad", "body onLoad"}) + @NotYetImplemented(CHROME) + public void onLoadMediaPrint() throws Exception { + getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.css"), ""); + onLoadOnError("rel='stylesheet' href='simple.css' media='print'"); + } + + /** + * @throws Exception if an error occurs + */ + @Test + @Alerts({"onLoad", "body onLoad"}) + public void onLoadMediaQueryMatch() throws Exception { + getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.css"), ""); + onLoadOnError("rel='stylesheet' href='simple.css' media='(min-width: 100px)'"); + } + + /** + * @throws Exception if an error occurs + */ + @Test + @Alerts({"onLoad", "body onLoad"}) + @NotYetImplemented(CHROME) + public void onLoadMediaQueryNotMatch() throws Exception { + getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.css"), ""); + onLoadOnError("rel='stylesheet' href='simple.css' media='(max-width: 10px)'"); + } + + /** + * @throws Exception if an error occurs + */ + @Test + @Alerts({"onLoad", "body onLoad"}) + public void onLoadRelWhitespace() throws Exception { + getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.css"), ""); + onLoadOnError("rel='\t stylesheet ' href='simple.css'"); + } + + /** + * @throws Exception if an error occurs + */ + @Test + @Alerts(DEFAULT = {"onError", "body onLoad"}, + IE = {"onLoad", "body onLoad"}) + @NotYetImplemented(IE) + public void onError() throws Exception { + onLoadOnError("rel='stylesheet' href='unknown.css'"); + } + + /** + * @throws Exception if an error occurs + */ + @Test + @Alerts("body onLoad") + public void onLoadOnErrorWithoutRel() throws Exception { + onLoadOnError("href='unknown.css'"); + } + + private void onLoadOnError(final String attribs) throws Exception { + final String html + = "<html>\n" + + "<head>\n" + + " <link " + attribs + + " onload='alert(\"onLoad\")' onerror='alert(\"onError\")'>\n" + + "</head>\n" + + "<body onload='window.getComputedStyle(document.body); alert(\"body onLoad\")'>\n" + + "</body>\n" + + "</html>"; + + loadPageWithAlerts2(html); + } } |