@litejs/dom 25.5.0 → 25.9.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.
Files changed (4) hide show
  1. package/css.js +6 -30
  2. package/dom.js +16 -14
  3. package/package.json +2 -2
  4. package/selector.js +102 -97
package/css.js CHANGED
@@ -3,7 +3,6 @@
3
3
 
4
4
  "use strict"
5
5
 
6
- exports.selectorSplit = selectorSplit
7
6
  exports.CSSStyleDeclaration = CSSStyleDeclaration
8
7
  exports.CSSStyleSheet = CSSStyleSheet
9
8
 
@@ -15,7 +14,7 @@ var fs = require("fs")
15
14
  var { DOMParser } = require("./dom.js")
16
15
  return v.replace(urlRe, function(_, q1, q2, url) {
17
16
  if (q1) return _
18
- var frag = url.split("#").pop()
17
+ var frag = url.split("#")[1]
19
18
  , ext = url.split(/[?#]/)[0].split(".").pop()
20
19
  , enc = ext === "svg" ? "utf8" : "base64"
21
20
  url = read(sheet, url, enc)
@@ -45,17 +44,15 @@ var fs = require("fs")
45
44
  , clear = s => s
46
45
  .replace(/("|')((?:\\\1|[^\1])*?)\1|\s*(\/)\*(?:[^*]|\*(?!\/))*\*\/\s*|(?:[^"'\/]|\/(?!\*))+/g, clearFn)
47
46
  .replace(/(["']).*?\1|url\(("|')([^'"()\s]+)\2\)/g, (m,q1,q2,u) => q1 ? m : "url(" + u + ")")
47
+ , hex = n => (0 | +n + 256.5).toString(16).slice(1)
48
48
  , toRgb = {
49
- rgb(r, g, b) {
50
- var f = n => ((n | 0) + 256).toString(16).slice(1)
51
- return f(r) + f(g) + f(b)
52
- },
49
+ rgb: (r, g, b) => hex(r) + hex(g) + hex(b),
53
50
  hsl(h, s, l) {
54
51
  l /= 100
55
52
  s /= 100 / (l < 0.5 ? l : 1 - l)
56
53
  function f(n) {
57
54
  n = (n + h / 30) % 12
58
- return (0 | 256.5 + (255 * (l - s * (n < 2 || n > 10 ? -1 : n < 4 ? n - 3 : n > 8 ? 9 - n : 1)))).toString(16).slice(1)
55
+ return hex(255 * (l - s * (n < 2 || n > 10 ? -1 : n < 4 ? n - 3 : n > 8 ? 9 - n : 1)))
59
56
  }
60
57
  return f(0) + f(8) + f(4)
61
58
  }
@@ -89,7 +86,6 @@ var fs = require("fs")
89
86
  for (; (m = re.exec(val)); ) {
90
87
  if (m[4]) {
91
88
  if (min && len && plugins[m[4] = m[4].trim()]) style[k = style[len - 1]] = clear(plugins[m[4]](sheet, style[k]))
92
- continue
93
89
  } else {
94
90
  k = m[1]
95
91
  if (lastIdx[k] >= 0) style.__[lastIdx[k]] = style[k]
@@ -235,10 +231,11 @@ CSSStyleSheet.prototype = {
235
231
  } else if (char === "{") {
236
232
  depth++
237
233
  } else if (char === "}" && --depth < 1 || char === ";" && depth < 1) {
238
- if (depth < 0) throw "Invalid css"
234
+ if (depth < 0) throw Error("Unexpected '}'")
239
235
  sheet.rules.push(CSSRule(text.slice(start, start = pos + 1), sheet, char))
240
236
  }
241
237
  }
238
+ if (depth > 0) throw Error("Unclosed block")
242
239
  },
243
240
  toString(min) {
244
241
  if (min) this.min = min
@@ -246,25 +243,4 @@ CSSStyleSheet.prototype = {
246
243
  }
247
244
  }
248
245
 
249
- function selectorSplit(text) {
250
- for (var char, inQuote, depth = 0, start = 0, pos = 0, len = text.length, out = []; pos < len; ) {
251
- char = text[pos++]
252
- if (char === "\\") {
253
- pos++
254
- } else if (inQuote) {
255
- if (char === inQuote) inQuote = ""
256
- } else if (char === "'" || char === "\"") {
257
- inQuote = char
258
- } else if (char === "(" || char === "[") {
259
- depth++
260
- } else if (char === ")" || char === "]") {
261
- depth--
262
- } else if (char === "," && depth === 0) {
263
- out.push(text.slice(start, (start = pos) - 1).trim())
264
- }
265
- }
266
- out.push(text.slice(start).trim())
267
- return out
268
- }
269
-
270
246
 
package/dom.js CHANGED
@@ -21,8 +21,9 @@ var boolAttrs = {
21
21
  , rawTextElements = { SCRIPT: /<(?=\/script)/i, STYLE: /<(?=\/style)/i }
22
22
  , rawTextEscape = { SCRIPT: /<(?=\/script|!--)/ig, STYLE: /<(?=\/style|!--)/ig }
23
23
  , hasOwn = voidElements.hasOwnProperty
24
- , { selectorSplit, CSSStyleDeclaration, CSSStyleSheet } = require("./css.js")
24
+ , { CSSStyleDeclaration, CSSStyleSheet } = require("./css.js")
25
25
  , selector = require("./selector.js")
26
+ , cssEscape = sel => ("" + sel).replace(/[^a-zA-Z0-9_\u00A0-\uFFFF-]/g, "\\$&").replace(/^(-?)([0-9])/, "$1\\3$2 ")
26
27
  , Node = {
27
28
  ELEMENT_NODE: 1,
28
29
  TEXT_NODE: 3,
@@ -108,17 +109,6 @@ var boolAttrs = {
108
109
  child.setAttribute(name, (q ? qvalue : value || "").replace(unescRe, unescFn))
109
110
  }
110
111
  },
111
- get outerHTML() {
112
- return this.toString()
113
- },
114
- set outerHTML(html) {
115
- var frag = this.ownerDocument.createDocumentFragment()
116
- frag.innerHTML = html
117
- this.parentNode.replaceChild(frag, this)
118
- },
119
- get sheet() {
120
- return makeSheet(this)
121
- },
122
112
  get style() {
123
113
  return this._style || (this._style = CSSStyleDeclaration(this.getAttribute("style") || ""))
124
114
  },
@@ -205,6 +195,14 @@ var boolAttrs = {
205
195
  get previousElementSibling() {
206
196
  return getSibling(this, -1, 1)
207
197
  },
198
+ get outerHTML() {
199
+ return this.toString()
200
+ },
201
+ set outerHTML(html) {
202
+ var frag = this.ownerDocument.createDocumentFragment()
203
+ frag.innerHTML = html
204
+ this.parentNode.replaceChild(frag, this)
205
+ },
208
206
  replaceChildren() {
209
207
  removeChilds(this)
210
208
  for (var i = 0, l = arguments.length; i < l; ) this.insertBefore(arguments[i++])
@@ -261,7 +259,7 @@ function addGetter(key, opts) {
261
259
  })
262
260
  }
263
261
 
264
- ;["hasAttribute", "getAttribute", "setAttribute", "removeAttribute"].forEach(function(name) {
262
+ ;["hasAttribute", "getAttribute", "setAttribute", "removeAttribute"].forEach(name => {
265
263
  Element[name + "NS"] = function(ns, a, b) {
266
264
  return this[name].call(this, a, b)
267
265
  }
@@ -350,6 +348,9 @@ extendNode(HTMLElement, Element, {
350
348
  namespaceURI: "http://www.w3.org/1999/xhtml",
351
349
  nodeType: 1,
352
350
  tagName: null,
351
+ get sheet() {
352
+ return makeSheet(this)
353
+ },
353
354
  blur() {
354
355
  this.ownerDocument.activeElement = null
355
356
  },
@@ -521,7 +522,8 @@ function mergeAttributes(source, target) {
521
522
  exports.document = new Document()
522
523
  exports.entities = entities
523
524
  exports.mergeAttributes = mergeAttributes
524
- exports.selectorSplit = selectorSplit
525
+ exports.selectorSplit = selector.selectorSplit
526
+ exports.cssEscape = cssEscape
525
527
  exports.CSSStyleDeclaration = CSSStyleDeclaration
526
528
  exports.CSSStyleSheet = CSSStyleSheet
527
529
  exports.DOMParser = DOMParser
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@litejs/dom",
3
- "version": "25.5.0",
3
+ "version": "25.9.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>",
@@ -22,7 +22,7 @@
22
22
  "scripts": {
23
23
  "test": "lj t"
24
24
  },
25
- "repository": "github:litejs/dom",
25
+ "repository": "https://github.com/litejs/dom.git",
26
26
  "devDependencies": {
27
27
  "@litejs/cli": "25.1.0"
28
28
  }
package/selector.js CHANGED
@@ -3,112 +3,117 @@
3
3
 
4
4
  "use strict"
5
5
 
6
- !function(exports) {
7
- var selectorCache = {
8
- "": function() {}
9
- }
10
- , selectorRe = /([.#:[])([-\w]+)(?:\(((?:[^()]|\([^)]+\))+?)\)|([~^$*|]?)=(("|')(?:\\.|[^\\])*?\6|[-\w]+))?]?/g
11
- , selectorLastRe = /([\s>+~]*)(?:("|')(?:\\.|[^\\])*?\2|\((?:[^()]|\([^()]+\))+?\)|~=|[^'"()\s>+~])+$/
12
- , selectorSplitRe = /\s*,\s*(?=(?:[^'"()]|"(?:\\.|[^\\"])*?"|'(?:\\.|[^\\'])*?'|\((?:[^()]|\([^()]+\))+?\))+$)/
13
- , selectorMap = {
14
- "contains": "_.textContent.indexOf(v)>-1",
15
- "empty": "!_.lastChild",
16
- "enabled": "!m(_,':disabled')",
17
- "first-child": "(a=_.parentNode)&&a.firstChild==_",
18
- "first-of-type": "!p(_,_.tagName)",
19
- "is": "m(_,v)",
20
- "lang": "m(c(_,'[lang]'),'[lang|='+v+']')",
21
- "last-child": "(a=_.parentNode)&&a.lastChild==_",
22
- "last-of-type": "!n(_,_.tagName)",
23
- "link": "m(_,'a[href]')",
24
- "not": "!m(_,v)",
25
- "nth-child": "(a=2,'odd'==v?b=1:'even'==v?b=0:a=1 in(v=v.split('n'))?(b=v[1],v[0]):(b=v[0],0),v=_.parentNode.childNodes,v=1+v.indexOf(_),0==a?v==b:('-'==a||0==(v-b)%a)&&(0<a||v<=b))",
26
- "only-child": "(a=_.parentNode)&&a.firstChild==a.lastChild",
27
- "only-of-type": "!p(_,_.tagName)&&!n(_,_.tagName)",
28
- "optional": "!m(_,':required')",
29
- "root": "(a=_.parentNode)&&!a.tagName",
30
- ".": "~_.className.split(/\\s+/).indexOf(a)",
31
- "#": "_.id==a",
32
- "^": "!a.indexOf(v)",
33
- "|": "a.split('-')[0]==v",
34
- "$": "a.slice(-v.length)==v",
35
- "~": "~a.split(/\\s+/).indexOf(v)",
36
- "*": "~a.indexOf(v)",
37
- ">>": "m(_.parentNode,v)",
38
- "++": "m(_.previousSibling,v)",
39
- "~~": "p(_,v)",
40
- "": "c(_.parentNode,v)"
41
- }
42
- , closest = exports.closest = walk.bind(exports, "parentNode", 1)
6
+ exports.find = find
7
+ exports.selectorSplit = selectorSplit
43
8
 
9
+ var selectorCache = {
10
+ "": () => {}
11
+ }
12
+ , selectorRe = /([.#:[])([-\w]+)(?:\(((?:[^()]|\([^)]+\))+?)\)|([~^$*|]?)=(("|')(?:\\.|[^\\])*?\6|[-\w]+))?]?/g
13
+ , selectorLastRe = /([\s>+~]*)(?:("|')(?:\\.|[^\\])*?\2|\((?:[^()]|\([^()]+\))+?\)|~=|[^'"()\s>+~])+$/
14
+ , selectorMap = exports.selectorMap = {
15
+ "contains": "_.textContent.indexOf(v)>-1",
16
+ "empty": "!_.lastChild",
17
+ "enabled": "!m(_,':disabled')",
18
+ "first-child": "(a=_.parentNode)&&a.firstChild==_",
19
+ "first-of-type": "!p(_,_.tagName)",
20
+ "is": "m(_,v)",
21
+ "lang": "m(c(_,'[lang]'),'[lang|='+v+']')",
22
+ "last-child": "(a=_.parentNode)&&a.lastChild==_",
23
+ "last-of-type": "!n(_,_.tagName)",
24
+ "link": "m(_,'a[href]')",
25
+ "not": "!m(_,v)",
26
+ "nth-child": "(a=2,'odd'==v?b=1:'even'==v?b=0:a=1 in(v=v.split('n'))?(b=v[1],v[0]):(b=v[0],0),v=_.parentNode.childNodes,v=1+v.indexOf(_),0==a?v==b:('-'==a||0==(v-b)%a)&&(0<a||v<=b))",
27
+ "only-child": "(a=_.parentNode)&&a.firstChild==a.lastChild",
28
+ "only-of-type": "!p(_,_.tagName)&&!n(_,_.tagName)",
29
+ "optional": "!m(_,':required')",
30
+ "root": "(a=_.parentNode)&&!a.tagName",
31
+ ".": "~_.className.split(/\\s+/).indexOf(a)",
32
+ "#": "_.id==a",
33
+ "^": "!a.indexOf(v)",
34
+ "|": "a.split('-')[0]==v",
35
+ "$": "a.slice(-v.length)==v",
36
+ "~": "~a.split(/\\s+/).indexOf(v)",
37
+ "*": "~a.indexOf(v)",
38
+ ">>": "m(_.parentNode,v)",
39
+ "++": "m(_.previousElementSibling,v)",
40
+ "~~": "p(_,v)",
41
+ "": "c(_.parentNode,v)"
42
+ }
43
+ , closest = exports.closest = walk.bind(exports, "parentNode", 1)
44
+ , matches = exports.matches = (el, sel) => !!selectorFn(sel)(el)
45
+ , next = exports.next = (el, sel) => walk("nextSibling", 1, el.nextSibling, sel)
46
+ , prev = exports.prev = (el, sel) => walk("previousSibling", 1, el.previousSibling, sel)
44
47
 
45
- selectorMap["nth-last-child"] = selectorMap["nth-child"].replace("1+", "v.length-")
46
48
 
47
- function selectorFn(str) {
48
- if (str != null && typeof str !== "string") throw Error("Invalid selector")
49
- return selectorCache[str || ""] ||
50
- (selectorCache[str] = Function("m,c,n,p", "return function(_,v,a,b){return " +
51
- str.split(selectorSplitRe).map(function(sel) {
52
- var relation, from
53
- , rules = ["_&&_.nodeType==1"]
54
- , parentSel = sel.replace(selectorLastRe, function(_, _rel, a, start) {
55
- from = start + _rel.length
56
- relation = _rel.trim()
57
- return ""
58
- })
59
- , tag = sel.slice(from).replace(selectorRe, function(_, op, key, subSel, fn, val, quotation) {
60
- rules.push(
61
- "((v='" +
62
- (subSel || (quotation ? val.slice(1, -1) : val) || "").replace(/[\\']/g, "\\$&") +
63
- "'),(a='" + key + "'),1)"
64
- ,
65
- selectorMap[op == ":" ? key : op] ||
66
- "(a=_.getAttribute(a))" +
67
- (fn ? "&&" + selectorMap[fn] : val ? "==v" : "!==null")
68
- )
69
- return ""
70
- })
49
+ selectorMap["nth-last-child"] = selectorMap["nth-child"].replace("1+", "v.length-")
71
50
 
72
- if (tag && tag != "*") rules[0] += "&&_.tagName==(_.namespaceURI?'" + tag.toUpperCase() + "':'" + tag + "')"
73
- if (parentSel) rules.push("(v='" + parentSel + "')", selectorMap[relation + relation])
74
- return rules.join("&&")
75
- }).join("||") + "}"
76
- )(matches, closest, next, prev))
77
- }
51
+ function selectorFn(str) {
52
+ if (str != null && typeof str !== "string") throw Error("Invalid selector")
53
+ return selectorCache[str || ""] ||
54
+ (selectorCache[str] = Function("m,c,n,p", "return (_,v,a,b)=>" +
55
+ selectorSplit(str).map(sel => {
56
+ var relation, from
57
+ , rules = ["_&&_.nodeType==1"]
58
+ , parentSel = sel.replace(selectorLastRe, (_, _rel, a, start) => {
59
+ from = start + _rel.length
60
+ relation = _rel.trim()
61
+ return ""
62
+ })
63
+ , tag = sel.slice(from).replace(selectorRe, (_, op, key, subSel, fn, val, quotation) => {
64
+ rules.push(
65
+ "((v='" +
66
+ (subSel || (quotation ? val.slice(1, -1) : val) || "").replace(/[\\']/g, "\\$&") +
67
+ "'),(a='" + key + "'),1)"
68
+ ,
69
+ selectorMap[op == ":" ? key : op] ||
70
+ "(a=_.getAttribute(a))" +
71
+ (fn ? "&&" + selectorMap[fn] : val ? "==v" : "!==null")
72
+ )
73
+ return ""
74
+ })
78
75
 
76
+ if (tag && tag != "*") rules[0] += "&&_.tagName==(_.namespaceURI?'" + tag.toUpperCase() + "':'" + tag + "')"
77
+ if (parentSel) rules.push("(v='" + parentSel + "')", selectorMap[relation + relation])
78
+ return rules.join("&&")
79
+ }).join("||")
80
+ )(matches, closest, next, prev))
81
+ }
79
82
 
80
- function walk(next, first, el, sel, nextFn) {
81
- sel = selectorFn(sel)
82
- for (var out = []; el; el = el[next] || nextFn && nextFn(el)) if (sel(el)) {
83
- if (first) return el
84
- out.push(el)
83
+ function selectorSplit(text) {
84
+ for (var char, inQuote, depth = 0, start = 0, pos = 0, len = text.length, out = []; pos < len; ) {
85
+ char = text[pos++]
86
+ if (char === "\\") {
87
+ pos++
88
+ } else if (inQuote) {
89
+ if (char === inQuote) inQuote = ""
90
+ } else if (char === "'" || char === "\"") {
91
+ inQuote = char
92
+ } else if (char === "(" || char === "[") {
93
+ depth++
94
+ } else if (char === ")" || char === "]") {
95
+ depth--
96
+ } else if (char === "," && depth === 0) {
97
+ out.push(text.slice(start, (start = pos) - 1).trim())
85
98
  }
86
- return first ? null : out
87
- }
88
-
89
- function find(node, sel, first) {
90
- return walk("firstChild", first, node.firstChild, sel, function(el) {
91
- for (var next = el.nextSibling; !next && ((el = el.parentNode) !== node); ) next = el.nextSibling
92
- return next
93
- })
94
- }
95
-
96
- function matches(el, sel) {
97
- return !!selectorFn(sel)(el)
98
- }
99
-
100
- function next(el, sel) {
101
- return walk("nextSibling", 1, el.nextSibling, sel)
102
99
  }
100
+ out.push(text.slice(start).trim())
101
+ return out
102
+ }
103
103
 
104
- function prev(el, sel) {
105
- return walk("previousSibling", 1, el.previousSibling, sel)
104
+ function walk(attr, first, el, sel, nextFn) {
105
+ sel = selectorFn(sel)
106
+ for (var out = []; el; el = el[attr] || nextFn && nextFn(el)) if (sel(el)) {
107
+ if (first) return el
108
+ out.push(el)
106
109
  }
110
+ return first ? null : out
111
+ }
107
112
 
108
- exports.find = find
109
- exports.matches = matches
110
- exports.next = next
111
- exports.prev = prev
112
- exports.selectorMap = selectorMap
113
- }(this) // jshint ignore:line
113
+ function find(node, sel, first) {
114
+ return walk("firstChild", first, node.firstChild, sel, (el, pos) => {
115
+ for (pos = el.nextSibling; !pos && ((el = el.parentNode) !== node); ) pos = el.nextSibling
116
+ return pos
117
+ })
118
+ }
114
119