Skip to content

Commit 51922cd

Browse files
duonglaiquangrbri
authored andcommitted
HtmlImage: fix Image.onload() being called immediately instead of later
1 parent 9eecaac commit 51922cd

File tree

3 files changed

+93
-39
lines changed

3 files changed

+93
-39
lines changed

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

Lines changed: 44 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,51 +1000,57 @@ public <P extends Page> P click(final boolean shiftKey, final boolean ctrlKey, f
10001000
mouseDown(shiftKey, ctrlKey, altKey, MouseEvent.BUTTON_LEFT);
10011001
}
10021002

1003-
if (handleFocus) {
1004-
// give focus to current element (if possible) or only remove it from previous one
1005-
DomElement elementToFocus = null;
1006-
if (this instanceof SubmittableElement
1007-
|| this instanceof HtmlAnchor
1008-
&& ATTRIBUTE_NOT_DEFINED != ((HtmlAnchor) this).getHrefAttribute()
1009-
|| this instanceof HtmlArea
1010-
&& (ATTRIBUTE_NOT_DEFINED != ((HtmlArea) this).getHrefAttribute()
1011-
|| getPage().getWebClient().getBrowserVersion().hasFeature(JS_AREA_WITHOUT_HREF_FOCUSABLE))
1012-
|| this instanceof HtmlElement && ((HtmlElement) this).getTabIndex() != null) {
1013-
elementToFocus = this;
1014-
}
1015-
else if (this instanceof HtmlOption) {
1016-
elementToFocus = ((HtmlOption) this).getEnclosingSelect();
1017-
}
1003+
final JavaScriptEngine jsEngine = (JavaScriptEngine)page.getWebClient().getJavaScriptEngine();
1004+
jsEngine.holdPosponedActions();
1005+
try {
1006+
if (handleFocus) {
1007+
// give focus to current element (if possible) or only remove it from previous one
1008+
DomElement elementToFocus = null;
1009+
if (this instanceof SubmittableElement
1010+
|| this instanceof HtmlAnchor
1011+
&& ATTRIBUTE_NOT_DEFINED != ((HtmlAnchor)this).getHrefAttribute()
1012+
|| 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) {
1016+
elementToFocus = this;
1017+
}
1018+
else if (this instanceof HtmlOption) {
1019+
elementToFocus = ((HtmlOption)this).getEnclosingSelect();
1020+
}
10181021

1019-
if (elementToFocus == null) {
1020-
((HtmlPage) page).setFocusedElement(null);
1021-
}
1022-
else {
1023-
elementToFocus.focus();
1022+
if (elementToFocus == null) {
1023+
((HtmlPage)page).setFocusedElement(null);
1024+
}
1025+
else {
1026+
elementToFocus.focus();
1027+
}
10241028
}
1025-
}
10261029

1027-
if (triggerMouseEvents) {
1028-
mouseUp(shiftKey, ctrlKey, altKey, MouseEvent.BUTTON_LEFT);
1029-
}
1030-
1031-
MouseEvent event = null;
1032-
if (page.getWebClient().isJavaScriptEnabled()) {
1033-
final BrowserVersion browser = page.getWebClient().getBrowserVersion();
1034-
if (browser.hasFeature(EVENT_ONCLICK_USES_POINTEREVENT)) {
1035-
event = new PointerEvent(getEventTargetElement(), MouseEvent.TYPE_CLICK, shiftKey,
1036-
ctrlKey, altKey, MouseEvent.BUTTON_LEFT, 1);
1037-
}
1038-
else {
1039-
event = new MouseEvent(getEventTargetElement(), MouseEvent.TYPE_CLICK, shiftKey,
1040-
ctrlKey, altKey, MouseEvent.BUTTON_LEFT, 1);
1030+
if (triggerMouseEvents) {
1031+
mouseUp(shiftKey, ctrlKey, altKey, MouseEvent.BUTTON_LEFT);
10411032
}
10421033

1043-
if (disableProcessLabelAfterBubbling) {
1044-
event.disableProcessLabelAfterBubbling();
1034+
MouseEvent event = null;
1035+
if (page.getWebClient().isJavaScriptEnabled()) {
1036+
final BrowserVersion browser = page.getWebClient().getBrowserVersion();
1037+
if (browser.hasFeature(EVENT_ONCLICK_USES_POINTEREVENT)) {
1038+
event = new PointerEvent(getEventTargetElement(), MouseEvent.TYPE_CLICK, shiftKey,
1039+
ctrlKey, altKey, MouseEvent.BUTTON_LEFT, 1);
1040+
}
1041+
else {
1042+
event = new MouseEvent(getEventTargetElement(), MouseEvent.TYPE_CLICK, shiftKey,
1043+
ctrlKey, altKey, MouseEvent.BUTTON_LEFT, 1);
1044+
}
1045+
1046+
if (disableProcessLabelAfterBubbling) {
1047+
event.disableProcessLabelAfterBubbling();
1048+
}
10451049
}
1050+
return click(event, shiftKey, ctrlKey, altKey, ignoreVisibility);
1051+
} finally {
1052+
jsEngine.processPostponedActions();
10461053
}
1047-
return click(event, shiftKey, ctrlKey, altKey, ignoreVisibility);
10481054
}
10491055
}
10501056

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.htmlunit.WebClient;
4242
import org.htmlunit.WebRequest;
4343
import org.htmlunit.WebResponse;
44+
import org.htmlunit.javascript.JavaScriptEngine;
4445
import org.htmlunit.javascript.PostponedAction;
4546
import org.htmlunit.javascript.host.dom.Document;
4647
import org.htmlunit.javascript.host.event.Event;
@@ -312,7 +313,19 @@ public void execute() {
312313
htmlPage.addAfterLoadAction(action);
313314
}
314315
else {
315-
fireEvent(event);
316+
JavaScriptEngine jsEngine = (JavaScriptEngine) client.getJavaScriptEngine();
317+
if (jsEngine.isScriptRunning()) {
318+
final PostponedAction action = new PostponedAction(getPage(), "HtmlImage.doOnLoad") {
319+
@Override
320+
public void execute() {
321+
HtmlImage.this.fireEvent(event);
322+
}
323+
};
324+
jsEngine.addPostponedAction(action);
325+
}
326+
else {
327+
fireEvent(event);
328+
}
316329
}
317330
}
318331
}

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,4 +317,39 @@ 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+
}
320355
}

0 commit comments

Comments
 (0)