lk-text-select-highlight 1.0.1 → 1.0.3
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/README-cn.md +6 -4
- package/README.md +4 -2
- package/index.js +36 -15
- package/package.json +1 -1
- package/test_server.cjs +43 -0
- package/test_uuid_attr.html +138 -0
- package/types/index.d.ts +2 -2
package/README-cn.md
CHANGED
|
@@ -61,13 +61,15 @@ document.addEventListener('mouseup', () => {
|
|
|
61
61
|
|
|
62
62
|
移除所有现有的高亮。
|
|
63
63
|
|
|
64
|
-
### highlighter.
|
|
64
|
+
### highlighter.getHighlights()
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
返回所有当前高亮的数组。每个高亮对象包含:
|
|
67
|
+
- `uuid`: 高亮元素的唯一标识符
|
|
68
|
+
- `text`: 高亮的文本内容
|
|
67
69
|
|
|
68
|
-
### highlighter.
|
|
70
|
+
### highlighter.removeHighlight(highlight)
|
|
69
71
|
|
|
70
|
-
|
|
72
|
+
移除指定的高亮对象。高亮对象可以从 getHighlights() 方法获取。该方法使用UUID来定位并移除相应的高亮元素。
|
|
71
73
|
|
|
72
74
|
## 配置选项详解
|
|
73
75
|
|
package/README.md
CHANGED
|
@@ -63,11 +63,13 @@ Removes all existing highlights.
|
|
|
63
63
|
|
|
64
64
|
### highlighter.getHighlights()
|
|
65
65
|
|
|
66
|
-
Returns an array of all current highlights.
|
|
66
|
+
Returns an array of all current highlights. Each highlight object contains:
|
|
67
|
+
- `uuid`: Unique identifier for the highlight element
|
|
68
|
+
- `text`: The highlighted text content
|
|
67
69
|
|
|
68
70
|
### highlighter.removeHighlight(highlight)
|
|
69
71
|
|
|
70
|
-
Removes a specific highlight object. The highlight object can be obtained from the getHighlights() method.
|
|
72
|
+
Removes a specific highlight object. The highlight object can be obtained from the getHighlights() method. The method uses the UUID to locate and remove the corresponding highlight element.
|
|
71
73
|
|
|
72
74
|
### highlighter.removeAllHighlights()
|
|
73
75
|
|
package/index.js
CHANGED
|
@@ -20,6 +20,18 @@ class TextHighlighter {
|
|
|
20
20
|
this.highlights = [];
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Generate a simple UUID
|
|
25
|
+
*/
|
|
26
|
+
generateUUID() {
|
|
27
|
+
return (
|
|
28
|
+
"highlight-" +
|
|
29
|
+
Date.now() +
|
|
30
|
+
"-" +
|
|
31
|
+
Math.random().toString(36).substring(2, 11)
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
23
35
|
/**
|
|
24
36
|
* Highlight selected text
|
|
25
37
|
*/
|
|
@@ -54,10 +66,11 @@ class TextHighlighter {
|
|
|
54
66
|
}
|
|
55
67
|
|
|
56
68
|
try {
|
|
57
|
-
const
|
|
69
|
+
const uuid = this.generateUUID();
|
|
70
|
+
const highlightedElement = this.wrapRange(range, uuid);
|
|
58
71
|
|
|
59
72
|
this.highlights.push({
|
|
60
|
-
|
|
73
|
+
uuid: uuid,
|
|
61
74
|
text: selection.toString(),
|
|
62
75
|
});
|
|
63
76
|
|
|
@@ -114,13 +127,18 @@ class TextHighlighter {
|
|
|
114
127
|
/**
|
|
115
128
|
* Wrap a range with highlight element
|
|
116
129
|
* @param {Range} range - The range to wrap
|
|
130
|
+
* @param {string} uuid - Unique identifier for the highlight
|
|
117
131
|
*/
|
|
118
|
-
wrapRange(range) {
|
|
132
|
+
wrapRange(range, uuid) {
|
|
119
133
|
const highlightEl = document.createElement("span");
|
|
120
134
|
highlightEl.className = this.options.className;
|
|
121
135
|
highlightEl.style.backgroundColor = this.options.color;
|
|
122
136
|
highlightEl.style.padding = "0";
|
|
123
137
|
highlightEl.style.margin = "0";
|
|
138
|
+
highlightEl.style.cursor = "pointer";
|
|
139
|
+
|
|
140
|
+
// Add UUID as data attribute
|
|
141
|
+
highlightEl.setAttribute("data-uuid", uuid);
|
|
124
142
|
|
|
125
143
|
// Clone the range and insert the highlight element
|
|
126
144
|
range.surroundContents(highlightEl);
|
|
@@ -133,12 +151,12 @@ class TextHighlighter {
|
|
|
133
151
|
*/
|
|
134
152
|
removeAllHighlights() {
|
|
135
153
|
this.highlights.forEach((highlight) => {
|
|
136
|
-
|
|
154
|
+
const element = document.querySelector(
|
|
155
|
+
`[data-uuid="${highlight.uuid}"]`,
|
|
156
|
+
);
|
|
157
|
+
if (element && element.parentNode) {
|
|
137
158
|
const textNode = document.createTextNode(highlight.text);
|
|
138
|
-
|
|
139
|
-
textNode,
|
|
140
|
-
highlight.element,
|
|
141
|
-
);
|
|
159
|
+
element.parentNode.replaceChild(textNode, element);
|
|
142
160
|
}
|
|
143
161
|
});
|
|
144
162
|
|
|
@@ -149,23 +167,26 @@ class TextHighlighter {
|
|
|
149
167
|
* Get all highlighted elements
|
|
150
168
|
*/
|
|
151
169
|
getHighlights() {
|
|
170
|
+
// Return highlights with uuid and text
|
|
152
171
|
return [...this.highlights];
|
|
153
172
|
}
|
|
154
173
|
|
|
155
174
|
/**
|
|
156
175
|
* Remove a specific highlight
|
|
157
|
-
* @param {Object} highlight - The highlight object to remove
|
|
176
|
+
* @param {Object} highlight - The highlight object to remove (containing uuid)
|
|
158
177
|
*/
|
|
159
178
|
removeHighlight(highlight) {
|
|
160
|
-
const index = this.highlights.
|
|
179
|
+
const index = this.highlights.findIndex(
|
|
180
|
+
(h) => h.uuid === highlight.uuid,
|
|
181
|
+
);
|
|
161
182
|
if (index !== -1) {
|
|
162
183
|
// Restore the original text
|
|
163
|
-
|
|
184
|
+
const element = document.querySelector(
|
|
185
|
+
`[data-uuid="${highlight.uuid}"]`,
|
|
186
|
+
);
|
|
187
|
+
if (element && element.parentNode) {
|
|
164
188
|
const textNode = document.createTextNode(highlight.text);
|
|
165
|
-
|
|
166
|
-
textNode,
|
|
167
|
-
highlight.element,
|
|
168
|
-
);
|
|
189
|
+
element.parentNode.replaceChild(textNode, element);
|
|
169
190
|
}
|
|
170
191
|
|
|
171
192
|
// Remove from the highlights array
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lk-text-select-highlight",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "A lightweight JavaScript library for highlighting selected text on web pages",
|
|
5
5
|
"main": "dist/lk-text-select-highlight.cjs.js",
|
|
6
6
|
"module": "dist/lk-text-select-highlight.esm.js",
|
package/test_server.cjs
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const http = require("http");
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
const path = require("path");
|
|
4
|
+
|
|
5
|
+
const port = 8080;
|
|
6
|
+
const server = http.createServer((req, res) => {
|
|
7
|
+
let filePath = "." + req.url;
|
|
8
|
+
|
|
9
|
+
if (filePath === "./") {
|
|
10
|
+
filePath = "./test_uuid_attr.html";
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const extname = path.extname(filePath).toLowerCase();
|
|
14
|
+
let contentType = "text/html";
|
|
15
|
+
|
|
16
|
+
const mimeTypes = {
|
|
17
|
+
".js": "application/javascript",
|
|
18
|
+
".css": "text/css",
|
|
19
|
+
".html": "text/html",
|
|
20
|
+
".json": "application/json",
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
contentType = mimeTypes[extname] || "text/html";
|
|
24
|
+
|
|
25
|
+
fs.readFile(filePath, (err, content) => {
|
|
26
|
+
if (err) {
|
|
27
|
+
if (err.code === "ENOENT") {
|
|
28
|
+
res.writeHead(404);
|
|
29
|
+
res.end("404 Not Found");
|
|
30
|
+
} else {
|
|
31
|
+
res.writeHead(500);
|
|
32
|
+
res.end(`Server Error: ${err.code}`);
|
|
33
|
+
}
|
|
34
|
+
} else {
|
|
35
|
+
res.writeHead(200, { "Content-Type": contentType });
|
|
36
|
+
res.end(content, "utf-8");
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
server.listen(port, () => {
|
|
42
|
+
console.log(`Server running at http://localhost:${port}/`);
|
|
43
|
+
});
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>UUID Attribute Test</title>
|
|
7
|
+
<style>
|
|
8
|
+
body {
|
|
9
|
+
font-family: Arial, sans-serif;
|
|
10
|
+
max-width: 800px;
|
|
11
|
+
margin: 0 auto;
|
|
12
|
+
padding: 20px;
|
|
13
|
+
line-height: 1.6;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.demo-text {
|
|
17
|
+
background-color: #f9f9f9;
|
|
18
|
+
padding: 20px;
|
|
19
|
+
border-radius: 5px;
|
|
20
|
+
margin: 20px 0;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.controls {
|
|
24
|
+
margin: 20px 0;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
button {
|
|
28
|
+
background-color: #4caf50;
|
|
29
|
+
color: white;
|
|
30
|
+
padding: 10px 15px;
|
|
31
|
+
border: none;
|
|
32
|
+
border-radius: 4px;
|
|
33
|
+
cursor: pointer;
|
|
34
|
+
margin-right: 10px;
|
|
35
|
+
margin-bottom: 10px;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
button:hover {
|
|
39
|
+
background-color: #45a049;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.highlighted-text {
|
|
43
|
+
background-color: #ffff00;
|
|
44
|
+
padding: 0;
|
|
45
|
+
margin: 0;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.inspect-btn {
|
|
49
|
+
background-color: #2196f3;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.inspect-btn:hover {
|
|
53
|
+
background-color: #0b7dda;
|
|
54
|
+
}
|
|
55
|
+
</style>
|
|
56
|
+
</head>
|
|
57
|
+
<body>
|
|
58
|
+
<h1>UUID Attribute Test</h1>
|
|
59
|
+
|
|
60
|
+
<div class="controls">
|
|
61
|
+
<button id="highlightBtn">高亮选中文本</button>
|
|
62
|
+
<button id="inspectBtn" class="inspect-btn">
|
|
63
|
+
检查高亮元素属性
|
|
64
|
+
</button>
|
|
65
|
+
<button id="clearBtn">清除所有高亮</button>
|
|
66
|
+
</div>
|
|
67
|
+
|
|
68
|
+
<div class="demo-text" id="demo-content">
|
|
69
|
+
<p>
|
|
70
|
+
请选择这段文字的一部分,然后点击"高亮选中文本"按钮。
|
|
71
|
+
高亮后点击"检查高亮元素属性"按钮查看data-uuid属性是否存在。
|
|
72
|
+
</p>
|
|
73
|
+
<p>
|
|
74
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
|
|
75
|
+
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
|
|
76
|
+
enim ad minim veniam, quis nostrud exercitation ullamco laboris
|
|
77
|
+
nisi ut aliquip ex ea commodo consequat.
|
|
78
|
+
</p>
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
<div id="output"></div>
|
|
82
|
+
|
|
83
|
+
<script src="./dist/lk-text-select-highlight.umd.js"></script>
|
|
84
|
+
<script>
|
|
85
|
+
// 初始化文本高亮器
|
|
86
|
+
const highlighter = new TextHighlighter({
|
|
87
|
+
className: "highlighted-text",
|
|
88
|
+
color: "#ffff00",
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// 高亮按钮事件
|
|
92
|
+
document
|
|
93
|
+
.getElementById("highlightBtn")
|
|
94
|
+
.addEventListener("click", () => {
|
|
95
|
+
const success = highlighter.highlightSelection();
|
|
96
|
+
console.log("高亮操作结果:", success);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// 检查属性按钮事件
|
|
100
|
+
document
|
|
101
|
+
.getElementById("inspectBtn")
|
|
102
|
+
.addEventListener("click", () => {
|
|
103
|
+
const allHighlights =
|
|
104
|
+
document.querySelectorAll(".highlighted-text");
|
|
105
|
+
let outputHtml = "<h3>高亮元素属性检查:</h3>";
|
|
106
|
+
|
|
107
|
+
allHighlights.forEach((el, index) => {
|
|
108
|
+
const uuid = el.getAttribute("data-uuid");
|
|
109
|
+
outputHtml += `<p>元素 ${index + 1}: data-uuid = ${uuid || "NOT FOUND"}</p>`;
|
|
110
|
+
|
|
111
|
+
// 输出所有属性
|
|
112
|
+
const attrs = Array.from(el.attributes);
|
|
113
|
+
attrs.forEach((attr) => {
|
|
114
|
+
console.log(
|
|
115
|
+
`Attribute: ${attr.name} = ${attr.value}`,
|
|
116
|
+
);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
if (allHighlights.length === 0) {
|
|
121
|
+
outputHtml = "<h3>没有发现高亮元素</h3>";
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
document.getElementById("output").innerHTML = outputHtml;
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// 清除高亮按钮
|
|
128
|
+
document
|
|
129
|
+
.getElementById("clearBtn")
|
|
130
|
+
.addEventListener("click", () => {
|
|
131
|
+
highlighter.removeAllHighlights();
|
|
132
|
+
document.getElementById("output").innerHTML =
|
|
133
|
+
"<h3>已清除所有高亮</h3>";
|
|
134
|
+
console.log("已清除所有高亮");
|
|
135
|
+
});
|
|
136
|
+
</script>
|
|
137
|
+
</body>
|
|
138
|
+
</html>
|