als-document 1.0.2-alpha → 1.0.4-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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "als-document",
3
- "version": "1.0.2-alpha",
3
+ "version": "1.0.4-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,7 +2,9 @@ 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
5
6
  content = content.replace(/^(?<!\\)\/\/.*$|(?<=\s)(?<!\\)\/\/.*$/gm, '') // remove comments
7
+ // content = content.replace(/\;\s*?$/gm,'') // remove ; at end of line
6
8
  content = content.replace(/\[\s*?\n\s*/gm, '[') //
7
9
  content = content.replace(/\s*?\]/gm, ']') //
8
10
  content = content.replace(/\s*?$/gm, '') // remove space at end of line
package/src/node/node.js CHANGED
@@ -1,3 +1,9 @@
1
+ function insertBefore(arr, index, newItem) {
2
+ const existingIndex = arr.indexOf(newItem);
3
+ if (existingIndex !== -1) arr.splice(existingIndex, 1);
4
+ arr.splice(index, 0, newItem);
5
+ }
6
+
1
7
  class Node {
2
8
  constructor(tagName, attributes = {}, parent = null) {
3
9
  this.isSingle = false;
@@ -11,10 +17,12 @@ class Node {
11
17
  this._dataset = null
12
18
  }
13
19
 
14
- get id() { return this.attributes.id || null; }
20
+ get id() { return this.attributes.id ? this.attributes.id : null; }
21
+ set id(newValue) { this.attributes.id = newValue; }
15
22
  get className() {return this.attributes.class || null}
16
23
  get parentNode() { return this.parent }
17
24
  get ancestors() {
25
+ if(!this.parent) return []
18
26
  const ancestors = []
19
27
  let element = this.parent
20
28
  while (element.tagName !== 'ROOT') {
@@ -24,17 +32,25 @@ class Node {
24
32
  return ancestors.reverse()
25
33
  }
26
34
 
27
- get childIndex() { return this.parent.childNodes ? this.parent.childNodes.indexOf(this) : null }
35
+ get childNodeIndex() {
36
+ if(!this.parent) return null
37
+ return this.parent.childNodes ? this.parent.childNodes.indexOf(this) : null
38
+ }
39
+
40
+ get childIndex() {
41
+ if(!this.parent) return null
42
+ return this.parent.children ? this.parent.children.indexOf(this) : null
43
+ }
28
44
  get previousElementSibling() { return this.prev }
29
45
  get prev() {
30
46
  if (!this.childIndex) return null // if no index or index == 0
31
- return this.parent.childNodes[this.childIndex - 1]
47
+ return this.parent.children[this.childIndex - 1]
32
48
  }
33
49
 
34
50
  get nextElementSibling() { return this.next }
35
51
  get next() {
36
52
  if (!this.childIndex) return null
37
- return this.parent.childNodes[this.childIndex + 1] || null
53
+ return this.parent.children[this.childIndex + 1] || null
38
54
  }
39
55
 
40
56
  get dataset() {
@@ -54,7 +70,7 @@ class Node {
54
70
 
55
71
  get outerHTML() {
56
72
  const attrs = Object.entries(this.attributes).map(([key, val]) => `${key}="${val}"`).join(" ");
57
- return `<${this.tagName} ${attrs}>${this.innerHTML}</${this.tagName}>`;
73
+ return `<${this.tagName}${attrs ? ' '+attrs : ''}>${this.innerHTML}</${this.tagName}>`;
58
74
  }
59
75
 
60
76
  getAttribute(attrName) { return this.attributes[attrName] || null }
@@ -103,15 +119,20 @@ class Node {
103
119
  const pos = position.toLowerCase();
104
120
  if (pos === "afterbegin") this.childNodes.unshift(newElement);
105
121
  else if (pos === "beforeend") this.childNodes.push(newElement);
122
+ newElement.parent = this
106
123
  if (!this.parent) return newElement
107
- if (pos === "beforebegin") this.parent.childNodes.unshift(newElement);
108
- else if (pos === "afterend") this.parent.childNodes.splice(this.childIndex + 1, 0, newElement);
124
+ if (pos === "beforebegin") insertBefore(this.parent.childNodes, this.childNodeIndex, newElement)
125
+ else if (pos === "afterend") this.parent.childNodes.splice(this.childNodeIndex + 1, 0, newElement);
126
+ newElement.parent = this.parent
109
127
  return newElement
110
128
  }
111
129
 
112
130
  insertAdjacentHTML(position, html) {
113
131
  const newNode = parseHTML(html);
114
- return this.insertAdjacentElement(position, newNode);
132
+ newNode.childNodes.reverse().forEach(node => {
133
+ this.insertAdjacentElement(position, node);
134
+ });
135
+ return newNode
115
136
  }
116
137
 
117
138
  insertAdjacentText(position, text) {
@@ -2,6 +2,27 @@ function parseHTML(html) {
2
2
  const root = new Node("ROOT");
3
3
  const stack = [root];
4
4
  let currentText = "", i = 0;
5
+ let max = 0
6
+
7
+ function parseScript() {
8
+ if (!html.startsWith("<script", i)) return false;
9
+ const openTagEnd = html.indexOf(">", i);
10
+ if (openTagEnd === -1) return false;
11
+
12
+ const attributesString = html.substring(i + 7, openTagEnd).trim(); // +7 чтобы пропустить "<script"
13
+ const attributes = parseAttributes(attributesString); // Извлечь атрибуты
14
+
15
+ let closeTagStart = html.indexOf("</script>", openTagEnd); // Находим закрывающий тег
16
+ if (closeTagStart === -1) return false; // Если нет закрывающего тега, возвращаем ошибку
17
+ const content = html.substring(openTagEnd + 1, closeTagStart); // Получить содержимое тега
18
+
19
+ const scriptNode = new Node('script', attributes, stack[stack.length - 1]); // Создаем узел
20
+ if(content.length > 0) scriptNode.childNodes.push(content);
21
+
22
+ // Переместить указатель i к концу закрывающего тега
23
+ i = closeTagStart + 9; // +9 чтобы пропустить "</script>"
24
+ return true;
25
+ }
5
26
 
6
27
  function parseSpecial(startStr, endStr, n1, n2, tag) {
7
28
  if (!html.startsWith(startStr, i)) return false
@@ -13,8 +34,10 @@ function parseHTML(html) {
13
34
  }
14
35
 
15
36
  while (i < html.length) {
37
+ if(i >= max) max = i;
38
+ else break;
39
+ if (parseScript()) continue
16
40
  if (parseSpecial("<!--", "-->", 4, 3, '#comment')) continue
17
- if (parseSpecial("<script", "</script>", 8, 9, 'script')) continue
18
41
  if (parseSpecial("<style", "</style>", 7, 8, 'style')) continue
19
42
 
20
43
  if (html.startsWith("<![CDATA[", i)) {
@@ -28,8 +51,8 @@ function parseHTML(html) {
28
51
  }
29
52
 
30
53
  if (html.startsWith("<", i)) {
31
- if (currentText.trim()) {
32
- stack[stack.length - 1].childNodes.push(new TextNode(currentText.trim()));
54
+ if (currentText) {
55
+ stack[stack.length - 1].childNodes.push(new TextNode(currentText));
33
56
  currentText = "";
34
57
  }
35
58
 
@@ -52,7 +75,6 @@ function parseHTML(html) {
52
75
  }
53
76
 
54
77
  const tagContent = html.substring(i + 1, tagEnd);
55
-
56
78
  if (tagContent.startsWith("/")) stack.pop(); // It is close tag
57
79
  else { // It is open tag
58
80
  let isSelfClosing = tagContent.endsWith('/');
@@ -69,6 +91,6 @@ function parseHTML(html) {
69
91
  i++;
70
92
  }
71
93
  }
72
- if (currentText.trim()) stack[stack.length - 1].childNodes.push(new TextNode(currentText.trim()));
94
+ if (currentText.trim()) stack[stack.length - 1].childNodes.push(new TextNode(currentText));
73
95
  return root;
74
96
  }
@@ -1,7 +1,7 @@
1
1
  function checkElement(el,selector) {
2
2
  if(selector == undefined) return true
3
3
  if(el == null) return false
4
- let {tag,classList,attributes,id,prev,ancestors,parents,prevAny} = selector
4
+ let {tag,classList,attribs:attributes,id,prev,ancestors,parents,prevAny} = selector
5
5
  if(typeof el === 'string') return false
6
6
  if(id !== undefined && el.id === null) return false
7
7
  if(id && id !== el.id) return false
package/tests/index.html CHANGED
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Document</title>
7
7
  <script src="/node_modules/als-simple-test/test.js"></script>
8
- <script src="/document.js"></script>
8
+ <script src="../document.js"></script>
9
9
  <script src="./data/html1.js"></script>
10
10
  <!-- <script src="./data/html2.js"></script> -->
11
11
  <script src="./data/svg.js"></script>