als-document 1.0.1-beta → 1.0.1

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,value]=attrib.split(/[\~\|\^\$\*]?\=/)
102
101
  let sign=attrib.replace(name,'').replace(value,'')
103
102
  attrib={ query }
104
103
  if (name) attrib.name=name
105
104
  if (value) attrib.value=value.trim().replace(/^\"/,'').replace(/\"$/,'')
106
105
  if (sign){
107
106
  attrib.sign=sign
108
107
  attrib.check=this.getAttribFn(sign).bind(attrib)
109
108
  }
110
109
  return attrib
111
110
  });
112
111
  return attribs
113
112
  }
114
113
  getAttribFn(sign){
115
114
  if (sign=='=') return function (value){ return value===this.value }
116
115
  if (sign=='*=') return function (value){ return value.includes(this.value) }
117
116
  if (sign=='^=') return function (value){ return value.startsWith(this.value) }
118
117
  if (sign=='$=') return function (value){ return value.endsWith(this.value) }
119
118
  if (sign=='|=') return function (value){
120
119
  return value.trim().split(' ').length==1
121
120
  && (value.startsWith(this.value) || value.startsWith(this.value+'-'))
122
121
  ? true : false
123
122
  }
124
123
  if (sign=='~=') return function (value){
125
124
  return this.value.trim().split(' ').length==1 && value.includes(this.value) ? true : false
126
125
  }
127
126
  }
128
127
  removeSpaces(selector){
129
128
  selector=selector.replace(/\s{2}/g,' ')
130
129
  selector=selector.replace(/\s?\^?\$?\|?\~?\*?\=\s*/g,(m)=>m.trim())
131
130
  selector=selector.replace(/\s?(\+|\~|\>)\s?/g,(m)=>m.trim())
132
131
  return selector
133
132
  }
