@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 CHANGED
@@ -51,9 +51,10 @@ xhr.onload = function() {
51
51
  xhr.send();
52
52
 
53
53
  // Minify CSS
54
- const sheet = new CSSStyleSheet({ min: { color: true } })
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(sheet.toString())
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
- var fs = require("fs")
10
- , path = require("path")
11
- , read = (sheet, url, enc = "utf8") => fs.readFileSync(path.resolve(sheet.min.root || "", sheet.baseURI, url).split(/[+#]/)[0], enc)
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(sheet, v) {
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(sheet, url, enc)
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(/ *([,;{}>~+\/]) */g, "$1")
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(/("|')((?:\\\1|[^\1])*?)\1|\s*(\/)\*(?:[^*]|\*(?!\/))*\*\/\s*|(?:[^"'\/]|\/(?!\*))+/g, clearFn)
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 min = style.parentRule && style.parentRule.parentStyleSheet.min
67
- for (var out = [], i = style.length; i--; ) {
68
- out[i] = joinProp(style[i], style.__[i] || style[style[i]])
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 (min && len && plugins[m[4] = m[4].trim()]) style[k = style[len - 1]] = clear(plugins[m[4]](sheet, style[k]))
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
- var sheet = this.parentStyleSheet
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 style = new CSSStyleSheet({})
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 = path.join(
189
- (opts.parentStyleSheet || opts.ownerNode && opts.ownerNode.ownerDocument).baseURI || "",
190
- opts.href,
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(min) {
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:1, defer:1, disabled:1, muted:1, multiple:1, nomodule:1, playsinline:1, readonly:1, required:1, selected:1
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 maxLength minLength size tabIndex width"
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 || true) + "\n" :
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
  "&sect;": "§", "&sup2;": "²", "&sup3;": "³", "&yen;": "¥"
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() { return +this.getAttribute(attr) || 0 } :
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.setAttribute(attr, value)
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
- return this[name].call(this, a, b)
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.defineProperty(this, "length", { get() { return this.names().length } })
276
- Object.defineProperty(this, "ownerElement", { value: node })
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 descriptor, key, i = 1; (extras = arguments[i++]); ) {
482
- for (key in extras) {
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, type) {
538
+ function getElement(childs, index, step) {
496
539
  if (childs && index > -1) for (; childs[index]; index += step) {
497
- if (childs[index].nodeType === type) return childs[index]
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 > 0 ? getElement(silbings, index + step, step, type) : silbings && silbings[index + step] || null
548
+ return type ? getElement(silbings, index + step, step) : silbings && silbings[index + step] || null
506
549
  }
507
550
 
508
- function makeSheet(el, min) {
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.cssEscape = cssEscape
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": "25.9.2",
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 != null && typeof str !== "string") throw Error("Invalid selector")
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, "\\$&") +
@@ -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
+ }