Skip to content

Commit e1da2f8

Browse files
committed
docs(README): add search
1 parent eb5ff3e commit e1da2f8

File tree

8 files changed

+99
-17
lines changed

8 files changed

+99
-17
lines changed

CHANGELOG.md

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
## 2.1.0
2+
### Features
3+
- Add search plugin
4+
```html
5+
<script src="//unpkg.com/docsify/lib/docsify.js"></script>
6+
<script src="//unpkg.com/docsify/lib/plugins/search.js"></script>
7+
```
8+
19
## 2.0.3
210
### Bug fixes
311
- fix: rendering emojis

docs/README.md

+36
Original file line numberDiff line numberDiff line change
@@ -459,3 +459,39 @@ window.$docsify = {
459459
themeColor: '#3F51B5'
460460
}
461461
```
462+
463+
## Plugins
464+
465+
### Full Text Search
466+
467+
If a document can have a search, can enhance some user experience. The introduction of search plugin is easy. such as
468+
469+
470+
```html
471+
<script src="//unpkg.com/docsify/lib/docsify.js"></script>
472+
<script src="//unpkg.com/docsify/lib/plugins/search.js"></script>
473+
```
474+
475+
By default, the hyperlink on the current page is recognized and the content is saved in `localStorage`. You can also specify the path to the files.
476+
477+
!> Configure the content before the plugin is installed.
478+
479+
```js
480+
window.$docsify = {
481+
search: 'auto', // default
482+
483+
search : [
484+
'/', // => /README.md
485+
'/guide', // => /guide.md
486+
'/get-started', // => /get-started.md
487+
'/zh-cn/', // => /zh-cn/README.md
488+
],
489+
490+
// Full configuration
491+
search: {
492+
maxAge: 86400000, // Expiration time, the default one day
493+
paths: [], // or 'auto'
494+
placeholder: 'Type to search'
495+
}
496+
}
497+
```

docs/zh-cn.md

+35
Original file line numberDiff line numberDiff line change
@@ -466,3 +466,38 @@ window.$docsify = {
466466
themeColor: '#3F51B5'
467467
}
468468
```
469+
470+
## Plugins
471+
472+
### 全文检索 - search
473+
474+
一份文档如果能有搜索功能会提升一些用户体验,加载搜索插件也很简单,直接引入就自动安装并启用。默认情况下会自动分析当前页面上的超链接,获取内容后建立索引并存储在 localStorage 里,默认过期时间为一天,当然这是可配置的。
475+
476+
自动识别的方式不一定能识别完整或者如果你想指定某些文件可索引,你可以自己指定文件的路径。
477+
478+
```html
479+
<script src="//unpkg.com/docsify/lib/docsify.js"></script>
480+
<script src="//unpkg.com/docsify/lib/plugins/search.js"></script>
481+
```
482+
483+
!> 配置要在 docsify 引入之前
484+
485+
```js
486+
window.$docsify = {
487+
search: 'auto', // default
488+
489+
search : [
490+
'/', // => /README.md
491+
'/guide', // => /guide.md
492+
'/get-started', // => /get-started.md
493+
'/zh-cn/', // => /zh-cn/README.md
494+
],
495+
496+
// Full configuration
497+
search: {
498+
maxAge: 86400000, // Expiration time, the default one day
499+
paths: [], // or 'auto'
500+
placeholder: 'Type to search'
501+
}
502+
}
503+
```

