| <!DOCTYPE html> |
| <html class="reftest-wait"> |
| <link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples"> |
| <link rel="match" href="parse-input-arguments-ref.html"> |
| <style> |
| .container { |
| width: 100px; |
| height: 100px; |
| } |
| |
| #canvas-geometry { |
| background-image: paint(geometry); |
| } |
| </style> |
| <script src="/common/reftest-wait.js"></script> |
| <script src="/common/worklet-reftest.js"></script> |
| <body> |
| <div id="canvas-geometry" class="container"></div> |
| <script id="code" type="text/worklet"> |
| // Globals that must be prepended to this script: |
| // - debugLog: A function that logs errors. |
| // - props: Test data. |
| |
| registerPaint('geometry', class { |
| static get inputProperties() { return props.map(p => p.name); } |
| |
| paint(ctx, geom, styleMap) { |
| ctx.strokeStyle = 'green'; |
| for (let prop of props) { |
| // Read values using get, getAll and iterator: |
| let valueFromGet = styleMap.get(prop.name); |
| let valueFromGetAll = styleMap.getAll(prop.name); |
| let valueFromIterator = Array.from(styleMap).filter(e => e[0] == prop.name)[0][1]; |
| |
| // Serialize 'actual'-values for all three cases: |
| let serialize = v => v.constructor.name + '=' + v.toString() |
| let actualFromGet = serialize(valueFromGet); |
| let actualFromGetAll = valueFromGetAll.map(serialize).join(','); |
| let actualFromIterator = valueFromIterator.map(serialize).join(','); |
| |
| // Create 'expected'-values for all three cases: |
| let expectedForGet = prop.expected[0]; |
| let expectedForGetAll = prop.expected.join(','); |
| let expectedForIterator = expectedForGetAll; |
| |
| let pass = true; |
| |
| // Assertions: |
| if (actualFromGet !== expectedForGet) { |
| debugLog(`FAIL: StylePropertyMap.get: actual: ${actualFromGet} expected: ${expectedForGet}`); |
| pass = false; |
| } |
| if (actualFromGetAll !== expectedForGetAll) { |
| debugLog(`FAIL: StylePropertyMap.getAll: actual: ${actualFromGetAll} expected: ${expectedForGetAll}`); |
| pass = false; |
| } |
| if (actualFromIterator !== expectedForIterator) { |
| debugLog(`FAIL: StylePropertyMap iterator: actual: ${actualFromIterator} expected: ${expectedForIterator}`); |
| pass = false; |
| } |
| |
| if (!pass) |
| ctx.strokeStyle = 'red'; |
| else |
| debugLog('PASS', prop.syntax, actualFromGetAll, expectedForGetAll); |
| } |
| ctx.lineWidth = 4; |
| ctx.strokeRect(0, 0, geom.width, geom.height); |
| } |
| }); |
| </script> |
| <script> |
| // A copy of this array (automatically enriched with 'name' and 'expected') |
| // is also available in the worklet. |
| let props = [ |
| // Initial values. |
| { syntax: '*', initialValue: 'if(){}' }, |
| { syntax: '<angle>', initialValue: '42deg' }, |
| { syntax: '<color>', initialValue: '#fefefe' }, |
| { syntax: '<custom-ident>', initialValue: 'none' }, |
| { syntax: '<image>', initialValue: 'linear-gradient(red, red)' }, |
| { syntax: '<image>', initialValue: 'url(http://a.com/a)' }, |
| { syntax: '<integer>', initialValue: '42' }, |
| { syntax: '<length-percentage>', initialValue: '10%' }, |
| { syntax: '<length-percentage>', initialValue: '10px' }, |
| { syntax: '<length-percentage>', initialValue: 'calc(10px + 10%)' }, |
| { syntax: '<length>', initialValue: '1337px' }, |
| { syntax: '<number>', initialValue: '42.5' }, |
| { syntax: '<percentage>', initialValue: '42%' }, |
| { syntax: '<resolution>', initialValue: '300dpi' }, |
| { syntax: '<time>', initialValue: '3600s' }, |
| { syntax: '<url>', initialValue: 'url(http://a.com/a)' }, |
| { syntax: 'thing', initialValue: 'thing' }, |
| { syntax: '<length> | <angle>', initialValue: '1337px' }, |
| { syntax: '<angle> | <image>', initialValue: '1turn' }, |
| { syntax: '<length>+', initialValue: '1337px' }, |
| { syntax: '<length>+', initialValue: '1337px 1338px', count: 2 }, |
| { syntax: '<length>#', initialValue: '1337px' }, |
| { syntax: '<length>#', initialValue: '1337px, 1338px', count: 2 }, |
| |
| // Non-initial values: |
| { syntax: '*', initialValue: 'fail', value: 'if(){}' }, |
| { syntax: '<angle> | fail', initialValue: 'fail', value: '42deg' }, |
| { syntax: '<color> | fail', initialValue: 'fail', value: '#fefefe' }, |
| { syntax: '<custom-ident> | fail', initialValue: 'fail', value: 'none' }, |
| { syntax: '<image> | fail', initialValue: 'fail', value: 'linear-gradient(red, red)' }, |
| { syntax: '<image> | fail', initialValue: 'fail', value: 'url(http://a.com/a)' }, |
| { syntax: '<integer> | fail', initialValue: 'fail', value: '42' }, |
| { syntax: '<length-percentage> | fail', initialValue: 'fail', value: '10%' }, |
| { syntax: '<length-percentage> | fail', initialValue: 'fail', value: '10px' }, |
| { syntax: '<length-percentage> | fail', initialValue: 'fail', value: 'calc(10px + 10%)' }, |
| { syntax: '<length> | fail', initialValue: 'fail', value: '1337px' }, |
| { syntax: '<number> | fail', initialValue: 'fail', value: '42.5' }, |
| { syntax: '<percentage> | fail', initialValue: 'fail', value: '42%' }, |
| { syntax: '<resolution> | fail', initialValue: 'fail', value: '300dpi' }, |
| { syntax: '<time> | fail', initialValue: 'fail', value: '3600s' }, |
| { syntax: '<url> | fail', initialValue: 'fail', value: 'url(http://a.com/a)' }, |
| { syntax: 'thing | fail', initialValue: 'fail', value: 'thing' }, |
| { syntax: '<length>+ | fail', initialValue: 'fail', value: '1337px' }, |
| { syntax: '<length>+ | fail', initialValue: 'fail', value: '1337px 1338px', count: 2 }, |
| { syntax: '<length># | fail', initialValue: 'fail', value: '1337px' }, |
| { syntax: '<length># | fail', initialValue: 'fail', value: '1337px, 1338px', count: 2 }, |
| ]; |
| |
| try { |
| let target = document.getElementById('canvas-geometry'); |
| let pid = 1; |
| |
| for (let p of props) { |
| p.name = `--prop-${++pid}`; |
| |
| CSS.registerProperty({ |
| name: p.name, |
| syntax: p.syntax, |
| initialValue: p.initialValue, |
| inherits: (typeof p.inherits !== 'undefined') ? p.inherits : false |
| }); |
| |
| if (typeof p.value !== 'undefined') |
| target.style.setProperty(p.name, p.value); |
| if (typeof p.count === 'undefined') |
| p.count = 1; |
| |
| let getValue = p => (typeof p.value !== 'undefined') ? p.value : p.initialValue; |
| let serialize = v => v.constructor.name + '=' + v.toString(); |
| |
| let parse = function (p) { |
| if (p.count == 1) |
| return [CSSStyleValue.parse(p.name, getValue(p))]; |
| return CSSStyleValue.parseAll(p.name, getValue(p)); |
| }; |
| |
| // Generate expected value. We assume that CSSStyleValue.parse/All |
| // returns the correct CSSStyleValue subclass and value. |
| p.expected = parse(p).map(serialize); |
| } |
| |
| // Adding '?debug' to the URL will cause this test to emit |
| // test results to console.log. |
| let debugMode = document.location.href.endsWith('?debug'); |
| let code = [ |
| `const props = ${JSON.stringify(props)};`, |
| `const debugLog = ${debugMode ? 'console.log' : 'function(){}'};`, |
| document.getElementById('code').textContent |
| ].join('\n'); |
| |
| importWorkletAndTerminateTestAfterAsyncPaint(CSS.paintWorklet, code); |
| } catch(e) { |
| document.body.textContent = e; |
| takeScreenshot(); |
| } |
| </script> |
| </body> |
| </html> |