als-document 1.0.1-alpha → 1.0.2-alpha

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