als-document 1.0.0-beta → 1.0.1-beta

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
@@ -22,7 +22,7 @@ function buildStyle(attributes){
22
22
  const styles=attributes.style || "";
23
23
  con
24
24
  class NodeClassList{
25
25
  constructor(node){ this.node=node }
26
26
  get classes(){ return (this.node.attributes.class || "").split(" ").filter(Boolean) }
27
27
  set classes(val){ this.node.attributes.class=val.join(" ") }
28
28
  contains(className){ return this.classes.includes(className) }
29
29
  add(className){
30
30
  const currentClasses=this.classes;
31
31
  if (!currentClasses.includes(className)) this.classes=[...currentClasses,className];
32
32
  }
33
33
  remove(className){ this.classes=this.classes.filter(cls=>cls!==className); }
34
34
  toggle(className){
35
35
  if (this.classes.includes(className)) this.remove(className);
36
36
  else this.add(className);
37
37
  }
38
38
  replace(oldClass,newClass){
39
39
  if (this.classes.includes(oldClass)){
40
40
  this.remove(oldClass);
41
41
  this.add(newClass);
42
42
  }
43
43
  }
44
44
  }
45
45
  function insertBefore(arr,index,newItem){
46
46
  const existingIndex=arr.indexOf(newItem);
47
47
  if (existingIndex!==-1) arr.splice(existingIndex,1);
48
48
  arr.splice(index,0,newItem);
49
- }
50
49
  class Node{
51
50
  constructor(tagName,attributes={},parent=null){
52
51
  this.isSingle=false;
53
52
  this.tagName=tagName;
54
53
  this.attributes=attributes;
55
54
  this.childNodes=[];
56
55
  if (parent!==null) parent.childNodes.push(this)
57
56
  this.parent=parent;
58
57
  this._classList=null;
59
58
  this.__style=null;
60
59
  this._dataset=null
61
60
  }
62
61
  get id(){ return this.attributes.id ? this.attributes.id : null; }
63
62
  set id(newValue){ this.attributes.id=newValue; }
64
63
  get className(){return this.attributes.class || null}
65
64
  get parentNode(){ return this.parent }
66
65
  get ancestors(){
67
66
  if(!this.parent) return []
68
67
  const ancestors=[]
69
68
  let element=this.parent
70
69
  while (element.tagName!=='ROOT'){
71
70
  ancestors.push(element)
72
71
  element=element.parent
73
72
  }
74
73
  return ancestors.reverse()
75
74
  }
76
75
  get childNodeIndex(){
77
76
  if(!this.parent) return null
78
77
  return this.parent.childNodes ? this.parent.childNodes.indexOf(this) : null
79
78
  }
80
79
  get childIndex(){
81
80
  if(!this.parent) return null
82
81
  return this.parent.children ? this.parent.children.indexOf(this) : null
83
82
  }
84
83
  get previousElementSibling(){ return this.prev }
85
84
  get prev(){
86
85
  if (!this.childIndex) return null
87
86
  return this.parent.children[this.childIndex-1]
88
87
  }
89
88
  get nextElementSibling(){ return this.next }
90
89
  get next(){
91
90
  if (!this.childIndex) return null
92
91
  return this.parent.children[this.childIndex+1] || null
93
92
  }
94
93
  get dataset(){
95
94
  if (!this._dataset) this._dataset=getDataset(this);
96
95
  return this._dataset;
97
96
  }
98
97
  get classList(){
99
98
  if (!this._classList) this._classList=new NodeClassList(this);
100
99
  return this._classList;
101
100
  }
102
101
  get style(){
103
102
  if (!this.__style) this.__style=buildStyle(this.attributes)
104
103
  return this.__style
105
104
  }
106
105
  get outerHTML(){
107
106
  const attrs=Object.entries(this.attributes).map(([key,val])=>val.length ? `${key}="${val}"` : key).join(" ");
108
107
  return `<${this.tagName}${attrs ? ' '+attrs : ''}>${this.innerHTML}</${this.tagName}>`;
109
108
  }
110
109
  getAttribute(attrName){ return this.attributes[attrName] || null }
111
110
  setAttribute(attrName,value){ this.attributes[attrName]=value }
112
111
  removeAttribute(attrName){ delete this.attributes[attrName] }
113
112
  remove(){
114
113
  if (!this.parent) return
115
114
  const index=this.childNodeIndex;
116
115
  if (index!==null) this.parent.childNodes.splice(index,1);
117
116
  }
118
117
  get innerHTML(){
119
118
  return this.childNodes.map(child=>{
120
119
  if (child instanceof Node || child instanceof SingleNode) return child.outerHTML;
121
120
  else if (child instanceof TextNode) return child.textContent;
122
121
  else return child
123
122
  }).join("");
124
123
  }
125
124
  $$(query){return this.querySelectorAll(query)}
126
125
  querySelectorAll(query){
127
126
  const selectors=Query.get(query)
128
127
  return find(selectors,this,new Set())
129
128
  }
130
129
  $(query){return this.querySelector(query)}
131
130
  querySelector(query){
132
131
  const selectors=Query.get(query)
133
132
  return find(selectors,this,new Set(),true)[0] || null
134
133
  }
135
134
  getElementsByClassName(query){ return this.querySelectorAll('.'+query) }
136
135
  getElementsByTagName(query){ return this.querySelectorAll(query) }
137
136
  getElementById(query){ return this.querySelector('#'+query) }
138
137
  get children(){
139
138
  return this.childNodes.filter(child=>{
140
139
  if (!(child instanceof Node)) return false
141
140
  if (child.tagName==='#comment') return false
142
141
  return true
143
142
  });
144
143
  }
145
144
  insertAdjacentElement(position,newElement){
146
145
  if(newElement.tagName==='ROOT' && newElement.childNodes.length>0) newElement=newElement.childNodes[0]
147
146
  const pos=position.toLowerCase();
148
147
  if (pos==="afterbegin") this.childNodes.unshift(newElement);
149
148
  else if (pos==="beforeend") this.childNodes.push(newElement);
150
149
  newElement.parent=this
151
150
  if (!this.parent) return newElement
152
151
  if (pos==="beforebegin") insertBefore(this.parent.childNodes,this.childNodeIndex,newElement)
153
152
  else if (pos==="afterend") this.parent.childNodes.splice(this.childNodeIndex+1,0,newElement);
154
153
  newElement.parent=this.parent
155
154
  return newElement
156
155
  }
157
156
  insertAdjacentHTML(position,html){
158
157
  const newNode=parseHTML(html);
159
158
  newNode.childNodes.reverse().forEach(node=>{
160
159
  this.insertAdjacentElement(position,node);
161
160
  });
162
161
  return newNode
163
162
  }
164
163
  insertAdjacentText(position,text){
165
164
  return this.insertAdjacentElement(position,new TextNode(text));
166
165
  }
167
166
  insert(position,element){
168
167
  const positions=['beforebegin','afterbegin','beforeend','afterend']
169
168
  if(positions[position]) position=positions[position]
170
169
  if(typeof element==='string'){
171
170
  element=element.trim()
172
171
  if(element.startsWith('<') && element.endsWith('>')){
173
172
  return this.insertAdjacentHTML(position,element)
174
173
  }
175
174
  return this.insertAdjacentText(position,element)
176
175
  }
177
176
  return this.insertAdjacentElement(position,element)
178
177
  }
179
178
  set innerHTML(html){
180
179
  const parsed=parseHTML(html);
181
180
  this.childNodes=parsed.childNodes;
182
181
  }
183
182
  set outerHTML(html){
184
183
  const parsed=parseHTML(html);
185
184
  if (!this.parent) return console.log('element has no parent node')
186
185
  const index=this.childIndex
187
186
  if (index!==null) this.parent.childNodes.splice(index,1,...parsed.childNodes);
188
187
  }
189
188
  appendChild(newChild){
190
189
  if (newChild instanceof Node || newChild instanceof TextNode || newChild instanceof SingleNode){
191
190
  if (newChild.parent) newChild.parent.childNodes=newChild.parent.childNodes.filter(child=>child!==newChild);
192
191
  } else if(typeof newChild==='string') newChild=new TextNode(newChild)
193
192
  else return newChild
194
193
  this.childNodes.push(newChild);
195
194
  newChild.parent=this;
196
195
  return newChild;
197
196
  }
198
197
  get textContent(){
199
198
  if (this.childNodes.length===0) return this.nodeName==='#text' ? this.nodeValue : '';
200
199
  return this.childNodes.map(child=>{
201
200
  if(child instanceof SingleNode) return ''
202
201
  if(child instanceof TextNode) return child.nodeValue
203
202
  if(child instanceof Node) return child.textContent;
204
203
  else return child;
205
204
  }).join(" ");
206
205
  }
207
206
  set textContent(value){
208
207
  this.childNodes=[];
209
208
  if (value!==null && value!==undefined){
210
209
  this.childNodes.push(value.toString());
211
210
  }
212
211
  }
212
+ }
213
213
  class Node{
214
214
  constructor(tagName,attributes={},parent=null){
215
215
  this.isSingle=false;
216
216
  this.tagName=tagName;
217
217
  this.attributes=attributes;
218
218
  this.childNodes=[];
219
219
  if (parent!==null) parent.childNodes.push(this)
220
220
  this.parent=parent;
221
221
  this._classList=null;
222
222
  this.__style=null;
223
223
  this._dataset=null
224
224
  }
225
225
  get id(){ return this.attributes.id ? this.attributes.id : null; }
226
226
  set id(newValue){ this.attributes.id=newValue; }
227
227
  get className(){return this.attributes.class || null}
228
228
  get parentNode(){ return this.parent }
229
229
  get ancestors(){
230
230
  if(!this.parent) return []
231
231
  const ancestors=[]
232
232
  let element=this.parent
233
233
  while (element.tagName!=='ROOT'){
234
234
  ancestors.push(element)
235
235
  element=element.parent
236
236
  }
237
237
  return ancestors.reverse()
238
238
  }
239
239
  get childNodeIndex(){
240
240
  if(!this.parent) return null
241
241
  return this.parent.childNodes ? this.parent.childNodes.indexOf(this) : null
242
242
  }
243
243
  get childIndex(){
244
244
  if(!this.parent) return null
245
245
  return this.parent.children ? this.parent.children.indexOf(this) : null
246
246
  }
247
247
  get previousElementSibling(){ return this.prev }
248
248
  get prev(){
249
249
  if (!this.childIndex) return null
250
250
  return this.parent.children[this.childIndex-1]
251
251
  }
252
252
  get nextElementSibling(){ return this.next }
253
253
  get next(){
254
254
  if (!this.childIndex) return null
255
255
  return this.parent.children[this.childIndex+1] || null
256
256
  }
257
257
  get dataset(){
258
258
  if (!this._dataset) this._dataset=getDataset(this);
259
259
  return this._dataset;
260
260
  }
261
261
  get classList(){
262
262
  if (!this._classList) this._classList=new NodeClassList(this);
263
263
  return this._classList;
264
264
  }
265
265
  get style(){
266
266
  if (!this.__style) this.__style=buildStyle(this.attributes)
267
267
  return this.__style
268
268
  }
269
269
  get outerHTML(){
270
270
  const attrs=Object.entries(this.attributes).map(([key,val])=>val.length ? `${key}="${val}"` : key).join(" ");
271
271
  return `<${this.tagName}${attrs ? ' '+attrs : ''}>${this.innerHTML}</${this.tagName}>`;
272
272
  }
273
273
  getAttribute(attrName){ return this.attributes[attrName] || null }
274
274
  setAttribute(attrName,value){ this.attributes[attrName]=value }
275
275
  removeAttribute(attrName){ delete this.attributes[attrName] }
276
276
  remove(){
277
277
  if (!this.parent) return
278
278
  const index=this.childNodeIndex;
279
279
  if (index!==null) this.parent.childNodes.splice(index,1);
280
280
  }
281
281
  get innerHTML(){
282
282
  return this.childNodes.map(child=>{
283
283
  if (child instanceof Node || child instanceof SingleNode) return child.outerHTML;
284
284
  else if (child instanceof TextNode) return child.textContent;
285
285
  else return child
286
286
  }).join("");
287
287
  }
288
288
  $$(query){return this.querySelectorAll(query)}
289
289
  querySelectorAll(query){
290
290
  const selectors=Query.get(query)
291
291
  return find(selectors,this,new Set())
292
292
  }
293
293
  $(query){return this.querySelector(query)}
294
294
  querySelector(query){
295
295
  const selectors=Query.get(query)
296
296
  return find(selectors,this,new Set(),true)[0] || null
297
297
  }
298
298
  getElementsByClassName(query){ return this.querySelectorAll('.'+query) }
299
299
  getElementsByTagName(query){ return this.querySelectorAll(query) }
300
300
  getElementById(query){ return this.querySelector('#'+query) }
301
301
  get children(){
302
302
  return this.childNodes.filter(child=>{
303
303
  if (!(child instanceof Node)) return false
304
304
  if (child.tagName==='#comment') return false
305
305
  return true
306
306
  });
307
307
  }
308
308
  insertAdjacentElement(position,newElement){
309
309
  if(newElement.tagName==='ROOT' && newElement.childNodes.length>0) newElement=newElement.childNodes[0]
310
310
  const pos=position.toLowerCase();
311
311
  if(pos==='afterbegin' || pos==='beforeend'){
312
312
  if (pos==="afterbegin") this.childNodes.unshift(newElement);
313
313
  else if (pos==="beforeend") this.childNodes.push(newElement);
314
314
  newElement.parent=this
315
315
  return newElement
316
316
  }
317
317
  if (!this.parent) throw new Error("Can't insert element to element without parent")
318
318
  if (pos==="beforebegin") insertBefore(this.parent.childNodes,this.childNodeIndex,newElement)
319
319
  else if (pos==="afterend") this.parent.childNodes.splice(this.childNodeIndex+1,0,newElement);
320
320
  newElement.parent=this.parent
321
321
  return newElement
322
322
  }
323
323
  insertAdjacentHTML(position,html){
324
324
  const newNode=parseHTML(html);
325
325
  newNode.childNodes.reverse().forEach(node=>{
326
326
  this.insertAdjacentElement(position,node);
327
327
  });
328
328
  return newNode
329
329
  }
330
330
  insertAdjacentText(position,text){
331
331
  return this.insertAdjacentElement(position,new TextNode(text));
332
332
  }
333
333
  insert(position,element){
334
334
  const positions=['beforebegin','afterbegin','beforeend','afterend']
335
335
  if(positions[position]) position=positions[position]
336
336
  if(typeof element==='string'){
337
337
  element=element.trim()
338
338
  if(element.startsWith('<') && element.endsWith('>')){
339
339
  return this.insertAdjacentHTML(position,element)
340
340
  }
341
341
  return this.insertAdjacentText(position,element)
342
342
  }
343
343
  return this.insertAdjacentElement(position,element)
344
344
  }
345
345
  set innerHTML(html){
346
346
  const parsed=parseHTML(html);
347
347
  this.childNodes=parsed.childNodes;
348
348
  }
349
349
  set outerHTML(html){
350
350
  const parsed=parseHTML(html);
351
351
  if (!this.parent) return console.log('element has no parent node')
352
352
  const index=this.childIndex
353
353
  if (index!==null) this.parent.childNodes.splice(index,1,...parsed.childNodes);
354
354
  }
355
355
  appendChild(newChild){
356
356
  if (newChild instanceof Node || newChild instanceof TextNode || newChild instanceof SingleNode){
357
357
  if (newChild.parent) newChild.parent.childNodes=newChild.parent.childNodes.filter(child=>child!==newChild);
358
358
  } else if(typeof newChild==='string') newChild=new TextNode(newChild)
359
359
  else return newChild
360
360
  this.childNodes.push(newChild);
361
361
  newChild.parent=this;
362
362
  return newChild;
363
363
  }
364
364
  get textContent(){
365
365
  if (this.childNodes.length===0) return this.nodeName==='#text' ? this.nodeValue : '';
366
366
  return this.childNodes.map(child=>{
367
367
  if(child instanceof SingleNode) return ''
368
368
  if(child instanceof TextNode) return child.nodeValue
369
369
  if(child instanceof Node) return child.textContent;
370
370
  else return child;
371
371
  }).join(" ");
372
372
  }
373
373
  set textContent(value){
374
374
  this.childNodes=[];
375
375
  if (value!==null && value!==undefined){
376
376
  this.childNodes.push(value.toString());
377
377
  }
378
378
  }
379
379
  }
380
380
  class SingleNode extends Node{
381
381
  constructor(tagName,attributes={},parent=null){
382
382
  if(attributes['?'] && tagName==='?xml') delete attributes['?']
383
383
  super(tagName,attributes,parent);
384
384
  this.isSingle=true
385
385
  }
386
386
  get outerHTML(){
387
387
  if (this.tagName==="#cdata-section") return `<![CDATA[${this.nodeValue}]]>`;
388
388
  const attrs=Object.entries(this.attributes).map(([key,val])=>val.length ? `${key}="${val}"` : key).join(" ");
389
389
  return `<${this.tagName} ${attrs}${this.tagName==='?xml' ? '?' : ''}>`;
390
390
  }
391
391
  get innerHTML(){ return ""; }
392
392
  set innerHTML(_){ }
393
393
  $(_){return null}
394
394
  $$(_){return []}
395
395
  querySelectorAll(_){ return []; }
396
396
  querySelector(_){ return null; }
397
397
  getElementsByClassName(_){ return []; }
398
398
  getElementsByTagName(_){ return []; }
399
399
  getElementById(_){ return null; }
400
400
  get children(){ return []; }
401
401
  insertAdjacentElement(_,__){ }
402
402
  insertAdjacentHTML(_,__){ }
403
403
  insertAdjacentText(_,__){ }
404
404
  appendChild(_){ }
405
405
  insert(_,__){ }
406
406
  get textContent(){ return ""; }
407
407
  set textContent(_){ }
408
408
  }
package/index.js CHANGED
@@ -21,7 +21,7 @@ function buildStyle(attributes){
21
21
  const styles=attributes.style || "";
22
22
  con
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
44
  function insertBefore(arr,index,newItem){
45
45
  const existingIndex=arr.indexOf(newItem);
46
46
  if (existingIndex!==-1) arr.splice(existingIndex,1);
47
47
  arr.splice(index,0,newItem);
48
- }
49
48
  class Node{
50
49
  constructor(tagName,attributes={},parent=null){
51
50
  this.isSingle=false;
52
51
  this.tagName=tagName;
53
52
  this.attributes=attributes;
54
53
  this.childNodes=[];
55
54
  if (parent!==null) parent.childNodes.push(this)
56
55
  this.parent=parent;
57
56
  this._classList=null;
58
57
  this.__style=null;
59
58
  this._dataset=null
60
59
  }
61
60
  get id(){ return this.attributes.id ? this.attributes.id : null; }
62
61
  set id(newValue){ this.attributes.id=newValue; }
63
62
  get className(){return this.attributes.class || null}
64
63
  get parentNode(){ return this.parent }
65
64
  get ancestors(){
66
65
  if(!this.parent) return []
67
66
  const ancestors=[]
68
67
  let element=this.parent
69
68
  while (element.tagName!=='ROOT'){
70
69
  ancestors.push(element)
71
70
  element=element.parent
72
71
  }
73
72
  return ancestors.reverse()
74
73
  }
75
74
  get childNodeIndex(){
76
75
  if(!this.parent) return null
77
76
  return this.parent.childNodes ? this.parent.childNodes.indexOf(this) : null
78
77
  }
79
78
  get childIndex(){
80
79
  if(!this.parent) return null
81
80
  return this.parent.children ? this.parent.children.indexOf(this) : null
82
81
  }
83
82
  get previousElementSibling(){ return this.prev }
84
83
  get prev(){
85
84
  if (!this.childIndex) return null
86
85
  return this.parent.children[this.childIndex-1]
87
86
  }
88
87
  get nextElementSibling(){ return this.next }
89
88
  get next(){
90
89
  if (!this.childIndex) return null
91
90
  return this.parent.children[this.childIndex+1] || null
92
91
  }
93
92
  get dataset(){
94
93
  if (!this._dataset) this._dataset=getDataset(this);
95
94
  return this._dataset;
96
95
  }
97
96
  get classList(){
98
97
  if (!this._classList) this._classList=new NodeClassList(this);
99
98
  return this._classList;
100
99
  }
101
100
  get style(){
102
101
  if (!this.__style) this.__style=buildStyle(this.attributes)
103
102
  return this.__style
104
103
  }
105
104
  get outerHTML(){
106
105
  const attrs=Object.entries(this.attributes).map(([key,val])=>val.length ? `${key}="${val}"` : key).join(" ");
107
106
  return `<${this.tagName}${attrs ? ' '+attrs : ''}>${this.innerHTML}</${this.tagName}>`;
108
107
  }
109
108
  getAttribute(attrName){ return this.attributes[attrName] || null }
110
109
  setAttribute(attrName,value){ this.attributes[attrName]=value }
111
110
  removeAttribute(attrName){ delete this.attributes[attrName] }
112
111
  remove(){
113
112
  if (!this.parent) return
114
113
  const index=this.childNodeIndex;
115
114
  if (index!==null) this.parent.childNodes.splice(index,1);
116
115
  }
117
116
  get innerHTML(){
118
117
  return this.childNodes.map(child=>{
119
118
  if (child instanceof Node || child instanceof SingleNode) return child.outerHTML;
120
119
  else if (child instanceof TextNode) return child.textContent;
121
120
  else return child
122
121
  }).join("");
123
122
  }
124
123
  $$(query){return this.querySelectorAll(query)}
125
124
  querySelectorAll(query){
126
125
  const selectors=Query.get(query)
127
126
  return find(selectors,this,new Set())
128
127
  }
129
128
  $(query){return this.querySelector(query)}
130
129
  querySelector(query){
131
130
  const selectors=Query.get(query)
132
131
  return find(selectors,this,new Set(),true)[0] || null
133
132
  }
134
133
  getElementsByClassName(query){ return this.querySelectorAll('.'+query) }
135
134
  getElementsByTagName(query){ return this.querySelectorAll(query) }
136
135
  getElementById(query){ return this.querySelector('#'+query) }
137
136
  get children(){
138
137
  return this.childNodes.filter(child=>{
139
138
  if (!(child instanceof Node)) return false
140
139
  if (child.tagName==='#comment') return false
141
140
  return true
142
141
  });
143
142
  }
144
143
  insertAdjacentElement(position,newElement){
145
144
  if(newElement.tagName==='ROOT' && newElement.childNodes.length>0) newElement=newElement.childNodes[0]
146
145
  const pos=position.toLowerCase();
147
146
  if (pos==="afterbegin") this.childNodes.unshift(newElement);
148
147
  else if (pos==="beforeend") this.childNodes.push(newElement);
149
148
  newElement.parent=this
150
149
  if (!this.parent) return newElement
151
150
  if (pos==="beforebegin") insertBefore(this.parent.childNodes,this.childNodeIndex,newElement)
152
151
  else if (pos==="afterend") this.parent.childNodes.splice(this.childNodeIndex+1,0,newElement);
153
152
  newElement.parent=this.parent
154
153
  return newElement
155
154
  }
156
155
  insertAdjacentHTML(position,html){
157
156
  const newNode=parseHTML(html);
158
157
  newNode.childNodes.reverse().forEach(node=>{
159
158
  this.insertAdjacentElement(position,node);
160
159
  });
161
160
  return newNode
162
161
  }
163
162
  insertAdjacentText(position,text){
164
163
  return this.insertAdjacentElement(position,new TextNode(text));
165
164
  }
166
165
  insert(position,element){
167
166
  const positions=['beforebegin','afterbegin','beforeend','afterend']
168
167
  if(positions[position]) position=positions[position]
169
168
  if(typeof element==='string'){
170
169
  element=element.trim()
171
170
  if(element.startsWith('<') && element.endsWith('>')){
172
171
  return this.insertAdjacentHTML(position,element)
173
172
  }
174
173
  return this.insertAdjacentText(position,element)
175
174
  }
176
175
  return this.insertAdjacentElement(position,element)
177
176
  }
178
177
  set innerHTML(html){
179
178
  const parsed=parseHTML(html);
180
179
  this.childNodes=parsed.childNodes;
181
180
  }
182
181
  set outerHTML(html){
183
182
  const parsed=parseHTML(html);
184
183
  if (!this.parent) return console.log('element has no parent node')
185
184
  const index=this.childIndex
186
185
  if (index!==null) this.parent.childNodes.splice(index,1,...parsed.childNodes);
187
186
  }
188
187
  appendChild(newChild){
189
188
  if (newChild instanceof Node || newChild instanceof TextNode || newChild instanceof SingleNode){
190
189
  if (newChild.parent) newChild.parent.childNodes=newChild.parent.childNodes.filter(child=>child!==newChild);
191
190
  } else if(typeof newChild==='string') newChild=new TextNode(newChild)
192
191
  else return newChild
193
192
  this.childNodes.push(newChild);
194
193
  newChild.parent=this;
195
194
  return newChild;
196
195
  }
197
196
  get textContent(){
198
197
  if (this.childNodes.length===0) return this.nodeName==='#text' ? this.nodeValue : '';
199
198
  return this.childNodes.map(child=>{
200
199
  if(child instanceof SingleNode) return ''
201
200
  if(child instanceof TextNode) return child.nodeValue
202
201
  if(child instanceof Node) return child.textContent;
203
202
  else return child;
204
203
  }).join(" ");
205
204
  }
206
205
  set textContent(value){
207
206
  this.childNodes=[];
208
207
  if (value!==null && value!==undefined){
209
208
  this.childNodes.push(value.toString());
210
209
  }
211
210
  }
211
+ }
212
212
  class Node{
213
213
  constructor(tagName,attributes={},parent=null){
214
214
  this.isSingle=false;
215
215
  this.tagName=tagName;
216
216
  this.attributes=attributes;
217
217
  this.childNodes=[];
218
218
  if (parent!==null) parent.childNodes.push(this)
219
219
  this.parent=parent;
220
220
  this._classList=null;
221
221
  this.__style=null;
222
222
  this._dataset=null
223
223
  }
224
224
  get id(){ return this.attributes.id ? this.attributes.id : null; }
225
225
  set id(newValue){ this.attributes.id=newValue; }
226
226
  get className(){return this.attributes.class || null}
227
227
  get parentNode(){ return this.parent }
228
228
  get ancestors(){
229
229
  if(!this.parent) return []
230
230
  const ancestors=[]
231
231
  let element=this.parent
232
232
  while (element.tagName!=='ROOT'){
233
233
  ancestors.push(element)
234
234
  element=element.parent
235
235
  }
236
236
  return ancestors.reverse()
237
237
  }
238
238
  get childNodeIndex(){
239
239
  if(!this.parent) return null
240
240
  return this.parent.childNodes ? this.parent.childNodes.indexOf(this) : null
241
241
  }
242
242
  get childIndex(){
243
243
  if(!this.parent) return null
244
244
  return this.parent.children ? this.parent.children.indexOf(this) : null
245
245
  }
246
246
  get previousElementSibling(){ return this.prev }
247
247
  get prev(){
248
248
  if (!this.childIndex) return null
249
249
  return this.parent.children[this.childIndex-1]
250
250
  }
251
251
  get nextElementSibling(){ return this.next }
252
252
  get next(){
253
253
  if (!this.childIndex) return null
254
254
  return this.parent.children[this.childIndex+1] || null
255
255
  }
256
256
  get dataset(){
257
257
  if (!this._dataset) this._dataset=getDataset(this);
258
258
  return this._dataset;
259
259
  }
260
260
  get classList(){
261
261
  if (!this._classList) this._classList=new NodeClassList(this);
262
262
  return this._classList;
263
263
  }
264
264
  get style(){
265
265
  if (!this.__style) this.__style=buildStyle(this.attributes)
266
266
  return this.__style
267
267
  }
268
268
  get outerHTML(){
269
269
  const attrs=Object.entries(this.attributes).map(([key,val])=>val.length ? `${key}="${val}"` : key).join(" ");
270
270
  return `<${this.tagName}${attrs ? ' '+attrs : ''}>${this.innerHTML}</${this.tagName}>`;
271
271
  }
272
272
  getAttribute(attrName){ return this.attributes[attrName] || null }
273
273
  setAttribute(attrName,value){ this.attributes[attrName]=value }
274
274
  removeAttribute(attrName){ delete this.attributes[attrName] }
275
275
  remove(){
276
276
  if (!this.parent) return
277
277
  const index=this.childNodeIndex;
278
278
  if (index!==null) this.parent.childNodes.splice(index,1);
279
279
  }
280
280
  get innerHTML(){
281
281
  return this.childNodes.map(child=>{
282
282
  if (child instanceof Node || child instanceof SingleNode) return child.outerHTML;
283
283
  else if (child instanceof TextNode) return child.textContent;
284
284
  else return child
285
285
  }).join("");
286
286
  }
287
287
  $$(query){return this.querySelectorAll(query)}
288
288
  querySelectorAll(query){
289
289
  const selectors=Query.get(query)
290
290
  return find(selectors,this,new Set())
291
291
  }
292
292
  $(query){return this.querySelector(query)}
293
293
  querySelector(query){
294
294
  const selectors=Query.get(query)
295
295
  return find(selectors,this,new Set(),true)[0] || null
296
296
  }
297
297
  getElementsByClassName(query){ return this.querySelectorAll('.'+query) }
298
298
  getElementsByTagName(query){ return this.querySelectorAll(query) }
299
299
  getElementById(query){ return this.querySelector('#'+query) }
300
300
  get children(){
301
301
  return this.childNodes.filter(child=>{
302
302
  if (!(child instanceof Node)) return false
303
303
  if (child.tagName==='#comment') return false
304
304
  return true
305
305
  });
306
306
  }
307
307
  insertAdjacentElement(position,newElement){
308
308
  if(newElement.tagName==='ROOT' && newElement.childNodes.length>0) newElement=newElement.childNodes[0]
309
309
  const pos=position.toLowerCase();
310
310
  if(pos==='afterbegin' || pos==='beforeend'){
311
311
  if (pos==="afterbegin") this.childNodes.unshift(newElement);
312
312
  else if (pos==="beforeend") this.childNodes.push(newElement);
313
313
  newElement.parent=this
314
314
  return newElement
315
315
  }
316
316
  if (!this.parent) throw new Error("Can't insert element to element without parent")
317
317
  if (pos==="beforebegin") insertBefore(this.parent.childNodes,this.childNodeIndex,newElement)
318
318
  else if (pos==="afterend") this.parent.childNodes.splice(this.childNodeIndex+1,0,newElement);
319
319
  newElement.parent=this.parent
320
320
  return newElement
321
321
  }
322
322
  insertAdjacentHTML(position,html){
323
323
  const newNode=parseHTML(html);
324
324
  newNode.childNodes.reverse().forEach(node=>{
325
325
  this.insertAdjacentElement(position,node);
326
326
  });
327
327
  return newNode
328
328
  }
329
329
  insertAdjacentText(position,text){
330
330
  return this.insertAdjacentElement(position,new TextNode(text));
331
331
  }
332
332
  insert(position,element){
333
333
  const positions=['beforebegin','afterbegin','beforeend','afterend']
334
334
  if(positions[position]) position=positions[position]
335
335
  if(typeof element==='string'){
336
336
  element=element.trim()
337
337
  if(element.startsWith('<') && element.endsWith('>')){
338
338
  return this.insertAdjacentHTML(position,element)
339
339
  }
340
340
  return this.insertAdjacentText(position,element)
341
341
  }
342
342
  return this.insertAdjacentElement(position,element)
343
343
  }
344
344
  set innerHTML(html){
345
345
  const parsed=parseHTML(html);
346
346
  this.childNodes=parsed.childNodes;
347
347
  }
348
348
  set outerHTML(html){
349
349
  const parsed=parseHTML(html);
350
350
  if (!this.parent) return console.log('element has no parent node')
351
351
  const index=this.childIndex
352
352
  if (index!==null) this.parent.childNodes.splice(index,1,...parsed.childNodes);
353
353
  }
354
354
  appendChild(newChild){
355
355
  if (newChild instanceof Node || newChild instanceof TextNode || newChild instanceof SingleNode){
356
356
  if (newChild.parent) newChild.parent.childNodes=newChild.parent.childNodes.filter(child=>child!==newChild);
357
357
  } else if(typeof newChild==='string') newChild=new TextNode(newChild)
358
358
  else return newChild
359
359
  this.childNodes.push(newChild);
360
360
  newChild.parent=this;
361
361
  return newChild;
362
362
  }
363
363
  get textContent(){
364
364
  if (this.childNodes.length===0) return this.nodeName==='#text' ? this.nodeValue : '';
365
365
  return this.childNodes.map(child=>{
366
366
  if(child instanceof SingleNode) return ''
367
367
  if(child instanceof TextNode) return child.nodeValue
368
368
  if(child instanceof Node) return child.textContent;
369
369
  else return child;
370
370
  }).join(" ");
371
371
  }
372
372
  set textContent(value){
373
373
  this.childNodes=[];
374
374
  if (value!==null && value!==undefined){
375
375
  this.childNodes.push(value.toString());
376
376
  }
377
377
  }
378
378
  }
379
379
  class SingleNode extends Node{
380
380
  constructor(tagName,attributes={},parent=null){
381
381
  if(attributes['?'] && tagName==='?xml') delete attributes['?']
382
382
  super(tagName,attributes,parent);
383
383
  this.isSingle=true
384
384
  }
385
385
  get outerHTML(){
386
386
  if (this.tagName==="#cdata-section") return `<![CDATA[${this.nodeValue}]]>`;
387
387
  const attrs=Object.entries(this.attributes).map(([key,val])=>val.length ? `${key}="${val}"` : key).join(" ");
388
388
  return `<${this.tagName} ${attrs}${this.tagName==='?xml' ? '?' : ''}>`;
389
389
  }
390
390
  get innerHTML(){ return ""; }
391
391
  set innerHTML(_){ }
392
392
  $(_){return null}
393
393
  $$(_){return []}
394
394
  querySelectorAll(_){ return []; }
395
395
  querySelector(_){ return null; }
396
396
  getElementsByClassName(_){ return []; }
397
397
  getElementsByTagName(_){ return []; }
398
398
  getElementById(_){ return null; }
399
399
  get children(){ return []; }
400
400
  insertAdjacentElement(_,__){ }
401
401
  insertAdjacentHTML(_,__){ }
402
402
  insertAdjacentText(_,__){ }
403
403
  appendChild(_){ }
404
404
  insert(_,__){ }
405
405
  get textContent(){ return ""; }
406
406
  set textContent(_){ }
407
407
  }
package/index.mjs CHANGED
@@ -21,7 +21,7 @@ function buildStyle(attributes){
21
21
  const styles=attributes.style || "";
22
22
  con
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
44
  function insertBefore(arr,index,newItem){
45
45
  const existingIndex=arr.indexOf(newItem);
46
46
  if (existingIndex!==-1) arr.splice(existingIndex,1);
47
47
  arr.splice(index,0,newItem);
48
- }
49
48
  class Node{
50
49
  constructor(tagName,attributes={},parent=null){
51
50
  this.isSingle=false;
52
51
  this.tagName=tagName;
53
52
  this.attributes=attributes;
54
53
  this.childNodes=[];
55
54
  if (parent!==null) parent.childNodes.push(this)
56
55
  this.parent=parent;
57
56
  this._classList=null;
58
57
  this.__style=null;
59
58
  this._dataset=null
60
59
  }
61
60
  get id(){ return this.attributes.id ? this.attributes.id : null; }
62
61
  set id(newValue){ this.attributes.id=newValue; }
63
62
  get className(){return this.attributes.class || null}
64
63
  get parentNode(){ return this.parent }
65
64
  get ancestors(){
66
65
  if(!this.parent) return []
67
66
  const ancestors=[]
68
67
  let element=this.parent
69
68
  while (element.tagName!=='ROOT'){
70
69
  ancestors.push(element)
71
70
  element=element.parent
72
71
  }
73
72
  return ancestors.reverse()
74
73
  }
75
74
  get childNodeIndex(){
76
75
  if(!this.parent) return null
77
76
  return this.parent.childNodes ? this.parent.childNodes.indexOf(this) : null
78
77
  }
79
78
  get childIndex(){
80
79
  if(!this.parent) return null
81
80
  return this.parent.children ? this.parent.children.indexOf(this) : null
82
81
  }
83
82
  get previousElementSibling(){ return this.prev }
84
83
  get prev(){
85
84
  if (!this.childIndex) return null
86
85
  return this.parent.children[this.childIndex-1]
87
86
  }
88
87
  get nextElementSibling(){ return this.next }
89
88
  get next(){
90
89
  if (!this.childIndex) return null
91
90
  return this.parent.children[this.childIndex+1] || null
92
91
  }
93
92
  get dataset(){
94
93
  if (!this._dataset) this._dataset=getDataset(this);
95
94
  return this._dataset;
96
95
  }
97
96
  get classList(){
98
97
  if (!this._classList) this._classList=new NodeClassList(this);
99
98
  return this._classList;
100
99
  }
101
100
  get style(){
102
101
  if (!this.__style) this.__style=buildStyle(this.attributes)
103
102
  return this.__style
104
103
  }
105
104
  get outerHTML(){
106
105
  const attrs=Object.entries(this.attributes).map(([key,val])=>val.length ? `${key}="${val}"` : key).join(" ");
107
106
  return `<${this.tagName}${attrs ? ' '+attrs : ''}>${this.innerHTML}</${this.tagName}>`;
108
107
  }
109
108
  getAttribute(attrName){ return this.attributes[attrName] || null }
110
109
  setAttribute(attrName,value){ this.attributes[attrName]=value }
111
110
  removeAttribute(attrName){ delete this.attributes[attrName] }
112
111
  remove(){
113
112
  if (!this.parent) return
114
113
  const index=this.childNodeIndex;
115
114
  if (index!==null) this.parent.childNodes.splice(index,1);
116
115
  }
117
116
  get innerHTML(){
118
117
  return this.childNodes.map(child=>{
119
118
  if (child instanceof Node || child instanceof SingleNode) return child.outerHTML;
120
119
  else if (child instanceof TextNode) return child.textContent;
121
120
  else return child
122
121
  }).join("");
123
122
  }
124
123
  $$(query){return this.querySelectorAll(query)}
125
124
  querySelectorAll(query){
126
125
  const selectors=Query.get(query)
127
126
  return find(selectors,this,new Set())
128
127
  }
129
128
  $(query){return this.querySelector(query)}
130
129
  querySelector(query){
131
130
  const selectors=Query.get(query)
132
131
  return find(selectors,this,new Set(),true)[0] || null
133
132
  }
134
133
  getElementsByClassName(query){ return this.querySelectorAll('.'+query) }
135
134
  getElementsByTagName(query){ return this.querySelectorAll(query) }
136
135
  getElementById(query){ return this.querySelector('#'+query) }
137
136
  get children(){
138
137
  return this.childNodes.filter(child=>{
139
138
  if (!(child instanceof Node)) return false
140
139
  if (child.tagName==='#comment') return false
141
140
  return true
142
141
  });
143
142
  }
144
143
  insertAdjacentElement(position,newElement){
145
144
  if(newElement.tagName==='ROOT' && newElement.childNodes.length>0) newElement=newElement.childNodes[0]
146
145
  const pos=position.toLowerCase();
147
146
  if (pos==="afterbegin") this.childNodes.unshift(newElement);
148
147
  else if (pos==="beforeend") this.childNodes.push(newElement);
149
148
  newElement.parent=this
150
149
  if (!this.parent) return newElement
151
150
  if (pos==="beforebegin") insertBefore(this.parent.childNodes,this.childNodeIndex,newElement)
152
151
  else if (pos==="afterend") this.parent.childNodes.splice(this.childNodeIndex+1,0,newElement);
153
152
  newElement.parent=this.parent
154
153
  return newElement
155
154
  }
156
155
  insertAdjacentHTML(position,html){
157
156
  const newNode=parseHTML(html);
158
157
  newNode.childNodes.reverse().forEach(node=>{
159
158
  this.insertAdjacentElement(position,node);
160
159
  });
161
160
  return newNode
162
161
  }
163
162
  insertAdjacentText(position,text){
164
163
  return this.insertAdjacentElement(position,new TextNode(text));
165
164
  }
166
165
  insert(position,element){
167
166
  const positions=['beforebegin','afterbegin','beforeend','afterend']
168
167
  if(positions[position]) position=positions[position]
169
168
  if(typeof element==='string'){
170
169
  element=element.trim()
171
170
  if(element.startsWith('<') && element.endsWith('>')){
172
171
  return this.insertAdjacentHTML(position,element)
173
172
  }
174
173
  return this.insertAdjacentText(position,element)
175
174
  }
176
175
  return this.insertAdjacentElement(position,element)
177
176
  }
178
177
  set innerHTML(html){
179
178
  const parsed=parseHTML(html);
180
179
  this.childNodes=parsed.childNodes;
181
180
  }
182
181
  set outerHTML(html){
183
182
  const parsed=parseHTML(html);
184
183
  if (!this.parent) return console.log('element has no parent node')
185
184
  const index=this.childIndex
186
185
  if (index!==null) this.parent.childNodes.splice(index,1,...parsed.childNodes);
187
186
  }
188
187
  appendChild(newChild){
189
188
  if (newChild instanceof Node || newChild instanceof TextNode || newChild instanceof SingleNode){
190
189
  if (newChild.parent) newChild.parent.childNodes=newChild.parent.childNodes.filter(child=>child!==newChild);
191
190
  } else if(typeof newChild==='string') newChild=new TextNode(newChild)
192
191
  else return newChild
193
192
  this.childNodes.push(newChild);
194
193
  newChild.parent=this;
195
194
  return newChild;
196
195
  }
197
196
  get textContent(){
198
197
  if (this.childNodes.length===0) return this.nodeName==='#text' ? this.nodeValue : '';
199
198
  return this.childNodes.map(child=>{
200
199
  if(child instanceof SingleNode) return ''
201
200
  if(child instanceof TextNode) return child.nodeValue
202
201
  if(child instanceof Node) return child.textContent;
203
202
  else return child;
204
203
  }).join(" ");
205
204
  }
206
205
  set textContent(value){
207
206
  this.childNodes=[];
208
207
  if (value!==null && value!==undefined){
209
208
  this.childNodes.push(value.toString());
210
209
  }
211
210
  }
211
+ }
212
212
  class Node{
213
213
  constructor(tagName,attributes={},parent=null){
214
214
  this.isSingle=false;
215
215
  this.tagName=tagName;
216
216
  this.attributes=attributes;
217
217
  this.childNodes=[];
218
218
  if (parent!==null) parent.childNodes.push(this)
219
219
  this.parent=parent;
220
220
  this._classList=null;
221
221
  this.__style=null;
222
222
  this._dataset=null
223
223
  }
224
224
  get id(){ return this.attributes.id ? this.attributes.id : null; }
225
225
  set id(newValue){ this.attributes.id=newValue; }
226
226
  get className(){return this.attributes.class || null}
227
227
  get parentNode(){ return this.parent }
228
228
  get ancestors(){
229
229
  if(!this.parent) return []
230
230
  const ancestors=[]
231
231
  let element=this.parent
232
232
  while (element.tagName!=='ROOT'){
233
233
  ancestors.push(element)
234
234
  element=element.parent
235
235
  }
236
236
  return ancestors.reverse()
237
237
  }
238
238
  get childNodeIndex(){
239
239
  if(!this.parent) return null
240
240
  return this.parent.childNodes ? this.parent.childNodes.indexOf(this) : null
241
241
  }
242
242
  get childIndex(){
243
243
  if(!this.parent) return null
244
244
  return this.parent.children ? this.parent.children.indexOf(this) : null
245
245
  }
246
246
  get previousElementSibling(){ return this.prev }
247
247
  get prev(){
248
248
  if (!this.childIndex) return null
249
249
  return this.parent.children[this.childIndex-1]
250
250
  }
251
251
  get nextElementSibling(){ return this.next }
252
252
  get next(){
253
253
  if (!this.childIndex) return null
254
254
  return this.parent.children[this.childIndex+1] || null
255
255
  }
256
256
  get dataset(){
257
257
  if (!this._dataset) this._dataset=getDataset(this);
258
258
  return this._dataset;
259
259
  }
260
260
  get classList(){
261
261
  if (!this._classList) this._classList=new NodeClassList(this);
262
262
  return this._classList;
263
263
  }
264
264
  get style(){
265
265
  if (!this.__style) this.__style=buildStyle(this.attributes)
266
266
  return this.__style
267
267
  }
268
268
  get outerHTML(){
269
269
  const attrs=Object.entries(this.attributes).map(([key,val])=>val.length ? `${key}="${val}"` : key).join(" ");
270
270
  return `<${this.tagName}${attrs ? ' '+attrs : ''}>${this.innerHTML}</${this.tagName}>`;
271
271
  }
272
272
  getAttribute(attrName){ return this.attributes[attrName] || null }
273
273
  setAttribute(attrName,value){ this.attributes[attrName]=value }
274
274
  removeAttribute(attrName){ delete this.attributes[attrName] }
275
275
  remove(){
276
276
  if (!this.parent) return
277
277
  const index=this.childNodeIndex;
278
278
  if (index!==null) this.parent.childNodes.splice(index,1);
279
279
  }
280
280
  get innerHTML(){
281
281
  return this.childNodes.map(child=>{
282
282
  if (child instanceof Node || child instanceof SingleNode) return child.outerHTML;
283
283
  else if (child instanceof TextNode) return child.textContent;
284
284
  else return child
285
285
  }).join("");
286
286
  }
287
287
  $$(query){return this.querySelectorAll(query)}
288
288
  querySelectorAll(query){
289
289
  const selectors=Query.get(query)
290
290
  return find(selectors,this,new Set())
291
291
  }
292
292
  $(query){return this.querySelector(query)}
293
293
  querySelector(query){
294
294
  const selectors=Query.get(query)
295
295
  return find(selectors,this,new Set(),true)[0] || null
296
296
  }
297
297
  getElementsByClassName(query){ return this.querySelectorAll('.'+query) }
298
298
  getElementsByTagName(query){ return this.querySelectorAll(query) }
299
299
  getElementById(query){ return this.querySelector('#'+query) }
300
300
  get children(){
301
301
  return this.childNodes.filter(child=>{
302
302
  if (!(child instanceof Node)) return false
303
303
  if (child.tagName==='#comment') return false
304
304
  return true
305
305
  });
306
306
  }
307
307
  insertAdjacentElement(position,newElement){
308
308
  if(newElement.tagName==='ROOT' && newElement.childNodes.length>0) newElement=newElement.childNodes[0]
309
309
  const pos=position.toLowerCase();
310
310
  if(pos==='afterbegin' || pos==='beforeend'){
311
311
  if (pos==="afterbegin") this.childNodes.unshift(newElement);
312
312
  else if (pos==="beforeend") this.childNodes.push(newElement);
313
313
  newElement.parent=this
314
314
  return newElement
315
315
  }
316
316
  if (!this.parent) throw new Error("Can't insert element to element without parent")
317
317
  if (pos==="beforebegin") insertBefore(this.parent.childNodes,this.childNodeIndex,newElement)
318
318
  else if (pos==="afterend") this.parent.childNodes.splice(this.childNodeIndex+1,0,newElement);
319
319
  newElement.parent=this.parent
320
320
  return newElement
321
321
  }
322
322
  insertAdjacentHTML(position,html){
323
323
  const newNode=parseHTML(html);
324
324
  newNode.childNodes.reverse().forEach(node=>{
325
325
  this.insertAdjacentElement(position,node);
326
326
  });
327
327
  return newNode
328
328
  }
329
329
  insertAdjacentText(position,text){
330
330
  return this.insertAdjacentElement(position,new TextNode(text));
331
331
  }
332
332
  insert(position,element){
333
333
  const positions=['beforebegin','afterbegin','beforeend','afterend']
334
334
  if(positions[position]) position=positions[position]
335
335
  if(typeof element==='string'){
336
336
  element=element.trim()
337
337
  if(element.startsWith('<') && element.endsWith('>')){
338
338
  return this.insertAdjacentHTML(position,element)
339
339
  }
340
340
  return this.insertAdjacentText(position,element)
341
341
  }
342
342
  return this.insertAdjacentElement(position,element)
343
343
  }
344
344
  set innerHTML(html){
345
345
  const parsed=parseHTML(html);
346
346
  this.childNodes=parsed.childNodes;
347
347
  }
348
348
  set outerHTML(html){
349
349
  const parsed=parseHTML(html);
350
350
  if (!this.parent) return console.log('element has no parent node')
351
351
  const index=this.childIndex
352
352
  if (index!==null) this.parent.childNodes.splice(index,1,...parsed.childNodes);
353
353
  }
354
354
  appendChild(newChild){
355
355
  if (newChild instanceof Node || newChild instanceof TextNode || newChild instanceof SingleNode){
356
356
  if (newChild.parent) newChild.parent.childNodes=newChild.parent.childNodes.filter(child=>child!==newChild);
357
357
  } else if(typeof newChild==='string') newChild=new TextNode(newChild)
358
358
  else return newChild
359
359
  this.childNodes.push(newChild);
360
360
  newChild.parent=this;
361
361
  return newChild;
362
362
  }
363
363
  get textContent(){
364
364
  if (this.childNodes.length===0) return this.nodeName==='#text' ? this.nodeValue : '';
365
365
  return this.childNodes.map(child=>{
366
366
  if(child instanceof SingleNode) return ''
367
367
  if(child instanceof TextNode) return child.nodeValue
368
368
  if(child instanceof Node) return child.textContent;
369
369
  else return child;
370
370
  }).join(" ");
371
371
  }
372
372
  set textContent(value){
373
373
  this.childNodes=[];
374
374
  if (value!==null && value!==undefined){
375
375
  this.childNodes.push(value.toString());
376
376
  }
377
377
  }
378
378
  }
379
379
  class SingleNode extends Node{
380
380
  constructor(tagName,attributes={},parent=null){
381
381
  if(attributes['?'] && tagName==='?xml') delete attributes['?']
382
382
  super(tagName,attributes,parent);
383
383
  this.isSingle=true
384
384
  }
385
385
  get outerHTML(){
386
386
  if (this.tagName==="#cdata-section") return `<![CDATA[${this.nodeValue}]]>`;
387
387
  const attrs=Object.entries(this.attributes).map(([key,val])=>val.length ? `${key}="${val}"` : key).join(" ");
388
388
  return `<${this.tagName} ${attrs}${this.tagName==='?xml' ? '?' : ''}>`;
389
389
  }
390
390
  get innerHTML(){ return ""; }
391
391
  set innerHTML(_){ }
392
392
  $(_){return null}
393
393
  $$(_){return []}
394
394
  querySelectorAll(_){ return []; }
395
395
  querySelector(_){ return null; }
396
396
  getElementsByClassName(_){ return []; }
397
397
  getElementsByTagName(_){ return []; }
398
398
  getElementById(_){ return null; }
399
399
  get children(){ return []; }
400
400
  insertAdjacentElement(_,__){ }
401
401
  insertAdjacentHTML(_,__){ }
402
402
  insertAdjacentText(_,__){ }
403
403
  appendChild(_){ }
404
404
  insert(_,__){ }
405
405
  get textContent(){ return ""; }
406
406
  set textContent(_){ }
407
407
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "als-document",
3
- "version": "1.0.0-beta",
3
+ "version": "1.0.1-beta",
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/node/node.js CHANGED
@@ -117,10 +117,13 @@ class Node {
117
117
  insertAdjacentElement(position, newElement) {
118
118
  if(newElement.tagName === 'ROOT' && newElement.childNodes.length > 0) newElement = newElement.childNodes[0]
119
119
  const pos = position.toLowerCase();
120
- if (pos === "afterbegin") this.childNodes.unshift(newElement);
121
- else if (pos === "beforeend") this.childNodes.push(newElement);
122
- newElement.parent = this
123
- if (!this.parent) return newElement
120
+ if(pos === 'afterbegin' || pos === 'beforeend') {
121
+ if (pos === "afterbegin") this.childNodes.unshift(newElement);
122
+ else if (pos === "beforeend") this.childNodes.push(newElement);
123
+ newElement.parent = this
124
+ return newElement
125
+ }
126
+ if (!this.parent) throw new Error("Can't insert element to element without parent")
124
127
  if (pos === "beforebegin") insertBefore(this.parent.childNodes, this.childNodeIndex, newElement)
125
128
  else if (pos === "afterend") this.parent.childNodes.splice(this.childNodeIndex + 1, 0, newElement);
126
129
  newElement.parent = this.parent