@d3plus/dom 3.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +176 -0
- package/es/index.js +13 -0
- package/es/src/assign.js +39 -0
- package/es/src/attrize.js +9 -0
- package/es/src/date.js +51 -0
- package/es/src/elem.js +38 -0
- package/es/src/fontExists.js +60 -0
- package/es/src/getSize.js +41 -0
- package/es/src/inViewport.js +14 -0
- package/es/src/isObject.js +18 -0
- package/es/src/parseSides.js +29 -0
- package/es/src/prefix.js +10 -0
- package/es/src/rtl.js +7 -0
- package/es/src/stylize.js +9 -0
- package/es/src/textWidth.js +41 -0
- package/package.json +40 -0
- package/umd/d3plus-dom.full.js +2690 -0
- package/umd/d3plus-dom.full.js.map +1 -0
- package/umd/d3plus-dom.full.min.js +219 -0
- package/umd/d3plus-dom.js +463 -0
- package/umd/d3plus-dom.js.map +1 -0
- package/umd/d3plus-dom.min.js +108 -0
package/README.md
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# @d3plus/dom
|
|
2
|
+
|
|
3
|
+
JavaScript functions for manipulating and analyzing DOM elements.
|
|
4
|
+
|
|
5
|
+
## Installing
|
|
6
|
+
|
|
7
|
+
If using npm, `npm install @d3plus/dom`. Otherwise, you can download the [latest release from GitHub](https://github.com/d3plus/d3plus/releases/latest) or load from a [CDN](https://cdn.jsdelivr.net/npm/@d3plus/dom@3.0.0-alpha.0/+esm).
|
|
8
|
+
|
|
9
|
+
```js
|
|
10
|
+
import modules from "@d3plus/dom";
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
In vanilla JavaScript, a `d3plus` global is exported from the pre-bundled version:
|
|
14
|
+
|
|
15
|
+
```html
|
|
16
|
+
<script src="https://cdn.jsdelivr.net/npm/@d3plus/dom@3.0.0-alpha.0"></script>
|
|
17
|
+
<script>
|
|
18
|
+
console.log(d3plus);
|
|
19
|
+
</script>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Examples
|
|
23
|
+
|
|
24
|
+
Live examples can be found on [d3plus.org](https://d3plus.org/), which includes a collection of example visualizations using @d3plus/react.
|
|
25
|
+
|
|
26
|
+
## API Reference
|
|
27
|
+
|
|
28
|
+
#####
|
|
29
|
+
* [assign](#assign) - A deeply recursive version of `Object.assign`.
|
|
30
|
+
* [attrize](#attrize) - Applies each key/value in an object as an attr.
|
|
31
|
+
* [date](#date) - Parses numbers and strings to valid Javascript Date objects.
|
|
32
|
+
* [elem](#elem) - Manages the enter/update/exit pattern for a single DOM element.
|
|
33
|
+
* [fontExists](#fontExists) - Given either a single font-family or a list of fonts, returns the name of the first font that can be rendered, or `false` if none are installed on the user's machine.
|
|
34
|
+
* [isObject](#isObject) - Detects if a variable is a javascript Object.
|
|
35
|
+
* [parseSides](#parseSides) - Converts a string of directional CSS shorthand values into an object with the values expanded.
|
|
36
|
+
* [prefix](#prefix) - Returns the appropriate CSS vendor prefix, given the current browser.
|
|
37
|
+
* [rtl](#rtl) - Returns `true` if the HTML or body element has either the "dir" HTML attribute or the "direction" CSS property set to "rtl".
|
|
38
|
+
* [stylize](#stylize) - Applies each key/value in an object as a style.
|
|
39
|
+
* [htmlDecode](#htmlDecode) - Strips HTML and "un-escapes" escape characters.
|
|
40
|
+
* [textWidth](#textWidth) - Given a text string, returns the predicted pixel width of the string when placed into DOM.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
<a name="assign"></a>
|
|
45
|
+
#### d3plus.**assign**(...objects) [<>](https://github.com/d3plus/d3plus/blob/main/packages/dom/src/assign.js#L14)
|
|
46
|
+
|
|
47
|
+
A deeply recursive version of `Object.assign`.
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
This is a global function
|
|
51
|
+
this
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
assign({id: "foo", deep: {group: "A"}}, {id: "bar", deep: {value: 20}}));
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
returns this
|
|
58
|
+
|
|
59
|
+
```js
|
|
60
|
+
{id: "bar", deep: {group: "A", value: 20}}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
<a name="attrize"></a>
|
|
66
|
+
#### d3plus.**attrize**(elem, attrs) [<>](https://github.com/d3plus/d3plus/blob/main/packages/dom/src/attrize.js#L1)
|
|
67
|
+
|
|
68
|
+
Applies each key/value in an object as an attr.
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
This is a global function
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
<a name="date"></a>
|
|
76
|
+
#### d3plus.**date**(*date*) [<>](https://github.com/d3plus/d3plus/blob/main/packages/dom/src/date.js#L1)
|
|
77
|
+
|
|
78
|
+
Returns a javascript Date object for a given a Number (representing either a 4-digit year or milliseconds since epoch), a String representing a Quarter (ie. "Q2 1987", mapping to the last day in that quarter), or a String that is in [valid dateString format](http://dygraphs.com/date-formats.html). Besides the 4-digit year parsing, this function is useful when needing to parse negative (BC) years, which the vanilla Date object cannot parse.
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
This is a global function
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
<a name="elem"></a>
|
|
86
|
+
#### d3plus.**elem**(selector, params) [<>](https://github.com/d3plus/d3plus/blob/main/packages/dom/src/elem.js#L6)
|
|
87
|
+
|
|
88
|
+
Manages the enter/update/exit pattern for a single DOM element.
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
This is a global function
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
<a name="fontExists"></a>
|
|
96
|
+
#### d3plus.**fontExists**(font) [<>](https://github.com/d3plus/d3plus/blob/main/packages/dom/src/fontExists.js#L10)
|
|
97
|
+
|
|
98
|
+
Given either a single font-family or a list of fonts, returns the name of the first font that can be rendered, or `false` if none are installed on the user's machine.
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
This is a global function
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
<a name="isObject"></a>
|
|
106
|
+
#### d3plus.**isObject**(item) [<>](https://github.com/d3plus/d3plus/blob/main/packages/dom/src/isObject.js#L1)
|
|
107
|
+
|
|
108
|
+
Detects if a variable is a javascript Object.
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
This is a global function
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
<a name="parseSides"></a>
|
|
116
|
+
#### d3plus.**parseSides**(sides) [<>](https://github.com/d3plus/d3plus/blob/main/packages/dom/src/parseSides.js#L1)
|
|
117
|
+
|
|
118
|
+
Converts a string of directional CSS shorthand values into an object with the values expanded.
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
This is a global function
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
<a name="prefix"></a>
|
|
126
|
+
#### d3plus.**prefix**() [<>](https://github.com/d3plus/d3plus/blob/main/packages/dom/src/prefix.js#L1)
|
|
127
|
+
|
|
128
|
+
Returns the appropriate CSS vendor prefix, given the current browser.
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
This is a global function
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
<a name="rtl"></a>
|
|
136
|
+
#### d3plus.**rtl**() [<>](https://github.com/d3plus/d3plus/blob/main/packages/dom/src/rtl.js#L3)
|
|
137
|
+
|
|
138
|
+
Returns `true` if the HTML or body element has either the "dir" HTML attribute or the "direction" CSS property set to "rtl".
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
This is a global function
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
<a name="stylize"></a>
|
|
146
|
+
#### d3plus.**stylize**(elem, styles) [<>](https://github.com/d3plus/d3plus/blob/main/packages/dom/src/stylize.js#L1)
|
|
147
|
+
|
|
148
|
+
Applies each key/value in an object as a style.
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
This is a global function
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
<a name="htmlDecode"></a>
|
|
156
|
+
#### d3plus.**htmlDecode**(input) [<>](https://github.com/d3plus/d3plus/blob/main/packages/dom/src/textWidth.js#L5)
|
|
157
|
+
|
|
158
|
+
Strips HTML and "un-escapes" escape characters.
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
This is a global function
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
<a name="textWidth"></a>
|
|
166
|
+
#### d3plus.**textWidth**(text, [style]) [<>](https://github.com/d3plus/d3plus/blob/main/packages/dom/src/textWidth.js#L12)
|
|
167
|
+
|
|
168
|
+
Given a text string, returns the predicted pixel width of the string when placed into DOM.
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
This is a global function
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
###### <sub>Documentation generated on Thu, 13 Mar 2025 19:58:29 GMT</sub>
|
package/es/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { default as assign } from "./src/assign.js";
|
|
2
|
+
export { default as attrize } from "./src/attrize.js";
|
|
3
|
+
export { default as date } from "./src/date.js";
|
|
4
|
+
export { default as elem } from "./src/elem.js";
|
|
5
|
+
export { default as fontExists } from "./src/fontExists.js";
|
|
6
|
+
export { default as getSize } from "./src/getSize.js";
|
|
7
|
+
export { default as inViewport } from "./src/inViewport.js";
|
|
8
|
+
export { default as isObject } from "./src/isObject.js";
|
|
9
|
+
export { default as parseSides } from "./src/parseSides.js";
|
|
10
|
+
export { default as prefix } from "./src/prefix.js";
|
|
11
|
+
export { default as rtl } from "./src/rtl.js";
|
|
12
|
+
export { default as stylize } from "./src/stylize.js";
|
|
13
|
+
export { default as textWidth } from "./src/textWidth.js";
|
package/es/src/assign.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import isObject from "./isObject.js";
|
|
2
|
+
/**
|
|
3
|
+
@function validObject
|
|
4
|
+
@desc Determines if the object passed is the document or window.
|
|
5
|
+
@param {Object} obj
|
|
6
|
+
@private
|
|
7
|
+
*/ function validObject(obj) {
|
|
8
|
+
if (typeof window === "undefined") return true;
|
|
9
|
+
else return obj !== window && obj !== document;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
@function assign
|
|
13
|
+
@desc A deeply recursive version of `Object.assign`.
|
|
14
|
+
@param {...Object} objects
|
|
15
|
+
@example <caption>this</caption>
|
|
16
|
+
assign({id: "foo", deep: {group: "A"}}, {id: "bar", deep: {value: 20}}));
|
|
17
|
+
@example <caption>returns this</caption>
|
|
18
|
+
{id: "bar", deep: {group: "A", value: 20}}
|
|
19
|
+
*/ function assign() {
|
|
20
|
+
var _loop = function(i) {
|
|
21
|
+
var source = objects[i];
|
|
22
|
+
if (!isObject(source)) return "continue";
|
|
23
|
+
Object.keys(source).forEach(function(prop) {
|
|
24
|
+
var value = source[prop];
|
|
25
|
+
if (isObject(value) && validObject(value)) {
|
|
26
|
+
if (Object.prototype.hasOwnProperty.call(target, prop) && isObject(target[prop])) target[prop] = assign({}, target[prop], value);
|
|
27
|
+
else target[prop] = assign({}, value);
|
|
28
|
+
} else if (Array.isArray(value)) target[prop] = value.slice();
|
|
29
|
+
else target[prop] = value;
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
for(var _len = arguments.length, objects = new Array(_len), _key = 0; _key < _len; _key++){
|
|
33
|
+
objects[_key] = arguments[_key];
|
|
34
|
+
}
|
|
35
|
+
var target = objects[0];
|
|
36
|
+
for(var i = 1; i < objects.length; i++)_loop(i);
|
|
37
|
+
return target;
|
|
38
|
+
}
|
|
39
|
+
export default assign;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@function attrize
|
|
3
|
+
@desc Applies each key/value in an object as an attr.
|
|
4
|
+
@param {D3selection} elem The D3 element to apply the styles to.
|
|
5
|
+
@param {Object} attrs An object of key/value attr pairs.
|
|
6
|
+
*/ export default function(e) {
|
|
7
|
+
var a = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
|
|
8
|
+
for(var k in a)if (({}).hasOwnProperty.call(a, k)) e.attr(k, a[k]);
|
|
9
|
+
}
|
package/es/src/date.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@function date
|
|
3
|
+
@summary Parses numbers and strings to valid Javascript Date objects.
|
|
4
|
+
@description Returns a javascript Date object for a given a Number (representing either a 4-digit year or milliseconds since epoch), a String representing a Quarter (ie. "Q2 1987", mapping to the last day in that quarter), or a String that is in [valid dateString format](http://dygraphs.com/date-formats.html). Besides the 4-digit year parsing, this function is useful when needing to parse negative (BC) years, which the vanilla Date object cannot parse.
|
|
5
|
+
@param {Number|String} *date*
|
|
6
|
+
*/ export default function(d) {
|
|
7
|
+
// returns if falsey or already Date object
|
|
8
|
+
if ([
|
|
9
|
+
false,
|
|
10
|
+
undefined,
|
|
11
|
+
NaN
|
|
12
|
+
].includes(d) || d.constructor === Date) return d;
|
|
13
|
+
else if (d.constructor === Number && "".concat(d).length > 5 && d % 1 === 0) return new Date(d);
|
|
14
|
+
var s = "".concat(d);
|
|
15
|
+
// tests for MM/DD/YYYY and MM-DD-YYYY format
|
|
16
|
+
var dayFormat = new RegExp(/^\d{1,2}[./-]\d{1,2}[./-](-*\d{1,4})$/g).exec(s);
|
|
17
|
+
if (dayFormat) {
|
|
18
|
+
var year = dayFormat[1];
|
|
19
|
+
if (year.indexOf("-") === 0) s = s.replace(year, year.substring(1));
|
|
20
|
+
var date = new Date(s);
|
|
21
|
+
date.setFullYear(year);
|
|
22
|
+
return date;
|
|
23
|
+
}
|
|
24
|
+
// tests for full Date object string format
|
|
25
|
+
var strFormat = new RegExp(/^[A-z]{1,3} [A-z]{1,3} \d{1,2} (-*\d{1,4}) \d{1,2}:\d{1,2}:\d{1,2} [A-z]{1,3}-*\d{1,4} \([A-z]{1,3}\)/g).exec(s);
|
|
26
|
+
if (strFormat) {
|
|
27
|
+
var year1 = strFormat[1];
|
|
28
|
+
if (year1.indexOf("-") === 0) s = s.replace(year1, year1.substring(1));
|
|
29
|
+
var date1 = new Date(s);
|
|
30
|
+
date1.setFullYear(year1);
|
|
31
|
+
return date1;
|
|
32
|
+
}
|
|
33
|
+
// tests for quarterly formats (ie. "QX YYYY")
|
|
34
|
+
var quarterPrefix = new RegExp(/^([qQ]{1}[1-4]{1}|[1-4]{1}[qQ]{1})[\s|-]{0,1}(-*\d{1,4})$/g).exec(s);
|
|
35
|
+
var quarterSuffix = new RegExp(/^(-*\d{1,4})[\s|-]{0,1}([qQ]{1}[1-4]{1}|[1-4]{1}[qQ]{1})$/g).exec(s);
|
|
36
|
+
if (quarterPrefix || quarterSuffix) {
|
|
37
|
+
var quarter = +(quarterPrefix ? quarterPrefix[1] : quarterSuffix[2]).toLowerCase().replace("q", "");
|
|
38
|
+
var year2 = +(quarterPrefix ? quarterPrefix[2] : quarterSuffix[1]);
|
|
39
|
+
var date2 = new Date(year2, quarter * 3 - 3, 1);
|
|
40
|
+
date2.setFullYear(year2);
|
|
41
|
+
return date2;
|
|
42
|
+
}
|
|
43
|
+
// detects if only passing a year value
|
|
44
|
+
if (!s.includes("/") && !s.includes(" ") && (!s.includes("-") || !s.indexOf("-"))) {
|
|
45
|
+
var date3 = new Date(+s, 0, 1);
|
|
46
|
+
date3.setFullYear(d);
|
|
47
|
+
return date3;
|
|
48
|
+
}
|
|
49
|
+
// falls back to Date object
|
|
50
|
+
return new Date(s);
|
|
51
|
+
}
|
package/es/src/elem.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { select } from "d3-selection";
|
|
2
|
+
import { transition } from "d3-transition";
|
|
3
|
+
import { default as attrize } from "./attrize.js";
|
|
4
|
+
/**
|
|
5
|
+
@function elem
|
|
6
|
+
@desc Manages the enter/update/exit pattern for a single DOM element.
|
|
7
|
+
@param {String} selector A D3 selector, which must include the tagname and a class and/or ID.
|
|
8
|
+
@param {Object} params Additional parameters.
|
|
9
|
+
@param {Boolean} [params.condition = true] Whether or not the element should be rendered (or removed).
|
|
10
|
+
@param {Object} [params.enter = {}] A collection of key/value pairs that map to attributes to be given on enter.
|
|
11
|
+
@param {Object} [params.exit = {}] A collection of key/value pairs that map to attributes to be given on exit.
|
|
12
|
+
@param {D3Selection} [params.parent = d3.select("body")] The parent element for this new element to be appended to.
|
|
13
|
+
@param {Number} [params.duration = 0] The duration for the d3 transition.
|
|
14
|
+
@param {Object} [params.update = {}] A collection of key/value pairs that map to attributes to be given on update.
|
|
15
|
+
*/ export default function(selector, p) {
|
|
16
|
+
// overrides default params
|
|
17
|
+
p = Object.assign({}, {
|
|
18
|
+
condition: true,
|
|
19
|
+
enter: {},
|
|
20
|
+
exit: {},
|
|
21
|
+
duration: 0,
|
|
22
|
+
parent: select("body"),
|
|
23
|
+
update: {}
|
|
24
|
+
}, p);
|
|
25
|
+
var className = /\.([^#]+)/g.exec(selector), id = /#([^.]+)/g.exec(selector), t = transition().duration(p.duration), tag = /^([^.^#]+)/g.exec(selector)[1];
|
|
26
|
+
var elem = p.parent.selectAll(selector.includes(":") ? selector.split(":")[1] : selector).data(p.condition ? [
|
|
27
|
+
null
|
|
28
|
+
] : []);
|
|
29
|
+
var enter = elem.enter().append(tag).call(attrize, p.enter);
|
|
30
|
+
if (id) enter.attr("id", id[1]);
|
|
31
|
+
if (className) enter.attr("class", className[1]);
|
|
32
|
+
if (p.duration) elem.exit().transition(t).call(attrize, p.exit).remove();
|
|
33
|
+
else elem.exit().call(attrize, p.exit).remove();
|
|
34
|
+
var update = enter.merge(elem);
|
|
35
|
+
if (p.duration) update.transition(t).call(attrize, p.update);
|
|
36
|
+
else update.call(attrize, p.update);
|
|
37
|
+
return update;
|
|
38
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
function _instanceof(left, right) {
|
|
2
|
+
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
|
3
|
+
return !!right[Symbol.hasInstance](left);
|
|
4
|
+
} else {
|
|
5
|
+
return left instanceof right;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
import { default as textWidth } from "./textWidth.js";
|
|
9
|
+
import { trim } from "@d3plus/text";
|
|
10
|
+
var alpha = "abcdefghiABCDEFGHI_!@#$%^&*()_+1234567890", checked = {}, height = 32;
|
|
11
|
+
var dejavu, macos, monospace, proportional;
|
|
12
|
+
/**
|
|
13
|
+
@function fontExists
|
|
14
|
+
@desc Given either a single font-family or a list of fonts, returns the name of the first font that can be rendered, or `false` if none are installed on the user's machine.
|
|
15
|
+
@param {String|Array} font Can be either a valid CSS font-family string (single or comma-separated names) or an Array of string names.
|
|
16
|
+
*/ var fontExists = function(font) {
|
|
17
|
+
if (!dejavu) {
|
|
18
|
+
dejavu = textWidth(alpha, {
|
|
19
|
+
"font-family": "DejaVuSans",
|
|
20
|
+
"font-size": height
|
|
21
|
+
});
|
|
22
|
+
macos = textWidth(alpha, {
|
|
23
|
+
"font-family": "-apple-system",
|
|
24
|
+
"font-size": height
|
|
25
|
+
});
|
|
26
|
+
monospace = textWidth(alpha, {
|
|
27
|
+
"font-family": "monospace",
|
|
28
|
+
"font-size": height
|
|
29
|
+
});
|
|
30
|
+
proportional = textWidth(alpha, {
|
|
31
|
+
"font-family": "sans-serif",
|
|
32
|
+
"font-size": height
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
if (!_instanceof(font, Array)) font = font.split(",");
|
|
36
|
+
font = font.map(function(f) {
|
|
37
|
+
return trim(f);
|
|
38
|
+
});
|
|
39
|
+
for(var i = 0; i < font.length; i++){
|
|
40
|
+
var fam = font[i];
|
|
41
|
+
if (checked[fam] || [
|
|
42
|
+
"-apple-system",
|
|
43
|
+
"monospace",
|
|
44
|
+
"sans-serif",
|
|
45
|
+
"DejaVuSans"
|
|
46
|
+
].includes(fam)) return fam;
|
|
47
|
+
else if (checked[fam] === false) continue;
|
|
48
|
+
var width = textWidth(alpha, {
|
|
49
|
+
"font-family": fam,
|
|
50
|
+
"font-size": height
|
|
51
|
+
});
|
|
52
|
+
checked[fam] = width !== monospace;
|
|
53
|
+
if (checked[fam]) checked[fam] = width !== proportional;
|
|
54
|
+
if (macos && checked[fam]) checked[fam] = width !== macos;
|
|
55
|
+
if (dejavu && checked[fam]) checked[fam] = width !== dejavu;
|
|
56
|
+
if (checked[fam]) return fam;
|
|
57
|
+
}
|
|
58
|
+
return false;
|
|
59
|
+
};
|
|
60
|
+
export default fontExists;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { select } from "d3-selection";
|
|
2
|
+
/**
|
|
3
|
+
@desc Given an HTMLElement and a "width" or "height" string, this function returns the current calculated size for the DOM element.
|
|
4
|
+
@private
|
|
5
|
+
*/ function _elementSize(element, s) {
|
|
6
|
+
if (!element) return undefined;
|
|
7
|
+
if (element.tagName === undefined || [
|
|
8
|
+
"BODY",
|
|
9
|
+
"HTML"
|
|
10
|
+
].indexOf(element.tagName) >= 0) {
|
|
11
|
+
var val = window["inner".concat(s.charAt(0).toUpperCase() + s.slice(1))];
|
|
12
|
+
var elem = select(element);
|
|
13
|
+
if (s === "width") {
|
|
14
|
+
val -= parseFloat(elem.style("margin-left"), 10);
|
|
15
|
+
val -= parseFloat(elem.style("margin-right"), 10);
|
|
16
|
+
val -= parseFloat(elem.style("padding-left"), 10);
|
|
17
|
+
val -= parseFloat(elem.style("padding-right"), 10);
|
|
18
|
+
} else {
|
|
19
|
+
val -= parseFloat(elem.style("margin-top"), 10);
|
|
20
|
+
val -= parseFloat(elem.style("margin-bottom"), 10);
|
|
21
|
+
val -= parseFloat(elem.style("padding-top"), 10);
|
|
22
|
+
val -= parseFloat(elem.style("padding-bottom"), 10);
|
|
23
|
+
}
|
|
24
|
+
return val;
|
|
25
|
+
} else {
|
|
26
|
+
var val1 = parseFloat(select(element).style(s), 10);
|
|
27
|
+
if (typeof val1 === "number" && val1 > 0) return val1;
|
|
28
|
+
else return _elementSize(element.parentNode, s);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
@function getSize
|
|
33
|
+
@desc Finds the available width and height for a specified HTMLElement, traversing it's parents until it finds something with constrained dimensions. Falls back to the inner dimensions of the browser window if none is found.
|
|
34
|
+
@param {HTMLElement} elem The HTMLElement to find dimensions for.
|
|
35
|
+
@private
|
|
36
|
+
*/ export default function(elem) {
|
|
37
|
+
return [
|
|
38
|
+
_elementSize(elem, "width"),
|
|
39
|
+
_elementSize(elem, "height")
|
|
40
|
+
];
|
|
41
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@module inViewport
|
|
3
|
+
@desc Returns a *Boolean* denoting whether or not a given DOM element is visible in the current window.
|
|
4
|
+
@param {DOMElement} elem The DOM element to analyze.
|
|
5
|
+
@param {Number} [buffer = 0] A pixel offset from the edge of the top and bottom of the screen. If a positive value, the element will be deemed visible when it is that many pixels away from entering the viewport. If negative, the element will have to enter the viewport by that many pixels before being deemed visible.
|
|
6
|
+
@private
|
|
7
|
+
*/ export default function(elem) {
|
|
8
|
+
var buffer = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 0;
|
|
9
|
+
var pageX = window.pageXOffset !== undefined ? window.pageXOffset : (document.documentElement || document.body.parentNode || document.body).scrollLeft;
|
|
10
|
+
var pageY = window.pageYOffset !== undefined ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
|
|
11
|
+
var bounds = elem.getBoundingClientRect();
|
|
12
|
+
var height = bounds.height, left = bounds.left + pageX, top = bounds.top + pageY, width = bounds.width;
|
|
13
|
+
return pageY + window.innerHeight > top + buffer && pageY + buffer < top + height && pageX + window.innerWidth > left + buffer && pageX + buffer < left + width;
|
|
14
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@function isObject
|
|
3
|
+
@desc Detects if a variable is a javascript Object.
|
|
4
|
+
@param {*} item
|
|
5
|
+
*/ function _instanceof(left, right) {
|
|
6
|
+
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
|
7
|
+
return !!right[Symbol.hasInstance](left);
|
|
8
|
+
} else {
|
|
9
|
+
return left instanceof right;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function _type_of(obj) {
|
|
13
|
+
"@swc/helpers - typeof";
|
|
14
|
+
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
15
|
+
}
|
|
16
|
+
export default function(item) {
|
|
17
|
+
return item && (typeof item === "undefined" ? "undefined" : _type_of(item)) === "object" && (typeof window === "undefined" || item !== window && item !== window.document && !_instanceof(item, Element)) && !Array.isArray(item) ? true : false;
|
|
18
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@function parseSides
|
|
3
|
+
@desc Converts a string of directional CSS shorthand values into an object with the values expanded.
|
|
4
|
+
@param {String|Number} sides The CSS shorthand string to expand.
|
|
5
|
+
*/ export default function(sides) {
|
|
6
|
+
var values;
|
|
7
|
+
if (typeof sides === "number") values = [
|
|
8
|
+
sides
|
|
9
|
+
];
|
|
10
|
+
else values = sides.split(/\s+/);
|
|
11
|
+
if (values.length === 1) values = [
|
|
12
|
+
values[0],
|
|
13
|
+
values[0],
|
|
14
|
+
values[0],
|
|
15
|
+
values[0]
|
|
16
|
+
];
|
|
17
|
+
else if (values.length === 2) values = values.concat(values);
|
|
18
|
+
else if (values.length === 3) values.push(values[1]);
|
|
19
|
+
return [
|
|
20
|
+
"top",
|
|
21
|
+
"right",
|
|
22
|
+
"bottom",
|
|
23
|
+
"left"
|
|
24
|
+
].reduce(function(acc, direction, i) {
|
|
25
|
+
var value = parseFloat(values[i]);
|
|
26
|
+
acc[direction] = value || 0;
|
|
27
|
+
return acc;
|
|
28
|
+
}, {});
|
|
29
|
+
}
|
package/es/src/prefix.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@function prefix
|
|
3
|
+
@desc Returns the appropriate CSS vendor prefix, given the current browser.
|
|
4
|
+
*/ export default function() {
|
|
5
|
+
if ("-webkit-transform" in document.body.style) return "-webkit-";
|
|
6
|
+
else if ("-moz-transform" in document.body.style) return "-moz-";
|
|
7
|
+
else if ("-ms-transform" in document.body.style) return "-ms-";
|
|
8
|
+
else if ("-o-transform" in document.body.style) return "-o-";
|
|
9
|
+
else return "";
|
|
10
|
+
}
|
package/es/src/rtl.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { select } from "d3-selection";
|
|
2
|
+
/**
|
|
3
|
+
@function rtl
|
|
4
|
+
@desc Returns `true` if the HTML or body element has either the "dir" HTML attribute or the "direction" CSS property set to "rtl".
|
|
5
|
+
*/ export default function() {
|
|
6
|
+
return select("html").attr("dir") === "rtl" || select("body").attr("dir") === "rtl" || select("html").style("direction") === "rtl" || select("body").style("direction") === "rtl";
|
|
7
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@function stylize
|
|
3
|
+
@desc Applies each key/value in an object as a style.
|
|
4
|
+
@param {D3selection} elem The D3 element to apply the styles to.
|
|
5
|
+
@param {Object} styles An object of key/value style pairs.
|
|
6
|
+
*/ export default function(e) {
|
|
7
|
+
var s = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
|
|
8
|
+
for(var k in s)if (({}).hasOwnProperty.call(s, k)) e.style(k, s[k]);
|
|
9
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Strips HTML and "un-escapes" escape characters.
|
|
3
|
+
* @param {String} input
|
|
4
|
+
*/ function _instanceof(left, right) {
|
|
5
|
+
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
|
6
|
+
return !!right[Symbol.hasInstance](left);
|
|
7
|
+
} else {
|
|
8
|
+
return left instanceof right;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
function htmlDecode(input) {
|
|
12
|
+
if (input.replace(/\s+/g, "") === "") return input;
|
|
13
|
+
var doc = new DOMParser().parseFromString(input.replace(/<[^>]+>/g, ""), "text/html");
|
|
14
|
+
return doc.documentElement ? doc.documentElement.textContent : input;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
@function textWidth
|
|
18
|
+
@desc Given a text string, returns the predicted pixel width of the string when placed into DOM.
|
|
19
|
+
@param {String|Array} text Can be either a single string or an array of strings to analyze.
|
|
20
|
+
@param {Object} [style] An object of CSS font styles to apply. Accepts any of the valid [CSS font property](http://www.w3schools.com/cssref/pr_font_font.asp) values.
|
|
21
|
+
*/ export default function(text, style) {
|
|
22
|
+
style = Object.assign({
|
|
23
|
+
"font-size": 10,
|
|
24
|
+
"font-family": "sans-serif",
|
|
25
|
+
"font-style": "normal",
|
|
26
|
+
"font-weight": 400,
|
|
27
|
+
"font-variant": "normal"
|
|
28
|
+
}, style);
|
|
29
|
+
var context = document.createElement("canvas").getContext("2d");
|
|
30
|
+
var font = [];
|
|
31
|
+
font.push(style["font-style"]);
|
|
32
|
+
font.push(style["font-variant"]);
|
|
33
|
+
font.push(style["font-weight"]);
|
|
34
|
+
font.push(typeof style["font-size"] === "string" ? style["font-size"] : "".concat(style["font-size"], "px"));
|
|
35
|
+
font.push(style["font-family"]);
|
|
36
|
+
context.font = font.join(" ");
|
|
37
|
+
if (_instanceof(text, Array)) return text.map(function(t) {
|
|
38
|
+
return context.measureText(htmlDecode(t)).width;
|
|
39
|
+
});
|
|
40
|
+
return context.measureText(htmlDecode(text)).width;
|
|
41
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@d3plus/dom",
|
|
3
|
+
"version": "3.0.0-alpha.0",
|
|
4
|
+
"description": "JavaScript functions for manipulating and analyzing DOM elements.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"exports": "./es/index.js",
|
|
8
|
+
"browser": "./umd/d3plus-dom.full.js",
|
|
9
|
+
"engines": {
|
|
10
|
+
"node": ">=18"
|
|
11
|
+
},
|
|
12
|
+
"sideEffects": false,
|
|
13
|
+
"files": [
|
|
14
|
+
"umd",
|
|
15
|
+
"es"
|
|
16
|
+
],
|
|
17
|
+
"homepage": "https://d3plus.org",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/d3plus/d3plus.git",
|
|
21
|
+
"directory": "packages/dom"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"dom",
|
|
25
|
+
"d3",
|
|
26
|
+
"d3plus",
|
|
27
|
+
"data",
|
|
28
|
+
"visualization"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build:esm": "node ../../scripts/build-esm.js",
|
|
32
|
+
"build:umd": "node ../../scripts/build-umd.js",
|
|
33
|
+
"dev": "node ../../scripts/dev.js",
|
|
34
|
+
"test": "eslint index.js src/**/*.js && eslint --global=it test && mocha 'test/**/*-test.js'"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"d3-selection": "^3.0.0",
|
|
38
|
+
"d3-transition": "^3.0.1"
|
|
39
|
+
}
|
|
40
|
+
}
|