@litejs/dom 23.2.2

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 ADDED
@@ -0,0 +1,88 @@
1
+
2
+ [1]: https://badgen.net/coveralls/c/github/litejs/dom
3
+ [2]: https://coveralls.io/r/litejs/dom
4
+ [3]: https://badgen.net/packagephobia/install/@litejs/dom
5
+ [4]: https://packagephobia.now.sh/result?p=@litejs/dom
6
+ [5]: https://badgen.net/badge/icon/Buy%20Me%20A%20Tea/orange?icon=kofi&label
7
+ [6]: https://www.buymeacoffee.com/lauriro
8
+
9
+
10
+ LiteJS DOM – [![Coverage][1]][2] [![Size][3]][4] [![Buy Me A Tea][5]][6]
11
+ ==========
12
+
13
+ A small DOM library for server-side testing, rendering, and handling of HTML files.
14
+
15
+
16
+ Examples
17
+ --------
18
+
19
+ ```javascript
20
+ const { document, DOMParser, XMLSerializer } = require("@litejs/dom");
21
+ const { XMLHttpRequest } = require("@litejs/dom/xmlhttprequest");
22
+
23
+ // Use XMLHttpRequest in server side
24
+ var xhr = new XMLHttpRequest()
25
+ xhr.open("GET", "https://litejs.com")
26
+ xhr.responseType = "document"
27
+ xhr.onload = function() {
28
+ var doc = xhr.responseXML
29
+ // Work with DOM in familiar way
30
+ console.log(doc.querySelector("title").textContent)
31
+ }
32
+ xhr.send()
33
+
34
+ // Build DOM manually
35
+ const el = document.createElement("h1");
36
+ el.id = 123;
37
+ el.className = "large";
38
+
39
+ const fragment = document.createDocumentFragment();
40
+ const text1 = document.createTextNode("hello");
41
+ const text2 = document.createTextNode(" world");
42
+
43
+ fragment.appendChild(text1);
44
+ fragment.appendChild(text2);
45
+ el.appendChild(fragment);
46
+
47
+ el.innerHTML;
48
+ // hello world
49
+ el.innerHTML = "<b>hello world</b>";
50
+ el.toString();
51
+ // <h1 id="123" class="large"><b>hello world</b></h1>
52
+
53
+ // minify output
54
+ el.toString(true);
55
+ // <h1 id=123 class=large><b>hello world</b></h1>
56
+
57
+ el.querySelectorAll("b");
58
+ // [ "<b>hello world</b>" ]
59
+ ```
60
+
61
+ ## Contributing
62
+
63
+ Follow [Coding Style Guide](https://github.com/litejs/litejs/wiki/Style-Guide)
64
+
65
+ Run tests
66
+
67
+ ```
68
+ npm install
69
+ npm test
70
+ ```
71
+
72
+
73
+ ## External links
74
+
75
+ [GitHub repo](https://github.com/litejs/dom) |
76
+ [npm package](https://npmjs.org/package/@litejs/dom) |
77
+ [DOM spec](https://dom.spec.whatwg.org/) |
78
+ [Selectors Level 3](http://www.w3.org/TR/selectors/) |
79
+ [Coveralls coverage][2]
80
+ [Buy Me A Tea][6]
81
+
82
+
83
+ ## Licence
84
+
85
+ Copyright (c) 2014-2023 Lauri Rooden &lt;lauri@rooden.ee&gt;
86
+ [The MIT License](http://lauri.rooden.ee/mit-license.txt)
87
+
88
+
package/index.js ADDED
@@ -0,0 +1,489 @@
1
+
2
+
3
+ /**
4
+ * @author Lauri Rooden <lauri@rooden.ee>
5
+ * @license MIT License
6
+ */
7
+
8
+
9
+ var boolAttrs = {
10
+ 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
11
+ }
12
+ , defaultAttrs = {
13
+ "form method get":1, "input type text":1,
14
+ "script type text/javascript":1, "style type text/css": 1
15
+ }
16
+ , voidElements = {
17
+ AREA:1, BASE:1, BR:1, COL:1, EMBED:1, HR:1, IMG:1, INPUT:1, KEYGEN:1, LINK:1, MENUITEM:1, META:1, PARAM:1, SOURCE:1, TRACK:1, WBR:1
18
+ }
19
+ , rawTextElements = { SCRIPT: /<(?=\/script)/i, STYLE: /<(?=\/style)/i }
20
+ , rawTextEscape = { SCRIPT: /<(?=\/script|!--)/ig, STYLE: /<(?=\/style|!--)/ig }
21
+ , hasOwn = voidElements.hasOwnProperty
22
+ , selector = require("./selector.js")
23
+ , Node = {
24
+ ELEMENT_NODE: 1,
25
+ TEXT_NODE: 3,
26
+ PROCESSING_INSTRUCTION_NODE: 7,
27
+ COMMENT_NODE: 8,
28
+ DOCUMENT_NODE: 9,
29
+ DOCUMENT_TYPE_NODE: 10,
30
+ DOCUMENT_FRAGMENT_NODE: 11,
31
+ nodeName: null,
32
+ parentNode: null,
33
+ ownerDocument: null,
34
+ childNodes: null,
35
+ get nodeValue() {
36
+ return this.nodeType === 3 || this.nodeType === 8 ? this.data : null
37
+ },
38
+ set nodeValue(text) {
39
+ return this.nodeType === 3 || this.nodeType === 8 ? (this.data = text) : null
40
+ },
41
+ get textContent() {
42
+ return this.nodeType === 3 || this.nodeType === 8 ? this.data : this.childNodes.map(function(child) {
43
+ return child.textContent
44
+ }).join("")
45
+ },
46
+ set textContent(text) {
47
+ if (this.nodeType === 3 || this.nodeType === 8) return (this.data = text)
48
+ replaceChildren.call(this, this.ownerDocument.createTextNode(
49
+ rawTextEscape[this.tagName] ? text.replace(rawTextEscape[this.tagName], "<\\") : text
50
+ ))
51
+ },
52
+ get firstChild() {
53
+ return this.childNodes && this.childNodes[0] || null
54
+ },
55
+ get lastChild() {
56
+ return this.childNodes && this.childNodes[ this.childNodes.length - 1 ] || null
57
+ },
58
+ get nextSibling() {
59
+ return getSibling(this, 1, 0)
60
+ },
61
+ get previousSibling() {
62
+ return getSibling(this, -1, 0)
63
+ },
64
+ // innerHTML and outerHTML should be extensions to the Element interface
65
+ get innerHTML() {
66
+ return Node.toString.call(this)
67
+ },
68
+ set innerHTML(html) {
69
+ var child, m, re, text
70
+ , node = this
71
+ , doc = node.ownerDocument || node
72
+ , tagRe = /<(!--([\s\S]*?)--!?|!\[CDATA\[([\s\S]*?)\]\]|[?!][\s\S]*?)>|<(\/?)([^ \/>]+)((?:("|')(?:\\\7|[\s\S])*?\7|[^>])*?)(\/?)>|[^<]+|</g
73
+ , attrRe = /([^=\s]+)(?:\s*=\s*(("|')((?:\\\3|[\s\S])*?)\3|[^\s"'`=<>]+)|)/g
74
+ , frag = doc.createDocumentFragment()
75
+ , tree = frag
76
+
77
+ for (; (m = tagRe.exec(html)); ) {
78
+ if (m[4]) {
79
+ tree = tree.parentNode || tree
80
+ } else if (m[5]) {
81
+ child = doc.contentType === "text/html" ? doc.createElement(m[5]) : doc.createElementNS(null, m[5])
82
+ if (m[6]) {
83
+ m[6].replace(attrRe, setAttr)
84
+ }
85
+ tree.appendChild(child)
86
+ if ((re = rawTextElements[child.tagName])) {
87
+ for (text = ""; (m = tagRe.exec(html)) && !re.test(m[0]); text += m[3] || m[2] || m[0]);
88
+ child.textContent = text.replace(unescRe, unescFn)
89
+ } else if (!voidElements[child.tagName] && !m[8]) tree = child
90
+ } else {
91
+ tree.appendChild(
92
+ m[2] ? doc.createComment(m[2].replace(unescRe, unescFn)) :
93
+ m[1] ? doc.createDocumentType(m[1]) :
94
+ doc.createTextNode(m[0].replace(unescRe, unescFn))
95
+ )
96
+ }
97
+ }
98
+ replaceChildren.call(node, frag)
99
+
100
+ return html
101
+
102
+ function setAttr(_, name, value, q, qvalue) {
103
+ child.setAttribute(name, (q ? qvalue : value || "").replace(unescRe, unescFn))
104
+ }
105
+ },
106
+ get outerHTML() {
107
+ return this.toString()
108
+ },
109
+ set outerHTML(html) {
110
+ var frag = this.ownerDocument.createDocumentFragment()
111
+ frag.innerHTML = html
112
+ this.parentNode.replaceChild(frag, this)
113
+ return html
114
+ },
115
+ get htmlFor() {
116
+ return this["for"]
117
+ },
118
+ set htmlFor(value) {
119
+ this["for"] = value
120
+ },
121
+ get className() {
122
+ return this["class"] || ""
123
+ },
124
+ set className(value) {
125
+ this["class"] = value
126
+ },
127
+ get style() {
128
+ return this.styleMap || (this.styleMap = new StyleMap())
129
+ },
130
+ set style(value) {
131
+ this.styleMap = new StyleMap(value)
132
+ },
133
+ contains: function (el) {
134
+ for (; el; el = el.parentNode) if (el === this) return true
135
+ return false
136
+ },
137
+ hasChildNodes: function() {
138
+ return this.childNodes && this.childNodes.length > 0
139
+ },
140
+ appendChild: function(el) {
141
+ return this.insertBefore(el)
142
+ },
143
+ insertBefore: function(el, ref) {
144
+ var node = this
145
+ , childs = node.childNodes
146
+
147
+ if (el.nodeType === 11) {
148
+ for (; el.firstChild; ) node.insertBefore(el.firstChild, ref)
149
+ } else {
150
+ if (el.parentNode) el.parentNode.removeChild(el)
151
+ el.parentNode = node
152
+
153
+ // If ref is null, insert el at the end of the list of children.
154
+ childs.splice(ref ? childs.indexOf(ref) : childs.length, 0, el)
155
+ if (node.nodeType === 9 && el.nodeType === 1) {
156
+ node.documentElement = el
157
+ node.body = el.querySelector("body")
158
+ }
159
+ }
160
+ return el
161
+ },
162
+ removeChild: function(el) {
163
+ var node = this
164
+ , index = node.childNodes.indexOf(el)
165
+ if (index === -1) throw Error("NOT_FOUND_ERR")
166
+
167
+ node.childNodes.splice(index, 1)
168
+ el.parentNode = null
169
+ return el
170
+ },
171
+ replaceChild: function(el, ref) {
172
+ this.insertBefore(el, ref)
173
+ return this.removeChild(ref)
174
+ },
175
+ cloneNode: function(deep) {
176
+ var key
177
+ , node = this
178
+ , clone = new node.constructor(node.tagName || node.data)
179
+ clone.ownerDocument = node.ownerDocument
180
+
181
+ if (node.hasAttribute) {
182
+ for (key in node) if (node.hasAttribute(key)) clone[key] = node[key].valueOf()
183
+ }
184
+
185
+ if (deep && node.hasChildNodes()) {
186
+ node.childNodes.forEach(function(child) {
187
+ clone.appendChild(child.cloneNode(deep))
188
+ })
189
+ }
190
+ return clone
191
+ },
192
+ toString: function(minify) {
193
+ return rawTextElements[this.tagName] ? this.textContent : this.hasChildNodes() ? this.childNodes.reduce(function(memo, node) {
194
+ return memo + node.toString(minify)
195
+ }, "") : ""
196
+ }
197
+ }
198
+ , Element = {
199
+ get firstElementChild() {
200
+ return getElement(this.childNodes, 0, 1, 1)
201
+ },
202
+ get lastElementChild() {
203
+ return getElement(this.childNodes, this.childNodes.length - 1, -1, 1)
204
+ },
205
+ get nextElementSibling() {
206
+ return getSibling(this, 1, 1)
207
+ },
208
+ get previousElementSibling() {
209
+ return getSibling(this, -1, 1)
210
+ },
211
+ replaceChildren: replaceChildren,
212
+ hasAttribute: function(name) {
213
+ name = escAttr(name)
214
+ return hasOwn.call(this, name === "style" ? "styleMap" : name)
215
+ },
216
+ getAttribute: function(name) {
217
+ return this.hasAttribute(name) ? "" + this[escAttr(name)] : null
218
+ },
219
+ setAttribute: function(name, value) {
220
+ this[escAttr(name)] = "" + value
221
+ },
222
+ removeAttribute: function(name) {
223
+ name = escAttr(name)
224
+ delete this[name === "style" ? "styleMap" : name]
225
+ },
226
+ getElementById: function(id) {
227
+ return selector.find(this, "#" + id, 1)
228
+ },
229
+ getElementsByTagName: function(tag) {
230
+ return selector.find(this, tag)
231
+ },
232
+ getElementsByClassName: function(sel) {
233
+ return selector.find(this, "." + sel.replace(/\s+/g, "."))
234
+ },
235
+ querySelector: function(sel) {
236
+ return selector.find(this, sel, 1)
237
+ },
238
+ querySelectorAll: function(sel) {
239
+ return selector.find(this, sel)
240
+ }
241
+ }
242
+ , quotedAttrRe = /[\s"'`=<>]/
243
+ , escRe = /<|&(?=[a-z#])/gi
244
+ , unescRe = /&\w+;|&#(x|)([\da-f]+);/ig
245
+ , unescMap = {
246
+ "&amp;": "&", "&apos;": "'", "&cent;": "¢", "&copy;": "©", "&curren;": "¤",
247
+ "&deg;": "°", "&euro;": "€", "&gt;": ">", "&lt;": "<", "&nbsp;": " ",
248
+ "&plusmn;": "±", "&pound;": "£", "&quot;": "\"", "&reg;": "®",
249
+ "&sect;": "§", "&sup2;": "²", "&sup3;": "³", "&yen;": "¥"
250
+ }
251
+
252
+ function escFn(chr) {
253
+ return chr === "<" ? "&lt;" : "&amp;"
254
+ }
255
+
256
+ function unescFn(ent, hex, num) {
257
+ return num ? String.fromCharCode(parseInt(num, hex === "" ? 10 : 16)) : unescMap[ent] || ent
258
+ }
259
+
260
+ ;["hasAttribute", "getAttribute", "setAttribute", "removeAttribute"].forEach(function(name) {
261
+ Element[name + "NS"] = function(ns, a, b) {
262
+ return this[name].call(this, a, b)
263
+ }
264
+ })
265
+
266
+ function Attr(node, name) {
267
+ this.ownerElement = node
268
+ this.name = name.toLowerCase()
269
+ }
270
+
271
+ Attr.prototype = {
272
+ get value() { return this.ownerElement.getAttribute(this.name) },
273
+ set value(val) { this.ownerElement.setAttribute(this.name, val) },
274
+ toString: function(minify) {
275
+ var value = this.value.replace(escRe, escFn)
276
+ if (this.ownerElement.ownerDocument.contentType !== "application/xml") {
277
+ if (hasOwn.call(boolAttrs, this.name)) return this.name
278
+ if (minify) {
279
+ if (hasOwn.call(defaultAttrs, (this.ownerElement.tagName + " " + this.name + " " + value).toLowerCase())) return
280
+ if (!quotedAttrRe.test(value)) return this.name + "=" + this.value
281
+ if (value.split("\"").length > value.split("'").length) return this.name + "='" + value.replace(/'/g, "&#39;") + "'"
282
+ }
283
+ }
284
+ return this.name + "=\"" + value.replace(/"/g, "&quot;") + "\""
285
+ }
286
+ }
287
+
288
+ function StyleMap(style) {
289
+ for (var m, re = /(?:^|;)\s*([-a-z]+)\s*:((?:("|')(?:\\.|(?!\3)[^\\])*?\3|[^"';])+)(?=;|$)/ig; (m = re.exec(style)); ) {
290
+ this[m[1] === "float" ? "cssFloat" : camelCase(m[1])] = m[2].trim()
291
+ }
292
+ }
293
+
294
+ StyleMap.prototype.valueOf = function() {
295
+ return Object.keys(this).map(function(key) {
296
+ return (key === "cssFloat" ? "float:" : hyphenCase(key) + ":") + this[key]
297
+ }, this).join(";")
298
+ }
299
+
300
+ function DocumentFragment() {
301
+ this.childNodes = []
302
+ }
303
+
304
+ extendNode(DocumentFragment, Element, {
305
+ nodeType: 11,
306
+ nodeName: "#document-fragment"
307
+ })
308
+
309
+ function HTMLElement(tag) {
310
+ var el = this
311
+ el.nodeName = el.tagName = tag.toUpperCase()
312
+ el.localName = tag.toLowerCase()
313
+ el.childNodes = []
314
+ }
315
+
316
+ extendNode(HTMLElement, Element, {
317
+ nodeType: 1,
318
+ get attributes() {
319
+ var key
320
+ , attrs = []
321
+ , el = this
322
+ for (key in el) if (key === escAttr(key) && el.hasAttribute(key))
323
+ attrs.push(new Attr(el, escAttr(key)))
324
+ return attrs
325
+ },
326
+ matches: function(sel) {
327
+ return selector.matches(this, sel)
328
+ },
329
+ closest: function(sel) {
330
+ return selector.closest(this, sel)
331
+ },
332
+ namespaceURI: "http://www.w3.org/1999/xhtml",
333
+ localName: null,
334
+ tagName: null,
335
+ styleMap: null,
336
+ toString: function(minify) {
337
+ var attrs = (minify ? this.attributes.map(toMinString).filter(Boolean) : this.attributes).join(" ")
338
+ return "<" + this.localName + (attrs ? " " + attrs + (attrs.slice(-1) === "/" ? " >" : ">") : ">") +
339
+ (voidElements[this.tagName] ? "" : Node.toString.call(this, minify) + "</" + this.localName + ">")
340
+ }
341
+ })
342
+
343
+ function ElementNS(namespace, tag) {
344
+ var el = this
345
+ el.namespaceURI = namespace
346
+ el.nodeName = el.tagName = el.localName = tag
347
+ el.childNodes = []
348
+ }
349
+
350
+ ElementNS.prototype = HTMLElement.prototype
351
+
352
+ function Text(data) {
353
+ this.data = data
354
+ }
355
+
356
+ extendNode(Text, {
357
+ nodeType: 3,
358
+ nodeName: "#text",
359
+ toString: function(minify) {
360
+ return (minify ? ("" + this.data).trim() : "" + this.data).replace(escRe, escFn)
361
+ }
362
+ })
363
+
364
+ function Comment(data) {
365
+ this.data = data
366
+ }
367
+
368
+ extendNode(Comment, {
369
+ nodeType: 8,
370
+ nodeName: "#comment",
371
+ toString: function(minify) {
372
+ return minify ? "" : "<!--" + this.data + "-->"
373
+ }
374
+ })
375
+
376
+ function DocumentType(data) {
377
+ this.data = data
378
+ }
379
+
380
+ extendNode(DocumentType, {
381
+ nodeType: 10,
382
+ toString: function() {
383
+ return "<" + this.data + ">"
384
+ // var node = document.doctype
385
+ // return "<!DOCTYPE " + node.name +
386
+ // (node.publicId ? ' PUBLIC "' + node.publicId + '"' : '') +
387
+ // (!node.publicId && node.systemId ? ' SYSTEM' : '') +
388
+ // (node.systemId ? ' "' + node.systemId + '"' : '') + '>'
389
+ }
390
+ })
391
+
392
+ function Document() {
393
+ this.childNodes = []
394
+ this
395
+ .appendChild(this.createElement("html"))
396
+ .appendChild(this.body = this.createElement("body"))
397
+ }
398
+
399
+ extendNode(Document, Element, {
400
+ nodeType: 9,
401
+ nodeName: "#document",
402
+ contentType: "text/html",
403
+ createElement: own(HTMLElement),
404
+ createElementNS: own(ElementNS),
405
+ createTextNode: own(Text),
406
+ createComment: own(Comment),
407
+ createDocumentType: own(DocumentType), //Should be document.implementation.createDocumentType(name, publicId, systemId)
408
+ createDocumentFragment: own(DocumentFragment)
409
+ })
410
+
411
+ function DOMParser() {}
412
+ function XMLSerializer() {}
413
+
414
+ DOMParser.prototype.parseFromString = function(str, mime) {
415
+ var doc = new Document()
416
+ doc.contentType = mime || "text/html"
417
+ doc.documentElement.outerHTML = str
418
+ return doc
419
+ }
420
+ XMLSerializer.prototype.serializeToString = function(doc) {
421
+ return doc.toString()
422
+ }
423
+
424
+
425
+ function own(Class) {
426
+ return function($1, $2) {
427
+ var node = new Class($1, $2)
428
+ node.ownerDocument = this
429
+ return node
430
+ }
431
+ }
432
+
433
+ function extendNode(obj, extras) {
434
+ obj.prototype = Object.create(Node)
435
+ for (var descriptor, key, i = 1; (extras = arguments[i++]); ) {
436
+ for (key in extras) {
437
+ descriptor = Object.getOwnPropertyDescriptor(extras, key)
438
+ Object.defineProperty(obj.prototype, key, descriptor)
439
+ }
440
+ }
441
+ obj.prototype.constructor = obj
442
+ }
443
+
444
+ function replaceChildren() {
445
+ for (var arr = this.childNodes, i = 0, l = arr && arr.length; i < l; ) arr[i++].parentNode = null
446
+ for (i = arr.length = 0, l = arguments.length; i < l; ) this.insertBefore(arguments[i++])
447
+ }
448
+
449
+ function getElement(childs, index, step, type) {
450
+ if (childs && index > -1) for (; childs[index]; index += step) {
451
+ if (childs[index].nodeType === type) return childs[index]
452
+ }
453
+ return null
454
+ }
455
+
456
+ function getSibling(node, step, type) {
457
+ var silbings = node.parentNode && node.parentNode.childNodes
458
+ , index = silbings ? silbings.indexOf(node) : -1
459
+ return type > 0 ? getElement(silbings, index + step, step, type) : silbings[index + step] || null
460
+ }
461
+
462
+ function escAttr(name) {
463
+ name = name.toLowerCase()
464
+ return name === "constructor" || name === "attributes" ? name.toUpperCase() : name
465
+ }
466
+
467
+ function camelCase(str) {
468
+ return str.replace(/-([a-z])/g, function(_, a) { return a.toUpperCase() })
469
+ }
470
+
471
+ function hyphenCase(str) {
472
+ return str.replace(/[A-Z]/g, "-$&").toLowerCase()
473
+ }
474
+
475
+ function toMinString(item) {
476
+ return item.toString(true)
477
+ }
478
+
479
+ module.exports = {
480
+ document: new Document(),
481
+ DOMParser: DOMParser,
482
+ XMLSerializer: XMLSerializer,
483
+ StyleMap: StyleMap,
484
+ Node: Node,
485
+ HTMLElement: HTMLElement,
486
+ DocumentFragment: DocumentFragment,
487
+ Document: Document
488
+ }
489
+
package/interactive.js ADDED
@@ -0,0 +1,15 @@
1
+
2
+
3
+ var DOM = module.exports = require(".")
4
+ , HTMLElementExtra = {
5
+ focus: function() {
6
+ this.ownerDocument.activeElement = this
7
+ },
8
+ blur: function() {
9
+ this.ownerDocument.activeElement = null
10
+ }
11
+ }
12
+
13
+ Object.assign(DOM.HTMLElement.prototype, HTMLElementExtra)
14
+
15
+
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@litejs/dom",
3
+ "version": "23.2.2",
4
+ "description": "A small DOM library for server-side testing, rendering, and handling of HTML files",
5
+ "license": "MIT",
6
+ "author": "Lauri Rooden <lauri@rooden.ee>",
7
+ "keywords": [
8
+ "document",
9
+ "dom",
10
+ "DOMParser",
11
+ "XMLHttpRequest",
12
+ "XMLSerializer",
13
+ "litejs"
14
+ ],
15
+ "files": [
16
+ "*.js"
17
+ ],
18
+ "scripts": {
19
+ "test": "lj test --coverage --ignore=xmlhttprequest.js --brief test/index.js && jshint *.js"
20
+ },
21
+ "repository": "github:litejs/dom",
22
+ "devDependencies": {
23
+ "@litejs/cli": "23.2.6",
24
+ "jshint": "2.13.6"
25
+ },
26
+ "litejs": {
27
+ "build": false,
28
+ "global": false
29
+ },
30
+ "jshintConfig": {
31
+ "esversion": 5,
32
+ "asi": true,
33
+ "evil": true,
34
+ "laxcomma": true,
35
+ "maxdepth": 6,
36
+ "node": true,
37
+ "nonbsp": true,
38
+ "undef": true,
39
+ "unused": true,
40
+ "shadow": "outer",
41
+ "quotmark": "double"
42
+ }
43
+ }
package/selector.js ADDED
@@ -0,0 +1,127 @@
1
+
2
+
3
+
4
+ /**
5
+ * @version 20.2.0
6
+ * @author Lauri Rooden <lauri@rooden.ee>
7
+ * @license MIT License
8
+ */
9
+
10
+
11
+
12
+ !function(exports) {
13
+ var selectorCache = {
14
+ "": function() {}
15
+ }
16
+ , selectorRe = /([.#:[])([-\w]+)(?:\(((?:[^()]|\([^)]+\))+?)\)|([~^$*|]?)=(("|')(?:\\.|[^\\])*?\6|[-\w]+))?]?/g
17
+ , selectorLastRe = /([\s>+~]*)(?:("|')(?:\\.|[^\\])*?\2|\((?:[^()]|\([^()]+\))+?\)|~=|[^'"()\s>+~])+$/
18
+ , selectorSplitRe = /\s*,\s*(?=(?:[^'"()]|"(?:\\.|[^\\"])*?"|'(?:\\.|[^\\'])*?'|\((?:[^()]|\([^()]+\))+?\))+$)/
19
+ , selectorMap = {
20
+ "contains": "_.textContent.indexOf(v)>-1",
21
+ "empty": "!_.lastChild",
22
+ "enabled": "!m(_,':disabled')",
23
+ "first-child": "(a=_.parentNode)&&a.firstChild==_",
24
+ "first-of-type": "!p(_,_.tagName)",
25
+ "is": "m(_,v)",
26
+ "lang": "m(c(_,'[lang]'),'[lang|='+v+']')",
27
+ "last-child": "(a=_.parentNode)&&a.lastChild==_",
28
+ "last-of-type": "!n(_,_.tagName)",
29
+ "link": "m(_,'a[href]')",
30
+ "not": "!m(_,v)",
31
+ "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))",
32
+ "only-child": "(a=_.parentNode)&&a.firstChild==a.lastChild",
33
+ "only-of-type": "!p(_,_.tagName)&&!n(_,_.tagName)",
34
+ "optional": "!m(_,':required')",
35
+ "root": "(a=_.parentNode)&&!a.tagName",
36
+ ".": "~_.className.split(/\\s+/).indexOf(a)",
37
+ "#": "_.id==a",
38
+ "^": "!a.indexOf(v)",
39
+ "|": "a.split('-')[0]==v",
40
+ "$": "a.slice(-v.length)==v",
41
+ "~": "~a.split(/\\s+/).indexOf(v)",
42
+ "*": "~a.indexOf(v)",
43
+ ">>": "m(_.parentNode,v)",
44
+ "++": "m(_.previousSibling,v)",
45
+ "~~": "p(_,v)",
46
+ "": "c(_.parentNode,v)"
47
+ }
48
+
49
+ selectorMap["nth-last-child"] = selectorMap["nth-child"].replace("1+", "v.length-")
50
+
51
+ function selectorFn(str) {
52
+ // jshint evil:true, unused:true, eqnull:true
53
+ if (str != null && typeof str !== "string") throw Error("Invalid selector")
54
+ return selectorCache[str || ""] ||
55
+ (selectorCache[str] = Function("m,c,n,p", "return function(_,v,a,b){return " +
56
+ str.split(selectorSplitRe).map(function(sel) {
57
+ var relation, from
58
+ , rules = ["_&&_.nodeType==1"]
59
+ , parentSel = sel.replace(selectorLastRe, function(_, _rel, a, start) {
60
+ from = start + _rel.length
61
+ relation = _rel.trim()
62
+ return ""
63
+ })
64
+ , tag = sel.slice(from).replace(selectorRe, function(_, op, key, subSel, fn, val, quotation) {
65
+ rules.push(
66
+ "((v='" +
67
+ (subSel || (quotation ? val.slice(1, -1) : val) || "").replace(/[\\']/g, "\\$&") +
68
+ "'),(a='" + key + "'),1)"
69
+ ,
70
+ selectorMap[op == ":" ? key : op] ||
71
+ "(a=_.getAttribute(a))" +
72
+ (fn ? "&&" + selectorMap[fn] : val ? "==v" : "!==null")
73
+ )
74
+ return ""
75
+ })
76
+
77
+ if (tag && tag != "*") rules[0] += "&&_.tagName=='" + tag.toUpperCase() + "'"
78
+ if (parentSel) rules.push("(v='" + parentSel + "')", selectorMap[relation + relation])
79
+ return rules.join("&&")
80
+ }).join("||") + "}"
81
+ )(matches, closest, next, prev))
82
+ }
83
+
84
+
85
+ function walk(next, first, el, sel, nextFn) {
86
+ var out = []
87
+ for (sel = selectorFn(sel); el; el = el[next] || nextFn && nextFn(el)) if (sel(el)) {
88
+ if (first) return el
89
+ out.push(el)
90
+ }
91
+ return first ? null : out
92
+ }
93
+
94
+ function find(node, sel, first) {
95
+ return walk("firstChild", first, node.firstChild, sel, function(el) {
96
+ var next = el.nextSibling
97
+ while (!next && ((el = el.parentNode) !== node)) next = el.nextSibling
98
+ return next
99
+ })
100
+ }
101
+
102
+ function matches(el, sel) {
103
+ return !!selectorFn(sel)(el)
104
+ }
105
+
106
+ function closest(el, sel) {
107
+ return walk("parentNode", 1, el, sel)
108
+ }
109
+
110
+ function next(el, sel) {
111
+ return walk("nextSibling", 1, el.nextSibling, sel)
112
+ }
113
+
114
+ function prev(el, sel) {
115
+ return walk("previousSibling", 1, el.previousSibling, sel)
116
+ }
117
+
118
+
119
+ exports.find = find
120
+ exports.fn = selectorFn
121
+ exports.matches = matches
122
+ exports.closest = closest
123
+ exports.next = next
124
+ exports.prev = prev
125
+ exports.selectorMap = selectorMap
126
+ }(this) // jshint ignore:line
127
+
@@ -0,0 +1,114 @@
1
+ /* global unescape */
2
+
3
+ var DOM = require(".")
4
+ , parser = new DOM.DOMParser()
5
+ , dataUrlRe = /^data:([^;,]*?)(;[^,]+?|),(.*)$/
6
+
7
+ function XMLHttpRequest() {}
8
+
9
+ function setState(xhr, state) {
10
+ if (xhr.readyState !== state) {
11
+ xhr.readyState = state
12
+ if (xhr.onreadystatechange) xhr.onreadystatechange()
13
+ if (state === xhr.DONE && xhr.onload) xhr.onload()
14
+ }
15
+ }
16
+
17
+ XMLHttpRequest.prototype = {
18
+ UNSENT: 0,
19
+ OPENED: 1,
20
+ HEADERS_RECEIVED: 2,
21
+ LOADING: 3,
22
+ DONE: 4,
23
+ readyState: 0,
24
+ status: 0,
25
+ statusText: "",
26
+ response: "",
27
+ responseText: "",
28
+ responseType: "",
29
+ responseURL: "",
30
+ get responseXML() {
31
+ var xhr = this
32
+ , mime = (xhr.getResponseHeader("Content-Type") || "").split(";")[0]
33
+ return (
34
+ xhr.readyState !== xhr.DONE ? null :
35
+ // XMLHttpRequest spec originally supported only XML
36
+ mime !== "application/xml" && xhr.responseType !== "document" ? null :
37
+ parser.parseFromString(xhr.responseText, mime)
38
+ )
39
+ },
40
+ getAllResponseHeaders: function () {
41
+ var xhr = this
42
+ return xhr.readyState >= xhr.HEADERS_RECEIVED && Object.keys(xhr._headers).map(function(name) {
43
+ return name + ": " + xhr._headers[name] + "\r\n"
44
+ }).join("") || null
45
+ },
46
+ getResponseHeader: function (name) {
47
+ var xhr = this
48
+ return xhr.readyState >= xhr.HEADERS_RECEIVED && xhr._headers[name.toLowerCase()] || null
49
+ },
50
+ abort: function() {
51
+ throw Error("XMLHttpRequest abort/reuse not implemented")
52
+ },
53
+ open: function (method, url, async) {
54
+ var xhr = this
55
+ if (async === false) throw Error("XMLHttpRequest sync not implemented")
56
+
57
+ if (xhr.readyState > xhr.UNSENT) {
58
+ xhr.abort()
59
+ }
60
+
61
+ xhr.method = method
62
+ xhr.responseURL = url
63
+ setState(xhr, xhr.OPENED)
64
+ },
65
+ send: function (data) {
66
+ var xhr = this
67
+ , url = xhr.responseURL
68
+ , proto = url.split(":", 1)[0]
69
+ , opts = {
70
+ method: xhr.method
71
+ }
72
+
73
+ if (proto === "http" || proto === "https") {
74
+ require(proto).request(url, opts, function(res) {
75
+ head(res.statusCode, res.statusMessage, res.headers)
76
+ res.on("data", body)
77
+ res.on("end", done)
78
+ }).end(data)
79
+ return
80
+ }
81
+ if (proto === "data") {
82
+ var match = dataUrlRe.exec(url)
83
+ if (!match) throw Error("Invalid URL: " + url)
84
+ setTimeout(function() {
85
+ head(200, "OK", { "content-type": match[1] || "text/plain" })
86
+ body(match[2] ? Buffer.from(match[3], "base64") : unescape(match[3]))
87
+ done()
88
+ }, 1)
89
+ return
90
+ }
91
+
92
+ throw Error("Unsuported protocol: " + proto)
93
+
94
+ function head(code, text, headers) {
95
+ xhr.status = code
96
+ xhr.statusText = text
97
+ xhr._headers = headers
98
+ setState(xhr, xhr.HEADERS_RECEIVED)
99
+ }
100
+ function body(chunk) {
101
+ xhr.responseText += chunk.toString("utf8")
102
+ setState(xhr, xhr.LOADING)
103
+ }
104
+ function done() {
105
+ setState(xhr, xhr.DONE)
106
+ }
107
+ }
108
+ }
109
+
110
+
111
+ module.exports = {
112
+ XMLHttpRequest: XMLHttpRequest
113
+ }
114
+