This commit is contained in:
Antón Molleda 2021-03-22 16:34:01 -07:00 коммит произвёл GitHub
Родитель d4ea1247e8
Коммит 18a7cb1df1
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 11 добавлений и 205 удалений

Просмотреть файл

@ -108,7 +108,7 @@ describe('electronjs.org', () => {
cy.get('.nav-search').clear() 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.get('.nav-search').type('window')
cy.wait(500) cy.wait(500)
let types = ['#tutorial-hits', '#api-hits', '#package-hits', '#app-hits'] 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.get('.nav-search').type('window')
cy.wait(500) cy.wait(500)
cy.get('.ais-hits--item em').contains('window') cy.get('.ais-hits--item em').contains('window')

Просмотреть файл

@ -1,7 +1,4 @@
import search from './search'
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
search()
require('./lazy-load-images')() require('./lazy-load-images')()
require('./get-localized-strings')() require('./get-localized-strings')()
require('./create-filter-list')() 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>
<script src="{{static-asset "js" "index.js"}}"></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> </body>
</html> </html>

Просмотреть файл

@ -44,6 +44,7 @@
<link rel="alternate" type="application/rss+xml" title="Electron Releases" href="https://electronjs.org/releases.xml" /> <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='{{static-asset "css" "index.css"}}'>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css" />
<script> <script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (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), (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),