Improve searching for a page
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
bb439fcfe7
commit
e1254ba3b4
|
@ -65,26 +65,100 @@ function addIndicator(editor, indicator) {
|
||||||
let holder = document.getElementById('editor');
|
let holder = document.getElementById('editor');
|
||||||
|
|
||||||
function showSearchResults(searchTool, query, input, value, resultType) {
|
function showSearchResults(searchTool, query, input, value, resultType) {
|
||||||
|
showSearchResultsExtended('#link-complete', 'link-template', searchTool, query, input, value, resultType, {belowCursor: true})
|
||||||
|
}
|
||||||
|
|
||||||
|
function showSearchResultsExtended(element, template, searchTool, query, input, value, resultType, options) {
|
||||||
let results = searchTool(query)
|
let results = searchTool(query)
|
||||||
|
|
||||||
if (results.length === 0) {
|
let opt = options || {};
|
||||||
return
|
|
||||||
|
const $lc = $(element)
|
||||||
|
$lc.data('result-type', resultType)
|
||||||
|
|
||||||
|
if (opt.belowCursor) {
|
||||||
|
let pos = getCaretCoordinates(input, value.selectionEnd, {})
|
||||||
|
let off = $(input).offset()
|
||||||
|
pos.top += off.top + pos.height
|
||||||
|
pos.left += off.left
|
||||||
|
$lc.offset(pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
let pos = getCaretCoordinates(input, value.selectionEnd, {})
|
var templateText = document.getElementById(template).innerHTML;
|
||||||
let off = $(input).offset()
|
var rendered = Mustache.render(templateText, {page: value, results: results}, {}, ['[[', ']]']);
|
||||||
pos.top += off.top + pos.height
|
|
||||||
pos.left += off.left
|
|
||||||
|
|
||||||
const $lc = $('#link-complete')
|
|
||||||
$lc.data('result-type', resultType)
|
|
||||||
$lc.offset(pos)
|
|
||||||
|
|
||||||
var template = document.getElementById('link-template').innerHTML;
|
|
||||||
var rendered = Mustache.render(template, {results: results}, {}, ['[[', ']]']);
|
|
||||||
$lc.html(rendered).fadeIn()
|
$lc.html(rendered).fadeIn()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$(document).on('keydown', '.keyboard-list', function (event) {
|
||||||
|
console.log('keydown .keyboard-list')
|
||||||
|
if (!$(':visible', this).length) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
const $popup = $(this)
|
||||||
|
if (event.key === 'Escape') {
|
||||||
|
$popup.fadeOut()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (event.key === 'Enter') {
|
||||||
|
const element = $popup.find('li.selected')
|
||||||
|
const linkName = element.text()
|
||||||
|
$popup.trigger('popup:selected', [linkName, $popup.data('result-type'), element])
|
||||||
|
$popup.fadeOut()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (event.key === 'ArrowUp') {
|
||||||
|
const selected = $popup.find('li.selected')
|
||||||
|
const prev = selected.prev('li')
|
||||||
|
if (prev.length) {
|
||||||
|
prev.addClass('selected')
|
||||||
|
selected.removeClass('selected')
|
||||||
|
prev[0].scrollIntoView({block: 'center', inline: 'nearest'})
|
||||||
|
} else {
|
||||||
|
// move back from dropdown to input
|
||||||
|
$popup.trigger('popup:leave')
|
||||||
|
selected.removeClass('selected')
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (event.key === 'ArrowDown') {
|
||||||
|
const selected = $popup.find('li.selected')
|
||||||
|
const next = selected.next('li');
|
||||||
|
if (next.length) {
|
||||||
|
next.addClass('selected')
|
||||||
|
selected.removeClass('selected')
|
||||||
|
next[0].scrollIntoView({block: 'center', inline: 'nearest'})
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
$(document).on('keydown', '#search-input', function (event) {
|
||||||
|
console.log('keydown #search-input')
|
||||||
|
let $ac = $('#autocomplete');
|
||||||
|
let isVisible = $(':visible', $ac)
|
||||||
|
if (event.key === 'ArrowDown' && isVisible) {
|
||||||
|
$ac.focus()
|
||||||
|
$ac.find('li:first-child').addClass('selected')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (event.key === 'Escape') {
|
||||||
|
$(searchInput).val('');
|
||||||
|
$ac.fadeOut();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
$(document).on('popup:selected', '#autocomplete', function (event, linkName, resultType, element) {
|
||||||
|
if (resultType === 'search-result') {
|
||||||
|
element.find('a')[0].click()
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
if (holder) {
|
if (holder) {
|
||||||
let editor = listEditor(holder, JSON.parse(holder.dataset.input));
|
let editor = listEditor(holder, JSON.parse(holder.dataset.input));
|
||||||
|
|
||||||
|
@ -101,57 +175,10 @@ if (holder) {
|
||||||
).save()
|
).save()
|
||||||
})
|
})
|
||||||
|
|
||||||
$(document).on('keydown', '#link-complete', function (event) {
|
|
||||||
if (!$('#link-complete:visible')) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
const $popup = $('#link-complete')
|
|
||||||
if (event.key === 'Escape') {
|
|
||||||
$popup.fadeOut()
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.key === 'Enter') {
|
|
||||||
const linkName = $popup.find('li.selected').text()
|
|
||||||
$popup.trigger('popup:selected', [linkName, $popup.data('result-type')])
|
|
||||||
$popup.fadeOut()
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.key === 'ArrowUp') {
|
|
||||||
const selected = $popup.find('li.selected')
|
|
||||||
const prev = selected.prev('li')
|
|
||||||
if (prev.length) {
|
|
||||||
prev.addClass('selected')
|
|
||||||
selected.removeClass('selected')
|
|
||||||
prev[0].scrollIntoView()
|
|
||||||
} else {
|
|
||||||
// move back from dropdown to input
|
|
||||||
$popup.trigger('popup:leave')
|
|
||||||
selected.removeClass('selected')
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.key === 'ArrowDown') {
|
|
||||||
const selected = $popup.find('li.selected')
|
|
||||||
const next = selected.next('li');
|
|
||||||
if (next.length) {
|
|
||||||
next.addClass('selected')
|
|
||||||
selected.removeClass('selected')
|
|
||||||
next[0].scrollIntoView()
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
|
|
||||||
createPageSearch().then(function ({titleSearch, commandSearch, commands}) {
|
createPageSearch().then(function ({titleSearch, commandSearch, commands}) {
|
||||||
editor.on('start-editing', function (input) {
|
editor.on('start-editing', function (input) {
|
||||||
const $lc = $('#link-complete')
|
const $lc = $('#link-complete');
|
||||||
|
$lc.on('popup:selected', function (event, linkName, resultType, element) {
|
||||||
$lc.on('popup:selected', function (event, linkName, resultType) {
|
|
||||||
let value = input.value
|
let value = input.value
|
||||||
let end = input.selectionEnd
|
let end = input.selectionEnd
|
||||||
if (resultType === 'link') {
|
if (resultType === 'link') {
|
||||||
|
@ -216,7 +243,6 @@ if (holder) {
|
||||||
$(input).on('keydown', function (event) {
|
$(input).on('keydown', function (event) {
|
||||||
const isVisible = $('#link-complete:visible').length > 0;
|
const isVisible = $('#link-complete:visible').length > 0;
|
||||||
|
|
||||||
const $lc = $('#link-complete')
|
|
||||||
if (event.key === 'Escape' && isVisible) {
|
if (event.key === 'Escape' && isVisible) {
|
||||||
$lc.fadeOut()
|
$lc.fadeOut()
|
||||||
return false
|
return false
|
||||||
|
@ -227,6 +253,7 @@ if (holder) {
|
||||||
$lc.find('li:first-child').addClass('selected')
|
$lc.find('li:first-child').addClass('selected')
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -268,7 +295,6 @@ if (holder) {
|
||||||
$('#link-complete').off()
|
$('#link-complete').off()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
$.contextMenu({
|
$.contextMenu({
|
||||||
selector: '.marker',
|
selector: '.marker',
|
||||||
items: {
|
items: {
|
||||||
|
@ -287,29 +313,29 @@ if (holder) {
|
||||||
let timeout = null;
|
let timeout = null;
|
||||||
let searchInput = document.getElementById('search-input');
|
let searchInput = document.getElementById('search-input');
|
||||||
search(searchInput).then(searcher => {
|
search(searchInput).then(searcher => {
|
||||||
searchInput.addEventListener('keyup', function (e) {
|
|
||||||
clearTimeout(timeout);
|
|
||||||
|
|
||||||
if (e.key === 'Escape') {
|
$(document).on('keyup', '#search-input', function (event) {
|
||||||
$(searchInput).val('');
|
clearTimeout(timeout);
|
||||||
$('#autocomplete').hide();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
timeout = setTimeout(function () {
|
timeout = setTimeout(function () {
|
||||||
let query = $(searchInput).val()
|
let query = $(searchInput).val()
|
||||||
if (query === '') {
|
if (query === '') {
|
||||||
let autocomplete = document.getElementById('autocomplete');
|
let autocomplete = document.getElementById('autocomplete');
|
||||||
$(autocomplete).hide()
|
$(autocomplete).hide()
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
$('#autocomplete').show()
|
|
||||||
let result = searcher.search(query)
|
showSearchResultsExtended('#autocomplete', 'result-template', query => searcher.search(query), query, searchInput, query, 'search-result')
|
||||||
const newpage = query.replace(/\s+/g, '_')
|
|
||||||
var template = document.getElementById('result-template').innerHTML;
|
// $('#autocomplete').show()
|
||||||
var rendered = Mustache.render(template, {page: newpage, results: result}, {}, ['[[', ']]']);
|
// let result = searcher.search(query)
|
||||||
let autocomplete = document.getElementById('autocomplete');
|
// const newpage = query.replace(/\s+/g, '_')
|
||||||
autocomplete.innerHTML = rendered;
|
// var template = document.getElementById('result-template').innerHTML;
|
||||||
}, 500)
|
// var rendered = Mustache.render(template, {page: newpage, results: result}, {}, ['[[', ']]']);
|
||||||
|
// let autocomplete = document.getElementById('autocomplete');
|
||||||
|
// autocomplete.innerHTML = rendered;
|
||||||
|
}, 200)
|
||||||
|
|
||||||
|
return true
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -20,11 +20,16 @@
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background: white;
|
background: white;
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
padding: 16px;
|
|
||||||
}
|
}
|
||||||
#autocomplete li > a {
|
#autocomplete li > a {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
#autocomplete li {
|
||||||
|
padding: 4px 16px;
|
||||||
|
}
|
||||||
|
#autocomplete li.selected {
|
||||||
|
background: lightblue;
|
||||||
|
}
|
||||||
#link-complete {
|
#link-complete {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
width: 217px;
|
width: 217px;
|
||||||
|
@ -259,7 +264,7 @@
|
||||||
<p class="control">
|
<p class="control">
|
||||||
<input class="search input" id="search-input" type="text" placeholder="Find a page">
|
<input class="search input" id="search-input" type="text" placeholder="Find a page">
|
||||||
</p>
|
</p>
|
||||||
<div id="autocomplete" class="hidden"></div>
|
<div id="autocomplete" class="hide keyboard-list" tabindex="0"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -276,7 +281,7 @@
|
||||||
|
|
||||||
<div id="save-indicator" class="hide"></div>
|
<div id="save-indicator" class="hide"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="link-complete" class="hide" tabindex="0"></div>
|
<div id="link-complete" class="hide keyboard-list" tabindex="0"></div>
|
||||||
{{ block "footer_scripts" . }}
|
{{ block "footer_scripts" . }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
<script src="/public/index.bundle.js"></script>
|
<script src="/public/index.bundle.js"></script>
|
||||||
|
@ -285,7 +290,10 @@
|
||||||
[[#results]]
|
[[#results]]
|
||||||
<li><a href="/[[ref]]">[[title]]</a></li>
|
<li><a href="/[[ref]]">[[title]]</a></li>
|
||||||
[[/results]]
|
[[/results]]
|
||||||
<ll><a href="/edit/[[page]]">Create a page</a></ll>
|
[[^results]]
|
||||||
|
<li>No results</li>
|
||||||
|
[[/results]]
|
||||||
|
<li><a href="/edit/[[page]]">Create a page</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div id="link-template" class="hide">
|
<div id="link-template" class="hide">
|
||||||
|
@ -293,6 +301,9 @@
|
||||||
[[#results]]
|
[[#results]]
|
||||||
<li>[[item.title]]</li>
|
<li>[[item.title]]</li>
|
||||||
[[/results]]
|
[[/results]]
|
||||||
|
[[^results]]
|
||||||
|
<li>No results</li>
|
||||||
|
[[/results]]
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user