pseudo-dom 0.7.0 → 0.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.
- package/README.md +468 -237
- package/browser/pseudo-dom.js +986 -563
- package/browser/pseudo-dom.min.js +1 -1
- package/dist/classes/PseudoHTMLDocument.d.ts +17 -43
- package/dist/classes/PseudoHTMLDocument.js +24 -94
- package/dist/classes/PseudoHTMLDocument.min.js +1 -1
- package/dist/factories/createDataset.d.ts +10 -0
- package/dist/factories/createDataset.js +78 -0
- package/dist/factories/createDataset.min.js +1 -0
- package/dist/factories/createStyleDeclaration.d.ts +30 -0
- package/dist/factories/createStyleDeclaration.js +64 -0
- package/dist/factories/createStyleDeclaration.min.js +1 -0
- package/dist/factories/cssSelectAdapter.d.ts +23 -23
- package/dist/factories/cssSelectAdapter.js +87 -87
- package/dist/factories/query.d.ts +33 -33
- package/dist/factories/query.js +66 -66
- package/dist/functions/getElementById.d.ts +13 -0
- package/dist/functions/getElementById.js +33 -0
- package/dist/functions/getElementById.min.js +1 -0
- package/dist/interfaces/PseudoCSSStyleDeclaration.d.ts +14 -0
- package/dist/interfaces/PseudoCSSStyleDeclaration.js +5 -0
- package/dist/interfaces/PseudoCSSStyleDeclaration.min.js +1 -0
- package/dist/interfaces/PseudoDocument.d.ts +35 -10
- package/dist/interfaces/PseudoDocumentFragment.d.ts +7 -0
- package/dist/interfaces/PseudoElement.d.ts +702 -702
- package/dist/interfaces/PseudoHTMLElement.d.ts +33 -22
- package/dist/services/CSSStyleDeclarationService.d.ts +73 -0
- package/dist/services/CSSStyleDeclarationService.js +156 -0
- package/dist/services/CSSStyleDeclarationService.min.js +1 -0
- package/dist/services/DocumentFragmentService.d.ts +8 -0
- package/dist/services/DocumentFragmentService.js +18 -0
- package/dist/services/DocumentFragmentService.min.js +1 -1
- package/dist/services/DocumentService.d.ts +46 -19
- package/dist/services/DocumentService.js +95 -46
- package/dist/services/DocumentService.min.js +1 -1
- package/dist/services/ElementService.d.ts +191 -191
- package/dist/services/ElementService.js +426 -426
- package/dist/services/HTMLCollectionService.d.ts +54 -54
- package/dist/services/HTMLCollectionService.js +92 -92
- package/dist/services/HTMLElementService.d.ts +87 -57
- package/dist/services/HTMLElementService.js +202 -163
- package/dist/services/HTMLElementService.min.js +1 -1
- package/dist/services/NodeService.d.ts +297 -297
- package/dist/services/NodeService.js +721 -721
- package/package.json +2 -2
- package/dist/classes.d.ts +0 -20
- package/dist/classes.js +0 -31
- package/dist/classes.min.js +0 -1
- package/dist/factories/generateNode.d.ts +0 -32
- package/dist/factories/generateNode.js +0 -85
- package/dist/factories/generateNode.min.js +0 -1
- package/dist/factories.d.ts +0 -11
- package/dist/factories.js +0 -27
- package/dist/factories.min.js +0 -1
- package/dist/functions.d.ts +0 -5
- package/dist/functions.js +0 -23
- package/dist/functions.min.js +0 -1
|
@@ -3,65 +3,39 @@
|
|
|
3
3
|
* @author Joshua Heagle <joshuaheagle@gmail.com>
|
|
4
4
|
* @version 1.0.0
|
|
5
5
|
*/
|
|
6
|
-
/**
|
|
7
|
-
*
|
|
8
|
-
* @type {PseudoHTMLElement}
|
|
9
|
-
*/
|
|
10
6
|
import { HTMLElementService as PseudoHTMLElement } from '../services/HTMLElementService';
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import { PseudoNode } from '../interfaces/PseudoNode';
|
|
7
|
+
import { DocumentService } from '../services/DocumentService';
|
|
8
|
+
import { NodeService } from '../services/NodeService';
|
|
14
9
|
/**
|
|
15
|
-
* Simulate the behaviour of the HTMLDocument Class when there is no DOM available.
|
|
10
|
+
* Simulate the behaviour of the HTMLDocument Class when there is no DOM available. Like the real HTMLDocument, this
|
|
11
|
+
* only adds the html/head/body structure on top of what Document already gives (createElement, createTextNode,
|
|
12
|
+
* createComment, createDocumentFragment, getElementById, textContent always null).
|
|
16
13
|
* @author Joshua Heagle <joshuaheagle@gmail.com>
|
|
17
14
|
* @class
|
|
18
|
-
* @augments
|
|
15
|
+
* @augments DocumentService
|
|
19
16
|
* @property {PseudoHTMLElement} head - A reference to the Head child element
|
|
20
17
|
* @property {PseudoHTMLElement} body - A reference to the Body child element
|
|
21
|
-
* @property {function} createElement - Generate a new PseudoHTMLElement (which is not in the document until it is appended)
|
|
22
18
|
*/
|
|
23
|
-
declare class PseudoHTMLDocument extends
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
declare class PseudoHTMLDocument extends DocumentService {
|
|
20
|
+
head: PseudoHTMLElement | null;
|
|
21
|
+
body: PseudoHTMLElement | null;
|
|
26
22
|
/**
|
|
27
23
|
* The root HTML element is acts as the parent to all HTML elements in the document.
|
|
28
24
|
* @constructor
|
|
29
25
|
*/
|
|
30
26
|
constructor();
|
|
31
|
-
get nodeName(): string;
|
|
32
|
-
get nodeType(): number;
|
|
33
|
-
get textContent(): string | null;
|
|
34
|
-
set textContent(text: string | null);
|
|
35
|
-
/**
|
|
36
|
-
* Make an element of the given type which belongs to this document but is not added anywhere until it is appended.
|
|
37
|
-
* @param {string} tagName - Tag Name is a string representing the type of Dom element this represents
|
|
38
|
-
* @returns {PseudoHTMLElement}
|
|
39
|
-
*/
|
|
40
|
-
createElement(tagName?: string): PseudoHTMLElement;
|
|
41
|
-
/**
|
|
42
|
-
* Make a text node which belongs to this document.
|
|
43
|
-
* @param {string} [data=''] The text
|
|
44
|
-
* @returns {TextService}
|
|
45
|
-
*/
|
|
46
|
-
createTextNode(data?: string): TextService;
|
|
47
|
-
/**
|
|
48
|
-
* Make a comment which belongs to this document.
|
|
49
|
-
* @param {string} [data=''] The comment
|
|
50
|
-
* @returns {CommentService}
|
|
51
|
-
*/
|
|
52
|
-
createComment(data?: string): CommentService;
|
|
53
27
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* @returns {
|
|
28
|
+
* A copy of this document with none of its html/head/body (cloneNode, from the inherited cloneShallow hook, fills
|
|
29
|
+
* them back in, deep copies own document's, empty otherwise - see cloneNode).
|
|
30
|
+
* @returns {PseudoHTMLDocument}
|
|
57
31
|
*/
|
|
58
|
-
|
|
32
|
+
protected cloneShallow(): NodeService;
|
|
59
33
|
/**
|
|
60
|
-
* Make a copy of this document. The copy has no parent or listeners, and a deep copy has copies of everything in
|
|
61
|
-
* document (a shallow one is an empty document).
|
|
34
|
+
* Make a copy of this document. The copy has no parent or listeners, and a deep copy has copies of everything in
|
|
35
|
+
* the document (a shallow one is an empty document).
|
|
62
36
|
* @param {boolean} [deep=false] Copy everything in the document as well
|
|
63
|
-
* @returns {
|
|
37
|
+
* @returns {PseudoHTMLDocument}
|
|
64
38
|
*/
|
|
65
|
-
cloneNode(deep?: boolean):
|
|
39
|
+
cloneNode(deep?: boolean): PseudoHTMLDocument;
|
|
66
40
|
}
|
|
67
41
|
export default PseudoHTMLDocument;
|
|
@@ -2,137 +2,67 @@
|
|
|
2
2
|
|
|
3
3
|
require('core-js/modules/esnext.iterator.constructor.js')
|
|
4
4
|
require('core-js/modules/esnext.iterator.find.js')
|
|
5
|
-
require('core-js/modules/esnext.iterator.for-each.js')
|
|
6
5
|
Object.defineProperty(exports, '__esModule', {
|
|
7
6
|
value: true
|
|
8
7
|
})
|
|
8
|
+
const DocumentService_1 = require('../services/DocumentService')
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*/
|
|
14
|
-
/**
|
|
15
|
-
*
|
|
16
|
-
* @type {PseudoHTMLElement}
|
|
17
|
-
*/
|
|
18
|
-
const HTMLElementService_1 = require('../services/HTMLElementService')
|
|
19
|
-
const NodeService_1 = require('../services/NodeService')
|
|
20
|
-
const DocumentFragmentService_1 = require('../services/DocumentFragmentService')
|
|
21
|
-
/**
|
|
22
|
-
* Simulate the behaviour of the HTMLDocument Class when there is no DOM available.
|
|
10
|
+
* Simulate the behaviour of the HTMLDocument Class when there is no DOM available. Like the real HTMLDocument, this
|
|
11
|
+
* only adds the html/head/body structure on top of what Document already gives (createElement, createTextNode,
|
|
12
|
+
* createComment, createDocumentFragment, getElementById, textContent always null).
|
|
23
13
|
* @author Joshua Heagle <joshuaheagle@gmail.com>
|
|
24
14
|
* @class
|
|
25
|
-
* @augments
|
|
15
|
+
* @augments DocumentService
|
|
26
16
|
* @property {PseudoHTMLElement} head - A reference to the Head child element
|
|
27
17
|
* @property {PseudoHTMLElement} body - A reference to the Body child element
|
|
28
|
-
* @property {function} createElement - Generate a new PseudoHTMLElement (which is not in the document until it is appended)
|
|
29
18
|
*/
|
|
30
|
-
class PseudoHTMLDocument extends
|
|
19
|
+
class PseudoHTMLDocument extends DocumentService_1.DocumentService {
|
|
31
20
|
/**
|
|
32
21
|
* The root HTML element is acts as the parent to all HTML elements in the document.
|
|
33
22
|
* @constructor
|
|
34
23
|
*/
|
|
35
24
|
constructor () {
|
|
36
25
|
super()
|
|
37
|
-
const html =
|
|
38
|
-
tagName: 'html'
|
|
39
|
-
})
|
|
26
|
+
const html = this.createElement('html')
|
|
40
27
|
this.appendChild(html)
|
|
41
28
|
/**
|
|
42
29
|
* Create document head element
|
|
43
30
|
* @type {PseudoHTMLElement}
|
|
44
31
|
*/
|
|
45
|
-
this.head =
|
|
46
|
-
tagName: 'head'
|
|
47
|
-
})
|
|
32
|
+
this.head = this.createElement('head')
|
|
48
33
|
html.appendChild(this.head)
|
|
49
34
|
/**
|
|
50
35
|
* Create document body element
|
|
51
36
|
* @type {PseudoHTMLElement}
|
|
52
37
|
*/
|
|
53
|
-
this.body =
|
|
54
|
-
tagName: 'body'
|
|
55
|
-
})
|
|
38
|
+
this.body = this.createElement('body')
|
|
56
39
|
html.appendChild(this.body)
|
|
57
40
|
}
|
|
58
41
|
|
|
59
|
-
get nodeName () {
|
|
60
|
-
return '#document'
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
get nodeType () {
|
|
64
|
-
return NodeService_1.NodeService.DOCUMENT_NODE
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// A document has no text of its own, and setting it does nothing
|
|
68
|
-
get textContent () {
|
|
69
|
-
return null
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
set textContent (text) {}
|
|
73
|
-
/**
|
|
74
|
-
* Make an element of the given type which belongs to this document but is not added anywhere until it is appended.
|
|
75
|
-
* @param {string} tagName - Tag Name is a string representing the type of Dom element this represents
|
|
76
|
-
* @returns {PseudoHTMLElement}
|
|
77
|
-
*/
|
|
78
|
-
createElement (tagName = 'div') {
|
|
79
|
-
// Like the DOM, the new element is not added anywhere: it has no parent until it is appended
|
|
80
|
-
const element = new HTMLElementService_1.HTMLElementService({
|
|
81
|
-
tagName
|
|
82
|
-
})
|
|
83
|
-
element.ownerDocumentStore = this
|
|
84
|
-
return element
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Make a text node which belongs to this document.
|
|
89
|
-
* @param {string} [data=''] The text
|
|
90
|
-
* @returns {TextService}
|
|
91
|
-
*/
|
|
92
|
-
createTextNode (data = '') {
|
|
93
|
-
const text = new NodeService_1.TextService(data)
|
|
94
|
-
text.ownerDocumentStore = this
|
|
95
|
-
return text
|
|
96
|
-
}
|
|
97
|
-
|
|
98
42
|
/**
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
* @returns {
|
|
43
|
+
* A copy of this document with none of its html/head/body (cloneNode, from the inherited cloneShallow hook, fills
|
|
44
|
+
* them back in, deep copies own document's, empty otherwise - see cloneNode).
|
|
45
|
+
* @returns {PseudoHTMLDocument}
|
|
102
46
|
*/
|
|
103
|
-
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
* then inserted in one go.
|
|
112
|
-
* @returns {DocumentFragmentService}
|
|
113
|
-
*/
|
|
114
|
-
createDocumentFragment () {
|
|
115
|
-
const fragment = new DocumentFragmentService_1.DocumentFragmentService()
|
|
116
|
-
fragment.ownerDocumentStore = this
|
|
117
|
-
return fragment
|
|
47
|
+
cloneShallow () {
|
|
48
|
+
const copy = new this.constructor()
|
|
49
|
+
while (copy.firstChild) {
|
|
50
|
+
copy.removeChild(copy.firstChild)
|
|
51
|
+
}
|
|
52
|
+
copy.head = null
|
|
53
|
+
copy.body = null
|
|
54
|
+
return copy
|
|
118
55
|
}
|
|
119
56
|
|
|
120
57
|
/**
|
|
121
|
-
* Make a copy of this document. The copy has no parent or listeners, and a deep copy has copies of everything in
|
|
122
|
-
* document (a shallow one is an empty document).
|
|
58
|
+
* Make a copy of this document. The copy has no parent or listeners, and a deep copy has copies of everything in
|
|
59
|
+
* the document (a shallow one is an empty document).
|
|
123
60
|
* @param {boolean} [deep=false] Copy everything in the document as well
|
|
124
|
-
* @returns {
|
|
61
|
+
* @returns {PseudoHTMLDocument}
|
|
125
62
|
*/
|
|
126
63
|
cloneNode (deep = false) {
|
|
127
|
-
const copy =
|
|
128
|
-
// The new document starts out with its own html, head and body, a copy has only what was copied from this one
|
|
129
|
-
while (copy.firstChild) {
|
|
130
|
-
copy.removeChild(copy.firstChild)
|
|
131
|
-
}
|
|
132
|
-
copy.head = null
|
|
133
|
-
copy.body = null
|
|
64
|
+
const copy = super.cloneNode(deep)
|
|
134
65
|
if (deep) {
|
|
135
|
-
Array.from(this.childNodes).forEach(child => copy.appendChild(child.cloneNode(true)))
|
|
136
66
|
const html = Array.from(copy.childNodes).find(child => child.tagName === 'html')
|
|
137
67
|
const inHtml = tagName => html ? Array.from(html.childNodes).find(child => child.tagName === tagName) || null : null
|
|
138
68
|
copy.head = inHtml('head')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.find.js"),
|
|
1
|
+
"use strict";require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.find.js"),Object.defineProperty(exports,"__esModule",{value:!0});const DocumentService_1=require("../services/DocumentService");class PseudoHTMLDocument extends DocumentService_1.DocumentService{constructor(){super();const e=this.createElement("html");this.appendChild(e),this.head=this.createElement("head"),e.appendChild(this.head),this.body=this.createElement("body"),e.appendChild(this.body)}cloneShallow(){const e=new this.constructor;for(;e.firstChild;)e.removeChild(e.firstChild);return e.head=null,e.body=null,e}cloneNode(e=!1){const t=super.cloneNode(e);if(e){const e=Array.from(t.childNodes).find(e=>"html"===e.tagName),o=t=>e&&Array.from(e.childNodes).find(e=>e.tagName===t)||null;t.head=o("head"),t.body=o("body")}return t}}exports.default=PseudoHTMLDocument;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A live DOMStringMap-like object for an element's data-* attributes.
|
|
3
|
+
* @memberOf module:factories
|
|
4
|
+
* @param {*} element The element whose data-* attributes this reflects
|
|
5
|
+
* @returns {Object.<string, string>}
|
|
6
|
+
*/
|
|
7
|
+
declare const createDataset: (element: any) => {
|
|
8
|
+
[key: string]: string;
|
|
9
|
+
};
|
|
10
|
+
export default createDataset;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
require('core-js/modules/esnext.iterator.constructor.js')
|
|
4
|
+
require('core-js/modules/esnext.iterator.map.js')
|
|
5
|
+
Object.defineProperty(exports, '__esModule', {
|
|
6
|
+
value: true
|
|
7
|
+
})
|
|
8
|
+
/**
|
|
9
|
+
* @file Wraps an element in a Proxy which behaves like the DOM's DOMStringMap (element.dataset): a live view of its
|
|
10
|
+
* data-* attributes, under their camelCase names, backed by the element's own getAttribute / setAttribute /
|
|
11
|
+
* hasAttribute / removeAttribute (nothing is stored separately, so it can never fall out of sync with the
|
|
12
|
+
* attributes).
|
|
13
|
+
* @author Joshua Heagle <joshuaheagle@gmail.com>
|
|
14
|
+
* @version 1.0.0
|
|
15
|
+
*/
|
|
16
|
+
const createStyleDeclaration_1 = require('./createStyleDeclaration')
|
|
17
|
+
const DATA_PREFIX = 'data-'
|
|
18
|
+
const attributeName = property => `${DATA_PREFIX}${(0, createStyleDeclaration_1.camelToKebab)(property)}`
|
|
19
|
+
/**
|
|
20
|
+
* Every data-* attribute name currently on the element, as [attributeName, camelCaseName] pairs.
|
|
21
|
+
* @param {*} element
|
|
22
|
+
* @returns {Array<Array<string>>}
|
|
23
|
+
*/
|
|
24
|
+
const dataAttributes = element => {
|
|
25
|
+
const names = []
|
|
26
|
+
for (let index = 0; index < element.attributes.length; index++) {
|
|
27
|
+
const name = element.attributes.item(index).name
|
|
28
|
+
if (name.indexOf(DATA_PREFIX) === 0 && name.length > DATA_PREFIX.length) {
|
|
29
|
+
names.push([name, (0, createStyleDeclaration_1.kebabToCamel)(name.slice(DATA_PREFIX.length))])
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return names
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A live DOMStringMap-like object for an element's data-* attributes.
|
|
36
|
+
* @memberOf module:factories
|
|
37
|
+
* @param {*} element The element whose data-* attributes this reflects
|
|
38
|
+
* @returns {Object.<string, string>}
|
|
39
|
+
*/
|
|
40
|
+
const createDataset = element => new Proxy({}, {
|
|
41
|
+
get (_target, property) {
|
|
42
|
+
if (typeof property !== 'string') {
|
|
43
|
+
return undefined
|
|
44
|
+
}
|
|
45
|
+
const value = element.getAttribute(attributeName(property))
|
|
46
|
+
return value === null ? undefined : value
|
|
47
|
+
},
|
|
48
|
+
set (_target, property, value) {
|
|
49
|
+
if (typeof property !== 'string') {
|
|
50
|
+
return false
|
|
51
|
+
}
|
|
52
|
+
element.setAttribute(attributeName(property), String(value))
|
|
53
|
+
return true
|
|
54
|
+
},
|
|
55
|
+
deleteProperty (_target, property) {
|
|
56
|
+
if (typeof property === 'string') {
|
|
57
|
+
element.removeAttribute(attributeName(property))
|
|
58
|
+
}
|
|
59
|
+
return true
|
|
60
|
+
},
|
|
61
|
+
has (_target, property) {
|
|
62
|
+
return typeof property === 'string' && element.hasAttribute(attributeName(property))
|
|
63
|
+
},
|
|
64
|
+
ownKeys () {
|
|
65
|
+
return dataAttributes(element).map(([, camelCaseName]) => camelCaseName)
|
|
66
|
+
},
|
|
67
|
+
getOwnPropertyDescriptor (_target, property) {
|
|
68
|
+
if (typeof property !== 'string' || !element.hasAttribute(attributeName(property))) {
|
|
69
|
+
return undefined
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
enumerable: true,
|
|
73
|
+
configurable: true,
|
|
74
|
+
value: element.getAttribute(attributeName(property))
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
exports.default = createDataset
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.map.js"),Object.defineProperty(exports,"__esModule",{value:!0});const createStyleDeclaration_1=require("./createStyleDeclaration"),DATA_PREFIX="data-",attributeName=t=>`data-${(0,createStyleDeclaration_1.camelToKebab)(t)}`,dataAttributes=t=>{const e=[];for(let r=0;r<t.attributes.length;r++){const a=t.attributes.item(r).name;0===a.indexOf("data-")&&a.length>5&&e.push([a,(0,createStyleDeclaration_1.kebabToCamel)(a.slice(5))])}return e},createDataset=t=>new Proxy({},{get(e,r){if("string"!=typeof r)return;const a=t.getAttribute(attributeName(r));return null===a?void 0:a},set:(e,r,a)=>"string"==typeof r&&(t.setAttribute(attributeName(r),String(a)),!0),deleteProperty:(e,r)=>("string"==typeof r&&t.removeAttribute(attributeName(r)),!0),has:(e,r)=>"string"==typeof r&&t.hasAttribute(attributeName(r)),ownKeys:()=>dataAttributes(t).map(([,t])=>t),getOwnPropertyDescriptor(e,r){if("string"==typeof r&&t.hasAttribute(attributeName(r)))return{enumerable:!0,configurable:!0,value:t.getAttribute(attributeName(r))}}});exports.default=createDataset;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Wraps a CSSStyleDeclarationService in a Proxy so arbitrary camelCase CSS properties (element.style.
|
|
3
|
+
* backgroundColor) work like the DOM's, on top of its real methods (getPropertyValue, setProperty, cssText, ...).
|
|
4
|
+
* @author Joshua Heagle <joshuaheagle@gmail.com>
|
|
5
|
+
* @version 1.0.0
|
|
6
|
+
*/
|
|
7
|
+
import { CSSStyleDeclarationService } from '../services/CSSStyleDeclarationService';
|
|
8
|
+
/**
|
|
9
|
+
* kebab-case -> camelCase ("background-color" -> "backgroundColor").
|
|
10
|
+
* @param {string} name
|
|
11
|
+
* @returns {string}
|
|
12
|
+
*/
|
|
13
|
+
declare const kebabToCamel: (name: string) => string;
|
|
14
|
+
/**
|
|
15
|
+
* camelCase -> kebab-case ("backgroundColor" -> "background-color").
|
|
16
|
+
* @param {string} name
|
|
17
|
+
* @returns {string}
|
|
18
|
+
*/
|
|
19
|
+
declare const camelToKebab: (name: string) => string;
|
|
20
|
+
/**
|
|
21
|
+
* A live CSSStyleDeclaration-like object: its real methods (cssText, getPropertyValue, setProperty, ...) work as
|
|
22
|
+
* declared, and any other property name is treated as a camelCase CSS property (declaration.backgroundColor reads /
|
|
23
|
+
* writes the "background-color" declaration), matching what a real element.style supports.
|
|
24
|
+
* @memberOf module:factories
|
|
25
|
+
* @param {string} [cssText=''] Initial declarations
|
|
26
|
+
* @returns {CSSStyleDeclarationService}
|
|
27
|
+
*/
|
|
28
|
+
declare const createStyleDeclaration: (cssText?: string) => CSSStyleDeclarationService;
|
|
29
|
+
export { kebabToCamel, camelToKebab };
|
|
30
|
+
export default createStyleDeclaration;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', {
|
|
4
|
+
value: true
|
|
5
|
+
})
|
|
6
|
+
exports.camelToKebab = exports.kebabToCamel = void 0
|
|
7
|
+
/**
|
|
8
|
+
* @file Wraps a CSSStyleDeclarationService in a Proxy so arbitrary camelCase CSS properties (element.style.
|
|
9
|
+
* backgroundColor) work like the DOM's, on top of its real methods (getPropertyValue, setProperty, cssText, ...).
|
|
10
|
+
* @author Joshua Heagle <joshuaheagle@gmail.com>
|
|
11
|
+
* @version 1.0.0
|
|
12
|
+
*/
|
|
13
|
+
const CSSStyleDeclarationService_1 = require('../services/CSSStyleDeclarationService')
|
|
14
|
+
const isIndex = property => /^\d+$/.test(property)
|
|
15
|
+
/**
|
|
16
|
+
* kebab-case -> camelCase ("background-color" -> "backgroundColor").
|
|
17
|
+
* @param {string} name
|
|
18
|
+
* @returns {string}
|
|
19
|
+
*/
|
|
20
|
+
const kebabToCamel = name => name.replace(/-([a-z0-9])/gi, (_match, letter) => letter.toUpperCase())
|
|
21
|
+
exports.kebabToCamel = kebabToCamel
|
|
22
|
+
/**
|
|
23
|
+
* camelCase -> kebab-case ("backgroundColor" -> "background-color").
|
|
24
|
+
* @param {string} name
|
|
25
|
+
* @returns {string}
|
|
26
|
+
*/
|
|
27
|
+
const camelToKebab = name => name.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`)
|
|
28
|
+
exports.camelToKebab = camelToKebab
|
|
29
|
+
/**
|
|
30
|
+
* A live CSSStyleDeclaration-like object: its real methods (cssText, getPropertyValue, setProperty, ...) work as
|
|
31
|
+
* declared, and any other property name is treated as a camelCase CSS property (declaration.backgroundColor reads /
|
|
32
|
+
* writes the "background-color" declaration), matching what a real element.style supports.
|
|
33
|
+
* @memberOf module:factories
|
|
34
|
+
* @param {string} [cssText=''] Initial declarations
|
|
35
|
+
* @returns {CSSStyleDeclarationService}
|
|
36
|
+
*/
|
|
37
|
+
const createStyleDeclaration = (cssText = '') => {
|
|
38
|
+
const target = new CSSStyleDeclarationService_1.CSSStyleDeclarationService(cssText)
|
|
39
|
+
return new Proxy(target, {
|
|
40
|
+
get (declaration, property, receiver) {
|
|
41
|
+
if (typeof property !== 'string') {
|
|
42
|
+
return Reflect.get(declaration, property, receiver)
|
|
43
|
+
}
|
|
44
|
+
if (isIndex(property)) {
|
|
45
|
+
return declaration.item(Number(property))
|
|
46
|
+
}
|
|
47
|
+
if (property in declaration) {
|
|
48
|
+
return Reflect.get(declaration, property, receiver)
|
|
49
|
+
}
|
|
50
|
+
return declaration.getPropertyValue(camelToKebab(property))
|
|
51
|
+
},
|
|
52
|
+
set (declaration, property, value) {
|
|
53
|
+
if (typeof property !== 'string' || property === 'cssText') {
|
|
54
|
+
return Reflect.set(declaration, property, value)
|
|
55
|
+
}
|
|
56
|
+
declaration.setProperty(camelToKebab(property), value === null || typeof value === 'undefined' ? '' : String(value))
|
|
57
|
+
return true
|
|
58
|
+
},
|
|
59
|
+
has (declaration, property) {
|
|
60
|
+
return typeof property === 'string' && (property in declaration || declaration.getPropertyValue(camelToKebab(property)) !== '')
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
exports.default = createStyleDeclaration
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.camelToKebab=exports.kebabToCamel=void 0;const CSSStyleDeclarationService_1=require("../services/CSSStyleDeclarationService"),isIndex=e=>/^\d+$/.test(e),kebabToCamel=e=>e.replace(/-([a-z0-9])/gi,(e,t)=>t.toUpperCase());exports.kebabToCamel=kebabToCamel;const camelToKebab=e=>e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`);exports.camelToKebab=camelToKebab;const createStyleDeclaration=(e="")=>{const t=new CSSStyleDeclarationService_1.CSSStyleDeclarationService(e);return new Proxy(t,{get:(e,t,a)=>"string"!=typeof t?Reflect.get(e,t,a):isIndex(t)?e.item(Number(t)):t in e?Reflect.get(e,t,a):e.getPropertyValue(camelToKebab(t)),set:(e,t,a)=>"string"!=typeof t||"cssText"===t?Reflect.set(e,t,a):(e.setProperty(camelToKebab(t),null==a?"":String(a)),!0),has:(e,t)=>"string"==typeof t&&(t in e||""!==e.getPropertyValue(camelToKebab(t)))})};exports.default=createStyleDeclaration;
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Maps pseudo-dom's own Node / Element API onto the Adapter interface css-select needs to query a tree which is not
|
|
3
|
-
* domutils' own (css-select's own Adapter<Node, ElementNode> type). Every method here is one pseudo-dom already has
|
|
4
|
-
* under a different name; nothing here reimplements DOM behaviour.
|
|
5
|
-
* @memberOf module:factories
|
|
6
|
-
* @type {Object}
|
|
7
|
-
*/
|
|
8
|
-
export declare const cssSelectAdapter: {
|
|
9
|
-
isTag: (node: any) => boolean;
|
|
10
|
-
existsOne: (test: (elem: any) => boolean, elems: Array<any>) => boolean;
|
|
11
|
-
getAttributeValue: (elem: any, name: string) => string | undefined;
|
|
12
|
-
getChildren: (node: any) => Array<any>;
|
|
13
|
-
getName: (elem: any) => string;
|
|
14
|
-
getParent: (node: any) => any | null;
|
|
15
|
-
getSiblings: (node: any) => Array<any>;
|
|
16
|
-
prevElementSibling: (node: any) => any | null;
|
|
17
|
-
getText: (node: any) => string;
|
|
18
|
-
hasAttrib: (elem: any, name: string) => boolean;
|
|
19
|
-
removeSubsets: (nodes: Array<any>) => Array<any>;
|
|
20
|
-
findAll: (test: (elem: any) => boolean, nodes: Array<any>) => Array<any>;
|
|
21
|
-
findOne: (test: (elem: any) => boolean, nodes: Array<any>) => any | null;
|
|
22
|
-
};
|
|
23
|
-
export default cssSelectAdapter;
|
|
1
|
+
/**
|
|
2
|
+
* Maps pseudo-dom's own Node / Element API onto the Adapter interface css-select needs to query a tree which is not
|
|
3
|
+
* domutils' own (css-select's own Adapter<Node, ElementNode> type). Every method here is one pseudo-dom already has
|
|
4
|
+
* under a different name; nothing here reimplements DOM behaviour.
|
|
5
|
+
* @memberOf module:factories
|
|
6
|
+
* @type {Object}
|
|
7
|
+
*/
|
|
8
|
+
export declare const cssSelectAdapter: {
|
|
9
|
+
isTag: (node: any) => boolean;
|
|
10
|
+
existsOne: (test: (elem: any) => boolean, elems: Array<any>) => boolean;
|
|
11
|
+
getAttributeValue: (elem: any, name: string) => string | undefined;
|
|
12
|
+
getChildren: (node: any) => Array<any>;
|
|
13
|
+
getName: (elem: any) => string;
|
|
14
|
+
getParent: (node: any) => any | null;
|
|
15
|
+
getSiblings: (node: any) => Array<any>;
|
|
16
|
+
prevElementSibling: (node: any) => any | null;
|
|
17
|
+
getText: (node: any) => string;
|
|
18
|
+
hasAttrib: (elem: any, name: string) => boolean;
|
|
19
|
+
removeSubsets: (nodes: Array<any>) => Array<any>;
|
|
20
|
+
findAll: (test: (elem: any) => boolean, nodes: Array<any>) => Array<any>;
|
|
21
|
+
findOne: (test: (elem: any) => boolean, nodes: Array<any>) => any | null;
|
|
22
|
+
};
|
|
23
|
+
export default cssSelectAdapter;
|