Skip to content

Commit 24edb67

Browse files
committed
Image.onload() must be processed as postponed action documentation and code style
1 parent 51922cd commit 24edb67

File tree

5 files changed

+126
-48
lines changed

5 files changed

+126
-48
lines changed

src/changes/changes.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
Jetty 9 websocket-client.
1919
</action>
2020

21+
<action type="fix" dev="Lai Quang Duong">
22+
Image.onload() must be processed as postponed action.
23+
</action>
2124
<action type="fix" dev="RhinoTeam">
2225
core-js: [Symbol.species] for Promise fixed'.
2326
</action>

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

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -972,7 +972,8 @@ public <P extends Page> P click(final boolean shiftKey, final boolean ctrlKey, f
972972

973973
// make enclosing window the current one
974974
final SgmlPage page = getPage();
975-
page.getWebClient().setCurrentWindow(page.getEnclosingWindow());
975+
final WebClient webClient = page.getWebClient();
976+
webClient.setCurrentWindow(page.getEnclosingWindow());
976977

977978
if (!ignoreVisibility) {
978979
if (!(page instanceof HtmlPage)) {
@@ -1000,27 +1001,27 @@ public <P extends Page> P click(final boolean shiftKey, final boolean ctrlKey, f
10001001
mouseDown(shiftKey, ctrlKey, altKey, MouseEvent.BUTTON_LEFT);
10011002
}
10021003

1003-
final JavaScriptEngine jsEngine = (JavaScriptEngine)page.getWebClient().getJavaScriptEngine();
1004+
final AbstractJavaScriptEngine<?> jsEngine = webClient.getJavaScriptEngine();
10041005
jsEngine.holdPosponedActions();
10051006
try {
10061007
if (handleFocus) {
10071008
// give focus to current element (if possible) or only remove it from previous one
10081009
DomElement elementToFocus = null;
10091010
if (this instanceof SubmittableElement
10101011
|| this instanceof HtmlAnchor
1011-
&& ATTRIBUTE_NOT_DEFINED != ((HtmlAnchor)this).getHrefAttribute()
1012+
&& ATTRIBUTE_NOT_DEFINED != ((HtmlAnchor) this).getHrefAttribute()
10121013
|| this instanceof HtmlArea
1013-
&& (ATTRIBUTE_NOT_DEFINED != ((HtmlArea)this).getHrefAttribute()
1014-
|| getPage().getWebClient().getBrowserVersion().hasFeature(JS_AREA_WITHOUT_HREF_FOCUSABLE))
1015-
|| this instanceof HtmlElement && ((HtmlElement)this).getTabIndex() != null) {
1014+
&& (ATTRIBUTE_NOT_DEFINED != ((HtmlArea) this).getHrefAttribute()
1015+
|| webClient.getBrowserVersion().hasFeature(JS_AREA_WITHOUT_HREF_FOCUSABLE))
1016+
|| this instanceof HtmlElement && ((HtmlElement) this).getTabIndex() != null) {
10161017
elementToFocus = this;
10171018
}
10181019
else if (this instanceof HtmlOption) {
1019-
elementToFocus = ((HtmlOption)this).getEnclosingSelect();
1020+
elementToFocus = ((HtmlOption) this).getEnclosingSelect();
10201021
}
10211022

10221023
if (elementToFocus == null) {
1023-
((HtmlPage)page).setFocusedElement(null);
1024+
((HtmlPage) page).setFocusedElement(null);
10241025
}
10251026
else {
10261027
elementToFocus.focus();
@@ -1032,8 +1033,8 @@ else if (this instanceof HtmlOption) {
10321033
}
10331034

10341035
MouseEvent event = null;
1035-
if (page.getWebClient().isJavaScriptEnabled()) {
1036-
final BrowserVersion browser = page.getWebClient().getBrowserVersion();
1036+
if (webClient.isJavaScriptEnabled()) {
1037+
final BrowserVersion browser = webClient.getBrowserVersion();
10371038
if (browser.hasFeature(EVENT_ONCLICK_USES_POINTEREVENT)) {
10381039
event = new PointerEvent(getEventTargetElement(), MouseEvent.TYPE_CLICK, shiftKey,
10391040
ctrlKey, altKey, MouseEvent.BUTTON_LEFT, 1);
@@ -1048,7 +1049,8 @@ else if (this instanceof HtmlOption) {
10481049
}
10491050
}
10501051
return click(event, shiftKey, ctrlKey, altKey, ignoreVisibility);
1051-
} finally {
1052+
}
1053+
finally {
10521054
jsEngine.processPostponedActions();
10531055
}
10541056
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
import org.htmlunit.WebClient;
4242
import org.htmlunit.WebRequest;
4343
import org.htmlunit.WebResponse;
44-
import org.htmlunit.javascript.JavaScriptEngine;
44+
import org.htmlunit.javascript.AbstractJavaScriptEngine;
4545
import org.htmlunit.javascript.PostponedAction;
4646
import org.htmlunit.javascript.host.dom.Document;
4747
import org.htmlunit.javascript.host.event.Event;
@@ -313,7 +313,7 @@ public void execute() {
313313
htmlPage.addAfterLoadAction(action);
314314
}
315315
else {
316-
JavaScriptEngine jsEngine = (JavaScriptEngine) client.getJavaScriptEngine();
316+
final AbstractJavaScriptEngine<?> jsEngine = client.getJavaScriptEngine();
317317
if (jsEngine.isScriptRunning()) {
318318
final PostponedAction action = new PostponedAction(getPage(), "HtmlImage.doOnLoad") {
319319
@Override

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

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -317,39 +317,4 @@ public void clickWithCoordinates() throws Exception {
317317
img.click(2, 7);
318318
assertEquals(getExpectedAlerts()[0] + getExpectedAlerts()[1], page.getTitleText());
319319
}
320-
321-
/**
322-
* @throws Exception on test failure
323-
*/
324-
@Test
325-
@Alerts({"in-out-Image.onload(0)-", "mousedown-in-out-Image.onload(1)-mouseup-in-out-click-in-out-Image.onload(2)-Image.onload(3)-"})
326-
public void onload() throws Exception {
327-
final String html =
328-
"<html>\n"
329-
+ "<head>\n"
330-
+ "<script>\n"
331-
+ " function log(msg) { window.document.title += msg + '-';}\n"
332-
+ " function test(i) {\n"
333-
+ " log('in');\n"
334-
+ " var image = new Image();\n"
335-
+ " image.onload = function () { log(\"Image.onload(\" + i + \")\") };\n"
336-
+ " image.src = '4x7.jpg';\n"
337-
+ " log('out');\n"
338-
+ " }\n"
339-
+ "</script>\n"
340-
+ "</head>\n"
341-
+ "<body onload=\"test(0)\">\n"
342-
+ "<button onmousedown=\"log('mousedown'); test(1)\""
343-
+ " onmouseup=\"log('mouseup'); test(2)\""
344-
+ " onclick=\"log('click'); test(3)\"></button>\n"
345-
+ "</body>\n"
346-
+ "</html>\n";
347-
348-
final HtmlPage page = loadPage(html);
349-
assertEquals(getExpectedAlerts()[0], page.getTitleText());
350-
351-
page.setTitleText("");
352-
page.<HtmlButton>getFirstByXPath("//button").click();
353-
assertEquals(getExpectedAlerts()[1], page.getTitleText());
354-
}
355320
}

src/test/java/org/htmlunit/javascript/host/html/HTMLImageElement2Test.java

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,20 @@
1414
*/
1515
package org.htmlunit.javascript.host.html;
1616

17+
import java.io.InputStream;
18+
import java.util.ArrayList;
19+
import java.util.Collections;
20+
import java.util.List;
21+
22+
import org.apache.commons.io.IOUtils;
23+
import org.htmlunit.CollectingAlertHandler;
1724
import org.htmlunit.MockWebConnection;
1825
import org.htmlunit.SimpleWebTestCase;
1926
import org.htmlunit.WebClient;
27+
import org.htmlunit.html.HtmlPage;
2028
import org.htmlunit.junit.BrowserRunner;
2129
import org.htmlunit.util.MimeType;
30+
import org.htmlunit.util.NameValuePair;
2231
import org.junit.Test;
2332
import org.junit.runner.RunWith;
2433

@@ -51,4 +60,103 @@ public void onLoad_notDownloadedWhenJavascriptDisabled() throws Exception {
5160
loadPageWithAlerts(html);
5261
assertEquals(URL_FIRST, conn.getLastWebRequest().getUrl());
5362
}
63+
64+
/**
65+
* Make sure this works without an exception.
66+
*
67+
* @throws Exception on test failure
68+
*/
69+
@Test
70+
public void onload_complex_JavascriptDisabled() throws Exception {
71+
try (InputStream is = getClass().getClassLoader().getResourceAsStream("testfiles/tiny-jpg.img")) {
72+
final byte[] directBytes = IOUtils.toByteArray(is);
73+
74+
final List<NameValuePair> emptyList = Collections.emptyList();
75+
getMockWebConnection().setResponse(URL_SECOND, directBytes, 200, "ok", MimeType.IMAGE_JPEG, emptyList);
76+
}
77+
78+
final String html =
79+
"<html>\n"
80+
+ "<head>\n"
81+
+ "<script>\n"
82+
+ " function test(i) {\n"
83+
+ " alert('in');\n"
84+
+ " var image = new Image();\n"
85+
+ " image.onload = function () { alert(\"Image.onload(\" + i + \")\") };\n"
86+
+ " image.src = '" + URL_SECOND + "';\n"
87+
+ " alert('out');\n"
88+
+ " }\n"
89+
+ "</script>\n"
90+
+ "</head>\n"
91+
+ "<body onload='test(0)'>\n"
92+
+ "<button id='myId'"
93+
+ "onmousedown=\"alert('mousedown'); test(1)\" "
94+
+ "onmouseup=\"alert('mouseup'); test(2)\" "
95+
+ "onclick=\"alert('click'); test(3)\"></button>\n"
96+
+ "</body>\n"
97+
+ "</html>\n";
98+
99+
final WebClient client = getWebClientWithMockWebConnection();
100+
client.getOptions().setJavaScriptEnabled(false);
101+
102+
final List<String> collectedAlerts = new ArrayList<>();
103+
client.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
104+
105+
final HtmlPage page = loadPage(html);
106+
page.getElementById("myId").click();
107+
assertEquals(getExpectedAlerts(), collectedAlerts);
108+
assertEquals(URL_FIRST, getMockWebConnection().getLastWebRequest().getUrl());
109+
}
110+
111+
/**
112+
* Make sure this works without an exception.
113+
*
114+
* @throws Exception on test failure
115+
*/
116+
@Test
117+
public void onload_complex_JavascriptEngineDisabled() throws Exception {
118+
try (InputStream is = getClass().getClassLoader().getResourceAsStream("testfiles/tiny-jpg.img")) {
119+
final byte[] directBytes = IOUtils.toByteArray(is);
120+
121+
final List<NameValuePair> emptyList = Collections.emptyList();
122+
getMockWebConnection().setResponse(URL_SECOND, directBytes, 200, "ok", MimeType.IMAGE_JPEG, emptyList);
123+
}
124+
125+
final String html =
126+
"<html>\n"
127+
+ "<head>\n"
128+
+ "<script>\n"
129+
+ " function test(i) {\n"
130+
+ " alert('in');\n"
131+
+ " var image = new Image();\n"
132+
+ " image.onload = function () { alert(\"Image.onload(\" + i + \")\") };\n"
133+
+ " image.src = '" + URL_SECOND + "';\n"
134+
+ " alert('out');\n"
135+
+ " }\n"
136+
+ "</script>\n"
137+
+ "</head>\n"
138+
+ "<body onload='test(0)'>\n"
139+
+ "<button id='myId'"
140+
+ "onmousedown=\"alert('mousedown'); test(1)\" "
141+
+ "onmouseup=\"alert('mouseup'); test(2)\" "
142+
+ "onclick=\"alert('click'); test(3)\"></button>\n"
143+
+ "</body>\n"
144+
+ "</html>\n";
145+
146+
try (WebClient webClient = new WebClient(getBrowserVersion(), false, null, -1)) {
147+
final List<String> collectedAlerts = new ArrayList<>();
148+
webClient.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
149+
150+
final MockWebConnection webConnection = getMockWebConnection();
151+
webConnection.setResponse(URL_FIRST, html);
152+
153+
webClient.setWebConnection(webConnection);
154+
155+
final HtmlPage page = loadPage(html);
156+
page.getElementById("myId").click();
157+
assertEquals(getExpectedAlerts(), collectedAlerts);
158+
assertEquals(URL_SECOND, webConnection.getLastWebRequest().getUrl());
159+
}
160+
}
161+
54162
}

0 commit comments

Comments
 (0)