als-document 1.0.1-alpha → 1.0.2-alpha
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/document.js +3 -3
- package/index.js +3 -3
- package/index.mjs +3 -3
- package/package.json +1 -1
- package/src/build.js +1 -2
- package/src/node/node.js +1 -1
- package/src/node/single-node.js +1 -1
- package/src/query/check-element.js +2 -3
package/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
class Query{
|
|
2
2
|
static get(query){
|
|
3
3
|
let q=new Query(query)
|
|
4
4
|
return q.selectors
|
|
5
5
|
}
|
|
6
6
|
constructor(query){
|
|
7
7
|
this.query=query
|
|
8
8
|
this.selectors=[]
|
|
9
9
|
this.stringValues=[];
|
|
10
10
|
this.parseSelectors(query.split(','))
|
|
11
11
|
}
|
|
12
12
|
parseSelectors(selectors){
|
|
13
13
|
selectors.forEach(selector=>{
|
|
14
14
|
let originalSelector=selector.trim()
|
|
15
15
|
selector=this.removeSpaces(selector)
|
|
16
16
|
this.stringValues=[]
|
|
17
17
|
selector=selector.replace(/\[.*?\]/g,(value)=>{
|
|
18
18
|
this.stringValues.push(value)
|
|
19
19
|
return `[${this.stringValues.length-1}]`
|
|
20
20
|
})
|
|
21
21
|
let [element,ancestors]=this.splitAndCutLast(selector,' ')
|
|
22
22
|
element=this.getFamily(element)
|
|
23
23
|
if (ancestors.length>0)
|
|
24
24
|
element.ancestors=ancestors.map(ancestor=>this.getFamily(ancestor))
|
|
25
25
|
element.group=originalSelector
|
|
26
26
|
this.selectors.push(element)
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
29
|
splitAndCutLast(string,splitBy){
|
|
30
30
|
const array=string.split(splitBy);
|
|
31
31
|
const last=array.pop();
|
|
32
32
|
return [last,array];
|
|
33
33
|
}
|
|
34
34
|
getFamily(group,element,prev,prevAny,sign){
|
|
35
35
|
if (group.match(/\~|\+/)!==null){
|
|
36
36
|
let [last,prevBrothers]=this.splitAndCutLast(group,/\~|\+/)
|
|
37
37
|
let signs=group.replace(last,'')
|
|
38
38
|
prevBrothers.forEach(el=>signs=signs.replace(el,''))
|
|
39
39
|
signs=signs.match(/\~|\+/g)
|
|
40
40
|
if (signs.length==1){
|
|
41
41
|
sign=signs[0]
|
|
42
42
|
} else if (signs.length>1){
|
|
43
43
|
sign=signs.splice(signs.length-1,signs.length-1)[0]
|
|
44
44
|
prevBrothers[0]=prevBrothers.map((b,i)=>{
|
|
45
45
|
if (i< prevBrothers.length-1) b+=signs[i]
|
|
46
46
|
return b
|
|
47
47
|
}).join('')
|
|
48
48
|
prevBrothers[0]=this.getFamily(prevBrothers[0])
|
|
49
49
|
}
|
|
50
50
|
if (sign=='~') prevAny=prevBrothers[0]
|
|
51
51
|
else if (sign=='+') prev=prevBrothers[0]
|
|
52
52
|
element=last
|
|
53
53
|
} else element=group
|
|
54
54
|
let family
|
|
55
55
|
if (prev || prevAny){
|
|
56
56
|
family=this.getParents(element)
|
|
57
57
|
if (prev) family.prev=this.getParents(prev)
|
|
58
58
|
if (prevAny) family.prevAny=this.getParents(prevAny)
|
|
59
59
|
} else family=this.getParents(element)
|
|
60
60
|
if (family.query!==group) family.group=group
|
|
61
61
|
return family
|
|
62
62
|
}
|
|
63
63
|
getParents(selector){
|
|
64
64
|
if (typeof selector=='string'){
|
|
65
65
|
let [element,parents]=this.splitAndCutLast(selector,'>')
|
|
66
66
|
element=this.buildElement(element)
|
|
67
67
|
parents=parents.map(parent=>this.buildElement(parent))
|
|
68
68
|
if (parents.length>0) element.parents=parents
|
|
69
69
|
return element
|
|
70
70
|
} else return selector
|
|
71
71
|
}
|
|
72
72
|
buildElement(element,id=null,tag=null,classList=[]){
|
|
73
73
|
let query=element
|
|
74
74
|
element=element.replace(/\#(\w-?)*/,$id=>{
|
|
75
75
|
id=$id.replace(/^\#/,''); return ''
|
|
76
76
|
})
|
|
77
77
|
element=element.replace(/\.(\w-?)*/,$class=>{
|
|
78
78
|
classList.push($class.replace(/^\./,'')); return ''
|
|
79
79
|
})
|
|
80
80
|
element=element.replace(/(\w\:?-?)*/,$tag=>{
|
|
81
81
|
tag=$tag=='' ? null : $tag; return ''
|
|
82
82
|
})
|
|
83
83
|
let attribs=this.getAttributes(element)
|
|
84
84
|
element={ query }
|
|
85
85
|
if (id) element.id=id
|
|
86
86
|
if (tag) element.tag=tag
|
|
87
87
|
if (classList.length>0) element.classList=classList
|
|
88
88
|
if (attribs.length>0) element.attribs=attribs
|
|
89
89
|
return element
|
|
90
90
|
}
|
|
91
91
|
getAttributes(element){
|
|
92
92
|
let attribs=this.stringValues.filter((value,index)=>{
|
|
93
93
|
let searchValue=`[${index}]`
|
|
94
94
|
if (element.match(searchValue)) return true
|
|
95
95
|
else return false
|
|
96
96
|
})
|
|
97
97
|
attribs=attribs.map(attrib=>{
|
|
98
98
|
let query=attrib
|
|
99
99
|
attrib=attrib.replace('[','').replace(']','')
|
|
100
100
|
let [name,value]=attrib.split(/[\~\|\^\$\*]?\=/)
|
|
101
101
|
let sign=attrib.replace(name,'').replace(value,'')
|
|
102
102
|
attrib={ query }
|
|
103
103
|
if (name) attrib.name=name
|
|
104
104
|
if (value) attrib.value=value.trim().replace(/^\"/,'').replace(/\"$/,'')
|
|
105
105
|
if (sign){
|
|
106
106
|
attrib.sign=sign
|
|
107
107
|
attrib.check=this.getAttribFn(sign).bind(attrib)
|
|
108
108
|
}
|
|
109
109
|
return attrib
|
|
110
110
|
});
|
|
111
111
|
return attribs
|
|
112
112
|
}
|
|
113
113
|
getAttribFn(sign){
|
|
114
114
|
if (sign=='=') return function (value){ return value===this.value }
|
|
115
115
|
if (sign=='*=') return function (value){ return value.includes(this.value) }
|
|
116
116
|
if (sign=='^=') return function (value){ return value.startsWith(this.value) }
|
|
117
117
|
if (sign=='$=') return function (value){ return value.endsWith(this.value) }
|
|
118
118
|
if (sign=='|=') return function (value){
|
|
119
119
|
return value.trim().split(' ').length==1
|
|
120
120
|
&& (value.startsWith(this.value) || value.startsWith(this.value+'-'))
|
|
121
121
|
? true : false
|
|
122
122
|
}
|
|
123
123
|
if (sign=='~=') return function (value){
|
|
124
124
|
return this.value.trim().split(' ').length==1 && value.includes(this.value) ? true : false
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
removeSpaces(selector){
|
|
128
128
|
selector=selector.replace(/\s{2}/g,' ')
|
|
129
129
|
selector=selector.replace(/\s?\^?\$?\|?\~?\*?\=\s*/g,(m)=>m.trim())
|
|
130
130
|
selector=selector.replace(/\s?(\+|\~|\>)\s?/g,(m)=>m.trim())
|
|
131
131
|
return selector
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
|
-
function checkElement(el,selector){
|
|
135
134
|
if(selector==undefined) return true
|
|
136
135
|
if(el==null) return false
|
|
137
136
|
let{tag,classList,attributes,id,prev,ancestors,parents,prevAny}=selector
|
|
138
137
|
if(typeof el==='string') return false
|
|
139
138
|
if(el.isSpecial) return false
|
|
140
139
|
if(id!==undefined && el.id===null) return false
|
|
141
140
|
if(id && id!==el.id) return false
|
|
142
141
|
if(tag && el.tagName===undefined) return false
|
|
143
142
|
else if(tag && tag!==el.tagName) return false
|
|
144
143
|
const clas=el.attributes.class
|
|
145
144
|
if(classList!==undefined && (clas===undefined || clas==='')) return false
|
|
146
145
|
else if(classList!==undefined){
|
|
147
146
|
if(classList.every(e=>el.classList.contains(e))===false) return false
|
|
148
147
|
}
|
|
149
148
|
if(checkattributes(attributes,el)===false) return false
|
|
150
149
|
if(checkElement(el.prev,prev)===false) return false
|
|
151
150
|
if(checkAncestors(el.ancestors,ancestors)===false) return false
|
|
152
151
|
if(checkParents(el.ancestors,parents)===false) return false
|
|
153
152
|
if(el.parent){
|
|
154
153
|
if(checkPrevAny(el.parent.children,el.childIndex,prevAny)==false) return false
|
|
155
154
|
}
|
|
156
155
|
return true
|
|
156
|
+
function checkElement(el,selector){
|
|
157
157
|
if(selector==undefined) return true
|
|
158
158
|
if(el==null) return false
|
|
159
159
|
let{tag,classList,attributes,id,prev,ancestors,parents,prevAny}=selector
|
|
160
160
|
if(typeof el==='string') return false
|
|
161
161
|
if(id!==undefined && el.id===null) return false
|
|
162
162
|
if(id && id!==el.id) return false
|
|
163
163
|
if(tag && el.tagName===undefined) return false
|
|
164
164
|
else if(tag && tag!==el.tagName) return false
|
|
165
165
|
const clas=el.attributes.class
|
|
166
166
|
if(classList!==undefined && (clas===undefined || clas==='')) return false
|
|
167
167
|
else if(classList!==undefined){
|
|
168
168
|
if(classList.every(e=>el.classList.contains(e))===false) return false
|
|
169
169
|
}
|
|
170
170
|
if(checkattributes(attributes,el)===false) return false
|
|
171
171
|
if(checkElement(el.prev,prev)===false) return false
|
|
172
172
|
if(checkAncestors(el.ancestors,ancestors)===false) return false
|
|
173
173
|
if(checkParents(el.ancestors,parents)===false) return false
|
|
174
174
|
if(el.parent){
|
|
175
175
|
if(checkPrevAny(el.parent.children,el.childIndex,prevAny)==false) return false
|
|
176
176
|
}
|
|
177
177
|
return true
|
|
178
178
|
}
|
|
179
179
|
function checkattributes(attributes=[],el){
|
|
180
180
|
let elattributes=el.attributes
|
|
181
181
|
let names=Object.keys(elattributes)
|
|
182
182
|
let passedTests=0
|
|
183
183
|
if(attributes) for(let i=0; i<attributes.length; i++){
|
|
184
184
|
let{name,value,check}=attributes[i]
|
|
185
185
|
if(name=='inner' && value!==undefined && check && el.inner){
|
|
186
186
|
if(check(el.inner)) passedTests++
|
|
187
187
|
}
|
|
188
188
|
if(!names.includes(name)) continue
|
|
189
189
|
else if(value==undefined) passedTests++
|
|
190
190
|
else if(value && elattributes[name]){
|
|
191
191
|
if(check(elattributes[name])==false) continue
|
|
192
192
|
else passedTests++
|
|
193
193
|
}
|
|
194
194
|
}
|
|
195
195
|
if(passedTests==attributes.length) return true
|
|
196
196
|
else return false
|
|
197
197
|
}
|
|
198
198
|
function checkPrevAny(children=[],index,prevAny){
|
|
199
199
|
let size=children.length
|
|
200
200
|
if((size==0 || index==0) && prevAny) return false
|
|
201
201
|
for(let i=index; i>=0; i--){
|
|
202
202
|
if(checkElement(children[i],prevAny)) return true
|
|
203
203
|
}
|
|
204
204
|
return false
|
|
205
205
|
}
|
|
206
206
|
function checkAncestors(ancestors=[],selectorAncestors=[]){
|
|
207
207
|
let count=0
|
|
208
208
|
if(selectorAncestors.length==0) return true
|
|
209
209
|
let endIndex=ancestors.length-1
|
|
210
210
|
let selectorIndex=selectorAncestors.length-1
|
|
211
211
|
while(selectorIndex>=0){
|
|
212
212
|
for(let i=endIndex; i>=0; i--){
|
|
213
213
|
endIndex=i-1
|
|
214
214
|
if(checkElement(ancestors[i],selectorAncestors[selectorIndex])==true){
|
|
215
215
|
count++
|
|
216
216
|
break
|
|
217
217
|
}
|
|
218
218
|
}
|
|
219
219
|
selectorIndex--
|
|
220
220
|
}
|
|
221
221
|
if(count==selectorAncestors.length) return true
|
|
222
222
|
else return false
|
|
@@ -20,9 +20,9 @@ function buildStyle(attributes){
|
|
|
20
20
|
const styles=attributes.style || "";
|
|
21
21
|
con
|
|
22
22
|
|
|
23
23
|
class NodeClassList{
|
|
24
24
|
constructor(node){ this.node=node }
|
|
25
25
|
get classes(){ return (this.node.attributes.class || "").split(" ").filter(Boolean) }
|
|
26
26
|
set classes(val){ this.node.attributes.class=val.join(" ") }
|
|
27
27
|
contains(className){ return this.classes.includes(className) }
|
|
28
28
|
add(className){
|
|
29
29
|
const currentClasses=this.classes;
|
|
30
30
|
if (!currentClasses.includes(className)) this.classes=[...currentClasses,className];
|
|
31
31
|
}
|
|
32
32
|
remove(className){ this.classes=this.classes.filter(cls=>cls!==className); }
|
|
33
33
|
toggle(className){
|
|
34
34
|
if (this.classes.includes(className)) this.remove(className);
|
|
35
35
|
else this.add(className);
|
|
36
36
|
}
|
|
37
37
|
replace(oldClass,newClass){
|
|
38
38
|
if (this.classes.includes(oldClass)){
|
|
39
39
|
this.remove(oldClass);
|
|
40
40
|
this.add(newClass);
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
|
-
class Node{
|
|
45
44
|
constructor(tagName,attributes={},parent=null){
|
|
46
45
|
this.isSingle=false;
|
|
47
46
|
this.tagName=tagName;
|
|
48
47
|
this.attributes=attributes;
|
|
49
48
|
this.childNodes=[];
|
|
50
49
|
if (parent!==null) parent.childNodes.push(this)
|
|
51
50
|
this.parent=parent;
|
|
52
51
|
this._classList=null;
|
|
53
52
|
this.__style=null;
|
|
54
53
|
this._dataset=null
|
|
55
54
|
}
|
|
56
55
|
get id(){ return this.attributes.id || null; }
|
|
57
56
|
get className(){return this.attributes.class || null}
|
|
58
57
|
get parentNode(){ return this.parent }
|
|
59
58
|
get ancestors(){
|
|
60
59
|
const ancestors=[]
|
|
61
60
|
let element=this.parent
|
|
62
61
|
while (element.tagName!=='ROOT'){
|
|
63
62
|
ancestors.push(element)
|
|
64
63
|
element=element.parent
|
|
65
64
|
}
|
|
66
65
|
return ancestors.reverse()
|
|
67
66
|
}
|
|
68
67
|
get childIndex(){ return this.parent.childNodes ? this.parent.childNodes.indexOf(this) : null }
|
|
69
68
|
get previousElementSibling(){ return this.prev }
|
|
70
69
|
get prev(){
|
|
71
70
|
if (!this.childIndex) return null
|
|
72
71
|
return this.parent.childNodes[this.childIndex-1]
|
|
73
72
|
}
|
|
74
73
|
get nextElementSibling(){ return this.next }
|
|
75
74
|
get next(){
|
|
76
75
|
if (!this.childIndex) return null
|
|
77
76
|
return this.parent.childNodes[this.childIndex+1] || null
|
|
78
77
|
}
|
|
79
78
|
get dataset(){
|
|
80
79
|
if (!this._dataset) this._dataset=getDataset(this);
|
|
81
80
|
return this._dataset;
|
|
82
81
|
}
|
|
83
82
|
get classList(){
|
|
84
83
|
if (!this._classList) this._classList=new NodeClassList(this);
|
|
85
84
|
return this._classList;
|
|
86
85
|
}
|
|
87
86
|
get style(){
|
|
88
87
|
if (!this.__style) this.__style=buildStyle(this.attributes)
|
|
89
88
|
return this.__style
|
|
90
89
|
}
|
|
91
90
|
get outerHTML(){
|
|
92
91
|
const attrs=Object.entries(this.attributes).map(([key,val])=>`${key}="${val}"`).join(" ");
|
|
93
92
|
return `<${this.tagName} ${attrs}>${this.innerHTML}</${this.tagName}>`;
|
|
94
93
|
}
|
|
95
94
|
getAttribute(attrName){ return this.attributes[attrName] || null }
|
|
96
95
|
setAttribute(attrName,value){ this.attributes[attrName]=value }
|
|
97
96
|
removeAttribute(attrName){ delete this.attributes[attrName] }
|
|
98
97
|
remove(){
|
|
99
98
|
if (!this.parent) return
|
|
100
99
|
const index=this.childIndex;
|
|
101
100
|
if (index!==null) this.parent.childNodes.splice(index,1);
|
|
102
101
|
}
|
|
103
102
|
get innerHTML(){
|
|
104
103
|
return this.childNodes.map(child=>{
|
|
105
104
|
if (child instanceof Node || child instanceof SingleNode) return child.outerHTML;
|
|
106
105
|
else if (child instanceof TextNode) return child.textContent;
|
|
107
106
|
else return child
|
|
108
107
|
}).join("");
|
|
109
108
|
}
|
|
110
109
|
$$(query){return this.querySelectorAll(query)}
|
|
111
110
|
querySelectorAll(query){
|
|
112
111
|
const selectors=Query.get(query)
|
|
113
112
|
return find(selectors,this,new Set())
|
|
114
113
|
}
|
|
115
114
|
$(query){return this.querySelector(query)}
|
|
116
115
|
querySelector(query){
|
|
117
116
|
const selectors=Query.get(query)
|
|
118
117
|
return find(selectors,this,new Set(),true)[0]
|
|
119
118
|
}
|
|
120
119
|
getElementsByClassName(query){ return this.querySelectorAll('.'+query) }
|
|
121
120
|
getElementsByTagName(query){ return this.querySelectorAll(query) }
|
|
122
121
|
getElementById(query){ return this.querySelector('#'+query) }
|
|
123
122
|
get children(){
|
|
124
123
|
return this.childNodes.filter(child=>{
|
|
125
124
|
if (!(child instanceof Node)) return false
|
|
126
125
|
if (child.tagName==='#comment') return false
|
|
127
126
|
return true
|
|
128
127
|
});
|
|
129
128
|
}
|
|
130
129
|
insertAdjacentElement(position,newElement){
|
|
131
130
|
if(newElement.tagName==='ROOT' && newElement.childNodes.length>0) newElement=newElement.childNodes[0]
|
|
132
131
|
const pos=position.toLowerCase();
|
|
133
132
|
if (pos==="afterbegin") this.childNodes.unshift(newElement);
|
|
134
133
|
else if (pos==="beforeend") this.childNodes.push(newElement);
|
|
135
134
|
if (!this.parent) return newElement
|
|
136
135
|
if (pos==="beforebegin") this.parent.childNodes.unshift(newElement);
|
|
137
136
|
else if (pos==="afterend") this.parent.childNodes.splice(this.childIndex+1,0,newElement);
|
|
138
137
|
return newElement
|
|
139
138
|
}
|
|
140
139
|
insertAdjacentHTML(position,html){
|
|
141
140
|
const newNode=parseHTML(html);
|
|
142
141
|
return this.insertAdjacentElement(position,newNode);
|
|
143
142
|
}
|
|
144
143
|
insertAdjacentText(position,text){
|
|
145
144
|
return this.insertAdjacentElement(position,new TextNode(text));
|
|
146
145
|
}
|
|
147
146
|
set innerHTML(html){
|
|
148
147
|
const parsed=parseHTML(html);
|
|
149
148
|
this.childNodes=parsed.childNodes;
|
|
150
149
|
}
|
|
151
150
|
set outerHTML(html){
|
|
152
151
|
const parsed=parseHTML(html);
|
|
153
152
|
if (!this.parent) return console.log('element has no parent node')
|
|
154
153
|
const index=this.childIndex
|
|
155
154
|
if (index!==null) this.parent.childNodes.splice(index,1,...parsed.childNodes);
|
|
156
155
|
}
|
|
157
156
|
appendChild(newChild){
|
|
158
157
|
if (newChild instanceof Node || newChild instanceof TextNode || newChild instanceof SingleNode){
|
|
159
158
|
if (newChild.parent) newChild.parent.childNodes=newChild.parent.childNodes.filter(child=>child!==newChild);
|
|
160
159
|
} else if(typeof newChild==='string') newChild=new TextNode(newChild)
|
|
161
160
|
else return newChild
|
|
162
161
|
this.childNodes.push(newChild);
|
|
163
162
|
newChild.parent=this;
|
|
164
163
|
return newChild;
|
|
165
164
|
}
|
|
166
165
|
get textContent(){
|
|
167
166
|
if (this.childNodes.length===0) return this.nodeName==='#text' ? this.nodeValue : '';
|
|
168
167
|
return this.childNodes.map(child=>{
|
|
169
168
|
if(child instanceof SingleNode) return ''
|
|
170
169
|
if(child instanceof TextNode) return child.nodeValue
|
|
171
170
|
if(child instanceof Node) return child.textContent;
|
|
172
171
|
else return child;
|
|
173
172
|
}).join(" ");
|
|
174
173
|
}
|
|
175
174
|
set textContent(value){
|
|
176
175
|
this.childNodes=[];
|
|
177
176
|
if (value!==null && value!==undefined){
|
|
178
177
|
this.childNodes.push(value.toString());
|
|
179
178
|
}
|
|
180
179
|
}
|
|
180
|
+
class Node{
|
|
181
181
|
constructor(tagName,attributes={},parent=null){
|
|
182
182
|
this.isSingle=false;
|
|
183
183
|
this.tagName=tagName;
|
|
184
184
|
this.attributes=attributes;
|
|
185
185
|
this.childNodes=[];
|
|
186
186
|
if (parent!==null) parent.childNodes.push(this)
|
|
187
187
|
this.parent=parent;
|
|
188
188
|
this._classList=null;
|
|
189
189
|
this.__style=null;
|
|
190
190
|
this._dataset=null
|
|
191
191
|
}
|
|
192
192
|
get id(){ return this.attributes.id || null; }
|
|
193
193
|
get className(){return this.attributes.class || null}
|
|
194
194
|
get parentNode(){ return this.parent }
|
|
195
195
|
get ancestors(){
|
|
196
196
|
const ancestors=[]
|
|
197
197
|
let element=this.parent
|
|
198
198
|
while (element.tagName!=='ROOT'){
|
|
199
199
|
ancestors.push(element)
|
|
200
200
|
element=element.parent
|
|
201
201
|
}
|
|
202
202
|
return ancestors.reverse()
|
|
203
203
|
}
|
|
204
204
|
get childIndex(){ return this.parent.childNodes ? this.parent.childNodes.indexOf(this) : null }
|
|
205
205
|
get previousElementSibling(){ return this.prev }
|
|
206
206
|
get prev(){
|
|
207
207
|
if (!this.childIndex) return null
|
|
208
208
|
return this.parent.childNodes[this.childIndex-1]
|
|
209
209
|
}
|
|
210
210
|
get nextElementSibling(){ return this.next }
|
|
211
211
|
get next(){
|
|
212
212
|
if (!this.childIndex) return null
|
|
213
213
|
return this.parent.childNodes[this.childIndex+1] || null
|
|
214
214
|
}
|
|
215
215
|
get dataset(){
|
|
216
216
|
if (!this._dataset) this._dataset=getDataset(this);
|
|
217
217
|
return this._dataset;
|
|
218
218
|
}
|
|
219
219
|
get classList(){
|
|
220
220
|
if (!this._classList) this._classList=new NodeClassList(this);
|
|
221
221
|
return this._classList;
|
|
222
222
|
}
|
|
223
223
|
get style(){
|
|
224
224
|
if (!this.__style) this.__style=buildStyle(this.attributes)
|
|
225
225
|
return this.__style
|
|
226
226
|
}
|
|
227
227
|
get outerHTML(){
|
|
228
228
|
const attrs=Object.entries(this.attributes).map(([key,val])=>`${key}="${val}"`).join(" ");
|
|
229
229
|
return `<${this.tagName} ${attrs}>${this.innerHTML}</${this.tagName}>`;
|
|
230
230
|
}
|
|
231
231
|
getAttribute(attrName){ return this.attributes[attrName] || null }
|
|
232
232
|
setAttribute(attrName,value){ this.attributes[attrName]=value }
|
|
233
233
|
removeAttribute(attrName){ delete this.attributes[attrName] }
|
|
234
234
|
remove(){
|
|
235
235
|
if (!this.parent) return
|
|
236
236
|
const index=this.childIndex;
|
|
237
237
|
if (index!==null) this.parent.childNodes.splice(index,1);
|
|
238
238
|
}
|
|
239
239
|
get innerHTML(){
|
|
240
240
|
return this.childNodes.map(child=>{
|
|
241
241
|
if (child instanceof Node || child instanceof SingleNode) return child.outerHTML;
|
|
242
242
|
else if (child instanceof TextNode) return child.textContent;
|
|
243
243
|
else return child
|
|
244
244
|
}).join("");
|
|
245
245
|
}
|
|
246
246
|
$$(query){return this.querySelectorAll(query)}
|
|
247
247
|
querySelectorAll(query){
|
|
248
248
|
const selectors=Query.get(query)
|
|
249
249
|
return find(selectors,this,new Set())
|
|
250
250
|
}
|
|
251
251
|
$(query){return this.querySelector(query)}
|
|
252
252
|
querySelector(query){
|
|
253
253
|
const selectors=Query.get(query)
|
|
254
254
|
return find(selectors,this,new Set(),true)[0] || null
|
|
255
255
|
}
|
|
256
256
|
getElementsByClassName(query){ return this.querySelectorAll('.'+query) }
|
|
257
257
|
getElementsByTagName(query){ return this.querySelectorAll(query) }
|
|
258
258
|
getElementById(query){ return this.querySelector('#'+query) }
|
|
259
259
|
get children(){
|
|
260
260
|
return this.childNodes.filter(child=>{
|
|
261
261
|
if (!(child instanceof Node)) return false
|
|
262
262
|
if (child.tagName==='#comment') return false
|
|
263
263
|
return true
|
|
264
264
|
});
|
|
265
265
|
}
|
|
266
266
|
insertAdjacentElement(position,newElement){
|
|
267
267
|
if(newElement.tagName==='ROOT' && newElement.childNodes.length>0) newElement=newElement.childNodes[0]
|
|
268
268
|
const pos=position.toLowerCase();
|
|
269
269
|
if (pos==="afterbegin") this.childNodes.unshift(newElement);
|
|
270
270
|
else if (pos==="beforeend") this.childNodes.push(newElement);
|
|
271
271
|
if (!this.parent) return newElement
|
|
272
272
|
if (pos==="beforebegin") this.parent.childNodes.unshift(newElement);
|
|
273
273
|
else if (pos==="afterend") this.parent.childNodes.splice(this.childIndex+1,0,newElement);
|
|
274
274
|
return newElement
|
|
275
275
|
}
|
|
276
276
|
insertAdjacentHTML(position,html){
|
|
277
277
|
const newNode=parseHTML(html);
|
|
278
278
|
return this.insertAdjacentElement(position,newNode);
|
|
279
279
|
}
|
|
280
280
|
insertAdjacentText(position,text){
|
|
281
281
|
return this.insertAdjacentElement(position,new TextNode(text));
|
|
282
282
|
}
|
|
283
283
|
set innerHTML(html){
|
|
284
284
|
const parsed=parseHTML(html);
|
|
285
285
|
this.childNodes=parsed.childNodes;
|
|
286
286
|
}
|
|
287
287
|
set outerHTML(html){
|
|
288
288
|
const parsed=parseHTML(html);
|
|
289
289
|
if (!this.parent) return console.log('element has no parent node')
|
|
290
290
|
const index=this.childIndex
|
|
291
291
|
if (index!==null) this.parent.childNodes.splice(index,1,...parsed.childNodes);
|
|
292
292
|
}
|
|
293
293
|
appendChild(newChild){
|
|
294
294
|
if (newChild instanceof Node || newChild instanceof TextNode || newChild instanceof SingleNode){
|
|
295
295
|
if (newChild.parent) newChild.parent.childNodes=newChild.parent.childNodes.filter(child=>child!==newChild);
|
|
296
296
|
} else if(typeof newChild==='string') newChild=new TextNode(newChild)
|
|
297
297
|
else return newChild
|
|
298
298
|
this.childNodes.push(newChild);
|
|
299
299
|
newChild.parent=this;
|
|
300
300
|
return newChild;
|
|
301
301
|
}
|
|
302
302
|
get textContent(){
|
|
303
303
|
if (this.childNodes.length===0) return this.nodeName==='#text' ? this.nodeValue : '';
|
|
304
304
|
return this.childNodes.map(child=>{
|
|
305
305
|
if(child instanceof SingleNode) return ''
|
|
306
306
|
if(child instanceof TextNode) return child.nodeValue
|
|
307
307
|
if(child instanceof Node) return child.textContent;
|
|
308
308
|
else return child;
|
|
309
309
|
}).join(" ");
|
|
310
310
|
}
|
|
311
311
|
set textContent(value){
|
|
312
312
|
this.childNodes=[];
|
|
313
313
|
if (value!==null && value!==undefined){
|
|
314
314
|
this.childNodes.push(value.toString());
|
|
315
315
|
}
|
|
316
316
|
}
|
|
317
317
|
}
|
|
318
|
-
class SingleNode extends Node{
|
|
319
318
|
constructor(tagName,attributes={},parent=null){
|
|
320
319
|
if(attributes['?'] && tagName==='?xml') delete attributes['?']
|
|
321
320
|
super(tagName,attributes,parent);
|
|
322
321
|
this.isSingle=true
|
|
323
322
|
}
|
|
324
323
|
get outerHTML(){
|
|
325
324
|
if (this.tagName==="#cdata-section") return `<![CDATA[${this.textContent}]]>`;
|
|
326
325
|
const attrs=Object.entries(this.attributes).map(([key,val])=>`${key}="${val}"`).join(" ");
|
|
327
326
|
return `<${this.tagName} ${attrs}${this.tagName==='?xml' ? '?' : ''}>`;
|
|
328
327
|
}
|
|
329
328
|
get innerHTML(){ return ""; }
|
|
330
329
|
set innerHTML(_){ }
|
|
331
330
|
$(_){return null}
|
|
332
331
|
$$(_){return []}
|
|
333
332
|
querySelectorAll(_){ return []; }
|
|
334
333
|
querySelector(_){ return null; }
|
|
335
334
|
getElementsByClassName(_){ return []; }
|
|
336
335
|
getElementsByTagName(_){ return []; }
|
|
337
336
|
getElementById(_){ return null; }
|
|
338
337
|
get children(){ return []; }
|
|
339
338
|
insertAdjacentElement(_,__){ }
|
|
340
339
|
insertAdjacentHTML(_,__){ }
|
|
341
340
|
insertAdjacentText(_,__){ }
|
|
342
341
|
appendChild(_){ }
|
|
343
342
|
get textContent(){ return ""; }
|
|
344
343
|
set textContent(_){ }
|
|
344
|
+
class SingleNode extends Node{
|
|
345
345
|
constructor(tagName,attributes={},parent=null){
|
|
346
346
|
if(attributes['?'] && tagName==='?xml') delete attributes['?']
|
|
347
347
|
super(tagName,attributes,parent);
|
|
348
348
|
this.isSingle=true
|
|
349
349
|
}
|
|
350
350
|
get outerHTML(){
|
|
351
351
|
if (this.tagName==="#cdata-section") return `<![CDATA[${this.nodeValue}]]>`;
|
|
352
352
|
const attrs=Object.entries(this.attributes).map(([key,val])=>`${key}="${val}"`).join(" ");
|
|
353
353
|
return `<${this.tagName} ${attrs}${this.tagName==='?xml' ? '?' : ''}>`;
|
|
354
354
|
}
|
|
355
355
|
get innerHTML(){ return ""; }
|
|
356
356
|
set innerHTML(_){ }
|
|
357
357
|
$(_){return null}
|
|
358
358
|
$$(_){return []}
|
|
359
359
|
querySelectorAll(_){ return []; }
|
|
360
360
|
querySelector(_){ return null; }
|
|
361
361
|
getElementsByClassName(_){ return []; }
|
|
362
362
|
getElementsByTagName(_){ return []; }
|
|
363
363
|
getElementById(_){ return null; }
|
|
364
364
|
get children(){ return []; }
|
|
365
365
|
insertAdjacentElement(_,__){ }
|
|
366
366
|
insertAdjacentHTML(_,__){ }
|
|
367
367
|
insertAdjacentText(_,__){ }
|
|
368
368
|
appendChild(_){ }
|
|
369
369
|
get textContent(){ return ""; }
|
|
370
370
|
set textContent(_){ }
|
|
371
371
|
}
|
|
372
372
|
function parseAttributes(str){
|
|
373
373
|
const attrs={};
|
|
374
374
|
let key="";
|
|
375
375
|
let value="";
|
|
376
376
|
let isKey=true;
|
|
377
377
|
let quoteChar=null;
|
|
378
378
|
for (let i=0; i< str.length; i++){
|
|
379
379
|
const char=str[i];
|
|
380
380
|
if (isKey && (char==='=' || char===' ')){
|
|
381
381
|
if (char==='=') isKey=false;
|
|
382
382
|
else if (key.trim()){
|
|
383
383
|
attrs[key.trim()]=true;
|
|
384
384
|
key="";
|
|
385
385
|
}
|
|
386
386
|
continue;
|
|
387
387
|
}
|
|
388
388
|
if (!quoteChar && (char==='"' || char==="'")){
|
|
389
389
|
quoteChar=char;
|
|
390
390
|
continue;
|
|
391
391
|
} else if (quoteChar && char===quoteChar){
|
|
392
392
|
quoteChar=null;
|
|
393
393
|
attrs[key.trim()]=value.trim();
|
|
394
394
|
key=""; value=""; isKey=true;
|
|
395
395
|
continue;
|
|
396
396
|
}
|
|
397
397
|
if (isKey) key+=char;
|
|
398
398
|
else value+=char;
|
|
399
399
|
}
|
|
400
400
|
if (key.trim() &&!value) attrs[key.trim()]=true;
|
|
401
401
|
return attrs;
|
|
402
402
|
}
|