mirror of
				https://github.com/videojs/video.js.git
				synced 2025-10-31 00:08:01 +02:00 
			
		
		
		
	fix(dom): handle slotted parent transform position (#8158)
* fix(dom): handle slotted parent transform position * fix(test): add test to cover getPointerPosition * run all tests --------- Co-authored-by: mister-ben <git@misterben.me>
This commit is contained in:
		| @@ -580,7 +580,15 @@ export function getPointerPosition(el, event) { | ||||
|         translated.y += values[13]; | ||||
|       } | ||||
|  | ||||
|       item = item.parentNode; | ||||
|       if (item.assignedSlot && item.assignedSlot.parentElement && window.WebKitCSSMatrix) { | ||||
|         const transformValue = window.getComputedStyle(item.assignedSlot.parentElement).transform; | ||||
|         const matrix = new window.WebKitCSSMatrix(transformValue); | ||||
|  | ||||
|         translated.x += matrix.m41; | ||||
|         translated.y += matrix.m42; | ||||
|       } | ||||
|  | ||||
|       item = item.parentNode || item.host; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -23,7 +23,23 @@ export class TestCustomElement extends HTMLElement { | ||||
|   } | ||||
| } | ||||
|  | ||||
| export class TestSlotElement extends HTMLElement { | ||||
|  | ||||
|   constructor() { | ||||
|     super(); | ||||
|     const shadowRoot = this.attachShadow({ mode: 'open' }); | ||||
|     const wrapperEl = document.createElement('div'); | ||||
|  | ||||
|     wrapperEl.style = this.dataset.style; | ||||
|     const slot = document.createElement('slot'); | ||||
|  | ||||
|     wrapperEl.appendChild(slot); | ||||
|     shadowRoot.appendChild(wrapperEl); | ||||
|   } | ||||
| } | ||||
|  | ||||
| // Not supported on Chrome < 54 | ||||
| if ('customElements' in window) { | ||||
|   window.customElements.define('test-custom-element', TestCustomElement); | ||||
|   window.customElements.define('test-slot-element', TestSlotElement); | ||||
| } | ||||
|   | ||||
| @@ -3,6 +3,7 @@ import document from 'global/document'; | ||||
| import sinon from 'sinon'; | ||||
| import * as Dom from '../../../src/js/utils/dom.js'; | ||||
| import TestHelpers from '../test-helpers.js'; | ||||
| import * as browser from '../../../src/js/utils/browser.js'; | ||||
|  | ||||
| QUnit.module('utils/dom'); | ||||
|  | ||||
| @@ -687,6 +688,89 @@ QUnit.test('isSingleLeftClick() checks return values for mousedown event', funct | ||||
|   assert.ok(Dom.isSingleLeftClick(mouseEvent), 'a tap-to-click on Mac trackpad is a single left click'); | ||||
| }); | ||||
|  | ||||
| QUnit.test('dom.getPointerPosition should return position with translated', function(assert) { | ||||
|   const wrapper = document.createElement('div'); | ||||
|  | ||||
|   const width = '100px'; | ||||
|   const height = '50px'; | ||||
|  | ||||
|   wrapper.style.width = width; | ||||
|   wrapper.style.height = height; | ||||
|   wrapper.style.position = 'absolute'; | ||||
|   wrapper.style.top = '0'; | ||||
|   wrapper.style.left = '0'; | ||||
|  | ||||
|   let position; | ||||
|  | ||||
|   document.body.appendChild(wrapper); | ||||
|   const event = { | ||||
|     offsetX: 20, | ||||
|     offsetY: 0, | ||||
|     target: wrapper | ||||
|   }; | ||||
|  | ||||
|   position = Dom.getPointerPosition(wrapper, event); | ||||
|  | ||||
|   // Default click on element without any transform | ||||
|   assert.deepEqual(position, { x: 0.2, y: 1 }); | ||||
|  | ||||
|   const origIOS = browser.IS_IOS; | ||||
|  | ||||
|   wrapper.style.transform = 'translate(5px)'; | ||||
|  | ||||
|   const transformedTouch = { | ||||
|     offsetX: 20, | ||||
|     offsetY: 0, | ||||
|     target: wrapper, | ||||
|     changedTouches: [ | ||||
|       { | ||||
|         pageX: 20, | ||||
|         pageY: 0 | ||||
|       } | ||||
|     ] | ||||
|   }; | ||||
|  | ||||
|   // Ignore translate x/y when not in IOS | ||||
|   position = Dom.getPointerPosition(wrapper, transformedTouch); | ||||
|   assert.deepEqual(position, { x: 0.2, y: 1 }); | ||||
|  | ||||
|   // Add calculate with IOS to true | ||||
|   browser.stub_IS_IOS(true); | ||||
|   position = Dom.getPointerPosition(wrapper, transformedTouch); | ||||
|   assert.deepEqual(position, { x: 0.15, y: 1 }); | ||||
|  | ||||
|   // Create complex template where position of each video is controlled by | ||||
|   // a web component with transform | ||||
|   wrapper.style.transform = ''; | ||||
|   const progressStyle = `position: absolute; height: ${height}; width: ${width};`; | ||||
|  | ||||
|   wrapper.innerHTML = ` | ||||
|     <test-slot-element id="slides" style="position: absolute" data-style="position: relative; transform: translate(5px);"> | ||||
|       <div class="video-01"> | ||||
|         <div class="progress-01" style="${progressStyle}"></div> | ||||
|       </div> | ||||
|       <div class="video-02"> | ||||
|         <div class="progress-02" style="${progressStyle}"></div> | ||||
|       </div> | ||||
|     </test-slot-element> | ||||
|   `; | ||||
|   document.body.appendChild(wrapper); | ||||
|  | ||||
|   const slottedProgressBar = wrapper.querySelector('div.progress-02'); | ||||
|  | ||||
|   // Handle slot elements pointer position | ||||
|   transformedTouch.target = slottedProgressBar; | ||||
|   position = Dom.getPointerPosition(slottedProgressBar, transformedTouch); | ||||
|   assert.deepEqual(position, { x: 0.15, y: 1 }); | ||||
|  | ||||
|   // Non IOS slot element pointer position | ||||
|   browser.stub_IS_IOS(false); | ||||
|   position = Dom.getPointerPosition(slottedProgressBar, transformedTouch); | ||||
|   assert.deepEqual(position, { x: 0.20, y: 1 }); | ||||
|  | ||||
|   browser.stub_IS_IOS(origIOS); | ||||
| }); | ||||
|  | ||||
| QUnit.test('Dom.copyStyleSheetsToWindow() copies all style sheets to a window', function(assert) { | ||||
|   /** | ||||
|    * This test is checking that styles are copied by comparing strings in original stylesheets to those in | ||||
|   | ||||
		Reference in New Issue
	
	Block a user