Clear contents of iframe clone that is in a Window so that when it's reattached to DOM we don't get 404tags/8.8.0.beta1
@@ -326,6 +326,23 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector | |||
} | |||
return newEl; | |||
} | |||
if ("iframe".equalsIgnoreCase(old.getTagName()) | |||
&& old.hasAttribute("src") | |||
&& old.getAttribute("src").contains("APP/connector")) { | |||
// an iframe reloads when reattached to the DOM, but | |||
// unfortunately, when newEl is reattached, server-side | |||
// resource (e.g. generated PDF) is already gone, so this will | |||
// end up with 404, which might be undesirable. | |||
// Instead of the resource that is not available anymore, | |||
// let's just use empty iframe. | |||
// See | |||
// https://github.com/vaadin/framework/issues/11369 | |||
// for details of the issue this works around | |||
Element newEl = old.cloneNode(false).cast(); | |||
newEl.setAttribute("src", "about:blank"); | |||
return newEl; | |||
} | |||
} | |||
Node res = node.cloneNode(false); | |||
if (node.hasChildNodes()) { |
@@ -0,0 +1,70 @@ | |||
package com.vaadin.tests.components.window; | |||
import com.vaadin.server.StreamResource; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.tests.components.AbstractTestUI; | |||
import com.vaadin.ui.*; | |||
import org.apache.commons.io.IOUtils; | |||
import java.io.ByteArrayInputStream; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
public class ClosingWindowWithBrowserFrameShouldntGenerate404 | |||
extends AbstractTestUI { | |||
private VerticalLayout layout; | |||
@Override | |||
protected void setup(VaadinRequest request) { | |||
layout = new VerticalLayout(); | |||
Button button = new Button("Click Me", e -> showPdfInAWindow()); | |||
layout.addComponent(button); | |||
addComponent(layout); | |||
} | |||
private void showPdfInAWindow() { | |||
try { | |||
final String fileName = "sample.pdf"; | |||
final byte[] bytes = IOUtils | |||
.toByteArray(getClass().getResource("/" + fileName)); | |||
StreamResource.StreamSource source = new StreamResource.StreamSource() { | |||
@Override | |||
public InputStream getStream() { | |||
return new ByteArrayInputStream(bytes); | |||
} | |||
}; | |||
StreamResource resource = new StreamResource(source, fileName); | |||
resource.setMIMEType("application/pdf"); | |||
resource.getStream().setParameter("Content-Disposition", | |||
"attachment; filename=" + fileName); | |||
resource.setCacheTime(-1); | |||
// Use browser frame | |||
BrowserFrame frame = new BrowserFrame(); | |||
frame.setSizeFull(); | |||
frame.setSource(resource); | |||
frame.setHeight("650px"); | |||
Window pdfWindow = new Window("Sample PDF"); | |||
pdfWindow.center(); | |||
pdfWindow.setModal(true); | |||
pdfWindow.setResizable(false); | |||
pdfWindow.setHeight("700px"); | |||
pdfWindow.setWidth("900px"); | |||
pdfWindow.setContent(frame); | |||
pdfWindow.addCloseListener(e -> { | |||
layout.addComponent(new Label("PDF was sent")); | |||
}); | |||
UI.getCurrent().addWindow(pdfWindow); | |||
} catch (IOException e) { | |||
e.printStackTrace(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,39 @@ | |||
package com.vaadin.tests.components.window; | |||
import com.vaadin.testbench.elements.ButtonElement; | |||
import com.vaadin.testbench.elements.LabelElement; | |||
import com.vaadin.testbench.elements.WindowElement; | |||
import com.vaadin.tests.tb3.MultiBrowserTest; | |||
import org.junit.Assert; | |||
import org.junit.Test; | |||
import org.openqa.selenium.logging.LogEntry; | |||
import java.util.List; | |||
public class ClosingWindowWithBrowserFrameShouldntGenerate404Test | |||
extends MultiBrowserTest { | |||
private static boolean contains404(LogEntry logEntry) { | |||
return logEntry.getMessage().contains("404"); | |||
} | |||
@Test | |||
public void openWindowWithFrame_closeWindow_no404() { | |||
openTestURL(); | |||
$(ButtonElement.class).first().click(); | |||
$(WindowElement.class).first().close(); | |||
$(LabelElement.class).exists(); | |||
List<LogEntry> logs = getDriver().manage().logs().get("browser") | |||
.getAll(); | |||
Assert.assertTrue(theresNoLogWith404In(logs)); | |||
} | |||
private boolean theresNoLogWith404In(List<LogEntry> logs) { | |||
return !logs.stream().anyMatch( | |||
ClosingWindowWithBrowserFrameShouldntGenerate404Test::contains404); | |||
} | |||
} |