@litejs/dom 25.12.0 → 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,
@@ -140,8 +140,8 @@ var boolAttrs = {
140
140
  var node = this
141
141
  if (node === other) return 0
142
142
  if (node.getRootNode() !== other.getRootNode()) return Node.DOCUMENT_POSITION_DISCONNECTED
143
- if (node.contains(other)) return Node.DOCUMENT_POSITION_CONTAINS
144
- if (other.contains(node)) return Node.DOCUMENT_POSITION_CONTAINED_BY
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
145
 
146
146
  for (; node; node = node.nextSibling || node.parentNode && node.parentNode.nextSibling) {
147
147
  if (node === other) return Node.DOCUMENT_POSITION_FOLLOWING
@@ -199,7 +199,7 @@ var boolAttrs = {
199
199
  },
200
200
  toString(min) {
201
201
  return rawTextElements[this.tagName] ? (
202
- 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" :
203
203
  this.textContent
204
204
  ) : this.childNodes.map(node => node.toString(min)).join("")
205
205
  },
@@ -277,8 +277,9 @@ var boolAttrs = {
277
277
  "&sect;": "§", "&sup2;": "²", "&sup3;": "³", "&yen;": "¥"
278
278
  }
279
279
 
280
- 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" }))
281
281
  numAttrs.split(" ").forEach(key => addGetter(key, { isNum: true }))
282
+ numAttrsNeg.split(" ").forEach(key => addGetter(key, { isNum: true, numDefault: -1 }))
282
283
  strAttrs.split(" ").forEach(key => addGetter(key, { "for": "htmlFor", "class": "className" }))
283
284
 
284
285
  function addGetter(key, opts) {
@@ -287,19 +288,28 @@ function addGetter(key, opts) {
287
288
  configurable: true,
288
289
  enumerable: true,
289
290
  get: (
291
+ opts.isDirty ? function() { return "_" + attr in this ? this["_" + attr] : this.hasAttribute(attr) } :
290
292
  opts.isBool ? function() { return this.hasAttribute(attr) } :
291
- 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) } :
292
294
  function() { return this.getAttribute(attr) || "" }
293
295
  ),
294
296
  set(value) {
295
- 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)
296
300
  }
297
301
  })
298
302
  }
299
303
 
300
304
  ;["hasAttribute", "getAttribute", "setAttribute", "removeAttribute"].forEach(name => {
301
305
  Element[name + "NS"] = function(ns, a, b) {
302
- 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)
303
313
  }
304
314
  })
305
315
 
@@ -310,8 +320,10 @@ function Attr(node, name, value) {
310
320
  }
311
321
 
312
322
  function NamedNodeMap(node) {
313
- Object.defineProperty(this, "length", { get() { return this.names().length } })
314
- Object.defineProperty(this, "ownerElement", { value: node })
323
+ Object.defineProperties(this, {
324
+ length: { get() { return this.names().length } },
325
+ ownerElement: { value: node }
326
+ })
315
327
  }
316
328
 
317
329
  NamedNodeMap.prototype = {
@@ -390,7 +402,7 @@ extendNode(HTMLElement, Element, {
390
402
  return makeSheet(this)
391
403
  },
392
404
  blur() {
393
- this.ownerDocument.activeElement = null
405
+ this.ownerDocument.activeElement = this.ownerDocument.body || null
394
406
  },
395
407
  closest(sel) {
396
408
  return selector.closest(this, sel)
@@ -422,7 +434,7 @@ function ElementNS(namespace, tag) {
422
434
  ElementNS.prototype = HTMLElement.prototype
423
435
 
424
436
  function Text(data) {
425
- this.data = data
437
+ this.data = "" + data
426
438
  }
427
439
 
428
440
  extendNode(Text, {
@@ -453,11 +465,6 @@ extendNode(DocumentType, {
453
465
  nodeType: 10,
454
466
  toString() {
455
467
  return "<" + this.data + ">"
456
- // var node = document.doctype
457
- // return "<!DOCTYPE " + node.name +
458
- // (node.publicId ? ' PUBLIC "' + node.publicId + '"' : '') +
459
- // (!node.publicId && node.systemId ? ' SYSTEM' : '') +
460
- // (node.systemId ? ' "' + node.systemId + '"' : '') + '>'
461
468
  }
462
469
  })
463
470
 
@@ -517,11 +524,8 @@ function own(Class) {
517
524
 
518
525
  function extendNode(obj, extras) {
519
526
  obj.prototype = Object.create(Node)
520
- for (var descriptor, key, i = 1; (extras = arguments[i++]); ) {
521
- for (key in extras) {
522
- descriptor = Object.getOwnPropertyDescriptor(extras, key)
523
- Object.defineProperty(obj.prototype, key, descriptor)
524
- }
527
+ for (var i = 1; (extras = arguments[i++]); ) {
528
+ Object.defineProperties(obj.prototype, Object.getOwnPropertyDescriptors(extras))
525
529
  }
526
530
  obj.prototype.constructor = obj
527
531
  }
@@ -531,9 +535,9 @@ function removeChilds(node) {
531
535
  node.childNodes.length = 0
532
536
  }
533
537
 
534
- function getElement(childs, index, step, type) {
538
+ function getElement(childs, index, step) {
535
539
  if (childs && index > -1) for (; childs[index]; index += step) {
536
- if (childs[index].nodeType === type) return childs[index]
540
+ if (childs[index].nodeType === 1) return childs[index]
537
541
  }
538
542
  return null
539
543
  }
@@ -541,14 +545,13 @@ function getElement(childs, index, step, type) {
541
545
  function getSibling(node, step, type) {
542
546
  var silbings = node.parentNode && node.parentNode.childNodes
543
547
  , index = silbings ? silbings.indexOf(node) : -1
544
- 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
545
549
  }
546
550
 
547
- function makeSheet(el, min) {
551
+ function makeSheet(el) {
548
552
  if (el.tagName === "STYLE" || el.tagName === "LINK" && el.rel === "stylesheet" && el.href) return new CSSStyleSheet({
549
553
  href: el.href,
550
- ownerNode: el,
551
- min
554
+ ownerNode: el
552
555
  }, el.tagName === "STYLE" && el.textContent)
553
556
  }
554
557
 
@@ -562,7 +565,7 @@ exports.document = new Document()
562
565
  exports.entities = entities
563
566
  exports.mergeAttributes = mergeAttributes
564
567
  exports.selectorSplit = selector.selectorSplit
565
- exports.cssEscape = cssEscape
568
+ exports.CSS = CSS
566
569
  exports.CSSStyleDeclaration = CSSStyleDeclaration
567
570
  exports.CSSStyleSheet = CSSStyleSheet
568
571
  exports.DOMParser = DOMParser
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@litejs/dom",
3
- "version": "25.12.0",
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>",
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, "\\$&") +
package/types/index.d.ts CHANGED
@@ -188,4 +188,7 @@ export const document: Document
188
188
  export const entities: Record<string, string>
189
189
  export function mergeAttributes(source: HTMLElement | null, target: HTMLElement | null): void
190
190
  export function selectorSplit(selector: string): string[]
191
- export function cssEscape(selector: string | number): string
191
+ export const CSS: {
192
+ escape(selector: string | number): string
193
+ minify(sheet: CSSStyleSheet, min?: { color?: boolean }): string
194
+ }