@midscene/shared 0.12.4 → 0.12.5-beta-20250306111616.0
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/dist/es/{constants.js → constants/index.js} +4 -5
- package/dist/es/extractor/client-extractor.js +161 -0
- package/dist/es/extractor/constants.js +10 -0
- package/dist/es/extractor/debug.js +9 -0
- package/dist/es/extractor/dom-util.js +73 -0
- package/dist/es/extractor/index.js +14 -0
- package/dist/es/extractor/tree.js +126 -0
- package/dist/es/extractor/util.js +344 -0
- package/dist/es/extractor/web-extractor.js +317 -0
- package/dist/es/img/box-select.js +187 -0
- package/dist/es/img/draw-box.js +43 -0
- package/dist/es/img/get-jimp.js +11 -0
- package/dist/es/img/index.js +34 -0
- package/dist/es/img/info.js +50 -0
- package/dist/es/img/transform.js +128 -0
- package/dist/es/index.js +0 -1
- package/dist/es/{fs.js → node/fs.js} +22 -5
- package/dist/es/types/index.js +5 -0
- package/dist/es/us-keyboard-layout.js +10 -11
- package/dist/es/utils.js +10 -569
- package/dist/lib/constants/index.js +20 -0
- package/dist/lib/extractor/client-extractor.js +161 -0
- package/dist/lib/extractor/constants.js +10 -0
- package/dist/lib/extractor/debug.js +9 -0
- package/dist/lib/extractor/dom-util.js +73 -0
- package/dist/lib/extractor/index.js +14 -0
- package/dist/lib/extractor/tree.js +126 -0
- package/dist/lib/extractor/util.js +344 -0
- package/dist/lib/extractor/web-extractor.js +317 -0
- package/dist/lib/img/box-select.js +187 -0
- package/dist/lib/img/draw-box.js +43 -0
- package/dist/lib/img/get-jimp.js +11 -0
- package/dist/lib/img/index.js +34 -0
- package/dist/lib/img/info.js +50 -0
- package/dist/lib/img/transform.js +128 -0
- package/dist/lib/index.js +3 -25
- package/dist/lib/node/fs.js +62 -0
- package/dist/lib/types/index.js +5 -0
- package/dist/lib/us-keyboard-layout.js +12 -41
- package/dist/lib/utils.js +12 -578
- package/dist/types/constants/index.d.ts +12 -0
- package/dist/types/extractor/client-extractor.d.ts +2 -0
- package/dist/types/extractor/constants.d.ts +1 -0
- package/dist/types/extractor/debug.d.ts +1 -0
- package/dist/types/extractor/dom-util.d.ts +5 -0
- package/dist/types/extractor/index.d.ts +29 -0
- package/dist/types/extractor/tree.d.ts +9 -0
- package/dist/types/extractor/util.d.ts +40 -0
- package/dist/types/extractor/web-extractor.d.ts +14 -0
- package/dist/types/img/box-select.d.ts +31 -0
- package/dist/types/img/draw-box.d.ts +15 -0
- package/dist/types/img/get-jimp.d.ts +2 -0
- package/dist/types/img/index.d.ts +4 -0
- package/dist/types/img/info.d.ts +40 -0
- package/dist/types/img/transform.d.ts +68 -0
- package/dist/types/index.d.ts +1 -2
- package/dist/{lib → types/node}/fs.d.ts +4 -4
- package/dist/{lib/index-305e7a7e.d.ts → types/types/index.d.ts} +6 -9
- package/dist/types/us-keyboard-layout.d.ts +32 -0
- package/dist/types/utils.d.ts +11 -0
- package/package.json +39 -39
- package/src/img/box-select.ts +17 -11
- package/src/img/draw-box.ts +5 -5
- package/src/img/get-jimp.ts +3 -0
- package/src/{fs/index.ts → node/fs.ts} +20 -0
- package/src/utils.ts +13 -0
- package/dist/browser/constants.d.ts +0 -14
- package/dist/browser/constants.js +0 -42
- package/dist/browser/extractor-debug.d.ts +0 -2
- package/dist/browser/extractor-debug.js +0 -1269
- package/dist/browser/extractor.d.ts +0 -47
- package/dist/browser/extractor.js +0 -1557
- package/dist/browser/fs.d.ts +0 -14
- package/dist/browser/fs.js +0 -66
- package/dist/browser/img.d.ts +0 -152
- package/dist/browser/img.js +0 -483
- package/dist/browser/index-305e7a7e.d.ts +0 -32
- package/dist/browser/index.d.ts +0 -3
- package/dist/browser/index.js +0 -26
- package/dist/browser/us-keyboard-layout.d.ts +0 -34
- package/dist/browser/us-keyboard-layout.js +0 -456
- package/dist/browser/utils.d.ts +0 -5
- package/dist/browser/utils.js +0 -611
- package/dist/es/constants.d.ts +0 -14
- package/dist/es/extractor-debug.d.ts +0 -2
- package/dist/es/extractor-debug.js +0 -1267
- package/dist/es/extractor.d.ts +0 -47
- package/dist/es/extractor.js +0 -1546
- package/dist/es/fs.d.ts +0 -14
- package/dist/es/img.d.ts +0 -152
- package/dist/es/img.js +0 -451
- package/dist/es/index-305e7a7e.d.ts +0 -32
- package/dist/es/index.d.ts +0 -3
- package/dist/es/us-keyboard-layout.d.ts +0 -34
- package/dist/es/utils.d.ts +0 -5
- package/dist/lib/constants.d.ts +0 -14
- package/dist/lib/constants.js +0 -50
- package/dist/lib/extractor-debug.d.ts +0 -2
- package/dist/lib/extractor-debug.js +0 -1261
- package/dist/lib/extractor.d.ts +0 -47
- package/dist/lib/extractor.js +0 -1559
- package/dist/lib/fs.js +0 -71
- package/dist/lib/img.d.ts +0 -152
- package/dist/lib/img.js +0 -501
- package/dist/lib/index.d.ts +0 -3
- package/dist/lib/us-keyboard-layout.d.ts +0 -34
- package/dist/lib/utils.d.ts +0 -5
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
var CONTAINER_MINI_WIDTH = 3;
|
|
1
|
+
const TEXT_SIZE_THRESHOLD = 9;
|
|
2
|
+
const TEXT_MAX_SIZE = 40;
|
|
3
|
+
const CONTAINER_MINI_HEIGHT = 3;
|
|
4
|
+
const CONTAINER_MINI_WIDTH = 3;
|
|
6
5
|
var NodeType = /* @__PURE__ */ ((NodeType2) => {
|
|
7
6
|
NodeType2["CONTAINER"] = "CONTAINER Node";
|
|
8
7
|
NodeType2["FORM_ITEM"] = "FORM_ITEM Node";
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { NodeType } from "./constants";
|
|
2
|
+
import { midsceneGenerateHash } from "./util";
|
|
3
|
+
function getNodeAttributes(node) {
|
|
4
|
+
const attrs = {};
|
|
5
|
+
if (node && node.nodeType === 1) {
|
|
6
|
+
const element = node;
|
|
7
|
+
for (let i = 0; i < element.attributes.length; i++) {
|
|
8
|
+
const attr = element.attributes[i];
|
|
9
|
+
attrs[attr.nodeName] = attr.nodeValue ?? "";
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
return attrs;
|
|
13
|
+
}
|
|
14
|
+
function getRect(attributes) {
|
|
15
|
+
const x = Math.round(Number.parseFloat(attributes.x ?? "0"));
|
|
16
|
+
const y = Math.round(Number.parseFloat(attributes.y ?? "0"));
|
|
17
|
+
const width = Math.round(Number.parseFloat(attributes.width ?? "0"));
|
|
18
|
+
const height = Math.round(Number.parseFloat(attributes.height ?? "0"));
|
|
19
|
+
return {
|
|
20
|
+
left: Math.max(0, Math.floor(x)),
|
|
21
|
+
top: Math.max(0, Math.floor(y)),
|
|
22
|
+
width: Math.max(0, width),
|
|
23
|
+
height: Math.max(0, height)
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function validTextNodeContent(node) {
|
|
27
|
+
if (node.nodeType === 3) {
|
|
28
|
+
return node.nodeValue?.trim() || "";
|
|
29
|
+
}
|
|
30
|
+
return "";
|
|
31
|
+
}
|
|
32
|
+
function getXPathForElement(element) {
|
|
33
|
+
if (element.nodeType !== 1) {
|
|
34
|
+
return "";
|
|
35
|
+
}
|
|
36
|
+
const getIndex = (sib, name) => {
|
|
37
|
+
let count = 1;
|
|
38
|
+
for (let cur = sib.previousSibling; cur; cur = cur.previousSibling) {
|
|
39
|
+
if (cur.nodeType === 1 && cur.nodeName === name) {
|
|
40
|
+
count++;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return count;
|
|
44
|
+
};
|
|
45
|
+
const buildAttributePart = (elem) => {
|
|
46
|
+
const attributes = ["id", "resource-id", "content-desc", "class"];
|
|
47
|
+
for (const attr of attributes) {
|
|
48
|
+
if (elem.hasAttribute(attr)) {
|
|
49
|
+
const value = elem.getAttribute(attr);
|
|
50
|
+
if (value && value.trim() !== "") {
|
|
51
|
+
return `[@${attr}="${value}"]`;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return "";
|
|
56
|
+
};
|
|
57
|
+
const getPath = (node, path = "") => {
|
|
58
|
+
if (node.parentNode) {
|
|
59
|
+
path = getPath(node.parentNode, path);
|
|
60
|
+
}
|
|
61
|
+
if (node.nodeType === 1) {
|
|
62
|
+
const elem = node;
|
|
63
|
+
const tagName = elem.nodeName.toLowerCase();
|
|
64
|
+
let part = `/${tagName}`;
|
|
65
|
+
const attributePart = buildAttributePart(elem);
|
|
66
|
+
if (attributePart) {
|
|
67
|
+
part += attributePart;
|
|
68
|
+
} else {
|
|
69
|
+
const index = getIndex(node, node.nodeName);
|
|
70
|
+
if (index > 1) {
|
|
71
|
+
part += `[${index}]`;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
path += part;
|
|
75
|
+
}
|
|
76
|
+
return path;
|
|
77
|
+
};
|
|
78
|
+
return getPath(element);
|
|
79
|
+
}
|
|
80
|
+
function extractTextWithPosition(initNode) {
|
|
81
|
+
const elementInfoArray = [];
|
|
82
|
+
let nodeIndex = 1;
|
|
83
|
+
function dfs(node, parentNode = null) {
|
|
84
|
+
if (!node) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const currentNodeDes = { node, children: [] };
|
|
88
|
+
if (parentNode) {
|
|
89
|
+
parentNode.children.push(currentNodeDes);
|
|
90
|
+
}
|
|
91
|
+
collectElementInfo(node);
|
|
92
|
+
if (node.childNodes && node.childNodes.length > 0) {
|
|
93
|
+
for (let i = 0; i < node.childNodes.length; i++) {
|
|
94
|
+
dfs(node.childNodes[i], currentNodeDes);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function collectElementInfo(node) {
|
|
99
|
+
const attributes = getNodeAttributes(node);
|
|
100
|
+
const rect = getRect(attributes);
|
|
101
|
+
const nodeHashId = midsceneGenerateHash(null, attributes.placeholder, rect);
|
|
102
|
+
const text = validTextNodeContent(node);
|
|
103
|
+
let nodeType;
|
|
104
|
+
switch (node.nodeName.toUpperCase()) {
|
|
105
|
+
case "TEXT":
|
|
106
|
+
nodeType = NodeType.TEXT;
|
|
107
|
+
break;
|
|
108
|
+
case "IMAGE":
|
|
109
|
+
nodeType = NodeType.IMG;
|
|
110
|
+
break;
|
|
111
|
+
case "BUTTON":
|
|
112
|
+
nodeType = NodeType.BUTTON;
|
|
113
|
+
break;
|
|
114
|
+
case "SEARCHINPUT":
|
|
115
|
+
case "TEXTINPUT":
|
|
116
|
+
case "INPUT":
|
|
117
|
+
nodeType = NodeType.FORM_ITEM;
|
|
118
|
+
break;
|
|
119
|
+
case "NAV":
|
|
120
|
+
case "LIST":
|
|
121
|
+
case "CELL":
|
|
122
|
+
nodeType = NodeType.CONTAINER;
|
|
123
|
+
break;
|
|
124
|
+
default:
|
|
125
|
+
if (attributes.id === "android:id/input" || attributes.id === "android:id/inputArea") {
|
|
126
|
+
nodeType = NodeType.FORM_ITEM;
|
|
127
|
+
} else {
|
|
128
|
+
nodeType = NodeType.CONTAINER;
|
|
129
|
+
}
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
const xpath = getXPathForElement(node);
|
|
133
|
+
const elementInfo = {
|
|
134
|
+
id: nodeHashId,
|
|
135
|
+
indexId: nodeIndex++,
|
|
136
|
+
nodeHashId,
|
|
137
|
+
locator: xpath,
|
|
138
|
+
attributes: {
|
|
139
|
+
nodeType,
|
|
140
|
+
...attributes
|
|
141
|
+
},
|
|
142
|
+
content: text,
|
|
143
|
+
rect,
|
|
144
|
+
center: [
|
|
145
|
+
Math.round(rect.left + rect.width / 2),
|
|
146
|
+
Math.round(rect.top + rect.height / 2)
|
|
147
|
+
],
|
|
148
|
+
nodeType
|
|
149
|
+
};
|
|
150
|
+
if (elementInfo.nodeType !== NodeType.CONTAINER) {
|
|
151
|
+
elementInfoArray.push(elementInfo);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const rootNode = initNode;
|
|
155
|
+
const rootDescriptor = { node: rootNode, children: [] };
|
|
156
|
+
dfs(rootNode, rootDescriptor);
|
|
157
|
+
return elementInfoArray;
|
|
158
|
+
}
|
|
159
|
+
export {
|
|
160
|
+
extractTextWithPosition
|
|
161
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { webExtractTextWithPosition } from ".";
|
|
2
|
+
import {
|
|
3
|
+
setExtractTextWithPositionOnWindow,
|
|
4
|
+
setMidsceneVisibleRectOnWindow
|
|
5
|
+
} from "./util";
|
|
6
|
+
console.log(webExtractTextWithPosition(document.body, true));
|
|
7
|
+
console.log(JSON.stringify(webExtractTextWithPosition(document.body, true)));
|
|
8
|
+
setExtractTextWithPositionOnWindow();
|
|
9
|
+
setMidsceneVisibleRectOnWindow();
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
function isFormElement(node) {
|
|
2
|
+
return node instanceof HTMLElement && (node.tagName.toLowerCase() === "input" || node.tagName.toLowerCase() === "textarea" || node.tagName.toLowerCase() === "select" || node.tagName.toLowerCase() === "option");
|
|
3
|
+
}
|
|
4
|
+
function isButtonElement(node) {
|
|
5
|
+
return node instanceof HTMLElement && node.tagName.toLowerCase() === "button";
|
|
6
|
+
}
|
|
7
|
+
function isImgElement(node) {
|
|
8
|
+
if (!includeBaseElement(node) && node instanceof Element) {
|
|
9
|
+
const computedStyle = window.getComputedStyle(node);
|
|
10
|
+
const backgroundImage = computedStyle.getPropertyValue("background-image");
|
|
11
|
+
if (backgroundImage !== "none") {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
if (isIconfont(node)) {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
return node instanceof HTMLElement && node.tagName.toLowerCase() === "img" || node instanceof SVGElement && node.tagName.toLowerCase() === "svg";
|
|
19
|
+
}
|
|
20
|
+
function isIconfont(node) {
|
|
21
|
+
if (node instanceof Element) {
|
|
22
|
+
const computedStyle = window.getComputedStyle(node);
|
|
23
|
+
const fontFamilyValue = computedStyle.fontFamily || "";
|
|
24
|
+
return fontFamilyValue.toLowerCase().indexOf("iconfont") >= 0;
|
|
25
|
+
}
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
function isTextElement(node) {
|
|
29
|
+
return node.nodeName.toLowerCase() === "#text" && !isIconfont(node);
|
|
30
|
+
}
|
|
31
|
+
function isContainerElement(node) {
|
|
32
|
+
if (!(node instanceof HTMLElement))
|
|
33
|
+
return false;
|
|
34
|
+
if (includeBaseElement(node)) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
const computedStyle = window.getComputedStyle(node);
|
|
38
|
+
const backgroundColor = computedStyle.getPropertyValue("background-color");
|
|
39
|
+
if (backgroundColor) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
function includeBaseElement(node) {
|
|
45
|
+
if (!(node instanceof HTMLElement))
|
|
46
|
+
return false;
|
|
47
|
+
if (node.innerText) {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
const includeList = [
|
|
51
|
+
"svg",
|
|
52
|
+
"button",
|
|
53
|
+
"input",
|
|
54
|
+
"textarea",
|
|
55
|
+
"select",
|
|
56
|
+
"option",
|
|
57
|
+
"img"
|
|
58
|
+
];
|
|
59
|
+
for (const tagName of includeList) {
|
|
60
|
+
const element = node.querySelectorAll(tagName);
|
|
61
|
+
if (element.length > 0) {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
export {
|
|
68
|
+
isButtonElement,
|
|
69
|
+
isContainerElement,
|
|
70
|
+
isFormElement,
|
|
71
|
+
isImgElement,
|
|
72
|
+
isTextElement
|
|
73
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { descriptionOfTree, traverseTree, treeToList } from "./tree";
|
|
2
|
+
import { extractTextWithPosition } from "./web-extractor";
|
|
3
|
+
import { extractTextWithPosition as extractTextWithPosition2 } from "./client-extractor";
|
|
4
|
+
import { extractTreeNode } from "./web-extractor";
|
|
5
|
+
import { extractTreeNodeAsString } from "./web-extractor";
|
|
6
|
+
export {
|
|
7
|
+
extractTextWithPosition2 as clientExtractTextWithPosition,
|
|
8
|
+
descriptionOfTree,
|
|
9
|
+
traverseTree,
|
|
10
|
+
treeToList,
|
|
11
|
+
extractTreeNode as webExtractNodeTree,
|
|
12
|
+
extractTreeNodeAsString as webExtractNodeTreeAsString,
|
|
13
|
+
extractTextWithPosition as webExtractTextWithPosition
|
|
14
|
+
};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
function truncateText(text, maxLength = 150) {
|
|
2
|
+
if (typeof text === "undefined") {
|
|
3
|
+
return "";
|
|
4
|
+
}
|
|
5
|
+
if (typeof text === "object") {
|
|
6
|
+
text = JSON.stringify(text);
|
|
7
|
+
}
|
|
8
|
+
if (typeof text === "number") {
|
|
9
|
+
return text.toString();
|
|
10
|
+
}
|
|
11
|
+
if (typeof text === "string" && text.length > maxLength) {
|
|
12
|
+
return `${text.slice(0, maxLength)}...`;
|
|
13
|
+
}
|
|
14
|
+
if (typeof text === "string") {
|
|
15
|
+
return text.trim();
|
|
16
|
+
}
|
|
17
|
+
return "";
|
|
18
|
+
}
|
|
19
|
+
function trimAttributes(attributes, truncateTextLength) {
|
|
20
|
+
const tailorAttributes = Object.keys(attributes).reduce(
|
|
21
|
+
(res, currentKey) => {
|
|
22
|
+
const attributeVal = attributes[currentKey];
|
|
23
|
+
if (currentKey === "style" || currentKey === "src" || currentKey === "htmlTagName" || currentKey === "nodeType") {
|
|
24
|
+
return res;
|
|
25
|
+
}
|
|
26
|
+
res[currentKey] = truncateText(attributeVal, truncateTextLength);
|
|
27
|
+
return res;
|
|
28
|
+
},
|
|
29
|
+
{}
|
|
30
|
+
);
|
|
31
|
+
return tailorAttributes;
|
|
32
|
+
}
|
|
33
|
+
const nodeSizeThreshold = 4;
|
|
34
|
+
function descriptionOfTree(tree, truncateTextLength, filterNonTextContent = false) {
|
|
35
|
+
const attributesString = (kv) => {
|
|
36
|
+
return Object.entries(kv).map(
|
|
37
|
+
([key, value]) => `${key}="${truncateText(value, truncateTextLength)}"`
|
|
38
|
+
).join(" ");
|
|
39
|
+
};
|
|
40
|
+
function buildContentTree(node, indent = 0) {
|
|
41
|
+
let before = "";
|
|
42
|
+
let contentWithIndent = "";
|
|
43
|
+
let after = "";
|
|
44
|
+
let emptyNode = true;
|
|
45
|
+
const indentStr = " ".repeat(indent);
|
|
46
|
+
let children = "";
|
|
47
|
+
for (let i = 0; i < (node.children || []).length; i++) {
|
|
48
|
+
const childContent = buildContentTree(node.children[i], indent + 1);
|
|
49
|
+
if (childContent) {
|
|
50
|
+
children += `
|
|
51
|
+
${childContent}`;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (node.node && node.node.rect.width > nodeSizeThreshold && node.node.rect.height > nodeSizeThreshold && (!filterNonTextContent || filterNonTextContent && node.node.content)) {
|
|
55
|
+
emptyNode = false;
|
|
56
|
+
let nodeTypeString;
|
|
57
|
+
if (node.node.attributes?.htmlTagName) {
|
|
58
|
+
nodeTypeString = node.node.attributes.htmlTagName.replace(/[<>]/g, "");
|
|
59
|
+
} else {
|
|
60
|
+
nodeTypeString = node.node.attributes.nodeType.replace(/\sNode$/, "").toLowerCase();
|
|
61
|
+
}
|
|
62
|
+
const markerId = node.node.indexId;
|
|
63
|
+
const markerIdString = markerId ? `markerId="${markerId}"` : "";
|
|
64
|
+
const rectAttribute = node.node.rect ? {
|
|
65
|
+
left: node.node.rect.left,
|
|
66
|
+
top: node.node.rect.top,
|
|
67
|
+
width: node.node.rect.width,
|
|
68
|
+
height: node.node.rect.height
|
|
69
|
+
} : {};
|
|
70
|
+
before = `<${nodeTypeString} id="${node.node.id}" ${markerIdString} ${attributesString(trimAttributes(node.node.attributes || {}, truncateTextLength))} ${attributesString(rectAttribute)}>`;
|
|
71
|
+
const content = truncateText(node.node.content, truncateTextLength);
|
|
72
|
+
contentWithIndent = content ? `
|
|
73
|
+
${indentStr} ${content}` : "";
|
|
74
|
+
after = `</${nodeTypeString}>`;
|
|
75
|
+
} else if (!filterNonTextContent) {
|
|
76
|
+
if (!children.trim().startsWith("<>")) {
|
|
77
|
+
before = "<>";
|
|
78
|
+
contentWithIndent = "";
|
|
79
|
+
after = "</>";
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (emptyNode && !children.trim()) {
|
|
83
|
+
return "";
|
|
84
|
+
}
|
|
85
|
+
const result2 = `${indentStr}${before}${contentWithIndent}${children}
|
|
86
|
+
${indentStr}${after}`;
|
|
87
|
+
if (result2.trim()) {
|
|
88
|
+
return result2;
|
|
89
|
+
}
|
|
90
|
+
return "";
|
|
91
|
+
}
|
|
92
|
+
const result = buildContentTree(tree);
|
|
93
|
+
return result.replace(/^\s*\n/gm, "");
|
|
94
|
+
}
|
|
95
|
+
function treeToList(tree) {
|
|
96
|
+
const result = [];
|
|
97
|
+
function dfs(node) {
|
|
98
|
+
if (node.node) {
|
|
99
|
+
result.push(node.node);
|
|
100
|
+
}
|
|
101
|
+
for (const child of node.children) {
|
|
102
|
+
dfs(child);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
dfs(tree);
|
|
106
|
+
return result;
|
|
107
|
+
}
|
|
108
|
+
function traverseTree(tree, onNode) {
|
|
109
|
+
function dfs(node) {
|
|
110
|
+
if (node.node) {
|
|
111
|
+
node.node = onNode(node.node);
|
|
112
|
+
}
|
|
113
|
+
for (const child of node.children) {
|
|
114
|
+
dfs(child);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
dfs(tree);
|
|
118
|
+
return tree;
|
|
119
|
+
}
|
|
120
|
+
export {
|
|
121
|
+
descriptionOfTree,
|
|
122
|
+
traverseTree,
|
|
123
|
+
treeToList,
|
|
124
|
+
trimAttributes,
|
|
125
|
+
truncateText
|
|
126
|
+
};
|