diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /testing/web-platform/tests/2dcontext/tools/tests.yaml | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'testing/web-platform/tests/2dcontext/tools/tests.yaml')
-rw-r--r-- | testing/web-platform/tests/2dcontext/tools/tests.yaml | 1068 |
1 files changed, 1068 insertions, 0 deletions
diff --git a/testing/web-platform/tests/2dcontext/tools/tests.yaml b/testing/web-platform/tests/2dcontext/tools/tests.yaml new file mode 100644 index 000000000..083dfd1bd --- /dev/null +++ b/testing/web-platform/tests/2dcontext/tools/tests.yaml @@ -0,0 +1,1068 @@ +# Copyright (c) 2010 Philip Taylor +# Released under the BSD license and W3C Test Suite License: see LICENSE.txt + +- name: fallback.basic + desc: Fallback content is inserted into the DOM + testing: + - fallback + code: | + @assert canvas.childNodes.length === 1; + +- name: fallback.multiple + desc: Fallback content with multiple elements + testing: + - fallback + fallback: '<p class="fallback">FAIL</p><p class="fallback">FAIL</p>' + code: | + @assert canvas.childNodes.length === 2; + +- name: fallback.nested + desc: Fallback content containing another canvas (mostly testing parsers) + testing: + - fallback + fallback: '<canvas><p class="fallback">FAIL (fallback content)</p></canvas><p class="fallback">FAIL (fallback content)</p>' + code: | + @assert canvas.childNodes.length === 2; + +- name: type.name + desc: HTMLCanvasElement type and toString + testing: + - canvas.type + code: | + @assert Object.prototype.toString.call(canvas) === '[object HTMLCanvasElement]'; + +- name: type.exists + desc: HTMLCanvasElement is a property of window + notes: &bindings Defined in "Web IDL" (draft) + testing: + - canvas.type + code: | + @assert window.HTMLCanvasElement; + +- name: type.delete + desc: window.HTMLCanvasElement interface object is [[Configurable]] + notes: *bindings + testing: + - canvas.type + code: | + @assert delete window.HTMLCanvasElement === true; + @assert window.HTMLCanvasElement === undefined; + +- name: type.prototype + desc: window.HTMLCanvasElement has prototype, which is { ReadOnly, DontDelete }. prototype has getContext, which is not + notes: *bindings + testing: + - canvas.type + code: | + @assert window.HTMLCanvasElement.prototype; + @assert window.HTMLCanvasElement.prototype.getContext; + window.HTMLCanvasElement.prototype = null; + @assert window.HTMLCanvasElement.prototype; + delete window.HTMLCanvasElement.prototype; + @assert window.HTMLCanvasElement.prototype; + window.HTMLCanvasElement.prototype.getContext = 1; + @assert window.HTMLCanvasElement.prototype.getContext === 1; + delete window.HTMLCanvasElement.prototype.getContext; + @assert window.HTMLCanvasElement.prototype.getContext === undefined; + +- name: type.replace + desc: HTMLCanvasElement methods can be replaced, and the replacement methods used by canvases + notes: *bindings + testing: + - canvas.type + code: | + window.HTMLCanvasElement.prototype.getContext = function (name) { return 0; }; + @assert canvas.getContext('2d') === 0; + +- name: type.extend + desc: HTMLCanvasElement methods can be added, and the new methods used by canvases + notes: *bindings + testing: + - canvas.type + code: | + window.HTMLCanvasElement.prototype.getZero = function () { return 0; }; + @assert canvas.getZero() === 0; + + +- name: size.attributes.idl.set.zero + desc: Setting width/height IDL attributes to 0 + testing: + - size.width + - size.height + code: | + canvas.width = 0; + canvas.height = 0; + @assert canvas.width === 0; + @assert canvas.height === 0; +# expected: size 0 0 # can't generate zero-sized PNG + +- name: size.attributes.idl + desc: Getting/setting width/height IDL attributes + testing: + - size.width + - size.height + webidl: + - es-unsigned-long + code: | + canvas.width = "100"; + canvas.height = "100"; + @assert canvas.width === 100; + @assert canvas.height === 100; + + canvas.width = "+1.5e2"; + canvas.height = "0x96"; + @assert canvas.width === 150; + @assert canvas.height === 150; + + canvas.width = 200 - Math.pow(2, 32); + canvas.height = 200 - Math.pow(2, 32); + @assert canvas.width === 200; + @assert canvas.height === 200; + + canvas.width = 301.999; + canvas.height = 301.001; + @assert canvas.width === 301; + @assert canvas.height === 301; + + canvas.width = "400x"; + canvas.height = "foo"; + @assert canvas.width === 0; + @assert canvas.height === 0; + +- name: size.attributes.default + desc: Default width/height when attributes are missing + testing: + - size.default + - size.missing + canvas: "" + code: | + @assert canvas.width === 300; + @assert canvas.height === 150; + @assert !canvas.hasAttribute('width'); + @assert !canvas.hasAttribute('height'); + expected: size 300 150 + +- name: size.attributes.reflect.setidl + desc: Setting IDL attributes updates IDL and content attributes + testing: + - size.reflect + code: | + canvas.width = 120; + canvas.height = 60; + @assert canvas.getAttribute('width') === '120'; + @assert canvas.getAttribute('height') === '60'; + @assert canvas.width === 120; + @assert canvas.height === 60; + expected: size 120 60 + +- name: size.attributes.reflect.setidlzero + desc: Setting IDL attributes to 0 updates IDL and content attributes + testing: + - size.reflect + code: | + canvas.width = 0; + canvas.height = 0; + @assert canvas.getAttribute('width') === '0'; + @assert canvas.getAttribute('height') === '0'; + @assert canvas.width === 0; + @assert canvas.height === 0; +# expected: size 0 0 # can't generate zero-sized PNG + +- name: size.attributes.reflect.setcontent + desc: Setting content attributes updates IDL and content attributes + testing: + - size.reflect + code: | + canvas.setAttribute('width', '120'); + canvas.setAttribute('height', '60'); + @assert canvas.getAttribute('width') === '120'; + @assert canvas.getAttribute('height') === '60'; + @assert canvas.width === 120; + @assert canvas.height === 60; + expected: size 120 60 + +- name: size.attributes.removed + desc: Removing content attributes reverts to default size + testing: + - size.missing + canvas: width="120" height="60" + code: | + @assert canvas.width === 120; + canvas.removeAttribute('width'); + @assert canvas.width === 300; + expected: size 300 60 + +- meta: | + cases = [ + ("zero", "0", 0), + ("empty", "", None), + ("onlyspace", " ", None), + ("space", " 100", 100), + ("whitespace", "\n\t\f100", 100), + ("plus", "+100", 100), + ("minus", "-100", None), + ("octal", "0100", 100), + ("hex", "0x100", 0), + ("exp", "100e1", 100), + ("decimal", "100.999", 100), + ("percent", "100%", 100), + ("em", "100em", 100), + ("junk", "#!?", None), + ("trailingjunk", "100#!?", 100), + ] + def gen(name, string, exp, code): + testing = ["size.nonnegativeinteger"] + if exp is None: + testing.append("size.error") + code += "@assert canvas.width === 300;\n@assert canvas.height === 150;\n" + expected = "size 300 150" + else: + code += "@assert canvas.width === %s;\n@assert canvas.height === %s;\n" % (exp, exp) + expected = "size %s %s" % (exp, exp) + + # With "100%", Opera gets canvas.width = 100 but renders at 100% of the frame width, + # so check the CSS display width + code += '@assert window.getComputedStyle(canvas, null).getPropertyValue("width") === "%spx";\n' % (exp, ) + + code += "@assert canvas.getAttribute('width') === %r;\n" % string + code += "@assert canvas.getAttribute('height') === %r;\n" % string + + if exp == 0: + expected = None # can't generate zero-sized PNGs for the expected image + + return code, testing, expected + + for name, string, exp in cases: + code = "" + code, testing, expected = gen(name, string, exp, code) + tests.append( { + "name": "size.attributes.parse.%s" % name, + "desc": "Parsing of non-negative integers", + "testing": testing, + "canvas": 'width="%s" height="%s"' % (string, string), + "code": code, + "expected": expected + } ) + + for name, string, exp in cases: + code = "canvas.setAttribute('width', %r);\ncanvas.setAttribute('height', %r);\n" % (string, string) + code, testing, expected = gen(name, string, exp, code) + tests.append( { + "name": "size.attributes.setAttribute.%s" % name, + "desc": "Parsing of non-negative integers in setAttribute", + "testing": testing, + "canvas": 'width="50" height="50"', + "code": code, + "expected": expected + } ) + +- name: size.attributes.style + desc: Canvas size is independent of CSS resizing + testing: + - size.css + canvas: 'width="50" height="30" style="width: 100px; height: 50px"' + code: | + @assert canvas.width === 50; + @assert canvas.height === 30; + expected: size 100 50 + +- name: size.large + DISABLED: | + "User agents may impose implementation-specific limits on otherwise unconstrained + inputs, e.g. to prevent denial of service attacks, to guard against running out of memory, + or to work around platform-specific limitations." + testing: + - size.width + - size.height + notes: Not sure how reasonable this is, but the spec doesn't say there's an upper limit on the size. + code: | + var n = 2147483647; // 2^31 - 1, which should be supported by any sensible definition of "long" + canvas.width = n; + canvas.height = n; + @assert canvas.width === n; + @assert canvas.height === n; +# expected: size 2147483647 2147483647 # not a good idea to generate the expected image in this case... + +- name: initial.colour + desc: Initial state is transparent black + testing: + - initial.colour + notes: | + Output should be transparent black (not transparent anything-else), but manual + verification can only confirm that it's transparent - it's not possible to make + the actual blackness visible. + code: | + @assert pixel 20,20 == 0,0,0,0; + expected: size 100 50 # transparent + +- name: initial.reset.different + desc: Changing size resets canvas to transparent black + testing: + - initial.reset + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 50, 50); + @assert pixel 20,20 == 255,0,0,255; + canvas.width = 50; + @assert pixel 20,20 == 0,0,0,0; + expected: size 50 50 # transparent + +- name: initial.reset.same + desc: Setting size (not changing the value) resets canvas to transparent black + testing: + - initial.reset + code: | + canvas.width = 100; + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 50, 50); + @assert pixel 20,20 == 255,0,0,255; + canvas.width = 100; + @assert pixel 20,20 == 0,0,0,0; + expected: size 100 50 # transparent + +- name: initial.reset.path + desc: Resetting the canvas state resets the current path + testing: + - initial.reset + code: | + canvas.width = 100; + ctx.rect(0, 0, 100, 50); + canvas.width = 100; + ctx.fillStyle = '#f00'; + ctx.fill(); + @assert pixel 20,20 == 0,0,0,0; + expected: size 100 50 # transparent + +- name: initial.reset.clip + desc: Resetting the canvas state resets the current clip region + testing: + - initial.reset + code: | + canvas.width = 100; + ctx.rect(0, 0, 1, 1); + ctx.clip(); + canvas.width = 100; + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 20,20 == 0,255,0,255; + expected: green + +- name: initial.reset.transform + desc: Resetting the canvas state resets the current transformation matrix + testing: + - initial.reset + code: | + canvas.width = 100; + ctx.scale(0.1, 0.1); + canvas.width = 100; + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 20,20 == 0,255,0,255; + expected: green + +- name: initial.reset.gradient + desc: Resetting the canvas state does not invalidate any existing gradients + testing: + - initial.reset + code: | + canvas.width = 50; + var g = ctx.createLinearGradient(0, 0, 100, 0); + g.addColorStop(0, '#0f0'); + g.addColorStop(1, '#0f0'); + canvas.width = 100; + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: initial.reset.pattern + desc: Resetting the canvas state does not invalidate any existing patterns + testing: + - initial.reset + code: | + canvas.width = 30; + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 30, 50); + var p = ctx.createPattern(canvas, 'repeat-x'); + canvas.width = 100; + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = p; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +# See tests2d.yaml for initial.reset.2dstate + + +- name: context.emptystring + desc: getContext with empty string returns null + testing: + - context.unrecognised + code: | + @assert canvas.getContext("") === null; + +- name: context.unrecognised.badname + desc: getContext with unrecognised context name returns null + testing: + - context.unrecognised + code: | + @assert canvas.getContext('This is not an implemented context in any real browser') === null; + +- name: context.unrecognised.badsuffix + desc: Context name "2d" plus a suffix is unrecognised + testing: + - context.unrecognised + code: | + @assert canvas.getContext("2d#") === null; + +- name: context.unrecognised.nullsuffix + desc: Context name "2d" plus a "\0" suffix is unrecognised + testing: + - context.unrecognised + code: | + @assert canvas.getContext("2d\0") === null; + +- name: context.unrecognised.unicode + desc: Context name which kind of looks like "2d" is unrecognised + testing: + - context.unrecognised + code: | + @assert canvas.getContext("2\uFF44") === null; // Fullwidth Latin Small Letter D + +- name: context.casesensitive + desc: Context name "2D" is unrecognised; matching is case sensitive + testing: + - context.unrecognised + code: | + @assert canvas.getContext('2D') === null; + +- name: context.arguments.missing + notes: *bindings + testing: + - canvas.getContext + code: | + @assert throws TypeError canvas.getContext(); @moz-todo + + + +- name: toBlob.png + desc: toBlob with image/png returns a PNG Blob + testing: + - toBlob.png + code: | + canvas.toBlob(function(data){ + @assert data.type === "image/png"; + }, 'image/png'); + +- name: toBlob.jpeg + desc: toBlob with image/jpeg returns a JPEG Blob + testing: + - toBlob.jpeg + code: | + canvas.toBlob(function(data){ + @assert data.type === "image/jpeg"; + }, 'image/jpeg'); + +- name: toDataURL.default + desc: toDataURL with no arguments returns a PNG + testing: + - toDataURL.noarguments + code: | + var data = canvas.toDataURL(); + @assert data =~ /^data:image\/png[;,]/; + +- name: toDataURL.png + desc: toDataURL with image/png returns a PNG + testing: + - toDataURL.png + - toDataURL.witharguments + code: | + var data = canvas.toDataURL('image/png'); + @assert data =~ /^data:image\/png[;,]/; + +- name: toDataURL.jpg + desc: toDataURL with image/jpg is invalid type hence returns a PNG + testing: + - toDataURL.jpg + - toDataURL.witharguments + code: | + var data = canvas.toDataURL('image/jpg'); + @assert data =~ /^data:image\/png[;,]/; + + +- name: toDataURL.bogustype + desc: toDataURL with a syntactically invalid type returns a PNG + testing: + - toDataURL.unrecognised + code: | + var data = canvas.toDataURL('bogus'); + @assert data =~ /^data:image\/png[;,]/; + +- name: toDataURL.unrecognised + desc: toDataURL with an unhandled type returns a PNG + testing: + - toDataURL.unrecognised + code: | + var data = canvas.toDataURL('image/example'); + @assert data =~ /^data:image\/png[;,]/; + +- name: toDataURL.lowercase.ascii + desc: toDataURL type is case-insensitive + testing: + - toDataURL.lowercase + code: | + var data = canvas.toDataURL('ImAgE/PnG'); + @assert data =~ /^data:image\/png[;,]/; + + // If JPEG is supported at all, it must be supported case-insensitively + data = canvas.toDataURL('image/jpeg'); + if (data.match(/^data:image\/jpeg[;,]/)) { + data = canvas.toDataURL('ImAgE/JpEg'); + @assert data =~ /^data:image\/jpeg[;,]/; + } + +- name: toDataURL.lowercase.unicode + desc: toDataURL type is ASCII-case-insensitive + testing: + - toDataURL.lowercase + code: | + // Use LATIN CAPITAL LETTER I WITH DOT ABOVE (Unicode lowercase is "i") + var data = canvas.toDataURL('\u0130mage/png'); + @assert data =~ /^data:image\/png[;,]/; + + var data = canvas.toDataURL('\u0130mage/jpeg'); + @assert data =~ /^data:image\/png[;,]/; + +- name: toDataURL.arguments.1 + desc: toDataURL ignores extra arguments + testing: + - toDataURL.arguments + code: | + var data = canvas.toDataURL('image/png', 'another argument that should not raise an exception'); + @assert data =~ /^data:image\/png[;,]/; + +- name: toDataURL.arguments.2 + desc: toDataURL ignores extra arguments + testing: + - toDataURL.arguments + code: | + var data = canvas.toDataURL('image/png', 'another argument that should not raise an exception', 'and another'); + @assert data =~ /^data:image\/png[;,]/; + +- name: toDataURL.arguments.3 + desc: toDataURL ignores extra arguments + testing: + - toDataURL.arguments + code: | + // More arguments that should not raise exceptions + var data = canvas.toDataURL('image/png', null, null, null); + @assert data =~ /^data:image\/png[;,]/; + +- name: toDataURL.nocontext + desc: toDataURL works before any context has been got + testing: + - toDataURL.noarguments + code: | + var canvas2 = document.createElement('canvas'); + var data = canvas2.toDataURL(); + @assert data =~ /^data:image\/png[;,]/; + +- name: toDataURL.zerosize + desc: toDataURL on zero-size canvas returns 'data:,' + testing: + - toDataURL.zerosize + canvas: width="0" height="0" + code: | + var data = canvas.toDataURL(); + @assert data === 'data:,'; + +- name: toDataURL.zerowidth + desc: toDataURL on zero-size canvas returns 'data:,' + testing: + - toDataURL.zerosize + canvas: width="0" + code: | + var data = canvas.toDataURL(); + @assert data === 'data:,'; + +- name: toDataURL.zeroheight + desc: toDataURL on zero-size canvas returns 'data:,' + testing: + - toDataURL.zerosize + canvas: height="0" + code: | + var data = canvas.toDataURL(); + @assert data === 'data:,'; + +- name: toDataURL.large1 + DISABLED: just testing implementation limits, and tends to crash + canvas: width="30000" height="1" + code: | + var data = canvas.toDataURL(); + @assert data =~ /^data:image\/png[;,]/; + +- name: toDataURL.large2 + DISABLED: just testing implementation limits, and tends to crash + canvas: width="32767" height="1" + code: | + var data = canvas.toDataURL(); + @assert data =~ /^data:image\/png[;,]/; + +- name: toDataURL.large3 + DISABLED: just testing implementation limits, and tends to crash + canvas: width="32768" height="1" + code: | + var data = canvas.toDataURL(); + @assert data =~ /^data:image\/png[;,]/; + +- name: toDataURL.png.primarycolours + desc: toDataURL with PNG handles simple colours correctly + testing: + - toDataURL.png + code: | + ctx.fillStyle = '#ff0'; + ctx.fillRect(0, 0, 25, 40); + ctx.fillStyle = '#0ff'; + ctx.fillRect(25, 0, 50, 40); + ctx.fillStyle = '#00f'; + ctx.fillRect(75, 0, 25, 40); + ctx.fillStyle = '#fff'; + ctx.fillRect(0, 40, 100, 10); + var data = canvas.toDataURL(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var img = new Image(); + deferTest(); + img.onload = t.step_func_done(function () + { + ctx.drawImage(img, 0, 0); + @assert pixel 12,20 == 255,255,0,255; + @assert pixel 50,20 == 0,255,255,255; + @assert pixel 87,20 == 0,0,255,255; + @assert pixel 50,45 == 255,255,255,255; + }); + img.src = data; + expected: | + size 100 50 + cr.set_source_rgb(1, 1, 0) + cr.rectangle(0, 0, 25, 40) + cr.fill() + cr.set_source_rgb(0, 1, 1) + cr.rectangle(25, 0, 50, 40) + cr.fill() + cr.set_source_rgb(0, 0, 1) + cr.rectangle(75, 0, 25, 40) + cr.fill() + cr.set_source_rgb(1, 1, 1) + cr.rectangle(0, 40, 100, 10) + cr.fill() + +- name: toDataURL.png.complexcolours + desc: toDataURL with PNG handles non-primary and non-solid colours correctly + testing: + - toDataURL.png + code: | + // (These values are chosen to survive relatively alright through being premultiplied) + ctx.fillStyle = 'rgba(1, 3, 254, 1)'; + ctx.fillRect(0, 0, 25, 25); + ctx.fillStyle = 'rgba(8, 252, 248, 0.75)'; + ctx.fillRect(25, 0, 25, 25); + ctx.fillStyle = 'rgba(6, 10, 250, 0.502)'; + ctx.fillRect(50, 0, 25, 25); + ctx.fillStyle = 'rgba(12, 16, 244, 0.25)'; + ctx.fillRect(75, 0, 25, 25); + var img = new Image(); + deferTest(); + img.onload = t.step_func_done(function () + { + ctx.drawImage(img, 0, 25); + // (The alpha values do not really survive float->int conversion, so just + // do approximate comparisons) + @assert pixel 12,40 == 1,3,254,255; + @assert pixel 37,40 ==~ 8,252,248,191 +/- 2; + @assert pixel 62,40 ==~ 6,10,250,127 +/- 4; + @assert pixel 87,40 ==~ 12,16,244,63 +/- 8; + }); + img.src = canvas.toDataURL(); + expected: | + size 100 50 + cr.set_source_rgba(1/255., 3/255., 254/255., 1) + cr.rectangle(0, 0, 25, 50) + cr.fill() + cr.set_source_rgba(8/255., 252/255., 248/255., 191/255.) + cr.rectangle(25, 0, 25, 50) + cr.fill() + cr.set_source_rgba(6/255., 10/255., 250/255., 127/255.) + cr.rectangle(50, 0, 25, 50) + cr.fill() + cr.set_source_rgba(12/255., 16/255., 244/255., 63/255.) + cr.rectangle(75, 0, 25, 50) + cr.fill() + +- name: toDataURL.jpeg.primarycolours + desc: toDataURL with JPEG handles simple colours correctly + testing: + - toDataURL.jpeg + code: | + ctx.fillStyle = '#ff0'; + ctx.fillRect(0, 0, 25, 40); + ctx.fillStyle = '#0ff'; + ctx.fillRect(25, 0, 50, 40); + ctx.fillStyle = '#00f'; + ctx.fillRect(75, 0, 25, 40); + ctx.fillStyle = '#fff'; + ctx.fillRect(0, 40, 100, 10); + var data = canvas.toDataURL('image/jpeg'); // it is okay if this returns a PNG instead + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var img = new Image(); + deferTest(); + img.onload = t.step_func_done(function () + { + ctx.drawImage(img, 0, 0); + @assert pixel 12,20 ==~ 255,255,0,255 +/- 8; + @assert pixel 50,20 ==~ 0,255,255,255 +/- 8; + @assert pixel 87,20 ==~ 0,0,255,255 +/- 8; + @assert pixel 50,45 ==~ 255,255,255,255 +/- 8; + }); + img.src = data; + expected: | + size 100 50 + cr.set_source_rgb(1, 1, 0) + cr.rectangle(0, 0, 25, 40) + cr.fill() + cr.set_source_rgb(0, 1, 1) + cr.rectangle(25, 0, 50, 40) + cr.fill() + cr.set_source_rgb(0, 0, 1) + cr.rectangle(75, 0, 25, 40) + cr.fill() + cr.set_source_rgb(1, 1, 1) + cr.rectangle(0, 40, 100, 10) + cr.fill() + +- name: toDataURL.jpeg.alpha + desc: toDataURL with JPEG composites onto black + testing: + - toDataURL.jpeg + - toDataURL.noalpha + code: | + ctx.fillStyle = 'rgba(128, 255, 128, 0.5)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'destination-over'; // should be ignored by toDataURL + var data = canvas.toDataURL('image/jpeg'); + ctx.globalCompositeOperation = 'source-over'; + if (!data.match(/^data:image\/jpeg[;,]/)) { + @assert true; + } else { + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var img = new Image(); + deferTest(); + img.onload = t.step_func_done(function () + { + ctx.drawImage(img, 0, 0); + @assert pixel 50,25 ==~ 63,127,63,255 +/- 8; + }); + img.src = data; + } + expected: | + size 100 50 + cr.set_source_rgb(0.25, 0.5, 0.25) + cr.rectangle(0, 0, 100, 50) + cr.fill() + +- name: toDataURL.jpeg.quality.basic + desc: toDataURL with JPEG uses the quality parameter + testing: + - toDataURL.jpeg.quality + mozilla: { throws } + code: | + ctx.fillStyle = '#00f'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0ff'; + ctx.fillRect(0, 3, 100, 1); + // Check for JPEG support first + var data = canvas.toDataURL('image/jpeg'); + if (!data.match(/^data:image\/jpeg[;,]/)) { + @assert true; + } else { + var data_hi = canvas.toDataURL('image/jpeg', 0.99); + var data_lo = canvas.toDataURL('image/jpeg', 0.01); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + deferTest(); + var img_hi = new Image(); + img_hi.onload = function () + { + var img_lo = new Image(); + img_lo.onload = t.step_func_done(function () + { + ctx.drawImage(img_hi, 0, 0, 50, 50, 0, 0, 50, 50); + ctx.drawImage(img_lo, 0, 0, 50, 50, 50, 0, 50, 50); + @assert data_hi.length > data_lo.length; + @assert pixel 25,25 ==~ 0,0,255,255 +/- 8; + @assert pixel 75,25 ==~ 0,0,255,255 +/- 32; + }); + img_lo.src = data_lo; + }; + img_hi.src = data_hi; + } + expected: | + size 100 50 + cr.set_source_rgb(0, 0, 1) + cr.rectangle(0, 0, 100, 50) + cr.fill() + cr.set_source_rgb(0, 1, 1) + cr.rectangle(0, 3, 100, 1) + cr.fill() + +- name: toDataURL.jpeg.quality.notnumber + desc: toDataURL with JPEG handles non-numeric quality parameters + testing: + - toDataURL.jpeg.nan + code: | + ctx.fillStyle = '#00f'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0ff'; + ctx.fillRect(0, 3, 100, 1); + // Check for JPEG support first + var data = canvas.toDataURL('image/jpeg'); + if (!data.match(/^data:image\/jpeg[;,]/)) { + @assert true; + } else { + @assert canvas.toDataURL('image/jpeg', 'bogus') === data; + @assert canvas.toDataURL('image/jpeg', {}) === data; + @assert canvas.toDataURL('image/jpeg', null) === data; + @assert canvas.toDataURL('image/jpeg', undefined) === data; + @assert canvas.toDataURL('image/jpeg', true) === data; + @assert canvas.toDataURL('image/jpeg', '0.01') === data; + } + +- name: toDataURL.jpeg.quality.outsiderange + desc: toDataURL with JPEG handles out-of-range quality parameters + testing: + - toDataURL.jpeg.range + code: | + ctx.fillStyle = '#00f'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0ff'; + ctx.fillRect(0, 3, 100, 1); + // Check for JPEG support first + var data = canvas.toDataURL('image/jpeg'); + if (!data.match(/^data:image\/jpeg[;,]/)) { + @assert true; + } else { + @assert canvas.toDataURL('image/jpeg', 10) === data; + @assert canvas.toDataURL('image/jpeg', -10) === data; + @assert canvas.toDataURL('image/jpeg', 1.01) === data; + @assert canvas.toDataURL('image/jpeg', -0.01) === data; + + @assert canvas.toDataURL('image/jpeg', 1).length >= canvas.toDataURL('image/jpeg', 0.9).length; + @assert canvas.toDataURL('image/jpeg', 0).length <= canvas.toDataURL('image/jpeg', 0.1).length; + } + + +# TODO: work out what security exception should be thrown +# TODO: test same-origin vs same-host + +- name: security.drawImage.image + desc: drawImage of different-origin image makes the canvas origin-unclean + mozilla: { disabled } # relies on external resources + testing: + - security.drawImage.image + - security.toDataURL + - security.getImageData + scripts: + - /common/get-host-info.sub.js + - data:text/javascript,addCrossOriginYellowImage() + code: | + ctx.drawImage(document.getElementById('yellow.png'), 0, 0); + @assert throws SECURITY_ERR canvas.toDataURL(); + @assert throws SECURITY_ERR ctx.getImageData(0, 0, 1, 1); + +- name: security.drawImage.canvas + desc: drawImage of unclean canvas makes the canvas origin-unclean + mozilla: { disabled } # relies on external resources + testing: + - security.drawImage.canvas + scripts: + - /common/get-host-info.sub.js + - data:text/javascript,addCrossOriginYellowImage() + code: | + var canvas2 = document.createElement('canvas'); + canvas2.width = 100; + canvas2.height = 50; + var ctx2 = canvas2.getContext('2d'); + ctx2.drawImage(document.getElementById('yellow.png'), 0, 0); + ctx.drawImage(canvas2, 0, 0); + @assert throws SECURITY_ERR canvas.toDataURL(); + @assert throws SECURITY_ERR ctx.getImageData(0, 0, 1, 1); + +- name: security.pattern.create + desc: Creating an unclean pattern does not make the canvas origin-unclean + mozilla: { disabled } # relies on external resources + testing: + - security.start + scripts: + - /common/get-host-info.sub.js + - data:text/javascript,addCrossOriginYellowImage() + code: | + var p = ctx.createPattern(document.getElementById('yellow.png'), 'repeat'); + canvas.toDataURL(); + ctx.getImageData(0, 0, 1, 1); + @assert true; // okay if there was no exception + +- name: security.pattern.cross + desc: Using an unclean pattern makes the target canvas origin-unclean, not the pattern canvas + mozilla: { disabled } # relies on external resources + testing: + - security.start + scripts: + - /common/get-host-info.sub.js + - data:text/javascript,addCrossOriginYellowImage() + code: | + var canvas2 = document.createElement('canvas'); + canvas2.width = 100; + canvas2.height = 50; + var ctx2 = canvas2.getContext('2d'); + var p = ctx2.createPattern(document.getElementById('yellow.png'), 'repeat'); + ctx.fillStyle = p; + ctx.fillRect(0, 0, 100, 50); + @assert throws SECURITY_ERR canvas.toDataURL(); + @assert throws SECURITY_ERR ctx.getImageData(0, 0, 1, 1); + canvas2.toDataURL(); + ctx2.getImageData(0, 0, 1, 1); + +- name: security.pattern.canvas.timing + desc: Pattern safety depends on whether the source was origin-clean, not on whether it still is clean + notes: Disagrees with spec on "is" vs "was" + mozilla: { disabled } # relies on external resources + testing: + - security.start + - security.fillStyle.canvas + scripts: + - /common/get-host-info.sub.js + - data:text/javascript,addCrossOriginYellowImage() + code: | + var canvas2 = document.createElement('canvas'); + canvas2.width = 100; + canvas2.height = 50; + var ctx2 = canvas2.getContext('2d'); + ctx2.fillStyle = '#0f0'; + ctx2.fillRect(0, 0, 100, 50); + var p = ctx.createPattern(canvas2, 'repeat'); + ctx2.drawImage(document.getElementById('yellow.png'), 0, 0); // make canvas2 origin-unclean + ctx.fillStyle = p; + ctx.fillRect(0, 0, 100, 50); + canvas.toDataURL(); + ctx.getImageData(0, 0, 1, 1); + @assert true; // okay if there was no exception + +- name: security.pattern.image.fillStyle + desc: Setting fillStyle to a pattern of a different-origin image makes the canvas origin-unclean + mozilla: { disabled } # relies on external resources + testing: + - security.fillStyle.image + scripts: + - /common/get-host-info.sub.js + - data:text/javascript,addCrossOriginYellowImage() + code: | + var p = ctx.createPattern(document.getElementById('yellow.png'), 'repeat'); + ctx.fillStyle = p; + ctx.fillStyle = 'red'; + @assert throws SECURITY_ERR canvas.toDataURL(); + @assert throws SECURITY_ERR ctx.getImageData(0, 0, 1, 1); + +- name: security.pattern.canvas.fillStyle + desc: Setting fillStyle to a pattern of an unclean canvas makes the canvas origin-unclean + mozilla: { bug: 354127, disabled } # relies on external resources + testing: + - security.fillStyle.canvas + scripts: + - /common/get-host-info.sub.js + - data:text/javascript,addCrossOriginYellowImage() + code: | + var canvas2 = document.createElement('canvas'); + canvas2.width = 100; + canvas2.height = 50; + var ctx2 = canvas2.getContext('2d'); + ctx2.drawImage(document.getElementById('yellow.png'), 0, 0); + var p = ctx.createPattern(canvas2, 'repeat'); + ctx.fillStyle = p; + ctx.fillStyle = 'red'; + @assert throws SECURITY_ERR canvas.toDataURL(); + @assert throws SECURITY_ERR ctx.getImageData(0, 0, 1, 1); + +- name: security.pattern.image.strokeStyle + desc: Setting strokeStyle to a pattern of a different-origin image makes the canvas origin-unclean + mozilla: { disabled } # relies on external resources + testing: + - security.strokeStyle.image + scripts: + - /common/get-host-info.sub.js + - data:text/javascript,addCrossOriginYellowImage() + code: | + var p = ctx.createPattern(document.getElementById('yellow.png'), 'repeat'); + ctx.strokeStyle = p; + ctx.strokeStyle = 'red'; + @assert throws SECURITY_ERR canvas.toDataURL(); + @assert throws SECURITY_ERR ctx.getImageData(0, 0, 1, 1); + +- name: security.pattern.canvas.strokeStyle + desc: Setting strokeStyle to a pattern of an unclean canvas makes the canvas origin-unclean + mozilla: { bug: 354127, disabled } # relies on external resources + testing: + - security.strokeStyle.canvas + scripts: + - /common/get-host-info.sub.js + - data:text/javascript,addCrossOriginYellowImage() + code: | + var canvas2 = document.createElement('canvas'); + canvas2.width = 100; + canvas2.height = 50; + var ctx2 = canvas2.getContext('2d'); + ctx2.drawImage(document.getElementById('yellow.png'), 0, 0); + var p = ctx.createPattern(canvas2, 'repeat'); + ctx.strokeStyle = p; + ctx.strokeStyle = 'red'; + @assert throws SECURITY_ERR canvas.toDataURL(); + @assert throws SECURITY_ERR ctx.getImageData(0, 0, 1, 1); + +- name: security.dataURI + desc: 'data: URIs do not count as different-origin, and do not taint the canvas' + mozilla: { disabled, bug: 417836 } # can't do "todo" so just disable it + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var data = canvas.toDataURL(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var img = new Image(); + deferTest(); + img.onload = t.step_func_done(function () + { + ctx.drawImage(img, 0, 0); + canvas.toDataURL(); // should be permitted + @assert pixel 50,25 == 0,255,0,255; + }); + img.src = data; + expected: green + +- name: security.reset + desc: Resetting the canvas state does not reset the origin-clean flag + mozilla: { disabled } # relies on external resources + testing: + - initial.reset + scripts: + - /common/get-host-info.sub.js + - data:text/javascript,addCrossOriginYellowImage() + code: | + canvas.width = 50; + ctx.drawImage(document.getElementById('yellow.png'), 0, 0); + @assert throws SECURITY_ERR canvas.toDataURL(); + canvas.width = 100; + @assert throws SECURITY_ERR canvas.toDataURL(); |