133
+ class Query{
134
134
  static get(query){
135
135
  let q=new Query(query)
136
136
  return q.selectors
137
137
  }
138
138
  constructor(query){
139
139
  this.query=query
140
140
  this.selectors=[]
141
141
  this.stringValues=[];
142
142
  this.parseSelectors(query.split(','))
143
143
  }
144
144
  parseSelectors(selectors){
145
145
  selectors.forEach(selector=>{
146
146
  let originalSelector=selector.trim()
147
147
  selector=this.removeSpaces(selector)
148
148
  this.stringValues=[]
149
149
  selector=selector.replace(/\[.*?\]/g,(value)=>{
150
150
  this.stringValues.push(value)
151
151
  return `[${this.stringValues.length-1}]`
152
152
  })
153
153
  let [element,ancestors]=this.splitAndCutLast(selector,' ')
154
154
  element=this.getFamily(element)
155
155
  if (ancestors.length>0)
156
156
  element.ancestors=ancestors.map(ancestor=>this.getFamily(ancestor))
157
157
  element.group=originalSelector
158
158
  this.selectors.push(element)
159
159
  });
160
160
  }
161
161
  splitAndCutLast(string,splitBy){
162
162
  const array=string.split(splitBy);
163
163
  const last=array.pop();
164
164
  return [last,array];
165
165
  }
166
166
  getFamily(group,element,prev,prevAny,sign){
167
167
  if (group.match(/\~|\+/)!==null){
168
168
  let [last,prevBrothers]=this.splitAndCutLast(group,/\~|\+/)
169
169
  let signs=group.replace(last,'')
170
170
  prevBrothers.forEach(el=>signs=signs.replace(el,''))
171
171
  signs=signs.match(/\~|\+/g)
172
172
  if (signs.length==1){
173
173
  sign=signs[0]
174
174
  } else if (signs.length>1){
175
175
  sign=signs.splice(signs.length-1,signs.length-1)[0]
176
176
  prevBrothers[0]=prevBrothers.map((b,i)=>{
177
177
  if (i< prevBrothers.length-1) b+=signs[i]
178
178
  return b
179
179
  }).join('')
180
180
  prevBrothers[0]=this.getFamily(prevBrothers[0])
181
181
  }
182
182
  if (sign=='~') prevAny=prevBrothers[0]
183
183
  else if (sign=='+') prev=prevBrothers[0]
184
184
  element=last
185
185
  } else element=group
186
186
  let family
187
187
  if (prev || prevAny){
188
188
  family=this.getParents(element)
189
189
  if (prev) family.prev=this.getParents(prev)
190
190
  if (prevAny) family.prevAny=this.getParents(prevAny)
191
191
  } else family=this.getParents(element)
192
192
  if (family.query!==group) family.group=group
193
193
  return family
194
194
  }
195
195
  getParents(selector){
196
196
  if (typeof selector=='string'){
197
197
  let [element,parents]=this.splitAndCutLast(selector,'>')
198
198
  element=this.buildElement(element)
199
199
  parents=parents.map(parent=>this.buildElement(parent))
200
200
  if (parents.length>0) element.parents=parents
201
201
  return element
202
202
  } else return selector
203
203
  }
204
204
  buildElement(element,id=null,tag=null,classList=[]){
205
205
  let query=element
206
206
  element=element.replace(/\#(\w-?)*/,$id=>{
207
207
  id=$id.replace(/^\#/,''); return ''
208
208
  })
209
209
  element=element.replace(/\.(\w-?)*/,$class=>{
210
210
  classList.push($class.replace(/^\./,'')); return ''
211
211
  })
212
212
  element=element.replace(/(\w\:?-?)*/,$tag=>{
213
213
  tag=$tag=='' ? null : $tag; return ''
214
214
  })
215
215
  let attribs=this.getAttributes(element)
216
216
  element={ query }
217
217
  if (id) element.id=id
218
218
  if (tag) element.tag=tag
219
219
  if (classList.length>0) element.classList=classList
220
220
  if (attribs.length>0) element.attribs=attribs
221
221
  return element
222
222
  }
223
223
  getAttributes(element){
224
224
  let attribs=this.stringValues.filter((value,index)=>{
225
225
  let searchValue=`[${index}]`
226
226
  if (element.match(searchValue)) return true
227
227
  else return false
228
228
  })
229
229
  attribs=attribs.map(attrib=>{
230
230
  let query=attrib
231
231
  attrib=attrib.replace('[','').replace(']','')
232
232
  let [name,...values]=attrib.split('=')
233
233
  const value=values.join('=').trim().replace(/^\"/,'').replace(/\"$/,'')
234
234
  let sign
235
235
  attrib={query,name}
236
236
  if(value){
237
237
  sign='='
238
238
  name=name.replace(/[\~\|\^\$\*]$/,(match=>{
239
239
  sign=match+sign
240
240
  return ''
241
241
  }))
242
242
  attrib.value=value
243
243
  }
244
244
  if (sign){
245
245
  attrib.sign=sign
246
246
  attrib.check=this.getAttribFn(sign).bind(attrib)
247
247
  }
248
248
  return attrib
249
249
  });
250
250
  return attribs
251
251
  }
252
252
  getAttribFn(sign){
253
253
  if (sign=='=') return function (value){ return value===this.value }
254
254
  if (sign=='*=') return function (value){ return value.includes(this.value) }
255
255
  if (sign=='^=') return function (value){ return value.startsWith(this.value) }
256
256
  if (sign=='$=') return function (value){ return value.endsWith(this.value) }
257
257
  if (sign=='|=') return function (value){
258
258
  return value.trim().split(' ').length==1
259
259
  && (value.startsWith(this.value) || value.startsWith(this.value+'-'))
260
260
  ? true : false
261
261
  }
262
262
  if (sign=='~=') return function (value){
263
263
  return this.value.trim().split(' ').length==1 && value.includes(this.value) ? true : false
264
264
  }
265
265
  }
266
266
  removeSpaces(selector){
267
267
  selector=selector.replace(/\s{2}/g,' ')
268
268
  selector=selector.replace(/\s?\^?\$?\|?\~?\*?\=\s*/g,(m)=>m.trim())
269
269
  selector=selector.replace(/\s?(\+|\~|\>)\s?/g,(m)=>m.trim())
270
270
  return selector
271
271
  }
272
272
  }
273
273
  function checkElement(el,selector){
274
274
  if(selector==undefined) return true
275
275
  if(el==null) return false
276
276
  let{tag,classList,attribs:attributes,id,prev,ancestors,parents,prevAny}=selector
277
277
  if(typeof el==='string') return false
278
278
  if(id!==undefined && el.id===null) return false
279
279
  if(id && id!==el.id) return false
280
280
  if(tag && el.tagName===undefined) return false
281
281
  else if(tag && tag!==el.tagName) return false
282
282
  const clas=el.attributes.class
283
283
  if(classList!==undefined && (clas===undefined || clas==='')) return false
284
284
  else if(classList!==undefined){
285
285
  if(classList.every(e=>el.classList.contains(e))===false) return false
286
286
  }
287
287
  if(checkattributes(attributes,el)===false) return false
288
288
  if(checkElement(el.prev,prev)===false) return false
289
289
  if(checkAncestors(el.ancestors,ancestors)===false) return false
290
290
  if(checkParents(el.ancestors,parents)===false) return false
291
291
  if(el.parent){
292
292
  if(checkPrevAny(el.parent.children,el.childIndex,prevAny)==false) return false
293
293
  }
294
294
  return true
295
295
  }
296
296
  function checkattributes(attributes=[],el){
297
297
  let elattributes=el.attributes
298
298
  let names=Object.keys(elattributes)
299
299
  let passedTests=0
300
300
  if(attributes) for(let i=0; i<attributes.length; i++){
301
301
  let{name,value,check}=attributes[i]
302
302
  if(name=='inner' && value!==undefined && check && el.inner){
303
303
  if(check(el.inner)) passedTests++
304
304
  }
305
305
  if(!names.includes(name)) continue
306
306
  else if(value==undefined) passedTests++
307
307
  else if(value && elattributes[name]){
308
308
  if(check(elattributes[name])==false) continue
309
309
  else passedTests++
310
310
  }
311
311
  }
312
312
  if(passedTests==attributes.length) return true
313
313
  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,value]=attrib.split(/[\~\|\^\$\*]?\=/)
101
100
  let sign=attrib.replace(name,'').replace(value,'')
102
101
  attrib={ query }
103
102
  if (name) attrib.name=name
104
103
  if (value) attrib.value=value.trim().replace(/^\"/,'').replace(/\"$/,'')
105
104
  if (sign){
106
105
  attrib.sign=sign
107
106
  attrib.check=this.getAttribFn(sign).bind(attrib)
108
107
  }
109
108
  return attrib
110
109
  });
