Welcome to mirror list, hosted at ThFree Co, Russian Federation.

postpone.js « js « assets - gitlab.com/rmaguiar/hugo-theme-color-your-world.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 529f92881eb8868d10a69c9ba366b5ef48942f14 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
'use strict';

// =================================================
// Accent color palette
// =================================================

const PALETTE = document.querySelector('footer input');

PALETTE.onchange = function () {

  const PICK = PALETTE.value;

  SHEET.setProperty('--accent', PICK);
  
  if (ROOT.dataset.mode === 'light') {
    localStorage.setItem('lightAccent', PICK)
  } else {
    localStorage.setItem('darkAccent', PICK)
  };
  
  updateAccent()
};

// =================================================
// Basic search functionality via Fuse.js
// Based on: https://gist.github.com/eddiewebb/735feb48f50f0ddd65ae5606a1cb41ae#gistcomment-2987774
// =================================================

{{ if eq .Layout "search" }}

  // Get latest Fuse.js (basic build) available
  {{ (index (last 1 (resources.Match "libs/fuse.js@*/dist/fuse.basic.min.js")) 0).Content | safeJS }}

  const fuseOptions = {
    shouldSort: true,
    threshold: 0,
    ignoreLocation: true,
    maxPatternLength: {{ .Site.Params.Search.maxLength | default .Site.Data.default.search.maxLength }},
    minMatchCharLength: {{ .Site.Params.Search.minLength | default .Site.Data.default.search.minLength }},
    keys: [
      { name: 'title',        weight: .4 },
      { name: 'tags',         weight: .3 },
      { name: 'description',  weight: .2 },
      { name: 'content',      weight: .1 }
    ]
  };

  // Sanitize
  function param(name) {
    return decodeURIComponent((location.search.split(name + '=')[1] || '').split('&')[0]).replace(/\+/g, ' ')
  };
  
  // Capture input
  let searchQuery = param('q');
  
  // Search info section
  const info = document.getElementById('search-info');

  if (searchQuery) {
  
    // Transfer text to search field
    document.querySelector('section.search-box input')
      .value = searchQuery;
    
    executeSearch(searchQuery);
  } else {
    info.innerHTML = '<p>{{ T "search_awaiting_search" }}</p>'
  };
  

  function getJSON(url, fn) {
    const request = new XMLHttpRequest();
    request.open('GET', url, true);
    request.onload = function () {
      if (request.status >= 200 && request.status < 400) {
        const data = JSON.parse(request.responseText);
        fn(data)
      }
    };
    request.send()
  };

  function executeSearch(searchQuery) {
    getJSON('index.json', function (data) {
      
      // Limit results and throw an error if too many pages are found
      const limit = {{ .Site.Params.Search.maxResults | default 30 }};
      
      const pages = data;
      const fuse = new Fuse(pages, fuseOptions);
      const result = fuse.search(searchQuery);

      // Reset info regarding the search
      info.innerHTML = '';
      
      info.innerHTML = '<p>{{ T "search_results_for" }}: ' + searchQuery + '</p>';
      
      if (result.length > 0) {
        if (result.length == 1) {
          info.innerHTML += '<p>{{ T "search_one_page_found" }}.</p>'
        } else if (1 < result.length && result.length < limit + 1) {
          info.innerHTML += '<p>' + result.length + ' {{ T "search_pages_found" }}.</p>'
        } else {
          info.innerHTML += '<p class=error>{{ T "search_too_many" }}</p>'
        }
      } else {
        info.innerHTML += '<p class=error>{{ T "search_no_page_found" }}</p>'
      };
      
      if (0 < result.length && result.length < limit + 1) {
        populateResults(result)
      }
    })
  };

  // Populate results
  function populateResults(result) {
    result.forEach(function (value, key) {
      const content = value.item.content;
      
      // Date as it should be rendered if not null
      const formatedDate = '<time datetime=' + value.item.date + '>' + value.item.date + '</time>';

      // Pull template from hugo template definition
      const templateDefinition = document.getElementById('search-result-template').innerHTML;

      // Replace values
      const output = render(templateDefinition, {
        link  : value.item.permalink,
        date  : value.item.date ? formatedDate : '',
        title : value.item.title
      });
      document.getElementById('search-results').appendChild(htmlToElement(output))
    })
  };

  function render(templateString, data) {
    let conditionalMatches, conditionalPattern, copy;
    
    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 content.
        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
  };


  function htmlToElement(html) {
    const template = document.createElement('template');
    html = html.trim(); // Never return a text node of whitespace as the result
    template.innerHTML = html;
    return template.content.firstChild
  };
  
{{ end }}