forked from firefox-devtools/profiler
-
Notifications
You must be signed in to change notification settings - Fork 0
/
css-geometry-tools.js
98 lines (88 loc) · 3.26 KB
/
css-geometry-tools.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// @flow
import DOMRect from './dom-rect';
// Imported interfaces incorrectly throw an error in eslint:
// https://github.com/benmosher/eslint-plugin-import/issues/726
import type { DOMRectInterface } from './dom-rect';
/**
* Return a float number for the number of CSS pixels from the computed style
* of the supplied CSS property on the supplied element.
*/
function getFloatStyle(element: HTMLElement, cssProperty: string): number {
// flow doesn't know about getComputedStyle.
const getComputedStyle = window.getComputedStyle;
return (
parseFloat(getComputedStyle(element).getPropertyValue(cssProperty)) || 0
);
}
function subtractBorder(
element: HTMLElement,
rect: DOMRectInterface | ClientRect
): DOMRectInterface {
const borderTop = getFloatStyle(element, 'border-top-width');
const borderRight = getFloatStyle(element, 'border-right-width');
const borderBottom = getFloatStyle(element, 'border-bottom-width');
const borderLeft = getFloatStyle(element, 'border-left-width');
return new DOMRect(
rect.left + borderLeft,
rect.top + borderTop,
rect.width - borderLeft - borderRight,
rect.height - borderTop - borderBottom
);
}
function subtractPadding(
element: HTMLElement,
rect: DOMRectInterface | ClientRect
): DOMRectInterface {
const paddingTop = getFloatStyle(element, 'padding-top');
const paddingRight = getFloatStyle(element, 'padding-right');
const paddingBottom = getFloatStyle(element, 'padding-bottom');
const paddingLeft = getFloatStyle(element, 'padding-left');
return new DOMRect(
rect.left + paddingLeft,
rect.top + paddingTop,
rect.width - paddingLeft - paddingRight,
rect.height - paddingTop - paddingBottom
);
}
function addMargin(
element: HTMLElement,
rect: DOMRectInterface | ClientRect
): DOMRectInterface {
const marginTop = getFloatStyle(element, 'margin-top');
const marginRight = getFloatStyle(element, 'margin-right');
const marginBottom = getFloatStyle(element, 'margin-bottom');
const marginLeft = getFloatStyle(element, 'margin-left');
return new DOMRect(
rect.left - marginLeft,
rect.top - marginTop,
rect.width + marginLeft + marginRight,
rect.height + marginTop + marginBottom
);
}
/**
* Returns a DOMRect for the content rect of the element, in float CSS pixels.
* Returns an empty rect if the object has zero or more than one client rects.
*/
export function getContentRect(element: HTMLElement): DOMRectInterface {
const clientRects = element.getClientRects();
if (clientRects.length !== 1) {
return new DOMRect();
}
const borderRect = clientRects[0];
return subtractPadding(element, subtractBorder(element, borderRect));
}
/**
* Returns a DOMRect for the margin rect of the element, in float CSS pixels.
* Returns an empty rect if the object has zero or more than one client rects.
*/
export function getMarginRect(element: HTMLElement): DOMRectInterface {
const clientRects = element.getClientRects();
if (clientRects.length !== 1) {
return new DOMRect();
}
const borderRect = clientRects[0];
return addMargin(element, borderRect);
}