Blob.js
Blob.js copied to clipboard
YUI compression broken
The following two snippets are located in the same function:
if (view.Blob && view.URL) {
try {
new Blob;
return;
} catch (e) {}
}
view.Blob = function Blob(blobParts, options) {
var type = options ? (options.type || "") : "";
var builder = new BlobBuilder();
if (blobParts) {
for (var i = 0, len = blobParts.length; i < len; i++) {
builder.append(blobParts[i]);
}
}
return builder.getBlob(type);
};
When run through a minification tool (I am using the latest YUI), the first function (which checks for the presence of Blob in the browser) is compressed as:
if(a.Blob&&a.URL){try{new d;return}catch(c){}}
This is correct minification, as further down the file, a named function "Blob" is defined in the local scope (and is minified to the name "d")
Because "new Blob" is minified as "new d", an error will occur regardless of the browser's Blob support, thereby overwriting it with the shim instead of using the native implementation.
You can run an online version of the YUI compressor here: http://refresh-sf.com/yui/
To fix this issue, change:
view.Blob = function Blob(blobParts, options) {
to:
view.Blob = function (blobParts, options) {
I don't know if this will break anything else though. As far as I can tell it still works when you change this.
FYI: That is NOT correct minification. In fact, if there were any real issue on that, the non-minimized code would cause some problem as well. At run time "Blob" is checked from the global scope since the polyfill isn't yet created and therefore any minificator should take that into account.
My advice, switch to a more robust and well tested minification tool.
Please file a bug with the YUI compressor and link it here if you want to resolve the root issue. I will revert to the previous named function code once this issue is fixed upstream with YUI.
https://github.com/yui/yuicompressor/issues/155
I think there's no need to revert d71ed78, though.
Ok, thanks. I've subscribed to that issue.
Because YUICompressor is implemented by compiling all JavaScript provided down to an AST (using Mozilla Rhino), there's no way to prevent YUICompressor from minifying browser-implementation objects like Blob short of using a parser hint, as mentioned in yui/yuicompressor#155. Some other JS compression engines do not actually compile the JS themselves, so they may not have this problem.
Sounds like Rhino's AST representation is broken or YUI's handling of it, imo. The first Blob
it runs into would be a different variable and scope from the next Blob
.
It's no different than the AST of any other javascript engine; node or spidermonkey would do the same things in this case.
For this code as posted on https://github.com/yui/yuicompressor/issues/155
(function(view) {
alert(typeof Test);
view.test = function Test() {
console.log(Test);
};
})(this);
This is the relevant part of the AST representation:
"type" : "UnaryExpression",
"operator" : "typeof",
"argument" : {
...
"type" : "Identifier",
"name" : "Test"
},
...
"type" : "FunctionExpression",
"id" : {
"loc" : null,
"type" : "Identifier",
"name" : "Test"
},
So, i highly doubt that's a bug on Rhino, but rather on YUICompressor wrongly interpreting the data.
close?