mirror of
https://github.com/wahyd4/docsify.git
synced 2026-08-09 13:26:34 +10:00
202 lines
4.1 KiB
JavaScript
202 lines
4.1 KiB
JavaScript
import { search } from './search'
|
|
|
|
let NO_DATA_TEXT = ''
|
|
|
|
function style () {
|
|
const code = `
|
|
.sidebar {
|
|
padding-top: 0;
|
|
}
|
|
|
|
.search {
|
|
margin-bottom: 20px;
|
|
padding: 6px;
|
|
border-bottom: 1px solid #eee;
|
|
}
|
|
|
|
.search .input-wrap {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.search .results-panel {
|
|
display: none;
|
|
}
|
|
|
|
.search .results-panel.show {
|
|
display: block;
|
|
}
|
|
|
|
.search input {
|
|
outline: none;
|
|
border: none;
|
|
width: 100%;
|
|
padding: 0 7px;
|
|
line-height: 36px;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.search input::-webkit-search-decoration,
|
|
.search input::-webkit-search-cancel-button,
|
|
.search input {
|
|
-webkit-appearance: none;
|
|
-moz-appearance: none;
|
|
appearance: none;
|
|
}
|
|
.search .clear-button {
|
|
width: 36px;
|
|
text-align: right;
|
|
display: none;
|
|
}
|
|
|
|
.search .clear-button.show {
|
|
display: block;
|
|
}
|
|
|
|
.search .clear-button svg {
|
|
transform: scale(.5);
|
|
}
|
|
|
|
.search h2 {
|
|
font-size: 17px;
|
|
margin: 10px 0;
|
|
}
|
|
|
|
.search a {
|
|
text-decoration: none;
|
|
color: inherit;
|
|
}
|
|
|
|
.search .matching-post {
|
|
border-bottom: 1px solid #eee;
|
|
}
|
|
|
|
.search .matching-post:last-child {
|
|
border-bottom: 0;
|
|
}
|
|
|
|
.search p {
|
|
font-size: 14px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 2;
|
|
-webkit-box-orient: vertical;
|
|
}
|
|
|
|
.search p.empty {
|
|
text-align: center;
|
|
}`
|
|
|
|
Docsify.dom.style(code)
|
|
}
|
|
|
|
function tpl (opts, defaultValue = '') {
|
|
const html =
|
|
`<div class="input-wrap">
|
|
<input type="search" value="${defaultValue}" />
|
|
<div class="clear-button">
|
|
<svg width="26" height="24">
|
|
<circle cx="12" cy="12" r="11" fill="#ccc" />
|
|
<path stroke="white" stroke-width="2" d="M8.25,8.25,15.75,15.75" />
|
|
<path stroke="white" stroke-width="2"d="M8.25,15.75,15.75,8.25" />
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
<div class="results-panel"></div>
|
|
</div>`
|
|
const el = Docsify.dom.create('div', html)
|
|
const aside = Docsify.dom.find('aside')
|
|
|
|
Docsify.dom.toggleClass(el, 'search')
|
|
Docsify.dom.before(aside, el)
|
|
}
|
|
|
|
function doSearch (value) {
|
|
const $search = Docsify.dom.find('div.search')
|
|
const $panel = Docsify.dom.find($search, '.results-panel')
|
|
const $clearBtn = Docsify.dom.find($search, '.clear-button')
|
|
|
|
if (!value) {
|
|
$panel.classList.remove('show')
|
|
$clearBtn.classList.remove('show')
|
|
$panel.innerHTML = ''
|
|
return
|
|
}
|
|
const matchs = search(value)
|
|
|
|
let html = ''
|
|
matchs.forEach(post => {
|
|
html += `<div class="matching-post">
|
|
<a href="${post.url}">
|
|
<h2>${post.title}</h2>
|
|
<p>${post.content}</p>
|
|
</a>
|
|
</div>`
|
|
})
|
|
|
|
$panel.classList.add('show')
|
|
$clearBtn.classList.add('show')
|
|
$panel.innerHTML = html || `<p class="empty">${NO_DATA_TEXT}</p>`
|
|
}
|
|
|
|
function bindEvents () {
|
|
const $search = Docsify.dom.find('div.search')
|
|
const $input = Docsify.dom.find($search, 'input')
|
|
const $inputWrap = Docsify.dom.find($search, '.input-wrap')
|
|
|
|
let timeId
|
|
// Prevent to Fold sidebar
|
|
Docsify.dom.on(
|
|
$search,
|
|
'click',
|
|
e => e.target.tagName !== 'A' && e.stopPropagation()
|
|
)
|
|
Docsify.dom.on($input, 'input', e => {
|
|
clearTimeout(timeId)
|
|
timeId = setTimeout(_ => doSearch(e.target.value.trim()), 100)
|
|
})
|
|
Docsify.dom.on($inputWrap, 'click', e => {
|
|
// click input outside
|
|
if (e.target.tagName !== 'INPUT') {
|
|
$input.value = ''
|
|
doSearch()
|
|
}
|
|
})
|
|
}
|
|
|
|
function updatePlaceholder (text, path) {
|
|
const $input = Docsify.dom.getNode('.search input[type="search"]')
|
|
|
|
if (!$input) return
|
|
if (typeof text === 'string') {
|
|
$input.placeholder = text
|
|
} else {
|
|
const match = Object.keys(text).filter(key => path.indexOf(key) > -1)[0]
|
|
$input.placeholder = text[match]
|
|
}
|
|
}
|
|
|
|
function updateNoData (text, path) {
|
|
if (typeof text === 'string') {
|
|
NO_DATA_TEXT = text
|
|
} else {
|
|
const match = Object.keys(text).filter(key => path.indexOf(key) > -1)[0]
|
|
NO_DATA_TEXT = text[match]
|
|
}
|
|
}
|
|
|
|
export function init (opts, vm) {
|
|
const keywords = vm.router.parse().query.s
|
|
|
|
style()
|
|
tpl(opts, keywords)
|
|
bindEvents()
|
|
keywords && setTimeout(_ => doSearch(keywords), 500)
|
|
}
|
|
|
|
export function update (opts, vm) {
|
|
updatePlaceholder(opts.placeholder, vm.route.path)
|
|
updateNoData(opts.noData, vm.route.path)
|
|
}
|