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/document.js +4 -3
- package/index.js +4 -3
- package/index.mjs +4 -3
- package/package.json +1 -1
- package/src/build.js +2 -0
- package/src/node/node.js +29 -8
- package/src/parse/parser.js +27 -5
- package/src/query/check-element.js +1 -1
- package/tests/index.html +1 -1
package/package.json
CHANGED
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
|
|
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
|
|
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.
|
|
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.
|
|
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}
|
|
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.
|
|
108
|
-
else if (pos === "afterend") this.parent.childNodes.splice(this.
|
|
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
|
-
|
|
132
|
+
newNode.childNodes.reverse().forEach(node => {
|
|
133
|
+
this.insertAdjacentElement(position, node);
|
|
134
|
+
});
|
|
135
|
+
return newNode
|
|
115
136
|
}
|
|
116
137
|
|
|
117
138
|
insertAdjacentText(position, text) {
|
package/src/parse/parser.js
CHANGED
|
@@ -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
|
|
32
|
-
stack[stack.length - 1].childNodes.push(new TextNode(currentText
|
|
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
|
|
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="
|
|
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>
|