src/event.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ export function bindToggle (dom) {
126126
dom.addEventListener('click', () => body.classList.toggle('close'))
127127

128128
if (isMobile()) {
129-
const sidebar = document.querySelector('.sidebar div')
129+
const sidebar = document.querySelector('.sidebar')
130130
sidebar.addEventListener('click', () => {
131131
body.classList.toggle('close')
132132
setTimeout(() => activeLink(sidebar, true), 0)

src/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ const mainRender = function (cb) {
5858
}
5959

6060
let page
61+
6162
if (!route) {
6263
page = OPTIONS.homepage || 'README.md'
6364
} else if (/\/$/.test(route)) {

src/plugins/search.js

+16-14
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,14 @@ const genFilePath = function (path) {
5050

5151
filePath = basePath + filePath
5252

53-
return filePath.replace(/\/\//g, '/')
53+
return filePath.replace(/\/+/g, '/')
5454
}
5555

5656
/**
5757
* generate index
5858
*/
5959
const genIndex = function (path, content = '') {
60-
// INDEXS[path] = {}
60+
INDEXS[path] = { slug: '', title: '', body: '' }
6161
let slug
6262

6363
content
@@ -73,7 +73,7 @@ const genIndex = function (path, content = '') {
7373
// <h1 id="xxx"></h1>
7474
const id = attr.match(/id="(\S+)"/)[1]
7575

76-
slug = `#/${path}#${id}`.replace(/\/\//, '/')
76+
slug = `#/${path}#${id}`.replace(/\/+/, '/')
7777
INDEXS[slug] = { slug, title: text, body: '' }
7878
} else {
7979
// other html tag
@@ -221,12 +221,10 @@ class SearchComponent {
221221
for (let i = 0; i < data.length; i++) {
222222
const post = data[i]
223223
let isMatch = false
224-
let matchingNum = 0
225224
let resultStr = ''
226225
const postTitle = post.title && post.title.trim()
227226
const postContent = post.body && post.body.trim()
228227
const postUrl = post.slug || ''
229-
const postType = post.pagetitle
230228

231229
if (postTitle !== '' && postContent !== '') {
232230
keywords.forEach((keyword, i) => {
@@ -241,7 +239,6 @@ class SearchComponent {
241239
isMatch = false
242240
} else {
243241
isMatch = true
244-
matchingNum++
245242
if (indexContent < 0) indexContent = 0
246243

247244
let start = 0
@@ -266,9 +263,7 @@ class SearchComponent {
266263
const matchingPost = {
267264
title: escapeHtml(postTitle),
268265
content: resultStr,
269-
url: postUrl,
270-
type: postType,
271-
matchingNum: matchingNum
266+
url: postUrl
272267
}
273268

274269
matchingResults.push(matchingPost)
@@ -280,23 +275,30 @@ class SearchComponent {
280275
}
281276
}
282277

283-
// TODO 如果不存在就重新加载
284278
const searchPlugin = function () {
285-
if (localStorage.getItem('docsify.search.expires') > Date.now()) {
286-
INDEXS = JSON.parse(localStorage.getItem('docsify.search.index'))
279+
const isAuto = CONFIG.paths === 'auto'
280+
const isExpired = localStorage.getItem('docsify.search.expires') < Date.now()
281+
282+
INDEXS = JSON.parse(localStorage.getItem('docsify.search.index'))
283+
284+
if (isExpired) {
285+
INDEXS = {}
286+
} else if (!isAuto) {
287287
return
288288
}
289289

290-
const paths = CONFIG.paths === 'auto' ? getAllPaths() : CONFIG.paths
290+
let count = 0
291+
const paths = isAuto ? getAllPaths() : CONFIG.paths
291292
const len = paths.length
292293
const { load, marked, slugify } = window.Docsify.utils
293-
let count = 0
294294
const done = () => {
295295
localStorage.setItem('docsify.search.expires', Date.now() + CONFIG.maxAge)
296296
localStorage.setItem('docsify.search.index', JSON.stringify(INDEXS))
297297
}
298298

299299
paths.forEach(path => {
300+
if (INDEXS[path]) return count++
301+
300302
load(genFilePath(path)).then(content => {
301303
genIndex(path, marked(content))
302304
slugify.clear()

src/render.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export function init () {
4343
}
4444
renderer.link = function (href, title, text) {
4545
if (!/:/.test(href)) {
46-
href = `#/${href}`.replace(/\/\//g, '/')
46+
href = `#/${href}`.replace(/\/+/g, '/')
4747
}
4848

4949
return `<a href="${href}" title="${title || ''}">${text}</a>`

src/util.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export function getRoute () {
8989
const loc = window.location
9090
if (cacheHash === loc.hash && !isNil(cacheRoute)) return cacheRoute
9191

92-
let route = loc.hash.match(/^#\/([^#]+)/)
92+
let route = loc.hash.replace(/%23/g, '#').match(/^#\/([^#]+)/)
9393

9494
if (route && route.length === 2) {
9595
route = route[1]

0 commit comments

Comments
 (0)