Skip to content

Commit fc0c413

Browse files
committed
scroll events do not bubble into the document/window
fix target for scroll events on document/window
1 parent f888a19 commit fc0c413

File tree

6 files changed

+161
-10
lines changed

6 files changed

+161
-10
lines changed

src/main/java/org/htmlunit/javascript/host/Element.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,6 +1252,18 @@ private void fireScrollEvent(final Node node) {
12521252
node.fireEvent(event);
12531253
}
12541254

1255+
private void fireScrollEvent(final Window window) {
1256+
final Event event;
1257+
if (getBrowserVersion().hasFeature(EVENT_SCROLL_UIEVENT)) {
1258+
event = new UIEvent(window.getDocument(), Event.TYPE_SCROLL);
1259+
}
1260+
else {
1261+
event = new Event(window.getDocument(), Event.TYPE_SCROLL);
1262+
event.setCancelable(false);
1263+
}
1264+
window.fireEvent(event);
1265+
}
1266+
12551267
/**
12561268
* Scrolls to a particular set of coordinates inside a given element.
12571269
* @param x the horizontal pixel value that you want to scroll to
@@ -1305,6 +1317,7 @@ public void scrollIntoView() {
13051317

13061318
parent = parent.getParent();
13071319
}
1320+
fireScrollEvent(getWindow());
13081321
}
13091322

13101323
/**

src/main/java/org/htmlunit/javascript/host/Window.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,6 +1161,8 @@ public void scrollBy(final Scriptable x, final Scriptable y) {
11611161

11621162
fireScrollEvent(body);
11631163
}
1164+
1165+
fireScrollEvent(document_);
11641166
}
11651167

11661168
private void fireScrollEvent(final Node node) {
@@ -1187,6 +1189,8 @@ public void scrollByLines(final int lines) {
11871189

11881190
fireScrollEvent(body);
11891191
}
1192+
1193+
fireScrollEvent(document_);
11901194
}
11911195

11921196
/**
@@ -1201,6 +1205,8 @@ public void scrollByPages(final int pages) {
12011205

12021206
fireScrollEvent(body);
12031207
}
1208+
1209+
fireScrollEvent(document_);
12041210
}
12051211

12061212
/**
@@ -1238,6 +1244,8 @@ public void scrollTo(final Scriptable x, final Scriptable y) {
12381244

12391245
fireScrollEvent(body);
12401246
}
1247+
1248+
fireScrollEvent(document_);
12411249
}
12421250

12431251
/**

src/main/java/org/htmlunit/javascript/host/event/EventTarget.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.List;
2020

2121
import org.apache.commons.lang3.StringUtils;
22+
import org.htmlunit.Page;
2223
import org.htmlunit.ScriptResult;
2324
import org.htmlunit.corejs.javascript.Function;
2425
import org.htmlunit.corejs.javascript.Scriptable;
@@ -125,6 +126,11 @@ public ScriptResult fireEvent(final Event event) {
125126
// Then add all our parents if we have any (pure JS object such as XMLHttpRequest
126127
// and MessagePort, etc. will not have any parents)
127128
for (DomNode parent = ourParentNode; parent != null; parent = parent.getParentNode()) {
129+
// scroll does not bubble into the document/window
130+
if (Event.TYPE_SCROLL.equals(event.getType()) && parent instanceof Page) {
131+
break;
132+
}
133+
128134
propagationPath.add(parent.getScriptableObject());
129135
}
130136

src/test/java/org/htmlunit/javascript/host/Window3Test.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,8 @@ public void scrollBy() throws Exception {
482482
+ "<script>\n"
483483
+ LOG_TITLE_FUNCTION
484484
+ "window.scrollBy(10, 20);\n"
485-
+ "</script></head><body>\n"
485+
+ "</script></head>\n"
486+
+ "<body>\n"
486487
+ "</body></html>";
487488
loadPageVerifyTitle2(html);
488489
}
@@ -491,15 +492,17 @@ public void scrollBy() throws Exception {
491492
* @throws Exception if the test fails
492493
*/
493494
@Test
494-
@Alerts({"document", "body"})
495+
@Alerts({"document [object HTMLDocument]", "body", "window [object HTMLDocument]"})
495496
public void scrollByEvents() throws Exception {
496497
final String html = DOCTYPE_HTML
497498
+ "<html>\n"
498499
+ "<head>\n"
499500
+ "<script>\n"
500501
+ LOG_TEXTAREA_FUNCTION
501502
+ " function test() {\n"
502-
+ " document.addEventListener('scroll', function(e) { log(\"document\") });\n"
503+
+ " window.addEventListener('scroll', function(e) { log(\"window \" + e.target) });\n"
504+
+ " document.addEventListener('scroll', function(e) { log(\"document \" + e.target) });\n"
505+
503506
+ " window.scrollBy(10, 20);\n"
504507
+ " }\n"
505508
+ "</script>\n"
@@ -575,15 +578,16 @@ public void scrollTo() throws Exception {
575578
* @throws Exception if the test fails
576579
*/
577580
@Test
578-
@Alerts({"document", "body"})
581+
@Alerts({"document[object HTMLDocument]", "body", "document[object HTMLDocument]"})
579582
public void scrollToEvents() throws Exception {
580583
final String html = DOCTYPE_HTML
581584
+ "<html>\n"
582585
+ "<head>\n"
583586
+ "<script>\n"
584587
+ LOG_TEXTAREA_FUNCTION
585588
+ " function test() {\n"
586-
+ " document.addEventListener('scroll', function(e) { log(\"document\") });\n"
589+
+ " window.addEventListener('scroll', function(e) { log(\"document\" + e.target) });\n"
590+
+ " document.addEventListener('scroll', function(e) { log(\"document\" + e.target) });\n"
587591
+ " window.scrollTo(10, 20);\n"
588592
+ " }\n"
589593
+ "</script>\n"

src/test/java/org/htmlunit/javascript/host/event/EventTest.java

Lines changed: 94 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1520,7 +1520,6 @@ public void domEventNameUsedAsFunctionName() throws Exception {
15201520
}
15211521

15221522
/**
1523-
* Tests that JavaScript scrollIntoView() scrollEvent.
15241523
* @throws Exception if the test fails
15251524
*/
15261525
@Test
@@ -1540,7 +1539,7 @@ public void scrollEventFromScrollIntoView() throws Exception {
15401539
+ "<body>\n"
15411540
+ " <div id='container' style='overflow-y: scroll; height: 100px;'>\n"
15421541
+ " <div style='height: 1000px;'>spacer</div>\n"
1543-
+ " <div id='target' style='background: red;'>Target</div>"
1542+
+ " <div id='target' style='background: red;'>Target</div>\n"
15441543
+ " </div>\n"
15451544

15461545
+ " <script>\n"
@@ -1555,6 +1554,39 @@ public void scrollEventFromScrollIntoView() throws Exception {
15551554

15561555
loadPageVerifyTitle2(html);
15571556
}
1557+
/**
1558+
* @throws Exception if the test fails
1559+
*/
1560+
@Test
1561+
@Alerts(DEFAULT = {"[object Event]", "scroll", "true", "false", "false"},
1562+
FF = {"[object UIEvent]", "scroll", "true", "true", "false"},
1563+
FF_ESR = {"[object UIEvent]", "scroll", "true", "true", "false"})
1564+
public void scrollEventWindowFromScrollIntoView() throws Exception {
1565+
final String html = DOCTYPE_HTML
1566+
+ "<html>\n"
1567+
+ "<head>\n"
1568+
+ "<script>\n"
1569+
+ LOG_TITLE_FUNCTION
1570+
+ DUMP_EVENT_FUNCTION
1571+
+ "</script>\n"
1572+
+ "</head>\n"
1573+
1574+
+ "<body>\n"
1575+
+ " <div id='container' style='height: 10000px;'>\n"
1576+
+ " </div>\n"
1577+
+ " <div id='target' style='background: red;'>Target</div>\n"
1578+
1579+
+ " <script>\n"
1580+
+ " window.addEventListener('scroll', function(e) { dump(e); });\n"
1581+
1582+
+ " var s = document.getElementById('target');"
1583+
+ " s.scrollIntoView();\n"
1584+
+ " </script>\n"
1585+
+ "</body>\n"
1586+
+ "</html>";
1587+
1588+
loadPageVerifyTitle2(html);
1589+
}
15581590

15591591
/**
15601592
* @throws Exception if the test fails
@@ -1586,6 +1618,36 @@ public void scrollEventFromScrollBy() throws Exception {
15861618
loadPageVerifyTitle2(html);
15871619
}
15881620

1621+
/**
1622+
* @throws Exception if the test fails
1623+
*/
1624+
@Test
1625+
@Alerts(DEFAULT = {"[object Event]", "scroll", "true", "false", "false"},
1626+
FF = {"[object UIEvent]", "scroll", "true", "true", "false"},
1627+
FF_ESR = {"[object UIEvent]", "scroll", "true", "true", "false"})
1628+
public void scrollEventWindowFromScrollBy() throws Exception {
1629+
final String html = DOCTYPE_HTML
1630+
+ "<html>\n"
1631+
+ "<head>\n"
1632+
+ "<script>\n"
1633+
+ LOG_TITLE_FUNCTION
1634+
+ DUMP_EVENT_FUNCTION
1635+
+ "</script>\n"
1636+
+ "</head>\n"
1637+
1638+
+ "<body>\n"
1639+
+ " <div style='height: 1000px;'></div>\n"
1640+
1641+
+ " <script>\n"
1642+
+ " window.addEventListener('scroll', function(e) { dump(e) });\n"
1643+
+ " window.scrollBy(10, 20);\n"
1644+
+ " </script>\n"
1645+
+ "</body>\n"
1646+
+ "</html>";
1647+
1648+
loadPageVerifyTitle2(html);
1649+
}
1650+
15891651
/**
15901652
* @throws Exception if the test fails
15911653
*/
@@ -1615,4 +1677,34 @@ public void scrollEventFromScrollTo() throws Exception {
16151677

16161678
loadPageVerifyTitle2(html);
16171679
}
1680+
1681+
/**
1682+
* @throws Exception if the test fails
1683+
*/
1684+
@Test
1685+
@Alerts(DEFAULT = {"[object Event]", "scroll", "true", "false", "false"},
1686+
FF = {"[object UIEvent]", "scroll", "true", "true", "false"},
1687+
FF_ESR = {"[object UIEvent]", "scroll", "true", "true", "false"})
1688+
public void scrollEventWindowFromScrollTo() throws Exception {
1689+
final String html = DOCTYPE_HTML
1690+
+ "<html>\n"
1691+
+ "<head>\n"
1692+
+ "<script>\n"
1693+
+ LOG_TITLE_FUNCTION
1694+
+ DUMP_EVENT_FUNCTION
1695+
+ "</script>\n"
1696+
+ "</head>\n"
1697+
1698+
+ "<body>\n"
1699+
+ " <div style='height: 1000px;'></div>\n"
1700+
1701+
+ " <script>\n"
1702+
+ " window.addEventListener('scroll', function(e) { dump(e) });\n"
1703+
+ " window.scrollTo(10, 20);\n"
1704+
+ " </script>\n"
1705+
+ "</body>\n"
1706+
+ "</html>";
1707+
1708+
loadPageVerifyTitle2(html);
1709+
}
16181710
}

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

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2157,7 +2157,6 @@ public void scrollIntoView() throws Exception {
21572157
}
21582158

21592159
/**
2160-
* Tests that JavaScript scrollIntoView() scrollEvent.
21612160
* @throws Exception if the test fails
21622161
*/
21632162
@Test
@@ -2200,7 +2199,6 @@ public void scrollIntoViewTriggersOnScroll() throws Exception {
22002199
}
22012200

22022201
/**
2203-
* Tests that JavaScript scrollIntoView() scrollEvent.
22042202
* @throws Exception if the test fails
22052203
*/
22062204
@Test
@@ -2253,7 +2251,37 @@ public void scrollIntoViewTriggersOnScrollBubbling() throws Exception {
22532251
}
22542252

22552253
/**
2256-
* Tests for issue #942.
2254+
* @throws Exception if the test fails
2255+
*/
2256+
@Test
2257+
@Alerts("window [object HTMLDocument]")
2258+
public void scrollIntoViewTriggersWindowOnScroll() throws Exception {
2259+
final String html = DOCTYPE_HTML
2260+
+ "<html>\n"
2261+
+ "<head>\n"
2262+
+ "<script>\n"
2263+
+ LOG_TITLE_FUNCTION
2264+
+ "</script>\n"
2265+
+ "</head>\n"
2266+
2267+
+ "<body>\n"
2268+
+ " <div style='height: 10000px;'>spacer</div>\n"
2269+
+ " <div id='target' style='background: red;'>Target</div>"
2270+
2271+
+ " <script>\n"
2272+
+ " window.addEventListener('scroll', function(e) { log('window ' + e.target) });\n"
2273+
2274+
+ " var s = document.getElementById('target');"
2275+
+ " s.scrollIntoView();\n"
2276+
+ " </script>\n"
2277+
+ "</body>\n"
2278+
+ "</html>";
2279+
2280+
loadPageVerifyTitle2(html);
2281+
}
2282+
2283+
/**
2284+
* Test for issue #942.
22572285
* @throws Exception if the test fails
22582286
*/
22592287
@Test

0 commit comments

Comments
 (0)