Skip to content

Commit

Permalink
Merge pull request #13613 from ckeditor/ck/10776-fix-image-resize-handle
Browse files Browse the repository at this point in the history
Fix (image): Fix the image resize handle displaying NaN in some scenarios. Closes #10776.
  • Loading branch information
arkflpc authored Mar 13, 2023
2 parents 99831ff + 20eabf1 commit 5d280fa
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 2 deletions.
25 changes: 23 additions & 2 deletions packages/ckeditor5-widget/src/widgetresize/resizerstate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,12 +189,33 @@ export default class ResizeState extends ObservableMixin() {
}

/**
* Calculates a relative width of a `domResizeHost` compared to it's parent in percents.
* Calculates a relative width of a `domResizeHost` compared to its ancestor in percents.
*/
function calculateHostPercentageWidth( domResizeHost: HTMLElement, resizeHostRect: Rect ) {
const domResizeHostParent = domResizeHost.parentElement;

// Need to use computed style as it properly excludes parent's paddings from the returned value.
const parentWidth = parseFloat( domResizeHostParent!.ownerDocument.defaultView!.getComputedStyle( domResizeHostParent! ).width );
let parentWidth = parseFloat( domResizeHostParent!.ownerDocument.defaultView!.getComputedStyle( domResizeHostParent! ).width );

// Sometimes parent width cannot be accessed. If that happens we should go up in the elements tree
// and try to get width from next ancestor.
// https://github.com/ckeditor/ckeditor5/issues/10776
const ancestorLevelLimit = 5;
let currentLevel = 0;

let checkedElement = domResizeHostParent!;

while ( isNaN( parentWidth ) ) {
checkedElement = checkedElement.parentElement!;

if ( ++currentLevel > ancestorLevelLimit ) {
return 0;
}

parentWidth = parseFloat(
domResizeHostParent!.ownerDocument.defaultView!.getComputedStyle( checkedElement ).width
);
}

return resizeHostRect.width / parentWidth * 100;
}
Expand Down
51 changes: 51 additions & 0 deletions packages/ckeditor5-widget/tests/widgetresize/resizerstate.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,57 @@ describe( 'ResizerState', () => {
} );
} );

describe( 'width percents calculations ', () => {
const domContentWrapper = document.createElement( 'span' );

before( () => {
const htmlMockup = `<div class="dom-element">
<div class="ck ck-reset_all ck-widget__resizer" style="width: 400px; height: 200px;">
<div class="ck-widget__resizer__handle ck-widget__resizer__handle-bottom-right"></div>
</div>
</div>`;

domContentWrapper.style.width = 'auto';
domContentWrapper.innerHTML = htmlMockup;
} );

it( 'should not return NaN if resizer is inside a <span>', () => {
document.body.append( domContentWrapper );

const domResizeHandle = domContentWrapper.querySelector( '.ck-widget__resizer__handle' );
const domHandleHost = domContentWrapper.querySelector( '.dom-element' );
const domResizeHost = domHandleHost;

const state = new ResizerState();
state.begin( domResizeHandle, domHandleHost, domResizeHost );

expect( state.originalWidthPercents, 'originalWidthPercents' ).to.not.be.NaN;
expect( state.originalWidthPercents, 'originalWidthPercents' ).to.equal( 100 );
domContentWrapper.remove();
} );

it( 'should return 0 if cannot calculate width from 5 ancestors', () => {
let elem = domContentWrapper;
for ( let i = 0; i < 5; i++ ) {
const e = document.createElement( 'span' );
e.appendChild( elem );
elem = e;
}
document.body.append( elem );

const domResizeHandle = domContentWrapper.querySelector( '.ck-widget__resizer__handle' );
const domHandleHost = domContentWrapper.querySelector( '.dom-element' );
const domResizeHost = domHandleHost;

const state = new ResizerState();
state.begin( domResizeHandle, domHandleHost, domResizeHost );

expect( state.originalWidthPercents, 'originalWidthPercents' ).to.not.be.NaN;
expect( state.originalWidthPercents, 'originalWidthPercents' ).to.equal( 0 );
elem.remove();
} );
} );

describe( 'update()', () => {
it( 'changes the properties', () => {
const state = new ResizerState();
Expand Down

0 comments on commit 5d280fa

Please sign in to comment.