⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 115582 in webkit


Ignore:
Timestamp:
Apr 28, 2012, 3:24:48 PM (14 years ago)
Author:
weinig@apple.com
Message:

Add support for the Blob constructor
https://bugs.webkit.org/show_bug.cgi?id=84555

Reviewed by Maciej Stachowiak.

Source/WebCore:

Test: fast/files/blob-constructor.html

This adds an implementation of the Blob constructor that willfully
violates the W3C Editor’s Draft 29 February 2012 in the following ways:

  • bindings/js/JSBlobCustom.cpp:

(WebCore::JSBlobConstructor::constructJSBlob):
Implement blob constructor.

  • bindings/v8/custom/V8BlobCustom.cpp:

(WebCore::V8Blob::constructorCallback):
Implement blob constructor.

  • fileapi/Blob.idl:

Add constructor to IDL.

  • workers/WorkerContext.idl:

Add Blob constructor to the worker global object.

LayoutTests:

Switch tests that were not directly testing BlobBuilder over to
using the Blob constructor, to get test coverage of standard way
constructing blobs.

  • fast/files/blob-constructor.html: Added.
  • fast/files/blob-constructor-expected.txt: Added.
  • fast/files/script-tests/blob-constructor.js: Added.

New test.

  • fast/dom/HTMLAnchorElement/anchor-download-unset.html:
  • fast/dom/HTMLAnchorElement/anchor-download.html:
  • fast/dom/HTMLAnchorElement/anchor-nodownload-set.html:
  • fast/dom/HTMLAnchorElement/anchor-nodownload.html:
  • fast/dom/constructed-objects-prototypes-expected.txt:
  • fast/dom/window-domurl-crash.html:
  • fast/files/blob-slice-overflow.html:
  • fast/files/blob-slice-test.html:
  • fast/files/file-reader-fffd-expected.txt:
  • fast/files/file-reader-fffd.html:
  • fast/files/not-enough-arguments-expected.txt:
  • fast/files/not-enough-arguments.html:
  • fast/files/resources/read-blob-test-cases.js:
  • fast/files/resources/read-common.js:
  • fast/files/workers/inline-worker-via-blob-url.html:
  • fast/filesystem/resources/file-writer-abort-continue.js:
  • fast/filesystem/resources/file-writer-abort-depth.js:
  • fast/filesystem/resources/file-writer-abort.js:
  • fast/filesystem/resources/file-writer-events.js:
  • fast/filesystem/resources/file-writer-gc-blob.js:
  • fast/filesystem/resources/file-writer-sync-truncate-extend.js:
  • fast/filesystem/resources/file-writer-sync-write-overlapped.js:
  • fast/filesystem/resources/file-writer-utils.js:
  • http/tests/fileapi/create-blob-url-from-data-url.html:
  • http/tests/filesystem/no-cache-filesystem-url.html:
  • http/tests/local/blob/resources/hybrid-blob-util.js:
  • http/tests/security/resources/create-filesystem-file.html:
  • http/tests/websocket/tests/hixie76/send-object.html:
  • http/tests/websocket/tests/hybi/bufferedAmount-after-close-in-busy.html:
  • http/tests/websocket/tests/hybi/bufferedAmount-after-close.html:
  • http/tests/websocket/tests/hybi/send-blob.html:
  • http/tests/websocket/tests/hybi/send-file-blob-fail.html:
  • http/tests/websocket/tests/hybi/send-file-blob.html:
  • http/tests/websocket/tests/hybi/workers/resources/send-blob.js:
  • platform/mac/fast/dom/Window/window-properties-expected.txt:
  • storage/indexeddb/noblobs.html:
  • storage/indexeddb/structured-clone.html:
