diff --git a/editor/src/index.js b/editor/src/index.js index 2dc6ecf..f758226 100644 --- a/editor/src/index.js +++ b/editor/src/index.js @@ -65,26 +65,100 @@ function addIndicator(editor, indicator) { let holder = document.getElementById('editor'); 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) - if (results.length === 0) { - return + let opt = options || {}; + + 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, {}) - let off = $(input).offset() - 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}, {}, ['[[', ']]']); + var templateText = document.getElementById(template).innerHTML; + var rendered = Mustache.render(templateText, {page: value, results: results}, {}, ['[[', ']]']); $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) { let editor = listEditor(holder, JSON.parse(holder.dataset.input)); @@ -101,57 +175,10 @@ if (holder) { ).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}) { editor.on('start-editing', function (input) { - const $lc = $('#link-complete') - - $lc.on('popup:selected', function (event, linkName, resultType) { + const $lc = $('#link-complete'); + $lc.on('popup:selected', function (event, linkName, resultType, element) { let value = input.value let end = input.selectionEnd if (resultType === 'link') { @@ -216,7 +243,6 @@ if (holder) { $(input).on('keydown', function (event) { const isVisible = $('#link-complete:visible').length > 0; - const $lc = $('#link-complete') if (event.key === 'Escape' && isVisible) { $lc.fadeOut() return false @@ -227,6 +253,7 @@ if (holder) { $lc.find('li:first-child').addClass('selected') return false } + return true }) @@ -268,7 +295,6 @@ if (holder) { $('#link-complete').off() }) }) - $.contextMenu({ selector: '.marker', items: { @@ -287,29 +313,29 @@ if (holder) { let timeout = null; let searchInput = document.getElementById('search-input'); search(searchInput).then(searcher => { - searchInput.addEventListener('keyup', function (e) { - clearTimeout(timeout); - if (e.key === 'Escape') { - $(searchInput).val(''); - $('#autocomplete').hide(); - return; - } + $(document).on('keyup', '#search-input', function (event) { + clearTimeout(timeout); timeout = setTimeout(function () { let query = $(searchInput).val() if (query === '') { let autocomplete = document.getElementById('autocomplete'); $(autocomplete).hide() - return + return false } - $('#autocomplete').show() - let result = searcher.search(query) - const newpage = query.replace(/\s+/g, '_') - var template = document.getElementById('result-template').innerHTML; - var rendered = Mustache.render(template, {page: newpage, results: result}, {}, ['[[', ']]']); - let autocomplete = document.getElementById('autocomplete'); - autocomplete.innerHTML = rendered; - }, 500) + + showSearchResultsExtended('#autocomplete', 'result-template', query => searcher.search(query), query, searchInput, query, 'search-result') + + // $('#autocomplete').show() + // let result = searcher.search(query) + // const newpage = query.replace(/\s+/g, '_') + // var template = document.getElementById('result-template').innerHTML; + // var rendered = Mustache.render(template, {page: newpage, results: result}, {}, ['[[', ']]']); + // let autocomplete = document.getElementById('autocomplete'); + // autocomplete.innerHTML = rendered; + }, 200) + + return true }) }) diff --git a/templates/layout.html b/templates/layout.html index 5f7ce4b..ba84958 100644 --- a/templates/layout.html +++ b/templates/layout.html @@ -20,11 +20,16 @@ position: absolute; background: white; border: 1px solid #ccc; - padding: 16px; } #autocomplete li > a { white-space: nowrap; } + #autocomplete li { + padding: 4px 16px; + } + #autocomplete li.selected { + background: lightblue; + } #link-complete { z-index: 1; width: 217px; @@ -259,7 +264,7 @@
- + @@ -276,7 +281,7 @@ - + {{ block "footer_scripts" . }} {{ end }} @@ -285,7 +290,10 @@ [[#results]]