Import Cobalt 19.master.0.203780

Includes the following patches:
  https://cobalt-review.googlesource.com/c/cobalt/+/5210
    by errong.leng@samsung.com
  https://cobalt-review.googlesource.com/c/cobalt/+/5270
    by linus.wang@samsung.com
diff --git a/src/third_party/web_platform_tests/FileAPI/BlobURL/support/file_test1.js b/src/third_party/web_platform_tests/FileAPI/BlobURL/support/file_test1.js
new file mode 100644
index 0000000..3498358
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/BlobURL/support/file_test1.js
@@ -0,0 +1 @@
+var test_result = 'test1_OK';
\ No newline at end of file
diff --git a/src/third_party/web_platform_tests/FileAPI/BlobURL/support/file_test2.txt b/src/third_party/web_platform_tests/FileAPI/BlobURL/support/file_test2.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/BlobURL/support/file_test2.txt
diff --git a/src/third_party/web_platform_tests/FileAPI/BlobURL/support/file_test3.html b/src/third_party/web_platform_tests/FileAPI/BlobURL/support/file_test3.html
new file mode 100644
index 0000000..fa234cb
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/BlobURL/support/file_test3.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>Test file</title>
+    <style>
+        body {
+            margin: 0;
+        }
+        .block {
+            height: 5000px;
+        }
+    </style>
+    <script>
+        window.test_result = 'test3_OK';
+    </script>
+</head>
+<body>
+    <a id="block1"></a>
+    <div class="block"></div>
+
+    <a id="block2"></a>
+    <div class="block"></div>
+</body>
+</html>
diff --git a/src/third_party/web_platform_tests/FileAPI/BlobURL/test1-manual.html b/src/third_party/web_platform_tests/FileAPI/BlobURL/test1-manual.html
new file mode 100644
index 0000000..8da42cf
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/BlobURL/test1-manual.html
@@ -0,0 +1,122 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>Blob and File reference URL Test(1)</title>
+    <link rel=help href="http://dev.w3.org/2006/webapi/FileAPI/#convenienceAPI">
+    <link rel=author title="Breezewish" href="mailto:me@breeswish.org">
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+    <form name="upload">
+        <input type="file" id="fileChooser">
+    </form>
+
+    <div>
+        <p>Test steps:</p>
+        <ol>
+            <li>Download the <a href="support/file_test1.js">file</a>.</li>
+            <li>Select the file in the file inputbox to run the test.</li>
+        </ol>
+    </div>
+
+    <div id="log"></div>
+
+    <script>
+
+        var fileChooser = document.querySelector('#fileChooser');
+
+        setup({explicit_done: true});
+        setup({explicit_timeout: true});
+
+        //Run the test when user selects a file
+
+        on_event(fileChooser, 'change', function() {
+
+            var testCount = 10000;
+
+            test(function() {
+
+                var list = [], file = fileChooser.files[0];
+
+                for (var i = 0; i <= testCount; i++) {
+                    list.push(window.URL.createObjectURL(file));
+                }
+
+                list.sort();
+
+                for (var i = 0; i < testCount; i++) {
+                    assert_not_equals(list[i], list[i+1], 'generated Blob URL should be unique');
+                }
+
+            }, 'Check whether generated Blob/File URL is unique (Notice: only generate for ' + testCount + ' times)');
+
+
+            async_test(function(t) {
+
+                var url = URL.createObjectURL(fileChooser.files[0]);
+                var expected_file_content = "var test_result = 'test1_OK';";
+
+                var xhr = new XMLHttpRequest();
+                xhr.open('GET', url, true);
+                xhr.onreadystatechange = t.step_func(function() {
+                    switch (xhr.readyState) {
+                    case xhr.DONE:
+                        assert_equals(xhr.status, 200, 'status code should be 200');
+                        assert_equals(xhr.responseText, expected_file_content);
+                        t.done();
+                        return;
+                    }
+                });
+
+                xhr.send();
+
+            }, 'Check whether Blob/File URL could be used in XHR requests and could get expected data');
+
+            async_test(function(t) {
+
+                var url = URL.createObjectURL(fileChooser.files[0]);
+                var expected_run_result = "test1_OK";
+
+                //expected file content:
+                //   var test_result = 'test1_OK';
+
+                var e = document.createElement('script');
+                e.setAttribute('type', 'text/javascript');
+                e.setAttribute('src', url);
+                e.onload = t.step_func_done(function() {
+                    assert_equals(test_result, expected_run_result);
+                });
+
+                document.body.appendChild(e);
+
+            }, 'Check whether Blob/File URL could be used in tags src like <script>');
+
+            async_test(function(t) {
+
+                var url = URL.createObjectURL(fileChooser.files[0]);
+                URL.revokeObjectURL(url);
+
+                var xhr = new XMLHttpRequest();
+                xhr.open('GET', url, true);
+                xhr.onreadystatechange = t.step_func(function() {
+                    switch (xhr.readyState) {
+                    case xhr.DONE:
+                        assert_equals(xhr.status, 500, 'status code should be 500 if Blob URI is revoked.');
+                        t.done();
+                        return;
+                    }
+                });
+
+                xhr.send();
+
+            }, 'Check whether revokeObjectURL works well');
+
+            done();
+
+        });
+
+    </script>
+</body>
+</html>
diff --git a/src/third_party/web_platform_tests/FileAPI/BlobURL/test2-manual.html b/src/third_party/web_platform_tests/FileAPI/BlobURL/test2-manual.html
new file mode 100644
index 0000000..07fb27e
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/BlobURL/test2-manual.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>Blob and File reference URL Test(2)</title>
+    <link rel=help href="http://dev.w3.org/2006/webapi/FileAPI/#convenienceAPI">
+    <link rel=author title="Breezewish" href="mailto:me@breeswish.org">
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+    <form name="upload">
+        <input type="file" id="fileChooser"><br><input type="button" id="start" value="start">
+    </form>
+
+    <div>
+        <p>Test steps:</p>
+        <ol>
+            <li>Download the <a href="support/file_test2.txt">file</a>.</li>
+            <li>Select the file in the file inputbox.</li>
+            <li>Delete the file.</li>
+            <li>Click the 'start' button.</li>
+        </ol>
+    </div>
+
+    <div id="log"></div>
+
+    <script>
+
+        var fileChooser = document.querySelector('#fileChooser');
+
+        setup({explicit_done: true});
+        setup({explicit_timeout: true});
+
+        on_event(document.querySelector('#start'), 'click', function() {
+
+            async_test(function(t) {
+
+                var url = URL.createObjectURL(fileChooser.files[0]);
+
+                var xhr = new XMLHttpRequest();
+                xhr.open('GET', url, true);
+                xhr.onreadystatechange = t.step_func(function() {
+                    switch (xhr.readyState) {
+                    case xhr.DONE:
+                        assert_equals(xhr.status, 500, 'status code should be 500.');
+                        t.done();
+                        return;
+                    }
+                });
+
+                xhr.send();
+
+            }, 'Check whether the browser response 500 in XHR if the selected file which File/Blob URL refered is not found');
+
+            done();
+
+        });
+
+    </script>
+</body>
+</html>
diff --git a/src/third_party/web_platform_tests/FileAPI/BlobURL/test3-manual.html b/src/third_party/web_platform_tests/FileAPI/BlobURL/test3-manual.html
new file mode 100644
index 0000000..ce020a7
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/BlobURL/test3-manual.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>Blob and File reference URL Test(3)</title>
+    <link rel=help href="http://dev.w3.org/2006/webapi/FileAPI/#convenienceAPI">
+    <link rel=author title="Breezewish" href="mailto:me@breeswish.org">
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+    <form name="upload">
+        <input type="file" id="fileChooser">
+    </form>
+
+    <div>
+        <p>Test steps:</p>
+        <ol>
+            <li>Download the <a href="support/file_test3.html">file</a>.</li>
+            <li>Select the file in the file inputbox and the test will start.</li>
+        </ol>
+    </div>
+
+    <div id="log"></div>
+
+    <script>
+
+        var fileChooser = document.querySelector('#fileChooser');
+
+        setup({explicit_done: true});
+        setup({explicit_timeout: true});
+
+        on_event(fileChooser, 'change', function() {
+
+            async_test(function(t) {
+
+                var url = URL.createObjectURL(fileChooser.files[0]);
+
+                var e = document.createElement('iframe');
+                e.setAttribute('src', url);
+                e.setAttribute('style', 'display:none;');
+                document.body.appendChild(e);
+
+                e.contentWindow.document.body.onload = t.step_func_done(function() {
+                    assert_equals(e.contentWindow.test_result, 'test3_OK');
+                });
+
+            }, 'Check whether the iframe content could be accessed when using Blob/File URL in the same origin.');
+
+            async_test(function(t) {
+
+                var url = URL.createObjectURL(fileChooser.files[0]);
+                url += '#block2';
+
+                var e = document.createElement('iframe');
+                e.setAttribute('src', url);
+                document.body.appendChild(e);
+
+                e.contentWindow.document.body.onload = t.step_func_done(function() {
+                    assert_equals(e.contentWindow.scrollY, 5000);
+                });
+
+            }, 'Check whether the Blob/File URL fragment is implemented.');
+
+            done();
+
+        });
+
+    </script>
+</body>
+</html>
diff --git a/src/third_party/web_platform_tests/FileAPI/FileReader/Progress_event_bubbles_cancelable.html b/src/third_party/web_platform_tests/FileAPI/FileReader/Progress_event_bubbles_cancelable.html
new file mode 100644
index 0000000..6a03243
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/FileReader/Progress_event_bubbles_cancelable.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>File API Test: Progress Event - bubbles, cancelable</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<link rel="help" href="http://www.w3.org/TR/FileAPI/#events">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+  async_test(function(){
+    var blob = new Blob(["TEST"]);
+    var reader = new FileReader();
+
+    reader.onloadstart = this.step_func(function(evt) {
+      assert_false(evt.bubbles, "The bubbles must be false when the event is dispatched");
+      assert_false(evt.cancelable, "The cancelable must be false when the event is dispatched");
+    });
+
+    reader.onload = this.step_func(function(evt) {
+      assert_false(evt.bubbles, "The bubbles must be false when the event is dispatched");
+      assert_false(evt.cancelable, "The cancelable must be false when the event is dispatched");
+    });
+
+    reader.onloadend = this.step_func(function(evt) {
+      assert_false(evt.bubbles, "The bubbles must be false when the event is dispatched");
+      assert_false(evt.cancelable, "The cancelable must be false when the event is dispatched");
+      this.done();
+    });
+
+    reader.readAsText(blob);
+  }, "Check the values of bubbles and cancelable are false when the progress event is dispatched");
+</script>
+
diff --git a/src/third_party/web_platform_tests/FileAPI/FileReader/support/file_test1.txt b/src/third_party/web_platform_tests/FileAPI/FileReader/support/file_test1.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/FileReader/support/file_test1.txt
diff --git a/src/third_party/web_platform_tests/FileAPI/FileReader/test_errors-manual.html b/src/third_party/web_platform_tests/FileAPI/FileReader/test_errors-manual.html
new file mode 100644
index 0000000..e0a6120
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/FileReader/test_errors-manual.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>FileReader Errors Test</title>
+    <link rel=help href="http://dev.w3.org/2006/webapi/FileAPI/#convenienceAPI">
+    <link rel=author title="Breezewish" href="mailto:me@breeswish.org">
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+    <form name="upload">
+        <input type="file" id="fileChooser"><br><input type="button" id="start" value="start">
+    </form>
+
+    <div>
+        <p>Test steps:</p>
+        <ol>
+            <li>Download the <a href="support/file_test1.txt">file</a>.</li>
+            <li>Select the file in the file inputbox.</li>
+            <li>Delete the file.</li>
+            <li>Click the 'start' button.</li>
+        </ol>
+    </div>
+
+    <div id="log"></div>
+
+    <script>
+
+        var fileChooser = document.querySelector('#fileChooser');
+
+        setup({explicit_done: true});
+        setup({explicit_timeout: true});
+
+        on_event(fileChooser, 'change', function() {
+
+            async_test(function(t) {
+
+                var reader = new FileReader();
+                reader.readAsArrayBuffer(fileChooser.files[0]);
+
+                reader.onloadend = t.step_func_done(function(event) {
+                    assert_equals(event.target.readyState, FileReader.DONE);
+                    assert_equals(reader.error, null);
+                });
+
+            }, 'FileReader.error should be null if there are no errors when reading');
+
+        });
+
+        on_event(document.querySelector('#start'), 'click', function() {
+
+            async_test(function(t) {
+
+                var reader = new FileReader();
+                reader.readAsArrayBuffer(fileChooser.files[0]);
+
+                reader.onloadend = t.step_func_done(function(event) {
+                    assert_equals(event.target.readyState, FileReader.DONE);
+                    assert_equals(reader.error.code, 8);
+                });
+
+            }, 'FileReader.error should be NOT_FOUND_ERR if the file is not found when reading');
+
+            done();
+
+        });
+
+    </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/src/third_party/web_platform_tests/FileAPI/FileReaderSync.worker.js b/src/third_party/web_platform_tests/FileAPI/FileReaderSync.worker.js
new file mode 100644
index 0000000..77af6a7
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/FileReaderSync.worker.js
@@ -0,0 +1,28 @@
+importScripts("/resources/testharness.js");
+
+var blob, readerSync;
+setup(function() {
+  readerSync = new FileReaderSync();
+  blob = new Blob(["test"]);
+});
+
+test(function() {
+  assert_true(readerSync instanceof FileReaderSync);
+}, "Interface");
+
+test(function() {
+  var text = readerSync.readAsText(blob);
+  assert_equals(text, "test");
+}, "readAsText");
+
+test(function() {
+  var data = readerSync.readAsDataURL(blob);
+  assert_equals(data.indexOf("data:"), 0);
+}, "readAsDataURL");
+
+test(function() {
+  var data = readerSync.readAsArrayBuffer(blob);
+  assert_true(data instanceof ArrayBuffer);
+}, "readAsArrayBuffer");
+
+done();
diff --git a/src/third_party/web_platform_tests/FileAPI/blob/Blob-XHR-revoke.html b/src/third_party/web_platform_tests/FileAPI/blob/Blob-XHR-revoke.html
new file mode 100644
index 0000000..fea313e
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/blob/Blob-XHR-revoke.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<title>Revoking blob URL used with XMLHttpRequest</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+async_test(function(t) {
+    var blob = new Blob(["test"]);
+    var url = URL.createObjectURL(blob);
+    var xhr = new XMLHttpRequest();
+    xhr.open("GET", url);
+
+    // Revoke the object URL.  XHR should take a reference to the blob as soon as
+    // it receives it in open(), so the request succeeds even though we revoke the
+    // URL before calling send().
+    URL.revokeObjectURL(url);
+
+    xhr.send();
+
+    xhr.onload = t.step_func(function() {
+        assert_equals(xhr.response, "test");
+        t.done();
+    })
+    xhr.onerror = t.step_func(function() {
+        assert_unreached("Got unexpected error event");
+    })
+});
+</script>
\ No newline at end of file
diff --git a/src/third_party/web_platform_tests/FileAPI/blob/Blob-close.html b/src/third_party/web_platform_tests/FileAPI/blob/Blob-close.html
new file mode 100644
index 0000000..45df1e2
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/blob/Blob-close.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Blob.close</title>
+<link rel=help href="http://dev.w3.org/2006/webapi/FileAPI/#dfn-close">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/Blob.js"></script>
+<div id="log"></div>
+<script>
+test(function() {
+  var blob = new Blob(["TEST"]);
+  var sliced = blob.slice();
+  blob.close();
+
+  async_test(function(t) {
+    var reader = new FileReader();
+
+    reader.onload = t.step_func(function(evt) {
+      assert_unreached("Should not dispatch the load event");
+    });
+
+    reader.onerror = t.step_func(function(e) {
+      assert_equals(reader.result, null);
+      assert_equals(reader.error.code, DOMException.INVALID_STATE_ERR);
+      t.done();
+    });
+
+    reader.readAsText(blob, "UTF-8");
+  }, "Closed Blob");
+
+  test_blob(function() {
+    return sliced;
+  }, {
+    expected: "TEST",
+    type: "",
+    desc: "Slice should still have the data."
+  });
+});
+</script>
diff --git a/src/third_party/web_platform_tests/FileAPI/blob/Blob-constructor.html b/src/third_party/web_platform_tests/FileAPI/blob/Blob-constructor.html
new file mode 100644
index 0000000..dced17d
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/blob/Blob-constructor.html
@@ -0,0 +1,495 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Blob constructor</title>
+<link rel=help href="http://dev.w3.org/2006/webapi/FileAPI/#constructorBlob">
+<link rel=help href="https://heycam.github.io/webidl/#es-union">
+<link rel=help href="https://heycam.github.io/webidl/#es-dictionary">
+<link rel=help href="https://heycam.github.io/webidl/#es-sequence">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/Blob.js"></script>
+<p><strong><a href="https://www.w3.org/Bugs/Public/show_bug.cgi?id=23683">Discussion</a>
+is ongoing that will affect a number of the following tests.</strong>
+<div id="log"></div>
+<!-- used by "platform object that supports indexed properties" tests -->
+<iframe style="display:none"></iframe>
+<script>
+test(function() {
+  assert_true("Blob" in window, "window should have a Blob property.");
+  assert_equals(Blob.length, 0, "Blob.length should be 0.");
+  assert_true(Blob instanceof Function, "Blob should be a function.");
+}, "Blob interface object");
+
+// Step 1.
+test(function() {
+  var blob = new Blob();
+  assert_true(blob instanceof Blob);
+  assert_equals(String(blob), '[object Blob]');
+  assert_equals(blob.size, 0);
+  assert_equals(blob.type, "");
+}, "no-argument Blob constructor");
+test(function() {
+  assert_throws(new TypeError(), function() { var blob = Blob(); });
+}, "no-argument Blob constructor without 'new'");
+test(function() {
+  var blob = new Blob;
+  assert_true(blob instanceof Blob);
+  assert_equals(blob.size, 0);
+  assert_equals(blob.type, "");
+}, "no-argument Blob constructor without brackets");
+
+// blobParts argument (WebIDL).
+test(function() {
+  var args = [
+    null,
+    undefined,
+    true,
+    false,
+    0,
+    1,
+    1.5,
+    "FAIL",
+    new Date(),
+    new RegExp(),
+  ];
+  args.forEach(function(arg) {
+    assert_throws(new TypeError(), function() {
+      new Blob(arg);
+    }, "Should throw for argument " + format_value(arg) + ".");
+  });
+}, "Passing non-objects, Dates and RegExps for blobParts should throw a TypeError.");
+
+test_blob(function() {
+  return new Blob({});
+}, {
+  expected: "",
+  type: "",
+  desc: "A plain object should be treated as a sequence for the blobParts argument."
+});
+test_blob(function() {
+  return new Blob({ 0: "PASS", length: 1 });
+}, {
+  expected: "PASS",
+  type: "",
+  desc: "A plain object with a length property should be treated as a sequence for the blobParts argument."
+});
+test_blob(function() {
+  return new Blob(new String("xyz"));
+}, {
+  expected: "xyz",
+  type: "",
+  desc: "A String object should be treated as a sequence for the blobParts argument."
+});
+test_blob(function() {
+  return new Blob(new Uint8Array([1, 2, 3]));
+}, {
+  expected: "123",
+  type: "",
+  desc: "A Uint8Array object should be treated as a sequence for the blobParts argument."
+});
+
+var test_error = { name: "test" };
+
+test(function() {
+  var obj = {
+    get length() { throw test_error; }
+  };
+  assert_throws(test_error, function() {
+    new Blob(obj);
+  });
+}, "The length getter should be invoked and any exceptions should be propagated.");
+
+test_blob(function() {
+  var element = document.createElement("div");
+  element.appendChild(document.createElement("div"));
+  element.appendChild(document.createElement("p"));
+  var list = element.children;
+  Object.defineProperty(list, "length", {
+    get: function() { throw test_error; }
+  });
+  return new Blob(list);
+}, {
+  expected: "[object HTMLDivElement][object HTMLParagraphElement]",
+  type: "",
+  desc: "A platform object that supports indexed properties should be treated as a sequence for the blobParts argument (overwritten 'length'.)"
+});
+
+test(function() {
+  assert_throws(test_error, function() {
+    var obj = {
+      length: {
+        valueOf: null,
+        toString: function() { throw test_error; }
+      }
+    };
+    new Blob(obj);
+  });
+  assert_throws(test_error, function() {
+    var obj = {
+      length: { valueOf: function() { throw test_error; } }
+    };
+    new Blob(obj);
+  });
+}, "ToUint32 should be applied to the length and any exceptions should be propagated.");
+
+test(function() {
+  var received = [];
+  var obj = {
+    get length() {
+      received.push("length getter");
+      return {
+        valueOf: function() {
+          received.push("length valueOf");
+          return 3;
+        }
+      };
+    },
+    get 0() {
+      received.push("0 getter");
+      return {
+        toString: function() {
+          received.push("0 toString");
+          return "a";
+        }
+      };
+    },
+    get 1() {
+      received.push("1 getter");
+      throw test_error;
+    },
+    get 2() {
+      received.push("2 getter");
+      assert_unreached("Should not call the getter for 2 if the getter for 1 threw.");
+    }
+  };
+  assert_throws(test_error, function() {
+    new Blob(obj);
+  });
+  assert_array_equals(received, [
+    "length getter",
+    "length valueOf",
+    "0 getter",
+    "0 toString",
+    "1 getter"
+  ]);
+}, "Getters and value conversions should happen in order until an exception is thrown.");
+
+// XXX should add tests edge cases of ToUint32(length)
+
+test(function() {
+  assert_throws(test_error, function() {
+    new Blob([{ toString: function() { throw test_error; } }]);
+  }, "Throwing toString");
+  assert_throws(test_error, function() {
+    new Blob([{ toString: undefined, valueOf: function() { throw test_error; } }]);
+  }, "Throwing valueOf");
+  assert_throws(test_error, function() {
+    new Blob([{
+      toString: function() { throw test_error; },
+      valueOf: function() { assert_unreached("Should not call valueOf if toString is present."); }
+    }]);
+  }, "Throwing toString and valueOf");
+  assert_throws(new TypeError(), function() {
+    new Blob([{toString: null, valueOf: null}]);
+  }, "Null toString and valueOf");
+}, "ToString should be called on elements of the blobParts array and any exceptions should be propagated.");
+
+test_blob(function() {
+  var arr = [
+    { toString: function() { arr.pop(); return "PASS"; } },
+    { toString: function() { assert_unreached("Should have removed the second element of the array rather than called toString() on it."); } }
+  ];
+  return new Blob(arr);
+}, {
+  expected: "PASSundefined",
+  type: "",
+  desc: "Changes to the blobParts array should be reflected in the returned Blob (pop)."
+});
+
+test_blob(function() {
+  var arr = [
+    {
+      toString: function() {
+        if (arr.length === 3) {
+          return "SS";
+        }
+        arr.unshift({
+          toString: function() {
+            assert_unreached("Should only access index 0 once.");
+          }
+        });
+        return "PA";
+      }
+    },
+    {
+      toString: function() {
+        assert_unreached("Should not access the final element.");
+      }
+    }
+  ];
+  return new Blob(arr);
+}, {
+  expected: "PASS",
+  type: "",
+  desc: "Changes to the blobParts array should be reflected in the returned Blob (unshift)."
+});
+
+test_blob(function() {
+  // https://www.w3.org/Bugs/Public/show_bug.cgi?id=17652
+  return new Blob([
+    null,
+    undefined,
+    true,
+    false,
+    0,
+    1,
+    new String("stringobject"),
+    [],
+    ['x', 'y'],
+    {},
+    { 0: "FAIL", length: 1 },
+    { toString: function() { return "stringA"; } },
+    { toString: undefined, valueOf: function() { return "stringB"; } },
+    { valueOf: function() { assert_unreached("Should not call valueOf if toString is present on the prototype."); } }
+  ]);
+}, {
+  expected: "nullundefinedtruefalse01stringobjectx,y[object Object][object Object]stringAstringB[object Object]",
+  type: "",
+  desc: "ToString should be called on elements of the blobParts array."
+});
+
+test_blob(function() {
+  return new Blob([
+    new ArrayBuffer(8)
+  ]);
+}, {
+  expected: "\0\0\0\0\0\0\0\0",
+  type: "",
+  desc: "ArrayBuffer elements of the blobParts array should be supported."
+});
+
+test_blob(function() {
+  return new Blob([
+    new Uint8Array([0x50, 0x41, 0x53, 0x53]),
+    new Int8Array([0x50, 0x41, 0x53, 0x53]),
+    new Uint16Array([0x4150, 0x5353]),
+    new Int16Array([0x4150, 0x5353]),
+    new Uint32Array([0x53534150]),
+    new Int32Array([0x53534150]),
+    new Float32Array([0xD341500000])
+  ]);
+}, {
+  expected: "PASSPASSPASSPASSPASSPASSPASS",
+  type: "",
+  desc: "Passing typed arrays as elements of the blobParts array should work."
+});
+test_blob(function() {
+  return new Blob([
+    // 0x535 3415053534150
+    // 0x535 = 0b010100110101 -> Sign = +, Exponent = 1333 - 1023 = 310
+    // 0x13415053534150 * 2**(-52)
+    // ==> 0x13415053534150 * 2**258 = 2510297372767036725005267563121821874921913208671273727396467555337665343087229079989707079680
+    new Float64Array([2510297372767036725005267563121821874921913208671273727396467555337665343087229079989707079680])
+  ]);
+}, {
+  expected: "PASSPASS",
+  type: "",
+  desc: "Passing a Float64Array as element of the blobParts array should work."
+});
+
+test_blob(function() {
+  return new Blob(document.createElement("div"));
+}, {
+  expected: "",
+  type: "",
+  desc: "Passing an element as the blobParts array should work."
+});
+
+test_blob(function() {
+  return new Blob(window);
+}, {
+  expected: "[object Window]",
+  type: "",
+  desc: "Passing an platform object that supports indexed properties as the blobParts array should work (window)."
+});
+test_blob(function() {
+  window[0].toString = function() { return "foo"; };
+  return new Blob(window);
+}, {
+  expected: "foo",
+  type: "",
+  desc: "Passing an platform object that supports indexed properties as the blobParts array should work (window with custom toString)."
+});
+test_blob(function() {
+  var select = document.createElement("select");
+  select.appendChild(document.createElement("option"));
+  return new Blob(select);
+}, {
+  expected: "[object HTMLOptionElement]",
+  type: "",
+  desc: "Passing an platform object that supports indexed properties as the blobParts array should work (select)."
+});
+
+var t_ports = async_test("Passing a platform array object as the blobParts array should work (MessagePort[]).");
+t_ports.step(function() {
+    var channel = new MessageChannel();
+    channel.port2.onmessage = this.step_func(function(e) {
+        var b_ports = new Blob(e.ports);
+        assert_equals(b_ports.size, "[object MessagePort]".length);
+        this.done();
+    });
+    var channel2 = new MessageChannel();
+    channel.port1.postMessage('', [channel2.port1]);
+});
+
+test_blob(function() {
+  var elm = document.createElement("div");
+  elm.setAttribute("foo", "bar");
+  return new Blob(elm.attributes);
+}, {
+  expected: "[object Attr]",
+  type: "",
+  desc: "Passing a platform array object as the blobParts array should work (Attr[])."
+});
+
+test_blob(function() {
+  var blob = new Blob(['foo']);
+  return new Blob([blob, blob]);
+}, {
+  expected: "foofoo",
+  type: "",
+  desc: "Array with two blobs"
+});
+
+test_blob_binary(function() {
+  var view = new Uint8Array([0, 255, 0]);
+  return new Blob([view.buffer, view.buffer]);
+}, {
+  expected: [0, 255, 0, 0, 255, 0],
+  type: "",
+  desc: "Array with two buffers"
+});
+
+test_blob_binary(function() {
+  var view = new Uint8Array([0, 255, 0, 4]);
+  var blob = new Blob([view, view]);
+  assert_equals(blob.size, 8);
+  var view1 = new Uint16Array(view.buffer, 2);
+  return new Blob([view1, view.buffer, view1]);
+}, {
+  expected: [0, 4, 0, 255, 0, 4, 0, 4],
+  type: "",
+  desc: "Array with two bufferviews"
+});
+
+test_blob(function() {
+  var view = new Uint8Array([0]);
+  var blob = new Blob(["fo"]);
+  return new Blob([view.buffer, blob, "foo"]);
+}, {
+  expected: "\0fofoo",
+  type: "",
+  desc: "Array with mixed types"
+});
+
+// options argument
+test(function() {
+  new Blob([], { endings: "invalidEnumValue" });
+  new Blob([], { endings: null });
+  new Blob([], { endings: undefined });
+  new Blob([], { endings: 0 });
+  new Blob([], { get endings() { assert_unreached("Should not call getter"); } });
+}, "The 'endings' property should be ignored.");
+
+test(function() {
+  assert_throws(test_error, function() {
+    new Blob([], {
+      get type() { throw test_error; }
+    });
+  });
+  assert_throws(test_error, function() {
+    new Blob([], {
+      type: { toString: function() { throw test_error; } }
+    });
+  });
+}, "options properties should be accessed in lexicographic order.");
+
+test(function() {
+  assert_throws(test_error, function() {
+    new Blob(
+      [{ toString: function() { throw test_error } }],
+      {
+        get type() { assert_unreached("type getter should not be called."); }
+      }
+    );
+  });
+}, "Arguments should be evaluated from left to right.");
+
+[
+  null,
+  undefined,
+  {},
+  { unrecognized: true },
+  /regex/,
+  function() {}
+].forEach(function(arg, idx) {
+  test_blob(function() {
+    return new Blob([], arg);
+  }, {
+    expected: "",
+    type: "",
+    desc: "Passing " + format_value(arg) + " (index " + idx + ") for options should use the defaults."
+  });
+  test_blob(function() {
+    return new Blob(["\na\r\nb\n\rc\r"], arg);
+  }, {
+    expected: "\na\r\nb\n\rc\r",
+    type: "",
+    desc: "Passing " + format_value(arg) + " (index " + idx + ") for options should use the defaults (with newlines)."
+  });
+});
+
+test_blob(function() {
+  return new Blob(["\na\r\nb\n\rc\r"], { endings: "transparent" });
+}, {
+  expected: "\na\r\nb\n\rc\r",
+  type: "",
+  desc: "Newlines should not change when endings is 'transparent'."
+});
+test_blob(function() {
+  return new Blob(["\na\r\nb\n\rc\r"], { endings: "native" });
+}, {
+  expected: "\na\r\nb\n\rc\r",
+  type: "",
+  desc: "Newlines should not change when endings is 'native'."
+});
+
+var type_tests = [
+  // blobParts, type, expected type
+  [[], '', ''],
+  [[], 'a', 'a'],
+  [[], 'A', 'a'],
+  [[], 'text/html', 'text/html'],
+  [[], 'TEXT/HTML', 'text/html'],
+  [[], '\u00E5', ''],
+  [[], '\uD801\uDC7E', ''], // U+1047E
+  [[], ' image/gif ', ' image/gif '],
+  [[], '\timage/gif\t', ''],
+  [[], 'image/gif;\u007f', ''],
+  [[], '\u0130mage/gif', ''], // uppercase i with dot
+  [[], '\u0131mage/gif', ''], // lowercase dotless i
+  [[], 'image/gif\u0000', ''],
+  // check that type isn't changed based on sniffing
+  [[0x3C, 0x48, 0x54, 0x4D, 0x4C, 0x3E], 'unknown/unknown', 'unknown/unknown'], // "<HTML>"
+  [[0x00, 0xFF], 'text/plain', 'text/plain'],
+  [[0x47, 0x49, 0x46, 0x38, 0x39, 0x61], 'image/png', 'image/png'], // "GIF89a"
+];
+
+type_tests.forEach(function(t) {
+  test(function() {
+    var arr = new Uint8Array([t[0]]).buffer;
+    var b = new Blob([arr], {type:t[1]});
+    assert_equals(b.type, t[2]);
+  }, "Blob with type " + format_value(t[1]));
+});
+</script>
diff --git a/src/third_party/web_platform_tests/FileAPI/blob/Blob-slice.html b/src/third_party/web_platform_tests/FileAPI/blob/Blob-slice.html
new file mode 100644
index 0000000..a66136b
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/blob/Blob-slice.html
@@ -0,0 +1,214 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Blob slice</title>
+<link rel=help href="http://dev.w3.org/2006/webapi/FileAPI/#slice-method-algo">
+<link rel=author title="Saurabh Anand" href="mailto:saurabhanandiit@gmail.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/Blob.js"></script>
+<div id="log"></div>
+<script>
+test_blob(function() {
+  var blobTemp = new Blob(["PASS"]);
+  return blobTemp.slice();
+}, {
+  expected: "PASS",
+  type: "",
+  desc: "no-argument Blob slice"
+});
+
+test(function() {
+  var blob1, blob2;
+
+  test_blob(function() {
+    return blob1 = new Blob(["squiggle"]);
+  }, {
+    expected: "squiggle",
+    type: "",
+    desc: "blob1."
+  });
+
+  test_blob(function() {
+    return blob2 = new Blob(["steak"], {type: "content/type"});
+  }, {
+    expected: "steak",
+    type: "content/type",
+    desc: "blob2."
+  });
+
+  var arrayBuffer = new ArrayBuffer(16);
+  var int8View = new Int8Array(arrayBuffer);
+  for (var i = 0; i < 16; i++) {
+    int8View[i] = i + 65;
+  }
+
+  var testData = [
+    [
+      ["PASSSTRING"],
+      [{start:  -6, contents: "STRING"},
+       {start: -12, contents: "PASSSTRING"},
+       {start:   4, contents: "STRING"},
+       {start:  12, contents: ""},
+       {start: 0, end:  -6, contents: "PASS"},
+       {start: 0, end: -12, contents: ""},
+       {start: 0, end:   4, contents: "PASS"},
+       {start: 0, end:  12, contents: "PASSSTRING"},
+       {start: 7, end:   4, contents: ""}]
+    ],
+
+    // Test 3 strings
+    [
+      ["foo", "bar", "baz"],
+      [{start:  0, end:  9, contents: "foobarbaz"},
+       {start:  0, end:  3, contents: "foo"},
+       {start:  3, end:  9, contents: "barbaz"},
+       {start:  6, end:  9, contents: "baz"},
+       {start:  6, end: 12, contents: "baz"},
+       {start:  0, end:  9, contents: "foobarbaz"},
+       {start:  0, end: 11, contents: "foobarbaz"},
+       {start: 10, end: 15, contents: ""}]
+    ],
+
+    // Test string, Blob, string
+    [
+      ["foo", blob1, "baz"],
+      [{start:  0, end:  3, contents: "foo"},
+       {start:  3, end: 11, contents: "squiggle"},
+       {start:  2, end:  4, contents: "os"},
+       {start: 10, end: 12, contents: "eb"}]
+    ],
+
+    // Test blob, string, blob
+    [
+      [blob1, "foo", blob1],
+      [{start:  0, end:  8, contents: "squiggle"},
+       {start:  7, end:  9, contents: "ef"},
+       {start: 10, end: 12, contents: "os"},
+       {start:  1, end:  4, contents: "qui"},
+       {start: 12, end: 15, contents: "qui"},
+       {start: 40, end: 60, contents: ""}]
+    ],
+
+    // Test blobs all the way down
+    [
+      [blob2, blob1, blob2],
+      [{start: 0,  end:  5, contents: "steak"},
+       {start: 5,  end: 13, contents: "squiggle"},
+       {start: 13, end: 18, contents: "steak"},
+       {start:  1, end:  3, contents: "te"},
+       {start:  6, end: 10, contents: "quig"}]
+    ],
+
+    // Test an ArrayBufferView
+    [
+      [int8View, blob1, "foo"],
+      [{start:  0, end:  8, contents: "ABCDEFGH"},
+       {start:  8, end: 18, contents: "IJKLMNOPsq"},
+       {start: 17, end: 20, contents: "qui"},
+       {start:  4, end: 12, contents: "EFGHIJKL"}]
+    ],
+
+    // Test a partial ArrayBufferView
+    [
+      [new Uint8Array(arrayBuffer, 3, 5), blob1, "foo"],
+      [{start:  0, end:  8, contents: "DEFGHsqu"},
+       {start:  8, end: 18, contents: "igglefoo"},
+       {start:  4, end: 12, contents: "Hsquiggl"}]
+    ],
+
+    // Test type coercion of a number
+    [
+      [3, int8View, "foo"],
+      [{start:  0, end:  8, contents: "3ABCDEFG"},
+       {start:  8, end: 18, contents: "HIJKLMNOPf"},
+       {start: 17, end: 21, contents: "foo"},
+       {start:  4, end: 12, contents: "DEFGHIJK"}]
+    ],
+
+    [
+      [(new Uint8Array([0, 255, 0])).buffer,
+       new Blob(['abcd']),
+       'efgh',
+       'ijklmnopqrstuvwxyz'],
+      [{start:  1, end:  4, contents: "\uFFFD\u0000a"},
+       {start:  4, end:  8, contents: "bcde"},
+       {start:  8, end: 12, contents: "fghi"},
+       {start:  1, end: 12, contents: "\uFFFD\u0000abcdefghi"}]
+    ]
+  ];
+
+  testData.forEach(function(data, i) {
+    var blobs = data[0];
+    var tests = data[1];
+    tests.forEach(function(expectations, j) {
+      test(function() {
+        var blob = new Blob(blobs);
+        assert_true(blob instanceof Blob);
+        assert_false(blob instanceof File);
+
+        test_blob(function() {
+          return expectations.end === undefined
+                 ? blob.slice(expectations.start)
+                 : blob.slice(expectations.start, expectations.end);
+        }, {
+          expected: expectations.contents,
+          type: "",
+          desc: "Slicing test: slice (" + i + "," + j + ")."
+        });
+      }, "Slicing test (" + i + "," + j + ").");
+    });
+  });
+}, "Slices");
+
+var invalidTypes = [
+  "\xFF",
+  "te(xt/plain",
+  "te)xt/plain",
+  "te<xt/plain",
+  "te>xt/plain",
+  "te@xt/plain",
+  "te,xt/plain",
+  "te;xt/plain",
+  "te:xt/plain",
+  "te\\xt/plain",
+  "te\"xt/plain",
+  "te/xt/plain",
+  "te[xt/plain",
+  "te]xt/plain",
+  "te?xt/plain",
+  "te=xt/plain",
+  "te{xt/plain",
+  "te}xt/plain",
+  "te\x20xt/plain",
+  "te\x09xt/plain",
+  "te\x00xt/plain",
+  "te\x1Fxt/plain",
+  "te\x7Fxt/plain"
+];
+invalidTypes.forEach(function(type) {
+  test_blob(function() {
+    var blob = new Blob(["PASS"]);
+    return blob.slice(0, 4, type);
+  }, {
+    expected: "PASS",
+    type: "",
+    desc: "Invalid contentType (" + format_value(type) + ")"
+  });
+});
+
+var validTypes = [
+  "TEXT/PLAIN",
+  "text/plain;charset = UTF-8",
+  "text/plain;charset=UTF-8"
+];
+validTypes.forEach(function(type) {
+  test_blob(function() {
+    var blob = new Blob(["PASS"]);
+    return blob.slice(0, 4, type);
+  }, {
+    expected: "PASS",
+    type: type.toLowerCase(),
+    desc: "Valid contentType (" + format_value(type) + ")"
+  });
+});
+</script>
diff --git a/src/third_party/web_platform_tests/FileAPI/file/File-constructor.html b/src/third_party/web_platform_tests/FileAPI/file/File-constructor.html
new file mode 100644
index 0000000..97c08b6
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/file/File-constructor.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>File constructor</title>
+<link rel=help href="http://dev.w3.org/2006/webapi/FileAPI/#dfn-file">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+test(function() {
+  assert_true("File" in window, "window should have a File property.");
+}, "File interface object exists");
+
+function test_first_argument(arg1, expectedSize, testName) {
+  test(function() {
+    var file = new File(arg1, "dummy");
+    assert_true(file instanceof File);
+    assert_equals(file.name, "dummy");
+    assert_equals(file.size, expectedSize);
+    assert_equals(file.type, "");
+    // assert_false(file.isClosed); XXX: File.isClosed doesn't seem to be implemented
+    assert_not_equals(file.lastModified, "");
+  }, testName);
+}
+
+test_first_argument(["bits"], 4, "DOMString fileBits");
+test_first_argument(["𝓽𝓮𝔁𝓽"], 16, "Unicode DOMString fileBits");
+test_first_argument([new Blob()], 0, "Empty Blob fileBits");
+test_first_argument([new Blob(["bits"])], 4, "Blob fileBits");
+test_first_argument([new ArrayBuffer(8)], 8, "ArrayBuffer fileBits");
+test_first_argument([new Uint8Array([0x50, 0x41, 0x53, 0x53])], 4, "Typed array fileBits");
+test_first_argument(["bits", new Blob(["bits"]), new Blob(), new Uint8Array([0x50, 0x41]),
+                     new Uint16Array([0x5353]), new Uint32Array([0x53534150])], 16, "Various fileBits");
+
+function test_second_argument(arg2, expectedFileName, testName) {
+  test(function() {
+    var file = new File(["bits"], arg2);
+    assert_true(file instanceof File);
+    assert_equals(file.name, expectedFileName);
+  }, testName);
+}
+
+test_second_argument("dummy", "dummy", "Using fileName");
+test_second_argument("dummy/foo", "dummy:foo", "Using special character in fileName");
+
+// testing the third argument
+test(function() {
+  var file = new File(["bits"], "dummy", { type: "text/plain"});
+  assert_true(file instanceof File);
+  assert_equals(file.type, "text/plain");
+}, "Using type on the File constructor");
+test(function() {
+  var file = new File(["bits"], "dummy", { type: "TEXT/PLAIN"});
+  assert_true(file instanceof File);
+  assert_equals(file.type, "text/plain");
+}, "Using uppercase characters in type");
+test(function() {
+  var file = new File(["bits"], "dummy", { type: "𝓽𝓮𝔁𝓽/𝔭𝔩𝔞𝔦𝔫"});
+  assert_true(file instanceof File);
+  assert_equals(file.type, "");
+}, "Using illegal character for type");
+test(function() {
+  var file = new File(["bits"], "dummy", { lastModified: 42 });
+  assert_true(file instanceof File);
+  assert_equals(file.lastModified, 42);
+}, "Using lastModified");
+test(function() {
+  var file = new File(["bits"], "dummy", { name: "foo" });
+  assert_true(file instanceof File);
+  assert_equals(file.name, "dummy");
+}, "Misusing name");
+
+</script>
diff --git a/src/third_party/web_platform_tests/FileAPI/fileReader.html b/src/third_party/web_platform_tests/FileAPI/fileReader.html
new file mode 100644
index 0000000..b767e22
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/fileReader.html
@@ -0,0 +1,67 @@
+<!doctype html>
+<html>
+  <head>
+      <title>FileReader States</title>
+      <link rel=help href="http://dev.w3.org/2006/webapi/FileAPI/#dfn-filereader">
+      <link rel=author title="Lenient" href="mailto:lenient315@gmail.com">
+      <script src="/resources/testharness.js"></script>
+      <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+        test(function() {
+             assert_true("FileReader" in window, "window should have a FileReader property.");
+        }, "FileReader interface object");
+
+        test(function(){
+            var fileReader = new FileReader();
+            assert_true(fileReader instanceof FileReader);
+        }, "no-argument FileReader constructor");
+
+        var t_abort = async_test("FileReader States -- abort");
+        t_abort.step(function(){
+            var fileReader = new FileReader();
+            assert_equals(fileReader.readyState, 0);
+            assert_equals(fileReader.readyState, FileReader.EMPTY);
+
+            var blob = new Blob();
+            fileReader.readAsArrayBuffer(blob);
+            assert_equals(fileReader.readyState, 1);
+            assert_equals(fileReader.readyState, FileReader.LOADING);
+
+            fileReader.onabort = this.step_func(function(e) {
+                assert_equals(fileReader.readyState, 2);
+                assert_equals(fileReader.readyState, FileReader.DONE);
+                t_abort.done();
+            });
+            fileReader.abort();
+            fileReader.onabort = this.unreached_func("abort event should fire sync")
+        });
+
+        var t_event = async_test("FileReader States -- events");
+        t_event.step(function(){
+            var fileReader = new FileReader();
+
+            var blob = new Blob();
+            fileReader.readAsArrayBuffer(blob);
+
+            fileReader.onloadstart = this.step_func(function(e) {
+                assert_equals(fileReader.readyState, 1);
+                assert_equals(fileReader.readyState, FileReader.LOADING);
+            });
+
+            fileReader.onprogress = this.step_func(function(e) {
+                assert_equals(fileReader.readyState, 1);
+                assert_equals(fileReader.readyState, FileReader.LOADING);
+            });
+
+            fileReader.onloadend = this.step_func(function(e) {
+                assert_equals(fileReader.readyState, 2);
+                assert_equals(fileReader.readyState, FileReader.DONE);
+                t_event.done();
+            });
+        });
+    </script>
+  </body>
+</html>
diff --git a/src/third_party/web_platform_tests/FileAPI/filelist-section/filelist.html b/src/third_party/web_platform_tests/FileAPI/filelist-section/filelist.html
new file mode 100644
index 0000000..b97dcde
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/filelist-section/filelist.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset='utf-8'>
+    <title>FileAPI Test: filelist</title>
+    <link rel='author' title='Intel' href='http://www.intel.com'>
+    <link rel='help' href='http://dev.w3.org/2006/webapi/FileAPI/#filelist-section'>
+    <link rel="help" href="http://dev.w3.org/2006/webapi/FileAPI/#dfn-length">
+    <link rel="help" href="http://dev.w3.org/2006/webapi/FileAPI/#dfn-item">
+    <script src='/resources/testharness.js'></script>
+    <script src='/resources/testharnessreport.js'></script>
+  </head>
+
+  <body>
+    <form name='uploadData' style="display:none">
+      <input type='file' id='fileChooser'>
+    </form>
+    <div id='log'></div>
+
+    <script>
+      var fileList;
+
+      setup(function () {
+        fileList = document.querySelector('#fileChooser').files;
+      });
+
+      test(function () {
+        assert_true('FileList' in window, 'window has a FileList property');
+      }, 'Check if window has a FileList property');
+
+      test(function () {
+        assert_equals(FileList.length, 0, 'FileList.length is 0');
+      }, 'Check if FileList.length is 0');
+
+      test(function () {
+        assert_true(fileList.item instanceof Function, 'item is a instanceof Function');
+      }, 'Check if item is a instanceof Function');
+
+      test(function() {
+        assert_inherits(fileList, 'item', 'item is a method of fileList');
+      }, 'Check if item is a method of fileList');
+
+      test(function() {
+        assert_equals(fileList.item(0), null, 'item method returns null');
+      }, 'Check if the item method returns null when no file selected');
+
+      test(function() {
+        assert_inherits(fileList, 'length', 'length is fileList attribute');
+      }, 'Check if length is fileList\'s attribute');
+
+      test(function() {
+        assert_equals(fileList.length, 0, 'fileList length is 0');
+      }, 'Check if the fileList length is 0 when no file selected');
+    </script>
+
+  </body>
+</html>
diff --git a/src/third_party/web_platform_tests/FileAPI/filelist-section/filelist_multiple_selected_files-manual.html b/src/third_party/web_platform_tests/FileAPI/filelist-section/filelist_multiple_selected_files-manual.html
new file mode 100644
index 0000000..2efaa05
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/filelist-section/filelist_multiple_selected_files-manual.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset='utf-8'>
+    <title>FileAPI Test: filelist_multiple_selected_files</title>
+    <link rel='author' title='Intel' href='http://www.intel.com'>
+    <link rel='help' href='http://dev.w3.org/2006/webapi/FileAPI/#filelist-section'>
+    <link rel="help" href="http://dev.w3.org/2006/webapi/FileAPI/#dfn-length">
+    <link rel="help" href="http://dev.w3.org/2006/webapi/FileAPI/#dfn-item">
+    <script src='/resources/testharness.js'></script>
+    <script src='/resources/testharnessreport.js'></script>
+  </head>
+
+  <body>
+    <form name='uploadData'>
+      <input type='file' id='fileChooser' multiple>
+    </form>
+    <div>
+      <p>Test steps:</p>
+      <ol>
+        <li>Download <a href='support/upload.txt'>upload.txt</a>, <a href="support/upload.zip">upload.zip</a> to local.</li>
+        <li>Select the local two files (upload.txt, upload.zip) to run the test.</li>
+      </ol>
+    </div>
+
+    <div id='log'></div>
+
+    <script>
+      var fileInput = document.querySelector('#fileChooser');
+      var fileList;
+
+      setup({explicit_done: true, explicit_timeout: true});
+
+      on_event(fileInput, 'change', function(evt) {
+        test(function() {
+          fileList = document.querySelector('#fileChooser').files;
+          assert_equals(fileList.length, 2, 'fileList length is 2');
+        }, 'Check if the fileList length is 2 when selected two files');
+
+        test(function() {
+          fileList = document.querySelector('#fileChooser').files;
+          assert_true(fileList.item(0) instanceof File, 'item method is instanceof File');
+        }, 'Check if the item method returns the File interface when selected two files');
+
+        test(function() {
+          fileList = document.querySelector('#fileChooser').files;
+          assert_not_equals(fileList.item(1), null, 'item(1) is not null');
+        }, 'Check if item(1) is not null when selected two files. Index must be treated by user agents as value for the position of a File object in the FileList, with 0 representing the first file.');
+
+        test(function() {
+          fileList = document.querySelector('#fileChooser').files;
+          assert_equals(fileList.item(2), null, 'item(2) is null');
+        }, 'Check if item(2) is null when selected two files');
+
+        test(function() {
+          fileList = document.querySelector('#fileChooser').files;
+          assert_array_equals([fileList.item(0).name, fileList.item(1).name], ['upload.txt', 'upload.zip'], 'file name string is the name of selected files "upload.txt", "upload.zip"');
+        }, 'Check if the file name string is the name of selected files');
+
+        done();
+      });
+    </script>
+  </body>
+</html>
diff --git a/src/third_party/web_platform_tests/FileAPI/filelist-section/filelist_selected_file-manual.html b/src/third_party/web_platform_tests/FileAPI/filelist-section/filelist_selected_file-manual.html
new file mode 100644
index 0000000..966aadd
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/filelist-section/filelist_selected_file-manual.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset='utf-8'>
+    <title>FileAPI Test: filelist_selected_file</title>
+    <link rel='author' title='Intel' href='http://www.intel.com'>
+    <link rel='help' href='http://dev.w3.org/2006/webapi/FileAPI/#filelist-section'>
+    <link rel="help" href="http://dev.w3.org/2006/webapi/FileAPI/#dfn-length">
+    <link rel="help" href="http://dev.w3.org/2006/webapi/FileAPI/#dfn-item">
+    <script src='/resources/testharness.js'></script>
+    <script src='/resources/testharnessreport.js'></script>
+  </head>
+
+  <body>
+    <form name='uploadData'>
+      <input type='file' id='fileChooser'>
+    </form>
+    <div>
+      <p>Test steps:</p>
+      <ol>
+        <li>Download <a href='support/upload.txt'>upload.txt</a> to local.</li>
+        <li>Select the local upload.txt file to run the test.</li>
+      </ol>
+    </div>
+
+    <div id='log'></div>
+
+    <script>
+      var fileInput = document.querySelector('#fileChooser');
+      var fileList;
+
+      setup({explicit_done: true, explicit_timeout: true});
+
+      on_event(fileInput, 'change', function(evt) {
+        test(function() {
+          fileList = document.querySelector('#fileChooser').files;
+          assert_equals(fileList.length, 1, 'fileList length is 1');
+        }, 'Check if the fileList length is 1 when selected one file');
+
+        test(function() {
+          fileList = document.querySelector('#fileChooser').files;
+          assert_true(fileList.item(0) instanceof File, 'item method is instanceof File');
+        }, 'Check if the item method returns the File interface when selected one file');
+
+        test(function() {
+          fileList = document.querySelector('#fileChooser').files;
+          assert_not_equals(fileList.item(0), null, 'item(0) is not null');
+        }, 'Check if item(0) is not null when selected one file. Index must be treated by user agents as value for the position of a File object in the FileList, with 0 representing the first file.');
+
+        test(function() {
+          fileList = document.querySelector('#fileChooser').files;
+          assert_equals(fileList.item(1), null, 'item(1) is null');
+        }, 'Check if item(1) is null when selected one file only');
+
+        test(function() {
+          fileList = document.querySelector('#fileChooser').files;
+          assert_equals(fileList.item(0).name, 'upload.txt', 'file name string is "upload.txt"');
+        }, 'Check if the file name string is the selected "upload.txt"');
+
+        done();
+      });
+    </script>
+  </body>
+</html>
diff --git a/src/third_party/web_platform_tests/FileAPI/filelist-section/support/upload.txt b/src/third_party/web_platform_tests/FileAPI/filelist-section/support/upload.txt
new file mode 100644
index 0000000..f45965b
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/filelist-section/support/upload.txt
@@ -0,0 +1 @@
+Hello, this is test file for file upload.
diff --git a/src/third_party/web_platform_tests/FileAPI/filelist-section/support/upload.zip b/src/third_party/web_platform_tests/FileAPI/filelist-section/support/upload.zip
new file mode 100644
index 0000000..a933d6a
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/filelist-section/support/upload.zip
Binary files differ
diff --git a/src/third_party/web_platform_tests/FileAPI/historical.html b/src/third_party/web_platform_tests/FileAPI/historical.html
new file mode 100644
index 0000000..3ff56a3
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/historical.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<html>
+ <head>
+  <meta charset="utf-8">
+  <title>Historical features</title>
+  <script src="/resources/testharness.js"></script>
+  <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+  <div id="log"></div>
+  <script>
+    test(function() {
+        assert_false('toNativeLineEndings' in window);
+    }, '"toNativeLineEndings" should not be supported');
+
+    test(function() {
+        assert_false('FileError' in window);
+    }, '"FileError" should not be supported');
+
+    test(function() {
+        assert_false('FileException' in window);
+    }, '"FileException" should not be supported');
+
+    test(function() {
+        var b = new Blob();
+        var prefixes = ['op', 'moz', 'webkit', 'ms'];
+        for (var i = 0; i < prefixes.length; ++i) {
+            assert_false(prefixes[i]+'Slice' in b, "'"+prefixes[i]+"Slice' in b");
+            assert_false(prefixes[i]+'Slice' in Blob.prototype, "'"+prefixes[i]+"Slice in Blob.prototype");
+        }
+    }, 'Blob should not support slice prefixed');
+
+    test(function() {
+        var prefixes = ['', 'O', 'Moz', 'WebKit', 'MS'];
+        for (var i = 0; i < prefixes.length; ++i) {
+            assert_false(prefixes[i]+'BlobBuilder' in window, prefixes[i]+'BlobBuilder');
+        }
+    }, 'BlobBuilder should not be supported.');
+
+    test(function() {
+        var reader = new FileReader();
+        assert_false('readAsBinaryString' in reader, 'should not be in reader');
+        assert_equals(reader.readAsBinaryString, undefined,
+                      'should be undefined on getting')
+    }, 'FileReader should not support readAsBinaryString');
+  </script>
+ </body>
+</html>
diff --git a/src/third_party/web_platform_tests/FileAPI/idlharness-manual.html b/src/third_party/web_platform_tests/FileAPI/idlharness-manual.html
new file mode 100644
index 0000000..8fb0dfb
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/idlharness-manual.html
@@ -0,0 +1,167 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>File API manual IDL tests</title>
+    <link rel="author" title="Intel" href="http://www.intel.com">
+    <link rel="help" href="http://dev.w3.org/2006/webapi/FileAPI/#conformance">
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/resources/WebIDLParser.js"></script>
+    <script src="/resources/idlharness.js"></script>
+  </head>
+  <body>
+    <h1>File API manual IDL tests</h1>
+
+    <div>
+      <p>Test steps:</p>
+      <ol>
+        <li>Download <a href="support/upload.txt">upload.txt</a> to local.</li>
+        <li>Select the local upload.txt file to run the test.</li>
+      </ol>
+    </div>
+
+    <form name="uploadData">
+      <input type="file" id="fileChooser">
+    </form>
+
+    <div id="log"></div>
+
+    <pre id="untested_idl" style="display: none">
+      interface ArrayBuffer {
+      };
+
+      interface ArrayBufferView {
+      };
+
+      interface URL {
+      };
+
+      interface EventTarget {
+      };
+
+      interface Event {
+      };
+
+      [TreatNonCallableAsNull]
+      callback EventHandlerNonNull = any (Event event);
+      typedef EventHandlerNonNull? EventHandler;
+    </pre>
+
+    <pre id="idl" style="display: none">
+[Constructor,
+ Constructor(sequence<(ArrayBuffer or ArrayBufferView or Blob or DOMString)> blobParts, optional BlobPropertyBag options), Exposed=Window,Worker]
+interface Blob {
+
+  readonly attribute unsigned long long size;
+  readonly attribute DOMString type;
+  readonly attribute boolean isClosed;
+
+  //slice Blob into byte-ranged chunks
+
+  Blob slice([Clamp] optional long long start,
+             [Clamp] optional long long end,
+             optional DOMString contentType);
+  void close();
+
+};
+
+dictionary BlobPropertyBag {
+  DOMString type = "";
+};
+
+[Constructor(sequence<(Blob or DOMString or ArrayBufferView or ArrayBuffer)> fileBits,
+[EnsureUTF16] DOMString fileName, optional FilePropertyBag options), Exposed=Window,Worker]
+interface File : Blob {
+
+  readonly attribute DOMString name;
+  readonly attribute long long lastModified;
+
+};
+
+dictionary FilePropertyBag {
+
+  DOMString type = "";
+  long long lastModified;
+
+};
+
+[Exposed=Window,Worker] interface FileList {
+  getter File? item(unsigned long index);
+  readonly attribute unsigned long length;
+};
+
+[Constructor, Exposed=Window,Worker]
+interface FileReader: EventTarget {
+
+  // async read methods
+  void readAsArrayBuffer(Blob blob);
+  void readAsText(Blob blob, optional DOMString label);
+  void readAsDataURL(Blob blob);
+
+  void abort();
+
+  // states
+  const unsigned short EMPTY = 0;
+  const unsigned short LOADING = 1;
+  const unsigned short DONE = 2;
+
+  readonly attribute unsigned short readyState;
+
+  // File or Blob data
+  readonly attribute (DOMString or ArrayBuffer)? result;
+
+  readonly attribute DOMError? error;
+
+  // event handler attributes
+  attribute EventHandler onloadstart;
+  attribute EventHandler onprogress;
+  attribute EventHandler onload;
+  attribute EventHandler onabort;
+  attribute EventHandler onerror;
+  attribute EventHandler onloadend;
+
+};
+
+[Constructor, Exposed=Worker]
+interface FileReaderSync {
+
+  // Synchronously return strings
+
+  ArrayBuffer readAsArrayBuffer(Blob blob);
+  DOMString readAsText(Blob blob, optional DOMString label);
+  DOMString readAsDataURL(Blob blob);
+};
+
+partial interface URL {
+
+  static DOMString createObjectURL(Blob blob);
+  static DOMString createFor(Blob blob);
+  static void revokeObjectURL(DOMString url);
+
+};
+    </pre>
+
+    <script>
+      var fileInput;
+
+      setup(function() {
+        fileInput = document.querySelector("#fileChooser")
+      }, {explicit_done: true, explicit_timeout: true});
+
+      on_event(fileInput, "change", function(evt) {
+        var idl_array = new IdlArray();
+        idl_array.add_untested_idls(document.getElementById("untested_idl").textContent);
+        idl_array.add_idls(document.getElementById("idl").textContent);
+
+        idl_array.add_objects({
+          FileList: [fileInput.files],
+          File: [fileInput.files[0]],
+        });
+        idl_array.test();
+
+        done();
+      });
+    </script>
+  </body>
+</html>
diff --git a/src/third_party/web_platform_tests/FileAPI/idlharness.html b/src/third_party/web_platform_tests/FileAPI/idlharness.html
new file mode 100644
index 0000000..0ef3700
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/idlharness.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>File API automated IDL tests</title>
+    <link rel="author" title="Intel" href="http://www.intel.com">
+    <link rel="help" href="http://dev.w3.org/2006/webapi/FileAPI/#conformance">
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/resources/WebIDLParser.js"></script>
+    <script src="/resources/idlharness.js"></script>
+  </head>
+  <body>
+    <h1>File API automated IDL tests</h1>
+
+    <div id="log"></div>
+
+    <form name="uploadData">
+      <input type="file" id="fileChooser">
+    </form>
+
+    <script>
+var file_input;
+setup(function() {
+    var idl_array = new IdlArray();
+
+    var request = new XMLHttpRequest();
+    request.open("GET", "idlharness.idl");
+    request.send();
+    request.onload = function() {
+        var idls = request.responseText;
+
+        idl_array.add_untested_idls("[PrimaryGlobal] interface Window { };");
+
+        idl_array.add_untested_idls("interface ArrayBuffer {};");
+        idl_array.add_untested_idls("interface ArrayBufferView {};");
+        idl_array.add_untested_idls("interface URL {};");
+        idl_array.add_untested_idls("interface EventTarget {};");
+        idl_array.add_untested_idls("interface Event {};");
+        idl_array.add_untested_idls("[TreatNonCallableAsNull] callback EventHandlerNonNull = any (Event event);");
+        idl_array.add_untested_idls("typedef EventHandlerNonNull? EventHandler;");
+
+        idl_array.add_idls(idls);
+
+        file_input = document.querySelector("#fileChooser");
+        idl_array.add_objects({
+            Blob: ['new Blob(["TEST"])'],
+            File: ['new File(["myFileBits"], "myFileName")'],
+            FileList: ['file_input.files'],
+            FileReader: ['new FileReader()']
+        });
+
+        idl_array.test();
+        done();
+  };
+}, {explicit_done: true});
+    </script>
+
+  </body>
+</html>
diff --git a/src/third_party/web_platform_tests/FileAPI/idlharness.idl b/src/third_party/web_platform_tests/FileAPI/idlharness.idl
new file mode 100644
index 0000000..ae83a9c
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/idlharness.idl
@@ -0,0 +1,81 @@
+[Constructor,
+ Constructor(sequence<(ArrayBuffer or ArrayBufferView or Blob or DOMString)> blobParts, optional BlobPropertyBag options), Exposed=Window,Worker]
+interface Blob {
+
+  readonly attribute unsigned long long size;
+  readonly attribute DOMString type;
+  readonly attribute boolean isClosed;
+
+  //slice Blob into byte-ranged chunks
+
+  Blob slice([Clamp] optional long long start,
+             [Clamp] optional long long end,
+             optional DOMString contentType);
+  void close();
+
+};
+
+dictionary BlobPropertyBag {
+  DOMString type = "";
+};
+
+[Constructor(sequence<(Blob or DOMString or ArrayBufferView or ArrayBuffer)> fileBits,
+[EnsureUTF16] DOMString fileName, optional FilePropertyBag options), Exposed=Window,Worker]
+interface File : Blob {
+
+  readonly attribute DOMString name;
+  readonly attribute long long lastModified;
+
+};
+
+dictionary FilePropertyBag {
+
+  DOMString type = "";
+  long long lastModified;
+
+};
+
+[Exposed=Window,Worker] interface FileList {
+  getter File? item(unsigned long index);
+  readonly attribute unsigned long length;
+};
+
+[Constructor, Exposed=Window,Worker]
+interface FileReader: EventTarget {
+
+  // async read methods
+  void readAsArrayBuffer(Blob blob);
+  void readAsText(Blob blob, optional DOMString label);
+  void readAsDataURL(Blob blob);
+
+  void abort();
+
+  // states
+  const unsigned short EMPTY = 0;
+  const unsigned short LOADING = 1;
+  const unsigned short DONE = 2;
+
+  readonly attribute unsigned short readyState;
+
+  // File or Blob data
+  readonly attribute (DOMString or ArrayBuffer)? result;
+
+  readonly attribute DOMError? error;
+
+  // event handler attributes
+  attribute EventHandler onloadstart;
+  attribute EventHandler onprogress;
+  attribute EventHandler onload;
+  attribute EventHandler onabort;
+  attribute EventHandler onerror;
+  attribute EventHandler onloadend;
+
+};
+
+partial interface URL {
+
+  static DOMString createObjectURL(Blob blob);
+  static DOMString createFor(Blob blob);
+  static void revokeObjectURL(DOMString url);
+
+};
diff --git a/src/third_party/web_platform_tests/FileAPI/idlharness.worker.js b/src/third_party/web_platform_tests/FileAPI/idlharness.worker.js
new file mode 100644
index 0000000..40ba816
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/idlharness.worker.js
@@ -0,0 +1,45 @@
+importScripts("/resources/testharness.js");
+importScripts("/resources/WebIDLParser.js", "/resources/idlharness.js");
+
+var request = new XMLHttpRequest();
+request.open("GET", "idlharness.idl");
+request.send();
+request.onload = function() {
+    var idl_array = new IdlArray();
+    var idls = request.responseText;
+
+    idl_array.add_untested_idls("[Global] interface Window { };");
+
+    idl_array.add_untested_idls("interface ArrayBuffer {};");
+    idl_array.add_untested_idls("interface ArrayBufferView {};");
+    idl_array.add_untested_idls("interface URL {};");
+    idl_array.add_untested_idls("interface EventTarget {};");
+    idl_array.add_untested_idls("interface Event {};");
+    idl_array.add_untested_idls("[TreatNonCallableAsNull] callback EventHandlerNonNull = any (Event event);");
+    idl_array.add_untested_idls("typedef EventHandlerNonNull? EventHandler;");
+
+
+    var worker_idls =
+            '[Constructor, Exposed=Worker]\n' +
+            'interface FileReaderSync {\n' +
+            '\n' +
+            '  // Synchronously return strings\n' +
+            '\n' +
+            '  ArrayBuffer readAsArrayBuffer(Blob blob);\n' +
+            '  DOMString readAsText(Blob blob, optional DOMString label);\n' +
+            '  DOMString readAsDataURL(Blob blob);\n' +
+            '};';
+
+    idl_array.add_idls(idls);
+    idl_array.add_idls(worker_idls);
+
+    idl_array.add_objects({
+        Blob: ['new Blob(["TEST"])'],
+        File: ['new File(["myFileBits"], "myFileName")'],
+        FileReader: ['new FileReader()'],
+        FileReaderSync: ['new FileReaderSync()']
+    });
+
+    idl_array.test();
+    done();
+};
diff --git a/src/third_party/web_platform_tests/FileAPI/progress-manual.html b/src/third_party/web_platform_tests/FileAPI/progress-manual.html
new file mode 100644
index 0000000..b2e03b3
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/progress-manual.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Process Events for FileReader</title>
+<link rel=help href="http://dev.w3.org/2006/webapi/FileAPI/#event-handler-attributes-section">
+<link rel=author title="Jinks Zhao" href="mailto:jinks@maxthon.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+Please choose one file through this input below.<br>
+<input type="file" id="filer">
+<div id="log"></div>
+<script>
+var input, reader, progressEventCounter, progressEventTimeList,
+    lastProgressEventTime;
+setup(function() {
+    input = document.getElementById('filer');
+    reader = new FileReader();
+    progressEventCounter = 0;
+    progressEventTimeList = [];
+    lastProgressEventTime;
+}, { explicit_timeout: true });
+
+var t = async_test("FileReader progress events.")
+
+reader.onprogress = t.step_func(function () {
+    var newTime = new Date;
+    var timeout = newTime - lastProgressEventTime;
+
+    progressEventTimeList.push(timeout);
+    lastProgressEventTime = newTime;
+    progressEventCounter++;
+
+    assert_less_than_equal(timeout, 50, "The progress event should be fired every 50ms.");
+});
+
+reader.onload = t.step_func_done(function () {
+    assert_greater_than_equal(progressEventCounter, 1,
+                              "When read completely, the progress event must be fired at least once.")
+});
+
+input.onchange = t.step_func(function () {
+    var files = input.files;
+
+    assert_greater_than(files.length, 0);
+    var file = files[0];
+
+    lastProgressEventTime = new Date;
+    reader.readAsArrayBuffer(file);
+});
+</script>
diff --git a/src/third_party/web_platform_tests/FileAPI/reading-data-section/Determining-Encoding.html b/src/third_party/web_platform_tests/FileAPI/reading-data-section/Determining-Encoding.html
new file mode 100644
index 0000000..d65ae9d
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/reading-data-section/Determining-Encoding.html
@@ -0,0 +1,91 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>FileAPI Test: Blob Determining Encoding</title>
+<link ref="author" title="march1993" href="mailto:march511@gmail.com">
+<link rel=help href="http://dev.w3.org/2006/webapi/FileAPI/#enctype">
+<link rel=help href="http://encoding.spec.whatwg.org/#decode">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+var t = async_test("Blob Determing Encoding with encoding argument");
+t.step(function() {
+    // string 'hello'
+    var data = [0xFE,0xFF,0x00,0x68,0x00,0x65,0x00,0x6C,0x00,0x6C,0x00,0x6F];
+    var blob = new Blob([new Uint8Array(data)]);
+    var reader = new FileReader();
+
+    reader.onloadend = t.step_func_done (function(event) {
+        assert_equals(this.result, "hello", "The FileReader should read the ArrayBuffer through UTF-16BE.")
+    }, reader);
+
+    reader.readAsText(blob, "UTF-16BE");
+});
+
+var t = async_test("Blob Determing Encoding with type attribute");
+t.step(function() {
+    var data = [0xFE,0xFF,0x00,0x68,0x00,0x65,0x00,0x6C,0x00,0x6C,0x00,0x6F];
+    var blob = new Blob([new Uint8Array(data)], {type:"text/plain;charset=UTF-16BE"});
+    var reader = new FileReader();
+
+    reader.onloadend = t.step_func_done (function(event) {
+        assert_equals(this.result, "hello", "The FileReader should read the ArrayBuffer through UTF-16BE.")
+    }, reader);
+
+    reader.readAsText(blob);
+});
+
+
+var t = async_test("Blob Determing Encoding with UTF-8 BOM");
+t.step(function() {
+    var data = [0xEF,0xBB,0xBF,0x68,0x65,0x6C,0x6C,0xC3,0xB6];
+    var blob = new Blob([new Uint8Array(data)]);
+    var reader = new FileReader();
+
+    reader.onloadend = t.step_func_done (function(event) {
+        assert_equals(this.result, "hellö", "The FileReader should read the blob with UTF-8.");
+    }, reader);
+
+    reader.readAsText(blob);
+});
+
+var t = async_test("Blob Determing Encoding without anything implying charset.");
+t.step(function() {
+    var data = [0x68,0x65,0x6C,0x6C,0xC3,0xB6];
+    var blob = new Blob([new Uint8Array(data)]);
+    var reader = new FileReader();
+
+    reader.onloadend = t.step_func_done (function(event) {
+        assert_equals(this.result, "hellö", "The FileReader should read the blob by default with UTF-8.");
+    }, reader);
+
+    reader.readAsText(blob);
+});
+
+var t = async_test("Blob Determing Encoding with UTF-16BE BOM");
+t.step(function() {
+    var data = [0xFE,0xFF,0x00,0x68,0x00,0x65,0x00,0x6C,0x00,0x6C,0x00,0x6F];
+    var blob = new Blob([new Uint8Array(data)]);
+    var reader = new FileReader();
+
+    reader.onloadend = t.step_func_done (function(event) {
+        assert_equals(this.result, "hello", "The FileReader should read the ArrayBuffer through UTF-16BE.");
+    }, reader);
+
+    reader.readAsText(blob);
+});
+
+var t = async_test("Blob Determing Encoding with UTF-16LE BOM");
+t.step(function() {
+    var data = [0xFF,0xFE,0x68,0x00,0x65,0x00,0x6C,0x00,0x6C,0x00,0x6F,0x00];
+    var blob = new Blob([new Uint8Array(data)]);
+    var reader = new FileReader();
+
+    reader.onloadend = t.step_func_done (function(event) {
+        assert_equals(this.result, "hello", "The FileReader should read the ArrayBuffer through UTF-16LE.");
+    }, reader);
+
+    reader.readAsText(blob);
+});
+
+</script>
diff --git a/src/third_party/web_platform_tests/FileAPI/reading-data-section/FileReader-event-handler-attributes.html b/src/third_party/web_platform_tests/FileAPI/reading-data-section/FileReader-event-handler-attributes.html
new file mode 100644
index 0000000..86657b5
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/reading-data-section/FileReader-event-handler-attributes.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>FileReader event handler attributes</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var attributes = [
+  "onloadstart",
+  "onprogress",
+  "onload",
+  "onabort",
+  "onerror",
+  "onloadend",
+];
+attributes.forEach(function(a) {
+  test(function() {
+    var reader = new FileReader();
+    assert_equals(reader[a], null,
+                  "event handler attribute should initially be null");
+  }, "FileReader." + a + ": initial value");
+});
+</script>
diff --git a/src/third_party/web_platform_tests/FileAPI/reading-data-section/FileReader-multiple-reads.html b/src/third_party/web_platform_tests/FileAPI/reading-data-section/FileReader-multiple-reads.html
new file mode 100644
index 0000000..86a29d1
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/reading-data-section/FileReader-multiple-reads.html
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<title>FileReader: starting new reads while one is in progress</title>
+<link rel="author" title="Yinkan Li" href="mailto:liyinkan.biz@gmail.com">
+<link rel="help" href="http://dev.w3.org/2006/webapi/FileAPI/#MultipleReads">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+test(function() {
+  var blob_1 = new Blob(['TEST000000001'])
+  var blob_2 = new Blob(['TEST000000002'])
+  var reader = new FileReader();
+  reader.readAsText(blob_1)
+  assert_equals(reader.readyState, FileReader.LOADING, "readyState Must be LOADING")
+  assert_throws("InvalidStateError", function () {
+    reader.readAsText(blob_2)
+  })
+}, 'test FileReader InvalidStateError exception for readAsText');
+
+test(function() {
+  var blob_1 = new Blob(['TEST000000001'])
+  var blob_2 = new Blob(['TEST000000002'])
+  var reader = new FileReader();
+  reader.readAsDataURL(blob_1)
+  assert_equals(reader.readyState, FileReader.LOADING, "readyState Must be LOADING")
+  assert_throws("InvalidStateError", function () {
+    reader.readAsDataURL(blob_2)
+  })
+}, 'test FileReader InvalidStateError exception for readAsDataURL');
+
+test(function() {
+  var blob_1 = new Blob(['TEST000000001'])
+  var blob_2 = new Blob(['TEST000000002'])
+  var reader = new FileReader();
+  reader.readAsArrayBuffer(blob_1)
+  assert_equals(reader.readyState, FileReader.LOADING, "readyState Must be LOADING")
+  assert_throws("InvalidStateError", function () {
+    reader.readAsArrayBuffer(blob_2)
+  })
+}, 'test FileReader InvalidStateError exception for readAsArrayBuffer');
+
+async_test(function() {
+  var blob_1 = new Blob(['TEST000000001'])
+  var blob_2 = new Blob(['TEST000000002'])
+  var reader = new FileReader();
+  var triggered = false;
+  reader.onloadstart = this.step_func_done(function() {
+    assert_false(triggered, "Only one loadstart event should be dispatched");
+    triggered = true;
+    assert_equals(reader.readyState, FileReader.LOADING,
+                  "readyState must be LOADING")
+    assert_throws("InvalidStateError", function () {
+      reader.readAsArrayBuffer(blob_2)
+    })
+  });
+  reader.readAsArrayBuffer(blob_1)
+  assert_equals(reader.readyState, FileReader.LOADING, "readyState Must be LOADING")
+}, 'test FileReader InvalidStateError exception in onloadstart event for readAsArrayBuffer');
+
+async_test(function() {
+  var blob_1 = new Blob(['TEST000000001'])
+  var blob_2 = new Blob(['TEST000000002'])
+  var reader = new FileReader();
+  reader.onloadend = this.step_func_done(function() {
+    assert_equals(reader.readyState, FileReader.LOADING,
+                  "readyState must be LOADING")
+    reader.readAsArrayBuffer(blob_2)
+    assert_equals(reader.readyState, FileReader.LOADING, "readyState Must be LOADING")
+  });
+  reader.readAsArrayBuffer(blob_1)
+  assert_equals(reader.readyState, FileReader.LOADING, "readyState Must be LOADING")
+}, 'test FileReader no InvalidStateError exception in onloadstart event for readAsArrayBuffer');
+</script>
diff --git a/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_abort.html b/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_abort.html
new file mode 100644
index 0000000..a96389c
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_abort.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>FileAPI Test: filereader_abort</title>
+    <link rel="author" title="Intel" href="http://www.intel.com">
+    <link rel="help" href="http://dev.w3.org/2006/webapi/FileAPI/#abort">
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+
+    <script>
+    test(function() {
+      var readerNoRead = new FileReader();
+      readerNoRead.abort();
+      assert_equals(readerNoRead.readyState, readerNoRead.EMPTY);
+      assert_equals(readerNoRead.result, null);
+    }, "Aborting before read");
+
+    async_test(function() {
+      var blob = new Blob(["TEST THE ABORT METHOD"]);
+      var readerAbort = new FileReader();
+
+      readerAbort.onabort = this.step_func(function(evt) {
+        assert_equals(readerAbort.readyState, readerAbort.DONE);
+      });
+
+      readerAbort.onloadstart = this.step_func(function(evt) {
+        assert_equals(readerAbort.readyState, readerAbort.LOADING);
+        readerAbort.abort();
+      });
+
+      readerAbort.onloadend = this.step_func(function(evt) {
+        // https://www.w3.org/Bugs/Public/show_bug.cgi?id=24401
+        assert_equals(readerAbort.result, null);
+        assert_equals(readerAbort.readyState, readerAbort.DONE);
+        this.done();
+      });
+
+      readerAbort.readAsText(blob);
+    }, "Aborting after read");
+    </script>
+  </body>
+</html>
diff --git a/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_error.html b/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_error.html
new file mode 100644
index 0000000..cf45248
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_error.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>FileAPI Test: filereader_error</title>
+    <link rel="author" title="Intel" href="http://www.intel.com">
+    <link rel="help" href="http://dev.w3.org/2006/webapi/FileAPI/#dfn-domerror">
+    <link rel="help" href="http://dev.w3.org/2006/webapi/FileAPI/#abort">
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+
+    <script>
+    async_test(function() {
+      var blob = new Blob(["TEST THE ERROR ATTRIBUTE AND ERROR EVENT"]);
+      var reader = new FileReader();
+      assert_equals(reader.error, null, "The error is null when no error occurred");
+
+      reader.onload = this.step_func(function(evt) {
+        assert_unreached("Should not dispatch the load event");
+      });
+
+      reader.onloadend = this.step_func(function(evt) {
+        assert_equals(reader.result, null, "The result is null");
+        this.done();
+      });
+
+      reader.readAsText(blob);
+      reader.abort();
+    });
+    </script>
+  </body>
+</html>
diff --git a/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_file-manual.html b/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_file-manual.html
new file mode 100644
index 0000000..702ca9a
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_file-manual.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>FileAPI Test: filereader_file</title>
+    <link rel="author" title="Intel" href="http://www.intel.com">
+    <link rel="help" href="http://dev.w3.org/2006/webapi/FileAPI/#FileReader-interface">
+    <link rel="help" href="http://dev.w3.org/2006/webapi/FileAPI/#file">
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div>
+      <p>Test step:</p>
+      <ol>
+        <li>Download <a href="support/blue-100x100.png">blue-100x100.png</a> to local.</li>
+        <li>Select the local file (blue-100x100.png) to run the test.</li>
+      </ol>
+    </div>
+
+    <form name="uploadData">
+      <input type="file" id="fileChooser">
+    </form>
+
+    <div id="log"></div>
+    <script>
+      var fileInput = document.querySelector('#fileChooser');
+      var reader = new FileReader();
+
+      //readType: 1-> ArrayBuffer, 2-> Text, 3-> DataURL
+      var readType = 1;
+
+      setup({
+        explicit_done: true,
+        explicit_timeout: true,
+      });
+
+      on_event(fileInput, "change", function(evt) {
+        reader.readAsArrayBuffer(fileInput.files[0]);
+      });
+
+      on_event(reader, "load", function(evt) {
+        if (readType == 1) {
+          test(function() {
+            assert_true(reader.result instanceof ArrayBuffer, "The result is instanceof ArrayBuffer");
+          }, "Check if the readAsArrayBuffer works");
+
+          readType++;
+          reader.readAsText(fileInput.files[0]);
+        } else if (readType == 2) {
+          test(function() {
+            assert_equals(typeof reader.result, "string", "The result is typeof string");
+          }, "Check if the readAsText works");
+
+          readType++;
+          reader.readAsDataURL(fileInput.files[0]);
+        } else if (readType == 3) {
+          test(function() {
+            assert_equals(typeof reader.result, "string", "The result is typeof string");
+            assert_equals(reader.result.indexOf("data"), 0, "The result starts with 'data'");
+            assert_true(reader.result.indexOf("base64") > 0, "The result contains 'base64'");
+          }, "Check if the readAsDataURL works");
+
+          done();
+        }
+      });
+    </script>
+  </body>
+</html>
diff --git a/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_file_img-manual.html b/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_file_img-manual.html
new file mode 100644
index 0000000..fca42c7
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_file_img-manual.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>FileAPI Test: filereader_file_img</title>
+    <link rel="author" title="Intel" href="http://www.intel.com">
+    <link rel="help" href="http://dev.w3.org/2006/webapi/FileAPI/#FileReader-interface">
+    <link rel="help" href="http://dev.w3.org/2006/webapi/FileAPI/#file">
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div>
+      <p>Test step:</p>
+      <ol>
+        <li>Download <a href="support/blue-100x100.png">blue-100x100.png</a> to local.</li>
+        <li>Select the local file (blue-100x100.png) to run the test.</li>
+      </ol>
+    </div>
+
+    <form name="uploadData">
+      <input type="file" id="fileChooser">
+    </form>
+
+    <div id="log"></div>
+    <script>
+      var fileInput = document.querySelector('#fileChooser');
+      var reader = new FileReader();
+
+      setup({
+        explicit_done: true,
+        explicit_timeout: true,
+      });
+
+      fileInput.addEventListener("change", function(evt) {
+        reader.readAsDataURL(fileInput.files[0]);
+      }, false);
+
+      reader.addEventListener("loadend", function(evt) {
+        test(function () {
+          assert_true(reader.result.indexOf("iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAqklEQVR42u3RsREAMAgDMe+/M4E7ZkhBoeI9gJWkWpfaeToTECACAkRAgAgIEAEB4gQgAgJEQIAICBABASIgAgJEQIAICBABASIgAgJEQIAICBABASIgAgJEQIAICBABASIgAgJEQIAICBABASIgAgJEQIAICBABASIgAgJEQIAICBABASIgAgJEQIAICBABASIgAgJEQIAICBABASIgQJwARECACAgQ/W4AQauujc8IdAoAAAAASUVORK5CYII=") != -1, "Encoded image")
+        }, "Check if readAsDataURL returns correct image");
+        done();
+      }, false);
+    </script>
+  </body>
+</html>
diff --git a/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_readAsArrayBuffer.html b/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_readAsArrayBuffer.html
new file mode 100644
index 0000000..31001a5
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_readAsArrayBuffer.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>FileAPI Test: filereader_readAsArrayBuffer</title>
+    <link rel="author" title="Intel" href="http://www.intel.com">
+    <link rel="help" href="http://dev.w3.org/2006/webapi/FileAPI/#readAsArrayBuffer">
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+
+    <script>
+    async_test(function() {
+      var blob = new Blob(["TEST"]);
+      var reader = new FileReader();
+
+      reader.onload = this.step_func(function(evt) {
+        assert_equals(reader.result.byteLength, 4, "The byteLength is 4");
+        assert_true(reader.result instanceof ArrayBuffer, "The result is instanceof ArrayBuffer");
+        assert_equals(reader.readyState, reader.DONE);
+        this.done();
+      });
+
+      reader.onloadstart = this.step_func(function(evt) {
+        assert_equals(reader.readyState, reader.LOADING);
+      });
+
+      reader.onprogress = this.step_func(function(evt) {
+        assert_equals(reader.readyState, reader.LOADING);
+      });
+
+      reader.readAsArrayBuffer(blob);
+    });
+    </script>
+  </body>
+</html>
diff --git a/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_readAsDataURL.html b/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_readAsDataURL.html
new file mode 100644
index 0000000..f0a3957
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_readAsDataURL.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>FileAPI Test: filereader_readAsDataURL</title>
+    <link rel="author" title="Intel" href="http://www.intel.com">
+    <link rel="help" href="http://dev.w3.org/2006/webapi/FileAPI/#readAsDataURL">
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+
+    <script>
+    async_test(function() {
+      var blob = new Blob(["TEST"]);
+      var reader = new FileReader();
+
+      reader.onload = this.step_func(function(evt) {
+        assert_equals(typeof reader.result, "string", "The result is string");
+        assert_equals(reader.result.indexOf("data:"), 0, "The result attribute starts with 'data'");
+        assert_true(reader.result.indexOf("base64") > 0, "The result attribute contains 'base64'");
+        assert_equals(reader.readyState, reader.DONE);
+        this.done();
+      });
+
+      reader.onloadstart = this.step_func(function(evt) {
+        assert_equals(reader.readyState, reader.LOADING);
+      });
+
+      reader.onprogress = this.step_func(function(evt) {
+        assert_equals(reader.readyState, reader.LOADING);
+      });
+
+      reader.readAsDataURL(blob);
+    });
+    </script>
+  </body>
+</html>
diff --git a/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_readAsText.html b/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_readAsText.html
new file mode 100644
index 0000000..7d639d0
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_readAsText.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>FileAPI Test: filereader_readAsText</title>
+    <link rel="author" title="Intel" href="http://www.intel.com">
+    <link rel="help" href="http://dev.w3.org/2006/webapi/FileAPI/#readAsDataText">
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+
+    <script>
+    async_test(function() {
+      var blob = new Blob(["TEST"]);
+      var reader = new FileReader();
+
+      reader.onload = this.step_func(function(evt) {
+        assert_equals(typeof reader.result, "string", "The result is typeof string");
+        assert_equals(reader.result, "TEST", "The result is TEST");
+        this.done();
+      });
+
+      reader.onloadstart = this.step_func(function(evt) {
+        assert_equals(reader.readyState, reader.LOADING, "The readyState");
+      });
+
+      reader.onprogress = this.step_func(function(evt) {
+        assert_equals(reader.readyState, reader.LOADING);
+      });
+
+      reader.readAsText(blob);
+    }, "readAsText should correctly read UTF-8.");
+
+    async_test(function() {
+      var blob = new Blob(["TEST"]);
+      var reader = new FileReader();
+      var reader_UTF16 = new FileReader();
+      reader_UTF16.onload = this.step_func(function(evt) {
+        // "TEST" in UTF-8 is 0x54 0x45 0x53 0x54.
+        // Decoded as utf-16 (little-endian), we get 0x4554 0x5453.
+        assert_equals(reader_UTF16.readyState, reader.DONE, "The readyState");
+        assert_equals(reader_UTF16.result, "\u4554\u5453", "The result is not TEST");
+        this.done();
+      });
+      reader_UTF16.readAsText(blob, "UTF-16");
+    }, "readAsText should correctly read UTF-16.");
+    </script>
+  </body>
+</html>
diff --git a/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_readystate.html b/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_readystate.html
new file mode 100644
index 0000000..1586b89
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_readystate.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>FileAPI Test: filereader_readystate</title>
+    <link rel="author" title="Intel" href="http://www.intel.com">
+    <link rel="help" href="http://dev.w3.org/2006/webapi/FileAPI/#blobreader-state">
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+
+    <script>
+    async_test(function() {
+      var blob = new Blob(["THIS TEST THE READYSTATE WHEN READ BLOB"]);
+      var reader = new FileReader();
+
+      assert_equals(reader.readyState, reader.EMPTY);
+
+      reader.onloadstart = this.step_func(function(evt) {
+        assert_equals(reader.readyState, reader.LOADING);
+      });
+
+      reader.onloadend = this.step_func(function(evt) {
+        assert_equals(reader.readyState, reader.DONE);
+        this.done();
+      });
+
+      reader.readAsDataURL(blob);
+    });
+    </script>
+  </body>
+</html>
diff --git a/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_result.html b/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_result.html
new file mode 100644
index 0000000..957d033
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/reading-data-section/filereader_result.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>FileAPI Test: filereader_result</title>
+    <link rel="author" title="Intel" href="http://www.intel.com">
+    <link rel="help" href="http://dev.w3.org/2006/webapi/FileAPI/#filedata-attr">
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+
+    <script>
+    var blob;
+    setup(function() {
+      blob = new Blob(["This test the result attribute"]);
+    });
+
+    async_test(function() {
+      var readText = new FileReader();
+      assert_equals(readText.result, null);
+
+      readText.onloadend = this.step_func(function(evt) {
+        assert_equals(typeof readText.result, "string", "The result type is string");
+        assert_equals(readText.result, "This test the result attribute", "The result is correct");
+        this.done();
+      });
+
+      readText.readAsText(blob);
+    }, "readAsText");
+
+    async_test(function() {
+      var readDataURL = new FileReader();
+      assert_equals(readDataURL.result, null);
+
+      readDataURL.onloadend = this.step_func(function(evt) {
+        assert_equals(typeof readDataURL.result, "string", "The result type is string");
+        assert_true(readDataURL.result.indexOf("VGhpcyB0ZXN0IHRoZSByZXN1bHQgYXR0cmlidXRl") != -1, "return the right base64 string");
+        this.done();
+      });
+
+      readDataURL.readAsDataURL(blob);
+    }, "readAsDataURL");
+
+    async_test(function() {
+      var readArrayBuffer = new FileReader();
+      assert_equals(readArrayBuffer.result, null);
+
+      readArrayBuffer.onloadend = this.step_func(function(evt) {
+        assert_true(readArrayBuffer.result instanceof ArrayBuffer, "The result is instanceof ArrayBuffer");
+        this.done();
+      });
+
+      readArrayBuffer.readAsArrayBuffer(blob);
+    }, "readAsArrayBuffer");
+    </script>
+  </body>
+</html>
diff --git a/src/third_party/web_platform_tests/FileAPI/reading-data-section/support/blue-100x100.png b/src/third_party/web_platform_tests/FileAPI/reading-data-section/support/blue-100x100.png
new file mode 100644
index 0000000..5748719
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/reading-data-section/support/blue-100x100.png
Binary files differ
diff --git a/src/third_party/web_platform_tests/FileAPI/support/Blob.js b/src/third_party/web_platform_tests/FileAPI/support/Blob.js
new file mode 100644
index 0000000..1d66f23
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/support/Blob.js
@@ -0,0 +1,49 @@
+function test_blob(fn, expectations) {
+  var expected = expectations.expected,
+      type = expectations.type,
+      desc = expectations.desc;
+
+  var t = async_test(desc);
+  t.step(function() {
+    var blob = fn();
+    assert_true(blob instanceof Blob);
+    assert_false(blob instanceof File);
+    assert_equals(blob.type, type);
+    assert_equals(blob.size, expected.length);
+
+    var fr = new FileReader();
+    fr.onload = t.step_func_done(function(event) {
+      assert_equals(this.result, expected);
+    }, fr);
+    fr.onerror = t.step_func(function(e) {
+      assert_unreached("got error event on FileReader");
+    });
+    fr.readAsText(blob, "UTF-8");
+  });
+}
+
+function test_blob_binary(fn, expectations) {
+  var expected = expectations.expected,
+      type = expectations.type,
+      desc = expectations.desc;
+
+  var t = async_test(desc);
+  t.step(function() {
+    var blob = fn();
+    assert_true(blob instanceof Blob);
+    assert_false(blob instanceof File);
+    assert_equals(blob.type, type);
+    assert_equals(blob.size, expected.length);
+
+    var fr = new FileReader();
+    fr.onload = t.step_func_done(function(event) {
+      assert_true(this.result instanceof ArrayBuffer,
+                  "Result should be an ArrayBuffer");
+      assert_array_equals(new Uint8Array(this.result), expected);
+    }, fr);
+    fr.onerror = t.step_func(function(e) {
+      assert_unreached("got error event on FileReader");
+    });
+    fr.readAsArrayBuffer(blob);
+  });
+}
diff --git a/src/third_party/web_platform_tests/FileAPI/support/upload.txt b/src/third_party/web_platform_tests/FileAPI/support/upload.txt
new file mode 100644
index 0000000..5ab2f8a
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/support/upload.txt
@@ -0,0 +1 @@
+Hello
\ No newline at end of file
diff --git a/src/third_party/web_platform_tests/FileAPI/url/url_createobjecturl_blob.html b/src/third_party/web_platform_tests/FileAPI/url/url_createobjecturl_blob.html
new file mode 100644
index 0000000..db6b441
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/url/url_createobjecturl_blob.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>FileAPI Test: Creating Blob URL with Blob</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<link rel="author" title="JunChen Xia" href="mailto:xjconlyme@gmail.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id="log"></div>
+
+<script>
+  var blob = new Blob(["Test Blob"]);
+
+  test(function() {
+    var testBlob = window.URL.createObjectURL(blob);
+    assert_equals(typeof testBlob, "string", "Blob URI is typeof string");
+    assert_equals(testBlob.indexOf("blob"), 0, "Blob URI starts with 'blob'");
+  }, "Check if the Blob URI starts with 'blob' using createObjectURL()");
+
+  test(function() {
+    var testBlob = window.URL.createFor(blob);
+    assert_equals(typeof testBlob, "string", "Blob URI is typeof string");
+    assert_equals(testBlob.indexOf("blob"), 0, "Blob URI starts with 'blob'");
+  }, "Check if the Blob URI starts with 'blob' using createFor()");
+</script>
+
diff --git a/src/third_party/web_platform_tests/FileAPI/url/url_createobjecturl_file-manual.html b/src/third_party/web_platform_tests/FileAPI/url/url_createobjecturl_file-manual.html
new file mode 100644
index 0000000..5dcd1d4
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/url/url_createobjecturl_file-manual.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>FileAPI Test: Creating Blob URL with File</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<link rel="author" title="JunChen Xia" href="mailto:xjconlyme@gmail.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name="timeout" content="long">
+
+<div>
+  <p>Test steps:</p>
+  <ol>
+    <li>Download <a href="/images/blue96x96.png">blue96x96.png</a> to local.</li>
+    <li>Select the local file (blue96x96.png) to run the test.</li>
+  </ol>
+</div>
+
+<form name="uploadData">
+  <input type="file" id="fileChooser">
+</form>
+
+<div id="log"></div>
+
+<script>
+  async_test(function(t) {
+    var fileInput = document.querySelector('#fileChooser');
+
+    fileInput.onchange = t.step_func(function(e) {
+      var blobURL, file = fileInput.files[0];
+
+      test(function() {
+        assert_true(file instanceof File, "FileList contains File");
+      }, "Check if FileList contains File");
+
+      test(function() {
+        blobURL = window.URL.createObjectURL(file);
+        assert_equals(typeof blobURL, "string", "Blob URL is type of string");
+        assert_equals(blobURL.indexOf("blob"), 0, "Blob URL's scheme is blob");
+      }, "Check if URL.createObjectURL(File) returns a Blob URL");
+
+      test(function() {
+        blobURL = window.URL.createFor(file);
+        assert_equals(typeof blobURL, "string", "Blob URL is type of string");
+        assert_equals(blobURL.indexOf("blob"), 0, "Blob URL's scheme is blob");
+      }, "Check if URL.createFor(File) returns a Blob URL");
+
+      t.done();
+    });
+  });
+</script>
+
diff --git a/src/third_party/web_platform_tests/FileAPI/url/url_createobjecturl_file_img-manual.html b/src/third_party/web_platform_tests/FileAPI/url/url_createobjecturl_file_img-manual.html
new file mode 100644
index 0000000..534c1de
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/url/url_createobjecturl_file_img-manual.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>FileAPI Test: Creating Blob URL with File as image source</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<link rel="author" title="JunChen Xia" href="mailto:xjconlyme@gmail.com">
+
+<div>
+  <p>Test steps:</p>
+  <ol>
+    <li>Download <a href="/images/blue96x96.png">blue96x96.png</a> to local.</li>
+    <li>Select the local file (blue96x96.png) to run the test.</li>
+  </ol>
+  <p>Pass/fail criteria:</p>
+  <p>Test passes if there is a filled blue square.</p>
+
+  <p><input type="file" accept="image/*" id="fileChooser"></p>
+  <p><img id="displayImage"></img></p>
+</div>
+
+<script>
+  var fileInput = document.querySelector("#fileChooser");
+  var img = document.querySelector("#displayImage");
+
+  fileInput.addEventListener("change", function(evt) {
+    img.src = window.URL.createObjectURL(fileInput.files[0]);
+  }, false);
+</script>
+
diff --git a/src/third_party/web_platform_tests/FileAPI/url/url_xmlhttprequest.html b/src/third_party/web_platform_tests/FileAPI/url/url_xmlhttprequest.html
new file mode 100644
index 0000000..7a86cdd
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/url/url_xmlhttprequest.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>FileAPI Test: Creating Blob URL via XMLHttpRequest</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<link rel="author" title="JunChen Xia" href="mailto:xjconlyme@gmail.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id="log"></div>
+
+<script>
+  async_test(function () {
+    var http = new XMLHttpRequest();
+    http.open("GET", "/images/blue96x96.png", true);
+    http.responseType = "blob";
+    http.onloadend = this.step_func(function(evt) {
+      var blobURI = window.URL.createObjectURL(http.response);
+      assert_true(http.response instanceof Blob, "XMLHttpRequest returns instanceof Blob");
+      assert_equals(typeof blobURI, "string", "Blob URI is typeof string");
+      assert_equals(blobURI.indexOf("blob"), 0, "Blob URI starts with 'blob'");
+      assert_equals(http.status, 200, "The status is 200");
+      assert_equals(http.statusText, "OK", "The status text is OK when XMLHttpRequest returns correct blob");
+      assert_equals(http.getResponseHeader("Content-Type"), "image/png", "The content type is image/png when set the respnose blob");
+      this.done();
+    });
+    http.send();
+  });
+</script>
+
diff --git a/src/third_party/web_platform_tests/FileAPI/url/url_xmlhttprequest_img-ref.html b/src/third_party/web_platform_tests/FileAPI/url/url_xmlhttprequest_img-ref.html
new file mode 100644
index 0000000..7d73904
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/url/url_xmlhttprequest_img-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>FileAPI Reference File</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<link rel="author" title="JunChen Xia" href="mailto:xjconlyme@gmail.com">
+
+<p>Test passes if there is a filled blue square.</p>
+
+<p>
+  <img id="fileDisplay" src="/images/blue96x96.png">
+</p>
+
diff --git a/src/third_party/web_platform_tests/FileAPI/url/url_xmlhttprequest_img.html b/src/third_party/web_platform_tests/FileAPI/url/url_xmlhttprequest_img.html
new file mode 100644
index 0000000..7f26633
--- /dev/null
+++ b/src/third_party/web_platform_tests/FileAPI/url/url_xmlhttprequest_img.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>FileAPI Test: Creating Blob URL via XMLHttpRequest as image source</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<link rel="author" title="JunChen Xia" href="mailto:xjconlyme@gmail.com">
+<link rel="match" href="url_xmlhttprequest_img-ref.html">
+
+<p>Test passes if there is a filled blue square.</p>
+
+<p>
+  <img id="fileDisplay">
+</p>
+
+<script src="/common/reftest-wait.js"></script>
+<script>
+  var http = new XMLHttpRequest();
+  http.open("GET", "/images/blue96x96.png", true);
+  http.responseType = "blob";
+  http.onloadend = function() {
+    var fileDisplay = document.querySelector("#fileDisplay");
+    fileDisplay.src = window.URL.createObjectURL(http.response);
+    takeScreenshot();
+  };
+  http.send();
+</script>
+</html>
+