|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- /**
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- * @format
- * @flow strict-local
- * @emails oncall+draft_js
- */
- 'use strict';
-
- const getRangeClientRects = require("./getRangeClientRects");
-
- export type FakeClientRect = {
- left: number,
- width: number,
- right: number,
- top: number,
- bottom: number,
- height: number,
- ...
- };
- /**
- * Like range.getBoundingClientRect() but normalizes for browser bugs.
- */
-
- function getRangeBoundingClientRect(range: Range): FakeClientRect {
- // "Return a DOMRect object describing the smallest rectangle that includes
- // the first rectangle in list and all of the remaining rectangles of which
- // the height or width is not zero."
- // http://www.w3.org/TR/cssom-view/#dom-range-getboundingclientrect
- const rects = getRangeClientRects(range);
- let top = 0;
- let right = 0;
- let bottom = 0;
- let left = 0;
-
- if (rects.length) {
- // If the first rectangle has 0 width, we use the second, this is needed
- // because Chrome renders a 0 width rectangle when the selection contains
- // a line break.
- if (rects.length > 1 && rects[0].width === 0) {
- ({
- top,
- right,
- bottom,
- left
- } = rects[1]);
- } else {
- ({
- top,
- right,
- bottom,
- left
- } = rects[0]);
- }
-
- for (let ii = 1; ii < rects.length; ii++) {
- const rect = rects[ii];
-
- if (rect.height !== 0 && rect.width !== 0) {
- top = Math.min(top, rect.top);
- right = Math.max(right, rect.right);
- bottom = Math.max(bottom, rect.bottom);
- left = Math.min(left, rect.left);
- }
- }
- }
-
- return {
- top,
- right,
- bottom,
- left,
- width: right - left,
- height: bottom - top
- };
- }
-
- module.exports = getRangeBoundingClientRect;
|