bruh 1.9.2-types.0 → 1.10.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 +0 -2
- package/dist/bruh.es.js +113 -164
- package/dist/bruh.es.js.map +1 -1
- package/dist/bruh.umd.js +1 -1
- package/dist/bruh.umd.js.map +1 -1
- package/package.json +5 -13
- package/src/dom/index.browser.mjs +116 -175
- package/src/dom/index.node.mjs +149 -127
- package/src/reactive/index.mjs +2 -4
- package/src/util/index.mjs +0 -14
- package/src/dom/index.browser.d.ts +0 -113
- package/src/reactive/index.d.ts +0 -36
package/package.json
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"library",
|
|
11
11
|
"modern"
|
|
12
12
|
],
|
|
13
|
-
"version": "1.
|
|
13
|
+
"version": "1.10.0",
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"author": {
|
|
16
16
|
"name": "Daniel Ethridge",
|
|
@@ -50,18 +50,10 @@
|
|
|
50
50
|
"prepare": "npm run build"
|
|
51
51
|
},
|
|
52
52
|
"optionalDependencies": {
|
|
53
|
-
"cac": "^6.7.
|
|
54
|
-
"sharp": "^0.
|
|
53
|
+
"cac": "^6.7.11",
|
|
54
|
+
"sharp": "^0.29.2"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"vite": "^2.
|
|
58
|
-
}
|
|
59
|
-
"browserslist": [
|
|
60
|
-
"ios_saf >= 12.4",
|
|
61
|
-
"and_chr >= 88",
|
|
62
|
-
"chrome >= 87",
|
|
63
|
-
"safari >= 13.1",
|
|
64
|
-
"edge >= 87",
|
|
65
|
-
"firefox >= 84"
|
|
66
|
-
]
|
|
57
|
+
"vite": "^2.6.10"
|
|
58
|
+
}
|
|
67
59
|
}
|
|
@@ -1,19 +1,12 @@
|
|
|
1
|
-
/** @typedef { import("./index.browser") } */
|
|
2
|
-
|
|
3
1
|
import { LiveFragment } from "./live-fragment.mjs"
|
|
4
|
-
import { reactiveDo } from "../reactive/index.mjs"
|
|
5
|
-
import { maybeDo } from "../util/index.mjs"
|
|
2
|
+
import { isReactive, reactiveDo } from "../reactive/index.mjs"
|
|
6
3
|
|
|
7
|
-
|
|
8
|
-
const isMetaNode = Symbol.for("bruh meta node")
|
|
9
|
-
const isMetaTextNode = Symbol.for("bruh meta text node")
|
|
10
|
-
const isMetaElement = Symbol.for("bruh meta element")
|
|
4
|
+
//#region Bruh child functions e.g. bruhChildrenToNodes()
|
|
11
5
|
|
|
12
|
-
// A basic check for if a value is allowed as a
|
|
6
|
+
// A basic check for if a value is allowed as a child in bruh
|
|
13
7
|
// It's responsible for quickly checking the type, not deep validation
|
|
14
|
-
const
|
|
15
|
-
//
|
|
16
|
-
x?.[isMetaNode] ||
|
|
8
|
+
const isBruhChild = x =>
|
|
9
|
+
// Reactives and DOM nodes
|
|
17
10
|
x?.[isReactive] ||
|
|
18
11
|
x instanceof Node ||
|
|
19
12
|
// Any array, just assume it contains valid children
|
|
@@ -24,31 +17,33 @@ const isMetaNodeChild = x =>
|
|
|
24
17
|
!(typeof x === "function" || typeof x === "object")
|
|
25
18
|
// Everything else can be a child when stringified
|
|
26
19
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
return x
|
|
33
|
-
|
|
34
|
-
return document.createTextNode(x)
|
|
35
|
-
}
|
|
20
|
+
// Coerces input into a DOM node, if it isn't already one
|
|
21
|
+
const toNode = x =>
|
|
22
|
+
x instanceof Node
|
|
23
|
+
? x
|
|
24
|
+
: document.createTextNode(x)
|
|
36
25
|
|
|
37
|
-
|
|
26
|
+
// Processes bruh children into an array of DOM nodes
|
|
27
|
+
// Reactive values are automatically replaced, so the output must be placed into a parent node
|
|
28
|
+
// before any top level (after flattening arrays) reactions run
|
|
29
|
+
export const bruhChildrenToNodes = (...children) =>
|
|
38
30
|
children
|
|
39
31
|
.flat(Infinity)
|
|
40
32
|
.flatMap(child => {
|
|
33
|
+
// Non-reactive values are untouched
|
|
41
34
|
if (!child[isReactive])
|
|
42
35
|
return [toNode(child)]
|
|
43
36
|
|
|
37
|
+
// Reactive arrays become live fragments with auto-swapped children
|
|
44
38
|
if (Array.isArray(child.value)) {
|
|
45
39
|
const liveFragment = new LiveFragment()
|
|
46
40
|
child.addReaction(() => {
|
|
47
|
-
liveFragment.replaceChildren(...
|
|
41
|
+
liveFragment.replaceChildren(...bruhChildrenToNodes(...child.value))
|
|
48
42
|
})
|
|
49
|
-
return [liveFragment.startMarker, ...
|
|
43
|
+
return [liveFragment.startMarker, ...bruhChildrenToNodes(...child.value), liveFragment.endMarker]
|
|
50
44
|
}
|
|
51
45
|
|
|
46
|
+
// Reactive values become auto-swapped DOM nodes
|
|
52
47
|
let node = toNode(child.value)
|
|
53
48
|
child.addReaction(() => {
|
|
54
49
|
const oldNode = node
|
|
@@ -58,134 +53,129 @@ export const childrenToNodes = children =>
|
|
|
58
53
|
return [node]
|
|
59
54
|
})
|
|
60
55
|
|
|
56
|
+
//#endregion
|
|
61
57
|
|
|
58
|
+
//#region Reactive-aware element helper functions e.g. applyAttributes()
|
|
62
59
|
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
-
export
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if (!textContent[isReactive]) {
|
|
73
|
-
this.node = document.createTextNode(textContent)
|
|
74
|
-
return
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
this.node = document.createTextNode(textContent.value)
|
|
78
|
-
textContent.addReaction(() => {
|
|
79
|
-
this.node.textContent = textContent.value
|
|
60
|
+
// Style attribute rules from an object with
|
|
61
|
+
// potentially reactive and/or undefined values
|
|
62
|
+
export const applyStyles = (element, styles) => {
|
|
63
|
+
for (const property in styles)
|
|
64
|
+
reactiveDo(styles[property], value => {
|
|
65
|
+
if (value !== undefined)
|
|
66
|
+
element.style.setProperty (property, value)
|
|
67
|
+
else
|
|
68
|
+
element.style.removeProperty(property)
|
|
80
69
|
})
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
addProperties(properties = {}) {
|
|
84
|
-
Object.assign(this.node, properties)
|
|
85
|
-
|
|
86
|
-
return this
|
|
87
|
-
}
|
|
88
70
|
}
|
|
89
71
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
namespace
|
|
99
|
-
? document.createElementNS(namespace, name)
|
|
100
|
-
: document.createElement ( name)
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
static from(element) {
|
|
104
|
-
const result = new this("div")
|
|
105
|
-
result.node = element
|
|
106
|
-
return result
|
|
107
|
-
}
|
|
72
|
+
// Class list from an object mapping from
|
|
73
|
+
// class names to potentially reactive booleans
|
|
74
|
+
export const applyClasses = (element, classes) => {
|
|
75
|
+
for (const name in classes)
|
|
76
|
+
reactiveDo(classes[name], value => {
|
|
77
|
+
element.classList.toggle(name, value)
|
|
78
|
+
})
|
|
79
|
+
}
|
|
108
80
|
|
|
109
|
-
|
|
110
|
-
|
|
81
|
+
// Attributes from an object with
|
|
82
|
+
// potentially reactive and/or undefined values
|
|
83
|
+
export const applyAttributes = (element, attributes) => {
|
|
84
|
+
for (const name in attributes)
|
|
85
|
+
reactiveDo(attributes[name], value => {
|
|
86
|
+
if (value !== undefined)
|
|
87
|
+
element.setAttribute (name, value)
|
|
88
|
+
else
|
|
89
|
+
element.removeAttribute(name)
|
|
90
|
+
})
|
|
91
|
+
}
|
|
111
92
|
|
|
112
|
-
|
|
113
|
-
}
|
|
93
|
+
//#endregion
|
|
114
94
|
|
|
115
|
-
|
|
116
|
-
for (const name in attributes)
|
|
117
|
-
reactiveDo(attributes[name],
|
|
118
|
-
maybeDo(
|
|
119
|
-
value => this.node.setAttribute (name, value),
|
|
120
|
-
() => this.node.removeAttribute(name)
|
|
121
|
-
)
|
|
122
|
-
)
|
|
95
|
+
//#region t() for text nodes and e() for element nodes
|
|
123
96
|
|
|
124
|
-
|
|
125
|
-
|
|
97
|
+
// Text nodes
|
|
98
|
+
export const t = textContent => {
|
|
99
|
+
// Non-reactive values are just text nodes
|
|
100
|
+
if (!textContent[isReactive])
|
|
101
|
+
return document.createTextNode(textContent)
|
|
126
102
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
)
|
|
103
|
+
// Reactive values auto-update the node's text content
|
|
104
|
+
const node = document.createTextNode(textContent.value)
|
|
105
|
+
textContent.addReaction(() => {
|
|
106
|
+
node.textContent = textContent.value
|
|
107
|
+
})
|
|
108
|
+
return node
|
|
109
|
+
}
|
|
135
110
|
|
|
136
|
-
|
|
111
|
+
// Elements
|
|
112
|
+
export const e = name => (...variadic) => {
|
|
113
|
+
// If there are no props
|
|
114
|
+
if (isBruhChild(variadic[0])) {
|
|
115
|
+
const element = document.createElement(name)
|
|
116
|
+
element.append(...bruhChildrenToNodes(...variadic))
|
|
117
|
+
return element
|
|
137
118
|
}
|
|
138
119
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
reactiveDo(styles[property],
|
|
142
|
-
maybeDo(
|
|
143
|
-
value => this.node.style.setProperty (property, value),
|
|
144
|
-
() => this.node.style.removeProperty(property)
|
|
145
|
-
)
|
|
146
|
-
)
|
|
120
|
+
// If props exist as the first variadic argument
|
|
121
|
+
const [props, ...children] = variadic
|
|
147
122
|
|
|
148
|
-
|
|
149
|
-
}
|
|
123
|
+
// Extract explicit options from the bruh prop
|
|
124
|
+
const { namespace } = props.bruh ?? {}
|
|
125
|
+
delete props.bruh
|
|
150
126
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
)
|
|
127
|
+
// Make an element with optional namespace
|
|
128
|
+
const element =
|
|
129
|
+
namespace
|
|
130
|
+
? document.createElementNS(namespace, name)
|
|
131
|
+
: document.createElement ( name)
|
|
156
132
|
|
|
157
|
-
|
|
133
|
+
// Apply overloaded props, if possible
|
|
134
|
+
if (typeof props.style === "object") {
|
|
135
|
+
applyStyles(element, props.style)
|
|
136
|
+
delete props.style
|
|
158
137
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
138
|
+
if (typeof props.class === "object") {
|
|
139
|
+
applyClasses(element, props.class)
|
|
140
|
+
delete props.class
|
|
162
141
|
}
|
|
142
|
+
// The rest of the props are attributes
|
|
143
|
+
applyAttributes(element, props)
|
|
163
144
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
145
|
+
// Add the children to the element
|
|
146
|
+
element.append(...bruhChildrenToNodes(...children))
|
|
147
|
+
return element
|
|
148
|
+
}
|
|
167
149
|
|
|
168
|
-
|
|
169
|
-
this.node.append(...childrenToNodes(xs))
|
|
170
|
-
}
|
|
150
|
+
//#endregion
|
|
171
151
|
|
|
172
|
-
|
|
173
|
-
this.node.after(...childrenToNodes(xs))
|
|
174
|
-
}
|
|
152
|
+
//#region JSX integration
|
|
175
153
|
|
|
176
|
-
|
|
177
|
-
|
|
154
|
+
// The function that jsx tags (except fragments) compile to
|
|
155
|
+
export const h = (nameOrComponent, props, ...children) => {
|
|
156
|
+
// If we are making an element, this is just a wrapper of e()
|
|
157
|
+
// This is likely when the JSX tag name begins with a lowercase character
|
|
158
|
+
if (typeof nameOrComponent === "string") {
|
|
159
|
+
const makeElement = e(nameOrComponent)
|
|
160
|
+
return props
|
|
161
|
+
? makeElement(props, ...children)
|
|
162
|
+
: makeElement(...children)
|
|
178
163
|
}
|
|
179
164
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
165
|
+
// It must be a component, then, as bruh components are just functions
|
|
166
|
+
// Due to JSX, this would mean a function with only one parameter - props
|
|
167
|
+
// This object includes the all of the normal props and a "children" key
|
|
168
|
+
return nameOrComponent({ ...props, children })
|
|
183
169
|
}
|
|
184
170
|
|
|
171
|
+
// The JSX fragment is made into a bruh fragment (just an array)
|
|
172
|
+
export const JSXFragment = ({ children }) => children
|
|
185
173
|
|
|
174
|
+
//#endregion
|
|
186
175
|
|
|
187
|
-
// Convenience functions
|
|
188
176
|
|
|
177
|
+
|
|
178
|
+
// Hydration of all bruh-textnode's from prerendered html
|
|
189
179
|
export const hydrateTextNodes = () => {
|
|
190
180
|
const tagged = {}
|
|
191
181
|
const bruhTextNodes = document.getElementsByTagName("bruh-textnode")
|
|
@@ -193,61 +183,12 @@ export const hydrateTextNodes = () => {
|
|
|
193
183
|
for (const bruhTextNode of bruhTextNodes) {
|
|
194
184
|
const textNode = document.createTextNode(bruhTextNode.textContent)
|
|
195
185
|
|
|
196
|
-
|
|
197
|
-
|
|
186
|
+
const tag = bruhTextNode.getAttribute("tag")
|
|
187
|
+
if (tag)
|
|
188
|
+
tagged[tag] = textNode
|
|
198
189
|
|
|
199
190
|
bruhTextNode.replaceWith(textNode)
|
|
200
191
|
}
|
|
201
192
|
|
|
202
193
|
return tagged
|
|
203
194
|
}
|
|
204
|
-
|
|
205
|
-
const createMetaTextNode = textContent =>
|
|
206
|
-
new MetaTextNode(textContent)
|
|
207
|
-
|
|
208
|
-
const createMetaElement = (name, namespace) => (...variadic) => {
|
|
209
|
-
const meta = new MetaElement(name, namespace)
|
|
210
|
-
|
|
211
|
-
// Implement optional attributes as first argument
|
|
212
|
-
if (!isMetaNodeChild(variadic[0])) {
|
|
213
|
-
const [attributes, ...children] = variadic
|
|
214
|
-
meta.addAttributes(attributes)
|
|
215
|
-
meta.append(children)
|
|
216
|
-
}
|
|
217
|
-
else {
|
|
218
|
-
meta.append(variadic)
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
return meta
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// JSX integration
|
|
225
|
-
const createMetaElementJSX = (nameOrComponent, attributesOrProps, ...children) => {
|
|
226
|
-
// If we are making a html element
|
|
227
|
-
// This is likely when the jsx tag name begins with a lowercase character
|
|
228
|
-
if (typeof nameOrComponent == "string") {
|
|
229
|
-
const meta = new MetaElement(nameOrComponent)
|
|
230
|
-
|
|
231
|
-
// These are attributes then, but they might be null/undefined
|
|
232
|
-
meta.addAttributes(attributesOrProps || {})
|
|
233
|
-
meta.append(children)
|
|
234
|
-
|
|
235
|
-
return meta
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// It must be a component, then
|
|
239
|
-
// Bruh components are just functions that return meta elements
|
|
240
|
-
// Due to JSX, this would mean a function with only one parameter - a "props" object
|
|
241
|
-
// This object includes the all of the attributes and a "children" key
|
|
242
|
-
return nameOrComponent( Object.assign({}, attributesOrProps, { children }) )
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
// These will be called with short names
|
|
246
|
-
export {
|
|
247
|
-
createMetaTextNode as t,
|
|
248
|
-
createMetaElement as e,
|
|
249
|
-
createMetaElementJSX as h
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
// The JSX fragment is made into a bruh fragment (just an array)
|
|
253
|
-
export const JSXFragment = ({ children }) => children
|