als-document 0.12.0 → 1.0.0-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 ADDED
@@ -0,0 +1,32 @@
1
+ class Query{
2
  static get(query){
1
3
  let q=new Query(query)
2
4
  return q.selectors
3
5
  }
4
6
  constructor(query){
5
7
  this.query=query
6
8
  this.selectors=[]
7
9
  this.stringValues=[];
8
10
  this.parseSelectors(query.split(','))
9
11
  }
10
12
  parseSelectors(selectors){
11
13
  selectors.forEach(selector=>{
12
14
  let originalSelector=selector.trim()
13
15
  selector=this.removeSpaces(selector)
14
16
  this.stringValues=[]
15
17
  selector=selector.replace(/\[.*?\]/g,(value)=>{
16
18
  this.stringValues.push(value)
17
19
  return `[${this.stringValues.length-1}]`
18
20
  })
19
21
  let [element,ancestors]=this.splitAndCutLast(selector,' ')
20
22
  element=this.getFamily(element)
21
23
  if (ancestors.length>0)
22
24
  element.ancestors=ancestors.map(ancestor=>this.getFamily(ancestor))
23
25
  element.group=originalSelector
24
26
  this.selectors.push(element)
25
27
  });
26
28
  }
27
29
  splitAndCutLast(string,splitBy){
28
30
  const array=string.split(splitBy);
29
31
  const last=array.pop();
30
32
  return [last,array];
31
33
  }
32
34
  getFamily(group,element,prev,prevAny,sign){
33
35
  if (group.match(/\~|\+/)!==null){
34
36
  let [last,prevBrothers]=this.splitAndCutLast(group,/\~|\+/)
35
37
  let signs=group.replace(last,'')
36
38
  prevBrothers.forEach(el=>signs=signs.replace(el,''))
37
39
  signs=signs.match(/\~|\+/g)
38
40
  if (signs.length==1){
39
41
  sign=signs[0]
40
42
  } else if (signs.length>1){
41
43
  sign=signs.splice(signs.length-1,signs.length-1)[0]
42
44
  prevBrothers[0]=prevBrothers.map((b,i)=>{
43
45
  if (i< prevBrothers.length-1) b+=signs[i]
44
46
  return b
45
47
  }).join('')
46
48
  prevBrothers[0]=this.getFamily(prevBrothers[0])
47
49
  }
48
50
  if (sign=='~') prevAny=prevBrothers[0]
49
51
  else if (sign=='+') prev=prevBrothers[0]
50
52
  element=last
51
53
  } else element=group
52
54
  let family
53
55
  if (prev || prevAny){
54
56
  family=this.getParents(element)
55
57
  if (prev) family.prev=this.getParents(prev)
56
58
  if (prevAny) family.prevAny=this.getParents(prevAny)
57
59
  } else family=this.getParents(element)
58
60
  if (family.query!==group) family.group=group
59
61
  return family
60
62
  }
61
63
  getParents(selector){
62
64
  if (typeof selector=='string'){
63
65
  let [element,parents]=this.splitAndCutLast(selector,'>')
64
66
  element=this.buildElement(element)
65
67
  parents=parents.map(parent=>this.buildElement(parent))
66
68
  if (parents.length>0) element.parents=parents
67
69
  return element
68
70
  } else return selector
69
71
  }
70
72
  buildElement(element,id=null,tag=null,classList=[]){
71
73
  let query=element
72
74
  element=element.replace(/\#(\w-?)*/,$id=>{
73
75
  id=$id.replace(/^\#/,''); return ''
74
76
  })
75
77
  element=element.replace(/\.(\w-?)*/,$class=>{
76
78
  classList.push($class.replace(/^\./,'')); return ''
77
79
  })
78
80
  element=element.replace(/(\w\:?-?)*/,$tag=>{
79
81
  tag=$tag=='' ? null : $tag; return ''
80
82
  })
81
83
  let attribs=this.getAttributes(element)
82
84
  element={ query }
83
85
  if (id) element.id=id
84
86
  if (tag) element.tag=tag
85
87
  if (classList.length>0) element.classList=classList
86
88
  if (attribs.length>0) element.attribs=attribs
87
89
  return element
88
90
  }
89
91
  getAttributes(element){
90
92
  let attribs=this.stringValues.filter((value,index)=>{
91
93
  let searchValue=`[${index}]`
92
94
  if (element.match(searchValue)) return true
93
95
  else return false
94
96
  })
95
97
  attribs=attribs.map(attrib=>{
96
98
  let query=attrib
97
99
  attrib=attrib.replace('[','').replace(']','')
98
100
  let [name,value]=attrib.split(/[\~\|\^\$\*]?\=/)
99
101
  let sign=attrib.replace(name,'').replace(value,'')
100
102
  attrib={ query }
101
103
  if (name) attrib.name=name
102
104
  if (value) attrib.value=value.trim().replace(/^\"/,'').replace(/\"$/,'')
103
105
  if (sign){
104
106
  attrib.sign=sign
105
107
  attrib.check=this.getAttribFn(sign).bind(attrib)
106
108
  }
107
109
  return attrib
108
110
  });
109
111
  return attribs
110
112
  }
111
113
  getAttribFn(sign){
112
114
  if (sign=='=') return function (value){ return value===this.value }
113
115
  if (sign=='*=') return function (value){ return value.includes(this.value) }
114
116
  if (sign=='^=') return function (value){ return value.startsWith(this.value) }
115
117
  if (sign=='$=') return function (value){ return value.endsWith(this.value) }
116
118
  if (sign=='|=') return function (value){
117
119
  return value.trim().split(' ').length==1
118
120
  && (value.startsWith(this.value) || value.startsWith(this.value+'-'))
119
121
  ? true : false
120
122
  }
121
123
  if (sign=='~=') return function (value){
122
124
  return this.value.trim().split(' ').length==1 && value.includes(this.value) ? true : false
123
125
  }
124
126
  }
125
127
  removeSpaces(selector){
126
128
  selector=selector.replace(/\s{2}/g,' ')
127
129
  selector=selector.replace(/\s?\^?\$?\|?\~?\*?\=\s*/g,(m)=>m.trim())
128
130
  selector=selector.replace(/\s?(\+|\~|\>)\s?/g,(m)=>m.trim())
129
131
  return selector
130
132
  }
133
+ }
134
+ function checkElement(el,selector){
131
135
  if(selector==undefined) return true
132
136
  if(el==null) return false
133
137
  let{tag,classList,attributes,id,prev,ancestors,parents,prevAny}=selector
134
138
  if(typeof el==='string') return false
135
139
  if(el.isSpecial) return false
136
140
  if(id!==undefined && el.id===null) return false
137
141
  if(id && id!==el.id) return false
138
142
  if(tag && el.tagName===undefined) return false
139
143
  else if(tag && tag!==el.tagName) return false
140
144
  const clas=el.attributes.class
141
145
  if(classList!==undefined && (clas===undefined || clas==='')) return false
142
146
  else if(classList!==undefined){
143
147
  if(classList.every(e=>el.classList.contains(e))===false) return false
144
148
  }
145
149
  if(checkattributes(attributes,el)===false) return false
146
150
  if(checkElement(el.prev,prev)===false) return false
147
151
  if(checkAncestors(el.ancestors,ancestors)===false) return false
148
152
  if(checkParents(el.ancestors,parents)===false) return false
149
153
  if(el.parent){
150
154
  if(checkPrevAny(el.parent.children,el.childIndex,prevAny)==false) return false
151
155
  }
152
156
  return true
157
+ }
153
158
  function checkattributes(attributes=[],el){
154
159
  let elattributes=el.attributes
155
160
  let names=Object.keys(elattributes)
156
161
  let passedTests=0
157
162
  if(attributes) for(let i=0; i<attributes.length; i++){
158
163
  let{name,value,check}=attributes[i]
159
164
  if(name=='inner' && value!==undefined && check && el.inner){
160
165
  if(check(el.inner)) passedTests++
161
166
  }
162
167
  if(!names.includes(name)) continue
163
168
  else if(value==undefined) passedTests++
164
169
  else if(value && elattributes[name]){
165
170
  if(check(elattributes[name])==false) continue
166
171
  else passedTests++
167
172
  }
168
173
  }
169
174
  if(passedTests==attributes.length) return true
170
175
  else return false
176
+ }
171
177
  function checkPrevAny(children=[],index,prevAny){
172
178
  let size=children.length
173
179
  if((size==0 || index==0) && prevAny) return false
174
180
  for(let i=index; i>=0; i--){
175
181
  if(checkElement(children[i],prevAny)) return true
176
182
  }
177
183
  return false
184
+ }
178
185
  function checkAncestors(ancestors=[],selectorAncestors=[]){
179
186
  let count=0
180
187
  if(selectorAncestors.length==0) return true
181
188
  let endIndex=ancestors.length-1
182
189
  let selectorIndex=selectorAncestors.length-1
183
190
  while(selectorIndex>=0){
184
191
  for(let i=endIndex; i>=0; i--){
185
192
  endIndex=i-1
186
193
  if(checkElement(ancestors[i],selectorAncestors[selectorIndex])==true){
187
194
  count++
188
195
  break
189
196
  }
190
197
  }
191
198
  selectorIndex--
192
199
  }
193
200
  if(count==selectorAncestors.length) return true
194
201
  else return false
202
+ }
195
203
  function checkParents(ancestors=[],selectorParents=[]){
196
204
  if(selectorParents.length===0) return true
197
205
  if(ancestors.length< selectorParents.length) return false
198
206
  let index=ancestors.length-1
199
207
  for(let i=selectorParents.length-1; i>=0; i--){
200
208
  if(checkElement(ancestors[index],selectorParents[i])===false) return false
201
209
  index--
202
210
  }
203
211
  return true
212
+ }
213
+ const getDataName=prop=>'data-'+prop.toLowerCase()
214
+ function getDataset(element){
204
215
  return new Proxy(element.attributes,{
205
216
  get: (target,prop)=>{return target[getDataName(prop)]},set: (target,prop,value)=>{target[getDataName(prop)]=value; return true},deleteProperty: (target,prop)=>{
206
217
  const dataAttr=getDataName(prop)
207
218
  if (dataAttr in target){
208
219
  delete target[dataAttr];
209
220
  return true;
210
221
  }
211
222
  return false;
212
223
  }
213
224
  });
225
+ }
226
+
227
+ function find(selectors,element,collection,first=false,firstTime=true){
214
228
  for(let selector of selectors){
215
229
  if(checkElement(element,selector)) collection.add(element)
216
230
  }
217
231
  if(element.children)
218
232
  element.children.forEach(child=>{
219
233
  if(first && collection.size>0) return
220
234
  find(selectors,child,collection,first,false)
221
235
  })
222
236
  return firstTime ? [...collection] : collection
237
+ }
238
+ class TextNode{
223
239
  constructor(data){
224
240
  this.nodeName='#text';
225
241
  this.parent=null;
226
242
  this.textContent=data;
227
243
  }
228
244
  get nodeValue(){return this.textContent}
229
245
  get parentNode(){return this.parent}
246
+ }
247
+
248
+ function buildStyle(attributes){
230
249
  const styles=attributes.style || "";
231
250
  const camelToKebab=str=>str.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g,'$1-$2').toLowerCase();
232
251
  const kebabToCamel=str=>str.replace(/-([a-z])/g,g=>g[1].toUpperCase());
233
252
  const baseStyleObj=styles.split(";").reduce((acc,style)=>{
234
253
  const [key,value]=style.split(":").map(s=>s.trim());
235
254
  if (key && value) acc[kebabToCamel(key)]=value;
236
255
  return acc;
237
256
  },{});
238
257
  return new Proxy(baseStyleObj,{
239
258
  get: (obj,prop)=>obj[camelToKebab(prop)] || obj[prop],set: (obj,prop,value)=>{
240
259
  obj[camelToKebab(prop)]=value;
241
260
  attributes.style=Object.entries(obj).map(([k,v])=>`${camelToKebab(k)}: ${v}`).join("; ");
242
261
  return true;
243
262
  },deleteProperty: (obj,prop)=>{
244
263
  delete obj[camelToKebab(prop)];
245
264
  attributes.style=Object.entries(obj).map(([k,v])=>`${camelToKebab(k)}: ${v}`).join("; ");
246
265
  return true;
247
266
  }
248
267
  });
268
+ }
269
+
270
+ class NodeClassList{
249
271
  constructor(node){ this.node=node }
250
272
  get classes(){ return (this.node.attributes.class || "").split(" ").filter(Boolean) }
251
273
  set classes(val){ this.node.attributes.class=val.join(" ") }
252
274
  contains(className){ return this.classes.includes(className) }
253
275
  add(className){
254
276
  const currentClasses=this.classes;
255
277
  if (!currentClasses.includes(className)) this.classes=[...currentClasses,className];
256
278
  }
257
279
  remove(className){ this.classes=this.classes.filter(cls=>cls!==className); }
258
280
  toggle(className){
259
281
  if (this.classes.includes(className)) this.remove(className);
260
282
  else this.add(className);
261
283
  }
262
284
  replace(oldClass,newClass){
263
285
  if (this.classes.includes(oldClass)){
264
286
  this.remove(oldClass);
265
287
  this.add(newClass);
266
288
  }
267
289
  }
290
+ }
291
+ class Node{
268
292
  constructor(tagName,attributes={},parent=null){
269
293
  this.isSingle=false;
270
294
  this.tagName=tagName;
271
295
  this.attributes=attributes;
272
296
  this.childNodes=[];
273
297
  if (parent!==null) parent.childNodes.push(this)
274
298
  this.parent=parent;
275
299
  this._classList=null;
276
300
  this.__style=null;
277
301
  this._dataset=null
278
302
  }
279
303
  get id(){ return this.attributes.id || null; }
280
304
  get className(){return this.attributes.class || null}
281
305
  get parentNode(){ return this.parent }
282
306
  get ancestors(){
283
307
  const ancestors=[]
284
308
  let element=this.parent
285
309
  while (element.tagName!=='ROOT'){
286
310
  ancestors.push(element)
287
311
  element=element.parent
288
312
  }
289
313
  return ancestors.reverse()
290
314
  }
291
315
  get childIndex(){ return this.parent.childNodes ? this.parent.childNodes.indexOf(this) : null }
292
316
  get previousElementSibling(){ return this.prev }
293
317
  get prev(){
294
318
  if (!this.childIndex) return null
295
319
  return this.parent.childNodes[this.childIndex-1]
296
320
  }
297
321
  get nextElementSibling(){ return this.next }
298
322
  get next(){
299
323
  if (!this.childIndex) return null
300
324
  return this.parent.childNodes[this.childIndex+1] || null
301
325
  }
302
326
  get dataset(){
303
327
  if (!this._dataset) this._dataset=getDataset(this);
304
328
  return this._dataset;
305
329
  }
306
330
  get classList(){
307
331
  if (!this._classList) this._classList=new NodeClassList(this);
308
332
  return this._classList;
309
333
  }
310
334
  get style(){
311
335
  if (!this.__style) this.__style=buildStyle(this.attributes)
312
336
  return this.__style
313
337
  }
314
338
  get outerHTML(){
315
339
  const attrs=Object.entries(this.attributes).map(([key,val])=>`${key}="${val}"`).join(" ");
316
340
  return `<${this.tagName} ${attrs}>${this.innerHTML}</${this.tagName}>`;
317
341
  }
318
342
  getAttribute(attrName){ return this.attributes[attrName] || null }
319
343
  setAttribute(attrName,value){ this.attributes[attrName]=value }
320
344
  removeAttribute(attrName){ delete this.attributes[attrName] }
321
345
  remove(){
322
346
  if (!this.parent) return
323
347
  const index=this.childIndex;
324
348
  if (index!==null) this.parent.childNodes.splice(index,1);
325
349
  }
326
350
  get innerHTML(){
327
351
  return this.childNodes.map(child=>{
328
352
  if (child instanceof Node || child instanceof SingleNode) return child.outerHTML;
329
353
  else if (child instanceof TextNode) return child.textContent;
330
354
  else return child
331
355
  }).join("");
332
356
  }
333
357
  $$(query){return this.querySelectorAll(query)}
334
358
  querySelectorAll(query){
335
359
  const selectors=Query.get(query)
336
360
  return find(selectors,this,new Set())
337
361
  }
338
362
  $(query){return this.querySelector(query)}
339
363
  querySelector(query){
340
364
  const selectors=Query.get(query)
341
365
  return find(selectors,this,new Set(),true)[0]
342
366
  }
343
367
  getElementsByClassName(query){ return this.querySelectorAll('.'+query) }
344
368
  getElementsByTagName(query){ return this.querySelectorAll(query) }
345
369
  getElementById(query){ return this.querySelector('#'+query) }
346
370
  get children(){
347
371
  return this.childNodes.filter(child=>{
348
372
  if (!(child instanceof Node)) return false
349
373
  if (child.tagName==='#comment') return false
350
374
  return true
351
375
  });
352
376
  }
353
377
  insertAdjacentElement(position,newElement){
354
378
  if(newElement.tagName==='ROOT' && newElement.childNodes.length>0) newElement=newElement.childNodes[0]
355
379
  const pos=position.toLowerCase();
356
380
  if (pos==="afterbegin") this.childNodes.unshift(newElement);
357
381
  else if (pos==="beforeend") this.childNodes.push(newElement);
358
382
  if (!this.parent) return newElement
359
383
  if (pos==="beforebegin") this.parent.childNodes.unshift(newElement);
360
384
  else if (pos==="afterend") this.parent.childNodes.splice(this.childIndex+1,0,newElement);
361
385
  return newElement
362
386
  }
363
387
  insertAdjacentHTML(position,html){
364
388
  const newNode=parseHTML(html);
365
389
  return this.insertAdjacentElement(position,newNode);
366
390
  }
367
391
  insertAdjacentText(position,text){
368
392
  return this.insertAdjacentElement(position,new TextNode(text));
369
393
  }
370
394
  set innerHTML(html){
371
395
  const parsed=parseHTML(html);
372
396
  this.childNodes=parsed.childNodes;
373
397
  }
374
398
  set outerHTML(html){
375
399
  const parsed=parseHTML(html);
376
400
  if (!this.parent) return console.log('element has no parent node')
377
401
  const index=this.childIndex
378
402
  if (index!==null) this.parent.childNodes.splice(index,1,...parsed.childNodes);
379
403
  }
380
404
  appendChild(newChild){
381
405
  if (newChild instanceof Node || newChild instanceof TextNode || newChild instanceof SingleNode){
382
406
  if (newChild.parent) newChild.parent.childNodes=newChild.parent.childNodes.filter(child=>child!==newChild);
383
407
  } else if(typeof newChild==='string') newChild=new TextNode(newChild)
384
408
  else return newChild
385
409
  this.childNodes.push(newChild);
386
410
  newChild.parent=this;
387
411
  return newChild;
388
412
  }
389
413
  get textContent(){
390
414
  if (this.childNodes.length===0) return this.nodeName==='#text' ? this.nodeValue : '';
391
415
  return this.childNodes.map(child=>{
392
416
  if(child instanceof SingleNode) return ''
393
417
  if(child instanceof TextNode) return child.nodeValue
394
418
  if(child instanceof Node) return child.textContent;
395
419
  else return child;
396
420
  }).join(" ");
397
421
  }
398
422
  set textContent(value){
399
423
  this.childNodes=[];
400
424
  if (value!==null && value!==undefined){
401
425
  this.childNodes.push(value.toString());
402
426
  }
403
427
  }
428
+ }
429
+ class SingleNode extends Node{
404
430
  constructor(tagName,attributes={},parent=null){
405
431
  if(attributes['?'] && tagName==='?xml') delete attributes['?']
406
432
  super(tagName,attributes,parent);
407
433
  this.isSingle=true
408
434
  }
409
435
  get outerHTML(){
410
436
  if (this.tagName==="#cdata-section") return `<![CDATA[${this.textContent}]]>`;
411
437
  const attrs=Object.entries(this.attributes).map(([key,val])=>`${key}="${val}"`).join(" ");
412
438
  return `<${this.tagName} ${attrs}${this.tagName==='?xml' ? '?' : ''}>`;
413
439
  }
414
440
  get innerHTML(){ return ""; }
415
441
  set innerHTML(_){ }
416
442
  $(_){return null}
417
443
  $$(_){return []}
418
444
  querySelectorAll(_){ return []; }
419
445
  querySelector(_){ return null; }
420
446
  getElementsByClassName(_){ return []; }
421
447
  getElementsByTagName(_){ return []; }
422
448
  getElementById(_){ return null; }
423
449
  get children(){ return []; }
424
450
  insertAdjacentElement(_,__){ }
425
451
  insertAdjacentHTML(_,__){ }
426
452
  insertAdjacentText(_,__){ }
427
453
  appendChild(_){ }
428
454
  get textContent(){ return ""; }
429
455
  set textContent(_){ }
456
+ }
457
+ function parseAttributes(str){
430
458
  const attrs={};
431
459
  let key="";
432
460
  let value="";
433
461
  let isKey=true;
434
462
  let quoteChar=null;
435
463
  for (let i=0; i< str.length; i++){
436
464
  const char=str[i];
437
465
  if (isKey && (char==='=' || char===' ')){
438
466
  if (char==='=') isKey=false;
439
467
  else if (key.trim()){
440
468
  attrs[key.trim()]=true;
441
469
  key="";
442
470
  }
443
471
  continue;
444
472
  }
445
473
  if (!quoteChar && (char==='"' || char==="'")){
446
474
  quoteChar=char;
447
475
  continue;
448
476
  } else if (quoteChar && char===quoteChar){
449
477
  quoteChar=null;
450
478
  attrs[key.trim()]=value.trim();
451
479
  key=""; value=""; isKey=true;
452
480
  continue;
453
481
  }
454
482
  if (isKey) key+=char;
455
483
  else value+=char;
456
484
  }
457
485
  if (key.trim() &&!value) attrs[key.trim()]=true;
458
486
  return attrs;
487
+ }
488
+ const VOID_TAGS=new Set(["area","base","br","col","command","embed","hr","img","input","keygen","link","meta","param","source","track","wbr","!doctype",'?xml']);
489
+ function parseHTML(html){
459
490
  const root=new Node("ROOT");
460
491
  const stack=[root];
461
492
  let currentText="",i=0;
462
493
  function parseSpecial(startStr,endStr,n1,n2,tag){
463
494
  if (!html.startsWith(startStr,i)) return false
464
495
  const end=html.indexOf(endStr,i+n1);
465
496
  const strNode=new Node(tag,{},stack[stack.length-1]);
466
497
  strNode.childNodes.push(html.substring(i+n1,end));
467
498
  i=end+n2;
468
499
  return true
469
500
  }
470
501
  while (i< html.length){
471
502
  if (parseSpecial("<!--","-->",4,3,'#comment')) continue
472
503
  if (parseSpecial("<script","</script>",8,9,'script')) continue
473
504
  if (parseSpecial("<style","</style>",7,8,'style')) continue
474
505
  if (html.startsWith("<![CDATA[",i)){
475
506
  const end=html.indexOf("]]>",i+9);
476
507
  if (end===-1) break;
477
508
  const content=html.substring(i+9,end);
478
509
  const cdataNode=new SingleNode("#cdata-section",{},stack[stack.length-1]);
479
510
  cdataNode.nodeValue=content;
480
511
  i=end+3;
481
512
  continue;
482
513
  }
483
514
  if (html.startsWith("<",i)){
484
515
  if (currentText.trim()){
485
516
  stack[stack.length-1].childNodes.push(new TextNode(currentText.trim()));
486
517
  currentText="";
487
518
  }
488
519
  let tagEnd=i+1;
489
520
  let insideQuotes=false;
490
521
  let quoteChar=null;
491
522
  while (tagEnd< html.length){
492
523
  const char=html[tagEnd];
493
524
  if (!insideQuotes && (char==='"' || char==="'")){
494
525
  insideQuotes=true;
495
526
  quoteChar=char;
496
527
  } else if (insideQuotes && char===quoteChar){
497
528
  insideQuotes=false;
498
529
  quoteChar=null;
499
530
  }
500
531
  if (!insideQuotes && char==='>') break;
501
532
  tagEnd++;
502
533
  }
503
534
  const tagContent=html.substring(i+1,tagEnd);
504
535
  if (tagContent.startsWith("/")) stack.pop();
505
536
  else{
506
537
  let isSelfClosing=tagContent.endsWith('/');
507
538
  const tagNameEnd=tagContent.search(/\s|>|\//);
508
539
  const tagName=tagContent.substring(0,tagNameEnd>0 ? tagNameEnd : tagEnd-i-1);
509
540
  const attributesString=tagContent.substring(tagName.length,isSelfClosing ? tagContent.length-1 : tagContent.length).trim();
510
541
  const attributes=parseAttributes(attributesString);
511
542
  if (VOID_TAGS.has(tagName.toLowerCase()) || isSelfClosing) new SingleNode(tagName,attributes,stack[stack.length-1])
512
543
  else stack.push(new Node(tagName,attributes,stack[stack.length-1]));
513
544
  }
514
545
  i=tagEnd+1;
515
546
  } else{
516
547
  currentText+=html[i];
517
548
  i++;
518
549
  }
519
550
  }
520
551
  if (currentText.trim()) stack[stack.length-1].childNodes.push(new TextNode(currentText.trim()));
521
552
  return root;
553
+ }
554
+ export default { parseHTML, Node, Query, TextNode, SingleNode }
package/package.json CHANGED
@@ -1,14 +1,17 @@
1
1
  {
2
2
  "name": "als-document",
3
- "version": "0.12.0",
4
- "description": "virtual dom",
5
- "main": "document.js",
3
+ "version": "1.0.0-alpha",
4
+ "description": "A powerful HTML parser & DOM manipulation library for both backend and frontend.",
5
+ "main": "index.js",
6
+ "module": "index.mjs",
6
7
  "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1"
8
+ "build": "node ./src/build.js",
9
+ "watch": "node ./src/build.js --watch"
8
10
  },
9
- "keywords": [
10
- "virtual DOM"
11
- ],
12
- "author": "Alex Sorkin",
13
- "license": "ISC"
14
- }
11
+ "keywords": ["HTML", "DOM", "parser", "manipulation", "backend", "frontend", "als-document"],
12
+ "author": "Alex Sorkin <alexsorkin1980@gmail.com>",
13
+ "license": "ISC",
14
+ "devDependencies": {
15
+ "als-simple-test": "^0.3.5"
16
+ }
17
+ }