From eac08c4f6c032273172bab36d3b333eaa4ee1e0f Mon Sep 17 00:00:00 2001 From: Alexey Fansky Date: Mon, 22 Dec 2014 12:05:53 -0800 Subject: FileDownloader opens file in a new tab (iOS) (#15366) Opening files in a new tab because iframe with a file isn't opened in iOS. Change-Id: I7f8af4b9348ade0f845e3a656c7287490b9482cf --- .../client/extensions/FileDownloaderConnector.java | 36 ++++++++++------- .../tests/extensions/IframeIsOpenedInNonIOS.java | 45 ++++++++++++++++++++++ .../extensions/IframeIsOpenedInNonIOSTest.java | 39 +++++++++++++++++++ 3 files changed, 106 insertions(+), 14 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/extensions/IframeIsOpenedInNonIOS.java create mode 100644 uitest/src/com/vaadin/tests/extensions/IframeIsOpenedInNonIOSTest.java diff --git a/client/src/com/vaadin/client/extensions/FileDownloaderConnector.java b/client/src/com/vaadin/client/extensions/FileDownloaderConnector.java index 66fc30575b..bed6622a6c 100644 --- a/client/src/com/vaadin/client/extensions/FileDownloaderConnector.java +++ b/client/src/com/vaadin/client/extensions/FileDownloaderConnector.java @@ -23,11 +23,14 @@ import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.dom.client.Style.Visibility; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.Widget; +import com.vaadin.client.BrowserInfo; import com.vaadin.client.ComponentConnector; import com.vaadin.client.ServerConnector; import com.vaadin.server.FileDownloader; +import com.vaadin.shared.VBrowserDetails; import com.vaadin.shared.ui.Connect; @Connect(FileDownloader.class) @@ -47,22 +50,27 @@ public class FileDownloaderConnector extends AbstractExtensionConnector public void onClick(ClickEvent event) { final String url = getResourceUrl("dl"); if (url != null && !url.isEmpty()) { - if (iframe != null) { - // make sure it is not on dom tree already, might start - // multiple downloads at once - iframe.removeFromParent(); - } - iframe = Document.get().createIFrameElement(); + BrowserInfo browser = BrowserInfo.get(); + if (browser.isIOS()) { + Window.open(url, "_blank", ""); + } else { + if (iframe != null) { + // make sure it is not on dom tree already, might start + // multiple downloads at once + iframe.removeFromParent(); + } + iframe = Document.get().createIFrameElement(); - Style style = iframe.getStyle(); - style.setVisibility(Visibility.HIDDEN); - style.setHeight(0, Unit.PX); - style.setWidth(0, Unit.PX); + Style style = iframe.getStyle(); + style.setVisibility(Visibility.HIDDEN); + style.setHeight(0, Unit.PX); + style.setWidth(0, Unit.PX); - iframe.setFrameBorder(0); - iframe.setTabIndex(-1); - iframe.setSrc(url); - RootPanel.getBodyElement().appendChild(iframe); + iframe.setFrameBorder(0); + iframe.setTabIndex(-1); + iframe.setSrc(url); + RootPanel.getBodyElement().appendChild(iframe); + } } } diff --git a/uitest/src/com/vaadin/tests/extensions/IframeIsOpenedInNonIOS.java b/uitest/src/com/vaadin/tests/extensions/IframeIsOpenedInNonIOS.java new file mode 100644 index 0000000000..a62b6bba88 --- /dev/null +++ b/uitest/src/com/vaadin/tests/extensions/IframeIsOpenedInNonIOS.java @@ -0,0 +1,45 @@ +package com.vaadin.tests.extensions; + +import com.vaadin.server.FileDownloader; +import com.vaadin.server.StreamResource; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Label; + +import java.io.*; + +public class IframeIsOpenedInNonIOS extends AbstractTestUI { + + public static final String FILE_CONTENT = "New text file"; + public static final String FILE_NAME = "textfile.txt"; + + @Override + protected void setup(VaadinRequest request) { + final Label errorLabel = new Label("No error"); + Button button = new Button("Download"); + FileDownloader downloader = new FileDownloader(new StreamResource(new StreamResource.StreamSource() { + @Override + public InputStream getStream () { + return createSomeFile(); + } + }, FILE_NAME)); + downloader.extend(button); + + addComponents(errorLabel, button); + } + + private InputStream createSomeFile() { + return new ByteArrayInputStream(FILE_CONTENT.getBytes()); + } + + @Override + protected Integer getTicketNumber() { + return 15366; + } + + @Override + public String getDescription() { + return "IFrame with a file is not shown in iOS"; + } +} diff --git a/uitest/src/com/vaadin/tests/extensions/IframeIsOpenedInNonIOSTest.java b/uitest/src/com/vaadin/tests/extensions/IframeIsOpenedInNonIOSTest.java new file mode 100644 index 0000000000..c544b495ab --- /dev/null +++ b/uitest/src/com/vaadin/tests/extensions/IframeIsOpenedInNonIOSTest.java @@ -0,0 +1,39 @@ +package com.vaadin.tests.extensions; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.tests.tb3.MultiBrowserTest; +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.remote.DesiredCapabilities; + +import java.util.List; + +public class IframeIsOpenedInNonIOSTest extends MultiBrowserTest { + + @Test + public void fileOpenedInNewTab() { + openTestURL(); + + $(ButtonElement.class).caption("Download").first().click(); + + List iframes = driver.findElements(By.tagName("iframe")); + boolean containsFileIframe = false; + for (WebElement iframe : iframes) { + containsFileIframe = containsFileIframe | + iframe.getAttribute("src").contains(IframeIsOpenedInNonIOS.FILE_NAME); + } + + Assert.assertTrue("page doesn't contain iframe with the file", containsFileIframe); + } + + @Override + public List getBrowsersToTest() { + //once running ios is possible, this test should be fixed to exclude it from the browsers list + + //The test is failing in all IEs for some reason even though the iframe is in place. + //Probably related to some IE driver issue + return getBrowsersExcludingIE(); + } +} -- cgit v1.2.3