-
-
Notifications
You must be signed in to change notification settings - Fork 184
Description
Problem in brief
This following Javascript will reload the "topFrame" frame, but to the wrong address if the code was run from a different frame.
parent.topFrame.location.reload();Reproducing
frameset.html:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN">
<html>
<frameset rows="150,*">
<frame name="topFrame" src="top.html">
<frame name="bottomFrame" src="bottom.html">
</frameset>
</html>bottom.html:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<script>
function test() {
parent.topFrame.location.reload();
}
</script>
</head>
<body>
<button onclick="test()">test</button>
</body>
</html>- When the button "test" in the bottom frame is clicked, the topFrame is reloaded.
- However, the topFrame is reloaded to the new address of "bottom.html" instead of "top.html".
- Therefore, both the top and bottom frames become "bottom.html".
Details
The problem appears to be due to the use of getWindow(getStartingScope()) here in reload() rather than window_. I do not know what the purpose of getWindow(getStartingScope()) is here but since a location instance holds its own address in window_, I don't know why getStartingScope() is being used instead of window_.
Another place using getStartingScope() is in Location.setHref() and I think it makes more sense.
I think reload() was implemented as setHref(getHref()) in the past and when it was later refactored to the current form, getWindow(getStartingScope()) was copied here incorrectly.
Suggested fix
* @throws IOException if there is a problem reloading the page
* @see <a href="http://msdn.microsoft.com/en-us/library/ms536342.aspx">MSDN Documentation</a>
*/
@JsxFunction
public void reload(final boolean force) throws IOException {
- final HtmlPage htmlPage = (HtmlPage) getWindow(getStartingScope()).getWebWindow().getEnclosedPage();
+ final HtmlPage htmlPage = (HtmlPage) window_.getWebWindow().getEnclosedPage();
final WebRequest request = htmlPage.getWebResponse().getWebRequest();
if (getBrowserVersion().hasFeature(JS_LOCATION_RELOAD_REFERRER)) {Test case
Here's a test that can be used in LocationTest.java.
/**
* Tests that location.reload() works correctly when invoked across frames.
*/
@Test
public void reloadAcrossFrames() throws Exception {
try (final WebClient webClient = getWebClient();
final MockWebConnection webConnection = new MockWebConnection()) {
final String framesetContent = ""
+ "<html>\n"
+ " <frameset rows='100,*'>\n"
+ " <frame name='upper' src='upper.html'/>\n"
+ " <frame name='lower' src='lower.html'/>\n"
+ " </frameset>\n"
+ "</html>";
final String upperContent = "<html><body><h1>upper</h1></body></html>";
final String lowerContent = ""
+ "<html><head>\n"
+ "<script>\n"
+ "function test() {\n"
+ " parent.upper.location.reload();\n"
+ "}\n"
+ "</script>\n"
+ "</head>\n"
+ "<body><h1>lower</h1><button onclick=\"test()\">test</button></body></html>";
webConnection.setResponse(URL_FIRST, framesetContent);
webConnection.setResponse(new URL(URL_FIRST, "upper.html"), upperContent);
webConnection.setResponse(new URL(URL_FIRST, "lower.html"), lowerContent);
webClient.setWebConnection(webConnection);
webClient.getPage(URL_FIRST);
assertEquals(3, webClient.getWebWindows().size());
assertEquals("/upper.html", webClient.getWebWindowByName("upper").getEnclosedPage().getUrl().getFile());
assertEquals("/lower.html", webClient.getWebWindowByName("lower").getEnclosedPage().getUrl().getFile());
final HtmlPage p = (HtmlPage)webClient.getWebWindowByName("lower").getEnclosedPage();
p.<HtmlButton>getFirstByXPath("//button").click();
assertEquals("/upper.html", webClient.getWebWindowByName("upper").getEnclosedPage().getUrl().getFile());
assertEquals("/lower.html", webClient.getWebWindowByName("lower").getEnclosedPage().getUrl().getFile());
}
}