111
110
  return attribs
112
111
  }
113
112
  getAttribFn(sign){
114
113
  if (sign=='=') return function (value){ return value===this.value }
115
114
  if (sign=='*=') return function (value){ return value.includes(this.value) }
116
115
  if (sign=='^=') return function (value){ return value.startsWith(this.value) }
117
116
  if (sign=='$=') return function (value){ return value.endsWith(this.value) }
118
117
  if (sign=='|=') return function (value){
119
118
  return value.trim().split(' ').length==1
120
119
  && (value.startsWith(this.value) || value.startsWith(this.value+'-'))
121
120
  ? true : false
122
121
  }
123
122
  if (sign=='~=') return function (value){
124
123
  return this.value.trim().split(' ').length==1 && value.includes(this.value) ? true : false
125
124
  }
126
125
  }
127
126
  removeSpaces(selector){
128
127
  selector=selector.replace(/\s{2}/g,' ')
129
128
  selector=selector.replace(/\s?\^?\$?\|?\~?\*?\=\s*/g,(m)=>m.trim())
130
129
  selector=selector.replace(/\s?(\+|\~|\>)\s?/g,(m)=>m.trim())
131
130
  return selector
132
131
  }
132
+ class Query{
133
133
  static get(query){
134
134
  let q=new Query(query)
135
135
  return q.selectors
136
136
  }
137
137
  constructor(query){
138
138
  this.query=query
139
139
  this.selectors=[]
140
140
  this.stringValues=[];
141
141
  this.parseSelectors(query.split(','))
142
142
  }
143
143
  parseSelectors(selectors){
144
144
  selectors.forEach(selector=>{
145
145
  let originalSelector=selector.trim()
146
146
  selector=this.removeSpaces(selector)
147
147
  this.stringValues=[]
148
148
  selector=selector.replace(/\[.*?\]/g,(value)=>{
149
149
  this.stringValues.push(value)
150
150
  return `[${this.stringValues.length-1}]`
151
151
  })
152
152
  let [element,ancestors]=this.splitAndCutLast(selector,' ')
153
153
  element=this.getFamily(element)
154
154
  if (ancestors.length>0)
155
155
  element.ancestors=ancestors.map(ancestor=>this.getFamily(ancestor))
156
156
  element.group=originalSelector
157
157
  this.selectors.push(element)
158
158
  });
159
159
  }
160
160
  splitAndCutLast(string,splitBy){
161
161
  const array=string.split(splitBy);
162
162
  const last=array.pop();
163
163
  return [last,array];
164
164
  }
165
165
  getFamily(group,element,prev,prevAny,sign){
166
166
  if (group.match(/\~|\+/)!==null){
167
167
  let [last,prevBrothers]=this.splitAndCutLast(group,/\~|\+/)
168
168
  let signs=group.replace(last,'')
169
169
  prevBrothers.forEach(el=>signs=signs.replace(el,''))
170
170
  signs=signs.match(/\~|\+/g)
171
171
  if (signs.length==1){
172
172
  sign=signs[0]
173
173
  } else if (signs.length>1){
174
174
  sign=signs.splice(signs.length-1,signs.length-1)[0]
175
175
  prevBrothers[0]=prevBrothers.map((b,i)=>{
176
176
  if (i< prevBrothers.length-1) b+=signs[i]
177
177
  return b
178
178
  }).join('')
179
179
  prevBrothers[0]=this.getFamily(prevBrothers[0])
180
180
  }
181
181
  if (sign=='~') prevAny=prevBrothers[0]
182
182
  else if (sign=='+') prev=prevBrothers[0]
183
183
  element=last
184
184
  } else element=group
185
185
  let family
186
186
  if (prev || prevAny){
187
187
  family=this.getParents(element)
188
188
  if (prev) family.prev=this.getParents(prev)
189
189
  if (prevAny) family.prevAny=this.getParents(prevAny)
190
190
  } else family=this.getParents(element)
191
191
  if (family.query!==group) family.group=group
192
192
  return family
193
193
  }
194
194
  getParents(selector){
195
195
  if (typeof selector=='string'){
196
196
  let [element,parents]=this.splitAndCutLast(selector,'>')
197
197
  element=this.buildElement(element)
198
198
  parents=parents.map(parent=>this.buildElement(parent))
199
199
  if (parents.length>0) element.parents=parents
200
200
  return element
201
201
  } else return selector
202
202
  }
203
203
  buildElement(element,id=null,tag=null,classList=[]){
204
204
  let query=element
205
205
  element=element.replace(/\#(\w-?)*/,$id=>{
206
206
  id=$id.replace(/^\#/,''); return ''
207
207
  })
208
208
  element=element.replace(/\.(\w-?)*/,$class=>{
209
209
  classList.push($class.replace(/^\./,'')); return ''
210
210
  })
211
211
  element=element.replace(/(\w\:?-?)*/,$tag=>{
212
212
  tag=$tag=='' ? null : $tag; return ''
213
213
  })
214
214
  let attribs=this.getAttributes(element)
215
215
  element={ query }
216
216
  if (id) element.id=id
217
217
  if (tag) element.tag=tag
218
218
  if (classList.length>0) element.classList=classList
219
219
  if (attribs.length>0) element.attribs=attribs
220
220
  return element
221
221
  }
222
222
  getAttributes(element){
223
223
  let attribs=this.stringValues.filter((value,index)=>{
224
224
  let searchValue=`[${index}]`
225
225
  if (element.match(searchValue)) return true
226
226
  else return false
227
227
  })
228
228
  attribs=attribs.map(attrib=>{
229
229
  let query=attrib
230
230
  attrib=attrib.replace('[','').replace(']','')
231
231
  let [name,...values]=attrib.split('=')
232
232
  const value=values.join('=').trim().replace(/^\"/,'').replace(/\"$/,'')
233
233
  let sign
234
234
  attrib={query,name}
235
235
  if(value){
236
236
  sign='='
237
237
  name=name.replace(/[\~\|\^\$\*]$/,(match=>{
238
238
  sign=match+sign
239
239
  return ''
240
240
  }))
241
241
  attrib.value=value
242
242
  }
243
243
  if (sign){
244
244
  attrib.sign=sign
245
245
  attrib.check=this.getAttribFn(sign).bind(attrib)
246
246
  }
247
247
  return attrib
248
248
  });
249
249
  return attribs
250
250
  }
251
251
  getAttribFn(sign){
252
252
  if (sign=='=') return function (value){ return value===this.value }
253
253
  if (sign=='*=') return function (value){ return value.includes(this.value) }
254
254
  if (sign=='^=') return function (value){ return value.startsWith(this.value) }
255
255
  if (sign=='$=') return function (value){ return value.endsWith(this.value) }
256
256
  if (sign=='|=') return function (value){
257
257
  return value.trim().split(' ').length==1
258
258
  && (value.startsWith(this.value) || value.startsWith(this.value+'-'))
259
259
  ? true : false
260
260
  }
261
261
  if (sign=='~=') return function (value){
262
262
  return this.value.trim().split(' ').length==1 && value.includes(this.value) ? true : false
263
263
  }
264
264
  }
265
265
  removeSpaces(selector){
266
266
  selector=selector.replace(/\s{2}/g,' ')
267
267
  selector=selector.replace(/\s?\^?\$?\|?\~?\*?\=\s*/g,(m)=>m.trim())
268
268
  selector=selector.replace(/\s?(\+|\~|\>)\s?/g,(m)=>m.trim())
269
269
  return selector
270
270
  }
271
271
  }
272
272
  function checkElement(el,selector){
273
273
  if(selector==undefined) return true
274
274
  if(el==null) return false
275
275
  let{tag,classList,attribs:attributes,id,prev,ancestors,parents,prevAny}=selector
276
276
  if(typeof el==='string') return false
277
277
  if(id!==undefined && el.id===null) return false
278
278
  if(id && id!==el.id) return false
279
279
  if(tag && el.tagName===undefined) return false
280
280
  else if(tag && tag!==el.tagName) return false
281
281
  const clas=el.attributes.class
282
282
  if(classList!==undefined && (clas===undefined || clas==='')) return false
283
283
  else if(classList!==undefined){
284
284
  if(classList.every(e=>el.classList.contains(e))===false) return false
285
285
  }
286
286
  if(checkattributes(attributes,el)===false) return false
287
287
  if(checkElement(el.prev,prev)===false) return false
288
288
  if(checkAncestors(el.ancestors,ancestors)===false) return false
289
289
  if(checkParents(el.ancestors,parents)===false) return false
290
290
  if(el.parent){
291
291
  if(checkPrevAny(el.parent.children,el.childIndex,prevAny)==false) return false
292
292
  }
293
293
  return true
294
294
  }
295
295
  function checkattributes(attributes=[],el){
296
296
  let elattributes=el.attributes
297
297
  let names=Object.keys(elattributes)
298
298
  let passedTests=0
299
299
  if(attributes) for(let i=0; i<attributes.length; i++){
300
300
  let{name,value,check}=attributes[i]
301
301
  if(name=='inner' && value!==undefined && check && el.inner){
302
302
  if(check(el.inner)) passedTests++
303
303
  }
304
304
  if(!names.includes(name)) continue
305
305
  else if(value==undefined) passedTests++
306
306
  else if(value && elattributes[name]){
307
307
  if(check(elattributes[name])==false) continue
308
308
  else passedTests++
309
309
  }
310
310
  }
311
311
  if(passedTests==attributes.length) return true
312
312
  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,value]=attrib.split(/[\~\|\^\$\*]?\=/)
101
100
  let sign=attrib.replace(name,'').replace(value,'')
102
101
  attrib={ query }
103
102
  if (name) attrib.name=name
104
103
  if (value) attrib.value=value.trim().replace(/^\"/,'').replace(/\"$/,'')
105
104
  if (sign){
106
105
  attrib.sign=sign
107
106
  attrib.check=this.getAttribFn(sign).bind(attrib)
108
107
  }
109
108
  return attrib
110
109
  });
