Skip to content

Commit

Permalink
Merge pull request #426 from mathuo/425-dockview-inside-shadowdom
Browse files Browse the repository at this point in the history
bug: resizable should work within shadow dom
  • Loading branch information
mathuo authored Jan 9, 2024
2 parents b78a7a6 + 5e45b9a commit 64076b2
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 3 deletions.
29 changes: 28 additions & 1 deletion packages/dockview-core/src/__tests__/dom.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { quasiDefaultPrevented, quasiPreventDefault } from '../dom';
import {
isInDocument,
quasiDefaultPrevented,
quasiPreventDefault,
} from '../dom';

describe('dom', () => {
test('quasiPreventDefault', () => {
Expand All @@ -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();
});
});
21 changes: 21 additions & 0 deletions packages/dockview-core/src/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
4 changes: 2 additions & 2 deletions packages/dockview-core/src/resizable.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { watchElementResize } from './dom';
import { isInDocument, watchElementResize } from './dom';
import { CompositeDisposable } from './lifecycle';

export abstract class Resizable extends CompositeDisposable {
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 64076b2

Please sign in to comment.