@@ -132,6 +132,45 @@ const Search = {
132
132
}
133
133
} ,
134
134
135
+ // 高亮文本
136
+ highlightText ( text , query ) {
137
+ if ( ! text || ! query ) {
138
+ return text ;
139
+ }
140
+
141
+ // 转义正则表达式特殊字符
142
+ const escapedQuery = query . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, '\\$&' ) ;
143
+ const regex = new RegExp ( `(${ escapedQuery } )` , 'gi' ) ;
144
+
145
+ return text . replace ( regex , `<mark class="bg-yellow-200 dark:bg-yellow-800 dark:text-gray-100">$1</mark>` ) ;
146
+ } ,
147
+
148
+ // 获取包含匹配内容的摘要
149
+ getContentExcerpt ( content , query , maxLength = 160 ) {
150
+ if ( ! content || ! query ) {
151
+ return content ;
152
+ }
153
+
154
+ const lowerContent = content . toLowerCase ( ) ;
155
+ const lowerQuery = query . toLowerCase ( ) ;
156
+ const matchIndex = lowerContent . indexOf ( lowerQuery ) ;
157
+
158
+ if ( matchIndex === - 1 ) {
159
+ return content . substring ( 0 , maxLength ) ;
160
+ }
161
+
162
+ // 确定摘要的起始和结束位置
163
+ let start = Math . max ( 0 , matchIndex - 60 ) ;
164
+ let end = Math . min ( content . length , matchIndex + 100 ) ;
165
+
166
+ // 如果摘要不是从开头开始,添加省略号
167
+ let excerpt = ( start > 0 ? '...' : '' ) +
168
+ content . substring ( start , end ) +
169
+ ( end < content . length ? '...' : '' ) ;
170
+
171
+ return excerpt ;
172
+ } ,
173
+
135
174
// 执行搜索
136
175
async performSearch ( query ) {
137
176
// 确保索引已加载
@@ -164,17 +203,23 @@ const Search = {
164
203
165
204
this . els . searchResults . innerHTML = `
166
205
<div class="divide-y divide-gray-100 dark:divide-gray-800">
167
- ${ results . map ( result => `
168
- <a href="${ result . url } "
169
- class="block px-4 py-3 hover:bg-gray-50 dark:hover:bg-gray-700/50">
170
- <div class="text-sm font-medium text-gray-900 dark:text-gray-100">
171
- ${ result . title }
172
- </div>
173
- <div class="mt-1 text-sm text-gray-500 dark:text-gray-400 line-clamp-2">
174
- ${ result . content . substring ( 0 , 160 ) } ...
175
- </div>
176
- </a>
177
- ` ) . join ( '' ) }
206
+ ${ results . map ( result => {
207
+ const highlightedTitle = this . highlightText ( result . title , query ) ;
208
+ const contentExcerpt = this . getContentExcerpt ( result . content , query ) ;
209
+ const highlightedContent = this . highlightText ( contentExcerpt , query ) ;
210
+
211
+ return `
212
+ <a href="${ result . url } "
213
+ class="block px-4 py-3 hover:bg-gray-50 dark:hover:bg-gray-700/50">
214
+ <div class="text-sm font-medium text-gray-900 dark:text-gray-100">
215
+ ${ highlightedTitle }
216
+ </div>
217
+ <div class="mt-1 text-sm text-gray-500 dark:text-gray-400 line-clamp-2">
218
+ ${ highlightedContent }
219
+ </div>
220
+ </a>
221
+ ` ;
222
+ } ) . join ( '' ) }
178
223
</div>
179
224
` ;
180
225
}
0 commit comments