Skip to content

Commit

Permalink
dom: Add types progressively to dom modules (#30103)
Browse files Browse the repository at this point in the history
* dom: Add types progressively to dom modules

* Add tests to assertIsDefined

* Try fix e2e

* Move defined assertion
  • Loading branch information
sarayourfriend committed Mar 30, 2021
1 parent c63361b commit 4b8b2d9
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 7 deletions.
2 changes: 1 addition & 1 deletion packages/dom/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ _Parameters_

_Returns_

- `?DOMRect`: The rectangle.
- `DOMRect | null`: The rectangle.

<a name="documentHasSelection" href="#documentHasSelection">#</a> **documentHasSelection**

Expand Down
2 changes: 1 addition & 1 deletion packages/dom/src/dom/caret-range-from-point.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* @param {number} x Horizontal position within the current viewport.
* @param {number} y Vertical position within the current viewport.
*
* @return {?Range} The best range for the given point.
* @return {Range | null} The best range for the given point.
*/
export default function caretRangeFromPoint( doc, x, y ) {
if ( doc.caretRangeFromPoint ) {
Expand Down
6 changes: 4 additions & 2 deletions packages/dom/src/dom/compute-caret-rect.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,22 @@
* Internal dependencies
*/
import getRectangleFromRange from './get-rectangle-from-range';
import { assertIsDefined } from '../utils/assert-is-defined';

/**
* Get the rectangle for the selection in a container.
*
* @param {Window} win The window of the selection.
*
* @return {?DOMRect} The rectangle.
* @return {DOMRect | null} The rectangle.
*/
export default function computeCaretRect( win ) {
const selection = win.getSelection();
assertIsDefined( selection, 'selection' );
const range = selection.rangeCount ? selection.getRangeAt( 0 ) : null;

if ( ! range ) {
return;
return null;
}

return getRectangleFromRange( range );
Expand Down
15 changes: 12 additions & 3 deletions packages/dom/src/dom/get-rectangle-from-range.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* Internal dependencies
*/
import { assertIsDefined } from '../utils/assert-is-defined';

/**
* Get the rectangle of a given Range.
*
Expand All @@ -19,10 +24,12 @@ export default function getRectangleFromRange( range ) {
// Correct invalid "BR" ranges. The cannot contain any children.
if ( startContainer.nodeName === 'BR' ) {
const { parentNode } = startContainer;
const index = Array.from( parentNode.childNodes ).indexOf(
startContainer
);
assertIsDefined( parentNode, 'parentNode' );
const index = /** @type {Node[]} */ ( Array.from(
parentNode.childNodes
) ).indexOf( startContainer );

assertIsDefined( ownerDocument, 'ownerDocument' );
range = ownerDocument.createRange();
range.setStart( parentNode, index );
range.setEnd( parentNode, index );
Expand All @@ -36,11 +43,13 @@ export default function getRectangleFromRange( range ) {
//
// See: https://stackoverflow.com/a/6847328/995445
if ( ! rect ) {
assertIsDefined( ownerDocument, 'ownerDocument' );
const padNode = ownerDocument.createTextNode( '\u200b' );
// Do not modify the live range.
range = range.cloneRange();
range.insertNode( padNode );
rect = range.getClientRects()[ 0 ];
assertIsDefined( padNode.parentNode, 'padNode.parentNode' );
padNode.parentNode.removeChild( padNode );
}

Expand Down
25 changes: 25 additions & 0 deletions packages/dom/src/test/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* Internal dependencies
*/
import { assertIsDefined } from '../utils/assert-is-defined';

describe( 'assertIsDefined', () => {
it( 'should throw if the variable is null', () => {
expect( () => assertIsDefined( null, 'val' ) ).toThrow(
"Expected 'val' to be defined, but received null"
);
} );

it( 'should throw if the variable is undefined', () => {
expect( () => assertIsDefined( undefined, 'val' ) ).toThrow(
"Expected 'val' to be defined, but received undefined"
);
} );

it.each( [ 0, '', NaN, -0, 1, new String(), {}, [], false, Infinity ] )(
'should not throw if the value is %s',
( val ) => {
expect( () => assertIsDefined( val, 'val' ) ).not.toThrow();
}
);
} );
10 changes: 10 additions & 0 deletions packages/dom/src/utils/assert-is-defined.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export function assertIsDefined< T >(
val: T,
name: string
): asserts val is NonNullable< T > {
if ( val === undefined || val === null ) {
throw new Error(
`Expected '${ name }' to be defined, but received ${ val }`
);
}
}
4 changes: 4 additions & 0 deletions packages/dom/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
},
"include": [
"src/data-transfer.js",
"src/dom/caret-range-from-point.js",
"src/dom/compute-caret-rect.js",
"src/dom/get-rectangle-from-range.js",
"src/utils/**/*",
"src/focusable.js",
"src/phrasing-content.js",
"src/tabbable.js",
Expand Down

0 comments on commit 4b8b2d9

Please sign in to comment.