PageSourceSearch

https://historyofcomputercommunications.info/assets/search.js

js historyofcomputercommunications.info collected 2026-09-24 09:29:16 UTC 9,529 bytes, 281 lines download raw bytes

1
2function decode (str) {
3    return str.replace(/'/g, "'")
4               .replace(/"/g, '"')
5               .replace(/>/g, '>')
6               .replace(/&lt;/g, '<')
7               .replace(/&amp;/g, '&');
8};
9
10function highlight(input, text) {
11  var indices = [];
12  function mark(str, txt, idx) {
13    idx = str.indexOf(txt, idx+txt.length);
14    if (idx >= 0) {
15      indices.push(idx);
16      mark(str, txt, idx);
17    }
18  }
19  var innerLower = input.toLowerCase();
20  text_lower = text.toLowerCase();
21  var index = innerLower.indexOf(text_lower);
22  if (index >= 0) {
23    indices.push(index);
24    var formatted_html = "";
25    formatted_html = input.substring(0,index);
26    mark(innerLower, text, index);
27    for (var i = 0; i < indices.length; i++) {
28      let highlighted = "<mark>" + input.substring(indices[i],indices[i] + text.length) + "</mark>";
29      if(typeof indices[i+1] === 'undefined') {
30        highlighted += input.substring(indices[i] + text.length);
31      } else {
32        highlighted += input.substring(indices[i] + text.length, indices[i+1]);
33      }
34      formatted_html += highlighted;
35    }
36    return formatted_html;
37  }
38}
39
40function srch(item, searchText) {
41  var matched = false;
42  var content = "";
43  var ch_title = "";
44  var section = "";
45  var footnotes = "";
46  var title_matched = false;
47  var section_matched = false;
48  var p_matched = false;
49  var img_matched = false;
50  var is_interview = false;
51  var fn_matched = false;
52  var url = "/"
53  if (item[0].startsWith("int")){
54    url = "/interviews/" + item[0].replace("int", "");
55  } else {
56    url = "/section/" + item[0] + "/" + item[1].url + "/";
57  }
58  if (item[1].ch == "Interviews") {
59    is_interview = true;
60  } else {
61    ch_title = highlight(item[1].ch_title, searchText);
62    if (ch_title) {
63      matched = true;
64    } else {
65      ch_title= item[1].ch_title;
66    }
67    section = highlight(item[0], searchText);
68    if (section) {
69      matched = true;
70      section_matched = true;
71    } else {
72      section = item[0];
73    }
74  }
75  var title = highlight(item[1].title, searchText);
76  if (title) {
77    matched = true;
78    title_matched = true;
79  } else {
80    title = item[1].title;
81  }
82  //var cntnt = item[1].content;
83  //cntnt = cntnt.toLowerCase();
84  //var content_index = cntnt.indexOf("https://archive.computerhistory.org/");
85  //console.log(content_index); 
86  //<a href="https://archive.computerhistory.org/resources/access/text/2013/05/102746645-05-01-acc.pdf">Norm Abramson Interviewed by James Pelkey 10/13/88</a>
87  
88  var matched_sentence = "";
89  var decoded_content = decode(item[1].content);
90  var matched_img = "";
91  var search_rx = new RegExp(searchText, "gi");
92  if (search_rx.test(decoded_content)) {
93    var a_rex = /<\s*a[^>]*>(.*?)<\s*\/\s*a>/g;
94    var img_rex = /<img([\w\W]+?)\/>/g;
95    var imgs = decoded_content.match(img_rex);
96
97    var paragraphs = [];
98    decoded_content = decoded_content.replace(a_rex, "").replace(img_rex, "").replace(/<p>*<\/p>/g, "");
99    decoded_content.replace(/<p>(.*?)<\/p>/g, function () {
100      paragraphs.push(arguments[1]);
101    });
102    if (imgs) {
103      var prev_img_count = 0;
104      for (var i=0; i<imgs.length; i++) {
105        var img_match_count = (imgs[i].match(search_rx) || []).length;
106        // search between tags using regex??
107        if (img_match_count > 0 && img_match_count > prev_img_count) {
108          prev_img_count = img_match_count;
109          matched_img = imgs[i];
110        }
111      }   
112    }
113    if (matched_img) {
114      matched = true;
115      var img_dom = document.createElement('html');
116      img_dom.innerHTML = matched_img;
117      var shadow_img = img_dom.getElementsByTagName('IMG')[0]
118      if (shadow_img) {
119        if (shadow_img.src) {
120          var classname = "imgc";         
121          var img_title = highlight(shadow_img.title, searchText);
122          if (!img_title) {
123            img_title = shadow_img.title;
124          }
125          if (img_title != "") {
126            img_title = "<h3>" + img_title + "</h3>";
127          }
128          var formatted_img = 
129            "<div class='" + classname + "'>" + 
130              "<img src='" + shadow_img.src + "' alt='" + shadow_img.alt + "' >" + 
131              img_title + 
132            "</div>";
133          matched_img = formatted_img;
134          img_matched = true;
135        }
136      }
137    }
138    var search_count = 0;
139    for (var i=0; i<paragraphs.length; i++) {
140      if (paragraphs[i].toLowerCase().includes(text_lower)) {
141        let sentences = paragraphs[i].split(/((?![.\n\s])[^.\n"]*(?:"[^\n"]*[^\n".]"[^.\n"]*)*(?:"[^"\n]+\."|\.|(?=\n)))/gi);
142        for (var s=0; s<sentences.length; s++) {
143          var count = (sentences[s].match(search_rx) || []).length;
144          if (count > 0 && count > search_count) {
145            search_count = count;
146            matched_sentence = sentences[s];
147            if (matched_sentence.startsWith('” ')) {
148              matched_sentence = matched_sentence.replace('” ', '');
149            }
150            if (matched_sentence.startsWith(", ")) {
151              matched_sentence = matched_sentence.replace(", ", "");
152            }
153          }
154        }
155      }
156    }
157  }
158  content = highlight(matched_sentence, searchText);
159  if (content) {
160    matched = true;
161    p_matched = true;
162    content = "<p>" + content + "</p>";
163  } else {
164    content = "";
165  }
166  if (item[1].footnotes !== undefined) {
167    var matched_fn = item[1].footnotes.filter(obj => obj.src.toLowerCase().indexOf(searchText.toLowerCase()) >= 0);
168    var fn_size = Object.keys(matched_fn).length;
169    if (fn_size) {
170      matched = true;
171      fn_matched = true;
172      footnotes = matched_fn.map(footnote => {
173        let found_fn = highlight(footnote.src.replace(/(<([^>]+)>)/ig, ""), searchText);
174        if (found_fn !== undefined) {
175          return `<p><span>[${footnote.num}]</span> : ${found_fn}</p>`;
176        }
177      });
178    }
179  }
180  if (matched) {
181    //console.log("\n\n" + section);
182    var search_item = {};
183    if (Object.keys(footnotes).length > 0) {
184      let footnotes_str = footnotes.join("");
185      footnotes = footnotes_str;
186      footnotes = `<div class="footnote"><div>Footnotes:</div>${footnotes}</div>`
187    } else {
188      footnotes = "";
189    }
190    var html = 
191      `<a href="${url}" class="search-item"><h1>${ch_title}</h1><h2>${section} ${title}</h2>${content}${matched_img}${footnotes}</a>`;
192    if (is_interview) {
193      if (title_matched) {
194        //console.log("int title matched");
195        search_item.interview = [html];
196      } else {
197        search_item.interviews = [html];
198        //console.log("int no title matched");
199      }
200    }
201    else if (section_matched || title_matched) {
202      search_item.h2 = html;
203      //console.log("non-int section/title matched");
204    } else if (p_matched && !section_matched && !title_matched) {
205      search_item.p = [html];
206      //console.log("p matched");
207    } else if (img_matched && !section_matched && !title_matched && !p_matched) {
208      search_item.img = [html];
209      //console.log("img matched");
210    } else if (fn_matched && !section_matched && !title_matched && !p_matched && !img_matched && footnotes != "") {
211      //console.log("footnotes matched");
212      search_item.footnotes = html;
213      //console.log(html);
214      //console.log(footnotes);
215    }
216    return search_item;
217  }
218}
219
220let search_timeout = null;
221document.getElementById('search').addEventListener('keyup', function (e) {
222  clearTimeout(search_timeout);
223  search_timeout = setTimeout(function () {
224    let html = "";
225    let searchText = document.getElementById('search').value;
226    if (searchText.length < 2) { // Clear when input or matches are empty
227      hideResults();
228    } else {
229      showResults();
230      var search_results = {
231        "h2" : [],
232        "interview" : [],
233        "interviews" : [],
234        "p" : [],
235        "img" : [],
236        "footnotes" : []
237      };
238      for (var i=1; i<search_array.length; i++) { // offset first entry for toc
239        let search_query = srch(search_array[i], searchText);
240        if (search_query) {
241          if (search_query.h2){
242            search_results.h2.push(search_query.h2);
243          }
244          if (search_query.interview){
245            search_results.interview.push(search_query.interview);
246          }
247          if (search_query.interviews){
248            search_results.interviews.push(search_query.interviews);
249          }
250          if (search_query.p){
251            search_results.p.push(search_query.p);
252          }
253          if (search_query.img){
254            search_results.img.push(search_query.img);
255          }
256          if (search_query.footnotes){
257            search_results.footnotes = search_results.footnotes.concat(search_query.footnotes);
258          }
259        }
260      }
261      //console.log(search_results);
262      html = search_results.h2.join("");
263      if (search_results.interview.length > 0) {
264        html += "<div class='search-item'><h1>Interviews:</h1></div>";
265        html += search_results.interview.join("");
266      }
267      html += search_results.p.join("");
268      html += search_results.img.join("");
269      if (search_results.interviews.length > 0) {
270        html += "<div class='search-item'><h1>Interviews:</h1></div>";
271        html += search_results.interviews.join("");
272      }
273      if (search_results.footnotes.length > 0) {
274        //html += search_results.footnotes;
275        html += search_results.footnotes.join("");
276        //console.log(search_results.footnotes);
277      }
278    }
279    document.getElementById('results').innerHTML = html;
280  }, 250);
281});

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.