bug: resizable should work within shadow dom

This commit is contained in:
mathuo 2024-01-09 21:12:56 +00:00
parent b78a7a6207
commit 5e45b9a469
No known key found for this signature in database
GPG Key ID: C6EEDEFD6CA07281
3 changed files with 51 additions and 3 deletions

View File

@ -1,4 +1,8 @@
import { quasiDefaultPrevented, quasiPreventDefault } from '../dom';
import {
isInDocument,
quasiDefaultPrevented,
quasiPreventDefault,
} from '../dom';
describe('dom', () => {
test('quasiPreventDefault', () => {
@ -18,4 +22,27 @@ describe('dom', () => {
(event as any)['dv-quasiPreventDefault'] = true;
expect(quasiDefaultPrevented(event)).toBeTruthy();
});
test('isInDocument: DOM element', () => {
const el = document.createElement('div');
expect(isInDocument(el)).toBeFalsy();
document.body.appendChild(el);
expect(isInDocument(el)).toBeTruthy();
});
test('isInDocument: Shadow DOM element', () => {
const el = document.createElement('div');
document.body.appendChild(el);
const shadow = el.attachShadow({ mode: 'open' });
const el2 = document.createElement('div');
expect(isInDocument(el2)).toBeFalsy();
shadow.appendChild(el2);
expect(isInDocument(el2)).toBeTruthy();
});
});

View File

@ -232,3 +232,24 @@ export function getDomNodePagePosition(domNode: Element): {
height: height,
};
}
/**
* Check whether an element is in the DOM (including the Shadow DOM)
* @see https://terodox.tech/how-to-tell-if-an-element-is-in-the-dom-including-the-shadow-dom/
*/
export function isInDocument(element: Element): boolean {
let currentElement: Element | ParentNode = element;
while (currentElement && currentElement.parentNode) {
if (currentElement.parentNode === document) {
return true;
} else if (currentElement.parentNode instanceof DocumentFragment) {
// handle shadow DOMs
currentElement = (currentElement.parentNode as ShadowRoot).host;
} else {
currentElement = currentElement.parentNode;
}
}
return false;
}

View File

@ -1,4 +1,4 @@
import { watchElementResize } from './dom';
import { isInDocument, watchElementResize } from './dom';
import { CompositeDisposable } from './lifecycle';
export abstract class Resizable extends CompositeDisposable {
@ -45,7 +45,7 @@ export abstract class Resizable extends CompositeDisposable {
return;
}
if (!document.body.contains(this._element)) {
if (!isInDocument(this._element)) {
/**
* since the event is dispatched through requestAnimationFrame there is a small chance
* the component is no longer attached to the DOM, if that is the case the dimensions