PageSourceSearch

https://www.readingwithausten.com/javascripts/catalogue.js

js readingwithausten.com collected 2026-10-02 12:00:05 UTC 13,513 bytes, 308 lines download raw bytes

1const QUERY_INPUT_PLACEHOLDERS = [
2    "Austen, Jane", "Shakespeare, William", "Homer", "Voltaire", "Swift, Jonathan", "Pope, Alexander"
3];
4
5// Randomize text field placeholder
6document.getElementById('query__input_text').placeholder = QUERY_INPUT_PLACEHOLDERS[Math.floor(Math.random()*QUERY_INPUT_PLACEHOLDERS.length)];
7
8var RESULTS_CONTAINER = document.getElementById('query__output');
9var RESULTS_LIST = document.getElementById('query__results');
10var NUMBER_RESULTS = document.getElementById('query__number-results_container');
11var filter_images = false;
12var total_results_shown = 0;
13var number_displayed_results = 18;
14var category = "";
15var query = "";
16var query_tokens = [];
17var query_result = [];
18
19document.addEventListener('keypress', function(event){
20    if(event.key == "Enter"){ queryCatalogue(); } 
21});
22
23function getFilterImages(){
24  if(filter_images && query_result.length > 0){
25    var resultWithImages = query_result.filter(function(bk){
26      return (bk.images && (bk.images == "yes"));
27    });
28    renderQuery(resultWithImages, query);
29  }else if(!filter_images && query_result.length > 0){
30    renderQuery(query_result,query);
31  }else{
32    renderQuery(query_result,query);
33  }
34}
35
36function pushBookToResults(book, id){
37    book["id"] = id;        // If found, add ID as param to book object
38    query_result.push(book);  
39}
40
41// Return first instance found
42function checkBookAttributes(book, id) {
43    var keys = Object.keys(book);
44    keys.forEach(function(key){
45      if(category == "pub_date"){
46        for(var i = 0; i < query_tokens.length; i++){
47          if(queryDatePublished(book, query_tokens[i])){
48            pushBookToResults(book, id);
49          } 
50        }
51      }else if (book[key]) {
52        var bk_value = book[key].toString().toLowerCase();
53        for(var i = 0; i < query_tokens.length; i++){
54          // For each value, check if token exists within it
55          if (bk_value.indexOf(query_tokens[i].toLowerCase()) > -1) {
56            pushBookToResults(book, id);
57          }
58        }
59      }
60    });
61}
62
63// Turns inputs into tokens and normalizes them
64// TODO:: refactor to accept query and return array of tokens
65function tokenizeQuery(){
66  if(query[0] == "\"" && query[query.length -1] == "\""){
67      query_tokens.push(query.replace(new RegExp("\"",'g'),""));  //remove quotes
68  }else{
69    query_tokens = query.split(' ');        
70    query_tokens.push(query);
71    for(var i = 0; i < query_tokens.length; i++){
72      query_tokens[i] = query_tokens[i].replace(/[.,\/#!$%\^&\*;:{}=\-_`~()\\]/g,"");   // remove special characters
73      query_tokens[i] = query_tokens[i].replace(/\s{2,}/g," "); // ?
74    }
75  }
76  // If yes is searched, true is also relevant
77  if(query_tokens.indexOf("yes") > -1){
78    query_tokens.push("true")
79  }
80}
81
82// TODO:: redo and optimize
83function queryCatalogue() {
84    RESULTS_LIST.innerHTML = "";
85    category = document.getElementsByName('category')[0].value;
86    query = document.getElementsByName('query')[0].value;
87    query_tokens = [];
88    tokenizeQuery();
89    filter_images = document.getElementById('query__check_filterImages').checked;
90    query_result = [];
91    
92    if (category == "all") {
93        Object.keys(COMPLETE_DATA).forEach(function(id){
94            checkBookAttributes(COMPLETE_DATA[id], id);
95        });
96    } else {
97        // Specific Category Selected
98        // TODO:: place this into checkBookAttributes, this is repeated
99        if(category === "id"){
100          query_tokens.forEach(token =>{
101            if(COMPLETE_DATA[token]) pushBookToResults(COMPLETE_DATA[token], token)
102          })
103        }else{
104          Object.keys(COMPLETE_DATA).forEach( id => {
105              let book = COMPLETE_DATA[id];
106              Object.keys(book).forEach( key =>{
107                  if (key.toString() == category) {
108                      if(category == "pub_date"){
109                        for(var i = 0; i < query_tokens.length; i++){
110                          if(queryDatePublished(book, query_tokens[i])) pushBookToResults(book, id);
111                        }
112                      }
113                      else{
114                          var bk_value = book[key].toString().toLowerCase();
115                          for(var i = 0; i < query_tokens.length; i++){
116                            if (bk_value.indexOf(query_tokens[i].toLowerCase()) > -1) {
117                              pushBookToResults(book, id);                           
118                              break;
119                            }
120                          }
121                      }
122                  }
123              });
124          });
125        }
126    }
127    
128    // remove duplicate entries
129    // note: duplicate entries b/c book is added for every instance found per attribute
130    // TODO:: return book once instance found, parse book during printout
131    var flags = [], output = [];
132    for(var i = 0; i < query_result.length; i++) {
133      if( flags[query_result[i].id]) continue;
134      flags[query_result[i].id] = true;
135      output.push(query_result[i]);
136    }
137    query_result = output;
138    
139    //sort by book id
140    query_result.sort(function(a,b){
141        return a.id - b.id;
142    });
143    if(filter_images){ getFilterImages(); }
144    else{ renderQuery()}; 
145}
146
147// Output results of query to DOM
148function renderQuery() {
149  RESULTS_CONTAINER.classList.add('query_hide-output');
150  setTimeout(function() {
151      document.getElementById('query__show-more').classList.remove('query_hide-output');
152      if (query_result.length == 0 || query == "") {
153          console.log('Query returned no results');
154          NUMBER_RESULTS.innerHTML = "<p>The query returned no books.</p>";
155          document.getElementById('query__results-shown').innerHTML ="";
156          document.getElementById('query__show-more').classList.add('query_hide-output');
157          return;
158      }
159      NUMBER_RESULTS.innerHTML = "<p>Found <span id='query__number-results'>" + query_result.length + "</span> Books</p>";
160      total_results_shown = 0;
161      number_displayed_results = 18;
162      if (number_displayed_results > query_result.length) {
163          number_displayed_results = query_result.length;
164      }
165      for (var i = 0; i < number_displayed_results; i++) {
166          total_results_shown++;
167          var bk = query_result[i];
168          var bookInfo = "";
169
170          // Highlights query in selected category
171          Object.keys(bk).forEach(function(attr){
172              if (bk[attr] && attr != "folder") {
173                  if (category == "all") {
174                      if(attr == "link"){
175                        let external_link = `<a class="query_result__link-text" href="${bk[attr]}" target="_blank">${highlightQuery(bk[attr])}</a>`
176                        bookInfo += "<p class='query_result__" + attr + "'><span class='query_result__category'>" + FORMAT_ATTR_NAME[attr] + "</span>: " +external_link + "</p>";
177                      }else{
178                        let temp = (bk[attr] === true || bk[attr] == "yes") ? "Yes" : bk[attr];
179                        bookInfo += "<p class='query_result__" + attr + "'><span class='query_result__category'>" + FORMAT_ATTR_NAME[attr] + "</span>: " + highlightQuery(temp) + "</p>";
180                      }
181                  } else if (category == attr) {
182                      bookInfo += "<p class='query_result__" + attr + "'><span class='query_result__category query__highlight-category'>" + FORMAT_ATTR_NAME[attr] + "</span>: " + highlightQuery(bk[attr]) + "</p>";
183                  } else if(attr == "link"){
184                      let external_link = `<a class="query_result__link-text" href="${bk[attr]}" target="_blank">${bk[attr]}</a>`
185                      bookInfo += "<p class='query_result__" + attr + "'><span class='query_result__category'>" + FORMAT_ATTR_NAME[attr] + "</span>: " + external_link + "</p>";
186                  } else {
187                      let temp = (bk[attr] === true || bk[attr] == "yes") ? "Yes" : bk[attr];
188                      bookInfo += "<p class='query_result__" + attr + "'><span class='query_result__category'>" + FORMAT_ATTR_NAME[attr] + "</span>: " + temp + "</p>";
189                  }
190              }
191          });
192
193          var link = makeBookViewInLibraryAnchor(bk);
194          var output = "<li class='query__result_item'>" + bookInfo + "</li>";
195          var wall_link = "<a href='" + link + "#bookID-" + bk.id + "'>" + output + "</a>";
196          RESULTS_LIST.innerHTML += wall_link;
197      }
198      if (total_results_shown < query_result.length) {
199        document.getElementById('query__results-shown').innerHTML = total_results_shown + " / " + query_result.length;
200      }else if(total_results_shown == query_result.length){
201        document.getElementById('query__results-shown').innerHTML = total_results_shown + " / " + query_result.length;
202        document.getElementById('query__show-more').classList.add('query_hide-output');
203      }
204  }, 300);
205  setTimeout(function() {
206      RESULTS_CONTAINER.classList.remove('query_hide-output');
207  }, 600);
208}
209
210function highlightQuery(string) {
211    var output = string;
212    for(var i = 0; i < query_tokens.length; i++){
213      var regex = new RegExp(query_tokens[i], "gi");
214      output = output.toString().replace(regex, '<span class="query__highlight">' + query_tokens[i] + '</span>');
215    }      
216    return output;
217}
218
219function showMoreResults() {
220    var count = total_results_shown + number_displayed_results;
221    if (count > query_result.length) {
222        count = query_result.length;
223    }
224    console.log("Total: " + total_results_shown + " ||Displayed: " + number_displayed_results + " ||Query Length: " + query_result.length + " ||count: " + count);
225    RESULTS_CONTAINER.classList.add('query_hide-output');
226    setTimeout(function() {
227        for (var i = total_results_shown; i < count; i++) {
228            total_results_shown++;
229            var bk = query_result[i];
230            var bookInfo = "";
231            Object.keys(bk).forEach(function(attr){
232                if (attr != "folder" && bk[attr]) {
233                  if (category == "all") {
234                    let temp = (bk[attr] === true || bk[attr] == "yes") ? "Yes" : bk[attr];
235                    bookInfo += "<p class='query_result__" + attr + "'><span class='query_result__category'>" + FORMAT_ATTR_NAME[attr] + "</span>: " + highlightQuery(temp) + "</p>";
236                  } else if (category == attr) {
237                    bookInfo += "<p class='query_result__" + attr + "'><span class='query_result__category query__highlight-category'>" + FORMAT_ATTR_NAME[attr] + "</span>: " + highlightQuery(bk[attr]) + "</p>";
238                  } else if(attr == "link"){
239                    let external_link = `<a class="query_result__link-text" href="${bk[attr]}" target="_blank">${bk[attr]}</a>`
240                    bookInfo += "<p class='query_result__" + attr + "'><span class='query_result__category'>" + FORMAT_ATTR_NAME[attr] + "</span>: " + external_link + "</p>";
241                  } else {
242                    let temp = (bk[attr] === true || bk[attr] == "yes") ? "Yes" : bk[attr];
243                    bookInfo += "<p class='query_result__" + attr + "'><span class='query_result__category'>" + FORMAT_ATTR_NAME[attr] + "</span>: " + temp + "</p>";
244                  }
245                }
246            });
247
248            var link = makeBookViewInLibraryAnchor(bk);
249            var output = "<li class='query__result_item'>" + bookInfo + "</li>";
250            var wall_link = "<a href='" + link + "#bookID-" + bk.id + "'>" + output + "</a>";
251            RESULTS_LIST.innerHTML += wall_link;
252        }
253        if (total_results_shown < query_result.length) {
254          document.getElementById('query__results-shown').innerHTML = total_results_shown + " / " + query_result.length;
255        }else if(total_results_shown == query_result.length){
256          document.getElementById('query__results-shown').innerHTML = total_results_shown + " / " + query_result.length;
257          document.getElementById('query__show-more').classList.add('query_hide-output');
258        }
259    }, 300);
260    setTimeout(function() {
261        RESULTS_CONTAINER.classList.remove('query_hide-output');
262    }, 600);
263}
264
265// Parses date_published string into INT
266function findDateRange(date_string){
267  if(date_string){
268    if(date_string.indexOf('-') > -1){
269      return {
270        type : "ranged",
271        dates : date_string.split('-') 
272      };
273    }else if(date_string.indexOf(',') > -1){
274      return {
275        type :"multipleDates",
276        dates : date_string
277      };
278    }else{
279      var regex = /\d+/g;
280      return {
281        type : "normal",
282        dates : parseInt(date_string.substring(date_string.search(regex)))
283      };
284    }
285  }else{
286    return{
287      type: "null",
288      dates: "no dates"
289    };
290  }
291}
292
293function queryDatePublished(bk,dateQuery){
294  var parsed_date = findDateRange(bk.pub_date);
295  switch(parsed_date.type){
296    case "ranged": 
297      if(dateQuery >= parsed_date.dates[0] && dateQuery <= parsed_date.dates[1]) return true;
298      break;
299    case "multipleDates": 
300      if(parsed_date.dates.indexOf(dateQuery) > -1) return true;
301      break;
302    case "normal": 
303      if(parsed_date.dates == dateQuery) return true;
304      break;
305    default:
306      return false;
307  }
308}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.