111
110
  return attribs
112
111
  }
113
112
  getAttribFn(sign){
114
113
  if (sign=='=') return function (value){ return value===this.value }
115
114
  if (sign=='*=') return function (value){ return value.includes(this.value) }
116
115
  if (sign=='^=') return function (value){ return value.startsWith(this.value) }
117
116
  if (sign=='$=') return function (value){ return value.endsWith(this.value) }
118
117
  if (sign=='|=') return function (value){
119
118
  return value.trim().split(' ').length==1
120
119
  && (value.startsWith(this.value) || value.startsWith(this.value+'-'))
121
120
  ? true : false
122
121
  }
123
122
  if (sign=='~=') return function (value){
124
123
  return this.value.trim().split(' ').length==1 && value.includes(this.value) ? true : false
125
124
  }
126
125
  }
127
126
  removeSpaces(selector){
128
127
  selector=selector.replace(/\s{2}/g,' ')
129
128
  selector=selector.replace(/\s?\^?\$?\|?\~?\*?\=\s*/g,(m)=>m.trim())
130
129
  selector=selector.replace(/\s?(\+|\~|\>)\s?/g,(m)=>m.trim())
131
130
  return selector
132
131
  }
132
+ class Query{
133
133
  static get(query){
134
134
  let q=new Query(query)
135
135
  return q.selectors
136
136
  }
137
137
  constructor(query){
138
138
  this.query=query
139
139
  this.selectors=[]
140
140
  this.stringValues=[];
141
141
  this.parseSelectors(query.split(','))
142
142
  }
143
143
  parseSelectors(selectors){
144
144
  selectors.forEach(selector=>{
145
145
  let originalSelector=selector.trim()
146
146
  selector=this.removeSpaces(selector)
147
147
  this.stringValues=[]
148
148
  selector=selector.replace(/\[.*?\]/g,(value)=>{
149
149
  this.stringValues.push(value)
150
150
  return `[${this.stringValues.length-1}]`
151
151
  })
152
152
  let [element,ancestors]=this.splitAndCutLast(selector,' ')
153
153
  element=this.getFamily(element)
154
154
  if (ancestors.length>0)
155
155
  element.ancestors=ancestors.map(ancestor=>this.getFamily(ancestor))
156
156
  element.group=originalSelector
157
157
  this.selectors.push(element)
158
158
  });
159
159
  }
160
160
  splitAndCutLast(string,splitBy){
161
161
  const array=string.split(splitBy);
162
162
  const last=array.pop();
163
163
  return [last,array];
164
164
  }
165
165
  getFamily(group,element,prev,prevAny,sign){
166
166
  if (group.match(/\~|\+/)!==null){
167
167
  let [last,prevBrothers]=this.splitAndCutLast(group,/\~|\+/)
168
168
  let signs=group.replace(last,'')
169
169
  prevBrothers.forEach(el=>signs=signs.replace(el,''))
170
170
  signs=signs.match(/\~|\+/g)
171
171
  if (signs.length==1){
172
172
  sign=signs[0]
173
173
  } else if (signs.length>1){
174
174
  sign=signs.splice(signs.length-1,signs.length-1)[0]
175
175
  prevBrothers[0]=prevBrothers.map((b,i)=>{
176
176
  if (i< prevBrothers.length-1) b+=signs[i]
177
177
  return b
178
178
  }).join('')
179
179
  prevBrothers[0]=this.getFamily(prevBrothers[0])
180
180
  }
181
181
  if (sign=='~') prevAny=prevBrothers[0]
182
182
  else if (sign=='+') prev=prevBrothers[0]
183
183
  element=last
184
184
  } else element=group
185
185
  let family
186
186
  if (prev || prevAny){
187
187
  family=this.getParents(element)
188
188
  if (prev) family.prev=this.getParents(prev)
189
189
  if (prevAny) family.prevAny=this.getParents(prevAny)
190
190
  } else family=this.getParents(element)
191
191
  if (family.query!==group) family.group=group
192
192
  return family
193
193
  }
194
194
  getParents(selector){
195
195
  if (typeof selector=='string'){
196
196
  let [element,parents]=this.splitAndCutLast(selector,'>')
197
197
  element=this.buildElement(element)
198
198
  parents=parents.map(parent=>this.buildElement(parent))
199
199
  if (parents.length>0) element.parents=parents
200
200
  return element
201
201
  } else return selector
202
202
  }
203
203
  buildElement(element,id=null,tag=null,classList=[]){
204
204
  let query=element
205
205
  element=element.replace(/\#(\w-?)*/,$id=>{
206
206
  id=$id.replace(/^\#/,''); return ''
207
207
  })
208
208
  element=element.replace(/\.(\w-?)*/,$class=>{
209
209
  classList.push($class.replace(/^\./,'')); return ''
210
210
  })
211
211
  element=element.replace(/(\w\:?-?)*/,$tag=>{
212
212
  tag=$tag=='' ? null : $tag; return ''
213
213
  })
214
214
  let attribs=this.getAttributes(element)
215
215
  element={ query }
216
216
  if (id) element.id=id
217
217
  if (tag) element.tag=tag
218
218
  if (classList.length>0) element.classList=classList
219
219
  if (attribs.length>0) element.attribs=attribs
220
220
  return element
221
221
  }
222
222
  getAttributes(element){
223
223
  let attribs=this.stringValues.filter((value,index)=>{
224
224
  let searchValue=`[${index}]`
225
225
  if (element.match(searchValue)) return true
226
226
  else return false
227
227
  })
228
228
  attribs=attribs.map(attrib=>{
229
229
  let query=attrib
230
230
  attrib=attrib.replace('[','').replace(']','')
231
231
  let [name,...values]=attrib.split('=')
232
232
  const value=values.join('=').trim().replace(/^\"/,'').replace(/\"$/,'')
233
233
  let sign
234
234
  attrib={query,name}
235
235
  if(value){
236
236
  sign='='
237
237
  name=name.replace(/[\~\|\^\$\*]$/,(match=>{
238
238
  sign=match+sign
239
239
  return ''
240
240
  }))
241
241
  attrib.value=value
242
242
  }
243
243
  if (sign){
244
244
  attrib.sign=sign
245
245
  attrib.check=this.getAttribFn(sign).bind(attrib)
246
246
  }
247
247
  return attrib
248
248
  });
249
249
  return attribs
250
250
  }
251
251
  getAttribFn(sign){
252
252
  if (sign=='=') return function (value){ return value===this.value }
253
253
  if (sign=='*=') return function (value){ return value.includes(this.value) }
254
254
  if (sign=='^=') return function (value){ return value.startsWith(this.value) }
255
255
  if (sign=='$=') return function (value){ return value.endsWith(this.value) }
256
256
  if (sign=='|=') return function (value){
257
257
  return value.trim().split(' ').length==1
258
258
  && (value.startsWith(this.value) || value.startsWith(this.value+'-'))
259
259
  ? true : false
260
260
  }
261
261
  if (sign=='~=') return function (value){
262
262
  return this.value.trim().split(' ').length==1 && value.includes(this.value) ? true : false
263
263
  }
264
264
  }
265
265
  removeSpaces(selector){
266
266
  selector=selector.replace(/\s{2}/g,' ')
267
267
  selector=selector.replace(/\s?\^?\$?\|?\~?\*?\=\s*/g,(m)=>m.trim())
268
268
  selector=selector.replace(/\s?(\+|\~|\>)\s?/g,(m)=>m.trim())
269
269
  return selector
270
270
  }
271
271
  }
272
272
  function checkElement(el,selector){
273
273
  if(selector==undefined) return true
274
274
  if(el==null) return false
275
275
  let{tag,classList,attribs:attributes,id,prev,ancestors,parents,prevAny}=selector
276
276
  if(typeof el==='string') return false
277
277
  if(id!==undefined && el.id===null) return false
278
278
  if(id && id!==el.id) return false
279
279
  if(tag && el.tagName===undefined) return false
280
280
  else if(tag && tag!==el.tagName) return false
281
281
  const clas=el.attributes.class
282
282
  if(classList!==undefined && (clas===undefined || clas==='')) return false
283
283
  else if(classList!==undefined){
284
284
  if(classList.every(e=>el.classList.contains(e))===false) return false
285
285
  }
286
286
  if(checkattributes(attributes,el)===false) return false
287
287
  if(checkElement(el.prev,prev)===false) return false
288
288
  if(checkAncestors(el.ancestors,ancestors)===false) return false
289
289
  if(checkParents(el.ancestors,parents)===false) return false
290
290
  if(el.parent){
291
291
  if(checkPrevAny(el.parent.children,el.childIndex,prevAny)==false) return false
292
292
  }
293
293
  return true
294
294
  }
295
295
  function checkattributes(attributes=[],el){
296
296
  let elattributes=el.attributes
297
297
  let names=Object.keys(elattributes)
298
298
  let passedTests=0
299
299
  if(attributes) for(let i=0; i<attributes.length; i++){
300
300
  let{name,value,check}=attributes[i]
301
301
  if(name=='inner' && value!==undefined && check && el.inner){
302
302
  if(check(el.inner)) passedTests++
303
303
  }
304
304
  if(!names.includes(name)) continue
305
305
  else if(value==undefined) passedTests++
306
306
  else if(value && elattributes[name]){
307
307
  if(check(elattributes[name])==false) continue
308
308
  else passedTests++
309
309
  }
310
310
  }
311
311
  if(passedTests==attributes.length) return true
312
312
  else return false
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "als-document",
3
- "version": "1.0.1-beta",
3
+ "version": "1.0.1",
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",
@@ -31,7 +31,7 @@ class Query {
31
31
 
32
32
  splitAndCutLast(string, splitBy) {
33
33
  const array = string.split(splitBy);
34
- const last = array.pop(); // pop() удаляет и возвращает последний элемент массива
34
+ const last = array.pop();
35
35
  return [last, array];
36
36
  }
37
37
 
@@ -104,11 +104,18 @@ class Query {
104
104
  attribs = attribs.map(attrib => {
105
105
  let query = attrib
106
106
  attrib = attrib.replace('[', '').replace(']', '')
107
- let [name, value] = attrib.split(/[\~\|\^\$\*]?\=/)
108
- let sign = attrib.replace(name, '').replace(value, '')
109
- attrib = { query }
110
- if (name) attrib.name = name
111
- if (value) attrib.value = value.trim().replace(/^\"/, '').replace(/\"$/, '')
107
+ let [name,...values] = attrib.split('=')
108
+ const value = values.join('=').trim().replace(/^\"/,'').replace(/\"$/,'')
109
+ let sign
110
+ attrib = {query,name}
111
+ if(value) {
112
+ sign = '='
113
+ name = name.replace(/[\~\|\^\$\*]$/,(match => {
114
+ sign = match+sign
115
+ return ''
116
+ }))
117
+ attrib.value = value
118
+ }
112
119
  if (sign) {
113
120
  attrib.sign = sign
114
121
  attrib.check = this.getAttribFn(sign).bind(attrib)
package/tests/index.html CHANGED
@@ -10,7 +10,7 @@
10
10
  <!-- <script src="./data/html2.js"></script> -->
11
11
  <script src="./data/svg.js"></script>
12
12
  <script>
13
- const { parseHTML, Node, Query, TextNode, SingleNode, buildFromCache, cacheDoc } = alsDocument
13
+ const { parseHTML, Node, Query, TextNode, SingleNode, buildFromCache, cacheDoc,Root } = alsDocument
14
14
  let {describe,it,beforeEach,runTests,expect,delay,assert,beforeAll} = SimpleTest
15
15
  SimpleTest.showFullError = true
16
16
  </script>