@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 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
- const { document, DOMParser, XMLSerializer } = require("@litejs/dom");
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 document = xhr.responseXML;
47
+ const doc = xhr.responseXML;
52
48
  // Work with DOM in familiar way
53
- console.log(document.querySelector("title").textContent);
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
- // CSSStyleDeclaration is a single CSS declaration block,
7
- // accessible via HTMLElement.style for inline styles, document.styleSheets[0].cssRules[0].style, and getComputedStyle()
8
- function CSSStyleDeclaration(style) {
9
- this.cssText = style
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
- CSSStyleDeclaration.prototype = {
13
- get cssText() {
14
- return Object.keys(this).map(function(key) {
15
- return (key === "cssFloat" ? "float:" : hyphenCase(key) + ":") + this[key]
16
- }, this).join(";")
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
- set cssText(style) {
19
- for (var m, re = /(?:^|;)\s*([-a-z]+)\s*:((?:("|')(?:\\.|(?!\3)[^\\])*?\3|[^"';])+)(?=;|$)/ig; (m = re.exec(style)); ) {
20
- this[m[1] === "float" ? "cssFloat" : camelCase(m[1])] = m[2].trim()
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 camelCase(str) {
26
- return str.replace(/-([a-z])/g, function(_, a) { return a.toUpperCase() })
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 hyphenCase(str) {
30
- return str.replace(/[A-Z]/g, "-$&").toLowerCase()
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").CSSStyleDeclaration
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(function(child) {
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 = new CSSStyleDeclaration(this.getAttribute("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: function (el) {
121
+ contains(el) {
118
122
  for (; el; el = el.parentNode) if (el === this) return true
119
123
  return false
120
124
  },
121
- hasChildNodes: function() {
122
- return this.childNodes && this.childNodes.length > 0
125
+ hasChildNodes() {
126
+ return !!this.firstChild
123
127
  },
124
- getElementById: function(id) {
128
+ getElementById(id) {
125
129
  return selector.find(this, "#" + id, 1)
126
130
  },
127
- appendChild: function(el) {
131
+ appendChild(el) {
128
132
  return this.insertBefore(el)
129
133
  },
130
- insertBefore: function(el, ref) {
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: function(el) {
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: function(el, ref) {
162
+ replaceChild(el, ref) {
159
163
  this.insertBefore(el, ref)
160
164
  return this.removeChild(ref)
161
165
  },
162
- cloneNode: function(deep) {
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(function(attr) {
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(function(child) {
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: function(sel) {
180
+ querySelector(sel) {
181
181
  return selector.find(this, sel, 1)
182
182
  },
183
- querySelectorAll: function(sel) {
183
+ querySelectorAll(sel) {
184
184
  return selector.find(this, sel)
185
185
  },
186
- toString: function(minify) {
187
- return rawTextElements[this.tagName] ? this.textContent : this.childNodes.reduce(function(memo, node) {
188
- return memo + node.toString(minify)
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: function(name) {
207
+ hasAttribute(name) {
207
208
  return this.attributes.getNamedItem(name) != null
208
209
  },
209
- getAttribute: function(name) {
210
+ getAttribute(name) {
210
211
  var attr = this.attributes.getNamedItem(name)
211
212
  return attr ? attr.value : null
212
213
  },
213
- setAttribute: function(name, value) {
214
+ setAttribute(name, value) {
214
215
  this.attributes.setNamedItem(new Attr(this, name, value))
215
216
  },
216
- removeAttribute: function(name) {
217
+ removeAttribute(name) {
217
218
  this.attributes.removeNamedItem(name)
218
219
  },
219
- getElementsByTagName: function(tag) {
220
+ getElementsByTagName(tag) {
220
221
  return selector.find(this, tag)
221
222
  },
222
- getElementsByClassName: function(sel) {
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 === "<" ? "&lt;" : "&amp;"
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
  "&amp;": "&", "&apos;": "'", "&cent;": "¢", "&copy;": "©", "&curren;": "¤",
231
234
  "&deg;": "°", "&euro;": "€", "&gt;": ">", "&lt;": "<", "&nbsp;": " ",
@@ -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: function(value) {
253
+ set(value) {
251
254
  this.setAttribute(attr, value)
252
255
  }
253
256
  })
254
257
  }
255
258
 
256
- function escFn(chr) {
257
- return chr === "<" ? "&lt;" : "&amp;"
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: function() { return this.names().length } })
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: function() {
277
+ names() {
283
278
  this.getNamedItem("style")
284
279
  return Object.keys(this)
285
280
  },
286
- getNamedItem: function(name) {
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: function(name) {
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: function(attr) {
297
+ setNamedItem(attr) {
303
298
  var oldAttr = this.getNamedItem(attr.name)
304
- if (attr.name === "style") attr.value = new CSSStyleDeclaration(attr.value).cssText
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: function(minify) {
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(function(loName) {
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: function(sel) {
344
+ matches(sel) {
350
345
  return selector.matches(this, sel)
351
346
  },
352
- closest: function(sel) {
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: function(minify) {
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: function(minify) {
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: function(minify) {
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: function() {
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 = function(str, mime) {
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 = function(doc) {
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
@@ -5,10 +5,10 @@
5
5
 
6
6
  var DOM = module.exports = require(".")
7
7
  , HTMLElementExtra = {
8
- focus: function() {
8
+ focus() {
9
9
  this.ownerDocument.activeElement = this
10
10
  },
11
- blur: function() {
11
+ blur() {
12
12
  this.ownerDocument.activeElement = null
13
13
  }
14
14
  }
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
- , dataUrlRe = /^([^;,]*?)(;[^,]+?|),(.*)$/
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: function () {
48
+ getAllResponseHeaders() {
53
49
  var xhr = this
54
- return xhr.readyState >= xhr.HEADERS_RECEIVED && Object.keys(xhr._headers).map(function(name) {
55
- return name + ": " + xhr._headers[name] + "\r\n"
56
- }).join("") || null
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: function (name) {
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: function(name, value) {
58
+ setRequestHeader(name, value) {
63
59
  this._reqHeaders[name.toLowerCase()] = [name, value]
64
60
  },
65
- abort: function() {
61
+ abort() {
66
62
  throw Error("XMLHttpRequest abort/reuse not implemented")
67
63
  },
68
- open: function (method, url, isAsync) {
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: function (data) {
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(function(result, key) {
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, function(res) {
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 = dataUrlRe.exec(url.pathname)
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, function(err, chunk) {
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.8.0",
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
- "dom",
10
- "html",
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": "23.11.1"
28
+ "@litejs/cli": "24.10.0"
27
29
  }
28
30
  }