Location:
trunk
Files:
3 added
45 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r115578 r115582  
     12012-04-28  Sam Weinig  <sam@webkit.org>
     2
     3        Add support for the Blob constructor
     4        https://bugs.webkit.org/show_bug.cgi?id=84555
     5
     6        Reviewed by Maciej Stachowiak.
     7
     8        Switch tests that were not directly testing BlobBuilder over to
     9        using the Blob constructor, to get test coverage of standard way
     10        constructing blobs.
     11
     12        * fast/files/blob-constructor.html: Added.
     13        * fast/files/blob-constructor-expected.txt: Added.
     14        * fast/files/script-tests/blob-constructor.js: Added.
     15        New test.
     16
     17        * fast/dom/HTMLAnchorElement/anchor-download-unset.html:
     18        * fast/dom/HTMLAnchorElement/anchor-download.html:
     19        * fast/dom/HTMLAnchorElement/anchor-nodownload-set.html:
     20        * fast/dom/HTMLAnchorElement/anchor-nodownload.html:
     21        * fast/dom/constructed-objects-prototypes-expected.txt:
     22        * fast/dom/window-domurl-crash.html:
     23        * fast/files/blob-slice-overflow.html:
     24        * fast/files/blob-slice-test.html:
     25        * fast/files/file-reader-fffd-expected.txt:
     26        * fast/files/file-reader-fffd.html:
     27        * fast/files/not-enough-arguments-expected.txt:
     28        * fast/files/not-enough-arguments.html:
     29        * fast/files/resources/read-blob-test-cases.js:
     30        * fast/files/resources/read-common.js:
     31        * fast/files/workers/inline-worker-via-blob-url.html:
     32        * fast/filesystem/resources/file-writer-abort-continue.js:
     33        * fast/filesystem/resources/file-writer-abort-depth.js:
     34        * fast/filesystem/resources/file-writer-abort.js:
     35        * fast/filesystem/resources/file-writer-events.js:
     36        * fast/filesystem/resources/file-writer-gc-blob.js:
     37        * fast/filesystem/resources/file-writer-sync-truncate-extend.js:
     38        * fast/filesystem/resources/file-writer-sync-write-overlapped.js:
     39        * fast/filesystem/resources/file-writer-utils.js:
     40        * http/tests/fileapi/create-blob-url-from-data-url.html:
     41        * http/tests/filesystem/no-cache-filesystem-url.html:
     42        * http/tests/local/blob/resources/hybrid-blob-util.js:
     43        * http/tests/security/resources/create-filesystem-file.html:
     44        * http/tests/websocket/tests/hixie76/send-object.html:
     45        * http/tests/websocket/tests/hybi/bufferedAmount-after-close-in-busy.html:
     46        * http/tests/websocket/tests/hybi/bufferedAmount-after-close.html:
     47        * http/tests/websocket/tests/hybi/send-blob.html:
     48        * http/tests/websocket/tests/hybi/send-file-blob-fail.html:
     49        * http/tests/websocket/tests/hybi/send-file-blob.html:
     50        * http/tests/websocket/tests/hybi/workers/resources/send-blob.js:
     51        * platform/mac/fast/dom/Window/window-properties-expected.txt:
     52        * storage/indexeddb/noblobs.html:
     53        * storage/indexeddb/structured-clone.html:
     54
    1552012-04-28  Zan Dobersek  <zandobersek@gmail.com>
    256
  • trunk/LayoutTests/fast/dom/HTMLAnchorElement/anchor-download-unset.html

    r115491 r115582  
    2525function runTest()
    2626{
    27     var bb = new WebKitBlobBuilder();
    28     bb.append("<!doctype html><html><head><title>Title</title><script>if (window.layoutTestController) layoutTestController.dumpAsText(); </" + "script></head><body>PASS</body><script>if (window.layoutTestController) layoutTestController.notifyDone();</scr" + "ipt></html>");
    29     var blob = bb.getBlob("text/html", "inline");
     27    var string = "<!doctype html><html><head><title>Title</title><script>if (window.layoutTestController) layoutTestController.dumpAsText(); </" + "script></head><body>PASS</body><script>if (window.layoutTestController) layoutTestController.notifyDone();</scr" + "ipt></html>");   
     28    var blob = new Blob([string], {type: "text/html"});
    3029    var link = document.getElementById("blob-url");
    3130    link.href = window.webkitURL.createObjectURL(blob);
  • trunk/LayoutTests/fast/dom/HTMLAnchorElement/anchor-download.html

    r115491 r115582  
    2525function runTest()
    2626{
    27     var bb = new WebKitBlobBuilder();
    28     bb.append("<!doctype html><html><head><title>Title</title><script>if (window.layoutTestController) layoutTestController.dumpAsText(); </" + "script></head><body>PASS</body><script>if (window.layoutTestController) layoutTestController.notifyDone();</scr" + "ipt></html>");
    29     var blob = bb.getBlob("text/html", "inline");
     27    var string = "<!doctype html><html><head><title>Title</title><script>if (window.layoutTestController) layoutTestController.dumpAsText(); </" + "script></head><body>PASS</body><script>if (window.layoutTestController) layoutTestController.notifyDone();</scr" + "ipt></html>";
     28    var blob = new Blob([string], {type: "text/html"});
    3029    var link = document.getElementById("blob-url");
    3130    link.href = window.webkitURL.createObjectURL(blob);
  • trunk/LayoutTests/fast/dom/HTMLAnchorElement/anchor-nodownload-set.html

    r115491 r115582  
    2525function runTest()
    2626{
    27     var bb = new WebKitBlobBuilder();
    28     bb.append("<!doctype html><html><head><title>Title</title><script>if (window.layoutTestController) layoutTestController.dumpAsText(); </" + "script></head><body>PASS</body><script>if (window.layoutTestController) layoutTestController.notifyDone();</scr" + "ipt></html>");
    29     var blob = bb.getBlob("text/html", "inline");
     27    var string = "<!doctype html><html><head><title>Title</title><script>if (window.layoutTestController) layoutTestController.dumpAsText(); </" + "script></head><body>PASS</body><script>if (window.layoutTestController) layoutTestController.notifyDone();</scr" + "ipt></html>";
     28    var blob = new Blob([string], {type: "text/html"});
    3029    var link = document.getElementById("blob-url");
    3130    link.href = window.webkitURL.createObjectURL(blob);
  • trunk/LayoutTests/fast/dom/HTMLAnchorElement/anchor-nodownload.html

    r115491 r115582  
    2525function runTest()
    2626{
    27     var bb = new WebKitBlobBuilder();
    28     bb.append("<!doctype html><html><head><title>Title</title><script>if (window.layoutTestController) layoutTestController.dumpAsText(); </" + "script></head><body>PASS</body><script>if (window.layoutTestController) layoutTestController.notifyDone();</scr" + "ipt></html>");
    29     var blob = bb.getBlob("text/html", "inline");
     27    var string = "<!doctype html><html><head><title>Title</title><script>if (window.layoutTestController) layoutTestController.dumpAsText(); </" + "script></head><body>PASS</body><script>if (window.layoutTestController) layoutTestController.notifyDone();</scr" + "ipt></html>";
     28    var blob = new Blob([string], {type: "text/html"});
    3029    var link = document.getElementById("blob-url");
    3130    link.href = window.webkitURL.createObjectURL(blob);
  • trunk/LayoutTests/fast/dom/constructed-objects-prototypes-expected.txt

    r105520 r115582  
    88PASS (new inner.BeforeLoadEvent()).isInner is true
    99PASS (new inner.BeforeLoadEvent()).constructor.isInner is true
     10PASS (new inner.Blob()).isInner is true
     11PASS (new inner.Blob()).constructor.isInner is true
    1012PASS (new inner.CloseEvent()).isInner is true
    1113PASS (new inner.CloseEvent()).constructor.isInner is true
  • trunk/LayoutTests/fast/dom/window-domurl-crash.html

    r115491 r115582  
    22<head>
    33<script>
    4 var blob = (new WebKitBlobBuilder).getBlob();
     4var blob = new Blob([]);
    55var url = null;
    66var count = 0;
  • trunk/LayoutTests/fast/files/blob-slice-overflow.html

    r115491 r115582  
    66<script>
    77if (window.layoutTestController) {
    8   layoutTestController.dumpAsText();
    9   layoutTestController.waitUntilDone()
     8    layoutTestController.dumpAsText();
     9    layoutTestController.waitUntilDone()
    1010}
    11 var builder =  new WebKitBlobBuilder();
     11
    1212var text = '';
    13 for (var i = 0; i < 2000; ++i) text += 'A';
    14 builder.append(text);
    15 blob = builder.getBlob();
     13for (var i = 0; i < 2000; ++i)
     14    text += 'A';
     15
     16blob = new Blob([text]);
    1617slicedBlob = blob.webkitSlice(1999, 9223372036854775000);
     18
    1719document.getElementById('console').appendChild(document.createTextNode('Blob slice length: ' + slicedBlob.size));
    1820if (slicedBlob.size != 1) {
    19   document.getElementById('console').appendChild(document.createTextNode('FAIL'));
     21    document.getElementById('console').appendChild(document.createTextNode('FAIL'));
    2022}
     23
    2124if (window.layoutTestController) {
    2225  layoutTestController.notifyDone();
  • trunk/LayoutTests/fast/files/blob-slice-test.html

    r115491 r115582  
    8383function runTests()
    8484{
    85     var builder = new WebKitBlobBuilder();
    86     builder.append("0123456789");
    87     blob = builder.getBlob();
     85    blob = new Blob(["0123456789"]);
    8886
    8987    runNextTest();
  • trunk/LayoutTests/fast/files/file-reader-fffd-expected.txt

    r97543 r115582  
    33On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
    44
    5 bb = new WebKitBlobBuilder();
    65array = new Uint8Array([65, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 66]);
    7 blob = buildBlob([array.buffer]);
     6blob = new Blob([array.buffer]);
    87reader = new FileReader();
    98reader.readAsText(blob);
  • trunk/LayoutTests/fast/files/file-reader-fffd.html

    r115491 r115582  
    1111description("Throw various bad bytes at file reader.");
    1212
    13 bb = evalAndLog("bb = new WebKitBlobBuilder();");
    1413array = evalAndLog("array = new Uint8Array([65, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 66]);");
    15 blob = evalAndLog("blob = buildBlob([array.buffer]);");
     14blob = evalAndLog("blob = new Blob([array.buffer]);");
    1615reader = evalAndLog("reader = new FileReader();");
    1716reader.onload = function(event) {
  • trunk/LayoutTests/fast/files/not-enough-arguments-expected.txt

    r96956 r115582  
    88PASS reader.readAsText() threw exception TypeError: Not enough arguments.
    99PASS reader.readAsDataURL() threw exception TypeError: Not enough arguments.
    10 PASS blobBuilder.append() threw exception TypeError: Type error.
    1110PASS fileInput.files.item() threw exception TypeError: Not enough arguments.
    1211PASS successfullyParsed is true
  • trunk/LayoutTests/fast/files/not-enough-arguments.html

    r115491 r115582  
    1616shouldThrow('reader.readAsDataURL()');
    1717
    18 var blobBuilder = new WebKitBlobBuilder();
    19 
    20 shouldThrow('blobBuilder.append()');
    21 
    2218var fileInput = document.getElementsByTagName('input')[0];
    2319
  • trunk/LayoutTests/fast/files/resources/read-blob-test-cases.js

    r115491 r115582  
    171171{
    172172    log("Test reading a triple-sliced hybrid blob");
    173     var builder = new WebKitBlobBuilder();
    174173    var array = new Uint8Array([48, 49, 50]);
    175     var blob = buildBlob(['First', testFiles['file1'].webkitSlice(1, 11), testFiles['empty-file'], 'Second', testFiles['file2'], testFiles['file3'], 'Third', array.buffer], undefined, builder);
     174    var items = ['First', testFiles['file1'].webkitSlice(1, 11), testFiles['empty-file'], 'Second', testFiles['file2'], testFiles['file3'], 'Third', array.buffer];
     175    var blob = buildBlob(items);
    176176    var blob = blob.webkitSlice(7, 19);
    177     var blob2 = buildBlob(['Foo', blob, 'Bar'], undefined, builder);
     177    var blob2 = buildBlob(items.concat(['Foo', blob, 'Bar']));
    178178    var blob2 = blob2.webkitSlice(12, 42);
    179179    readBlobAsBinaryString(testFiles, blob2);
  • trunk/LayoutTests/fast/files/resources/read-common.js

    r115491 r115582  
    22// The 'contentType' argument is optional.
    33// If the 'builder' argument is not provided, create a new one.
    4 function buildBlob(items, contentType, builder)
    5 {
    6     if (builder === undefined)
    7         builder = new WebKitBlobBuilder();
    8     for (var i = 0; i < items.length; i++)
    9         builder.append(items[i]);
    10     return builder.getBlob(contentType);
     4function buildBlob(items, contentType)
     5{
     6    if (contentType === undefined)
     7        return new Blob(items);
     8    return new Blob(items, {type:contentType});
    119}
    1210
  • trunk/LayoutTests/fast/files/workers/inline-worker-via-blob-url.html

    r115491 r115582  
    1111{
    1212    log("Test inline web worker via blob URL.");
    13     var blobBuilder = new WebKitBlobBuilder();
    14     blobBuilder.append([
     13    var string = [
    1514        "onmessage = function(e) {",
    1615        "    postMessage('Hello from worker');",
    1716        "};"
    1817    ].join('\n'));
    19     var blobURL = webkitURL.createObjectURL(blobBuilder.getBlob());
     18    var blobURL = webkitURL.createObjectURL(new Blob([string]));
    2019    var worker = new Worker(blobURL);
    2120    worker.onmessage = function(event) {
  • trunk/LayoutTests/fast/filesystem/resources/file-writer-abort-continue.js

    r115491 r115582  
    5353
    5454function tenXBlob(blob) {
    55     var bb = new WebKitBlobBuilder();
     55    var bb = [];
    5656    for (var i = 0; i < 10; ++i) {
    57         bb.append(blob);
     57        bb.push(blob);
    5858    }
    59     return bb.getBlob();
     59    return new Blob(bb);
    6060}
    6161
     
    9292function startWrite() {
    9393    // Let's make it about a megabyte.
    94     var bb = new WebKitBlobBuilder();
    95     bb.append("lorem ipsum");
    96     var blob = tenXBlob(bb.getBlob());
     94    var blob = tenXBlob(new Blob(["lorem ipsum"]));
    9795    blob = tenXBlob(blob);
    9896    blob = tenXBlob(blob);
  • trunk/LayoutTests/fast/filesystem/resources/file-writer-abort-depth.js

    r115491 r115582  
    1111var sawWriteEnd;
    1212var writer;
    13 var bb = new WebKitBlobBuilder();
    14 bb.append("lorem ipsum");
    15 var blob = bb.getBlob();
     13var blob = new Blob(["lorem ipsum"]);
    1614var recursionDepth = 0;
    1715var method;
  • trunk/LayoutTests/fast/filesystem/resources/file-writer-abort.js

    r115491 r115582  
    1313
    1414function tenXBlob(blob) {
    15     var bb = new WebKitBlobBuilder();
     15    var bb = [];
    1616    for (var i = 0; i < 10; ++i) {
    17         bb.append(blob);
     17        bb.push(blob);
    1818    }
    19     return bb.getBlob();
     19    return new Blob(bb);
    2020}
    2121
     
    6363function startWrite(fileWriter) {
    6464    // Let's make it about a megabyte.
    65     var bb = new WebKitBlobBuilder();
    66     bb.append("lorem ipsum");
    67     var blob = tenXBlob(bb.getBlob());
     65    var blob = tenXBlob(new Blob(["lorem ipsum"]));
    6866    blob = tenXBlob(blob);
    6967    blob = tenXBlob(blob);
  • trunk/LayoutTests/fast/filesystem/resources/file-writer-events.js

    r115491 r115582  
    1717
    1818function tenXBlob(blob) {
    19     var bb = new WebKitBlobBuilder();
     19    var bb = [];
    2020    for (var i = 0; i < 10; ++i) {
    21         bb.append(blob);
     21        bb.push(blob);
    2222    }
    23     return bb.getBlob();
     23    return new Blob(bb);
    2424}
    2525
     
    7979function startWrite(fileWriter) {
    8080    // Let's make it about a megabyte.
    81     var bb = new WebKitBlobBuilder();
    82     bb.append("lorem ipsum");
    83     var blob = tenXBlob(bb.getBlob());
     81    var blob = tenXBlob(new Blob(["lorem ipsum"]));
    8482    blob = tenXBlob(blob);
    8583    blob = tenXBlob(blob);
  • trunk/LayoutTests/fast/filesystem/resources/file-writer-gc-blob.js

    r115491 r115582  
    1515
    1616function tenXBlob(blob) {
    17     var bb = new WebKitBlobBuilder();
     17    var bb = [];
    1818    for (var i = 0; i < 10; ++i) {
    19         bb.append(blob);
     19        bb.push(blob);
    2020    }
    21     return bb.getBlob();
     21    return new Blob(bb);
    2222}
    2323
    2424function startWrite(writer) {
    2525    // Let's make it about a megabyte.
    26     var bb = new WebKitBlobBuilder();
    27     bb.append("lorem ipsum");
    28     var blob = tenXBlob(bb.getBlob());
     26    var blob = tenXBlob(new Blob["lorem ipsum"]);
    2927    blob = tenXBlob(blob);
    3028    blob = tenXBlob(blob);
  • trunk/LayoutTests/fast/filesystem/resources/file-writer-sync-truncate-extend.js

    r115491 r115582  
    1616var writer = entry.createWriter();
    1717assert(!writer.position);
    18 var builder = new WebKitBlobBuilder();
    1918var testData = "test data";
    20 builder.append(testData);
    21 writer.write(builder.getBlob());
     19writer.write(new Blob([testData]));
    2220assert(writer.length == testData.length);
    2321assert(writer.position == writer.length);
  • trunk/LayoutTests/fast/filesystem/resources/file-writer-sync-write-overlapped.js

    r115491 r115582  
    1616var writer = entry.createWriter();
    1717assert(!writer.position);
    18 var builder = new WebKitBlobBuilder();
    1918var testData = "test data";
    20 builder.append(testData);
    21 var blob = builder.getBlob();
     19var blob = new Blob([testData]);
    2220writer.write(blob);
    2321assert(writer.length == testData.length);
  • trunk/LayoutTests/fast/filesystem/resources/file-writer-utils.js

    r115491 r115582  
    135135function writeString(fileEntry, fileWriter, offset, data, onSuccess)
    136136{
    137     var bb = new WebKitBlobBuilder();
    138     bb.append(data);
    139     var blob = bb.getBlob();
     137    var blob = new Blob([data]);
    140138    fileWriter.seek(offset);
    141139    fileWriter.write(blob);
  • trunk/LayoutTests/http/tests/fileapi/create-blob-url-from-data-url.html

    r115491 r115582  
    2929<p> Test case for checking blob URL not allowed to be created from the code running from data URI</p>
    3030<pre id='console'></pre>
    31 <iframe src="data:text/html,%3Cscript%3Evar%20b%20%3D%20new%20WebKitBlobBuilder()%3Bb.append(%22Foo%22)%3Bvar%20bb%20%3D%20b.getBlob('text%2Fhtml')%3Btop.location%3D'http%3A%2F%2F127.0.0.1%3A8000%2Ffileapi%2Fcreate-blob-url-from-data-url.html%23'%20%2B%20window.webkitURL.createObjectURL(bb)%3B%3C%2Fscript%3E"></iframe>
     31<iframe src="data:text/html,%3Cscript%3Evar%20bb%20%3D%20new%20Blob%28%5B%22Foo%22%5D%2C%20%7Btype%3A%22text%2Fhtml%22%7D%29%3Btop.location%3D%27http%3A%2F%2F127.0.0.1%3A8000%2Ffileapi%2Fcreate-blob-url-from-data-url.html%23%27%20%2B%20window.webkitURL.createObjectURL%28bb%29%3B%3C%2Fscript%3E"></iframe>
    3232</body>
    3333</html>
  • trunk/LayoutTests/http/tests/filesystem/no-cache-filesystem-url.html

    r115491 r115582  
    2525        callback(rand);
    2626      };
    27       var bb = new WebKitBlobBuilder();
    28       bb.append('document.getElementById("result").innerHTML = (expected == ' + rand + ') ? "SUCCESS" : "FAILURE";');
    29       writer.write(bb.getBlob('text/plain'));
     27      writer.write(new Blob(['document.getElementById("result").innerHTML = (expected == ' + rand + ') ? "SUCCESS" : "FAILURE";'], {type:'text/plain'}));
    3028    }
    3129
  • trunk/LayoutTests/http/tests/local/blob/resources/hybrid-blob-util.js

    r115491 r115582  
    132132    this.appendAndCreateBlob = function(items, opt_ending, opt_type)
    133133    {
    134         var bb = new WebKitBlobBuilder();
     134        var builder = [];
    135135        for (var i = 0; i < items.length; i++) {
    136136            if (items[i] instanceof Array) {
    137137                // If it's an array, combine its elements and append as a blob.
    138                 bb.append(this.appendAndCreateBlob(items[i], opt_ending, opt_type));
    139             } else if (items[i].type == "data" && opt_ending)
    140                 bb.append(items[i].value, opt_ending);
    141             else
    142                 bb.append(items[i].value);
     138                builder.push(this.appendAndCreateBlob(items[i], opt_ending, opt_type));
     139            } else
     140                builder.push(items[i].value);
    143141        }
    144         return bb.getBlob(opt_type);
     142        var options = {};
     143        if (opt_ending)
     144            options.endings = opt_ending;
     145        if (opt_type)
     146            options.type = opt_type;
     147        return new Blob(builder, options);
    145148    };
    146149};
  • trunk/LayoutTests/http/tests/security/resources/create-filesystem-file.html

    r115491 r115582  
    66                fs.root.getFile("page.html", {create:true}, function(entry) {
    77                    entry.createWriter(function(writer) {
    8                         var bb = new WebKitBlobBuilder();
    9                         bb.append('<div id="innerDiv">Visible Contents</div>\n');
    108                        writer.onwrite = function() {
    119                            console.log(entry.toURL() + " created.");
    1210                        };
    13                         writer.write(bb.getBlob());
     11                        writer.write(new Blob(['<div id="innerDiv">Visible Contents</div>\n']));
    1412                    });
    1513                });
  • trunk/LayoutTests/http/tests/websocket/tests/hixie76/send-object.html

    r115491 r115582  
    1616function createEmptyBlob()
    1717{
    18     var builder = new WebKitBlobBuilder();
    19     return builder.getBlob();
     18    return new Blob([]);
    2019}
    2120
  • trunk/LayoutTests/http/tests/websocket/tests/hybi/bufferedAmount-after-close-in-busy.html

    r115491 r115582  
    2424function createBlobWithLength(length)
    2525{
    26     var builder = new WebKitBlobBuilder();
    27     builder.append(new ArrayBuffer(length));
    28     return builder.getBlob();
     26    return new Blob([new ArrayBuffer(length)]);
    2927}
    3028
  • trunk/LayoutTests/http/tests/websocket/tests/hybi/bufferedAmount-after-close.html

    r115491 r115582  
    2424function createBlobWithLength(length)
    2525{
    26     var builder = new WebKitBlobBuilder();
    27     builder.append(new ArrayBuffer(length));
    28     return builder.getBlob();
     26    return new Blob([new ArrayBuffer(length)]);
    2927}
    3028
  • trunk/LayoutTests/http/tests/websocket/tests/hybi/send-blob.html

    r115491 r115582  
    2121function createBlobContainingHelloWorld()
    2222{
    23     var builder = new WebKitBlobBuilder();
    24     builder.append("Hello, world!");
    25     return builder.getBlob();
     23    return new Blob(["Hello, world!"]);
    2624}
    2725
    2826function createEmptyBlob()
    2927{
    30     var builder = new WebKitBlobBuilder();
    31     return builder.getBlob();
     28    return new Blob([]);
    3229}
    3330
     
    3734    for (var i = 0; i < 256; ++i)
    3835        array[i] = i;
    39     var builder = new WebKitBlobBuilder();
    40     builder.append(array.buffer);
    41     return builder.getBlob();
     36    return new Blob([array.buffer]);
    4237}
    4338
  • trunk/LayoutTests/http/tests/websocket/tests/hybi/send-file-blob-fail.html

    r115491 r115582  
    6060    writer.onwrite = function()
    6161    {
    62         var builder = new WebKitBlobBuilder();
    63         builder.append(messageToWrite);
    64         writer.write(builder.getBlob());
     62        writer.write(new Blob([messageToWrite]));
    6563        writer.onwrite = didWriteFile;
    6664    };
  • trunk/LayoutTests/http/tests/websocket/tests/hybi/send-file-blob.html

    r115491 r115582  
    6060    writer.onwrite = function()
    6161    {
    62         var builder = new WebKitBlobBuilder();
    63         builder.append(messageToWrite);
    64         writer.write(builder.getBlob());
     62        writer.write(new Blob([messageToWrite]));
    6563        writer.onwrite = didWriteFile;
    6664    };
  • trunk/LayoutTests/http/tests/websocket/tests/hybi/workers/resources/send-blob.js

    r115491 r115582  
    11function createBlobContainingHelloWorld()
    22{
    3     var builder = new WebKitBlobBuilder();
    4     builder.append("Hello, world!");
    5     return builder.getBlob();
     3    return new Blob(["Hello, world!"]);
    64}
    75
    86function createEmptyBlob()
    97{
    10     var builder = new WebKitBlobBuilder();
    11     return builder.getBlob();
     8    return new Blob([]);
    129}
    1310
     
    1714    for (var i = 0; i < 256; ++i)
    1815        array[i] = i;
    19     var builder = new WebKitBlobBuilder();
    20     builder.append(array.buffer);
    21     return builder.getBlob();
     16    return new Blob([array.buffer]);
    2217}
    2318
  • trunk/LayoutTests/platform/mac/fast/dom/Window/window-properties-expected.txt

    r115491 r115582  
    181181window.BeforeLoadEvent.prototype.stopPropagation [function]
    182182window.Blob [object BlobConstructor]
     183window.Blob.length [number]
    183184window.Blob.prototype [object BlobPrototype]
    184185window.Boolean [function]
  • trunk/LayoutTests/storage/indexeddb/noblobs.html

    r115491 r115582  
    5959    debug("testBlob():");
    6060
    61     evalAndLog("BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder");
    62     shouldBeTrue("BlobBuilder != null");
    6361    shouldBeTrue("FileReader != null");
    64     evalAndLog("builder = new BlobBuilder()");
    6562    evalAndLog("test_content = 'This is a test. This is only a test.'");
    66     evalAndLog("builder.append(test_content)");
    67     evalAndLog("blob = builder.getBlob()");
     63    evalAndLog("blob = new Blob([test_content])");
    6864    validateExceptions("blob", testFile);
    6965}
  • trunk/LayoutTests/storage/indexeddb/structured-clone.html

    r115491 r115582  
    377377    return;
    378378
    379     evalAndLog("BlobBuilder = self.BlobBuilder || self.WebKitBlobBuilder");
    380     shouldBeTrue("BlobBuilder != null");
    381379    shouldBeTrue("FileReader != null");
    382     evalAndLog("builder = new BlobBuilder()");
    383380    evalAndLog("test_content = 'This is a test. This is only a test.'");
    384     evalAndLog("builder.append(test_content)");
    385     evalAndLog("test_data = builder.getBlob()");
     381    evalAndLog("test_data = new Blob([test_content])");
    386382    testValue(test_data, function(result) {
    387383        self.result = result;
  • trunk/Source/WebCore/ChangeLog

    r115581 r115582  
     12012-04-27  Sam Weinig  <sam@webkit.org>
     2
     3        Add support for the Blob constructor
     4        https://bugs.webkit.org/show_bug.cgi?id=84555
     5
     6        Reviewed by Maciej Stachowiak.
     7
     8        Test: fast/files/blob-constructor.html
     9
     10        This adds an implementation of the Blob constructor that willfully
     11        violates the W3C Editor’s Draft 29 February 2012 in the following ways:
     12        - Elements in the parts array are coerced to DOMStrings https://www.w3.org/Bugs/Public/show_bug.cgi?id=16721
     13        - Don't throw for invalid key in the dictionary https://www.w3.org/Bugs/Public/show_bug.cgi?id=16727
     14        - Values for the endings property are treated as enums https://www.w3.org/Bugs/Public/show_bug.cgi?id=16729
     15
     16        * bindings/js/JSBlobCustom.cpp:
     17        (WebCore::JSBlobConstructor::constructJSBlob):
     18        Implement blob constructor.
     19
     20        * bindings/v8/custom/V8BlobCustom.cpp:
     21        (WebCore::V8Blob::constructorCallback):
     22        Implement blob constructor.
     23
     24        * fileapi/Blob.idl:
     25        Add constructor to IDL.
     26
     27        * workers/WorkerContext.idl:
     28        Add Blob constructor to the worker global object.
     29
    1302012-04-28  Igor Oliveira  <igor.o@sisa.samsung.com>
    231
  • trunk/Source/WebCore/bindings/js/JSBlobCustom.cpp

    r115491 r115582  
    3333
    3434#include "Blob.h"
     35#include "ExceptionCode.h"
     36#include "ExceptionCodePlaceholder.h"
     37#include "JSArrayBuffer.h"
    3538#include "JSDOMBinding.h"
     39#include "JSDictionary.h"
    3640#include "JSFile.h"
     41#include "WebKitBlobBuilder.h"
     42#include <runtime/Error.h>
     43#include <runtime/JSArray.h>
    3744#include <wtf/Assertions.h>
    3845
     
    5259}
    5360
     61EncodedJSValue JSC_HOST_CALL JSBlobConstructor::constructJSBlob(ExecState* exec)
     62{
     63    JSBlobConstructor* jsConstructor = jsCast<JSBlobConstructor*>(exec->callee());
     64    ScriptExecutionContext* context = jsConstructor->scriptExecutionContext();
     65    if (!context)
     66        return throwVMError(exec, createReferenceError(exec, "Blob constructor associated document is unavailable"));
     67
     68    if (!exec->argumentCount()) {
     69        RefPtr<Blob> blob = Blob::create();
     70        return JSValue::encode(CREATE_DOM_WRAPPER(exec, jsConstructor->globalObject(), Blob, blob.get()));
     71    }
     72
     73    JSValue firstArg = exec->argument(0);
     74    if (!isJSArray(firstArg))
     75        return throwVMError(exec, createTypeError(exec, "First argument of the constructor is not of type Array"));
     76
     77    String type;
     78    String endings = "transparent";
     79
     80    if (exec->argumentCount() > 1) {
     81        JSValue blobPropertyBagValue = exec->argument(1);
     82
     83        // FIXME: Should we throw if the blobPropertyBag is not an object?
     84
     85        if (blobPropertyBagValue.isObject()) {
     86            // Given the above test, this will always yield an object.
     87            JSObject* blobPropertyBagObject = blobPropertyBagValue.toObject(exec);
     88
     89            // Create the dictionary wrapper from the initializer object.
     90            JSDictionary dictionary(exec, blobPropertyBagObject);
     91
     92            // Attempt to get the type property.
     93            dictionary.get("type", type);
     94            if (exec->hadException())
     95                return JSValue::encode(jsUndefined());
     96
     97            // Attempt to get the endings property and validate it.
     98            bool containsEndings = dictionary.get("endings", endings);
     99            if (exec->hadException())
     100                return JSValue::encode(jsUndefined());
     101
     102            if (containsEndings) {
     103                if (endings != "transparent" && endings != "native") {
     104                    setDOMException(exec, INVALID_STATE_ERR);
     105                    return JSValue::encode(jsUndefined());
     106                }
     107            }
     108        }
     109    }
     110
     111    ASSERT(endings == "transparent" || endings == "native");
     112
     113    // FIXME: this would be better if the WebKitBlobBuilder were a stack object to avoid the allocation.
     114    RefPtr<WebKitBlobBuilder> blobBuilder = WebKitBlobBuilder::create();
     115
     116    JSArray* array = asArray(firstArg);
     117    unsigned length = array->length();
     118
     119    for (unsigned i = 0; i < length; ++i) {
     120        JSValue item = array->getIndex(i);
     121#if ENABLE(BLOB)
     122        if (item.inherits(&JSArrayBuffer::s_info))
     123            blobBuilder->append(toArrayBuffer(item));
     124        else
     125#endif
     126        if (item.inherits(&JSBlob::s_info))
     127            blobBuilder->append(toBlob(item));
     128        else {
     129            String string = ustringToString(item.toString(exec)->value(exec));
     130            if (exec->hadException())
     131                return JSValue::encode(jsUndefined());
     132            blobBuilder->append(string, endings, ASSERT_NO_EXCEPTION);
     133        }
     134    }
     135
     136    RefPtr<Blob> blob = blobBuilder->getBlob(type);
     137    return JSValue::encode(CREATE_DOM_WRAPPER(exec, jsConstructor->globalObject(), Blob, blob.get()));
     138}
     139
    54140} // namespace WebCore
  • trunk/Source/WebCore/bindings/v8/custom/V8BlobCustom.cpp

    r115491 r115582  
    3232#include "Blob.h"
    3333
     34#include "Dictionary.h"
     35#include "V8Binding.h"
    3436#include "V8Blob.h"
    3537#include "V8File.h"
    3638#include "V8Proxy.h"
     39#include "V8Utilities.h"
     40#include "WebKitBlobBuilder.h"
    3741#include <wtf/RefPtr.h>
    3842
     
    5054}
    5155
     56v8::Handle<v8::Value> V8Blob::constructorCallback(const v8::Arguments& args)
     57{
     58    INC_STATS("DOM.Blob.Constructor");
     59
     60    if (!args.IsConstructCall())
     61        return throwError("DOM object constructor cannot be called as a function.", V8Proxy::TypeError);
     62
     63    if (ConstructorMode::current() == ConstructorMode::WrapExistingObject)
     64        return args.Holder();
     65
     66    // Get the script execution context.
     67    ScriptExecutionContext* context = getScriptExecutionContext();
     68    if (!context)
     69        return throwError("Blob constructor associated document is unavailable", V8Proxy::ReferenceError);
     70
     71    if (!args.Length())
     72        RefPtr<Blob> blob = Blob::create();
     73        return toV8(blob.get(), args.GetIsolate());
     74    }
     75
     76    v8::Local<v8::Value> firstArg = args[0];
     77    if (!firstArg->IsArray())
     78        return throwError("First argument of the constructor is not of type Array", V8Proxy::TypeError);
     79
     80    EXCEPTION_BLOCK(v8::Local<v8::Array>, blobParts, v8::Local<v8::Array>::Cast(firstArg));
     81
     82    String type;
     83    String endings = "transparent";
     84
     85    if (args.Length() > 1 && args[1]->IsObject()) {
     86        Dictionary dictionary(args[1]);
     87
     88        v8::TryCatch tryCatchType;
     89        dictionary.get("type", type);
     90        if (tryCatchType.HasCaught())
     91            return throwError(tryCatchType.Exception());
     92
     93        v8::TryCatch tryCatchEndings;
     94        bool containsEndings = dictionary.get("endings", endings);
     95        if (tryCatchEndings.HasCaught())
     96            return throwError(tryCatchEndings.Exception());
     97
     98        if (containsEndings) {
     99            if (endings != "transparent" && endings != "native") {
     100                V8Proxy::setDOMException(INVALID_STATE_ERR);
     101                return v8::Undefined();
     102            }
     103        }
     104    }
     105
     106    ASSERT(endings == "transparent" || endings == "native");
     107
     108    RefPtr<WebKitBlobBuilder> blobBuilder = WebKitBlobBuilder::create();
     109    for (uint32_t i = 0; i < blobParts->Length(); ++i) {
     110        v8::Local<v8::Value> item = blobParts->Get(v8::Uint32::New(i));
     111        ASSERT(!item.IsEmpty());
     112#if ENABLE(BLOB)
     113        if (V8ArrayBuffer::HasInstance(item)) {
     114            ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(v8::Handle<v8::Object>::Cast(item));
     115            ASSERT(arrayBuffer);
     116            blobBuilder->append(arrayBuffer);
     117        } else
     118#endif
     119        if (V8Blob::HasInstance(item)) {
     120            Blob* blob = V8Blob::toNative(v8::Handle<v8::Object>::Cast(item));
     121            ASSERT(blob);
     122            blobBuilder->append(blob);
     123        } else {
     124            EXCEPTION_BLOCK(String, stringValue, toWebCoreString(item->ToString()));
     125            blobBuilder->append(stringValue, endings, ASSERT_NO_EXCEPTION);
     126        }
     127    }
     128
     129    RefPtr<Blob> blob = blobBuilder->getBlob(type);
     130    return toV8(blob.get(), args.GetIsolate());
     131}
     132
    52133} // namespace WebCore
  • trunk/Source/WebCore/fileapi/Blob.cpp

    r115491 r115582  
    3737
    3838namespace WebCore {
     39
     40Blob::Blob()
     41    : m_size(0)
     42{
     43    OwnPtr<BlobData> blobData = BlobData::create();
     44
     45    // Create a new internal URL and register it with the provided blob data.
     46    m_internalURL = BlobURL::createInternalURL();
     47    ThreadableBlobRegistry::registerBlobURL(m_internalURL, blobData.release());
     48}
    3949
    4050Blob::Blob(PassOwnPtr<BlobData> blobData, long long size)
  • trunk/Source/WebCore/fileapi/Blob.h

    r115491 r115582  
    4444class Blob : public RefCounted<Blob> {
    4545public:
     46    static PassRefPtr<Blob> create()
     47    {
     48        return adoptRef(new Blob);
     49    }
     50
    4651    static PassRefPtr<Blob> create(PassOwnPtr<BlobData> blobData, long long size)
    4752    {
     
    6873
    6974protected:
     75    Blob();
    7076    Blob(PassOwnPtr<BlobData>, long long size);
    7177
  • trunk/Source/WebCore/fileapi/Blob.idl

    r115491 r115582  
    3434        JSGenerateIsReachable=Impl,
    3535        CustomToJSObject,
    36         JSNoStaticTables
     36        JSNoStaticTables,
     37        CustomConstructor,
     38        ConstructorParameters=2
    3739    ] Blob {
    3840        readonly attribute unsigned long long size;
  • trunk/Source/WebCore/workers/WorkerContext.idl

    r115491 r115582  
    8585#if defined(ENABLE_BLOB) && ENABLE_BLOB
    8686        attribute WebKitBlobBuilderConstructor WebKitBlobBuilder;
     87        attribute BlobConstructor Blob;
    8788        attribute FileReaderConstructor FileReader;
    8889        attribute FileReaderSyncConstructor FileReaderSync;
Note: See TracChangeset for help on using the changeset viewer.