From: Jukka Kurkela Date: Fri, 20 Nov 2020 20:59:48 +0000 (+0200) Subject: Do not use offsetX/Y in shadow DOM (#8082) X-Git-Tag: v3.0.0-beta.7~22 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fa997f06e23e2644ce1985de51b9dfbf2e7426df;p=thirdparty%2FChart.js.git Do not use offsetX/Y in shadow DOM (#8082) Do not use offsetX/Y in shadow DOM --- diff --git a/src/helpers/helpers.dom.js b/src/helpers/helpers.dom.js index 12eb7f3a6..50c2654d9 100644 --- a/src/helpers/helpers.dom.js +++ b/src/helpers/helpers.dom.js @@ -52,6 +52,8 @@ function getPositionedStyle(styles, style, suffix) { return result; } +const useOffsetPos = (x, y, target) => (x > 0 || y > 0) && (!target || !target.shadowRoot); + function getCanvasPosition(evt, canvas) { const e = evt.originalEvent || evt; const touches = e.touches; @@ -59,7 +61,7 @@ function getCanvasPosition(evt, canvas) { const {offsetX, offsetY} = source; let box = false; let x, y; - if (offsetX > 0 || offsetY > 0) { + if (useOffsetPos(offsetX, offsetY, e.target)) { x = offsetX; y = offsetY; } else { diff --git a/test/specs/helpers.dom.tests.js b/test/specs/helpers.dom.tests.js index 11f13dec2..9cd370d05 100644 --- a/test/specs/helpers.dom.tests.js +++ b/test/specs/helpers.dom.tests.js @@ -345,5 +345,59 @@ describe('DOM helpers tests', function() { expect(Math.abs(pos3.x - Math.round((event.clientX - rect3.x - 10) / 360 * 400))).toBeLessThanOrEqual(1); expect(Math.abs(pos3.y - Math.round((event.clientY - rect3.y - 10) / 360 * 400))).toBeLessThanOrEqual(1); }); + + it ('should get the correct relative position for a node in a ShadowRoot', function() { + const event = { + offsetX: 50, + offsetY: 100, + clientX: 50, + clientY: 100 + }; + + const chart = window.acquireChart({}, { + canvas: { + height: 200, + width: 200, + }, + useShadowDOM: true + }); + + event.target = chart.canvas.parentNode.host; + expect(event.target.shadowRoot).not.toEqual(null); + const rect = chart.canvas.getBoundingClientRect(); + const pos = helpers.getRelativePosition(event, chart); + expect(Math.abs(pos.x - Math.round(event.clientX - rect.x))).toBeLessThanOrEqual(1); + expect(Math.abs(pos.y - Math.round(event.clientY - rect.y))).toBeLessThanOrEqual(1); + + const chart2 = window.acquireChart({}, { + canvas: { + height: 200, + width: 200, + style: 'padding: 10px' + }, + useShadowDOM: true + }); + + event.target = chart2.canvas.parentNode.host; + const rect2 = chart2.canvas.getBoundingClientRect(); + const pos2 = helpers.getRelativePosition(event, chart2); + expect(Math.abs(pos2.x - Math.round((event.clientX - rect2.x - 10) / 180 * 200))).toBeLessThanOrEqual(1); + expect(Math.abs(pos2.y - Math.round((event.clientY - rect2.y - 10) / 180 * 200))).toBeLessThanOrEqual(1); + + const chart3 = window.acquireChart({}, { + canvas: { + height: 200, + width: 200, + style: 'width: 400px, height: 400px; padding: 10px' + }, + useShadowDOM: true + }); + + event.target = chart3.canvas.parentNode.host; + const rect3 = chart3.canvas.getBoundingClientRect(); + const pos3 = helpers.getRelativePosition(event, chart3); + expect(Math.abs(pos3.x - Math.round((event.clientX - rect3.x - 10) / 360 * 400))).toBeLessThanOrEqual(1); + expect(Math.abs(pos3.y - Math.round((event.clientY - rect3.y - 10) / 360 * 400))).toBeLessThanOrEqual(1); + }); }); }); diff --git a/test/utils.js b/test/utils.js index 010971dde..ee443880e 100644 --- a/test/utils.js +++ b/test/utils.js @@ -30,6 +30,7 @@ function readImageData(url, callback) { * @param {object} options.canvas - Canvas attributes. * @param {object} options.wrapper - Canvas wrapper attributes. * @param {boolean} options.useOffscreenCanvas - use an OffscreenCanvas instead of the normal HTMLCanvasElement. + * @param {boolean} options.useShadowDOM - use shadowDom * @param {boolean} options.persistent - If true, the chart will not be released after the spec. */ function acquireChart(config, options) { @@ -60,7 +61,15 @@ function acquireChart(config, options) { config.options.responsive = config.options.responsive === undefined ? false : config.options.responsive; config.options.locale = config.options.locale || 'en-US'; - wrapper.appendChild(canvas); + if (options.useShadowDOM) { + if (!wrapper.attachShadow) { + // If shadowDOM is not supported by the browsers, mark test as 'pending'. + return pending(); + } + wrapper.attachShadow({mode: 'open'}).appendChild(canvas); + } else { + wrapper.appendChild(canvas); + } window.document.body.appendChild(wrapper); try { @@ -71,8 +80,7 @@ function acquireChart(config, options) { // test. // TODO: switch to skip() once it's implemented (https://github.com/jasmine/jasmine/issues/1709), or // remove if all browsers implement `transferControlToOffscreen` - pending(); - return; + return pending(); } var offscreenCanvas = canvas.transferControlToOffscreen(); ctx = offscreenCanvas.getContext('2d');