als-document 0.1.1 → 0.5.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/document.js +489 -512
- package/package.json +6 -7
- package/parser/parser.js +287 -0
- package/parser/readme.md +121 -0
- package/parser/test.js +233 -0
- package/query/query.js +147 -0
- package/query/readme.md +131 -0
- package/query/test.js +143 -0
- package/readme.md +287 -135
- package/selector/readme.md +74 -0
- package/selector/selector.js +125 -0
- package/selector/test.js +410 -0
- package/test/html1.js +50 -0
- package/test/html2.js +1126 -0
- package/test/test.js +17 -0
package/document.js
CHANGED
|
@@ -1,585 +1,562 @@
|
|
|
1
|
-
class
|
|
2
|
-
static
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
this.types = {}
|
|
6
|
-
this.domTree = []
|
|
7
|
-
this.added = []
|
|
8
|
-
this.domList = []
|
|
9
|
-
this.comments = []
|
|
10
|
-
this.scripts = {}
|
|
11
|
-
this.events = {}
|
|
12
|
-
this.htmlText = htmlText
|
|
13
|
-
this.doctype = ''
|
|
14
|
-
this.getDoctype()
|
|
15
|
-
this.removeComments()
|
|
16
|
-
this.removeScripts()
|
|
17
|
-
this.removeEvents()
|
|
18
|
-
this.parseTags()
|
|
19
|
-
this.addScripts()
|
|
20
|
-
this.addEvents()
|
|
21
|
-
this.addComments()
|
|
22
|
-
this.getPairs()
|
|
23
|
-
}
|
|
24
|
-
// Get domList
|
|
25
|
-
getDoctype() {
|
|
26
|
-
let doctype = this.htmlText.match(/\<\!DOCTYPE([\S\s]*?)\>/gm,'')
|
|
27
|
-
if(doctype !== null) {
|
|
28
|
-
this.doctype = doctype[0]
|
|
29
|
-
this.htmlText = this.htmlText.replace(/\<\!DOCTYPE([\S\s]*?)\>/gm,'')
|
|
30
|
-
}
|
|
1
|
+
class Query {
|
|
2
|
+
static get(query) {
|
|
3
|
+
let q = new Query(query)
|
|
4
|
+
return q.selectors
|
|
31
5
|
}
|
|
32
6
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
7
|
+
constructor(query) {
|
|
8
|
+
this.query = query
|
|
9
|
+
this.selectors = []
|
|
10
|
+
this.getQueries(query.split(','))
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
getQueries(selectors) {
|
|
14
|
+
selectors.forEach(selector => {
|
|
15
|
+
let originalSelector = selector
|
|
16
|
+
selector = this.removeSpaces(selector)
|
|
17
|
+
this.stringValues = []
|
|
18
|
+
selector = selector.replace(/\[.*?\]/g,(value) => {
|
|
19
|
+
this.stringValues.push(value)
|
|
20
|
+
return `[${this.stringValues.length-1}]`
|
|
21
|
+
})
|
|
22
|
+
let [element,ancestors] = this.splitAndCutLast(selector,' ') // \s - ancestor
|
|
23
|
+
element = this.getFamily(element)
|
|
24
|
+
if(ancestors.length > 0)
|
|
25
|
+
element.ancestors = ancestors.map(ancestor => this.getFamily(ancestor))
|
|
26
|
+
element.group = originalSelector
|
|
27
|
+
this.selectors.push(element)
|
|
39
28
|
});
|
|
40
29
|
}
|
|
41
30
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
});
|
|
31
|
+
splitAndCutLast(string,splitBy) {
|
|
32
|
+
let array = string.split(splitBy)
|
|
33
|
+
let last
|
|
34
|
+
if(array.length == 1) {
|
|
35
|
+
last = array[0]
|
|
36
|
+
array = []
|
|
37
|
+
} else last = array.splice(array.length-1,array.length-1)[0]
|
|
38
|
+
return [last,array]
|
|
53
39
|
}
|
|
54
40
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
let
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
41
|
+
getFamily(group,element,prev,prevAny,sign) {
|
|
42
|
+
if(group.match(/\~|\+/) !== null) {
|
|
43
|
+
let [last,prevBrothers] = this.splitAndCutLast(group,/\~|\+/)
|
|
44
|
+
let signs = group.replace(last,'')
|
|
45
|
+
prevBrothers.forEach(el => signs = signs.replace(el,''))
|
|
46
|
+
signs = signs.match(/\~|\+/g)
|
|
47
|
+
if(signs.length == 1) {
|
|
48
|
+
sign = signs[0]
|
|
49
|
+
} else if(signs.length > 1){
|
|
50
|
+
sign = signs.splice(signs.length-1,signs.length-1)[0]
|
|
51
|
+
prevBrothers[0] = prevBrothers.map((b,i) => {
|
|
52
|
+
if(i<prevBrothers.length-1) b += signs[i]
|
|
53
|
+
return b
|
|
54
|
+
}).join('')
|
|
55
|
+
prevBrothers[0] = this.getFamily(prevBrothers[0])
|
|
64
56
|
}
|
|
65
|
-
|
|
57
|
+
if(sign == '~') prevAny = prevBrothers[0] // ~ - any prev brother
|
|
58
|
+
else if(sign == '+') prev = prevBrothers[0] // + - prev brother
|
|
59
|
+
element = last
|
|
60
|
+
} else element = group
|
|
61
|
+
let family
|
|
62
|
+
if(prev || prevAny) {
|
|
63
|
+
family = this.getParents(element)
|
|
64
|
+
if(prev) family.prev = this.getParents(prev)
|
|
65
|
+
if(prevAny) family.prevAny = this.getParents(prevAny)
|
|
66
|
+
} else family = this.getParents(element)
|
|
67
|
+
if(family.query !== group) family.group = group
|
|
68
|
+
return family
|
|
66
69
|
}
|
|
67
70
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
let scriptName = `{script${i}}`
|
|
77
|
-
let newScript = script.replace(scriptContent,scriptName)
|
|
78
|
-
this.events[scriptName] = scriptContent
|
|
79
|
-
this.htmlText = this.htmlText.replace(script,newScript)
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
});
|
|
71
|
+
getParents(selector) {
|
|
72
|
+
if(typeof selector == 'string') {
|
|
73
|
+
let [element,parents] = this.splitAndCutLast(selector,'>')
|
|
74
|
+
element = this.buildElement(element)
|
|
75
|
+
parents = parents.map(parent => this.buildElement(parent))
|
|
76
|
+
if(parents.length > 0) element.parents = parents
|
|
77
|
+
return element
|
|
78
|
+
} else return selector
|
|
83
79
|
}
|
|
84
80
|
|
|
85
|
-
addScripts() {
|
|
86
|
-
this.domList.forEach((element,i) => {
|
|
87
|
-
if(element.tagName == 'script' && !element.close) {
|
|
88
|
-
let text = this.domList[i+1].text
|
|
89
|
-
if(this.scripts[text] !== undefined) {
|
|
90
|
-
this.domList[i+1].text = this.scripts[text]
|
|
91
|
-
delete this.scripts[text]
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
81
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
82
|
+
buildElement(element,id=null,tag=null,classList=[]) {
|
|
83
|
+
let query = element
|
|
84
|
+
element = element.replace(/\#(\w-?)*/,$id => {
|
|
85
|
+
id = $id.replace(/^\#/,''); return ''
|
|
86
|
+
})
|
|
87
|
+
element = element.replace(/\.(\w-?)*/,$class => {
|
|
88
|
+
classList.push($class.replace(/^\./,'')); return ''
|
|
89
|
+
})
|
|
90
|
+
element = element.replace(/(\w-?)*/,$tag => {
|
|
91
|
+
tag = $tag == '' ? null : $tag; return ''
|
|
92
|
+
})
|
|
93
|
+
let attribs = this.getAttributes(element)
|
|
94
|
+
element = {query}
|
|
95
|
+
if(id) element.id = id
|
|
96
|
+
if(tag) element.tag = tag
|
|
97
|
+
if(classList.length > 0) element.classList = classList
|
|
98
|
+
if(attribs.length > 0) element.attribs = attribs
|
|
99
|
+
return element
|
|
109
100
|
}
|
|
110
101
|
|
|
111
|
-
|
|
112
|
-
let
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
if(
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
if(obj.close) {
|
|
129
|
-
let j = this.findOpen(objName)
|
|
130
|
-
if(j >=0) {
|
|
131
|
-
let closeTag = index
|
|
132
|
-
let openTagObj = this.domList[j][this.domList[j].name]
|
|
133
|
-
this.domList[j] = {...openTagObj,closeTag}
|
|
134
|
-
}
|
|
135
|
-
this.domList[obj.index] = obj
|
|
102
|
+
getAttributes(element) {
|
|
103
|
+
let attribs = this.stringValues.filter((value,index) => {
|
|
104
|
+
let searchValue = `[${index}]`
|
|
105
|
+
if(element.match(searchValue)) return true
|
|
106
|
+
else return false
|
|
107
|
+
})
|
|
108
|
+
attribs = attribs.map(attrib => {
|
|
109
|
+
let query = attrib
|
|
110
|
+
attrib = attrib.replace('[','').replace(']','')
|
|
111
|
+
let [name,value] = attrib.split(/[\~\|\^\$\*]?\=/)
|
|
112
|
+
let sign = attrib.replace(name,'').replace(value,'')
|
|
113
|
+
attrib = {query}
|
|
114
|
+
if(name) attrib.name = name
|
|
115
|
+
if(value) attrib.value = value.trim().replace(/^\"/,'').replace(/\"$/,'')
|
|
116
|
+
if(sign) {
|
|
117
|
+
attrib.sign = sign
|
|
118
|
+
attrib.check = this.getAttribFn(sign).bind(attrib)
|
|
136
119
|
}
|
|
137
|
-
|
|
138
|
-
index++
|
|
120
|
+
return attrib
|
|
139
121
|
});
|
|
122
|
+
return attribs
|
|
140
123
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
if(
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
if(
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
obj = this.buildClass(obj)
|
|
155
|
-
if(obj.attributes.id !== undefined) {
|
|
156
|
-
obj.id = obj.attributes.id
|
|
157
|
-
delete obj.attributes.id
|
|
124
|
+
|
|
125
|
+
getAttribFn(sign) {
|
|
126
|
+
if(sign == '=') return function(value) {return value == this.value ? true : false}
|
|
127
|
+
if(sign == '*=') return function(value) {return value.includes(this.value) ? true : false}
|
|
128
|
+
if(sign == '^=') return function(value) {return value.startsWith(this.value) ? true : false}
|
|
129
|
+
if(sign == '$=') return function(value) {return value.endsWith(this.value) ? true : false}
|
|
130
|
+
if(sign == '|=') return function(value) {
|
|
131
|
+
return value.trim().split(' ').length == 1
|
|
132
|
+
&& (value.startsWith(this.value) || value.startsWith(this.value+'-'))
|
|
133
|
+
? true : false
|
|
134
|
+
}
|
|
135
|
+
if(sign == '~=') return function(value) { // includes whole word only
|
|
136
|
+
return this.value.trim().split(' ').length == 1 && value.includes(this.value) ? true : false
|
|
158
137
|
}
|
|
159
|
-
return obj
|
|
160
138
|
}
|
|
161
139
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
else if(obj.close && this.types[tagName].lastOperation == 0)
|
|
168
|
-
this.types[tagName].count--
|
|
169
|
-
else if(!obj.close && this.types[tagName].lastOperation == 0)
|
|
170
|
-
this.types[tagName].lastOperation = 1
|
|
171
|
-
else if(!obj.close && this.types[tagName].lastOperation == 1)
|
|
172
|
-
this.types[tagName].count++
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
getAttributes(string,attributes = {}) {
|
|
176
|
-
let matches = string.match(/\s(\/?\w*\-?)*((\S)*?\s?=[\S\s]*?\"[\S\s]*?\")?/g)
|
|
177
|
-
if(matches !== null) matches.forEach(attribute => {
|
|
178
|
-
attribute = attribute.trim()
|
|
179
|
-
if(attribute !== '') {
|
|
180
|
-
let attName = attribute.split('=')[0]
|
|
181
|
-
let attValue = attribute.replace(attName,'').replace('=','').replace(/\"/g,'')
|
|
182
|
-
if(attName !== '/') attributes[attName] = attValue.trim()
|
|
183
|
-
}
|
|
184
|
-
})
|
|
185
|
-
return attributes
|
|
140
|
+
removeSpaces(selector) {
|
|
141
|
+
selector = selector.replace(/\s{2}/g,' ') // remove double spaces
|
|
142
|
+
selector = selector.replace(/\s?\^?\$?\|?\~?\*?\=\s*/g,(m) => m.trim()) // remove spaces inside []
|
|
143
|
+
selector = selector.replace(/\s?(\+|\~|\>)\s?/g,(m) => m.trim()) // remove spaces around +|~|>
|
|
144
|
+
return selector
|
|
186
145
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
class HtmlParser {
|
|
149
|
+
static parse(html) {
|
|
150
|
+
let result = new HtmlParser(html)
|
|
151
|
+
return result.root
|
|
152
|
+
}
|
|
153
|
+
constructor(html='') {
|
|
154
|
+
if(this.checkHtml(html)) {
|
|
155
|
+
this.indexes = []
|
|
156
|
+
this.events = []
|
|
157
|
+
this.html = this.htmlString = html
|
|
158
|
+
this.removeScripts()
|
|
159
|
+
this.removeStyles()
|
|
160
|
+
this.removeEventStrings()
|
|
161
|
+
this.htmlString = this.htmlString.replace(/\<\!\-\-([\S\s]*?)\-\-\>/gm,'') // remove all comments
|
|
162
|
+
this.root = this.parse()
|
|
204
163
|
}
|
|
205
|
-
return obj
|
|
206
164
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
this.buildTag(index,domTree)
|
|
214
|
-
break;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
165
|
+
|
|
166
|
+
checkHtml(html,isGood=false) {
|
|
167
|
+
if(html == '') console.log('html parameter is empty')
|
|
168
|
+
else if(typeof html !== 'string') console.log(`html parameter has to be string. Recieved ${typeof html}`)
|
|
169
|
+
else isGood = true
|
|
170
|
+
return isGood
|
|
217
171
|
}
|
|
218
172
|
|
|
219
|
-
|
|
220
|
-
this.
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
this.
|
|
230
|
-
if(
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
content.json = () => Document.removeMethods(content)
|
|
235
|
-
delete content.closeTag
|
|
236
|
-
delete content.close
|
|
237
|
-
delete content.index
|
|
238
|
-
delete content.order
|
|
239
|
-
domTree.push(content)
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
static buildMethods(content) {
|
|
243
|
-
content.children.forEach((child,index) => { // prev and next
|
|
244
|
-
if(index == 0) child.prev = null
|
|
245
|
-
else child.prev = content.children[index-1]
|
|
246
|
-
if(index == content.children.length-1) child.next = null
|
|
247
|
-
else child.next = content.children[index+1]
|
|
173
|
+
removeScripts(scripts=[]) {
|
|
174
|
+
let $scripts = this.htmlString.match(/\<script(.*?)\>[\S\s]*?\<\/script\>/gm)
|
|
175
|
+
if($scripts !== null) $scripts.forEach((script,i) => {
|
|
176
|
+
let inner = script.replace(/^\<script(.*?)\>/,'').replace(/\<\/script\>$/,'')
|
|
177
|
+
scripts.push(inner)
|
|
178
|
+
this.htmlString = this.htmlString.replace(inner,`{{{{script ${scripts.length-1}`)
|
|
179
|
+
});
|
|
180
|
+
this.scripts = scripts
|
|
181
|
+
}
|
|
182
|
+
removeStyles(styles=[]) {
|
|
183
|
+
let $styles = this.htmlString.match(/\<style\>[\S\s]*?\<\/style\>/gm)
|
|
184
|
+
if($styles !== null) $styles.forEach((style,i) => {
|
|
185
|
+
let inner = style.replace(/^\<style\>/,'').replace(/\<\/style\>$/,'')
|
|
186
|
+
styles.push(inner)
|
|
187
|
+
this.htmlString = this.htmlString.replace(inner,`{{{{style ${styles.length-1}`)
|
|
248
188
|
});
|
|
249
|
-
|
|
189
|
+
this.styles = styles
|
|
250
190
|
}
|
|
251
191
|
|
|
252
|
-
|
|
253
|
-
let
|
|
254
|
-
if(
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
192
|
+
removeEventStrings() {
|
|
193
|
+
let eventsWithHtml = this.htmlString.match(/on\w*\s*?\=\s*?["|'|`](.*?(<[^>]*>)(\'|\`).*?)["|'|`]/g)
|
|
194
|
+
if(eventsWithHtml !== null) {
|
|
195
|
+
eventsWithHtml.forEach(event => {
|
|
196
|
+
let array = event.split('=')
|
|
197
|
+
let value = array.filter((v,i) => i>0 && i!=='').join('=')
|
|
198
|
+
value = value.replace(/^\"/,'').replace(/\"$/,'')
|
|
199
|
+
this.events.push(value)
|
|
200
|
+
let newEvent = event.replace(value,`{{{{event ${this.events.length-1}`)
|
|
201
|
+
this.htmlString = this.htmlString.replace(event,newEvent)
|
|
202
|
+
})
|
|
260
203
|
}
|
|
261
204
|
}
|
|
262
205
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
206
|
+
parse(htmlString=this.htmlString) {
|
|
207
|
+
// Parse tags
|
|
208
|
+
let elements = htmlString.match(/<[^>]*>/g)
|
|
209
|
+
elements.forEach((tag,index) => {
|
|
210
|
+
elements[index] = this.parseElement(tag)
|
|
211
|
+
htmlString = htmlString.replace(tag,`<tag${index}>`)
|
|
268
212
|
});
|
|
213
|
+
// Parse inner text
|
|
214
|
+
let inners = htmlString.match(/tag[\s\S]*?\</g)
|
|
215
|
+
for (let i = inners.length-1; i >=0 ; i--) {
|
|
216
|
+
let inner = inners[i];
|
|
217
|
+
let tagIndex = inner.match(/(\d*)\>/)[1]
|
|
218
|
+
inner = inner.replace(/tag.*\>/,'').slice(0, -1).trim()
|
|
219
|
+
if(inner.length > 0) {
|
|
220
|
+
elements.splice(parseInt(tagIndex)+1, 0, inner);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
this.elements = elements
|
|
224
|
+
let root = this.getPairs()
|
|
225
|
+
return root
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
lookForPair(element,startIndex,parent,level) {
|
|
229
|
+
element.parent = parent
|
|
230
|
+
element.children = []
|
|
231
|
+
let {tag} = element
|
|
232
|
+
let count = 0
|
|
233
|
+
let endIndex
|
|
234
|
+
for (let index = startIndex+1; index < this.elements.length; index++) {
|
|
235
|
+
const el = this.elements[index];
|
|
236
|
+
if(el.tag == tag) {
|
|
237
|
+
if(el.status == 'close') {
|
|
238
|
+
if(count == 0) {
|
|
239
|
+
endIndex = index
|
|
240
|
+
el.level = level
|
|
241
|
+
break
|
|
242
|
+
} else count--
|
|
243
|
+
} else if(el.status == 'open') count++
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
if(!endIndex) endIndex = startIndex+1
|
|
247
|
+
element.endIndex = endIndex
|
|
248
|
+
let child = this.getPairs(element,startIndex+1,endIndex,level+1)
|
|
249
|
+
return child
|
|
269
250
|
}
|
|
270
251
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
252
|
+
getPairs(parent={type:'root',children:[]},startIndex = 0,endIndex=this.elements.length,level=0,childIndex=0) {
|
|
253
|
+
for(let index = startIndex; index < endIndex; index++) {
|
|
254
|
+
if(this.indexes.includes(index)) continue
|
|
255
|
+
const element = this.elements[index];
|
|
256
|
+
let child
|
|
257
|
+
if(typeof element == 'string') child = element
|
|
258
|
+
else if(element.type == 'tag') {
|
|
259
|
+
if(element.status == 'single') {
|
|
260
|
+
child = element
|
|
261
|
+
child.parent = parent
|
|
262
|
+
}
|
|
263
|
+
else if(element.status == 'open') {
|
|
264
|
+
child = this.lookForPair(element,index,parent,level)
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
this.addChild(parent,child,index,level,childIndex/2)
|
|
268
|
+
childIndex++
|
|
275
269
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
if(place == 0 || place == 3) build(content.parent)
|
|
286
|
-
|
|
287
|
-
function build(parent) {
|
|
288
|
-
element.parent = parent
|
|
289
|
-
element = Document.buildMethods(parent)
|
|
290
|
-
Document.buildInnerText(parent)
|
|
270
|
+
return parent
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
addScriptsAndStyles(parent,child,index) {
|
|
274
|
+
if(parent.tag == 'script') {
|
|
275
|
+
let scriptIndex = child.match(/(?<=\{\{\{\{script\s)(\d*)?/)
|
|
276
|
+
if(scriptIndex !== null) {
|
|
277
|
+
let i = parseInt(scriptIndex[0])
|
|
278
|
+
if(typeof i == 'number') child = this.scripts[i]
|
|
291
279
|
}
|
|
292
|
-
return element
|
|
293
280
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
static newElement(outerHtml) {
|
|
301
|
-
let document = new Document(outerHtml)
|
|
302
|
-
return document.domTree[0].json()
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
build(filePath,array=this.domTree,html = '',space='') {
|
|
306
|
-
let extraSpace = space+' '
|
|
307
|
-
let nl = `
|
|
308
|
-
`
|
|
309
|
-
array.forEach(element => {
|
|
310
|
-
if(element.text !== undefined) html += space+element.text+nl
|
|
311
|
-
else if(element.tagName == 'comment' ) {
|
|
312
|
-
html += space+element.comment + nl
|
|
313
|
-
} else {
|
|
314
|
-
let attributes = ''
|
|
315
|
-
for(let propName in element.attributes) {
|
|
316
|
-
let value = element.attributes[propName]
|
|
317
|
-
let attribute = ` ${propName}="${value}"`
|
|
318
|
-
if(attribute.length + attributes.length > 80) attribute = nl+space+attribute
|
|
319
|
-
attributes += attribute
|
|
320
|
-
}
|
|
321
|
-
let id = ''
|
|
322
|
-
if(element.id !== undefined) id = ` id="${element.id}"`
|
|
323
|
-
html += `${space}<${element.tagName}${id}${attributes}>${nl}`
|
|
324
|
-
if(element.children !== undefined)
|
|
325
|
-
if(element.children.length >0) html = this.build(filePath,element.children,html,extraSpace)
|
|
326
|
-
if(element.tagName !== undefined && !Document.singlTags.includes(element.tagName))
|
|
327
|
-
html += `${space}</${element.tagName}>${nl}`
|
|
281
|
+
if(parent.tag == 'style') {
|
|
282
|
+
let stylesIndex = child.match(/(?<=\{\{\{\{style\s)(\d*)?/)
|
|
283
|
+
if(stylesIndex !== null) {
|
|
284
|
+
let i = parseInt(stylesIndex[0])
|
|
285
|
+
if(typeof i == 'number') child = this.styles[i]
|
|
328
286
|
}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
287
|
+
}
|
|
288
|
+
this.elements[index] = child
|
|
289
|
+
return child
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
addChild(parent,child,index,level,childIndex) {
|
|
293
|
+
if(typeof child == 'string') {
|
|
294
|
+
child = this.addScriptsAndStyles(parent,child,index)
|
|
295
|
+
child = {type:'text',text:child}
|
|
296
|
+
this.elements[index] = child
|
|
333
297
|
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
298
|
+
if(child) {
|
|
299
|
+
delete child.status
|
|
300
|
+
this.getElements(child)
|
|
301
|
+
this.innerHTML(child)
|
|
302
|
+
this.outerHTML(child)
|
|
303
|
+
this.innerText(child)
|
|
304
|
+
this.getAncestors(child)
|
|
305
|
+
this.getAttribute(child)
|
|
306
|
+
child.childIndex = childIndex
|
|
307
|
+
child.index = index
|
|
308
|
+
child.level = level
|
|
309
|
+
child.prev = null
|
|
310
|
+
child.next = null
|
|
311
|
+
if(parent.children.length > 0) {
|
|
312
|
+
let prevI = parent.children.length-1
|
|
313
|
+
parent.children[prevI].next = child
|
|
314
|
+
child.prev = parent.children[prevI]
|
|
348
315
|
}
|
|
316
|
+
parent.children.push(child)
|
|
349
317
|
}
|
|
318
|
+
this.indexes.push(index)
|
|
350
319
|
}
|
|
351
|
-
|
|
352
|
-
findOpen(key,array=this.domList) {
|
|
353
|
-
return array.findIndex(function(obj, index) {
|
|
354
|
-
if(obj[key] !== undefined && obj[key].close == false && obj[key].closeTag == undefined)
|
|
355
|
-
return true;
|
|
356
|
-
});
|
|
357
|
-
}
|
|
358
|
-
// querySelector
|
|
359
|
-
$(selector,obj) {return this.$$(selector,obj,true)}
|
|
360
320
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
let array = this.findElements(obj)
|
|
367
|
-
if(first) return array[0]
|
|
368
|
-
else return this.buildCollection(array)
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
getSelectors() {
|
|
372
|
-
this.getPropSelctors() // remove all attributes from selector, build them, replace as [i] and put into selectors.attributes[]
|
|
373
|
-
let groups = this.selector.split(',')
|
|
374
|
-
groups.forEach(group => {
|
|
375
|
-
let result = {}
|
|
376
|
-
group = group.trim()
|
|
377
|
-
let family = group.split('>')
|
|
378
|
-
let prevBrother = group.split('+')
|
|
379
|
-
let nextBrother = group.split('~')
|
|
380
|
-
if(family.length > 1) {
|
|
381
|
-
result.parent = this.buildSingleSelector(family[0])
|
|
382
|
-
result.element = this.buildSingleSelector(family[1])
|
|
383
|
-
} else if(prevBrother.length > 1) {
|
|
384
|
-
result.prev = this.buildSingleSelector(prevBrother[0])
|
|
385
|
-
result.element = this.buildSingleSelector(prevBrother[1])
|
|
386
|
-
} else if(nextBrother.length > 1) {
|
|
387
|
-
result.next = this.buildSingleSelector(nextBrother[0])
|
|
388
|
-
result.element = this.buildSingleSelector(nextBrother[1])
|
|
389
|
-
} else result.element = this.buildSingleSelector(group)
|
|
390
|
-
this.selectors.push(result)
|
|
391
|
-
});
|
|
321
|
+
getAttribute(element) {
|
|
322
|
+
element.getAttribute = function(name) {
|
|
323
|
+
let array = Object.keys(this.attribs).filter(key => key == name)
|
|
324
|
+
return array.length > 0 ? this.attribs[array[0]] : null
|
|
325
|
+
}
|
|
392
326
|
}
|
|
393
327
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
let array = attribute.split('=')
|
|
402
|
-
let propName = array[0]
|
|
403
|
-
let propValue = (array[1] == undefined) ? '' : array[1].replace(/"/g,'')
|
|
404
|
-
let sign
|
|
405
|
-
if(signs.includes(propName.slice(-1))) {
|
|
406
|
-
sign = propName.slice(-1)
|
|
407
|
-
propName = propName.slice(0, -1)
|
|
328
|
+
getAncestors(element) {
|
|
329
|
+
Object.defineProperty(element, 'ancestors', { get() {
|
|
330
|
+
let ancestors = []
|
|
331
|
+
let parent = this.parent
|
|
332
|
+
if(parent) while(parent.parent) {
|
|
333
|
+
ancestors.unshift(parent)
|
|
334
|
+
parent = parent.parent
|
|
408
335
|
}
|
|
409
|
-
|
|
410
|
-
});
|
|
336
|
+
return ancestors
|
|
337
|
+
}});
|
|
411
338
|
}
|
|
412
339
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
340
|
+
getElements(element,elements=this.elements) {
|
|
341
|
+
Object.defineProperty(element, 'elements', { get() {
|
|
342
|
+
return elements.slice(this.index,this.endIndex+1)
|
|
343
|
+
}});
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
outerHTML(element) {
|
|
347
|
+
Object.defineProperty(element, 'outerHTML', { get() {
|
|
348
|
+
let {elements} = this
|
|
349
|
+
return elements[0].text + this.innerHTML + elements[elements.length-1].text
|
|
350
|
+
}});
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
innerText(element) {
|
|
354
|
+
Object.defineProperty(element, 'innerText', { get() {
|
|
355
|
+
if(element.children)
|
|
356
|
+
return element.children.map(child => child.type == 'text' ? child.text : '').join('')
|
|
357
|
+
else return ''
|
|
358
|
+
}})
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
innerHTML(element) {
|
|
362
|
+
Object.defineProperty(element, 'innerHTML', { get() {
|
|
363
|
+
let tab = ' ',result = '',firstLevel,space=''
|
|
364
|
+
let {elements} = this
|
|
365
|
+
let endIndex = elements.length
|
|
366
|
+
for (let i = 1; i < endIndex-1; i++) {
|
|
367
|
+
let element = elements[i]
|
|
368
|
+
let {level,tag,text} = element
|
|
369
|
+
if(firstLevel == undefined) firstLevel = level
|
|
370
|
+
if(i == endIndex-1) space = ''
|
|
371
|
+
else if(level) space = Array.from(Array(level-firstLevel).keys()).map(n => tab).join('')
|
|
372
|
+
result += space + text
|
|
373
|
+
if(endIndex > 3) result += '\n'
|
|
439
374
|
}
|
|
440
|
-
|
|
441
|
-
|
|
375
|
+
return result
|
|
376
|
+
}});
|
|
442
377
|
}
|
|
443
378
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
379
|
+
parseElement(tagString) {
|
|
380
|
+
let text = tagString
|
|
381
|
+
let type = 'tag'
|
|
382
|
+
if(tagString == '<!DOCTYPE html>') return {tag:'!DOCTYPE html',status:'single',attribs:{},type}
|
|
383
|
+
let status = 'close'
|
|
384
|
+
let tag = tagString.match(/(?<=\<\/)(\w*\-?)*/)
|
|
385
|
+
if(tag == null) {
|
|
386
|
+
tag = tagString.match(/(?<=\<)(\w*\-?)*/)
|
|
387
|
+
if(tag) {
|
|
388
|
+
tag = tag[0]
|
|
389
|
+
if(this.singleTags.includes(tag)) status='single'
|
|
390
|
+
else status = 'open'
|
|
391
|
+
}
|
|
392
|
+
} else tag = tag[0]
|
|
393
|
+
let {classList,attribs,style,id} = this.parseAttributes(tagString)
|
|
394
|
+
let obj = {tag,status,attribs,type,classList,text,style,id}
|
|
395
|
+
return obj
|
|
452
396
|
}
|
|
397
|
+
singleTags = ['comment','area','base','br','col','command','embed','hr','img','input','keygen','link','meta','param','source','track','wbr']
|
|
398
|
+
|
|
399
|
+
parseAttributes(tagString,classList=[],attribs={},style={},id=null) {
|
|
400
|
+
let attributes = tagString.match(/(?<=\s)(\w*\-?)*(\s*?\=\s*?\"[\s\S]*?\")?/g)
|
|
401
|
+
if(attributes) attributes.forEach(attribString => {
|
|
402
|
+
let [name,value] = attribString.split('=')
|
|
403
|
+
if(value !== undefined && name !== '') {
|
|
404
|
+
value = value.trim().replace(/^\"/,'').replace(/\"$/m,'')
|
|
405
|
+
|
|
406
|
+
let eventIndex = value.match(/(?<=\{\{\{\{event\s)(\d*)?/)
|
|
407
|
+
if(eventIndex !== null) value = this.events[eventIndex[0]]
|
|
453
408
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
if(
|
|
459
|
-
if(group.next !== undefined) addIt += this.checkElement(element.next,group.next)
|
|
460
|
-
if(group.element !== undefined) addIt += this.checkElement(element,group.element)
|
|
461
|
-
if(addIt == 0) array.push(element)
|
|
409
|
+
if(name == 'class') classList = value.split(/\s\s?\s?/)
|
|
410
|
+
else if(name == 'style') style = this.parseInlineCss(value)
|
|
411
|
+
else if(name == 'id') id = value
|
|
412
|
+
attribs[name] = value
|
|
413
|
+
} else if(name !== '') attribs[name] = undefined
|
|
462
414
|
});
|
|
463
|
-
return
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
if(
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
});
|
|
476
|
-
else addIt--
|
|
477
|
-
}
|
|
478
|
-
if(selectors.attributes !== undefined) addIt += this.checkAttributes(
|
|
479
|
-
element.attributes,
|
|
480
|
-
selectors.attributes.propName,
|
|
481
|
-
selectors.attributes.propValue,
|
|
482
|
-
selectors.attributes.sign
|
|
483
|
-
)
|
|
484
|
-
return addIt
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
checkAttributes(props,propName,propValue,sign,addIt = 0) {
|
|
488
|
-
if(props == undefined) return -1
|
|
489
|
-
else {
|
|
490
|
-
if(props[propName] == undefined) addIt--
|
|
491
|
-
if(propValue == '' && props[propName] == undefined) addIt--
|
|
492
|
-
if(propValue.length>0 && props[propName] !== undefined) {
|
|
493
|
-
if(sign == undefined) {
|
|
494
|
-
if(props[propName] !== propValue) addIt--
|
|
495
|
-
} else if(sign == '~') {
|
|
496
|
-
let r = new RegExp(`\\b${propValue}`)
|
|
497
|
-
if(props[propName].match(r) == null) addIt--
|
|
498
|
-
} else if(sign == '|') {
|
|
499
|
-
if(!props[propName].startsWith(propValue) || props[propName] !== propValue) addIt--
|
|
500
|
-
} else if(sign == '^') {
|
|
501
|
-
if(!props[propName].startsWith(propValue)) addIt--
|
|
502
|
-
} else if(sign == '$') {
|
|
503
|
-
if(!props[propName].endsWith(propValue)) addIt--
|
|
504
|
-
} else if(sign == '*') {
|
|
505
|
-
if(!props[propName].includes(propValue)) addIt--
|
|
415
|
+
return {classList,attribs,style,id}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
parseInlineCss(textCss) {
|
|
419
|
+
let rules = textCss.split(';')
|
|
420
|
+
let styles = {}
|
|
421
|
+
rules.forEach(rule => {
|
|
422
|
+
let [prop,value] = rule.trim().split(':')
|
|
423
|
+
if(rule !== '') {
|
|
424
|
+
if(prop.match(/\w*\-\w*(-\w*)?/) !== null) {
|
|
425
|
+
let words = prop.split('-')
|
|
426
|
+
prop = words.map((w,i) => i==0 ? w : w[0].toUpperCase() + w.slice(1)).join('')
|
|
506
427
|
}
|
|
428
|
+
styles[prop] = value.trim()
|
|
507
429
|
}
|
|
508
|
-
}
|
|
509
|
-
return
|
|
430
|
+
});
|
|
431
|
+
return styles
|
|
510
432
|
}
|
|
433
|
+
}
|
|
511
434
|
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
435
|
+
|
|
436
|
+
class HtmlSelector {
|
|
437
|
+
constructor(html) {
|
|
438
|
+
if(typeof html == 'string') {
|
|
439
|
+
html = new HtmlParser(html)
|
|
440
|
+
this.html = html
|
|
441
|
+
this.elements = html.elements
|
|
442
|
+
this.makeSelectable()
|
|
443
|
+
} else console.log('Parameter is not string')
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
makeSelectable() {
|
|
447
|
+
this.elements.forEach(element => {
|
|
448
|
+
if(element.type == 'tag' && element.status !== 'close') {
|
|
449
|
+
element.$$ = (query) => this.$$(query,element.index,element.endIndex)
|
|
450
|
+
element.$ = (query) => this.$(query,element.index,element.endIndex)
|
|
451
|
+
}
|
|
452
|
+
})
|
|
517
453
|
}
|
|
518
454
|
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
455
|
+
$(query,start=0,end=this.elements.length) {
|
|
456
|
+
return this.$$(query,start,end,true)
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
$$(query,start=0,end=this.elements.length,single=false) {
|
|
460
|
+
let result = []
|
|
461
|
+
this.selectors = new Query(query).selectors
|
|
462
|
+
this.query = query
|
|
463
|
+
this.selectors.forEach(selector => {
|
|
464
|
+
for(let i=start; i<end; i++) {
|
|
465
|
+
let el = this.elements[i]
|
|
466
|
+
if(this.checkElement(el,selector) && !result.includes(el)) result.push(el)
|
|
467
|
+
if(single && result.length == 1) break
|
|
468
|
+
}
|
|
469
|
+
});
|
|
470
|
+
if(single && result.length == 1) return result[0]
|
|
471
|
+
else if(single && result.length == 0) return null
|
|
472
|
+
else return result
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
checkElement(el,selector) {
|
|
476
|
+
if(selector == undefined) return true
|
|
477
|
+
if(el == null) return false
|
|
478
|
+
let {tag,classList,attribs,id,prev,ancestors,parents,prevAny} = selector
|
|
479
|
+
|
|
480
|
+
if(el.status == 'close' || el.type == 'text') return false
|
|
481
|
+
if(id !== undefined && el.id == undefined) return false
|
|
482
|
+
if(id && id !== el.id) return false
|
|
483
|
+
if(tag && el.tag == undefined) return false
|
|
484
|
+
else if(tag && tag !== el.tag) return false
|
|
485
|
+
if(classList !== undefined && el.classList == undefined) return false
|
|
486
|
+
else if(classList !== undefined && Array.isArray(el.classList)) {
|
|
487
|
+
if(classList.every(e => el.classList.includes(e)) == false) return false
|
|
522
488
|
}
|
|
523
|
-
return
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
if(
|
|
528
|
-
|
|
529
|
-
let content
|
|
530
|
-
if(element[part] !== undefined) content = element[part]
|
|
531
|
-
else if(element.attributes !== undefined)
|
|
532
|
-
if(element.attributes[part] !== undefined)
|
|
533
|
-
content = element.attributes[part]
|
|
534
|
-
|
|
535
|
-
if(content !== undefined) {
|
|
536
|
-
if(typeof content == 'string')
|
|
537
|
-
content = content.replace(/ /g,' ')
|
|
538
|
-
if(fn !== undefined) {
|
|
539
|
-
if(fn(content)) array.push(content)
|
|
540
|
-
} else array.push(content)
|
|
541
|
-
}
|
|
542
|
-
})
|
|
543
|
-
} else {
|
|
544
|
-
collection.forEach(element => {
|
|
545
|
-
array.push(Document.removeMethods(element))
|
|
546
|
-
});
|
|
489
|
+
if(this.checkAttribs(attribs,el) == false) return false
|
|
490
|
+
if(this.checkElement(el.prev,prev) == false) return false
|
|
491
|
+
if(this.checkAncestors(el.ancestors,ancestors) == false) return false
|
|
492
|
+
if(this.checkParents(el.ancestors,parents) == false) return false
|
|
493
|
+
if(el.parent) {
|
|
494
|
+
if(this.prevAny(el.parent.children,el.childIndex,prevAny) == false) return false
|
|
547
495
|
}
|
|
548
|
-
return
|
|
496
|
+
return true
|
|
549
497
|
}
|
|
550
498
|
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
element.children[i] = Document.removeMethods(child)
|
|
559
|
-
});
|
|
560
|
-
return element
|
|
499
|
+
prevAny(children=[],index,prevAny) {
|
|
500
|
+
let size = children.length
|
|
501
|
+
if((size == 0 || index == 0) && prevAny) return false
|
|
502
|
+
for(let i=index; i>=0; i--) {
|
|
503
|
+
if(this.checkElement(children[i],prevAny)) return true
|
|
504
|
+
}
|
|
505
|
+
return false
|
|
561
506
|
}
|
|
562
507
|
|
|
563
|
-
|
|
564
|
-
let
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
508
|
+
checkAncestors(ancestors=[],selectorAncestors=[]) {
|
|
509
|
+
let count = 0
|
|
510
|
+
if(selectorAncestors.length == 0) return true
|
|
511
|
+
let endIndex = ancestors.length-1
|
|
512
|
+
let selectorIndex = selectorAncestors.length-1
|
|
513
|
+
while(selectorIndex>=0) {
|
|
514
|
+
for(let i=endIndex; i>=0; i--) {
|
|
515
|
+
endIndex=i-1
|
|
516
|
+
if(this.checkElement(ancestors[i],selectorAncestors[selectorIndex]) == true) {
|
|
517
|
+
count++
|
|
518
|
+
break
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
selectorIndex--
|
|
522
|
+
}
|
|
523
|
+
if(count == selectorAncestors.length) return true
|
|
524
|
+
else return false
|
|
571
525
|
}
|
|
572
526
|
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
527
|
+
checkParents(ancestors=[],selectorParents=[]) {
|
|
528
|
+
if(selectorParents.length == 0) return true
|
|
529
|
+
if(ancestors.length < selectorParents.length) return false
|
|
530
|
+
let index = ancestors.length-1
|
|
531
|
+
for(let i=selectorParents.length-1; i>=0; i--) {
|
|
532
|
+
if(this.checkElement(ancestors[index],selectorParents[i]) == false) return false
|
|
533
|
+
index--
|
|
534
|
+
}
|
|
535
|
+
return true
|
|
577
536
|
}
|
|
578
537
|
|
|
579
|
-
|
|
580
|
-
let
|
|
581
|
-
|
|
582
|
-
|
|
538
|
+
checkAttribs(attribs=[],el) {
|
|
539
|
+
let elAttribs = el.attribs
|
|
540
|
+
let names = Object.keys(elAttribs)
|
|
541
|
+
let passedTests = 0
|
|
542
|
+
if(attribs) for(let i=0; i<attribs.length; i++) {
|
|
543
|
+
let {name,value,check} = attribs[i]
|
|
544
|
+
if(name == 'inner' && value !== undefined && check && el.innerText) {
|
|
545
|
+
if(check(el.innerText)) passedTests++
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
if(!names.includes(name)) continue
|
|
549
|
+
else if(value == undefined) passedTests++
|
|
550
|
+
else if(value && elAttribs[name]) {
|
|
551
|
+
if(check(elAttribs[name]) == false) continue
|
|
552
|
+
else passedTests++
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
if(passedTests == attribs.length) return true
|
|
556
|
+
else return false
|
|
583
557
|
}
|
|
584
558
|
}
|
|
585
|
-
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
|
|
562
|
+
try {module.exports = {HtmlSelector,Query,HtmlParser}} catch{}
|