Merge m-c to inbound

This commit is contained in:
Carsten "Tomcat" Book 2013-07-23 11:06:20 +02:00
commit a48932bfb9
38 changed files with 38 additions and 397 deletions

View File

@ -100,16 +100,10 @@ public:
: JS::UndefinedValue(); : JS::UndefinedValue();
aRv = ToDataURL(aType, params, aCx, aDataURL); aRv = ToDataURL(aType, params, aCx, aDataURL);
} }
void ToBlob(JSContext* aCx, void ToBlob(nsIFileCallback* aCallback, const nsAString& aType,
nsIFileCallback* aCallback,
const nsAString& aType,
const Optional<JS::Handle<JS::Value> >& aParams,
ErrorResult& aRv) ErrorResult& aRv)
{ {
JS::Value params = aParams.WasPassed() aRv = ToBlob(aCallback, aType);
? aParams.Value()
: JS::UndefinedValue();
aRv = ToBlob(aCallback, aType, params, aCx);
} }
bool MozOpaque() const bool MozOpaque() const
@ -233,11 +227,6 @@ protected:
nsIntSize GetWidthHeight(); nsIntSize GetWidthHeight();
nsresult UpdateContext(JSContext* aCx, JS::Handle<JS::Value> options); nsresult UpdateContext(JSContext* aCx, JS::Handle<JS::Value> options);
nsresult ParseParams(JSContext* aCx,
const nsAString& aType,
const JS::Value& aEncoderOptions,
nsAString& aParams,
bool* usingCustomParseOptions);
nsresult ExtractData(const nsAString& aType, nsresult ExtractData(const nsAString& aType,
const nsAString& aOptions, const nsAString& aOptions,
nsIInputStream** aStream, nsIInputStream** aStream,

View File

@ -1,6 +1,5 @@
# autofocus attribute (we can't test with mochitests) # autofocus attribute (we can't test with mochitests)
include autofocus/reftest.list include autofocus/reftest.list
include toblob-todataurl/reftest.list
skip-if(B2G) == 41464-1a.html 41464-1-ref.html skip-if(B2G) == 41464-1a.html 41464-1-ref.html
skip-if(B2G) == 41464-1b.html 41464-1-ref.html skip-if(B2G) == 41464-1b.html 41464-1-ref.html

View File

@ -1,68 +0,0 @@
function init() {
function end() {
document.documentElement.className = '';
}
function next() {
compressAndDisplay(original, end);
}
var original = getImageFromDataUrl(sample);
setImgLoadListener(original, next);
}
function compressAndDisplay(image, next) {
var canvas = document.createElement('canvas');
canvas.width = image.naturalWidth;
canvas.height = image.naturalHeight;
var ctx = canvas.getContext('2d');
ctx.drawImage(image, 0, 0);
function gotBlob(blob) {
var img = getImageFromBlob(blob);
setImgLoadListener(img, next);
document.body.appendChild(img);
}
// I want to test passing 'undefined' as quality as well
if ('quality' in window) {
canvas.toBlob(gotBlob, 'image/jpeg', quality);
} else {
canvas.toBlob(gotBlob, 'image/jpeg');
}
}
function setImgLoadListener(img, func) {
if (img.complete) {
func.call(img, { target: img});
} else {
img.addEventListener('load', func);
}
}
function naturalDimensionsHandler(e) {
var img = e.target;
img.width = img.naturalWidth;
img.height = img.naturalHeight;
}
function getImageFromBlob(blob) {
var img = document.createElement('img');
img.src = window.URL.createObjectURL(blob);
setImgLoadListener(img, naturalDimensionsHandler);
setImgLoadListener(img, function(e) {
window.URL.revokeObjectURL(e.target.src);
});
return img;
}
function getImageFromDataUrl(url) {
var img = document.createElement('img');
img.src = url;
setImgLoadListener(img, naturalDimensionsHandler);
return img;
}
init();

View File

@ -1,56 +0,0 @@
function init() {
function end() {
document.documentElement.className = '';
}
function next() {
compressAndDisplay(original, end);
}
var original = getImageFromDataUrl(sample);
setImgLoadListener(original, next);
}
function compressAndDisplay(image, next) {
var canvas = document.createElement('canvas');
canvas.width = image.naturalWidth;
canvas.height = image.naturalHeight;
var ctx = canvas.getContext('2d');
ctx.drawImage(image, 0, 0);
var dataUrl;
// I want to test passing undefined as well
if ('quality' in window) {
dataUrl = canvas.toDataURL('image/jpeg', quality);
} else {
dataUrl = canvas.toDataURL('image/jpeg');
}
var img = getImageFromDataUrl(dataUrl);
setImgLoadListener(img, next);
document.body.appendChild(img);
}
function setImgLoadListener(img, func) {
if (img.complete) {
func.call(img, { target: img});
} else {
img.addEventListener('load', func);
}
}
function naturalDimensionsHandler(e) {
var img = e.target;
img.width = img.naturalWidth;
img.height = img.naturalHeight;
}
function getImageFromDataUrl(url) {
var img = document.createElement('img');
img.src = url;
setImgLoadListener(img, naturalDimensionsHandler);
return img;
}
init();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@ -1,2 +0,0 @@
<!doctype html>
<html><body><img src='images/q0.jpg'/></table></body></html>

View File

@ -1,2 +0,0 @@
<!doctype html>
<html><body><img src='images/q100.jpg'/></table></body></html>

View File

@ -1,2 +0,0 @@
<!doctype html>
<html><body><img src='images/q25.jpg'/></table></body></html>

View File

@ -1,2 +0,0 @@
<!doctype html>
<html><body><img src='images/q50.jpg'/></table></body></html>

View File

@ -1,2 +0,0 @@
<!doctype html>
<html><body><img src='images/q75.jpg'/></table></body></html>

View File

@ -1,2 +0,0 @@
<!doctype html>
<html><body><img src='images/q92.jpg'/></table></body></html>

View File

@ -1,16 +0,0 @@
== toblob-quality-0.html quality-0-ref.html
== toblob-quality-25.html quality-25-ref.html
== toblob-quality-50.html quality-50-ref.html
== toblob-quality-75.html quality-75-ref.html
== toblob-quality-92.html quality-92-ref.html
== toblob-quality-100.html quality-100-ref.html
== toblob-quality-undefined.html quality-92-ref.html
== toblob-quality-default.html quality-92-ref.html
== todataurl-quality-0.html quality-0-ref.html
== todataurl-quality-25.html quality-25-ref.html
== todataurl-quality-50.html quality-50-ref.html
== todataurl-quality-75.html quality-75-ref.html
== todataurl-quality-92.html quality-92-ref.html
== todataurl-quality-100.html quality-100-ref.html
== todataurl-quality-undefined.html quality-92-ref.html
== todataurl-quality-default.html quality-92-ref.html

File diff suppressed because one or more lines are too long

View File

@ -1,10 +0,0 @@
<!doctype html>
<html class='reftest-wait'>
<body>
<script>
var quality = 0;
</script>
<script src='sample.js'></script>
<script src='blob.js'></script>
</body>
</html>

View File

@ -1,10 +0,0 @@
<!doctype html>
<html class='reftest-wait'>
<body>
<script>
var quality = 1;
</script>
<script src='sample.js'></script>
<script src='blob.js'></script>
</body>
</html>

View File

@ -1,10 +0,0 @@
<!doctype html>
<html class='reftest-wait'>
<body>
<script>
var quality = 0.25;
</script>
<script src='sample.js'></script>
<script src='blob.js'></script>
</body>
</html>

View File

@ -1,10 +0,0 @@
<!doctype html>
<html class='reftest-wait'>
<body>
<script>
var quality = 0.50;
</script>
<script src='sample.js'></script>
<script src='blob.js'></script>
</body>
</html>

View File

@ -1,10 +0,0 @@
<!doctype html>
<html class='reftest-wait'>
<body>
<script>
var quality = 0.75;
</script>
<script src='sample.js'></script>
<script src='blob.js'></script>
</body>
</html>

View File

@ -1,10 +0,0 @@
<!doctype html>
<html class='reftest-wait'>
<body>
<script>
var quality = 0.92;
</script>
<script src='sample.js'></script>
<script src='blob.js'></script>
</body>
</html>

View File

@ -1,7 +0,0 @@
<!doctype html>
<html class='reftest-wait'>
<body>
<script src='sample.js'></script>
<script src='blob.js'></script>
</body>
</html>

View File

@ -1,10 +0,0 @@
<!doctype html>
<html class='reftest-wait'>
<body>
<script>
var quality = undefined;
</script>
<script src='sample.js'></script>
<script src='blob.js'></script>
</body>
</html>

View File

@ -1,10 +0,0 @@
<!doctype html>
<html class='reftest-wait'>
<body>
<script>
var quality = 0;
</script>
<script src='sample.js'></script>
<script src='dataurl.js'></script>
</body>
</html>

View File

@ -1,10 +0,0 @@
<!doctype html>
<html class='reftest-wait'>
<body>
<script>
var quality = 1;
</script>
<script src='sample.js'></script>
<script src='dataurl.js'></script>
</body>
</html>

View File

@ -1,10 +0,0 @@
<!doctype html>
<html class='reftest-wait'>
<body>
<script>
var quality = 0.25;
</script>
<script src='sample.js'></script>
<script src='dataurl.js'></script>
</body>
</html>

View File

@ -1,10 +0,0 @@
<!doctype html>
<html class='reftest-wait'>
<body>
<script>
var quality = 0.50;
</script>
<script src='sample.js'></script>
<script src='dataurl.js'></script>
</body>
</html>

View File

@ -1,10 +0,0 @@
<!doctype html>
<html class='reftest-wait'>
<body>
<script>
var quality = 0.75;
</script>
<script src='sample.js'></script>
<script src='dataurl.js'></script>
</body>
</html>

View File

@ -1,10 +0,0 @@
<!doctype html>
<html class='reftest-wait'>
<body>
<script>
var quality = 0.92;
</script>
<script src='sample.js'></script>
<script src='dataurl.js'></script>
</body>
</html>

View File

@ -1,7 +0,0 @@
<!doctype html>
<html class='reftest-wait'>
<body>
<script src='sample.js'></script>
<script src='dataurl.js'></script>
</body>
</html>

View File

@ -1,10 +0,0 @@
<!doctype html>
<html class='reftest-wait'>
<body>
<script>
var quality = undefined;
</script>
<script src='sample.js'></script>
<script src='dataurl.js'></script>
</body>
</html>

View File

@ -475,48 +475,6 @@ HTMLCanvasElement::ExtractData(const nsAString& aType,
return NS_OK; return NS_OK;
} }
nsresult
HTMLCanvasElement::ParseParams(JSContext* aCx,
const nsAString& aType,
const JS::Value& aEncoderOptions,
nsAString& aParams,
bool* usingCustomParseOptions)
{
// Quality parameter is only valid for the image/jpeg MIME type
if (aType.EqualsLiteral("image/jpeg")) {
if (aEncoderOptions.isNumber()) {
double quality = aEncoderOptions.toNumber();
// Quality must be between 0.0 and 1.0, inclusive
if (quality >= 0.0 && quality <= 1.0) {
aParams.AppendLiteral("quality=");
aParams.AppendInt(NS_lround(quality * 100.0));
}
}
}
// If we haven't parsed the aParams check for proprietary options.
// The proprietary option -moz-parse-options will take a image lib encoder
// parse options string as is and pass it to the encoder.
*usingCustomParseOptions = false;
if (aParams.Length() == 0 && aEncoderOptions.isString()) {
NS_NAMED_LITERAL_STRING(mozParseOptions, "-moz-parse-options:");
nsDependentJSString paramString;
if (!paramString.init(aCx, aEncoderOptions.toString())) {
return NS_ERROR_FAILURE;
}
if (StringBeginsWith(paramString, mozParseOptions)) {
nsDependentSubstring parseOptions = Substring(paramString,
mozParseOptions.Length(),
paramString.Length() -
mozParseOptions.Length());
aParams.Append(parseOptions);
*usingCustomParseOptions = true;
}
}
return NS_OK;
}
nsresult nsresult
HTMLCanvasElement::ToDataURLImpl(JSContext* aCx, HTMLCanvasElement::ToDataURLImpl(JSContext* aCx,
const nsAString& aMimeType, const nsAString& aMimeType,
@ -538,10 +496,37 @@ HTMLCanvasElement::ToDataURLImpl(JSContext* aCx,
} }
nsAutoString params; nsAutoString params;
bool usingCustomParseOptions;
rv = ParseParams(aCx, type, aEncoderOptions, params, &usingCustomParseOptions); // Quality parameter is only valid for the image/jpeg MIME type
if (NS_FAILED(rv)) { if (type.EqualsLiteral("image/jpeg")) {
return rv; if (aEncoderOptions.isNumber()) {
double quality = aEncoderOptions.toNumber();
// Quality must be between 0.0 and 1.0, inclusive
if (quality >= 0.0 && quality <= 1.0) {
params.AppendLiteral("quality=");
params.AppendInt(NS_lround(quality * 100.0));
}
}
}
// If we haven't parsed the params check for proprietary options.
// The proprietary option -moz-parse-options will take a image lib encoder
// parse options string as is and pass it to the encoder.
bool usingCustomParseOptions = false;
if (params.Length() == 0 && aEncoderOptions.isString()) {
NS_NAMED_LITERAL_STRING(mozParseOptions, "-moz-parse-options:");
nsDependentJSString paramString;
if (!paramString.init(aCx, aEncoderOptions.toString())) {
return NS_ERROR_FAILURE;
}
if (StringBeginsWith(paramString, mozParseOptions)) {
nsDependentSubstring parseOptions = Substring(paramString,
mozParseOptions.Length(),
paramString.Length() -
mozParseOptions.Length());
params.Append(parseOptions);
usingCustomParseOptions = true;
}
} }
nsCOMPtr<nsIInputStream> stream; nsCOMPtr<nsIInputStream> stream;
@ -574,9 +559,7 @@ HTMLCanvasElement::ToDataURLImpl(JSContext* aCx,
// XXXkhuey the encoding should be off the main thread, but we're lazy. // XXXkhuey the encoding should be off the main thread, but we're lazy.
NS_IMETHODIMP NS_IMETHODIMP
HTMLCanvasElement::ToBlob(nsIFileCallback* aCallback, HTMLCanvasElement::ToBlob(nsIFileCallback* aCallback,
const nsAString& aType, const nsAString& aType)
const JS::Value& aEncoderOptions,
JSContext* aCx)
{ {
// do a trust check if this is a write-only canvas // do a trust check if this is a write-only canvas
if (mWriteOnly && !nsContentUtils::IsCallerChrome()) { if (mWriteOnly && !nsContentUtils::IsCallerChrome()) {
@ -593,24 +576,10 @@ HTMLCanvasElement::ToBlob(nsIFileCallback* aCallback,
return rv; return rv;
} }
nsAutoString params;
bool usingCustomParseOptions;
rv = ParseParams(aCx, type, aEncoderOptions, params, &usingCustomParseOptions);
if (NS_FAILED(rv)) {
return rv;
}
bool fallbackToPNG = false; bool fallbackToPNG = false;
nsCOMPtr<nsIInputStream> stream; nsCOMPtr<nsIInputStream> stream;
rv = ExtractData(type, params, getter_AddRefs(stream), fallbackToPNG); rv = ExtractData(type, EmptyString(), getter_AddRefs(stream), fallbackToPNG);
// If there are unrecognized custom parse options, we should fall back to
// the default values for the encoder without any options at all.
if (rv == NS_ERROR_INVALID_ARG && usingCustomParseOptions) {
fallbackToPNG = false;
rv = ExtractData(type, EmptyString(), getter_AddRefs(stream), fallbackToPNG);
}
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (fallbackToPNG) { if (fallbackToPNG) {

View File

@ -46,7 +46,7 @@ interface nsIFileCallback : nsISupports {
void receive(in nsIDOMBlob file); void receive(in nsIDOMBlob file);
}; };
[scriptable, uuid(788f69a4-30e0-42b4-804d-b99549f9d463)] [scriptable, uuid(350fddae-4476-4dcd-bccf-9c9c356354a6)]
interface nsIDOMHTMLCanvasElement : nsIDOMHTMLElement interface nsIDOMHTMLCanvasElement : nsIDOMHTMLElement
{ {
attribute unsigned long width; attribute unsigned long width;
@ -66,14 +66,8 @@ interface nsIDOMHTMLCanvasElement : nsIDOMHTMLElement
// mozGetAsFile(name, type); -- uses given type // mozGetAsFile(name, type); -- uses given type
nsIDOMFile mozGetAsFile(in DOMString name, [optional] in DOMString type); nsIDOMFile mozGetAsFile(in DOMString name, [optional] in DOMString type);
// Valid calls are:
// toBlob(); -- defaults to image/png
// toBlob(type); -- uses given type
// toBlob(type, params); -- uses given type, and any valid parameters
[implicit_jscontext]
void toBlob(in nsIFileCallback callback, void toBlob(in nsIFileCallback callback,
[optional] in DOMString type, [optional] in DOMString type);
[optional] in jsval params);
// A Mozilla-only extension to get a canvas context backed by double-buffered // A Mozilla-only extension to get a canvas context backed by double-buffered
// shared memory. Only privileged callers can call this. // shared memory. Only privileged callers can call this.

View File

@ -30,9 +30,7 @@ interface HTMLCanvasElement : HTMLElement {
DOMString toDataURL(optional DOMString type = "", DOMString toDataURL(optional DOMString type = "",
optional any encoderOptions); optional any encoderOptions);
[Throws] [Throws]
void toBlob(FileCallback _callback, void toBlob(FileCallback _callback, optional DOMString type = "");
optional DOMString type = "",
optional any encoderOptions);
}; };
// Mozilla specific bits // Mozilla specific bits