| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 | import Fuse from 'fuse.js'import Mark from 'mark.js'window.addEventListener('DOMContentLoaded', () => {  const summaryInclude = 60  const fuseOptions = {    shouldSort: true,    includeMatches: true,    threshold: 0.0,    tokenize: true,    location: 0,    distance: 100,    maxPatternLength: 32,    minMatchCharLength: 1,    keys: [      { name: 'title', weight: 0.8 },      { name: 'hero', weight: 0.7 },      { name: 'summary', weight: 0.6 },      { name: 'date', weight: 0.5 },      { name: 'contents', weight: 0.5 },      { name: 'tags', weight: 0.3 },      { name: 'categories', weight: 0.3 }    ]  }  const searchQuery = param('keyword')  if (searchQuery) {    document.getElementById('search-box').value = searchQuery    executeSearch(searchQuery)  } else {    const node = document.createElement('p')    node.textContent = 'Please enter a word or phrase above'    document.getElementById('search-results')?.append(node)  }  function executeSearch (searchQuery) {    const url = window.location.href.split('/search/')[0] + '/index.json'    fetch(url).then(response => response.json()).then(function (data) {      const pages = data      const fuse = new Fuse(pages, fuseOptions)      const results = fuse.search(searchQuery)      document.getElementById('search-box').value = searchQuery      if (results.length > 0) {        populateResults(results)      } else {        const node = document.createElement('p')        node.textContent = 'No matches found'        document.getElementById('search-results')?.append(node)      }    })  }  function populateResults (results) {    results.forEach(function (value, key) {      const contents = value.item.contents      let snippet = ''      const snippetHighlights = []      if (fuseOptions.tokenize) {        snippetHighlights.push(searchQuery)      } else {        value.matches.forEach(function (mvalue) {          if (mvalue.key === 'tags' || mvalue.key === 'categories') {            snippetHighlights.push(mvalue.value)          } else if (mvalue.key === 'contents') {            const start = mvalue.indices[0][0] - summaryInclude > 0 ? mvalue.indices[0][0] - summaryInclude : 0            const end = mvalue.indices[0][1] + summaryInclude < contents.length ? mvalue.indices[0][1] + summaryInclude : contents.length            snippet += contents.substring(start, end)            snippetHighlights.push(mvalue.value.substring(mvalue.indices[0][0], mvalue.indices[0][1] - mvalue.indices[0][0] + 1))          }        })      }      if (snippet.length < 1) {        snippet += contents.substring(0, summaryInclude * 2)      }      // pull template from hugo template definition      const templateDefinition = document.getElementById('search-result-template').innerHTML      // replace values      const output = render(templateDefinition, {        key,        title: value.item.title,        hero: value.item.hero,        date: value.item.date,        summary: value.item.summary,        link: value.item.permalink,        tags: value.item.tags,        categories: value.item.categories,        snippet      })      const dom = new DOMParser().parseFromString(output, 'text/html')      document.getElementById('search-results').append(dom.getElementsByClassName('post-card')[0])      snippetHighlights.forEach(function (snipvalue) {        const context = document.getElementById('#summary-' + key)        const instance = new Mark(context)        instance.mark(snipvalue)      })    })  }  function param (name) {    return decodeURIComponent((location.search.split(name + '=')[1] || '').split('&')[0]).replace(/\+/g, ' ')  }  function render (templateString, data) {    let conditionalMatches, copy    const conditionalPattern = /\$\{\s*isset ([a-zA-Z]*) \s*\}(.*)\$\{\s*end\s*}/g    // since loop below depends on re.lastInxdex, we use a copy to capture any manipulations whilst inside the loop    copy = templateString    while ((conditionalMatches = conditionalPattern.exec(templateString)) !== null) {      if (data[conditionalMatches[1]]) {        // valid key, remove conditionals, leave contents.        copy = copy.replace(conditionalMatches[0], conditionalMatches[2])      } else {        // not valid, remove entire section        copy = copy.replace(conditionalMatches[0], '')      }    }    templateString = copy    // now any conditionals removed we can do simple substitution    let key, find, re    for (key in data) {      find = '\\$\\{\\s*' + key + '\\s*\\}'      re = new RegExp(find, 'g')      templateString = templateString.replace(re, data[key])    }    return templateString  }})
 |