Implement DOMRect and DOMRectReadOnly matching Web
Summary: This adds the `DOMRect` and `DOMRectReadOnly` classes to React Native, mostly following the Web spec. This is a requirement for `node.getBoundingClientRect()`, which we'll implement in React (in https://github.com/facebook/react/blob/main/packages/react-native-renderer/src/ReactFabricHostConfig.js#L134-L323). Changelog: [General][Added] - Added Web-compatible `DOMRect` and `DOMRectReadOnly` classes to the global scope. Reviewed By: ryancat Differential Revision: D42963222 fbshipit-source-id: bf2ed15bfbfd71822cb6f969f8cc0a67c7834333
This commit is contained in:
Родитель
333755367f
Коммит
673c7617bc
|
@ -27,6 +27,7 @@
|
|||
const start = Date.now();
|
||||
|
||||
require('./setUpGlobals');
|
||||
require('./setUpDOM');
|
||||
require('./setUpPerformance');
|
||||
require('./setUpErrorHandling');
|
||||
require('./polyfillPromise');
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow strict
|
||||
* @format
|
||||
*/
|
||||
|
||||
import DOMRect from '../DOM/Geometry/DOMRect';
|
||||
import DOMRectReadOnly from '../DOM/Geometry/DOMRectReadOnly';
|
||||
|
||||
// $FlowExpectedError[cannot-write] The global isn't writable anywhere but here, where we define it
|
||||
global.DOMRect = DOMRect;
|
||||
|
||||
// $FlowExpectedError[cannot-write] The global isn't writable anywhere but here, where we define it
|
||||
global.DOMRectReadOnly = DOMRectReadOnly;
|
|
@ -0,0 +1,82 @@
|
|||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow strict
|
||||
* @format
|
||||
*/
|
||||
|
||||
/**
|
||||
* The JSDoc comments in this file have been extracted from [DOMRect](https://developer.mozilla.org/en-US/docs/Web/API/DOMRect).
|
||||
* Content by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/DOMRect/contributors.txt),
|
||||
* licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/).
|
||||
*/
|
||||
|
||||
import DOMRectReadOnly, {type DOMRectLike} from './DOMRectReadOnly';
|
||||
|
||||
// flowlint unsafe-getters-setters:off
|
||||
|
||||
/**
|
||||
* A `DOMRect` describes the size and position of a rectangle.
|
||||
* The type of box represented by the `DOMRect` is specified by the method or property that returned it.
|
||||
*
|
||||
* This is a (mostly) spec-compliant version of `DOMRect` (https://developer.mozilla.org/en-US/docs/Web/API/DOMRect).
|
||||
*/
|
||||
export default class DOMRect extends DOMRectReadOnly {
|
||||
/**
|
||||
* The x coordinate of the `DOMRect`'s origin.
|
||||
*/
|
||||
get x(): number {
|
||||
return this.__getInternalX();
|
||||
}
|
||||
|
||||
set x(x: ?number) {
|
||||
this.__setInternalX(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* The y coordinate of the `DOMRect`'s origin.
|
||||
*/
|
||||
get y(): number {
|
||||
return this.__getInternalY();
|
||||
}
|
||||
|
||||
set y(y: ?number) {
|
||||
this.__setInternalY(y);
|
||||
}
|
||||
|
||||
/**
|
||||
* The width of the `DOMRect`.
|
||||
*/
|
||||
get width(): number {
|
||||
return this.__getInternalWidth();
|
||||
}
|
||||
|
||||
set width(width: ?number) {
|
||||
this.__setInternalWidth(width);
|
||||
}
|
||||
|
||||
/**
|
||||
* The height of the `DOMRect`.
|
||||
*/
|
||||
get height(): number {
|
||||
return this.__getInternalHeight();
|
||||
}
|
||||
|
||||
set height(height: ?number) {
|
||||
this.__setInternalHeight(height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new `DOMRect` object with a given location and dimensions.
|
||||
*/
|
||||
static fromRect(rect?: ?DOMRectLike): DOMRect {
|
||||
if (!rect) {
|
||||
return new DOMRect();
|
||||
}
|
||||
|
||||
return new DOMRect(rect.x, rect.y, rect.width, rect.height);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,188 @@
|
|||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow strict
|
||||
* @format
|
||||
*/
|
||||
|
||||
/**
|
||||
* The JSDoc comments in this file have been extracted from [DOMRectReadOnly](https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly).
|
||||
* Content by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly/contributors.txt),
|
||||
* licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/).
|
||||
*/
|
||||
|
||||
// flowlint sketchy-null:off, unsafe-getters-setters:off
|
||||
|
||||
export interface DOMRectLike {
|
||||
x?: ?number;
|
||||
y?: ?number;
|
||||
width?: ?number;
|
||||
height?: ?number;
|
||||
}
|
||||
|
||||
function castToNumber(value: mixed): number {
|
||||
return value ? Number(value) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The `DOMRectReadOnly` interface specifies the standard properties used by `DOMRect` to define a rectangle whose properties are immutable.
|
||||
*
|
||||
* This is a (mostly) spec-compliant version of `DOMRectReadOnly` (https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly).
|
||||
*/
|
||||
export default class DOMRectReadOnly {
|
||||
_x: number;
|
||||
_y: number;
|
||||
_width: number;
|
||||
_height: number;
|
||||
|
||||
constructor(x: ?number, y: ?number, width: ?number, height: ?number) {
|
||||
this.__setInternalX(x);
|
||||
this.__setInternalY(y);
|
||||
this.__setInternalWidth(width);
|
||||
this.__setInternalHeight(height);
|
||||
}
|
||||
|
||||
/**
|
||||
* The x coordinate of the `DOMRectReadOnly`'s origin.
|
||||
*/
|
||||
get x(): number {
|
||||
return this._x;
|
||||
}
|
||||
|
||||
/**
|
||||
* The y coordinate of the `DOMRectReadOnly`'s origin.
|
||||
*/
|
||||
get y(): number {
|
||||
return this._y;
|
||||
}
|
||||
|
||||
/**
|
||||
* The width of the `DOMRectReadOnly`.
|
||||
*/
|
||||
get width(): number {
|
||||
return this._width;
|
||||
}
|
||||
|
||||
/**
|
||||
* The height of the `DOMRectReadOnly`.
|
||||
*/
|
||||
get height(): number {
|
||||
return this._height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the top coordinate value of the `DOMRect` (has the same value as `y`, or `y + height` if `height` is negative).
|
||||
*/
|
||||
get top(): number {
|
||||
const height = this._height;
|
||||
const y = this._y;
|
||||
|
||||
if (height < 0) {
|
||||
return y + height;
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the right coordinate value of the `DOMRect` (has the same value as ``x + width`, or `x` if `width` is negative).
|
||||
*/
|
||||
get right(): number {
|
||||
const width = this._width;
|
||||
const x = this._x;
|
||||
|
||||
if (width < 0) {
|
||||
return x;
|
||||
}
|
||||
|
||||
return x + width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bottom coordinate value of the `DOMRect` (has the same value as `y + height`, or `y` if `height` is negative).
|
||||
*/
|
||||
get bottom(): number {
|
||||
const height = this._height;
|
||||
const y = this._y;
|
||||
|
||||
if (height < 0) {
|
||||
return y;
|
||||
}
|
||||
|
||||
return y + height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the left coordinate value of the `DOMRect` (has the same value as `x`, or `x + width` if `width` is negative).
|
||||
*/
|
||||
get left(): number {
|
||||
const width = this._width;
|
||||
const x = this._x;
|
||||
|
||||
if (width < 0) {
|
||||
return x + width;
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
toJSON(): {
|
||||
x: number,
|
||||
y: number,
|
||||
width: number,
|
||||
height: number,
|
||||
top: number,
|
||||
left: number,
|
||||
bottom: number,
|
||||
right: number,
|
||||
} {
|
||||
const {x, y, width, height, top, left, bottom, right} = this;
|
||||
return {x, y, width, height, top, left, bottom, right};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new `DOMRectReadOnly` object with a given location and dimensions.
|
||||
*/
|
||||
static fromRect(rect?: ?DOMRectLike): DOMRectReadOnly {
|
||||
if (!rect) {
|
||||
return new DOMRectReadOnly();
|
||||
}
|
||||
|
||||
return new DOMRectReadOnly(rect.x, rect.y, rect.width, rect.height);
|
||||
}
|
||||
|
||||
__getInternalX(): number {
|
||||
return this._x;
|
||||
}
|
||||
|
||||
__getInternalY(): number {
|
||||
return this._y;
|
||||
}
|
||||
|
||||
__getInternalWidth(): number {
|
||||
return this._width;
|
||||
}
|
||||
|
||||
__getInternalHeight(): number {
|
||||
return this._height;
|
||||
}
|
||||
|
||||
__setInternalX(x: ?number) {
|
||||
this._x = castToNumber(x);
|
||||
}
|
||||
|
||||
__setInternalY(y: ?number) {
|
||||
this._y = castToNumber(y);
|
||||
}
|
||||
|
||||
__setInternalWidth(width: ?number) {
|
||||
this._width = castToNumber(width);
|
||||
}
|
||||
|
||||
__setInternalHeight(height: ?number) {
|
||||
this._height = castToNumber(height);
|
||||
}
|
||||
}
|
|
@ -80,6 +80,10 @@ declare var global: {
|
|||
+__DEV__?: boolean,
|
||||
+RN$Bridgeless?: boolean,
|
||||
|
||||
// setupDOM
|
||||
+DOMRect: typeof DOMRect,
|
||||
+DOMRectReadOnly: typeof DOMRectReadOnly,
|
||||
|
||||
// Undeclared properties are implicitly `any`.
|
||||
[string | symbol]: any,
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче