diff --git a/scripts/generate.py b/scripts/generate.py index 3dcaee6..688aabf 100644 --- a/scripts/generate.py +++ b/scripts/generate.py @@ -481,7 +481,14 @@ def as_document(html, title): + {html} + + + """ diff --git a/scripts/search-server/server.go b/scripts/search-server/server.go index 37f04fa..2f6cbc1 100644 --- a/scripts/search-server/server.go +++ b/scripts/search-server/server.go @@ -49,7 +49,19 @@ func main() { }) }) + api.OPTIONS("/search", func(c *gin.Context) { + c.Writer.Header().Set("Access-Control-Allow-Origin", "*") + c.Writer.Header().Set("Access-Control-Allow-Headers", "Accept-Encoding, Authorization, accept, origin, Cache-Control, X-Requested-With") + c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS") + + c.AbortWithStatus(204) + }) + api.GET("/search", func(c *gin.Context) { + c.Writer.Header().Set("Access-Control-Allow-Origin", "*") + c.Writer.Header().Set("Access-Control-Allow-Headers", "Accept-Encoding, Authorization, accept, origin, Cache-Control, X-Requested-With") + c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS") + query := c.Query("q") stm, err := db.Prepare("SELECT note_id, title FROM note_search WHERE title LIKE ?") diff --git a/static/search-box.js b/static/search-box.js new file mode 100644 index 0000000..fe2e056 --- /dev/null +++ b/static/search-box.js @@ -0,0 +1,55 @@ +function _codigoparallevar_enable_search_box(selector, options) { + const element = document.querySelector(selector); + if ('placeholder' in options) { + element.setAttribute('placeholder', options.placeholder); + } + + // Prepare backdrop + const resultsBoxBackdrop = document.createElement('div'); + resultsBoxBackdrop.setAttribute('class', 'results-box-container hidden'); + const resultsBox = document.createElement('div'); + resultsBox.setAttribute('class', 'results-box'); + + resultsBoxBackdrop.appendChild(resultsBox); + document.body.appendChild(resultsBoxBackdrop); + + + const DEBOUNCE_TIME = 500; // Milliseconds + const MIN_LENGTH = 3; + const SEARCH_ENDPOINT = 'http://localhost:3001/api/search'; + + let debounceWaiter = null; + let currentQuery = null; + + let lastVal = null; + const doQuery = () => { + const val = element.value.trim(); + if ((val.length < MIN_LENGTH) || (val === lastVal)) { + return; + } + lastVal = val; + + const uri = SEARCH_ENDPOINT + '?q=' + encodeURIComponent(val); + let query = fetch(uri); + currentQuery = query; + query + .then(res => res.json()) + .then((body) => { + if (query !== currentQuery) { + console.log("Query out-raced 🤷"); + return; + } + + console.log('=>', body); + }); + }; + element.removeAttribute('disabled'); + + element.onkeyup = (ev) => { + if (debounceWaiter !== null) { + clearTimeout(debounceWaiter); + } + debounceWaiter = setTimeout(doQuery, DEBOUNCE_TIME); + + }; +} diff --git a/static/style.css b/static/style.css index aad771b..bf7f170 100644 --- a/static/style.css +++ b/static/style.css @@ -11,6 +11,28 @@ body { margin: 0 auto; } +body nav { + text-align: center; +} +body nav h1 { + text-align: center; + color: #000; + display: inline-block; +} +body nav input { + background-color: transparent; + color: #000; + border: none; + border-bottom: 1px solid #222; +} +.results-box-container { + z-index: 5; + position: absolute; + width: 100vw; + height: 100vh; + background-color: rgba(0,0,0,0.3); +} + @font-face { font-family: "Atkinson Hyperlegible"; src: url('./fonts/atkinson-hyperlegible/eot/Atkinson-Hyperlegible-Regular-102.eot'); @@ -115,7 +137,7 @@ li .tag::after { pre { overflow: auto; padding: 0.25ex; - box-shadow: 0px 2px 4px 2px rgba(0, 0, 0, 0.26); + box-shadow: 0px 1px 2px 1px rgba(0, 0, 0, 0.25); border-radius: 2px; } pre > code { @@ -212,6 +234,7 @@ tr.__table-separator { background-color: #111; color: #fafafe; } + h2 a { color: #fafafe; } @@ -233,6 +256,15 @@ tr.__table-separator { border-right: 1px solid #fff; } + /* Nav bar */ + body nav h1 { + color: #eee; + } + body nav input { + color: #ddd; + border-bottom: 1px solid #888; + } + /* Code blocks */ pre { padding: 0.5ex;