vuepress-theme-uniapp-official 1.6.1 → 1.6.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.
@@ -0,0 +1,54 @@
1
+ .ai-answer-card
2
+ padding 14px 16px
3
+ margin-top 12px
4
+ background #fff
5
+ border-radius 12px
6
+ border 1px solid rgba(0,0,0,0.06)
7
+ box-shadow 0 2px 8px rgba(0,0,0,0.04)
8
+ transition box-shadow .25s, transform .2s
9
+ cursor pointer
10
+
11
+ &:hover
12
+ box-shadow 0 4px 14px rgba(0,0,0,0.08)
13
+ transform translateY(-1px)
14
+ /* 重置部分元素样式,防止样式冲突 */
15
+ pre, code
16
+ white-space: pre-wrap; /* 允许换行 */
17
+ word-wrap: break-word; /* 允许长行断开 */
18
+ word-break: break-word;
19
+ h1, h2, h3, h4, h5, h6, p, ul, ol, dl, figure, blockquote, pre
20
+ line-height: normal
21
+ margin: 0
22
+ padding: 0
23
+ ul, ol
24
+ list-style: none
25
+
26
+ .ai-answer-header
27
+ display flex
28
+ align-items center
29
+ margin-bottom 8px
30
+
31
+ .ai-answer-icon
32
+ font-size 18px
33
+ margin-right 6px
34
+
35
+ .ai-answer-title
36
+ font-weight 600
37
+ font-size 15px
38
+ color #333
39
+
40
+ .ai-answer-msg
41
+ font-size 14px
42
+ line-height normal
43
+ color #555
44
+ // white-space pre-wrap
45
+ word-break break-word
46
+ animation fadeIn .3s ease
47
+
48
+ @keyframes fadeIn
49
+ from
50
+ opacity 0
51
+ transform translateY(4px)
52
+ to
53
+ opacity 1
54
+ transform translateY(0)
@@ -28,14 +28,7 @@
28
28
  </div>
29
29
  </transition-group>
30
30
 
31
- <div v-if="sending" class="chat-skeleton chat-skeleton-left">
32
- <div class="content">
33
- <div class="line"></div>
34
- <div class="line"></div>
35
- <div class="line short"></div>
36
- </div>
37
- </div>
38
-
31
+ <Skeleton style="width: 60%" v-if="sending" />
39
32
  </main>
40
33
 
41
34
  <footer class="chat-input-bar">
@@ -52,14 +45,14 @@
52
45
  </template>
53
46
 
54
47
  <script setup>
55
- import { ref, nextTick, watchEffect, onMounted, onActivated, watch } from 'vue'
48
+ import { ref, nextTick, watchEffect, onMounted } from 'vue'
56
49
  import { renderMarkdown } from "./markdown-loader";
57
- import 'highlight.js/styles/github.min.css'
58
50
  import SelectPlatform from './SelectPlatform.vue';
59
51
  import { ajax } from '../../utils/postDcloudServer';
60
52
  import searchPageConfig from '@theme-config/searchPage';
53
+ import Skeleton from '../Skeleton';
61
54
 
62
- const { aiPlatforms = [], aiChatForDocSearch } = searchPageConfig;
55
+ const { aiPlatforms = [], aiChatForDocSearch = 'https://ai-assist-api.dcloud.net.cn/tbox/chatForDocSearch' } = searchPageConfig;
63
56
 
