From: <asa...@us...> - 2017-08-11 07:56:46
|
Revision: 14783 http://sourceforge.net/p/htmlunit/code/14783 Author: asashour Date: 2017-08-11 07:56:43 +0000 (Fri, 11 Aug 2017) Log Message: ----------- JavaScript: support FileReader.readAsDataURL() Issue 1912 Modified Paths: -------------- trunk/htmlunit/src/changes/changes.xml trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/BrowserVersionFeatures.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/file/FileReader.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/ErrorOutputChecker.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/file/FileReaderTest.java Modified: trunk/htmlunit/src/changes/changes.xml =================================================================== --- trunk/htmlunit/src/changes/changes.xml 2017-08-11 07:02:39 UTC (rev 14782) +++ trunk/htmlunit/src/changes/changes.xml 2017-08-11 07:56:43 UTC (rev 14783) @@ -8,6 +8,9 @@ <body> <release version="2.28" date="???" description="Bugfixes, Chrome 60"> + <action type="add" dev="asashour" issue="1912"> + JavaScript: support FileReader.readAsDataURL(). + </action> <action type="fix" dev="asashour" issue="1911"> ProxyAutoConfig: fix isInNet(). </action> Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/BrowserVersionFeatures.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/BrowserVersionFeatures.java 2017-08-11 07:02:39 UTC (rev 14782) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/BrowserVersionFeatures.java 2017-08-11 07:56:43 UTC (rev 14783) @@ -897,6 +897,14 @@ @BrowserFeature(FF) JS_FILE_SHORT_DATE_FORMAT, + /** Whether {@link FileReader} includes content type or not. */ + @BrowserFeature(FF) + JS_FILEREADER_CONTENT_TYPE, + + /** Whether {@link FileReader} includes {@code base64} for empty content or not. */ + @BrowserFeature(IE) + JS_FILEREADER_EMPTY_NULL, + /** Indicates that the action property will not be expanded if defined as empty string. */ @BrowserFeature(FF) JS_FORM_ACTION_EXPANDURL_IGNORE_EMPTY, Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/file/FileReader.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/file/FileReader.java 2017-08-11 07:02:39 UTC (rev 14782) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/file/FileReader.java 2017-08-11 07:56:43 UTC (rev 14783) @@ -14,6 +14,9 @@ */ package com.gargoylesoftware.htmlunit.javascript.host.file; +import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_FILEREADER_CONTENT_TYPE; +import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_FILEREADER_EMPTY_NULL; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.file.Files; @@ -21,6 +24,7 @@ import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.FileUtils; +import com.gargoylesoftware.htmlunit.BrowserVersion; import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass; import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstant; import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor; @@ -96,12 +100,30 @@ private void setResult(final Object object) throws IOException { readyState_ = LOADING; final java.io.File file = ((File) object).getFile(); - final String contentType = Files.probeContentType(file.toPath()); + String contentType = Files.probeContentType(file.toPath()); try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) { FileUtils.copyFile(file, bos); final byte[] bytes = bos.toByteArray(); - result_ = "data:" + contentType + ";base64," + new String(new Base64().encode(bytes)); + final String value = new String(new Base64().encode(bytes)); + final BrowserVersion browserVersion = getBrowserVersion(); + + result_ = "data:"; + final boolean includeConentType = browserVersion.hasFeature(JS_FILEREADER_CONTENT_TYPE); + if (!value.isEmpty() || includeConentType) { + if (contentType == null) { + if (includeConentType) { + contentType = "application/octet-stream"; + } + else { + contentType = ""; + } + } + result_ += contentType + ";base64," + value; + } + if (value.isEmpty() && getBrowserVersion().hasFeature(JS_FILEREADER_EMPTY_NULL)) { + result_ = "null"; + } } readyState_ = DONE; } Modified: trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/ErrorOutputChecker.java =================================================================== --- trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/ErrorOutputChecker.java 2017-08-11 07:02:39 UTC (rev 14782) +++ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/ErrorOutputChecker.java 2017-08-11 07:56:43 UTC (rev 14783) @@ -45,6 +45,9 @@ Pattern.compile(".*geckodriver.*\r?\n"), Pattern.compile(".*mozprofile.*\r?\n"), Pattern.compile(".*Marionette.*\r?\n"), + Pattern.compile(".*\tDEBUG\t.*\r?\n"), + Pattern.compile(".*\taddons\\..*\r?\n"), + Pattern.compile("\\*\\*\\* Blocklist::.*\r?\n"), Pattern.compile("Started InternetExplorerDriver server \\(\\d\\d\\-bit\\)\r?\n" + "3\\.4\\.0\\.0\r?\n" + "Listening on port \\d*\r?\n" Modified: trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/file/FileReaderTest.java =================================================================== --- trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/file/FileReaderTest.java 2017-08-11 07:02:39 UTC (rev 14782) +++ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/file/FileReaderTest.java 2017-08-11 07:56:43 UTC (rev 14783) @@ -110,4 +110,82 @@ FileUtils.deleteQuietly(tstFile); } } + + /** + * @throws Exception if the test fails + */ + @Test + @Alerts(DEFAULT = "data:;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAABlBMVEX+1K8AAADjghFsAAAAGXRFWHRTb2" + + "Z0d2FyZQBHcmFwaGljQ29udmVydGVyNV1I7gAAABBJREFUeJxiYAAAAAD//wMAAAIAAcx+i34AAAAASUVORK5CYII=", + FF = "data:application/octet-stream;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAABlBMVEX+1K8AAAD" + + "jghFsAAAAGXRFWHRTb2Z0d2FyZQBHcmFwaGljQ29udmVydGVyNV1I7gAAABBJREFUeJxiYAAAAAD//wMAAAIAAcx+i34AAAAASU" + + "VORK5CYII=") + public void readAsDataURLUnknown() throws Exception { + final String html + = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html>\n" + + "<head><title>foo</title>\n" + + "<script>\n" + + " function previewFile() {\n" + + " var file = document.querySelector('input[type=file]').files[0];\n" + + " var reader = new FileReader();\n" + + " reader.addEventListener('load', function () {\n" + + " alert(reader.result);\n" + + " }, false);\n" + + "\n" + + " if (file) {\n" + + " reader.readAsDataURL(file);\n" + + " }\n" + + " }\n" + + "</script>\n" + + "</head>\n" + + "<body>\n" + + " <input type='file' onchange='previewFile()'>\n" + + "</body>\n" + + "</html>"; + + final WebDriver driver = loadPage2(html); + + final String path = new File("src/test/resources/testfiles/tiny-png.img").getCanonicalPath(); + driver.findElement(By.tagName("input")).sendKeys(path); + verifyAlerts(driver, getExpectedAlerts()); + } + + /** + * @throws Exception if the test fails + */ + @Test + @Alerts(DEFAULT = "data:", + FF = "data:image/png;base64,", + IE = "null") + public void readAsDataURLEmptyImage() throws Exception { + final String html + = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html>\n" + + "<head><title>foo</title>\n" + + "<script>\n" + + " function previewFile() {\n" + + " var file = document.querySelector('input[type=file]').files[0];\n" + + " var reader = new FileReader();\n" + + " reader.addEventListener('load', function () {\n" + + " alert(reader.result);\n" + + " }, false);\n" + + "\n" + + " if (file) {\n" + + " reader.readAsDataURL(file);\n" + + " }\n" + + " }\n" + + "</script>\n" + + "</head>\n" + + "<body>\n" + + " <input type='file' onchange='previewFile()'>\n" + + "</body>\n" + + "</html>"; + + final WebDriver driver = loadPage2(html); + + final String path = new File("src/test/resources/testfiles/empty.png").getCanonicalPath(); + driver.findElement(By.tagName("input")).sendKeys(path); + verifyAlerts(driver, getExpectedAlerts()); + } } |