als-document 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/document.js CHANGED
@@ -1,5 +1,5 @@
1
1
  const alsDocument = (function(){
2
- class Query{
3
2
  static get(query){
4
3
  let q=new Query(query)
5
4
  return q.selectors
6
5
  }
7
6
  constructor(query){
8
7
  this.query=query
9
8
  this.selectors=[]
10
9
  this.stringValues=[];
11
10
  this.parseSelectors(query.split(','))
12
11
  }
13
12
  parseSelectors(selectors){
14
13
  selectors.forEach(selector=>{
15
14
  let originalSelector=selector.trim()
16
15
  selector=this.removeSpaces(selector)
17
16
  this.stringValues=[]
18
17
  selector=selector.replace(/\[.*?\]/g,(value)=>{
19
18
  this.stringValues.push(value)
20
19
  return `[${this.stringValues.length-1}]`
21
20
  })
22
21
  let [element,ancestors]=this.splitAndCutLast(selector,' ')
23
22
  element=this.getFamily(element)
24
23
  if (ancestors.length>0)
25
24
  element.ancestors=ancestors.map(ancestor=>this.getFamily(ancestor))
26
25
  element.group=originalSelector
27
26
  this.selectors.push(element)
28
27
  });
29
28
  }
30
29
  splitAndCutLast(string,splitBy){
31
30
  const array=string.split(splitBy);
32
31
  const last=array.pop();
33
32
  return [last,array];
34
33
  }
35
34
  getFamily(group,element,prev,prevAny,sign){
36
35
  if (group.match(/\~|\+/)!==null){
37
36
  let [last,prevBrothers]=this.splitAndCutLast(group,/\~|\+/)
38
37
  let signs=group.replace(last,'')
39
38
  prevBrothers.forEach(el=>signs=signs.replace(el,''))
40
39
  signs=signs.match(/\~|\+/g)
41
40
  if (signs.length==1){
42
41
  sign=signs[0]
43
42
  } else if (signs.length>1){
44
43
  sign=signs.splice(signs.length-1,signs.length-1)[0]
45
44
  prevBrothers[0]=prevBrothers.map((b,i)=>{
46
45
  if (i< prevBrothers.length-1) b+=signs[i]
47
46
  return b
48
47
  }).join('')
49
48
  prevBrothers[0]=this.getFamily(prevBrothers[0])
50
49
  }
51
50
  if (sign=='~') prevAny=prevBrothers[0]
52
51
  else if (sign=='+') prev=prevBrothers[0]
53
52
  element=last
54
53
  } else element=group
55
54
  let family
56
55
  if (prev || prevAny){
57
56
  family=this.getParents(element)
58
57
  if (prev) family.prev=this.getParents(prev)
59
58
  if (prevAny) family.prevAny=this.getParents(prevAny)
60
59
  } else family=this.getParents(element)
61
60
  if (family.query!==group) family.group=group
62
61
  return family
63
62
  }
64
63
  getParents(selector){
65
64
  if (typeof selector=='string'){
66
65
  let [element,parents]=this.splitAndCutLast(selector,'>')
67
66
  element=this.buildElement(element)
68
67
  parents=parents.map(parent=>this.buildElement(parent))
69
68
  if (parents.length>0) element.parents=parents
70
69
  return element
71
70
  } else return selector
72
71
  }
73
72
  buildElement(element,id=null,tag=null,classList=[]){
74
73
  let query=element
75
74
  element=element.replace(/\#(\w-?)*/,$id=>{
76
75
  id=$id.replace(/^\#/,''); return ''
77
76
  })
78
77
  element=element.replace(/\.(\w-?)*/,$class=>{
79
78
  classList.push($class.replace(/^\./,'')); return ''
80
79
  })
81
80
  element=element.replace(/(\w\:?-?)*/,$tag=>{
82
81
  tag=$tag=='' ? null : $tag; return ''
83
82
  })
84
83
  let attribs=this.getAttributes(element)
85
84
  element={ query }
86
85
  if (id) element.id=id
87
86
  if (tag) element.tag=tag
88
87
  if (classList.length>0) element.classList=classList
89
88
  if (attribs.length>0) element.attribs=attribs
90
89
  return element
91
90
  }
92
91
  getAttributes(element){
93
92
  let attribs=this.stringValues.filter((value,index)=>{
94
93
  let searchValue=`[${index}]`
95
94
  if (element.match(searchValue)) return true
96
95
  else return false
97
96
  })
98
97
  attribs=attribs.map(attrib=>{
99
98
  let query=attrib
100
99
  attrib=attrib.replace('[','').replace(']','')
101
100
  let [name,...values]=attrib.split('=')
102
101
  const value=values.join('=').trim().replace(/^\"/,'').replace(/\"$/,'')
103
102
  let sign
104
103
  attrib={query,name}
105
104
  if(value){
106
105
  sign='='
107
106
  name=name.replace(/[\~\|\^\$\*]$/,(match=>{
108
107
  sign=match+sign
109
108
  return ''
110
109
  }))
111
110
  attrib.value=value
112
111
  }
113
112
  if (sign){
114
113
  attrib.sign=sign
115
114
  attrib.check=this.getAttribFn(sign).bind(attrib)
116
115
  }
117
116
  return attrib
118
117
  });
119
118
  return attribs
120
119
  }
121
120
  getAttribFn(sign){
122
121
  if (sign=='=') return function (value){ return value===this.value }
123
122
  if (sign=='*=') return function (value){ return value.includes(this.value) }
124
123
  if (sign=='^=') return function (value){ return value.startsWith(this.value) }
125
124
  if (sign=='$=') return function (value){ return value.endsWith(this.value) }
126
125
  if (sign=='|=') return function (value){
127
126
  return value.trim().split(' ').length==1
128
127
  && (value.startsWith(this.value) || value.startsWith(this.value+'-'))
129
128
  ? true : false
130
129
  }
131
130
  if (sign=='~=') return function (value){
132
131
  return this.value.trim().split(' ').length==1 && value.includes(this.value) ? true : false
133
132
  }
134
133
  }
135
134
  removeSpaces(selector){
136
135
  selector=selector.replace(/\s{2}/g,' ')
137
136
  selector=selector.replace(/\s?\^?\$?\|?\~?\*?\=\s*/g,(m)=>m.trim())
138
137
  selector=selector.replace(/\s?(\+|\~|\>)\s?/g,(m)=>m.trim())
139
138
  return selector
140
139
  }
140
+ class Query{
141
141
  static get(query){
142
142
  let q=new Query(query)
143
143
  return q.selectors
144
144
  }
145
145
  constructor(query){
146
146
  this.query=query
147
147
  this.selectors=[]
148
148
  this.stringValues=[];
149
149
  this.parseSelectors(query.split(','))
150
150
  }
151
151
  parseSelectors(selectors){
152
152
  selectors.forEach(selector=>{
153
153
  let originalSelector=selector.trim()
154
154
  selector=this.removeSpaces(selector)
155
155
  this.stringValues=[]
156
156
  selector=selector.replace(/\[.*?\]/g,(value)=>{
157
157
  this.stringValues.push(value)
158
158
  return `[${this.stringValues.length-1}]`
159
159
  })
160
160
  let [element,ancestors]=this.splitAndCutLast(selector,' ')
161
161
  element=this.getFamily(element)
162
162
  if (ancestors.length>0)
163
163
  element.ancestors=ancestors.map(ancestor=>this.getFamily(ancestor))
164
164
  element.group=originalSelector
165
165
  this.selectors.push(element)
166
166
  });
167
167
  }
168
168
  splitAndCutLast(string,splitBy){
169
169
  const array=string.split(splitBy);
170
170
  const last=array.pop();
171
171
  return [last,array];
172
172
  }
173
173
  getFamily(group,element,prev,prevAny,sign){
174
174
  if (group.match(/\~|\+/)!==null){
175
175
  let [last,prevBrothers]=this.splitAndCutLast(group,/\~|\+/)
176
176
  let signs=group.replace(last,'')
177
177
  prevBrothers.forEach(el=>signs=signs.replace(el,''))
178
178
  signs=signs.match(/\~|\+/g)
179
179
  if (signs.length==1){
180
180
  sign=signs[0]
181
181
  } else if (signs.length>1){
182
182
  sign=signs.splice(signs.length-1,signs.length-1)[0]
183
183
  prevBrothers[0]=prevBrothers.map((b,i)=>{
184
184
  if (i< prevBrothers.length-1) b+=signs[i]
185
185
  return b
186
186
  }).join('')
187
187
  prevBrothers[0]=this.getFamily(prevBrothers[0])
188
188
  }
189
189
  if (sign=='~') prevAny=prevBrothers[0]
190
190
  else if (sign=='+') prev=prevBrothers[0]
191
191
  element=last
192
192
  } else element=group
193
193
  let family
194
194
  if (prev || prevAny){
195
195
  family=this.getParents(element)
196
196
  if (prev) family.prev=this.getParents(prev)
197
197
  if (prevAny) family.prevAny=this.getParents(prevAny)
198
198
  } else family=this.getParents(element)
199
199
  if (family.query!==group) family.group=group
200
200
  return family
201
201
  }
202
202
  getParents(selector){
203
203
  if (typeof selector=='string'){
204
204
  let [element,parents]=this.splitAndCutLast(selector,'>')
205
205
  element=this.buildElement(element)
206
206
  parents=parents.map(parent=>this.buildElement(parent))
207
207
  if (parents.length>0) element.parents=parents
208
208
  return element
209
209
  } else return selector
210
210
  }
211
211
  buildElement(element,id=null,tag=null,classList=[]){
212
212
  let query=element
213
213
  element=element.replace(/\#(\w-?)*/,$id=>{
214
214
  id=$id.replace(/^\#/,''); return ''
215
215
  })
216
216
  element=element.replace(/\.(\w-?)*/,$class=>{
217
217
  classList.push($class.replace(/^\./,'')); return ''
218
218
  })
219
219
  element=element.replace(/(\w\:?-?)*/,$tag=>{
220
220
  tag=$tag=='' ? null : $tag; return ''
221
221
  })
222
222
  let attribs=this.getAttributes(element)
223
223
  element={ query }
224
224
  if (id) element.id=id
225
225
  if (tag) element.tag=tag
226
226
  if (classList.length>0) element.classList=classList
227
227
  if (attribs.length>0) element.attribs=attribs
228
228
  return element
229
229
  }
230
230
  getAttributes(element){
231
231
  let attribs=this.stringValues.filter((value,index)=>{
232
232
  let searchValue=`[${index}]`
233
233
  if (element.match(searchValue)) return true
234
234
  else return false
235
235
  })
236
236
  attribs=attribs.map(attrib=>{
237
237
  let query=attrib
238
238
  attrib=attrib.replace('[','').replace(']','')
239
239
  let [name,...values]=attrib.split('=')
240
240
  const value=values.join('=').trim().replace(/^\"/,'').replace(/\"$/,'')
241
241
  let sign
242
242
  attrib={query,name}
243
243
  if(value){
244
244
  sign='='
245
245
  attrib.name=attrib.name.replace(/[\~\|\^\$\*]$/,(match=>{
246
246
  sign=match+sign
247
247
  return ''
248
248
  }))
249
249
  attrib.value=value
250
250
  }
251
251
  if (sign){
252
252
  attrib.sign=sign
253
253
  attrib.check=this.getAttribFn(sign).bind(attrib)
254
254
  }
255
255
  return attrib
256
256
  });
257
257
  return attribs
258
258
  }
259
259
  getAttribFn(sign){
260
260
  if (sign=='=') return function (value){ return value===this.value }
261
261
  if (sign=='*=') return function (value){ return value.includes(this.value) }
262
262
  if (sign=='^=') return function (value){ return value.startsWith(this.value) }
263
263
  if (sign=='$=') return function (value){ return value.endsWith(this.value) }
264
264
  if (sign=='|=') return function (value){
265
265
  return value.trim().split(' ').length==1
266
266
  && (value.startsWith(this.value) || value.startsWith(this.value+'-'))
267
267
  ? true : false
268
268
  }
269
269
  if (sign=='~=') return function (value){
270
270
  return this.value.trim().split(' ').length==1 && value.includes(this.value) ? true : false
271
271
  }
272
272
  }
273
273
  removeSpaces(selector){
274
274
  selector=selector.replace(/\s{2}/g,' ')
275
275
  selector=selector.replace(/\s?\^?\$?\|?\~?\*?\=\s*/g,(m)=>m.trim())
276
276
  selector=selector.replace(/\s?(\+|\~|\>)\s?/g,(m)=>m.trim())
277
277
  return selector
278
278
  }
279
279
  }
280
280
  function checkElement(el,selector){
281
281
  if(selector==undefined) return true
282
282
  if(el==null) return false
283
283
  let{tag,classList,attribs:attributes,id,prev,ancestors,parents,prevAny}=selector
284
284
  if(typeof el==='string') return false
285
285
  if(id!==undefined && el.id===null) return false
286
286
  if(id && id!==el.id) return false
287
287
  if(tag && el.tagName===undefined) return false
288
288
  else if(tag && tag!==el.tagName) return false
289
289
  const clas=el.attributes.class
290
290
  if(classList!==undefined && (clas===undefined || clas==='')) return false
291
291
  else if(classList!==undefined){
292
292
  if(classList.every(e=>el.classList.contains(e))===false) return false
293
293
  }
294
294
  if(checkattributes(attributes,el)===false) return false
295
295
  if(checkElement(el.prev,prev)===false) return false
296
296
  if(checkAncestors(el.ancestors,ancestors)===false) return false
297
297
  if(checkParents(el.ancestors,parents)===false) return false
298
298
  if(el.parent){
299
299
  if(checkPrevAny(el.parent.children,el.childIndex,prevAny)==false) return false
300
300
  }
301
301
  return true
302
302
  }
303
303
  function checkattributes(attributes=[],el){
304
304
  let elattributes=el.attributes
305
305
  let names=Object.keys(elattributes)
306
306
  let passedTests=0
307
307
  if(attributes) for(let i=0; i<attributes.length; i++){
308
308
  let{name,value,check}=attributes[i]
309
309
  if(name=='inner' && value!==undefined && check && el.inner){
310
310
  if(check(el.inner)) passedTests++
311
311
  }
312
312
  if(!names.includes(name)) continue
313
313
  else if(value==undefined) passedTests++
314
314
  else if(value && elattributes[name]){
315
315
  if(check(elattributes[name])==false) continue
316
316
  else passedTests++
317
317
  }
318
318
  }
319
319
  if(passedTests==attributes.length) return true
320
320
  else return false
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- class Query{
2
1
  static get(query){
3
2
  let q=new Query(query)
4
3
  return q.selectors
5
4
  }
6
5
  constructor(query){
7
6
  this.query=query
8
7
  this.selectors=[]
9
8
  this.stringValues=[];
10
9
  this.parseSelectors(query.split(','))
11
10
  }
12
11
  parseSelectors(selectors){
13
12
  selectors.forEach(selector=>{
14
13
  let originalSelector=selector.trim()
15
14
  selector=this.removeSpaces(selector)
16
15
  this.stringValues=[]
17
16
  selector=selector.replace(/\[.*?\]/g,(value)=>{
18
17
  this.stringValues.push(value)
19
18
  return `[${this.stringValues.length-1}]`
20
19
  })
21
20
  let [element,ancestors]=this.splitAndCutLast(selector,' ')
22
21
  element=this.getFamily(element)
23
22
  if (ancestors.length>0)
24
23
  element.ancestors=ancestors.map(ancestor=>this.getFamily(ancestor))
25
24
  element.group=originalSelector
26
25
  this.selectors.push(element)
27
26
  });
28
27
  }
29
28
  splitAndCutLast(string,splitBy){
30
29
  const array=string.split(splitBy);
31
30
  const last=array.pop();
32
31
  return [last,array];
33
32
  }
34
33
  getFamily(group,element,prev,prevAny,sign){
35
34
  if (group.match(/\~|\+/)!==null){
36
35
  let [last,prevBrothers]=this.splitAndCutLast(group,/\~|\+/)
37
36
  let signs=group.replace(last,'')
38
37
  prevBrothers.forEach(el=>signs=signs.replace(el,''))
39
38
  signs=signs.match(/\~|\+/g)
40
39
  if (signs.length==1){
41
40
  sign=signs[0]
42
41
  } else if (signs.length>1){
43
42
  sign=signs.splice(signs.length-1,signs.length-1)[0]
44
43
  prevBrothers[0]=prevBrothers.map((b,i)=>{
45
44
  if (i< prevBrothers.length-1) b+=signs[i]
46
45
  return b
47
46
  }).join('')
48
47
  prevBrothers[0]=this.getFamily(prevBrothers[0])
49
48
  }
50
49
  if (sign=='~') prevAny=prevBrothers[0]
51
50
  else if (sign=='+') prev=prevBrothers[0]
52
51
  element=last
53
52
  } else element=group
54
53
  let family
55
54
  if (prev || prevAny){
56
55
  family=this.getParents(element)
57
56
  if (prev) family.prev=this.getParents(prev)
58
57
  if (prevAny) family.prevAny=this.getParents(prevAny)
59
58
  } else family=this.getParents(element)
60
59
  if (family.query!==group) family.group=group
61
60
  return family
62
61
  }
63
62
  getParents(selector){
64
63
  if (typeof selector=='string'){
65
64
  let [element,parents]=this.splitAndCutLast(selector,'>')
66
65
  element=this.buildElement(element)
67
66
  parents=parents.map(parent=>this.buildElement(parent))
68
67
  if (parents.length>0) element.parents=parents
69
68
  return element
70
69
  } else return selector
71
70
  }
72
71
  buildElement(element,id=null,tag=null,classList=[]){
73
72
  let query=element
74
73
  element=element.replace(/\#(\w-?)*/,$id=>{
75
74
  id=$id.replace(/^\#/,''); return ''
76
75
  })
77
76
  element=element.replace(/\.(\w-?)*/,$class=>{
78
77
  classList.push($class.replace(/^\./,'')); return ''
79
78
  })
80
79
  element=element.replace(/(\w\:?-?)*/,$tag=>{
81
80
  tag=$tag=='' ? null : $tag; return ''
82
81
  })
83
82
  let attribs=this.getAttributes(element)
84
83
  element={ query }
85
84
  if (id) element.id=id
86
85
  if (tag) element.tag=tag
87
86
  if (classList.length>0) element.classList=classList
88
87
  if (attribs.length>0) element.attribs=attribs
89
88
  return element
90
89
  }
91
90
  getAttributes(element){
92
91
  let attribs=this.stringValues.filter((value,index)=>{
93
92
  let searchValue=`[${index}]`
94
93
  if (element.match(searchValue)) return true
95
94
  else return false
96
95
  })
97
96
  attribs=attribs.map(attrib=>{
98
97
  let query=attrib
99
98
  attrib=attrib.replace('[','').replace(']','')
100
99
  let [name,...values]=attrib.split('=')
101
100
  const value=values.join('=').trim().replace(/^\"/,'').replace(/\"$/,'')
102
101
  let sign
103
102
  attrib={query,name}
104
103
  if(value){
105
104
  sign='='
106
105
  name=name.replace(/[\~\|\^\$\*]$/,(match=>{
107
106
  sign=match+sign
108
107
  return ''
109
108
  }))
110
109
  attrib.value=value
111
110
  }
112
111
  if (sign){
113
112
  attrib.sign=sign
114
113
  attrib.check=this.getAttribFn(sign).bind(attrib)
115
114
  }
116
115
  return attrib
117
116
  });
118
117
  return attribs
119
118
  }
120
119
  getAttribFn(sign){
121
120
  if (sign=='=') return function (value){ return value===this.value }
122
121
  if (sign=='*=') return function (value){ return value.includes(this.value) }
123
122
  if (sign=='^=') return function (value){ return value.startsWith(this.value) }
124
123
  if (sign=='$=') return function (value){ return value.endsWith(this.value) }
125
124
  if (sign=='|=') return function (value){
126
125
  return value.trim().split(' ').length==1
127
126
  && (value.startsWith(this.value) || value.startsWith(this.value+'-'))
128
127
  ? true : false
129
128
  }
130
129
  if (sign=='~=') return function (value){
131
130
  return this.value.trim().split(' ').length==1 && value.includes(this.value) ? true : false
132
131
  }
133
132
  }
134
133
  removeSpaces(selector){
135
134
  selector=selector.replace(/\s{2}/g,' ')
136
135
  selector=selector.replace(/\s?\^?\$?\|?\~?\*?\=\s*/g,(m)=>m.trim())
137
136
  selector=selector.replace(/\s?(\+|\~|\>)\s?/g,(m)=>m.trim())
138
137
  return selector
139
138
  }
139
+ class Query{
140
140
  static get(query){
141
141
  let q=new Query(query)
142
142
  return q.selectors
143
143
  }
144
144
  constructor(query){
145
145
  this.query=query
146
146
  this.selectors=[]
147
147
  this.stringValues=[];
148
148
  this.parseSelectors(query.split(','))
149
149
  }
150
150
  parseSelectors(selectors){
151
151
  selectors.forEach(selector=>{
152
152
  let originalSelector=selector.trim()
153
153
  selector=this.removeSpaces(selector)
154
154
  this.stringValues=[]
155
155
  selector=selector.replace(/\[.*?\]/g,(value)=>{
156
156
  this.stringValues.push(value)
157
157
  return `[${this.stringValues.length-1}]`
158
158
  })
159
159
  let [element,ancestors]=this.splitAndCutLast(selector,' ')
160
160
  element=this.getFamily(element)
161
161
  if (ancestors.length>0)
162
162
  element.ancestors=ancestors.map(ancestor=>this.getFamily(ancestor))
163
163
  element.group=originalSelector
164
164
  this.selectors.push(element)
165
165
  });
166
166
  }
167
167
  splitAndCutLast(string,splitBy){
168
168
  const array=string.split(splitBy);
169
169
  const last=array.pop();
170
170
  return [last,array];
171
171
  }
172
172
  getFamily(group,element,prev,prevAny,sign){
173
173
  if (group.match(/\~|\+/)!==null){
174
174
  let [last,prevBrothers]=this.splitAndCutLast(group,/\~|\+/)
175
175
  let signs=group.replace(last,'')
176
176
  prevBrothers.forEach(el=>signs=signs.replace(el,''))
177
177
  signs=signs.match(/\~|\+/g)
178
178
  if (signs.length==1){
179
179
  sign=signs[0]
180
180
  } else if (signs.length>1){
181
181
  sign=signs.splice(signs.length-1,signs.length-1)[0]
182
182
  prevBrothers[0]=prevBrothers.map((b,i)=>{
183
183
  if (i< prevBrothers.length-1) b+=signs[i]
184
184
  return b
185
185
  }).join('')
186
186
  prevBrothers[0]=this.getFamily(prevBrothers[0])
187
187
  }
188
188
  if (sign=='~') prevAny=prevBrothers[0]
189
189
  else if (sign=='+') prev=prevBrothers[0]
190
190
  element=last
191
191
  } else element=group
192
192
  let family
193
193
  if (prev || prevAny){
194
194
  family=this.getParents(element)
195
195
  if (prev) family.prev=this.getParents(prev)
196
196
  if (prevAny) family.prevAny=this.getParents(prevAny)
197
197
  } else family=this.getParents(element)
198
198
  if (family.query!==group) family.group=group
199
199
  return family
200
200
  }
201
201
  getParents(selector){
202
202
  if (typeof selector=='string'){
203
203
  let [element,parents]=this.splitAndCutLast(selector,'>')
204
204
  element=this.buildElement(element)
205
205
  parents=parents.map(parent=>this.buildElement(parent))
206
206
  if (parents.length>0) element.parents=parents
207
207
  return element
208
208
  } else return selector
209
209
  }
210
210
  buildElement(element,id=null,tag=null,classList=[]){
211
211
  let query=element
212
212
  element=element.replace(/\#(\w-?)*/,$id=>{
213
213
  id=$id.replace(/^\#/,''); return ''
214
214
  })
215
215
  element=element.replace(/\.(\w-?)*/,$class=>{
216
216
  classList.push($class.replace(/^\./,'')); return ''
217
217
  })
218
218
  element=element.replace(/(\w\:?-?)*/,$tag=>{
219
219
  tag=$tag=='' ? null : $tag; return ''
220
220
  })
221
221
  let attribs=this.getAttributes(element)
222
222
  element={ query }
223
223
  if (id) element.id=id
224
224
  if (tag) element.tag=tag
225
225
  if (classList.length>0) element.classList=classList
226
226
  if (attribs.length>0) element.attribs=attribs
227
227
  return element
228
228
  }
229
229
  getAttributes(element){
230
230
  let attribs=this.stringValues.filter((value,index)=>{
231
231
  let searchValue=`[${index}]`
232
232
  if (element.match(searchValue)) return true
233
233
  else return false
234
234
  })
235
235
  attribs=attribs.map(attrib=>{
236
236
  let query=attrib
237
237
  attrib=attrib.replace('[','').replace(']','')
238
238
  let [name,...values]=attrib.split('=')
239
239
  const value=values.join('=').trim().replace(/^\"/,'').replace(/\"$/,'')
240
240
  let sign
241
241
  attrib={query,name}
242
242
  if(value){
243
243
  sign='='
244
244
  attrib.name=attrib.name.replace(/[\~\|\^\$\*]$/,(match=>{
245
245
  sign=match+sign
246
246
  return ''
247
247
  }))
248
248
  attrib.value=value
249
249
  }
250
250
  if (sign){
251
251
  attrib.sign=sign
252
252
  attrib.check=this.getAttribFn(sign).bind(attrib)
253
253
  }
254
254
  return attrib
255
255
  });
256
256
  return attribs
257
257
  }
258
258
  getAttribFn(sign){
259
259
  if (sign=='=') return function (value){ return value===this.value }
260
260
  if (sign=='*=') return function (value){ return value.includes(this.value) }
261
261
  if (sign=='^=') return function (value){ return value.startsWith(this.value) }
262
262
  if (sign=='$=') return function (value){ return value.endsWith(this.value) }
263
263
  if (sign=='|=') return function (value){
264
264
  return value.trim().split(' ').length==1
265
265
  && (value.startsWith(this.value) || value.startsWith(this.value+'-'))
266
266
  ? true : false
267
267
  }
268
268
  if (sign=='~=') return function (value){
269
269
  return this.value.trim().split(' ').length==1 && value.includes(this.value) ? true : false
270
270
  }
271
271
  }
272
272
  removeSpaces(selector){
273
273
  selector=selector.replace(/\s{2}/g,' ')
274
274
  selector=selector.replace(/\s?\^?\$?\|?\~?\*?\=\s*/g,(m)=>m.trim())
275
275
  selector=selector.replace(/\s?(\+|\~|\>)\s?/g,(m)=>m.trim())
276
276
  return selector
277
277
  }
278
278
  }
279
279
  function checkElement(el,selector){
280
280
  if(selector==undefined) return true
281
281
  if(el==null) return false
282
282
  let{tag,classList,attribs:attributes,id,prev,ancestors,parents,prevAny}=selector
283
283
  if(typeof el==='string') return false
284
284
  if(id!==undefined && el.id===null) return false
285
285
  if(id && id!==el.id) return false
286
286
  if(tag && el.tagName===undefined) return false
287
287
  else if(tag && tag!==el.tagName) return false
288
288
  const clas=el.attributes.class
289
289
  if(classList!==undefined && (clas===undefined || clas==='')) return false
290
290
  else if(classList!==undefined){
291
291
  if(classList.every(e=>el.classList.contains(e))===false) return false
292
292
  }
293
293
  if(checkattributes(attributes,el)===false) return false
294
294
  if(checkElement(el.prev,prev)===false) return false
295
295
  if(checkAncestors(el.ancestors,ancestors)===false) return false
296
296
  if(checkParents(el.ancestors,parents)===false) return false
297
297
  if(el.parent){
298
298
  if(checkPrevAny(el.parent.children,el.childIndex,prevAny)==false) return false
299
299
  }
300
300
  return true
301
301
  }
302
302
  function checkattributes(attributes=[],el){
303
303
  let elattributes=el.attributes
304
304
  let names=Object.keys(elattributes)
305
305
  let passedTests=0
306
306
  if(attributes) for(let i=0; i<attributes.length; i++){
307
307
  let{name,value,check}=attributes[i]
308
308
  if(name=='inner' && value!==undefined && check && el.inner){
309
309
  if(check(el.inner)) passedTests++
310
310
  }
311
311
  if(!names.includes(name)) continue
312
312
  else if(value==undefined) passedTests++
313
313
  else if(value && elattributes[name]){
314
314
  if(check(elattributes[name])==false) continue
315
315
  else passedTests++
316
316
  }
317
317
  }
318
318
  if(passedTests==attributes.length) return true
319
319
  else return false
package/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- class Query{
2
1
  static get(query){
3
2
  let q=new Query(query)
4
3
  return q.selectors
5
4
  }
6
5
  constructor(query){
7
6
  this.query=query
8
7
  this.selectors=[]
9
8
  this.stringValues=[];
10
9
  this.parseSelectors(query.split(','))
11
10
  }
12
11
  parseSelectors(selectors){
13
12
  selectors.forEach(selector=>{
14
13
  let originalSelector=selector.trim()
15
14
  selector=this.removeSpaces(selector)
16
15
  this.stringValues=[]
17
16
  selector=selector.replace(/\[.*?\]/g,(value)=>{
18
17
  this.stringValues.push(value)
19
18
  return `[${this.stringValues.length-1}]`
20
19
  })
21
20
  let [element,ancestors]=this.splitAndCutLast(selector,' ')
22
21
  element=this.getFamily(element)
23
22
  if (ancestors.length>0)
24
23
  element.ancestors=ancestors.map(ancestor=>this.getFamily(ancestor))
25
24
  element.group=originalSelector
26
25
  this.selectors.push(element)
27
26
  });
28
27
  }
29
28
  splitAndCutLast(string,splitBy){
30
29
  const array=string.split(splitBy);
31
30
  const last=array.pop();
32
31
  return [last,array];
33
32
  }
34
33
  getFamily(group,element,prev,prevAny,sign){
35
34
  if (group.match(/\~|\+/)!==null){
36
35
  let [last,prevBrothers]=this.splitAndCutLast(group,/\~|\+/)
37
36
  let signs=group.replace(last,'')
38
37
  prevBrothers.forEach(el=>signs=signs.replace(el,''))
39
38
  signs=signs.match(/\~|\+/g)
40
39
  if (signs.length==1){
41
40
  sign=signs[0]
42
41
  } else if (signs.length>1){
43
42
  sign=signs.splice(signs.length-1,signs.length-1)[0]
44
43
  prevBrothers[0]=prevBrothers.map((b,i)=>{
45
44
  if (i< prevBrothers.length-1) b+=signs[i]
46
45
  return b
47
46
  }).join('')
48
47
  prevBrothers[0]=this.getFamily(prevBrothers[0])
49
48
  }
50
49
  if (sign=='~') prevAny=prevBrothers[0]
51
50
  else if (sign=='+') prev=prevBrothers[0]
52
51
  element=last
53
52
  } else element=group
54
53
  let family
55
54
  if (prev || prevAny){
56
55
  family=this.getParents(element)
57
56
  if (prev) family.prev=this.getParents(prev)
58
57
  if (prevAny) family.prevAny=this.getParents(prevAny)
59
58
  } else family=this.getParents(element)
60
59
  if (family.query!==group) family.group=group
61
60
  return family
62
61
  }
63
62
  getParents(selector){
64
63
  if (typeof selector=='string'){
65
64
  let [element,parents]=this.splitAndCutLast(selector,'>')
66
65
  element=this.buildElement(element)
67
66
  parents=parents.map(parent=>this.buildElement(parent))
68
67
  if (parents.length>0) element.parents=parents
69
68
  return element
70
69
  } else return selector
71
70
  }
72
71
  buildElement(element,id=null,tag=null,classList=[]){
73
72
  let query=element
74
73
  element=element.replace(/\#(\w-?)*/,$id=>{
75
74
  id=$id.replace(/^\#/,''); return ''
76
75
  })
77
76
  element=element.replace(/\.(\w-?)*/,$class=>{
78
77
  classList.push($class.replace(/^\./,'')); return ''
79
78
  })
80
79
  element=element.replace(/(\w\:?-?)*/,$tag=>{
81
80
  tag=$tag=='' ? null : $tag; return ''
82
81
  })
83
82
  let attribs=this.getAttributes(element)
84
83
  element={ query }
85
84
  if (id) element.id=id
86
85
  if (tag) element.tag=tag
87
86
  if (classList.length>0) element.classList=classList
88
87
  if (attribs.length>0) element.attribs=attribs
89
88
  return element
90
89
  }
91
90
  getAttributes(element){
92
91
  let attribs=this.stringValues.filter((value,index)=>{
93
92
  let searchValue=`[${index}]`
94
93
  if (element.match(searchValue)) return true
95
94
  else return false
96
95
  })
97
96
  attribs=attribs.map(attrib=>{
98
97
  let query=attrib
99
98
  attrib=attrib.replace('[','').replace(']','')
100
99
  let [name,...values]=attrib.split('=')
101
100
  const value=values.join('=').trim().replace(/^\"/,'').replace(/\"$/,'')
102
101
  let sign
103
102
  attrib={query,name}
104
103
  if(value){
105
104
  sign='='
106
105
  name=name.replace(/[\~\|\^\$\*]$/,(match=>{
107
106
  sign=match+sign
108
107
  return ''
109
108
  }))
110
109
  attrib.value=value
111
110
  }
112
111
  if (sign){
113
112
  attrib.sign=sign
114
113
  attrib.check=this.getAttribFn(sign).bind(attrib)
115
114
  }
116
115
  return attrib
117
116
  });
118
117
  return attribs
119
118
  }
120
119
  getAttribFn(sign){
121
120
  if (sign=='=') return function (value){ return value===this.value }
122
121
  if (sign=='*=') return function (value){ return value.includes(this.value) }
123
122
  if (sign=='^=') return function (value){ return value.startsWith(this.value) }
124
123
  if (sign=='$=') return function (value){ return value.endsWith(this.value) }
125
124
  if (sign=='|=') return function (value){
126
125
  return value.trim().split(' ').length==1
127
126
  && (value.startsWith(this.value) || value.startsWith(this.value+'-'))
128
127
  ? true : false
129
128
  }
130
129
  if (sign=='~=') return function (value){
131
130
  return this.value.trim().split(' ').length==1 && value.includes(this.value) ? true : false
132
131
  }
133
132
  }
134
133
  removeSpaces(selector){
135
134
  selector=selector.replace(/\s{2}/g,' ')
136
135
  selector=selector.replace(/\s?\^?\$?\|?\~?\*?\=\s*/g,(m)=>m.trim())
137
136
  selector=selector.replace(/\s?(\+|\~|\>)\s?/g,(m)=>m.trim())
138
137
  return selector
139
138
  }
139
+ class Query{
140
140
  static get(query){
141
141
  let q=new Query(query)
142
142
  return q.selectors
143
143
  }
144
144
  constructor(query){
145
145
  this.query=query
146
146
  this.selectors=[]
147
147
  this.stringValues=[];
148
148
  this.parseSelectors(query.split(','))
149
149
  }
150
150
  parseSelectors(selectors){
151
151
  selectors.forEach(selector=>{
152
152
  let originalSelector=selector.trim()
153
153
  selector=this.removeSpaces(selector)
154
154
  this.stringValues=[]
155
155
  selector=selector.replace(/\[.*?\]/g,(value)=>{
156
156
  this.stringValues.push(value)
157
157
  return `[${this.stringValues.length-1}]`
158
158
  })
159
159
  let [element,ancestors]=this.splitAndCutLast(selector,' ')
160
160
  element=this.getFamily(element)
161
161
  if (ancestors.length>0)
162
162
  element.ancestors=ancestors.map(ancestor=>this.getFamily(ancestor))
163
163
  element.group=originalSelector
164
164
  this.selectors.push(element)
165
165
  });
166
166
  }
167
167
  splitAndCutLast(string,splitBy){
168
168
  const array=string.split(splitBy);
169
169
  const last=array.pop();
170
170
  return [last,array];
171
171
  }
172
172
  getFamily(group,element,prev,prevAny,sign){
173
173
  if (group.match(/\~|\+/)!==null){
174
174
  let [last,prevBrothers]=this.splitAndCutLast(group,/\~|\+/)
175
175
  let signs=group.replace(last,'')
176
176
  prevBrothers.forEach(el=>signs=signs.replace(el,''))
177
177
  signs=signs.match(/\~|\+/g)
178
178
  if (signs.length==1){
179
179
  sign=signs[0]
180
180
  } else if (signs.length>1){
181
181
  sign=signs.splice(signs.length-1,signs.length-1)[0]
182
182
  prevBrothers[0]=prevBrothers.map((b,i)=>{
183
183
  if (i< prevBrothers.length-1) b+=signs[i]
184
184
  return b
185
185
  }).join('')
186
186
  prevBrothers[0]=this.getFamily(prevBrothers[0])
187
187
  }
188
188
  if (sign=='~') prevAny=prevBrothers[0]
189
189
  else if (sign=='+') prev=prevBrothers[0]
190
190
  element=last
191
191
  } else element=group
192
192
  let family
193
193
  if (prev || prevAny){
194
194
  family=this.getParents(element)
195
195
  if (prev) family.prev=this.getParents(prev)
196
196
  if (prevAny) family.prevAny=this.getParents(prevAny)
197
197
  } else family=this.getParents(element)
198
198
  if (family.query!==group) family.group=group
199
199
  return family
200
200
  }
201
201
  getParents(selector){
202
202
  if (typeof selector=='string'){
203
203
  let [element,parents]=this.splitAndCutLast(selector,'>')
204
204
  element=this.buildElement(element)
205
205
  parents=parents.map(parent=>this.buildElement(parent))
206
206
  if (parents.length>0) element.parents=parents
207
207
  return element
208
208
  } else return selector
209
209
  }
210
210
  buildElement(element,id=null,tag=null,classList=[]){
211
211
  let query=element
212
212
  element=element.replace(/\#(\w-?)*/,$id=>{
213
213
  id=$id.replace(/^\#/,''); return ''
214
214
  })
215
215
  element=element.replace(/\.(\w-?)*/,$class=>{
216
216
  classList.push($class.replace(/^\./,'')); return ''
217
217
  })
218
218
  element=element.replace(/(\w\:?-?)*/,$tag=>{
219
219
  tag=$tag=='' ? null : $tag; return ''
220
220
  })
221
221
  let attribs=this.getAttributes(element)
222
222
  element={ query }
223
223
  if (id) element.id=id
224
224
  if (tag) element.tag=tag
225
225
  if (classList.length>0) element.classList=classList
226
226
  if (attribs.length>0) element.attribs=attribs
227
227
  return element
228
228
  }
229
229
  getAttributes(element){
230
230
  let attribs=this.stringValues.filter((value,index)=>{
231
231
  let searchValue=`[${index}]`
232
232
  if (element.match(searchValue)) return true
233
233
  else return false
234
234
  })
235
235
  attribs=attribs.map(attrib=>{
236
236
  let query=attrib
237
237
  attrib=attrib.replace('[','').replace(']','')
238
238
  let [name,...values]=attrib.split('=')
239
239
  const value=values.join('=').trim().replace(/^\"/,'').replace(/\"$/,'')
240
240
  let sign
241
241
  attrib={query,name}
242
242
  if(value){
243
243
  sign='='
244
244
  attrib.name=attrib.name.replace(/[\~\|\^\$\*]$/,(match=>{
245
245
  sign=match+sign
246
246
  return ''
247
247
  }))
248
248
  attrib.value=value
249
249
  }
250
250
  if (sign){
251
251
  attrib.sign=sign
252
252
  attrib.check=this.getAttribFn(sign).bind(attrib)
253
253
  }
254
254
  return attrib
255
255
  });
256
256
  return attribs
257
257
  }
258
258
  getAttribFn(sign){
259
259
  if (sign=='=') return function (value){ return value===this.value }
260
260
  if (sign=='*=') return function (value){ return value.includes(this.value) }
261
261
  if (sign=='^=') return function (value){ return value.startsWith(this.value) }
262
262
  if (sign=='$=') return function (value){ return value.endsWith(this.value) }
263
263
  if (sign=='|=') return function (value){
264
264
  return value.trim().split(' ').length==1
265
265
  && (value.startsWith(this.value) || value.startsWith(this.value+'-'))
266
266
  ? true : false
267
267
  }
268
268
  if (sign=='~=') return function (value){
269
269
  return this.value.trim().split(' ').length==1 && value.includes(this.value) ? true : false
270
270
  }
271
271
  }
272
272
  removeSpaces(selector){
273
273
  selector=selector.replace(/\s{2}/g,' ')
274
274
  selector=selector.replace(/\s?\^?\$?\|?\~?\*?\=\s*/g,(m)=>m.trim())
275
275
  selector=selector.replace(/\s?(\+|\~|\>)\s?/g,(m)=>m.trim())
276
276
  return selector
277
277
  }
278
278
  }
279
279
  function checkElement(el,selector){
280
280
  if(selector==undefined) return true
281
281
  if(el==null) return false
282
282
  let{tag,classList,attribs:attributes,id,prev,ancestors,parents,prevAny}=selector
283
283
  if(typeof el==='string') return false
284
284
  if(id!==undefined && el.id===null) return false
285
285
  if(id && id!==el.id) return false
286
286
  if(tag && el.tagName===undefined) return false
287
287
  else if(tag && tag!==el.tagName) return false
288
288
  const clas=el.attributes.class
289
289
  if(classList!==undefined && (clas===undefined || clas==='')) return false
290
290
  else if(classList!==undefined){
291
291
  if(classList.every(e=>el.classList.contains(e))===false) return false
292
292
  }
293
293
  if(checkattributes(attributes,el)===false) return false
294
294
  if(checkElement(el.prev,prev)===false) return false
295
295
  if(checkAncestors(el.ancestors,ancestors)===false) return false
296
296
  if(checkParents(el.ancestors,parents)===false) return false
297
297
  if(el.parent){
298
298
  if(checkPrevAny(el.parent.children,el.childIndex,prevAny)==false) return false
299
299
  }
300
300
  return true
301
301
  }
302
302
  function checkattributes(attributes=[],el){
303
303
  let elattributes=el.attributes
304
304
  let names=Object.keys(elattributes)
305
305
  let passedTests=0
306
306
  if(attributes) for(let i=0; i<attributes.length; i++){
307
307
  let{name,value,check}=attributes[i]
308
308
  if(name=='inner' && value!==undefined && check && el.inner){
309
309
  if(check(el.inner)) passedTests++
310
310
  }
311
311
  if(!names.includes(name)) continue
312
312
  else if(value==undefined) passedTests++
313
313
  else if(value && elattributes[name]){
314
314
  if(check(elattributes[name])==false) continue
315
315
  else passedTests++
316
316
  }
317
317
  }
318
318
  if(passedTests==attributes.length) return true
319
319
  else return false
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "als-document",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "A powerful HTML parser & DOM manipulation library for both backend and frontend.",
5
5
  "main": "index.js",
6
6
  "module": "index.mjs",
@@ -110,7 +110,7 @@ class Query {
110
110
  attrib = {query,name}
111
111
  if(value) {
112
112
  sign = '='
113
- name = name.replace(/[\~\|\^\$\*]$/,(match => {
113
+ attrib.name = attrib.name.replace(/[\~\|\^\$\*]$/,(match => {
114
114
  sign = match+sign
115
115
  return ''
116
116
  }))