Skip to content
This repository has been archived by the owner on Jun 26, 2020. It is now read-only.

Commit

Permalink
Merge pull request #331 from ckeditor/i/6570
Browse files Browse the repository at this point in the history
Fix: Do not execute `ResizeObserver` callbacks when the resized element is invisible (but still in DOM) (see ckeditor/ckeditor5#6570).
  • Loading branch information
oleq authored Apr 9, 2020
2 parents 4b8c9cd + 7a5143a commit fb13d9d
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/dom/resizeobserver.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,12 @@ export default class ResizeObserver {

ResizeObserver._observerInstance = new ObserverConstructor( entries => {
for ( const entry of entries ) {
// Do not execute callbacks for elements that are invisible.
// https://github.com/ckeditor/ckeditor5/issues/6570
if ( !entry.target.offsetParent ) {
continue;
}

const callbacks = ResizeObserver._getElementCallbacks( entry.target );

if ( callbacks ) {
Expand Down
61 changes: 61 additions & 0 deletions tests/dom/resizeobserver.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,18 @@ describe( 'ResizeObserver()', () => {
elementA.id = 'A';
elementB = document.createElement( 'div' );
elementB.id = 'B';

document.body.appendChild( elementA );
document.body.appendChild( elementB );
} );

afterEach( () => {
// Make it look like the module was loaded from scratch.
ResizeObserver._observerInstance = null;
ResizeObserver._elementCallbacks = null;

elementA.remove();
elementB.remove();
} );

describe( 'constructor()', () => {
Expand Down Expand Up @@ -108,6 +114,61 @@ describe( 'ResizeObserver()', () => {
observerA.destroy();
} );

it( 'should not react to resizing of an element if element is invisible', () => {
const callbackA = sinon.spy();
let resizeCallback;

testUtils.sinon.stub( global.window, 'ResizeObserver' ).callsFake( callback => {
resizeCallback = callback;

return {
observe() {},
unobserve() {}
};
} );

const observerA = new ResizeObserver( elementA, callbackA );

elementA.style.display = 'none';

resizeCallback( [
{ target: elementA }
] );

sinon.assert.notCalled( callbackA );

observerA.destroy();
} );

it( 'should not react to resizing of an element if element\'s parent is invisible', () => {
const callbackA = sinon.spy();
let resizeCallback;

testUtils.sinon.stub( global.window, 'ResizeObserver' ).callsFake( callback => {
resizeCallback = callback;

return {
observe() {},
unobserve() {}
};
} );

const observerA = new ResizeObserver( elementA, callbackA );
const parent = document.createElement( 'div' );
document.body.appendChild( parent );
parent.appendChild( elementA );
parent.style.display = 'none';

resizeCallback( [
{ target: elementA }
] );

sinon.assert.notCalled( callbackA );

parent.remove();
observerA.destroy();
} );

it( 'should be able to observe the same element along with other observers', () => {
const callbackA = sinon.spy();
const callbackB = sinon.spy();
Expand Down

0 comments on commit fb13d9d

Please sign in to comment.