@litejs/dom 25.9.2 → 26.2.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 +3 -2
- package/css.js +87 -48
- package/dom.js +72 -31
- package/package.json +4 -2
- package/selector.js +5 -6
- package/types/index.d.ts +194 -0
package/README.md
CHANGED
|
@@ -51,9 +51,10 @@ xhr.onload = function() {
|
|
|
51
51
|
xhr.send();
|
|
52
52
|
|
|
53
53
|
// Minify CSS
|
|
54
|
-
|
|
54
|
+
import { CSS } from "@litejs/dom/css.js";
|
|
55
|
+
const sheet = new CSSStyleSheet()
|
|
55
56
|
sheet.replaceSync(".a { color: hsl(0 0% 100%) }")
|
|
56
|
-
console.log(
|
|
57
|
+
console.log(CSS.minify(sheet, { color: true }))
|
|
57
58
|
// .a{color:#fff}
|
|
58
59
|
```
|
|
59
60
|
|
package/css.js
CHANGED
|
@@ -6,18 +6,69 @@
|
|
|
6
6
|
exports.CSSStyleDeclaration = CSSStyleDeclaration
|
|
7
7
|
exports.CSSStyleSheet = CSSStyleSheet
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
,
|
|
9
|
+
/* c8 ignore next */
|
|
10
|
+
var URL = global.URL || require("url").URL
|
|
11
|
+
, varRe = /var\((--[^,)]+)(?:,([^)]+))?\)/g
|
|
12
|
+
, CSS = exports.CSS = {
|
|
13
|
+
escape(sel) {
|
|
14
|
+
return ("" + sel).replace(/[^a-zA-Z0-9_\u00A0-\uFFFF-]/g, "\\$&").replace(/^(-?)([0-9])/, "$1\\3$2 ")
|
|
15
|
+
},
|
|
16
|
+
minify(sheet, opts) {
|
|
17
|
+
var rules = sheet.cssRules || sheet.rules
|
|
18
|
+
, root = opts && opts.root || ""
|
|
19
|
+
, vars = opts && opts.var ? {} : null
|
|
20
|
+
, varFn = vars && function(_, n) { return vars[n] || _ }
|
|
21
|
+
return Array.prototype.map.call(rules, rule => {
|
|
22
|
+
if (vars && rule.selectorText === ":root") {
|
|
23
|
+
if (rule.style) for (var i = 0; i < rule.style.length; i++) {
|
|
24
|
+
var n = rule.style[i]
|
|
25
|
+
if (n.slice(0, 2) === "--") vars[n] = rule.style[n].replace(varRe, varFn)
|
|
26
|
+
}
|
|
27
|
+
return ""
|
|
28
|
+
}
|
|
29
|
+
// Handle @import inlining
|
|
30
|
+
if (opts && opts.import && rule.href) {
|
|
31
|
+
var imported = new CSSStyleSheet({
|
|
32
|
+
href: rule.href,
|
|
33
|
+
parentStyleSheet: sheet
|
|
34
|
+
}, read(root, rule.href, sheet.baseURI))
|
|
35
|
+
, urlFn = (m,q1,q2,u) => q1 ? m : "url('" + new URL(u, toUrl(imported.baseURI)).pathname.slice(1) + "')"
|
|
36
|
+
if (sheet.baseURI !== imported.baseURI) {
|
|
37
|
+
updateImportUrls(imported, urlFn)
|
|
38
|
+
}
|
|
39
|
+
return CSS.minify(imported, opts)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Handle plugins on style rules
|
|
43
|
+
if (rule.style && rule.style._plugins) {
|
|
44
|
+
for (var style = rule.style, j = 0; j < style._plugins.length; j++) {
|
|
45
|
+
var idx = style._plugins[j][0]
|
|
46
|
+
, pn = style._plugins[j][1]
|
|
47
|
+
, k = style[idx]
|
|
48
|
+
style[k] = clear(plugins[pn](root, sheet.baseURI, style[k]))
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
var text = clear(rule.cssText)
|
|
53
|
+
if (!text || /\{\s*\}$/.test(text)) return ""
|
|
54
|
+
if (vars) text = text.replace(varRe, (_, v, fb) => vars[v] || fb || _)
|
|
55
|
+
if (opts && opts.color) text = text.replace(colorRe, colorFn)
|
|
56
|
+
if (opts && opts.url) text = text.replace(urlRe, (m, q1, q2, u) => q1 ? m : "url(" + opts.url(u) + ")")
|
|
57
|
+
return text
|
|
58
|
+
}).filter(Boolean).join("\n")
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
, toUrl = (dir) => new URL((dir || ".").replace(/\/+$/, "") + "/", "file:///").href
|
|
62
|
+
, read = (root, url, baseURI, enc = "utf8") => require("fs").readFileSync(new URL(url, new URL((baseURI || ".") + "/", new URL((root || ".").replace(/\/+$/, "") + "/", "file:///" + process.cwd() + "/"))).pathname.split(/[+#]/)[0], enc)
|
|
12
63
|
, plugins = exports.plugins = {
|
|
13
|
-
"data-uri": function(
|
|
64
|
+
"data-uri": function(root, baseURI, v) {
|
|
14
65
|
var { DOMParser } = require("./dom.js")
|
|
15
66
|
return v.replace(urlRe, function(_, q1, q2, url) {
|
|
16
67
|
if (q1) return _
|
|
17
68
|
var frag = url.split("#")[1]
|
|
18
69
|
, ext = url.split(/[?#]/)[0].split(".").pop()
|
|
19
70
|
, enc = ext === "svg" ? "utf8" : "base64"
|
|
20
|
-
url = read(
|
|
71
|
+
url = read(root, url, baseURI, enc)
|
|
21
72
|
if (ext === "svg") {
|
|
22
73
|
url = new DOMParser().parseFromString(url, "application/xml")
|
|
23
74
|
if (frag && (frag = url.getElementById(frag))) {
|
|
@@ -37,12 +88,12 @@ var fs = require("fs")
|
|
|
37
88
|
q ? (q = str.indexOf("'") == -1 ? "'" : "\"", q + str.replace(q === "'" ? /\\(")/g : /\\(')/g, "$1")) + q :
|
|
38
89
|
c ? "" :
|
|
39
90
|
_.replace(/[\t\n]+/g, " ")
|
|
40
|
-
.replace(/
|
|
91
|
+
.replace(/ +(?=[,;{}>~+\/])/g, "").replace(/([,;{}>~+\/]) +/g, "$1")
|
|
41
92
|
.replace(/;(?=})/g, "")
|
|
42
93
|
.replace(/: +/g, ":")
|
|
43
94
|
.replace(/([ :,])0\.([0-9])/g, "$1.$2")
|
|
44
95
|
, clear = s => s
|
|
45
|
-
.replace(/("|')((
|
|
96
|
+
.replace(/("|')((?:\\.|[^\\\1])*?)\1|\s*(\/)\*(?:[^*]|\*(?!\/))*\*\/\s*|(?:[^"'\/]|\/(?!\*))+/g, clearFn)
|
|
46
97
|
.replace(/(["']).*?\1|url\(("|')([^'"()\s]+)\2\)/g, (m,q1,q2,u) => q1 ? m : "url(" + u + ")")
|
|
47
98
|
, hex = n => (0 | +n + 256.5).toString(16).slice(1)
|
|
48
99
|
, toRgb = {
|
|
@@ -63,29 +114,25 @@ var fs = require("fs")
|
|
|
63
114
|
, styleHandler = {
|
|
64
115
|
get(style, prop) {
|
|
65
116
|
if (prop === "cssText") {
|
|
66
|
-
var
|
|
67
|
-
|
|
68
|
-
|
|
117
|
+
for (var out = [], name, value, i = style.length; i--; ) {
|
|
118
|
+
name = style[i]
|
|
119
|
+
value = style.__[i] || style[name]
|
|
120
|
+
out[i] = name + ":" + value
|
|
69
121
|
}
|
|
70
122
|
return out.join(";")
|
|
71
123
|
}
|
|
72
124
|
return style[prop] || ""
|
|
73
|
-
function joinProp(name, value) {
|
|
74
|
-
if (min && min.color) value = value.replace(colorRe, colorFn)
|
|
75
|
-
return name + ":" + value
|
|
76
|
-
}
|
|
77
125
|
},
|
|
78
126
|
set(style, prop, val) {
|
|
79
127
|
if (prop === "cssText") {
|
|
80
128
|
var m, k
|
|
81
|
-
, sheet = style.parentRule && style.parentRule.parentStyleSheet
|
|
82
|
-
, min = sheet && sheet.min
|
|
83
129
|
, re = /([*_]?[-a-z]+)\s*:((?:("|')(?:\\.|(?!\3)[^\\])*?\3|[^"';])+)|\/\*!?((?:[^*]|\*(?!\/))*)\*\//ig
|
|
84
130
|
, len = 0
|
|
85
131
|
, lastIdx = {}
|
|
132
|
+
, _plugins = []
|
|
86
133
|
for (; (m = re.exec(val)); ) {
|
|
87
134
|
if (m[4]) {
|
|
88
|
-
if (
|
|
135
|
+
if (len && plugins[m[4] = m[4].trim()]) _plugins.push([len - 1, m[4]])
|
|
89
136
|
} else {
|
|
90
137
|
k = m[1]
|
|
91
138
|
if (lastIdx[k] >= 0) style.__[lastIdx[k]] = style[k]
|
|
@@ -95,6 +142,7 @@ var fs = require("fs")
|
|
|
95
142
|
}
|
|
96
143
|
}
|
|
97
144
|
style.length = len
|
|
145
|
+
if (_plugins.length) style._plugins = _plugins
|
|
98
146
|
} else {
|
|
99
147
|
if (!style[prop]) style[style.length++] = prop
|
|
100
148
|
style[prop] = style[prop === "cssFloat" ? "float" : prop.replace(/[A-Z]/g, "-$&").toLowerCase()] = clear(val)
|
|
@@ -116,26 +164,7 @@ var fs = require("fs")
|
|
|
116
164
|
},
|
|
117
165
|
import: {
|
|
118
166
|
get cssText() {
|
|
119
|
-
|
|
120
|
-
, min = sheet.min
|
|
121
|
-
, text = this.text
|
|
122
|
-
, urlFn = (m,q1,q2,u) => q1 ? m : "url('" + path.join(text.baseURI, u) + "')"
|
|
123
|
-
if (min && min.import) {
|
|
124
|
-
text = new CSSStyleSheet({
|
|
125
|
-
parentStyleSheet: sheet,
|
|
126
|
-
href: this.href,
|
|
127
|
-
min
|
|
128
|
-
}, read(sheet, this.href))
|
|
129
|
-
if (sheet.baseURI !== text.baseURI) {
|
|
130
|
-
text.rules.forEach(rule => {
|
|
131
|
-
if (rule.type === 1) for (let style = rule.style, i = style.length; i--; ) {
|
|
132
|
-
if (urlRe.test(style[style[i]])) style[style[i]] = style[style[i]].replace(urlRe, urlFn)
|
|
133
|
-
}
|
|
134
|
-
})
|
|
135
|
-
}
|
|
136
|
-
text += ""
|
|
137
|
-
}
|
|
138
|
-
return text
|
|
167
|
+
return this.text
|
|
139
168
|
},
|
|
140
169
|
set cssText(text) {
|
|
141
170
|
this.href = text.split(/['"()]+/)[1]
|
|
@@ -144,9 +173,7 @@ var fs = require("fs")
|
|
|
144
173
|
},
|
|
145
174
|
"}": {
|
|
146
175
|
get cssText() {
|
|
147
|
-
var
|
|
148
|
-
style.replaceSync(this.text)
|
|
149
|
-
var body = "" + style
|
|
176
|
+
var body = "" + new CSSStyleSheet({}, this.text)
|
|
150
177
|
return body.length > 0 ? this.mediaText + "{" + body + "}" : ""
|
|
151
178
|
},
|
|
152
179
|
set cssText(text) {
|
|
@@ -185,18 +212,31 @@ function CSSStyleDeclaration(text, parentRule = null) {
|
|
|
185
212
|
function CSSStyleSheet(opts, text = "") {
|
|
186
213
|
Object.assign(this, opts)
|
|
187
214
|
if (opts && opts.href) {
|
|
188
|
-
this.baseURI =
|
|
189
|
-
(opts.parentStyleSheet || opts.ownerNode && opts.ownerNode.ownerDocument).baseURI || ""
|
|
190
|
-
|
|
191
|
-
".."
|
|
192
|
-
)
|
|
215
|
+
this.baseURI = new URL(".", new URL(opts.href, toUrl(
|
|
216
|
+
(opts.parentStyleSheet || opts.ownerNode && opts.ownerNode.ownerDocument).baseURI || ""
|
|
217
|
+
))).pathname.slice(1).replace(/\/$/, "")
|
|
193
218
|
}
|
|
194
219
|
this.replaceSync(text)
|
|
195
220
|
}
|
|
196
221
|
|
|
222
|
+
function updateImportUrls(sheet, urlFn) {
|
|
223
|
+
sheet.rules.forEach(rule => {
|
|
224
|
+
if (rule.type === 1) {
|
|
225
|
+
for (let style = rule.style, val, i = style.length; i--; ) {
|
|
226
|
+
val = style[style[i]]
|
|
227
|
+
if (urlRe.test(val)) style[style[i]] = val.replace(urlRe, urlFn)
|
|
228
|
+
}
|
|
229
|
+
} else if (rule.mediaText != null && rule.text != null) {
|
|
230
|
+
var nested = new CSSStyleSheet({})
|
|
231
|
+
nested.replaceSync(rule.text)
|
|
232
|
+
updateImportUrls(nested, urlFn)
|
|
233
|
+
rule.text = nested.toString()
|
|
234
|
+
}
|
|
235
|
+
})
|
|
236
|
+
}
|
|
237
|
+
|
|
197
238
|
CSSStyleSheet.prototype = {
|
|
198
239
|
baseURI: "",
|
|
199
|
-
root: "",
|
|
200
240
|
disabled: false,
|
|
201
241
|
type: "text/css",
|
|
202
242
|
deleteRule(idx) {
|
|
@@ -237,8 +277,7 @@ CSSStyleSheet.prototype = {
|
|
|
237
277
|
}
|
|
238
278
|
if (depth > 0) throw Error("Unclosed block")
|
|
239
279
|
},
|
|
240
|
-
toString(
|
|
241
|
-
if (min) this.min = min
|
|
280
|
+
toString() {
|
|
242
281
|
return this.rules.map(rule => rule.cssText).filter(Boolean).join("\n")
|
|
243
282
|
}
|
|
244
283
|
}
|
package/dom.js
CHANGED
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
"use strict"
|
|
5
5
|
|
|
6
6
|
var boolAttrs = {
|
|
7
|
-
async:1, autoplay:1, loop:1, checked:
|
|
7
|
+
async:1, autoplay:1, loop:1, checked:2, defer:1, disabled:1, muted:1, multiple:1, nomodule:1, playsinline:1, readonly:1, required:1, selected:2
|
|
8
8
|
}
|
|
9
|
-
, numAttrs = "height
|
|
9
|
+
, numAttrs = "height size tabIndex width"
|
|
10
|
+
, numAttrsNeg = "maxLength minLength"
|
|
10
11
|
, strAttrs = "accept accesskey autocapitalize autofocus capture class contenteditable crossorigin dir for hidden href id integrity lang name nonce rel slot spellcheck src title type translate"
|
|
11
12
|
, defaultAttrs = {
|
|
12
13
|
"form method get":1, "input type text":1,
|
|
@@ -21,9 +22,8 @@ var boolAttrs = {
|
|
|
21
22
|
, rawTextElements = { SCRIPT: /<(?=\/script)/i, STYLE: /<(?=\/style)/i }
|
|
22
23
|
, rawTextEscape = { SCRIPT: /<(?=\/script|!--)/ig, STYLE: /<(?=\/style|!--)/ig }
|
|
23
24
|
, hasOwn = voidElements.hasOwnProperty
|
|
24
|
-
, { CSSStyleDeclaration, CSSStyleSheet } = require("./css.js")
|
|
25
|
+
, { CSS, CSSStyleDeclaration, CSSStyleSheet } = require("./css.js")
|
|
25
26
|
, selector = require("./selector.js")
|
|
26
|
-
, cssEscape = sel => ("" + sel).replace(/[^a-zA-Z0-9_\u00A0-\uFFFF-]/g, "\\$&").replace(/^(-?)([0-9])/, "$1\\3$2 ")
|
|
27
27
|
, Node = {
|
|
28
28
|
ELEMENT_NODE: 1,
|
|
29
29
|
TEXT_NODE: 3,
|
|
@@ -32,6 +32,12 @@ var boolAttrs = {
|
|
|
32
32
|
DOCUMENT_NODE: 9,
|
|
33
33
|
DOCUMENT_TYPE_NODE: 10,
|
|
34
34
|
DOCUMENT_FRAGMENT_NODE: 11,
|
|
35
|
+
DOCUMENT_POSITION_DISCONNECTED: 1,
|
|
36
|
+
DOCUMENT_POSITION_PRECEDING: 2,
|
|
37
|
+
DOCUMENT_POSITION_FOLLOWING: 4,
|
|
38
|
+
DOCUMENT_POSITION_CONTAINS: 8,
|
|
39
|
+
DOCUMENT_POSITION_CONTAINED_BY: 16,
|
|
40
|
+
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 32,
|
|
35
41
|
nodeName: null,
|
|
36
42
|
parentNode: null,
|
|
37
43
|
ownerDocument: null,
|
|
@@ -130,10 +136,26 @@ var boolAttrs = {
|
|
|
130
136
|
}
|
|
131
137
|
return clone
|
|
132
138
|
},
|
|
139
|
+
compareDocumentPosition(other) {
|
|
140
|
+
var node = this
|
|
141
|
+
if (node === other) return 0
|
|
142
|
+
if (node.getRootNode() !== other.getRootNode()) return Node.DOCUMENT_POSITION_DISCONNECTED
|
|
143
|
+
if (node.contains(other)) return Node.DOCUMENT_POSITION_CONTAINED_BY | Node.DOCUMENT_POSITION_FOLLOWING
|
|
144
|
+
if (other.contains(node)) return Node.DOCUMENT_POSITION_CONTAINS | Node.DOCUMENT_POSITION_PRECEDING
|
|
145
|
+
|
|
146
|
+
for (; node; node = node.nextSibling || node.parentNode && node.parentNode.nextSibling) {
|
|
147
|
+
if (node === other) return Node.DOCUMENT_POSITION_FOLLOWING
|
|
148
|
+
}
|
|
149
|
+
return Node.DOCUMENT_POSITION_PRECEDING
|
|
150
|
+
},
|
|
133
151
|
contains(el) {
|
|
134
152
|
for (; el; el = el.parentNode) if (el === this) return true
|
|
135
153
|
return false
|
|
136
154
|
},
|
|
155
|
+
getRootNode() {
|
|
156
|
+
for (var node = this; node.parentNode; ) node = node.parentNode
|
|
157
|
+
return node
|
|
158
|
+
},
|
|
137
159
|
hasChildNodes() {
|
|
138
160
|
return !!this.firstChild
|
|
139
161
|
},
|
|
@@ -177,9 +199,25 @@ var boolAttrs = {
|
|
|
177
199
|
},
|
|
178
200
|
toString(min) {
|
|
179
201
|
return rawTextElements[this.tagName] ? (
|
|
180
|
-
this.tagName === "STYLE" && (min === true || min && min.css) ? "\n" + makeSheet(this, min.css
|
|
202
|
+
this.tagName === "STYLE" && (min === true || min && min.css) ? "\n" + CSS.minify(makeSheet(this), typeof min.css === "object" ? min.css : null) + "\n" :
|
|
181
203
|
this.textContent
|
|
182
204
|
) : this.childNodes.map(node => node.toString(min)).join("")
|
|
205
|
+
},
|
|
206
|
+
toJSON() {
|
|
207
|
+
var node = this
|
|
208
|
+
, json = {
|
|
209
|
+
name: node.nodeName
|
|
210
|
+
}
|
|
211
|
+
if (node.nodeType === 1) {
|
|
212
|
+
json.attributes = {}
|
|
213
|
+
node.attributes.names().forEach(name => json.attributes[name] = node.getAttribute(name))
|
|
214
|
+
}
|
|
215
|
+
if (node.nodeType === 1 || node.nodeType === 9) {
|
|
216
|
+
json.children = node.childNodes.map(child => child.toJSON())
|
|
217
|
+
} else {
|
|
218
|
+
json.data = node.data
|
|
219
|
+
}
|
|
220
|
+
return json
|
|
183
221
|
}
|
|
184
222
|
}
|
|
185
223
|
, Element = {
|
|
@@ -239,8 +277,9 @@ var boolAttrs = {
|
|
|
239
277
|
"§": "§", "²": "²", "³": "³", "¥": "¥"
|
|
240
278
|
}
|
|
241
279
|
|
|
242
|
-
Object.keys(boolAttrs).forEach(key => addGetter(key, { isBool: true, readonly: "readOnly" }))
|
|
280
|
+
Object.keys(boolAttrs).forEach(key => addGetter(key, { isBool: true, isDirty: boolAttrs[key] > 1, readonly: "readOnly" }))
|
|
243
281
|
numAttrs.split(" ").forEach(key => addGetter(key, { isNum: true }))
|
|
282
|
+
numAttrsNeg.split(" ").forEach(key => addGetter(key, { isNum: true, numDefault: -1 }))
|
|
244
283
|
strAttrs.split(" ").forEach(key => addGetter(key, { "for": "htmlFor", "class": "className" }))
|
|
245
284
|
|
|
246
285
|
function addGetter(key, opts) {
|
|
@@ -249,19 +288,28 @@ function addGetter(key, opts) {
|
|
|
249
288
|
configurable: true,
|
|
250
289
|
enumerable: true,
|
|
251
290
|
get: (
|
|
291
|
+
opts.isDirty ? function() { return "_" + attr in this ? this["_" + attr] : this.hasAttribute(attr) } :
|
|
252
292
|
opts.isBool ? function() { return this.hasAttribute(attr) } :
|
|
253
|
-
opts.isNum ? function() {
|
|
293
|
+
opts.isNum ? function() { var v = this.getAttribute(attr); return v != null ? (+v || 0) : (opts.numDefault || 0) } :
|
|
254
294
|
function() { return this.getAttribute(attr) || "" }
|
|
255
295
|
),
|
|
256
296
|
set(value) {
|
|
257
|
-
this
|
|
297
|
+
if (opts.isDirty) this["_" + attr] = !!value
|
|
298
|
+
else if (opts.isBool && !value) this.removeAttribute(attr)
|
|
299
|
+
else this.setAttribute(attr, value)
|
|
258
300
|
}
|
|
259
301
|
})
|
|
260
302
|
}
|
|
261
303
|
|
|
262
304
|
;["hasAttribute", "getAttribute", "setAttribute", "removeAttribute"].forEach(name => {
|
|
263
305
|
Element[name + "NS"] = function(ns, a, b) {
|
|
264
|
-
|
|
306
|
+
if (name !== "setAttribute" && ns) {
|
|
307
|
+
var lo = (":" + a).toLowerCase()
|
|
308
|
+
for (var key in this.attributes) {
|
|
309
|
+
if (key.endsWith(lo)) return this[name](key)
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return this[name](a, b)
|
|
265
313
|
}
|
|
266
314
|
})
|
|
267
315
|
|
|
@@ -272,8 +320,10 @@ function Attr(node, name, value) {
|
|
|
272
320
|
}
|
|
273
321
|
|
|
274
322
|
function NamedNodeMap(node) {
|
|
275
|
-
Object.
|
|
276
|
-
|
|
323
|
+
Object.defineProperties(this, {
|
|
324
|
+
length: { get() { return this.names().length } },
|
|
325
|
+
ownerElement: { value: node }
|
|
326
|
+
})
|
|
277
327
|
}
|
|
278
328
|
|
|
279
329
|
NamedNodeMap.prototype = {
|
|
@@ -352,7 +402,7 @@ extendNode(HTMLElement, Element, {
|
|
|
352
402
|
return makeSheet(this)
|
|
353
403
|
},
|
|
354
404
|
blur() {
|
|
355
|
-
this.ownerDocument.activeElement = null
|
|
405
|
+
this.ownerDocument.activeElement = this.ownerDocument.body || null
|
|
356
406
|
},
|
|
357
407
|
closest(sel) {
|
|
358
408
|
return selector.closest(this, sel)
|
|
@@ -384,7 +434,7 @@ function ElementNS(namespace, tag) {
|
|
|
384
434
|
ElementNS.prototype = HTMLElement.prototype
|
|
385
435
|
|
|
386
436
|
function Text(data) {
|
|
387
|
-
this.data = data
|
|
437
|
+
this.data = "" + data
|
|
388
438
|
}
|
|
389
439
|
|
|
390
440
|
extendNode(Text, {
|
|
@@ -415,16 +465,12 @@ extendNode(DocumentType, {
|
|
|
415
465
|
nodeType: 10,
|
|
416
466
|
toString() {
|
|
417
467
|
return "<" + this.data + ">"
|
|
418
|
-
// var node = document.doctype
|
|
419
|
-
// return "<!DOCTYPE " + node.name +
|
|
420
|
-
// (node.publicId ? ' PUBLIC "' + node.publicId + '"' : '') +
|
|
421
|
-
// (!node.publicId && node.systemId ? ' SYSTEM' : '') +
|
|
422
|
-
// (node.systemId ? ' "' + node.systemId + '"' : '') + '>'
|
|
423
468
|
}
|
|
424
469
|
})
|
|
425
470
|
|
|
426
471
|
function Document() {
|
|
427
472
|
this.childNodes = []
|
|
473
|
+
this.attributes = new NamedNodeMap(this)
|
|
428
474
|
this
|
|
429
475
|
.appendChild(this.createElement("html"))
|
|
430
476
|
.appendChild(this.body = this.createElement("body"))
|
|
@@ -478,11 +524,8 @@ function own(Class) {
|
|
|
478
524
|
|
|
479
525
|
function extendNode(obj, extras) {
|
|
480
526
|
obj.prototype = Object.create(Node)
|
|
481
|
-
for (var
|
|
482
|
-
|
|
483
|
-
descriptor = Object.getOwnPropertyDescriptor(extras, key)
|
|
484
|
-
Object.defineProperty(obj.prototype, key, descriptor)
|
|
485
|
-
}
|
|
527
|
+
for (var i = 1; (extras = arguments[i++]); ) {
|
|
528
|
+
Object.defineProperties(obj.prototype, Object.getOwnPropertyDescriptors(extras))
|
|
486
529
|
}
|
|
487
530
|
obj.prototype.constructor = obj
|
|
488
531
|
}
|
|
@@ -492,9 +535,9 @@ function removeChilds(node) {
|
|
|
492
535
|
node.childNodes.length = 0
|
|
493
536
|
}
|
|
494
537
|
|
|
495
|
-
function getElement(childs, index, step
|
|
538
|
+
function getElement(childs, index, step) {
|
|
496
539
|
if (childs && index > -1) for (; childs[index]; index += step) {
|
|
497
|
-
if (childs[index].nodeType ===
|
|
540
|
+
if (childs[index].nodeType === 1) return childs[index]
|
|
498
541
|
}
|
|
499
542
|
return null
|
|
500
543
|
}
|
|
@@ -502,14 +545,13 @@ function getElement(childs, index, step, type) {
|
|
|
502
545
|
function getSibling(node, step, type) {
|
|
503
546
|
var silbings = node.parentNode && node.parentNode.childNodes
|
|
504
547
|
, index = silbings ? silbings.indexOf(node) : -1
|
|
505
|
-
return type
|
|
548
|
+
return type ? getElement(silbings, index + step, step) : silbings && silbings[index + step] || null
|
|
506
549
|
}
|
|
507
550
|
|
|
508
|
-
function makeSheet(el
|
|
551
|
+
function makeSheet(el) {
|
|
509
552
|
if (el.tagName === "STYLE" || el.tagName === "LINK" && el.rel === "stylesheet" && el.href) return new CSSStyleSheet({
|
|
510
553
|
href: el.href,
|
|
511
|
-
ownerNode: el
|
|
512
|
-
min
|
|
554
|
+
ownerNode: el
|
|
513
555
|
}, el.tagName === "STYLE" && el.textContent)
|
|
514
556
|
}
|
|
515
557
|
|
|
@@ -523,7 +565,7 @@ exports.document = new Document()
|
|
|
523
565
|
exports.entities = entities
|
|
524
566
|
exports.mergeAttributes = mergeAttributes
|
|
525
567
|
exports.selectorSplit = selector.selectorSplit
|
|
526
|
-
exports.
|
|
568
|
+
exports.CSS = CSS
|
|
527
569
|
exports.CSSStyleDeclaration = CSSStyleDeclaration
|
|
528
570
|
exports.CSSStyleSheet = CSSStyleSheet
|
|
529
571
|
exports.DOMParser = DOMParser
|
|
@@ -532,4 +574,3 @@ exports.DocumentFragment = DocumentFragment
|
|
|
532
574
|
exports.HTMLElement = HTMLElement
|
|
533
575
|
exports.Node = Node
|
|
534
576
|
exports.XMLSerializer = XMLSerializer
|
|
535
|
-
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@litejs/dom",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "26.2.0",
|
|
4
4
|
"description": "A small DOM library for server-side testing, rendering, and handling of HTML files",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Lauri Rooden <lauri@rooden.ee>",
|
|
@@ -15,9 +15,11 @@
|
|
|
15
15
|
"XMLSerializer",
|
|
16
16
|
"litejs"
|
|
17
17
|
],
|
|
18
|
+
"types": "types/index.d.ts",
|
|
18
19
|
"main": "dom.js",
|
|
19
20
|
"files": [
|
|
20
|
-
"*.js"
|
|
21
|
+
"*.js",
|
|
22
|
+
"types"
|
|
21
23
|
],
|
|
22
24
|
"scripts": {
|
|
23
25
|
"test": "lj t"
|
package/selector.js
CHANGED
|
@@ -6,9 +6,7 @@
|
|
|
6
6
|
exports.find = find
|
|
7
7
|
exports.selectorSplit = selectorSplit
|
|
8
8
|
|
|
9
|
-
var selectorCache = {
|
|
10
|
-
"": () => {}
|
|
11
|
-
}
|
|
9
|
+
var selectorCache = {}
|
|
12
10
|
, selectorRe = /([.#:[])([-\w]+)(?:\(((?:[^()]|\([^)]+\))+?)\)|([~^$*|]?)=(("|')(?:\\.|[^\\])*?\6|[-\w]+))?]?/g
|
|
13
11
|
, selectorLastRe = /([\s>+~]*)(?:("|')(?:\\.|[^\\])*?\2|\((?:[^()]|\([^()]+\))+?\)|~=|[^'"()\s>+~])+$/
|
|
14
12
|
, selectorMap = exports.selectorMap = {
|
|
@@ -41,7 +39,7 @@ var selectorCache = {
|
|
|
41
39
|
"": "c(_.parentNode,v)"
|
|
42
40
|
}
|
|
43
41
|
, closest = exports.closest = walk.bind(exports, "parentNode", 1)
|
|
44
|
-
, matches = exports.matches = (el, sel) => !!selectorFn(sel)(el)
|
|
42
|
+
, matches = exports.matches = (el, sel) => !!(sel && selectorFn(sel)(el))
|
|
45
43
|
, next = exports.next = (el, sel) => walk("nextSibling", 1, el.nextSibling, sel)
|
|
46
44
|
, prev = exports.prev = (el, sel) => walk("previousSibling", 1, el.previousSibling, sel)
|
|
47
45
|
|
|
@@ -49,8 +47,8 @@ var selectorCache = {
|
|
|
49
47
|
selectorMap["nth-last-child"] = selectorMap["nth-child"].replace("1+", "v.length-")
|
|
50
48
|
|
|
51
49
|
function selectorFn(str) {
|
|
52
|
-
if (str
|
|
53
|
-
return selectorCache[str
|
|
50
|
+
if (!str || typeof str !== "string") throw Error("Invalid selector")
|
|
51
|
+
return selectorCache[str] ||
|
|
54
52
|
(selectorCache[str] = Function("m,c,n,p", "return (_,v,a,b)=>" +
|
|
55
53
|
selectorSplit(str).map(sel => {
|
|
56
54
|
var relation, from
|
|
@@ -61,6 +59,7 @@ function selectorFn(str) {
|
|
|
61
59
|
return ""
|
|
62
60
|
})
|
|
63
61
|
, tag = sel.slice(from).replace(selectorRe, (_, op, key, subSel, fn, val, quotation) => {
|
|
62
|
+
if (key[0] == + key[0]) throw Error("Invalid selector")
|
|
64
63
|
rules.push(
|
|
65
64
|
"((v='" +
|
|
66
65
|
(subSel || (quotation ? val.slice(1, -1) : val) || "").replace(/[\\']/g, "\\$&") +
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
export type JSONNode = {
|
|
2
|
+
nodeType: number
|
|
3
|
+
nodeName: string
|
|
4
|
+
tagName?: string
|
|
5
|
+
attributes?: Record<string, string>
|
|
6
|
+
data?: string
|
|
7
|
+
childNodes?: JSONNode[]
|
|
8
|
+
contentType?: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface Attr {
|
|
12
|
+
name: string
|
|
13
|
+
value: string
|
|
14
|
+
ownerElement: HTMLElement
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface NamedNodeMap {
|
|
18
|
+
readonly length: number
|
|
19
|
+
readonly ownerElement: HTMLElement
|
|
20
|
+
names(): string[]
|
|
21
|
+
getNamedItem(name: string): Attr | null
|
|
22
|
+
setNamedItem(attr: Attr): Attr | null
|
|
23
|
+
removeNamedItem(name: string): Attr | null
|
|
24
|
+
toString(minify?: boolean): string
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface NodeConstants {
|
|
28
|
+
readonly ELEMENT_NODE: 1
|
|
29
|
+
readonly TEXT_NODE: 3
|
|
30
|
+
readonly PROCESSING_INSTRUCTION_NODE: 7
|
|
31
|
+
readonly COMMENT_NODE: 8
|
|
32
|
+
readonly DOCUMENT_NODE: 9
|
|
33
|
+
readonly DOCUMENT_TYPE_NODE: 10
|
|
34
|
+
readonly DOCUMENT_FRAGMENT_NODE: 11
|
|
35
|
+
readonly DOCUMENT_POSITION_DISCONNECTED: 1
|
|
36
|
+
readonly DOCUMENT_POSITION_PRECEDING: 2
|
|
37
|
+
readonly DOCUMENT_POSITION_FOLLOWING: 4
|
|
38
|
+
readonly DOCUMENT_POSITION_CONTAINS: 8
|
|
39
|
+
readonly DOCUMENT_POSITION_CONTAINED_BY: 16
|
|
40
|
+
readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 32
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export type MinifyOption = boolean | { css?: boolean }
|
|
44
|
+
|
|
45
|
+
export abstract class Node {
|
|
46
|
+
static readonly ELEMENT_NODE: 1
|
|
47
|
+
static readonly TEXT_NODE: 3
|
|
48
|
+
static readonly PROCESSING_INSTRUCTION_NODE: 7
|
|
49
|
+
static readonly COMMENT_NODE: 8
|
|
50
|
+
static readonly DOCUMENT_NODE: 9
|
|
51
|
+
static readonly DOCUMENT_TYPE_NODE: 10
|
|
52
|
+
static readonly DOCUMENT_FRAGMENT_NODE: 11
|
|
53
|
+
static readonly DOCUMENT_POSITION_DISCONNECTED: 1
|
|
54
|
+
static readonly DOCUMENT_POSITION_PRECEDING: 2
|
|
55
|
+
static readonly DOCUMENT_POSITION_FOLLOWING: 4
|
|
56
|
+
static readonly DOCUMENT_POSITION_CONTAINS: 8
|
|
57
|
+
static readonly DOCUMENT_POSITION_CONTAINED_BY: 16
|
|
58
|
+
static readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 32
|
|
59
|
+
|
|
60
|
+
nodeType: number
|
|
61
|
+
nodeName: string
|
|
62
|
+
parentNode: Node | null
|
|
63
|
+
ownerDocument: Document | null
|
|
64
|
+
childNodes: Node[]
|
|
65
|
+
nodeValue: string | null
|
|
66
|
+
textContent: string
|
|
67
|
+
firstChild: Node | null
|
|
68
|
+
lastChild: Node | null
|
|
69
|
+
nextSibling: Node | null
|
|
70
|
+
previousSibling: Node | null
|
|
71
|
+
appendChild(child: Node): Node
|
|
72
|
+
insertBefore(child: Node, ref?: Node | null): Node
|
|
73
|
+
removeChild(child: Node): Node
|
|
74
|
+
replaceChild(child: Node, ref: Node): Node
|
|
75
|
+
cloneNode(deep?: boolean): Node
|
|
76
|
+
contains(node: Node | null): boolean
|
|
77
|
+
compareDocumentPosition(other: Node): number
|
|
78
|
+
getRootNode(): Node
|
|
79
|
+
hasChildNodes(): boolean
|
|
80
|
+
toString(minify?: MinifyOption): string
|
|
81
|
+
toJSON(): JSONNode
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export class DocumentFragment extends Node {
|
|
85
|
+
constructor()
|
|
86
|
+
override nodeType: 11
|
|
87
|
+
override nodeName: "#document-fragment"
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export class CSSStyleDeclaration {
|
|
91
|
+
constructor(cssText?: string)
|
|
92
|
+
cssText: string
|
|
93
|
+
[key: string]: string
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export interface StyleSheetInit {
|
|
97
|
+
min?: boolean | { css?: boolean }
|
|
98
|
+
href?: string
|
|
99
|
+
ownerNode?: HTMLElement
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export class CSSStyleSheet {
|
|
103
|
+
constructor(init?: StyleSheetInit, cssText?: string)
|
|
104
|
+
href?: string
|
|
105
|
+
ownerNode?: HTMLElement
|
|
106
|
+
replaceSync(cssText: string): void
|
|
107
|
+
toString(minify?: boolean | { css?: boolean }): string
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export class HTMLElement extends Node {
|
|
111
|
+
attributes: NamedNodeMap
|
|
112
|
+
localName: string
|
|
113
|
+
tagName: string
|
|
114
|
+
namespaceURI: string
|
|
115
|
+
style: CSSStyleDeclaration
|
|
116
|
+
outerHTML: string
|
|
117
|
+
innerHTML: string
|
|
118
|
+
firstElementChild: HTMLElement | null
|
|
119
|
+
lastElementChild: HTMLElement | null
|
|
120
|
+
nextElementSibling: HTMLElement | null
|
|
121
|
+
previousElementSibling: HTMLElement | null
|
|
122
|
+
readonly sheet?: CSSStyleSheet
|
|
123
|
+
replaceChildren(...nodes: Node[]): void
|
|
124
|
+
getAttribute(name: string): string | null
|
|
125
|
+
setAttribute(name: string, value: unknown): void
|
|
126
|
+
removeAttribute(name: string): void
|
|
127
|
+
hasAttribute(name: string): boolean
|
|
128
|
+
getAttributeNS(ns: string | null, name: string): string | null
|
|
129
|
+
setAttributeNS(ns: string | null, name: string, value: unknown): void
|
|
130
|
+
removeAttributeNS(ns: string | null, name: string): void
|
|
131
|
+
hasAttributeNS(ns: string | null, name: string): boolean
|
|
132
|
+
getElementsByTagName(tag: string): HTMLElement[]
|
|
133
|
+
getElementsByClassName(sel: string): HTMLElement[]
|
|
134
|
+
querySelector(sel: string): HTMLElement | null
|
|
135
|
+
querySelectorAll(sel: string): HTMLElement[]
|
|
136
|
+
matches(sel: string): boolean
|
|
137
|
+
closest(sel: string): HTMLElement | null
|
|
138
|
+
blur(): void
|
|
139
|
+
focus(): void
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export class ElementNS extends HTMLElement {
|
|
143
|
+
constructor(namespace: string | null, tag: string)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export class Text extends Node {
|
|
147
|
+
constructor(data: string | number | null | undefined)
|
|
148
|
+
data: string
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export class Comment extends Node {
|
|
152
|
+
constructor(data: string | number | null | undefined)
|
|
153
|
+
data: string
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export class DocumentType extends Node {
|
|
157
|
+
constructor(name: string)
|
|
158
|
+
data: string
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export class Document extends HTMLElement {
|
|
162
|
+
constructor()
|
|
163
|
+
override nodeType: 9
|
|
164
|
+
override nodeName: "#document"
|
|
165
|
+
body: HTMLElement
|
|
166
|
+
documentElement: HTMLElement
|
|
167
|
+
contentType: string
|
|
168
|
+
styleSheets: CSSStyleSheet[]
|
|
169
|
+
title: string
|
|
170
|
+
createElement(tag: string): HTMLElement
|
|
171
|
+
createElementNS(namespace: string | null, tag: string): ElementNS
|
|
172
|
+
createTextNode(data: string | number | null | undefined): Text
|
|
173
|
+
createComment(data: string | number | null | undefined): Comment
|
|
174
|
+
createDocumentType(name: string): DocumentType
|
|
175
|
+
createDocumentFragment(): DocumentFragment
|
|
176
|
+
getElementById(id: string): HTMLElement | null
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export class DOMParser {
|
|
180
|
+
parseFromString(str: string, mime?: string): Document
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export class XMLSerializer {
|
|
184
|
+
serializeToString(doc: Document): string
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export const document: Document
|
|
188
|
+
export const entities: Record<string, string>
|
|
189
|
+
export function mergeAttributes(source: HTMLElement | null, target: HTMLElement | null): void
|
|
190
|
+
export function selectorSplit(selector: string): string[]
|
|
191
|
+
export const CSS: {
|
|
192
|
+
escape(selector: string | number): string
|
|
193
|
+
minify(sheet: CSSStyleSheet, min?: { color?: boolean }): string
|
|
194
|
+
}
|