From: <rb...@us...> - 2017-08-25 09:59:34
|
Revision: 14792 http://sourceforge.net/p/htmlunit/code/14792 Author: rbri Date: 2017-08-25 09:59:32 +0000 (Fri, 25 Aug 2017) Log Message: ----------- FileReader.readAsArrayBuffer() Modified Paths: -------------- trunk/htmlunit/src/changes/changes.xml trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/WebSocket.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/ArrayBuffer.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/file/FileReader.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-25 09:04:46 UTC (rev 14791) +++ trunk/htmlunit/src/changes/changes.xml 2017-08-25 09:59:32 UTC (rev 14792) @@ -8,6 +8,9 @@ <body> <release version="2.28" date="???" description="Bugfixes, Chrome 60"> + <action type="add" dev="rbri" issue="1913"> + JavaScript: support FileReader.readAsArrayBuffer(). + </action> <action type="add" dev="asashour" issue="1912"> JavaScript: support FileReader.readAsDataURL(). </action> Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/WebSocket.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/WebSocket.java 2017-08-25 09:04:46 UTC (rev 14791) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/WebSocket.java 2017-08-25 09:59:32 UTC (rev 14792) @@ -457,13 +457,10 @@ } super.onWebSocketBinary(data, offset, length); - final ArrayBuffer buffer = new ArrayBuffer(); + final ArrayBuffer buffer = new ArrayBuffer(Arrays.copyOfRange(data, offset, length)); buffer.setParentScope(getParentScope()); buffer.setPrototype(getPrototype(buffer.getClass())); - buffer.constructor(length); - buffer.setBytes(0, Arrays.copyOfRange(data, offset, length)); - final MessageEvent msgEvent = new MessageEvent(buffer); msgEvent.setOrigin(getUrl()); fire(msgEvent); Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/ArrayBuffer.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/ArrayBuffer.java 2017-08-25 09:04:46 UTC (rev 14791) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/ArrayBuffer.java 2017-08-25 09:59:32 UTC (rev 14792) @@ -36,6 +36,20 @@ private byte[] bytes_; /** + * Ctor. + */ + public ArrayBuffer() { + } + + /** + * Ctor with given bytes. + * @param bytes the initial bytes + */ + public ArrayBuffer(final byte[] bytes) { + bytes_ = bytes; + } + + /** * The constructor. * @param length the size, in bytes, of the array buffer to create. */ @@ -74,8 +88,7 @@ else if (Double.isInfinite(beginNumber)) { if (beginNumber > 0) { final byte[] byteArray = new byte[0]; - final ArrayBuffer arrayBuffer = new ArrayBuffer(); - arrayBuffer.bytes_ = byteArray; + final ArrayBuffer arrayBuffer = new ArrayBuffer(byteArray); return arrayBuffer; } beginInt = 0; @@ -101,8 +114,7 @@ final byte[] byteArray = new byte[(int) endNumber - beginInt]; System.arraycopy(bytes_, beginInt, byteArray, 0, byteArray.length); - final ArrayBuffer arrayBuffer = new ArrayBuffer(); - arrayBuffer.bytes_ = byteArray; + final ArrayBuffer arrayBuffer = new ArrayBuffer(byteArray); return arrayBuffer; } 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-25 09:04:46 UTC (rev 14791) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/file/FileReader.java 2017-08-25 09:59:32 UTC (rev 14792) @@ -31,6 +31,7 @@ import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction; import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter; import com.gargoylesoftware.htmlunit.javascript.configuration.JsxSetter; +import com.gargoylesoftware.htmlunit.javascript.host.arrays.ArrayBuffer; import com.gargoylesoftware.htmlunit.javascript.host.event.Event; import com.gargoylesoftware.htmlunit.javascript.host.event.EventTarget; @@ -93,12 +94,6 @@ */ @JsxFunction public void readAsDataURL(final Object object) throws IOException { - setResult(object); - final Event event = new Event(this, Event.TYPE_LOAD); - fireEvent(event); - } - - private void setResult(final Object object) throws IOException { readyState_ = LOADING; final java.io.File file = ((File) object).getFile(); String contentType = Files.probeContentType(file.toPath()); @@ -127,9 +122,37 @@ } } readyState_ = DONE; + + final Event event = new Event(this, Event.TYPE_LOAD); + fireEvent(event); } /** + * Reads the contents of the specified {@link Blob} or {@link File}. + * @param object the {@link Blob} or {@link File} from which to read + * @throws IOException if an error occurs + */ + @JsxFunction + public void readAsArrayBuffer(final Object object) throws IOException { + readyState_ = LOADING; + final java.io.File file = ((File) object).getFile(); + try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) { + FileUtils.copyFile(file, bos); + + final byte[] bytes = bos.toByteArray(); + + final ArrayBuffer buffer = new ArrayBuffer(bytes); + buffer.setParentScope(getParentScope()); + buffer.setPrototype(getPrototype(buffer.getClass())); + result_ = buffer; + } + readyState_ = DONE; + + final Event event = new Event(this, Event.TYPE_LOAD); + fireEvent(event); + } + + /** * Returns the {@code onload} event handler for this {@link FileReader}. * @return the {@code onload} event handler for this {@link FileReader} */ 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-25 09:04:46 UTC (rev 14791) +++ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/file/FileReaderTest.java 2017-08-25 09:59:32 UTC (rev 14792) @@ -193,4 +193,126 @@ driver.findElement(By.tagName("input")).sendKeys(path); verifyAlerts(driver, getExpectedAlerts()); } + + /** + * @throws Exception if the test fails + */ + @Test + @Alerts({"[object ArrayBuffer]", "8"}) + public void readAsArrayBuffer() throws Exception { + final String html + = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html>\n" + + "<head>\n" + + " <script>\n" + + " function test() {\n" + + " var files = document.testForm.fileupload.files;\n" + + " var reader = new FileReader();\n" + + " reader.onload = function() {\n" + + " alert(reader.result);\n" + + " alert(reader.result.byteLength);\n" + + " };\n" + + " reader.readAsArrayBuffer(files[0]);\n" + + " }\n" + + " </script>\n" + + "<head>\n" + + "<body>\n" + + " <form name='testForm'>\n" + + " <input type='file' id='fileupload' name='fileupload'>\n" + + " </form>\n" + + " <button id='testBtn' onclick='test()'>Tester</button>\n" + + "</body>\n" + + "</html>"; + + final WebDriver driver = loadPage2(html); + + final File tstFile = File.createTempFile("HtmlUnitReadAsArrayBufferTest", ".txt"); + try { + FileUtils.write(tstFile, "HtmlUnit", StandardCharsets.UTF_8); + + final String path = tstFile.getCanonicalPath(); + driver.findElement(By.name("fileupload")).sendKeys(path); + + driver.findElement(By.id("testBtn")).click(); + + verifyAlerts(driver, getExpectedAlerts()); + } + finally { + FileUtils.deleteQuietly(tstFile); + } + } + + /** + * @throws Exception if the test fails + */ + @Test + @Alerts({"[object ArrayBuffer]", "128"}) + public void readAsArrayBufferUnknown() 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" + + " alert(reader.result.byteLength);\n" + + " }, false);\n" + + "\n" + + " if (file) {\n" + + " reader.readAsArrayBuffer(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({"[object ArrayBuffer]", "0"}) + public void readAsArrayBufferEmptyImage() 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" + + " alert(reader.result.byteLength);\n" + + " }, false);\n" + + "\n" + + " if (file) {\n" + + " reader.readAsArrayBuffer(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()); + } } |