64
57
  const props = defineProps({
65
58
  currentCategory: {
@@ -98,7 +91,8 @@ watchEffect(() => {
98
91
  if (props.visible) {
99
92
  nextTick(() => {
100
93
  scrollToBottom()
101
- autoGrow(true)
94
+ autoGrow()
95
+ input.value.focus()
102
96
  })
103
97
  }
104
98
  })
@@ -111,11 +105,11 @@ function formatTime() {
111
105
  .padStart(2, '0')}`
112
106
  }
113
107
 
114
- function autoGrow(clear) {
108
+ function autoGrow() {
115
109
  const el = input.value
116
110
  el.style.height = 'auto'
117
111
  scrollToBottom()
118
- if (clear === true) {
112
+ if (inputText.value.length === 0) {
119
113
  return
120
114
  }
121
115
  el.style.height = el.scrollHeight + 'px'
@@ -164,12 +158,21 @@ function platformChange(newPlatform) {
164
158
  sendPlatform.value = newPlatform
165
159
  }
166
160
 
161
+ // 限制只取最近 6 条消息
162
+ function getChatHistory() {
163
+ return messages.value.slice(-6).map(m => ({
164
+ role: m.role,
165
+ contentType: 'text',
166
+ content: m.raw
167
+ }))
168
+ }
169
+
167
170
  async function send() {
168
171
  if (!inputText.value.trim() || sending.value) return
169
172
 
170
173
  const userText = inputText.value.trim()
171
174
  inputText.value = ''
172
- autoGrow(true)
175
+ autoGrow()
173
176
 
174
177
  // 用户消息
175
178
  messages.value.push({
@@ -186,9 +189,10 @@ async function send() {
186
189
 
187
190
  let fakeReply = ''
188
191
  try {
189
- const res = await ajax(aiChatForDocSearch ? aiChatForDocSearch : 'https://ai-assist-api.dcloud.net.cn/tbox/chatForDocSearch', 'POST', {
192
+ const res = await ajax(aiChatForDocSearch, 'POST', {
190
193
  "question": userText,
191
- "group_name": sendPlatform.value
194
+ "group_name": sendPlatform.value,
195
+ "history": getChatHistory()
192
196
  })
193
197
  if (res.errorCode === 0) {
194
198
  fakeReply = res.chunk
@@ -196,7 +200,7 @@ async function send() {
196
200
  fakeReply = `抱歉,AI 助手出错了:${res.errorMessage || '未知错误'}`
197
201
  }
198
202
  } catch (error) {
199
-
203
+ fakeReply = `抱歉,AI 助手出错了:${error.message || '未知错误'}`
200
204
  }
201
205
  sending.value = false
202
206
 
@@ -223,8 +227,6 @@ window.addEventListener('resize', scrollToBottom)
223
227
  </script>
224
228
 
225
229
  <style lang="stylus">
226
- @import './skeleton.styl'
227
-
228
230
  .chat-wrapper
229
231
  display flex
230
232
  flex-direction column
@@ -2,39 +2,40 @@
2
2
  let markedInstance = null;
3
3
  let hljsInstance = null;
4
4
 
5
- function transfromLang(lang) {
6
- switch (lang) {
7
- case 'uts':
8
- return 'typescript';
9
- case 'json5':
10
- return 'json';
11
- }
12
- if (!hljsInstance) return 'plaintext';
13
- return hljsInstance.getLanguage(lang) ? lang : 'plaintext';
5
+ function getLangCodeFromExtension (extension) {
6
+ const extensionMap = {
7
+ vue: 'markup',
8
+ html: 'markup',
9
+ md: 'markdown',
10
+ rb: 'ruby',
11
+ ts: 'typescript',
12
+ py: 'python',
13
+ sh: 'bash',
14
+ yml: 'yaml',
15
+ styl: 'stylus',
16
+ kt: 'kotlin',
17
+ rs: 'rust',
18
+ uts: 'typescript',
19
+ json5: 'json',
20
+ }
21
+
22
+ return extensionMap[extension] || extension
14
23
  }
15
24
 
16
25
  export async function renderMarkdown(md) {
17
26
  if (!markedInstance) {
18
- const [{ Marked }, { markedHighlight }, hljs] = await Promise.all([
19
- import('marked'),
20
- import('marked-highlight'),
21
- import('highlight.js'),
22
- ]);
23
-
24
- const marked = new Marked(
25
- markedHighlight({
26
- emptyLangClass: 'hljs',
27
- langPrefix: 'hljs language-',
28
- highlight(code, lang, info) {
29
- const language = transfromLang(lang);
30
- return hljs.highlight(code, { language }).value;
31
- },
32
- })
33
- );
27
+ const [marked, hljs] = await Promise.all([import('marked'), import('highlight.js')]);
34
28
 
35
29
  marked.setOptions({
36
30
  headerIds: false,
37
31
  mangle: false,
32
+ highlight(code, lang) {
33
+ lang = getLangCodeFromExtension(lang);
34
+ if (lang && hljs.getLanguage(lang)) {
35
+ return hljs.highlight(code, { language: lang }).value;
36
+ }
37
+ return hljs.highlightAuto(code).value;
38
+ },
38
39
  });
39
40
 
40
41
  markedInstance = marked;
@@ -1,3 +1,14 @@
1
+ <template>
2
+ <div class="chat-skeleton chat-skeleton-left">
3
+ <div class="content">
4
+ <div class="line"></div>
5
+ <div class="line"></div>
6
+ <div class="line short"></div>
7
+ </div>
8
+ </div>
9
+ </template>
10
+
11
+ <style lang="stylus" scope>
1
12
  /* Skeleton base style */
2
13
  .skeleton
3
14
  background: #eee
@@ -20,7 +31,6 @@
20
31
 
21
32
  .chat-skeleton .line
22
33
  height: 14px
23
- width: 60%
24
34
  border-radius: 6px
25
35
  @extend .skeleton
26
36
 
@@ -37,3 +47,5 @@
37
47
  display: flex
38
48
  flex-direction: column
39
49
  gap: 10px
50
+
51
+ </style>
@@ -29,14 +29,14 @@
29
29
  <div class="input-wrap">
30
30
  <input ref="searchInput" class="search-input" :placeholder="placeholder" type="text" @keydown.enter="
31
31
  () => {
32
- resetSearchPage();
32
+ resetSearch();
33
33
  search();
34
34
  }
35
35
  " v-model="searchValue" />
36
36
  <span class="search-input-btn">
37
37
  <button @click="
38
38
  () => {
39
- resetSearchPage();
39
+ resetSearch();
40
40
  search();
41
41
  }
42
42
  ">
@@ -83,7 +83,21 @@
83
83
  <div class="result-wrap">
84
84
  <template v-if="isAlgolia">
85
85
  <template v-for="item in resultList">
86
- <Results :key="item.sourceId" :title="item.title" :results="item.items" :onSelect="item.onSelect" />
86
+ <template v-if="item">
87
+ <Results v-if="!item.isAI" :key="item.sourceId" :title="item.title" :results="item.items"
88
+ :onSelect="item.onSelect" />
89
+ <template v-else>
90
+ <div class="ai-answer-card">
91
+ <div class="ai-answer-header">
92
+ <span class="ai-answer-icon">🤖</span>
93
+ <span class="ai-answer-title">{{ item.title }}</span>
94
+ </div>
95
+
96
+ <div v-if="item.msg.length" class="ai-answer-msg" v-html="item.msg" />
97
+ <Skeleton v-else />
98
+ </div>
99
+ </template>
100
+ </template>
87
101
  </template>
88
102
  </template>
89
103
 
@@ -128,17 +142,21 @@
128
142
  </template>
129
143
 
130
144
  <script>
145
+ import searchPageConfig from '@theme-config/searchPage';
131
146
  import NavbarLogo from '../NavbarLogo.vue';
132
147
  import Results from './components/Results.vue';
133
148
  import pagination from './components/pagination.vue';
134
149
  import AIChat from './components/AIChat/index.vue';
135
150
  import MainNavbarLink from '../MainNavbarLink.vue';
151
+ import Skeleton from './components/Skeleton.vue';
136
152
  import { search as searchClient } from './utils/searchClient';
137
153
  import { postExt, postAsk } from './utils/postDcloudServer';
138
154
  import { forbidScroll, debounce } from '../../util';
139
155
  import { removeHighlightTags, isEditingContent } from './utils/searchUtils';
140
- import searchPageConfig from '@theme-config/searchPage';
141
156
  import Base64 from './utils/Base64';
157
+ import { ajax } from './utils/postDcloudServer';
158
+ import { renderMarkdown } from "./components/AIChat/markdown-loader";
159
+ import 'highlight.js/styles/github.min.css'
142
160
 
143
161
  const {
144
162
  enableAI = true,
@@ -147,9 +165,11 @@ const {
147
165
  searchBox: { placeholder, buttonText, searchBy },
148
166
  resultsScreen: { resultsText, noResultsText, askNoResultsText },
149
167
  },
150
- extraFacetFilters = []
168
+ extraFacetFilters = [],
169
+ aiChatForDocSearch = 'https://ai-assist-api.dcloud.net.cn/tbox/chatForDocSearch'
151
170
  } = searchPageConfig;
152
171
  const crawlerUrl = 'https://zh.uniapp.dcloud.io/'
172
+ const AIErrorMsg = '很抱歉,AI 助手未能找到相关答案。请尝试更换关键词进行搜索。'
153
173
 
154
174
  const resolveRoutePathFromUrl = (url, base = '/') => {
155
175
  if (url.indexOf(crawlerUrl) === 0) {
@@ -165,7 +185,7 @@ export default {
165
185
 
166
186
  props: ['options'],
167
187
 
168
- components: { NavbarLogo, Results, pagination, MainNavbarLink, AIChat },
188
+ components: { NavbarLogo, Results, pagination, MainNavbarLink, AIChat, Skeleton },
169
189
 
170
190
  data() {
171
191
  return {
@@ -191,6 +211,13 @@ export default {
191
211
  totalPage: 0, // 搜索结果总共页数
192
212
  curPage: 1, // 当前页
193
213
  pageSize: 0, // 每页条数
214
+
215
+ searchAIResult: Promise.resolve(null),
216
+ aiMessage: {
217
+ isAI: true,
218
+ title: 'AI 助手回答',
219
+ msg: ''
220
+ }
194
221
  };
195
222
  },
196
223
 
@@ -260,10 +287,10 @@ export default {
260
287
  });
261
288
  },
262
289
 
263
- searchValue: debounce(function () {
264
- this.resetSearchPage();
290
+ /* searchValue: debounce(function () {
291
+ this.resetSearch();
265
292
  this.search();
266
- }, 300),
293
+ }, 300), */
267
294
 
268
295
  $route: {
269
296
  immediate: true,
@@ -320,8 +347,20 @@ export default {
320
347
  }
321
348
  },
322
349
 
323
- resetSearchPage() {
350
+ resetSearch() {
324
351
  this.searchPage = 0;
352
+ this.resetAI();
353
+ },
354
+
355
+ resetAI() {
356
+ if (this.searchAIResult && typeof this.searchAIResult.abort === 'function') {
357
+ this.searchAIResult.abort()
358
+ }
359
+ this.aiMessage.msg = ''
360
+ this.searchAIResult = null
361
+ if (this.enableAI && this.searchValue.trim().length) {
362
+ this.searchByAI()
363
+ }
325
364
  },
326
365
 
327
366
  research(curPage) {
@@ -345,11 +384,16 @@ export default {
345
384
  items,
346
385
  };
347
386
  });
387
+
348
388
  this.noResult = !this.resultList.length;
349
389
  this.curHits = nbHits;
350
390
  this.pageSize = hitsPerPage;
351
391
  this.totalPage = nbPages;
352
392
  this.curPage = page + 1;
393
+
394
+ if (this.curPage === 1 && this.enableAI) {
395
+ this.resultList.splice(1, 0, this.aiMessage);
396
+ }
353
397
  })
354
398
  .finally(() => {
355
399
  this.showLoading = false
@@ -396,6 +440,33 @@ export default {
396
440
  );
397
441
  },
398
442
 
443
+ searchByAI() {
444
+ try {
445
+ this.searchAIResult = ajax(aiChatForDocSearch, 'POST', {
446
+ "question": this.searchValue,
447
+ "group_name": this.currentCategory.text
448
+ }).then(res => {
449
+ if (res.errorCode === 0) {
450
+ return renderMarkdown(res.chunk)
451
+ } else {
452
+ this.aiMessage.msg = res.errorMessage || AIErrorMsg;
453
+ return ''
454
+ }
455
+ })
456
+ .catch((err) => {
457
+ console.log('err :>> ', err);
458
+ return ''
459
+ })
460
+ .then(msg => {
461
+ this.aiMessage.msg = msg || AIErrorMsg;
462
+ })
463
+ } catch (err) {
464
+ console.log('err :>> ', err);
465
+ this.aiMessage.msg = err.message || AIErrorMsg;
466
+ return ''
467
+ }
468
+ },
469
+
399
470
  searchByServer(append = false) {
400
471
  const { tag } = this.currentCategory;
401
472
  const query = this.searchValue || '';
@@ -509,4 +580,5 @@ export default {
509
580
 
510
581
  <style lang="stylus">
511
582
  @import './index'
583
+ @import './ai-result.styl'
512
584
  </style>
@@ -1,74 +1,76 @@
1
- const isProduction = process.env.NODE_ENV === "production"
2
- const isMock = false
3
- import mock from './mock'
1
+ const isProduction = process.env.NODE_ENV === 'production';
2
+ const isMock = false;
3
+ import mock from './mock';
4
4
 
5
5
  export function ajax(url = '', method = 'get', data = {}) {
6
- return new Promise((resolve, reject) => {
7
- if (!url) reject('url 不可为空')
8
- const xhr = new XMLHttpRequest();
9
- xhr.open(method, url);
10
- xhr.onreadystatechange = function () {
11
- if (this.readyState == 4 && this.status == 200) {
12
- try {
13
- resolve(JSON.parse(this.response))
14
- } catch (error) {
15
- resolve(this.response)
16
- }
17
- }
18
- }
19
- if (method.toLowerCase() === 'post') {
20
- xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
21
- xhr.send(JSON.stringify(data));
22
- } else {
23
- xhr.send();
24
- }
25
- })
6
+ if (!url) return Promise.reject('url 不可为空');
7
+ const xhr = new XMLHttpRequest();
8
+ const p = new Promise((resolve, reject) => {
9
+ xhr.open(method, url);
10
+ xhr.onreadystatechange = function () {
11
+ if (this.readyState == 4 && this.status == 200) {
12
+ try {
13
+ resolve(JSON.parse(this.response));
14
+ } catch (error) {
15
+ resolve(this.response);
16
+ }
17
+ }
18
+ };
19
+ if (method.toLowerCase() === 'post') {
20
+ xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
21
+ xhr.send(JSON.stringify(data));
22
+ } else {
23
+ xhr.send();
24
+ }
25
+ });
26
+ p.abort = () => xhr.abort();
27
+ return p;
26
28
  }
27
29
 
28
30
  export async function postExt(query) {
29
- const base = isProduction ? '//ext.dcloud.net.cn' : '/ext'
30
- let extRet
31
- if (!isMock) {
32
- const extRes = await ajax(base + '/search/json?query=' + encodeURIComponent(query))
33
- extRet = JSON.parse(extRes);
34
- } else {
35
- extRet = mock.ext;
36
- }
37
-
38
- let extHtml = '';
39
- let data = extRet.data;
40
- if (extRet.ret === 0) {
41
- for (let i = 0, len = data.length; i < len; i++) {
42
- extHtml += _renderExt(data[i], query);
43
- }
44
- }
45
- return {
46
- html: extHtml,
47
- hits: data.length
48
- }
31
+ const base = isProduction ? '//ext.dcloud.net.cn' : '/ext';
32
+ let extRet;
33
+ if (!isMock) {
34
+ const extRes = await ajax(base + '/search/json?query=' + encodeURIComponent(query));
35
+ extRet = JSON.parse(extRes);
36
+ } else {
37
+ extRet = mock.ext;
38
+ }
39
+
40
+ let extHtml = '';
41
+ let data = extRet.data;
42
+ if (extRet.ret === 0) {
43
+ for (let i = 0, len = data.length; i < len; i++) {
44
+ extHtml += _renderExt(data[i], query);
45
+ }
46
+ }
47
+ return {
48
+ html: extHtml,
49
+ hits: data.length,
50
+ };
49
51
  }
50
52
 
51
53
  export async function postAsk(query, page = 1) {
52
- const base = isProduction ? '//ask.dcloud.net.cn' : '/ask'
53
- let askHtml = '';
54
-
55
- if (!isMock) {
56
- askHtml = await ajax(base + `/search/ajax/search_result/search_type-all__q-${query}__page-${page}`)
57
- if (!askHtml) {
58
- return;
59
- }
60
- } else {
61
- askHtml = mock.askHtml
62
- }
63
-
64
- return {
65
- html: askHtml,
66
- hits: 0
67
- }
54
+ const base = isProduction ? '//ask.dcloud.net.cn' : '/ask';
55
+ let askHtml = '';
56
+
57
+ if (!isMock) {
58
+ askHtml = await ajax(base + `/search/ajax/search_result/search_type-all__q-${query}__page-${page}`);
59
+ if (!askHtml) {
60
+ return;
61
+ }
62
+ } else {
63
+ askHtml = mock.askHtml;
64
+ }
65
+
66
+ return {
67
+ html: askHtml,
68
+ hits: 0,
69
+ };
68
70
  }
69
71
 
70
72
  function _renderExt(ext, keyword) {
71
- return `<div class="matching-post">
73
+ return `<div class="matching-post">
72
74
  <a href="${ext.url}" target="_blank">
73
75
  <div class="post-wrapper">
74
76
  <h2>
@@ -81,30 +83,30 @@ function _renderExt(ext, keyword) {
81
83
  <p>${ext.total_download}次下载</p>
82
84
  <p>${_handleHTMLString(ext.description, keyword)}</p>
83
85
  </a>
84
- </div>`
86
+ </div>`;
85
87
  }
86
88
 
87
89
  function _renderPost(post, value) {
88
- let html = '';
89
- let commentText = '';
90
- let tagName = '规范';
91
-
92
- // 1,问题;2,文章;默认是规范。
93
- switch (post.type) {
94
- case 'questions':
95
- tagName = '问题';
96
- break;
97
- case 'articles':
98
- tagName = '文章';
99
- break;
100
- }
101
-
102
- if (!!value) {
103
- post.title = _handleHTMLString(post.title, value);
104
- post.content = _handleHTMLString(post.content, value);
105
- }
106
-
107
- html += `<div class="matching-post">
90
+ let html = '';
91
+ let commentText = '';
92
+ let tagName = '规范';
93
+
94
+ // 1,问题;2,文章;默认是规范。
95
+ switch (post.type) {
96
+ case 'questions':
97
+ tagName = '问题';
98
+ break;
99
+ case 'articles':
100
+ tagName = '文章';
101
+ break;
102
+ }
103
+
104
+ if (!!value) {
105
+ post.title = _handleHTMLString(post.title, value);
106
+ post.content = _handleHTMLString(post.content, value);
107
+ }
108
+
109
+ html += `<div class="matching-post">
108
110
  <a href="${post.url}" target="_blank">
109
111
  <div class="post-wrapper">
110
112
  <h2>
@@ -113,38 +115,29 @@ function _renderPost(post, value) {
113
115
  </p>
114
116
  ${post.title}
115
117
  </h2>
116
- </div>`
118
+ </div>`;
117
119
 
118
- if (!!value) {
119
- commentText = post.type === 'questions' ? '回复' : '评论';
120
- html += `<p>
120
+ if (!!value) {
121
+ commentText = post.type === 'questions' ? '回复' : '评论';
122
+ html += `<p>
121
123
  ${post.comment_count}个${commentText}
122
124
  <span class="aw-text-space">-</span>
123
125
  ${post.view_count}次浏览
124
126
  </p>`;
125
- }
127
+ }
126
128
 
127
- html += `\n<p>${post.content}</p>\n</a>\n</div>`;
129
+ html += `\n<p>${post.content}</p>\n</a>\n</div>`;
128
130
 
129
- return html;
131
+ return html;
130
132
  }
131
133
 
132
134
  function _handleHTMLString(dataString, keyword) {
133
- let keywordReg = new RegExp(
134
- keyword.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&'),
135
- 'gi'
136
- );
137
- let tagStartReg = new RegExp(
138
- '&lt;span style=\'font-weight:bold;color:red\'&gt;',
139
- 'g'
140
- );
141
- let tagEndReg = new RegExp(
142
- '&lt;/span&gt;',
143
- 'g'
144
- );
145
-
146
- return dataString
147
- .replace(tagStartReg, '')
148
- .replace(tagEndReg, '')
149
- .replace(keywordReg, ("<em class=\"search-keyword\">" + keyword + "</em>"));
150
- };
135
+ let keywordReg = new RegExp(keyword.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&'), 'gi');
136
+ let tagStartReg = new RegExp("&lt;span style='font-weight:bold;color:red'&gt;", 'g');
137
+ let tagEndReg = new RegExp('&lt;/span&gt;', 'g');
138
+
139
+ return dataString
140
+ .replace(tagStartReg, '')
141
+ .replace(tagEndReg, '')
142
+ .replace(keywordReg, '<em class="search-keyword">' + keyword + '</em>');
143
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vuepress-theme-uniapp-official",
3
- "version": "1.6.1",
3
+ "version": "1.6.3",
4
4
  "description": "uni-app official website theme for vuepress",
5
5
  "main": "index.js",
6
6
  "repository": {
@@ -39,8 +39,7 @@
39
39
  "markdown-it-attrs": "^4.1.6",
40
40
  "markdown-it-raw-table": "^1.0.0",
41
41
  "markdown-it-task-lists": "^2.1.1",
42
- "marked": "^5.1.2",
43
- "marked-highlight": "^2.2.3",
42
+ "marked": "^3.0.8",
44
43
  "qr-code-with-logo": "^1.1.0",
45
44
  "vuepress-plugin-juejin-style-copy": "^1.0.4",
46
45
  "vuepress-plugin-mermaidjs": "1.9.1",