-
Notifications
You must be signed in to change notification settings - Fork 481
Expand file tree
/
Copy pathcss-geometry-tools.ts
More file actions
106 lines (95 loc) · 3.48 KB
/
Copy pathcss-geometry-tools.ts
File metadata and controls
106 lines (95 loc) · 3.48 KB
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
99
100
101
102
103
104
105
106
/* 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/. */
/**
* 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: DOMRect): DOMRect {
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: DOMRect): DOMRect {
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: DOMRect): DOMRect {
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): DOMRect {
const clientRects = element.getClientRects();
if (clientRects.length !== 1) {
return new DOMRect(0, 0, 0, 0);
}
const borderRect = clientRects[0];
return subtractPadding(
element,
subtractBorder(element, clientRectToDomRect(borderRect))
);
}
function clientRectToDomRect(clientRect: DOMRectReadOnly): DOMRect {
return new DOMRect(
clientRect.left,
clientRect.top,
clientRect.width,
clientRect.height
);
}
/**
* 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): DOMRect {
const clientRects = element.getClientRects();
if (clientRects.length !== 1) {
return new DOMRect(0, 0, 0, 0);
}
return addMargin(element, clientRectToDomRect(clientRects[0]));
}
/**
* When upgrading to Flow v0.96.0, it started including a DOMRect implementation.
* This nominal class doesn't like accessing an object via indexer properties, so
* encapsulate this access in a function.
*/
export function extractDomRectValue(
rect: DOMRect,
key: 'top' | 'left' | 'right' | 'bottom'
): number {
return rect[key];
}