Changeset 115484 in webkit


Ignore:
Timestamp:
Apr 27, 2012 1:23:53 PM (12 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:
  • fast/files/blob-constructor-expected.txt:
  • fast/files/script-tests/blob-constructor.js:

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/window-domurl-crash.html:
  • fast/files/blob-builder-crash-expected.txt: Removed.
  • fast/files/blob-builder-crash.html: Removed.
  • fast/files/blob-slice-overflow.html:
  • fast/files/blob-slice-test.html:
  • fast/files/file-reader-fffd.html:
  • 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
42 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r115481 r115484  
     12012-04-26  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:
     13        * fast/files/blob-constructor-expected.txt:
     14        * fast/files/script-tests/blob-constructor.js:
     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/window-domurl-crash.html:
     22        * fast/files/blob-builder-crash-expected.txt: Removed.
     23        * fast/files/blob-builder-crash.html: Removed.
     24        * fast/files/blob-slice-overflow.html:
     25        * fast/files/blob-slice-test.html:
     26        * fast/files/file-reader-fffd.html:
     27        * fast/files/not-enough-arguments.html:
     28        * fast/files/resources/read-blob-test-cases.js:
     29        * fast/files/resources/read-common.js:
     30        * fast/files/workers/inline-worker-via-blob-url.html:
     31        * fast/filesystem/resources/file-writer-abort-continue.js:
     32        * fast/filesystem/resources/file-writer-abort-depth.js:
     33        * fast/filesystem/resources/file-writer-abort.js:
     34        * fast/filesystem/resources/file-writer-events.js:
     35        * fast/filesystem/resources/file-writer-gc-blob.js:
     36        * fast/filesystem/resources/file-writer-sync-truncate-extend.js:
     37        * fast/filesystem/resources/file-writer-sync-write-overlapped.js:
     38        * fast/filesystem/resources/file-writer-utils.js:
     39        * http/tests/fileapi/create-blob-url-from-data-url.html:
     40        * http/tests/filesystem/no-cache-filesystem-url.html:
     41        * http/tests/local/blob/resources/hybrid-blob-util.js:
     42        * http/tests/security/resources/create-filesystem-file.html:
     43        * http/tests/websocket/tests/hixie76/send-object.html:
     44        * http/tests/websocket/tests/hybi/bufferedAmount-after-close-in-busy.html:
     45        * http/tests/websocket/tests/hybi/bufferedAmount-after-close.html:
     46        * http/tests/websocket/tests/hybi/send-blob.html:
     47        * http/tests/websocket/tests/hybi/send-file-blob-fail.html:
     48        * http/tests/websocket/tests/hybi/send-file-blob.html:
     49        * http/tests/websocket/tests/hybi/workers/resources/send-blob.js:
     50        * platform/mac/fast/dom/Window/window-properties-expected.txt:
     51        * storage/indexeddb/noblobs.html:
     52        * storage/indexeddb/structured-clone.html:
     53
    1542012-04-27  Dimitri Glazkov  <dglazkov@chromium.org>
    255
  • trunk/LayoutTests/fast/dom/HTMLAnchorElement/anchor-download-unset.html

    r91797 r115484  
    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

    r91797 r115484  
    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

    r91797 r115484  
    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

    r91797 r115484  
    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/window-domurl-crash.html

    r83884 r115484  
    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

    r83884 r115484  
    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

    r87181 r115484  
    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.html

    r98407 r115484  
    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.html

    r98407 r115484  
    1616shouldThrow('reader.readAsDataURL()');
    1717
    18 var blobBuilder = new WebKitBlobBuilder();
    19 
    20 shouldThrow('blobBuilder.append()');
     18shouldThrow('new Blob()');
    2119
    2220var fileInput = document.getElementsByTagName('input')[0];
  • trunk/LayoutTests/fast/files/resources/read-blob-test-cases.js

    r83884 r115484  
    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

    r107994 r115484  
    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

    r83884 r115484  
    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

    r106898 r115484  
    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

    r106898 r115484  
    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

    r106898 r115484  
    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

    r113924 r115484  
    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

    r110650 r115484  
    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

    r106898 r115484  
    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

    r106898 r115484  
    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

    r85556 r115484  
    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

    r83884 r115484  
    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

    r86192 r115484  
    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

    r83884 r115484  
    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

    r103505 r115484  
    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

    r107689 r115484  
    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

    r102327 r115484  
    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

    r99258 r115484  
    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

    r99258 r115484  
    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

    r99258 r115484  
    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

    r99258 r115484  
    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

    r94482 r115484  
    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

    r114154 r115484  
    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

    r111225 r115484  
    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

    r111211 r115484  
    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

    r115482 r115484  
     12012-04-26  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-27  Allan Sandfeld Jensen  <allan.jensen@nokia.com>
    231
  • trunk/Source/WebCore/bindings/js/JSBlobCustom.cpp

    r105506 r115484  
    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    JSArray* array = asArray(firstArg);
     78    unsigned length = array->length();
     79
     80    String type;
     81    String endings = "transparent";
     82
     83    if (exec->argumentCount() > 1) {
     84        JSValue blobPropertyBagValue = exec->argument(1);
     85
     86        // FIXME: Should we throw if the blobPropertyBag is not an object?
     87
     88        if (!blobPropertyBagValue.isUndefinedOrNull()) {
     89            // Given the above test, this will always yield an object.
     90            JSObject* blobPropertyBagObject = blobPropertyBagValue.toObject(exec);
     91
     92            // Create the dictionary wrapper from the initializer object.
     93            JSDictionary dictionary(exec, blobPropertyBagObject);
     94
     95            // Attempt to get the type property.
     96            dictionary.get("type", type);
     97            if (exec->hadException())
     98                return JSValue::encode(jsUndefined());
     99
     100            // Attempt to get the endings property and validate it.
     101            bool containsEndings = dictionary.get("endings", endings);
     102            if (exec->hadException())
     103                return JSValue::encode(jsUndefined());
     104
     105            if (containsEndings) {
     106                if (endings != "transparent" && endings != "native") {
     107                    setDOMException(exec, INVALID_STATE_ERR);
     108                    return JSValue::encode(jsUndefined());
     109                }
     110            }
     111        }
     112    }
     113
     114    ASSERT(endings == "transparent" || endings == "native");
     115
     116    // FIXME: this would be better if the WebKitBlobBuilder were a stack object to avoid the allocation.
     117    RefPtr<WebKitBlobBuilder> blobBuilder = WebKitBlobBuilder::create();
     118    for (unsigned i = 0; i < length; ++i) {
     119        JSValue item = array->getIndex(i);
     120#if ENABLE(BLOB)
     121        if (item.inherits(&JSArrayBuffer::s_info))
     122            blobBuilder->append(toArrayBuffer(item));
     123        else
     124#endif
     125        if (item.inherits(&JSBlob::s_info))
     126            blobBuilder->append(toBlob(item));
     127        else {
     128            String string = ustringToString(item.toString(exec)->value(exec));
     129            if (exec->hadException())
     130                return JSValue::encode(JSValue());
     131            blobBuilder->append(string, endings, ASSERT_NO_EXCEPTION);
     132        }
     133    }
     134
     135    RefPtr<Blob> blob = blobBuilder->getBlob(type);
     136    return JSValue::encode(CREATE_DOM_WRAPPER(exec, jsConstructor->globalObject(), Blob, blob.get()));
     137}
     138
    54139} // namespace WebCore
  • trunk/Source/WebCore/bindings/v8/custom/V8BlobCustom.cpp

    r115366 r115484  
    5050}
    5151
     52v8::Handle<v8::Value> V8Blob::constructorCallback(const v8::Arguments& args)
     53{
     54    INC_STATS("DOM.Blob.Constructor");
     55
     56    if (!args.IsConstructCall())
     57        return throwError("DOM object constructor cannot be called as a function.", V8Proxy::TypeError);
     58
     59    if (ConstructorMode::current() == ConstructorMode::WrapExistingObject)
     60        return args.Holder();
     61
     62    // Get the script execution context.
     63    ScriptExecutionContext* context = getScriptExecutionContext();
     64    if (!context)
     65        return throwError("Blob constructor's associated frame is not available", V8Proxy::ReferenceError);
     66
     67    if (!args.Length())
     68        RefPtr<Blob> blob = Blob::create();
     69        return toV8(blob.get());
     70    }
     71
     72    v8::Local<v8::Value> firstArg = args[0];
     73    if (!firstArg->IsArray())
     74        return throwError("First argument of the constructor is not of type Array", V8Proxy::TypeError);
     75
     76    EXCEPTION_BLOCK(v8::Local<v8::Array>, blobParts, v8::Local<v8::Array>::Cast(firstArg));
     77
     78    String type;
     79    String endings = "transparent";
     80
     81    if (args.Length() > 1 && args[1]->IsObject()) {
     82        Dictionary dictionary(args[1]);
     83        dictionary.get("type", type);
     84        if (dictionary.get("endings", endings)) {
     85            if (endings != "transparent" && endings != "native") {
     86                V8Proxy::setDOMException(INVALID_STATE_ERR);
     87                return v8::Undefined();
     88            }
     89        }
     90    }
     91
     92    ASSERT(endings == "transparent" || endings == "native");
     93
     94    RefPtr<WebKitBlobBuilder> blobBuilder = WebKitBlobBuilder::create();
     95    for (uint32_t i = 0; i < blobParts->Length(); ++i) {
     96        v8::Local<v8::Value> item = blobParts->Get(v8::Uint32::New(i));
     97        ASSERT(!item.IsEmpty());
     98#if ENABLE(BLOB)
     99        if (V8ArrayBuffer::HasInstance(item)) {
     100            ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(v8::Handle<v8::Object>::Cast(item));
     101            ASSERT(arrayBuffer);
     102            blobBuilder->append(arrayBuffer);
     103        } else
     104#endif
     105        if (V8Blob::HasInstance(item)) {
     106            Blob* blob = V8Blob::toNative(v8::Handle<v8::Object>::Cast(item));
     107            ASSERT(blob);
     108            blobBuilder->append(blob);
     109        } else {
     110            EXCEPTION_BLOCK(String, stringValue, toWebCoreString(item->ToString()));
     111            blobBuilder->append(stringValue, endings, ASSERT_NO_EXCEPTION);
     112        }
     113    }
     114
     115    RefPtr<Blob> blob = blobBuilder->getBlob(type);
     116    return toV8(blob.get());
     117}
     118
    52119} // namespace WebCore
  • trunk/Source/WebCore/fileapi/Blob.cpp

    r95901 r115484  
    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

    r95901 r115484  
    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

    r107636 r115484  
    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

    r111969 r115484  
    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.