chore: migrate to docsearch (#5233)
This commit is contained in:
Родитель
d4ea1247e8
Коммит
18a7cb1df1
|
@ -108,7 +108,7 @@ describe('electronjs.org', () => {
|
|||
cy.get('.nav-search').clear()
|
||||
})
|
||||
|
||||
it('the results returned from searching match the results returned from each algolia index', () => {
|
||||
xit('the results returned from searching match the results returned from each algolia index', () => {
|
||||
cy.get('.nav-search').type('window')
|
||||
cy.wait(500)
|
||||
let types = ['#tutorial-hits', '#api-hits', '#package-hits', '#app-hits']
|
||||
|
@ -124,7 +124,7 @@ describe('electronjs.org', () => {
|
|||
})
|
||||
})
|
||||
|
||||
it('highlights what is typed in the input', () => {
|
||||
xit('highlights what is typed in the input', () => {
|
||||
cy.get('.nav-search').type('window')
|
||||
cy.wait(500)
|
||||
cy.get('.ais-hits--item em').contains('window')
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
import search from './search'
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
search()
|
||||
require('./lazy-load-images')()
|
||||
require('./get-localized-strings')()
|
||||
require('./create-filter-list')()
|
||||
|
|
|
@ -1,200 +0,0 @@
|
|||
const templates = require('../templates')
|
||||
import instantsearch from 'instantsearch.js'
|
||||
import { searchBox, hits } from 'instantsearch.js/es/widgets'
|
||||
const pluralize = require('pluralize')
|
||||
const searchWithYourKeyboard = require('search-with-your-keyboard')
|
||||
const searches = {}
|
||||
const types = [
|
||||
{
|
||||
name: 'api',
|
||||
path: '/docs/api',
|
||||
},
|
||||
{
|
||||
name: 'tutorial',
|
||||
path: '/docs/tutorial',
|
||||
},
|
||||
{
|
||||
name: 'package',
|
||||
path: '/community',
|
||||
},
|
||||
]
|
||||
const typeNames = types.map((type) => type.name)
|
||||
|
||||
export default () => {
|
||||
buildMultiSearch()
|
||||
buildSearchUIHandlers()
|
||||
determineOrder()
|
||||
searchWithYourKeyboard('#search-input', '.ais-hits--item')
|
||||
}
|
||||
|
||||
function buildSearch(type, isPrimarySearch = false, searches) {
|
||||
const opts = {
|
||||
appId: 'L9LD9GHGQJ',
|
||||
apiKey: '24e7e99910a15eb5d9d93531e5682370',
|
||||
indexName: pluralize(type),
|
||||
advancedSyntax: true,
|
||||
}
|
||||
|
||||
// the primary search delegates queries to secondary searches
|
||||
if (isPrimarySearch) {
|
||||
// sync search input with query param in address bar
|
||||
opts.routing = {
|
||||
stateMapping: {
|
||||
stateToRoute(UIstate) {
|
||||
// Use 'q' parameter in route instead of 'query'
|
||||
return { q: UIstate.query }
|
||||
},
|
||||
routeToState(routeState) {
|
||||
return { query: routeState.q }
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
opts.searchFunction = (helper) => {
|
||||
let query = helper.state.query
|
||||
|
||||
// should search be isolated to a specific type?
|
||||
// e.g. `is:app foo` or `app:foo`
|
||||
const isolatedType = typeNames.find((typeName) => {
|
||||
return (
|
||||
query.includes(`is:${typeName}`) || query.includes(`${typeName}:`)
|
||||
)
|
||||
})
|
||||
|
||||
// hide hit containers if a specific type is isolated
|
||||
typeNames.forEach((typeName) => {
|
||||
const display =
|
||||
!isolatedType || isolatedType === typeName ? 'block' : 'none'
|
||||
document.getElementById(`${typeName}-hits`).style.display = display
|
||||
})
|
||||
|
||||
// remove `is:foo` filter from query
|
||||
// TODO: figure out a way to make this affect the search
|
||||
// without affecting the input element or the query param
|
||||
// if (isolatedType) {
|
||||
// query = query.replace(`is:${isolatedType}`, '').trim()
|
||||
// }
|
||||
|
||||
// hide the primary search results' container if no results
|
||||
const primarySearch = searches[types[0].name]
|
||||
if (primarySearch && primarySearch.helper)
|
||||
primarySearch.helper.once('result', onResult)
|
||||
|
||||
// delegate query to secondary searches
|
||||
types.slice(1).forEach((type) => {
|
||||
const search = searches[type.name]
|
||||
if (search && search.helper) {
|
||||
search.helper.once('result', onResult)
|
||||
search.helper.setQuery(query).search()
|
||||
}
|
||||
})
|
||||
|
||||
// trigger the primary search
|
||||
helper.setQuery(query).search()
|
||||
}
|
||||
}
|
||||
|
||||
// https://community.algolia.com/algoliasearch-helper-js/reference.html#AlgoliaSearchHelper#event:search
|
||||
function onResult(results, state) {
|
||||
const id = `${state.index.replace(/s$/, '')}-hits`
|
||||
document.getElementById(id).style.display =
|
||||
results.hits.length === 0 ? 'none' : 'block'
|
||||
}
|
||||
|
||||
const search = instantsearch(opts)
|
||||
|
||||
search.addWidget(
|
||||
hits({
|
||||
container: `#${type}-hits`,
|
||||
templates: {
|
||||
// empty: 'No results',
|
||||
item: templates[type],
|
||||
},
|
||||
transformData: {
|
||||
item: (data) => {
|
||||
// useful for viewing template context:
|
||||
// console.log(`${type} data`, data)
|
||||
return data
|
||||
},
|
||||
},
|
||||
})
|
||||
)
|
||||
|
||||
if (isPrimarySearch) {
|
||||
search.addWidget(
|
||||
searchBox({
|
||||
container: '#search-input',
|
||||
placeholder: `Search Electron ${pluralize(type)}`,
|
||||
autofocus: false,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
search.on('render', (...args) => {
|
||||
// console.log(`algolia render (${type})`, args)
|
||||
})
|
||||
|
||||
search.on('error', (...args) => {
|
||||
console.log(`algolia error (${type})`, args)
|
||||
})
|
||||
|
||||
searches[type] = search
|
||||
|
||||
search.start()
|
||||
}
|
||||
|
||||
function determineOrder() {
|
||||
types.forEach((type) => {
|
||||
if (location.pathname === type.path)
|
||||
document.getElementById(`${type.name}-hits`).className = 'first'
|
||||
})
|
||||
}
|
||||
|
||||
function buildMultiSearch() {
|
||||
types.forEach((type) => {
|
||||
buildSearch(type.name, type.name === types[0].name, searches)
|
||||
})
|
||||
}
|
||||
|
||||
function buildSearchUIHandlers() {
|
||||
if (location.search.includes('query=')) showHits()
|
||||
|
||||
let navInput = document.querySelector('.nav-search')
|
||||
let hits = document.getElementById('hits')
|
||||
navInput.addEventListener('input', (e) => {
|
||||
navInput.value ? showHits() : hideHits()
|
||||
})
|
||||
navInput.addEventListener('focus', (e) => {
|
||||
navInput.value ? showHits() : hideHits()
|
||||
})
|
||||
window.addEventListener('click', (e) => {
|
||||
if (!navInput.value) return hideHits()
|
||||
|
||||
e.target === navInput || checkIfChild(hits, e.target)
|
||||
? showHits()
|
||||
: hideHits()
|
||||
})
|
||||
|
||||
// window.addEventListener('click', e => {
|
||||
// if (e.target === document.querySelector('.dialog-button')) document.querySelector('#search-hint-dialog').style.display = 'none'
|
||||
// })
|
||||
|
||||
function showHits() {
|
||||
document.getElementById('hits').style.display = 'block'
|
||||
// document.getElementById('search-hint').style.display="none"
|
||||
// document.querySelector('#search-hint-dialog').style.display = "none"
|
||||
}
|
||||
|
||||
function hideHits() {
|
||||
document.getElementById('hits').style.display = 'none'
|
||||
// document.getElementById('search-hint').style.display = "inline"
|
||||
}
|
||||
|
||||
function checkIfChild(parentElement, checkElement) {
|
||||
parentElement.childNodes.forEach((node) => {
|
||||
if (node === checkElement) return true
|
||||
checkIfChild(node, checkElement)
|
||||
})
|
||||
return false
|
||||
}
|
||||
}
|
|
@ -23,5 +23,13 @@
|
|||
}
|
||||
</script>
|
||||
<script src="{{static-asset "js" "index.js"}}"></script>
|
||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js"></script>
|
||||
<script type="text/javascript"> docsearch({
|
||||
apiKey: 'c9e8f898b3b32afe40f0a96637e7ea85',
|
||||
indexName: 'electronjs',
|
||||
inputSelector: '#search-input',
|
||||
debug: false // Set debug to true if you want to inspect the dropdown
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
<link rel="alternate" type="application/rss+xml" title="Electron Releases" href="https://electronjs.org/releases.xml" />
|
||||
<link rel='stylesheet' href='{{static-asset "css" "index.css"}}'>
|
||||
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css" />
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
|
|
Загрузка…
Ссылка в новой задаче