diff options
31 files changed, 49 insertions, 131 deletions
diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml index 78ed8b1f24f..5c62fb3ee28 100644 --- a/components/script/Cargo.toml +++ b/components/script/Cargo.toml @@ -92,3 +92,4 @@ tendril = "0.1.1" rand = "0.3" serde = "0.6" caseless = "0.1.0" +image = "0.4.0" diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs index 2fdb8a129e6..47126ed3dd0 100644 --- a/components/script/dom/htmlcanvaselement.rs +++ b/components/script/dom/htmlcanvaselement.rs @@ -5,13 +5,16 @@ use canvas_traits::{CanvasMsg, FromLayoutMsg}; use dom::attr::Attr; use dom::bindings::cell::DOMRefCell; +use dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::CanvasRenderingContext2DMethods; use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding; use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding::HTMLCanvasElementMethods; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLContextAttributes; use dom::bindings::codegen::UnionTypes::CanvasRenderingContext2DOrWebGLRenderingContext; use dom::bindings::conversions::Castable; +use dom::bindings::error::{Error, Fallible}; use dom::bindings::global::GlobalRef; use dom::bindings::js::{HeapGCValue, JS, LayoutJS, Root}; +use dom::bindings::num::Finite; use dom::bindings::utils::{Reflectable}; use dom::canvasrenderingcontext2d::{CanvasRenderingContext2D, LayoutCanvasRenderingContext2DHelpers}; use dom::document::Document; @@ -21,9 +24,12 @@ use dom::node::{Node, window_from_node}; use dom::virtualmethods::VirtualMethods; use dom::webglrenderingcontext::{LayoutCanvasWebGLRenderingContextHelpers, WebGLRenderingContext}; use euclid::size::Size2D; +use image::ColorType; +use image::png::PNGEncoder; use ipc_channel::ipc::{self, IpcSender}; use js::jsapi::{HandleValue, JSContext}; use offscreen_gl_context::GLContextAttributes; +use rustc_serialize::base64::{STANDARD, ToBase64}; use std::cell::Cell; use std::iter::repeat; use util::str::{DOMString, parse_unsigned_integer}; @@ -246,6 +252,44 @@ impl HTMLCanvasElementMethods for HTMLCanvasElement { _ => None } } + + // https://html.spec.whatwg.org/multipage/#dom-canvas-todataurl + fn ToDataURL(&self, + _context: *mut JSContext, + _mime_type: Option<DOMString>, + _arguments: Vec<HandleValue>) -> Fallible<DOMString> { + + // Step 1: Check the origin-clean flag (should be set in fillText/strokeText + // and currently unimplemented) + + // Step 2. + if self.Width() == 0 || self.Height() == 0 { + return Ok("data:,".to_owned()); + } + + // Step 3. + if let Some(CanvasContext::Context2d(ref context)) = *self.context.borrow() { + let window = window_from_node(self); + let image_data = try!(context.GetImageData(Finite::wrap(0f64), Finite::wrap(0f64), + Finite::wrap(self.Width() as f64), + Finite::wrap(self.Height() as f64))); + let raw_data = image_data.get_data_array(&GlobalRef::Window(window.r())); + + // Only handle image/png for now. + let mime_type = "image/png"; + + let mut encoded = Vec::new(); + { + let encoder: PNGEncoder<&mut Vec<u8>> = PNGEncoder::new(&mut encoded); + encoder.encode(&raw_data, self.Width(), self.Height(), ColorType::RGBA(8)).unwrap(); + } + + let encoded = encoded.to_base64(STANDARD); + Ok(format!("data:{};base64,{}", mime_type, encoded)) + } else { + Err(Error::NotSupported) + } + } } impl VirtualMethods for HTMLCanvasElement { diff --git a/components/script/dom/webidls/HTMLCanvasElement.webidl b/components/script/dom/webidls/HTMLCanvasElement.webidl index fcd162dca0b..d427f32ade1 100644 --- a/components/script/dom/webidls/HTMLCanvasElement.webidl +++ b/components/script/dom/webidls/HTMLCanvasElement.webidl @@ -18,6 +18,7 @@ interface HTMLCanvasElement : HTMLElement { //void setContext(RenderingContext context); //CanvasProxy transferControlToProxy(); - //DOMString toDataURL(optional DOMString type, any... arguments); + [Throws] + DOMString toDataURL(optional DOMString type, any... arguments); //void toBlob(FileCallback? _callback, optional DOMString type, any... arguments); }; diff --git a/components/script/lib.rs b/components/script/lib.rs index eb5849221da..b442a3b2d31 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -58,6 +58,7 @@ extern crate euclid; extern crate fnv; extern crate html5ever; extern crate hyper; +extern crate image; extern crate ipc_channel; extern crate js; extern crate libc; diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index f112af3d8bd..bfeee4a49ac 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -1516,6 +1516,7 @@ dependencies = [ "fnv 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "html5ever 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", + "image 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)", "js 0.1.0 (git+https://github.com/servo/rust-mozjs)", "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/tests/wpt/metadata/2dcontext/transformations/2d.transformation.scale.zero.html.ini b/tests/wpt/metadata/2dcontext/transformations/2d.transformation.scale.zero.html.ini deleted file mode 100644 index b75f87a88eb..00000000000 --- a/tests/wpt/metadata/2dcontext/transformations/2d.transformation.scale.zero.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[2d.transformation.scale.zero.html] - type: testharness - [scale() with a scale factor of zero works] - expected: FAIL - diff --git a/tests/wpt/metadata/XMLHttpRequest/send-entity-body-document.htm.ini b/tests/wpt/metadata/XMLHttpRequest/send-entity-body-document.htm.ini index 0c3aab22ac1..3d2bb0da7ba 100644 --- a/tests/wpt/metadata/XMLHttpRequest/send-entity-body-document.htm.ini +++ b/tests/wpt/metadata/XMLHttpRequest/send-entity-body-document.htm.ini @@ -2,7 +2,6 @@ type: testharness disabled: if os == "mac": https://github.com/servo/servo/issues/8157 - [XMLHttpRequest: send() - Document] expected: FAIL diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini index a72593fcf48..a449fbbb70f 100644 --- a/tests/wpt/metadata/html/dom/interfaces.html.ini +++ b/tests/wpt/metadata/html/dom/interfaces.html.ini @@ -6042,9 +6042,6 @@ [HTMLCanvasElement interface: operation transferControlToProxy()] expected: FAIL - [HTMLCanvasElement interface: operation toDataURL(DOMString,any)] - expected: FAIL - [HTMLCanvasElement interface: operation toBlob(FileCallback,DOMString,any)] expected: FAIL @@ -6063,12 +6060,6 @@ [HTMLCanvasElement interface: document.createElement("canvas") must inherit property "transferControlToProxy" with the proper type (5)] expected: FAIL - [HTMLCanvasElement interface: document.createElement("canvas") must inherit property "toDataURL" with the proper type (6)] - expected: FAIL - - [HTMLCanvasElement interface: calling toDataURL(DOMString,any) on document.createElement("canvas") with too few arguments must throw TypeError] - expected: FAIL - [HTMLCanvasElement interface: document.createElement("canvas") must inherit property "toBlob" with the proper type (7)] expected: FAIL diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/security.dataURI.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/security.dataURI.html.ini deleted file mode 100644 index be88270e814..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/security.dataURI.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[security.dataURI.html] - type: testharness - [data: URIs do not count as different-origin, and do not taint the canvas] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/security.pattern.canvas.timing.sub.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/security.pattern.canvas.timing.sub.html.ini deleted file mode 100644 index db050579665..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/security.pattern.canvas.timing.sub.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[security.pattern.canvas.timing.sub.html] - type: testharness - [Pattern safety depends on whether the source was origin-clean, not on whether it still is clean] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/security.pattern.create.sub.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/security.pattern.create.sub.html.ini deleted file mode 100644 index e371b886951..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/security.pattern.create.sub.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[security.pattern.create.sub.html] - type: testharness - [Creating an unclean pattern does not make the canvas origin-unclean] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.arguments.1.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.arguments.1.html.ini deleted file mode 100644 index aa9c627d421..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.arguments.1.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[toDataURL.arguments.1.html] - type: testharness - [toDataURL ignores extra arguments] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.arguments.2.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.arguments.2.html.ini deleted file mode 100644 index 6a92dda450d..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.arguments.2.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[toDataURL.arguments.2.html] - type: testharness - [toDataURL ignores extra arguments] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.arguments.3.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.arguments.3.html.ini deleted file mode 100644 index 82a3218da79..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.arguments.3.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[toDataURL.arguments.3.html] - type: testharness - [toDataURL ignores extra arguments] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.bogustype.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.bogustype.html.ini deleted file mode 100644 index 0442fc214d9..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.bogustype.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[toDataURL.bogustype.html] - type: testharness - [toDataURL with a syntactically invalid type returns a PNG] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.default.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.default.html.ini deleted file mode 100644 index ec5839e1193..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.default.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[toDataURL.default.html] - type: testharness - [toDataURL with no arguments returns a PNG] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.alpha.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.alpha.html.ini deleted file mode 100644 index 4c3370a04b4..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.alpha.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[toDataURL.jpeg.alpha.html] - type: testharness - [toDataURL with JPEG composites onto black] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.primarycolours.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.primarycolours.html.ini deleted file mode 100644 index 17fc0b3f28b..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.primarycolours.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[toDataURL.jpeg.primarycolours.html] - type: testharness - [toDataURL with JPEG handles simple colours correctly] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.quality.basic.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.quality.basic.html.ini deleted file mode 100644 index a0be98e3c91..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.quality.basic.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[toDataURL.jpeg.quality.basic.html] - type: testharness - [toDataURL with JPEG uses the quality parameter] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.quality.notnumber.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.quality.notnumber.html.ini deleted file mode 100644 index c96ae1779c3..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.quality.notnumber.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[toDataURL.jpeg.quality.notnumber.html] - type: testharness - [toDataURL with JPEG handles non-numeric quality parameters] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.quality.outsiderange.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.quality.outsiderange.html.ini deleted file mode 100644 index 6fd4cd1198c..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.quality.outsiderange.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[toDataURL.jpeg.quality.outsiderange.html] - type: testharness - [toDataURL with JPEG handles out-of-range quality parameters] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.jpg.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.jpg.html.ini deleted file mode 100644 index 511427f54a7..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.jpg.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[toDataURL.jpg.html] - type: testharness - [toDataURL with image/jpg is invalid type hence returns a PNG] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.lowercase.ascii.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.lowercase.ascii.html.ini deleted file mode 100644 index 55aa126d8b2..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.lowercase.ascii.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[toDataURL.lowercase.ascii.html] - type: testharness - [toDataURL type is case-insensitive] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.lowercase.unicode.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.lowercase.unicode.html.ini deleted file mode 100644 index 84c847dd655..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.lowercase.unicode.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[toDataURL.lowercase.unicode.html] - type: testharness - [toDataURL type is ASCII-case-insensitive] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.png.complexcolours.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.png.complexcolours.html.ini deleted file mode 100644 index 0db84d3a6b4..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.png.complexcolours.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[toDataURL.png.complexcolours.html] - type: testharness - [toDataURL with PNG handles non-primary and non-solid colours correctly] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.png.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.png.html.ini deleted file mode 100644 index 2b76a49d948..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.png.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[toDataURL.png.html] - type: testharness - [toDataURL with image/png returns a PNG] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.png.primarycolours.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.png.primarycolours.html.ini deleted file mode 100644 index 9be12d66b36..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.png.primarycolours.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[toDataURL.png.primarycolours.html] - type: testharness - [toDataURL with PNG handles simple colours correctly] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.unrecognised.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.unrecognised.html.ini deleted file mode 100644 index 1335a8d9286..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.unrecognised.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[toDataURL.unrecognised.html] - type: testharness - [toDataURL with an unhandled type returns a PNG] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.zeroheight.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.zeroheight.html.ini deleted file mode 100644 index a1ec50721b7..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.zeroheight.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[toDataURL.zeroheight.html] - type: testharness - [toDataURL on zero-size canvas returns 'data:,'] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.zerosize.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.zerosize.html.ini deleted file mode 100644 index b52bb795bac..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.zerosize.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[toDataURL.zerosize.html] - type: testharness - [toDataURL on zero-size canvas returns 'data:,'] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.zerowidth.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.zerowidth.html.ini deleted file mode 100644 index fec6bdcf2c5..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.zerowidth.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[toDataURL.zerowidth.html] - type: testharness - [toDataURL on zero-size canvas returns 'data:,'] - expected: FAIL - |