@litejs/dom 24.8.0 → 24.12.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 +6 -10
- package/css.js +121 -17
- package/dom.js +56 -60
- package/interactive.js +2 -2
- package/net.js +38 -43
- package/package.json +6 -4
package/README.md
CHANGED
|
@@ -10,16 +10,13 @@
|
|
|
10
10
|
LiteJS DOM – [![Coverage][1]][2] [![Size][3]][4] [![Buy Me A Tea][5]][6]
|
|
11
11
|
==========
|
|
12
12
|
|
|
13
|
-
Dependency-free DOM library for handling HTML files on server-side.
|
|
14
|
-
[DOM spec](https://dom.spec.whatwg.org/) |
|
|
15
|
-
[Selectors Level 3](http://www.w3.org/TR/selectors/)
|
|
13
|
+
Dependency-free DOM library for handling HTML files on server-side.
|
|
16
14
|
|
|
17
15
|
|
|
18
|
-
Examples
|
|
19
|
-
--------
|
|
20
|
-
|
|
21
16
|
```javascript
|
|
22
|
-
|
|
17
|
+
import { document, DOMParser, XMLSerializer } from "@litejs/dom";
|
|
18
|
+
import { XMLHttpRequest } from "@litejs/dom/net.js";
|
|
19
|
+
// const { document } = require("@litejs/dom");
|
|
23
20
|
|
|
24
21
|
// Build DOM manually
|
|
25
22
|
const el = document.createElement("h1");
|
|
@@ -43,14 +40,13 @@ el.querySelectorAll("b");
|
|
|
43
40
|
// [ "<b>hello world</b>" ]
|
|
44
41
|
|
|
45
42
|
// Use XMLHttpRequest in server side
|
|
46
|
-
const { XMLHttpRequest } = require("@litejs/dom/net.js");
|
|
47
43
|
const xhr = new XMLHttpRequest();
|
|
48
44
|
xhr.open("GET", "https://litejs.com");
|
|
49
45
|
xhr.responseType = "document";
|
|
50
46
|
xhr.onload = function() {
|
|
51
|
-
const
|
|
47
|
+
const doc = xhr.responseXML;
|
|
52
48
|
// Work with DOM in familiar way
|
|
53
|
-
console.log(
|
|
49
|
+
console.log(doc.querySelector("title").textContent);
|
|
54
50
|
}
|
|
55
51
|
xhr.send();
|
|
56
52
|
```
|
package/css.js
CHANGED
|
@@ -2,31 +2,135 @@
|
|
|
2
2
|
/*! litejs.com/MIT-LICENSE.txt */
|
|
3
3
|
|
|
4
4
|
exports.CSSStyleDeclaration = CSSStyleDeclaration
|
|
5
|
+
exports.CSSStyleSheet = CSSStyleSheet
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
var clearFn = (_, q, str) => q ? (q == "\"" && str.indexOf("'") == -1 ? "'" + str + "'" : _) :
|
|
8
|
+
_.trim().replace(/[\t\n]/g, " ")
|
|
9
|
+
.replace(/ *([,;{}>~+\/]) */g, "$1")
|
|
10
|
+
.replace(/^ +|;(?=})/g, "")
|
|
11
|
+
.replace(/: +/g, ":")
|
|
12
|
+
, clear = s => s.replace(/(["'])((?:\\\1|.)*?)\1|[^"']+/g, clearFn).replace(/url\(("|')([^'"()\s]+)\1\)/g, "url($2)")
|
|
13
|
+
, styleHandler = {
|
|
14
|
+
get(style, prop) {
|
|
15
|
+
if (prop === "cssText") {
|
|
16
|
+
for (var out = [], i = style.length; i--; ) {
|
|
17
|
+
out[i] = style[i] + ":" + (style.__[i] || style[style[i]])
|
|
18
|
+
}
|
|
19
|
+
return out.join(";")
|
|
20
|
+
}
|
|
21
|
+
return style[prop] || ""
|
|
22
|
+
},
|
|
23
|
+
set(style, prop, val) {
|
|
24
|
+
if (prop === "cssText") {
|
|
25
|
+
var m, k
|
|
26
|
+
, re = /(?:^|;)\s*([-a-z]+)\s*:((?:("|')(?:\\.|(?!\3)[^\\])*?\3|[^"';])+)(?=;|$)/ig
|
|
27
|
+
, len = 0
|
|
28
|
+
, lastIdx = {}
|
|
29
|
+
for (; (m = re.exec(val)); ) {
|
|
30
|
+
k = m[1]
|
|
31
|
+
if (lastIdx[k] >= 0) style.__[lastIdx[k]] = style[k]
|
|
32
|
+
style[style[lastIdx[k] = len++] = k] = style[
|
|
33
|
+
k === "float" ? "cssFloat" : k.replace(/-([a-z])/g, (_, a) => a.toUpperCase())
|
|
34
|
+
] = clear(m[2])
|
|
35
|
+
}
|
|
36
|
+
style.length = len
|
|
37
|
+
} else {
|
|
38
|
+
if (!style[prop]) style[style.length++] = prop
|
|
39
|
+
style[prop] = style[prop === "cssFloat" ? "float" : prop.replace(/[A-Z]/g, "-$&").toLowerCase()] = clear(val)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
10
42
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
43
|
+
, ruleTypes = {
|
|
44
|
+
style: {
|
|
45
|
+
get cssText() {
|
|
46
|
+
return this.style.length > 0 ? this.selectorText + "{" + this.style.cssText + "}" : ""
|
|
47
|
+
},
|
|
48
|
+
set cssText(text) {
|
|
49
|
+
var idx = text.indexOf("{")
|
|
50
|
+
this.selectorText = text.slice(0, idx).trim()
|
|
51
|
+
this.style = CSSStyleDeclaration(text.slice(idx + 1).replace(/}\s*/, ""), this)
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
import: {
|
|
55
|
+
get cssText() {
|
|
56
|
+
return clear(this.text)
|
|
57
|
+
},
|
|
58
|
+
set cssText(text) {
|
|
59
|
+
this.text = clear(text)
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"}": {
|
|
63
|
+
get cssText() {
|
|
64
|
+
var body = "" + this.style
|
|
65
|
+
return body.length > 0 ? this.mediaText + "{\n" + body + "\n}" : ""
|
|
66
|
+
},
|
|
67
|
+
set cssText(text) {
|
|
68
|
+
var idx = text.indexOf("{")
|
|
69
|
+
this.mediaText = clear(text.slice(0, idx).trim())
|
|
70
|
+
this.style = new CSSStyleSheet({})
|
|
71
|
+
this.style.replaceSync(text.slice(idx + 1, -1))
|
|
72
|
+
}
|
|
17
73
|
},
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
74
|
+
";": {
|
|
75
|
+
get cssText() {
|
|
76
|
+
return clear(this.text)
|
|
77
|
+
},
|
|
78
|
+
set cssText(text) {
|
|
79
|
+
this.text = clear(text)
|
|
21
80
|
}
|
|
22
81
|
}
|
|
23
82
|
}
|
|
24
83
|
|
|
25
|
-
function
|
|
26
|
-
|
|
84
|
+
function CSSRule(text, parentStyleSheet, atType, parentRule = null) {
|
|
85
|
+
// Clear comments and trim
|
|
86
|
+
text = text.replace(/^\s+|\/\*[^*]*\*+([^/*][^*]*\*+)*\/|\s+$/g, "")
|
|
87
|
+
var type = text[0] === "@" && text.slice(1, text.indexOf(" ")) || "style"
|
|
88
|
+
, rule = Object.create(ruleTypes[type] || ruleTypes[type === "font-face" || type === "counter-style" ? "style" : atType])
|
|
89
|
+
rule.cssText = text
|
|
90
|
+
rule.parentStyleSheet = parentStyleSheet
|
|
91
|
+
rule.parentRule = parentRule
|
|
92
|
+
return rule
|
|
27
93
|
}
|
|
28
94
|
|
|
29
|
-
function
|
|
30
|
-
|
|
95
|
+
function CSSStyleDeclaration(text, parentRule = null) {
|
|
96
|
+
var style = new Proxy({__: {}, parentRule}, styleHandler)
|
|
97
|
+
style.cssText = text
|
|
98
|
+
return style
|
|
31
99
|
}
|
|
32
100
|
|
|
101
|
+
function CSSStyleSheet(opts) {
|
|
102
|
+
Object.assign(this, opts)
|
|
103
|
+
this.replaceSync(this.ownerNode ? this.ownerNode.textContent : "")
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
CSSStyleSheet.prototype = {
|
|
107
|
+
disabled: false,
|
|
108
|
+
type: "text/css",
|
|
109
|
+
deleteRule(idx) {
|
|
110
|
+
this.rules.splice(idx, 1)
|
|
111
|
+
},
|
|
112
|
+
insertRule(rule, idx) {
|
|
113
|
+
this.rules.splice(idx > -1 ? idx : this.rules.length, 0, CSSRule(rule, this))
|
|
114
|
+
},
|
|
115
|
+
replaceSync(text) {
|
|
116
|
+
var m
|
|
117
|
+
, sheet = this
|
|
118
|
+
, re = /((?:("|')(?:\\.|(?!\2)[^\\])*?\2|[^"'}{;])+)|./ig
|
|
119
|
+
, block = 0
|
|
120
|
+
, pos = 0
|
|
121
|
+
sheet.rules = sheet.cssRules = []
|
|
122
|
+
sheet.warnings = []
|
|
123
|
+
for (; (m = re.exec(text)); ) {
|
|
124
|
+
if (m[0] === "{") {
|
|
125
|
+
block++
|
|
126
|
+
} else if (m[0] === ";" && block === 0 || m[0] === "}" && --block < 1) {
|
|
127
|
+
sheet.rules.push(CSSRule(text.slice(pos, pos = re.lastIndex), sheet, m[0]))
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
toString() {
|
|
132
|
+
return this.rules.map(rule => rule.cssText).filter(Boolean).join("\n")
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
|
package/dom.js
CHANGED
|
@@ -5,7 +5,7 @@ var boolAttrs = {
|
|
|
5
5
|
async:1, autoplay:1, loop:1, checked:1, defer:1, disabled:1, muted:1, multiple:1, nomodule:1, playsinline:1, readonly:1, required:1, selected:1
|
|
6
6
|
}
|
|
7
7
|
, numAttrs = "height maxLength minLength size tabIndex width"
|
|
8
|
-
, strAttrs = "accept accesskey autocapitalize autofocus capture class contenteditable crossorigin dir for hidden href id integrity lang name nonce slot spellcheck src title type translate"
|
|
8
|
+
, 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"
|
|
9
9
|
, defaultAttrs = {
|
|
10
10
|
"form method get":1, "input type text":1,
|
|
11
11
|
"script type text/javascript":1, "style type text/css":1
|
|
@@ -16,7 +16,7 @@ var boolAttrs = {
|
|
|
16
16
|
, rawTextElements = { SCRIPT: /<(?=\/script)/i, STYLE: /<(?=\/style)/i }
|
|
17
17
|
, rawTextEscape = { SCRIPT: /<(?=\/script|!--)/ig, STYLE: /<(?=\/style|!--)/ig }
|
|
18
18
|
, hasOwn = voidElements.hasOwnProperty
|
|
19
|
-
, CSSStyleDeclaration = require("./css.js")
|
|
19
|
+
, { CSSStyleDeclaration, CSSStyleSheet } = require("./css.js")
|
|
20
20
|
, selector = require("./selector.js")
|
|
21
21
|
, Node = {
|
|
22
22
|
ELEMENT_NODE: 1,
|
|
@@ -37,9 +37,7 @@ var boolAttrs = {
|
|
|
37
37
|
if (this.nodeType === 3 || this.nodeType === 8) this.data = text
|
|
38
38
|
},
|
|
39
39
|
get textContent() {
|
|
40
|
-
return this.nodeType === 3 || this.nodeType === 8 ? this.data : this.childNodes.map(
|
|
41
|
-
return child.textContent
|
|
42
|
-
}).join("")
|
|
40
|
+
return this.nodeType === 3 || this.nodeType === 8 ? this.data : this.childNodes.map(node => node.textContent).join("")
|
|
43
41
|
},
|
|
44
42
|
set textContent(text) {
|
|
45
43
|
if (this.nodeType === 3 || this.nodeType === 8) this.data = text
|
|
@@ -108,26 +106,32 @@ var boolAttrs = {
|
|
|
108
106
|
frag.innerHTML = html
|
|
109
107
|
this.parentNode.replaceChild(frag, this)
|
|
110
108
|
},
|
|
109
|
+
get sheet() {
|
|
110
|
+
if (this.tagName === "STYLE" || this.tagName === "LINK" && this.rel === "stylesheet" && this.href) return new CSSStyleSheet({
|
|
111
|
+
href: this.href,
|
|
112
|
+
ownerNode: this
|
|
113
|
+
})
|
|
114
|
+
},
|
|
111
115
|
get style() {
|
|
112
|
-
return this._style || (this._style =
|
|
116
|
+
return this._style || (this._style = CSSStyleDeclaration(this.getAttribute("style") || ""))
|
|
113
117
|
},
|
|
114
118
|
set style(value) {
|
|
115
119
|
this.style.cssText = value
|
|
116
120
|
},
|
|
117
|
-
contains
|
|
121
|
+
contains(el) {
|
|
118
122
|
for (; el; el = el.parentNode) if (el === this) return true
|
|
119
123
|
return false
|
|
120
124
|
},
|
|
121
|
-
hasChildNodes
|
|
122
|
-
return this.
|
|
125
|
+
hasChildNodes() {
|
|
126
|
+
return !!this.firstChild
|
|
123
127
|
},
|
|
124
|
-
getElementById
|
|
128
|
+
getElementById(id) {
|
|
125
129
|
return selector.find(this, "#" + id, 1)
|
|
126
130
|
},
|
|
127
|
-
appendChild
|
|
131
|
+
appendChild(el) {
|
|
128
132
|
return this.insertBefore(el)
|
|
129
133
|
},
|
|
130
|
-
insertBefore
|
|
134
|
+
insertBefore(el, ref) {
|
|
131
135
|
var node = this
|
|
132
136
|
, childs = node.childNodes
|
|
133
137
|
|
|
@@ -146,7 +150,7 @@ var boolAttrs = {
|
|
|
146
150
|
}
|
|
147
151
|
return el
|
|
148
152
|
},
|
|
149
|
-
removeChild
|
|
153
|
+
removeChild(el) {
|
|
150
154
|
var node = this
|
|
151
155
|
, index = node.childNodes.indexOf(el)
|
|
152
156
|
if (index === -1) throw Error("NOT_FOUND_ERR")
|
|
@@ -155,38 +159,35 @@ var boolAttrs = {
|
|
|
155
159
|
el.parentNode = null
|
|
156
160
|
return el
|
|
157
161
|
},
|
|
158
|
-
replaceChild
|
|
162
|
+
replaceChild(el, ref) {
|
|
159
163
|
this.insertBefore(el, ref)
|
|
160
164
|
return this.removeChild(ref)
|
|
161
165
|
},
|
|
162
|
-
cloneNode
|
|
166
|
+
cloneNode(deep) {
|
|
163
167
|
var node = this
|
|
164
168
|
, clone = new node.constructor(node.tagName || node.data)
|
|
165
169
|
clone.ownerDocument = node.ownerDocument
|
|
166
170
|
|
|
167
171
|
if (node.attributes) {
|
|
168
|
-
node.attributes.names().forEach(
|
|
169
|
-
clone.setAttribute(attr, node.getAttribute(attr))
|
|
170
|
-
})
|
|
172
|
+
node.attributes.names().forEach(attr => clone.setAttribute(attr, node.getAttribute(attr)))
|
|
171
173
|
}
|
|
172
174
|
|
|
173
175
|
if (deep && node.hasChildNodes()) {
|
|
174
|
-
node.childNodes.forEach(
|
|
175
|
-
clone.appendChild(child.cloneNode(deep))
|
|
176
|
-
})
|
|
176
|
+
node.childNodes.forEach(child => clone.appendChild(child.cloneNode(deep)))
|
|
177
177
|
}
|
|
178
178
|
return clone
|
|
179
179
|
},
|
|
180
|
-
querySelector
|
|
180
|
+
querySelector(sel) {
|
|
181
181
|
return selector.find(this, sel, 1)
|
|
182
182
|
},
|
|
183
|
-
querySelectorAll
|
|
183
|
+
querySelectorAll(sel) {
|
|
184
184
|
return selector.find(this, sel)
|
|
185
185
|
},
|
|
186
|
-
toString
|
|
187
|
-
return rawTextElements[this.tagName] ?
|
|
188
|
-
|
|
189
|
-
|
|
186
|
+
toString(min) {
|
|
187
|
+
return rawTextElements[this.tagName] ? (
|
|
188
|
+
this.tagName === "STYLE" && (min === true || min && min.css) ? "\n" + this.sheet.toString(min.css || true) + "\n" :
|
|
189
|
+
this.textContent
|
|
190
|
+
) : this.childNodes.map(node => node.toString(min)).join("")
|
|
190
191
|
}
|
|
191
192
|
}
|
|
192
193
|
, Element = {
|
|
@@ -203,29 +204,31 @@ var boolAttrs = {
|
|
|
203
204
|
return getSibling(this, -1, 1)
|
|
204
205
|
},
|
|
205
206
|
replaceChildren: replaceChildren,
|
|
206
|
-
hasAttribute
|
|
207
|
+
hasAttribute(name) {
|
|
207
208
|
return this.attributes.getNamedItem(name) != null
|
|
208
209
|
},
|
|
209
|
-
getAttribute
|
|
210
|
+
getAttribute(name) {
|
|
210
211
|
var attr = this.attributes.getNamedItem(name)
|
|
211
212
|
return attr ? attr.value : null
|
|
212
213
|
},
|
|
213
|
-
setAttribute
|
|
214
|
+
setAttribute(name, value) {
|
|
214
215
|
this.attributes.setNamedItem(new Attr(this, name, value))
|
|
215
216
|
},
|
|
216
|
-
removeAttribute
|
|
217
|
+
removeAttribute(name) {
|
|
217
218
|
this.attributes.removeNamedItem(name)
|
|
218
219
|
},
|
|
219
|
-
getElementsByTagName
|
|
220
|
+
getElementsByTagName(tag) {
|
|
220
221
|
return selector.find(this, tag)
|
|
221
222
|
},
|
|
222
|
-
getElementsByClassName
|
|
223
|
+
getElementsByClassName(sel) {
|
|
223
224
|
return selector.find(this, "." + sel.replace(/\s+/g, "."))
|
|
224
225
|
}
|
|
225
226
|
}
|
|
226
227
|
, quotedAttrRe = /[\s"'`=<>]/
|
|
227
228
|
, escRe = /<|&(?=[a-z#])/gi
|
|
229
|
+
, escFn = chr => chr === "<" ? "<" : "&"
|
|
228
230
|
, unescRe = /&[a-z]{1,31};?|&#(x|)([\da-f]+);/ig
|
|
231
|
+
, unescFn = (ent, hex, num) => num ? String.fromCharCode(parseInt(num, hex === "" ? 10 : 16)) : entities[ent] || ent
|
|
229
232
|
, entities = {
|
|
230
233
|
"&": "&", "'": "'", "¢": "¢", "©": "©", "¤": "¤",
|
|
231
234
|
"°": "°", "€": "€", ">": ">", "<": "<", " ": " ",
|
|
@@ -247,20 +250,12 @@ function addGetter(key) {
|
|
|
247
250
|
this.isNum ? function() { return +this.getAttribute(attr) || 0 } :
|
|
248
251
|
function() { return this.getAttribute(attr) || "" }
|
|
249
252
|
),
|
|
250
|
-
set
|
|
253
|
+
set(value) {
|
|
251
254
|
this.setAttribute(attr, value)
|
|
252
255
|
}
|
|
253
256
|
})
|
|
254
257
|
}
|
|
255
258
|
|
|
256
|
-
function escFn(chr) {
|
|
257
|
-
return chr === "<" ? "<" : "&"
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
function unescFn(ent, hex, num) {
|
|
261
|
-
return num ? String.fromCharCode(parseInt(num, hex === "" ? 10 : 16)) : entities[ent] || ent
|
|
262
|
-
}
|
|
263
|
-
|
|
264
259
|
;["hasAttribute", "getAttribute", "setAttribute", "removeAttribute"].forEach(function(name) {
|
|
265
260
|
Element[name + "NS"] = function(ns, a, b) {
|
|
266
261
|
return this[name].call(this, a, b)
|
|
@@ -274,16 +269,16 @@ function Attr(node, name, value) {
|
|
|
274
269
|
}
|
|
275
270
|
|
|
276
271
|
function NamedNodeMap(node) {
|
|
277
|
-
Object.defineProperty(this, "length", { get
|
|
272
|
+
Object.defineProperty(this, "length", { get() { return this.names().length } })
|
|
278
273
|
Object.defineProperty(this, "ownerElement", { value: node })
|
|
279
274
|
}
|
|
280
275
|
|
|
281
276
|
NamedNodeMap.prototype = {
|
|
282
|
-
names
|
|
277
|
+
names() {
|
|
283
278
|
this.getNamedItem("style")
|
|
284
279
|
return Object.keys(this)
|
|
285
280
|
},
|
|
286
|
-
getNamedItem
|
|
281
|
+
getNamedItem(name) {
|
|
287
282
|
var loName = name.toLowerCase()
|
|
288
283
|
, attr = this[loName] || null
|
|
289
284
|
if (loName === "style" && this.ownerElement._style) {
|
|
@@ -292,24 +287,24 @@ NamedNodeMap.prototype = {
|
|
|
292
287
|
}
|
|
293
288
|
return attr
|
|
294
289
|
},
|
|
295
|
-
removeNamedItem
|
|
290
|
+
removeNamedItem(name) {
|
|
296
291
|
var loName = name.toLowerCase()
|
|
297
292
|
, attr = this[loName] || null
|
|
298
293
|
if (loName === "style") delete this.ownerElement._style
|
|
299
294
|
if (attr !== null) delete this[loName]
|
|
300
295
|
return attr
|
|
301
296
|
},
|
|
302
|
-
setNamedItem
|
|
297
|
+
setNamedItem(attr) {
|
|
303
298
|
var oldAttr = this.getNamedItem(attr.name)
|
|
304
|
-
if (attr.name === "style") attr.value =
|
|
299
|
+
if (attr.name === "style") attr.value = CSSStyleDeclaration(attr.value).cssText
|
|
305
300
|
this[attr.name] = attr
|
|
306
301
|
return oldAttr
|
|
307
302
|
},
|
|
308
|
-
toString
|
|
303
|
+
toString(minify) {
|
|
309
304
|
var map = this
|
|
310
305
|
, tagName = map.ownerElement.tagName
|
|
311
306
|
, isXml = map.ownerElement.ownerDocument.contentType === "application/xml"
|
|
312
|
-
return map.names().map(
|
|
307
|
+
return map.names().map(loName => {
|
|
313
308
|
var attr = map.getNamedItem(loName)
|
|
314
309
|
, name = attr.name
|
|
315
310
|
, value = attr.value.replace(escRe, escFn)
|
|
@@ -346,16 +341,16 @@ function HTMLElement(tag) {
|
|
|
346
341
|
|
|
347
342
|
extendNode(HTMLElement, Element, {
|
|
348
343
|
nodeType: 1,
|
|
349
|
-
matches
|
|
344
|
+
matches(sel) {
|
|
350
345
|
return selector.matches(this, sel)
|
|
351
346
|
},
|
|
352
|
-
closest
|
|
347
|
+
closest(sel) {
|
|
353
348
|
return selector.closest(this, sel)
|
|
354
349
|
},
|
|
355
350
|
namespaceURI: "http://www.w3.org/1999/xhtml",
|
|
356
351
|
localName: null,
|
|
357
352
|
tagName: null,
|
|
358
|
-
toString
|
|
353
|
+
toString(minify) {
|
|
359
354
|
var attrs = this.attributes.toString(minify)
|
|
360
355
|
return "<" + this.localName + (attrs ? " " + attrs + (attrs.slice(-1) === "/" ? " >" : ">") : ">") +
|
|
361
356
|
(voidElements[this.tagName] ? "" : Node.toString.call(this, minify) + "</" + this.localName + ">")
|
|
@@ -379,7 +374,7 @@ function Text(data) {
|
|
|
379
374
|
extendNode(Text, {
|
|
380
375
|
nodeType: 3,
|
|
381
376
|
nodeName: "#text",
|
|
382
|
-
toString
|
|
377
|
+
toString(minify) {
|
|
383
378
|
return (minify ? ("" + this.data).trim() : "" + this.data).replace(escRe, escFn)
|
|
384
379
|
}
|
|
385
380
|
})
|
|
@@ -391,7 +386,7 @@ function Comment(data) {
|
|
|
391
386
|
extendNode(Comment, {
|
|
392
387
|
nodeType: 8,
|
|
393
388
|
nodeName: "#comment",
|
|
394
|
-
toString
|
|
389
|
+
toString(minify) {
|
|
395
390
|
return minify ? "" : "<!--" + this.data + "-->"
|
|
396
391
|
}
|
|
397
392
|
})
|
|
@@ -402,7 +397,7 @@ function DocumentType(data) {
|
|
|
402
397
|
|
|
403
398
|
extendNode(DocumentType, {
|
|
404
399
|
nodeType: 10,
|
|
405
|
-
toString
|
|
400
|
+
toString() {
|
|
406
401
|
return "<" + this.data + ">"
|
|
407
402
|
// var node = document.doctype
|
|
408
403
|
// return "<!DOCTYPE " + node.name +
|
|
@@ -420,6 +415,9 @@ function Document() {
|
|
|
420
415
|
}
|
|
421
416
|
|
|
422
417
|
extendNode(Document, Element, {
|
|
418
|
+
get styleSheets() {
|
|
419
|
+
return selector.find(this, "style,link[rel=stylesheet][href]").map(el => el.sheet)
|
|
420
|
+
},
|
|
423
421
|
get title() {
|
|
424
422
|
var el = selector.find(this, "title", 1)
|
|
425
423
|
return el && el.textContent || ""
|
|
@@ -442,15 +440,13 @@ extendNode(Document, Element, {
|
|
|
442
440
|
function DOMParser() {}
|
|
443
441
|
function XMLSerializer() {}
|
|
444
442
|
|
|
445
|
-
DOMParser.prototype.parseFromString =
|
|
443
|
+
DOMParser.prototype.parseFromString = (str, mime) => {
|
|
446
444
|
var doc = new Document()
|
|
447
445
|
doc.contentType = mime || "text/html"
|
|
448
446
|
doc.documentElement.outerHTML = str
|
|
449
447
|
return doc
|
|
450
448
|
}
|
|
451
|
-
XMLSerializer.prototype.serializeToString =
|
|
452
|
-
return doc.toString()
|
|
453
|
-
}
|
|
449
|
+
XMLSerializer.prototype.serializeToString = doc => doc.toString()
|
|
454
450
|
|
|
455
451
|
|
|
456
452
|
function own(Class) {
|
package/interactive.js
CHANGED
package/net.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
/* global unescape */
|
|
2
1
|
|
|
3
2
|
/*! litejs.com/MIT-LICENSE.txt */
|
|
4
3
|
|
|
5
|
-
|
|
6
4
|
var DOM = require(".")
|
|
7
5
|
, URL = require("url").URL
|
|
8
6
|
, parser = new DOM.DOMParser()
|
|
9
|
-
,
|
|
7
|
+
, setState = (xhr, state) => {
|
|
8
|
+
if (xhr.readyState !== state) {
|
|
9
|
+
xhr.readyState = state
|
|
10
|
+
if (xhr.onreadystatechange) xhr.onreadystatechange()
|
|
11
|
+
if (state === xhr.DONE && xhr.onload) xhr.onload()
|
|
12
|
+
}
|
|
13
|
+
}
|
|
10
14
|
|
|
11
15
|
exports.XMLHttpRequest = XMLHttpRequest
|
|
12
16
|
exports.defaultHeaders = {
|
|
@@ -18,14 +22,6 @@ function XMLHttpRequest() {
|
|
|
18
22
|
this._reqHeaders = Object.assign({}, exports.defaultHeaders)
|
|
19
23
|
}
|
|
20
24
|
|
|
21
|
-
function setState(xhr, state) {
|
|
22
|
-
if (xhr.readyState !== state) {
|
|
23
|
-
xhr.readyState = state
|
|
24
|
-
if (xhr.onreadystatechange) xhr.onreadystatechange()
|
|
25
|
-
if (state === xhr.DONE && xhr.onload) xhr.onload()
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
25
|
XMLHttpRequest.prototype = {
|
|
30
26
|
UNSENT: 0,
|
|
31
27
|
OPENED: 1,
|
|
@@ -49,23 +45,23 @@ XMLHttpRequest.prototype = {
|
|
|
49
45
|
parser.parseFromString(xhr.responseText, mime)
|
|
50
46
|
)
|
|
51
47
|
},
|
|
52
|
-
getAllResponseHeaders
|
|
48
|
+
getAllResponseHeaders() {
|
|
53
49
|
var xhr = this
|
|
54
|
-
return xhr.readyState >= xhr.HEADERS_RECEIVED && Object.keys(xhr._headers).map(
|
|
55
|
-
|
|
56
|
-
|
|
50
|
+
return xhr.readyState >= xhr.HEADERS_RECEIVED && Object.keys(xhr._headers).map(
|
|
51
|
+
name => name + ": " + xhr._headers[name] + "\r\n"
|
|
52
|
+
).join("") || null
|
|
57
53
|
},
|
|
58
|
-
getResponseHeader
|
|
54
|
+
getResponseHeader(name) {
|
|
59
55
|
var xhr = this
|
|
60
56
|
return xhr.readyState >= xhr.HEADERS_RECEIVED && xhr._headers[name.toLowerCase()] || null
|
|
61
57
|
},
|
|
62
|
-
setRequestHeader
|
|
58
|
+
setRequestHeader(name, value) {
|
|
63
59
|
this._reqHeaders[name.toLowerCase()] = [name, value]
|
|
64
60
|
},
|
|
65
|
-
abort
|
|
61
|
+
abort() {
|
|
66
62
|
throw Error("XMLHttpRequest abort/reuse not implemented")
|
|
67
63
|
},
|
|
68
|
-
open
|
|
64
|
+
open(method, url, isAsync) {
|
|
69
65
|
var xhr = this
|
|
70
66
|
xhr._sync = isAsync === false
|
|
71
67
|
|
|
@@ -77,20 +73,38 @@ XMLHttpRequest.prototype = {
|
|
|
77
73
|
xhr.responseURL = url
|
|
78
74
|
setState(xhr, xhr.OPENED)
|
|
79
75
|
},
|
|
80
|
-
send
|
|
76
|
+
send(data) {
|
|
81
77
|
var xhr = this
|
|
82
78
|
, url = new URL(xhr.responseURL, XMLHttpRequest.base)
|
|
83
79
|
, proto = url.protocol.slice(0, -1)
|
|
80
|
+
, head = (code, text, headers) => {
|
|
81
|
+
xhr.status = code
|
|
82
|
+
xhr.statusText = text
|
|
83
|
+
xhr._headers = headers
|
|
84
|
+
setState(xhr, xhr.HEADERS_RECEIVED)
|
|
85
|
+
}
|
|
86
|
+
, fillBody = chunk => {
|
|
87
|
+
xhr.responseText += chunk.toString("utf8")
|
|
88
|
+
setState(xhr, xhr.LOADING)
|
|
89
|
+
}
|
|
90
|
+
, done = err => {
|
|
91
|
+
if (err) {
|
|
92
|
+
if (xhr.onerror) xhr.onerror(err)
|
|
93
|
+
else throw err
|
|
94
|
+
}
|
|
95
|
+
else if (xhr._sync) setState(xhr, xhr.DONE)
|
|
96
|
+
else process.nextTick(setState, xhr, xhr.DONE)
|
|
97
|
+
}
|
|
84
98
|
|
|
85
99
|
if (proto === "http" || proto === "https") {
|
|
86
100
|
if (xhr._sync) throw Error("XMLHttpRequest sync not implemented")
|
|
87
101
|
url.method = xhr.method
|
|
88
|
-
url.headers = Object.keys(xhr._reqHeaders).reduce(
|
|
102
|
+
url.headers = Object.keys(xhr._reqHeaders).reduce((result, key) => {
|
|
89
103
|
var entrie = xhr._reqHeaders[key]
|
|
90
104
|
result[entrie[0]] = entrie[1]
|
|
91
105
|
return result
|
|
92
106
|
}, {})
|
|
93
|
-
var req = require(proto).request(url,
|
|
107
|
+
var req = require(proto).request(url, res => {
|
|
94
108
|
head(res.statusCode, res.statusMessage, res.headers)
|
|
95
109
|
res.on("data", fillBody)
|
|
96
110
|
res.on("end", done)
|
|
@@ -100,7 +114,7 @@ XMLHttpRequest.prototype = {
|
|
|
100
114
|
return
|
|
101
115
|
}
|
|
102
116
|
if (proto === "data") {
|
|
103
|
-
var match =
|
|
117
|
+
var match = /^([^;,]*?)(;[^,]+?|),(.*)$/.exec(url.pathname)
|
|
104
118
|
if (match) {
|
|
105
119
|
head(200, "OK", { "content-type": match[1] || "text/plain" })
|
|
106
120
|
fillBody(match[2] ? Buffer.from(match[3], "base64") : unescape(match[3]))
|
|
@@ -110,7 +124,7 @@ XMLHttpRequest.prototype = {
|
|
|
110
124
|
}
|
|
111
125
|
|
|
112
126
|
if (proto === "file") {
|
|
113
|
-
require("fs").readFile(url,
|
|
127
|
+
require("fs").readFile(url, (err, chunk) => {
|
|
114
128
|
if (err) {
|
|
115
129
|
head(404, "Not Found", {})
|
|
116
130
|
} else {
|
|
@@ -128,25 +142,6 @@ XMLHttpRequest.prototype = {
|
|
|
128
142
|
}
|
|
129
143
|
|
|
130
144
|
throw Error("Unsuported protocol in: " + url)
|
|
131
|
-
|
|
132
|
-
function head(code, text, headers) {
|
|
133
|
-
xhr.status = code
|
|
134
|
-
xhr.statusText = text
|
|
135
|
-
xhr._headers = headers
|
|
136
|
-
setState(xhr, xhr.HEADERS_RECEIVED)
|
|
137
|
-
}
|
|
138
|
-
function fillBody(chunk) {
|
|
139
|
-
xhr.responseText += chunk.toString("utf8")
|
|
140
|
-
setState(xhr, xhr.LOADING)
|
|
141
|
-
}
|
|
142
|
-
function done(err) {
|
|
143
|
-
if (err) {
|
|
144
|
-
if (xhr.onerror) xhr.onerror(err)
|
|
145
|
-
else throw err
|
|
146
|
-
}
|
|
147
|
-
else if (xhr._sync) setState(xhr, xhr.DONE)
|
|
148
|
-
else process.nextTick(setState, xhr, xhr.DONE)
|
|
149
|
-
}
|
|
150
145
|
}
|
|
151
146
|
}
|
|
152
147
|
|
package/package.json
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@litejs/dom",
|
|
3
|
-
"version": "24.
|
|
3
|
+
"version": "24.12.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>",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"document",
|
|
9
|
-
"
|
|
10
|
-
"
|
|
9
|
+
"DOM",
|
|
10
|
+
"HTML",
|
|
11
11
|
"DOMParser",
|
|
12
|
+
"CSSOM",
|
|
13
|
+
"CSSStyleSheet",
|
|
12
14
|
"XMLHttpRequest",
|
|
13
15
|
"XMLSerializer",
|
|
14
16
|
"litejs"
|
|
@@ -23,6 +25,6 @@
|
|
|
23
25
|
},
|
|
24
26
|
"repository": "github:litejs/dom",
|
|
25
27
|
"devDependencies": {
|
|
26
|
-
"@litejs/cli": "
|
|
28
|
+
"@litejs/cli": "24.10.0"
|
|
27
29
|
}
|
|
28
30
|
}
|