PageSourceSearch

https://www.calcografica.it/js/hilitor.js

js calcografica.it collected 2026-10-02 11:58:44 UTC 8,519 bytes, 294 lines download raw bytes

1// Original JavaScript code by Chirp Internet: www.chirp.com.au
2// Please acknowledge use of this code by including this header.
3
4function Hilitor2(id, tag)
5{
6
7  // private variables
8  var targetNode = document.getElementById(id) || document.body;
9  var hiliteTag = tag || "MARK";
10  var skipTags = new RegExp("^(?:" + hiliteTag + "|SCRIPT|FORM)$");
11  var colors = ["#ff6", "#a0ffff", "#9f9", "#f99", "#f6f"];
12  var wordColor = [];
13  var colorIdx = 0;
14  var matchRegExp = "";
15  var openLeft = false;
16  var openRight = false;
17  var matches = [];
18
19  // characters to strip from start and end of the input string
20  var endRegExp = new RegExp('^[^\\w]+|[^\\w]+$', "g");
21
22  // characters used to break up the input string into words
23   var breakRegExp = new RegExp('[^\\w\'-]+', "g");
24  // var breakRegExp = new RegExp('\b\w+\b', "g");
25
26
27  this.setEndRegExp = function(regex)
28  {
29    endRegExp = regex;
30    return true;
31  };
32
33  this.setBreakRegExp = function(regex)
34  {
35    breakRegExp = regex;
36    return true;
37  };
38
39  this.setMatchType = function(type)
40  {
41    switch(type)
42    {
43      case "open":
44        this.openLeft = this.openRight = true;
45        break;
46
47      case "closed":
48        this.openLeft = this.openRight = false;
49        break;
50
51      case "right":
52        this.openLeft = true;
53        this.openRight = false;
54        break;
55
56      case "left":
57      default:
58        this.openLeft = false;
59        this.openRight = true;
60
61    }
62    return true;
63  };
64
65  // break user input into words and convert to RegExp
66  this.setRegex = function(input)
67  {
68    input = input.replace(/\\u[0-9A-F]{4}/g, ""); // remove missed unicode
69    input = input.replace(endRegExp, "");
70    input = input.replace(breakRegExp, "|");
71    input = input.replace(/^\||\|$/g, "");
72    input = addAccents(input);
73    if(input) {
74      var re = "(" + input + ")";
75      if(!this.openLeft) {
76        re = "(?:^|[\\b\\s])" + re;
77      }
78      if(!this.openRight) {
79        re = re + "(?:[\\b\\s]|$)";
80      }
81      matchRegExp = new RegExp(re, "i");
82      return matchRegExp;
83    }
84    return false;
85  };
86
87  this.getRegex = function()
88  {
89    var retval = matchRegExp.toString();
90    retval = retval.replace(/(^\/|\(\?:[^\)]+\)|\/i$)/g, "");
91    return retval;
92  };
93
94  // recursively apply word highlighting
95  this.hiliteWords = function(node)
96  {
97    if(node === undefined || !node) return;
98    if(!matchRegExp) return;
99    if(skipTags.test(node.nodeName)) return;
100
101    if(node.hasChildNodes()) {
102      for(var i=0; i < node.childNodes.length; i++)
103        this.hiliteWords(node.childNodes[i]);
104    }
105    if(node.nodeType == 3) { // NODE_TEXT
106      if((nv = node.nodeValue) && (regs = matchRegExp.exec(nv))) {
107        if(!wordColor[regs[1].toLowerCase()]) {
108          wordColor[regs[1].toLowerCase()] = colors[colorIdx++ % colors.length];
109        }
110
111        var match = document.createElement(hiliteTag);
112        match.appendChild(document.createTextNode(regs[1]));
113        match.style.backgroundColor = wordColor[regs[1].toLowerCase()];
114        match.style.color = "#000";
115
116        var after;
117        if(regs[0].match(/^\s/)) { // in case of leading whitespace
118          after = node.splitText(regs.index + 1);
119        } else {
120          after = node.splitText(regs.index);
121        }
122        after.nodeValue = after.nodeValue.substring(regs[1].length);
123        node.parentNode.insertBefore(match, after);
124      }
125    };
126  };
127
128  // remove highlighting
129  this.remove = function()
130  {
131    var arr = document.getElementsByTagName(hiliteTag);
132    while(arr.length && (el = arr[0])) {
133      var parent = el.parentNode;
134      parent.replaceChild(el.firstChild, el);
135      parent.normalize();
136    }
137    return true;
138  };
139
140  // start highlighting at target node
141  this.apply = function(input)
142  {
143    this.remove();
144    if(input === undefined || !(input = input.replace(/(^\s+|\s+$)/g, ""))) {
145      return;
146    }
147    input = escapeUnicode(input);
148    input = removeUnicode(input);
149    if(this.setRegex(input)) {
150      this.hiliteWords(targetNode);
151    }
152
153    // build array of matches
154    matches = targetNode.getElementsByTagName(hiliteTag);
155
156    // return number of matches
157    return matches.length;
158  };
159
160  // scroll to the nth match
161  this.gotoMatch = function(idx)
162  {
163    if(matches[idx]) {
164      matches[idx].scrollIntoView({
165        behavior: "smooth",
166        block: "center",
167      });
168      for(var i=0; i < matches.length; i++) {
169        matches[i].style.outline = (idx == i) ? "2px solid red" : "";
170      }
171      return true;
172    }
173    return false;
174  };
175
176  // convert escaped UNICODE to ASCII
177  function removeUnicode(input)
178  {
179    var retval = input;
180    retval = retval.replace(/\\u(00E[024]|010[23]|00C2)/ig, "a");
181    retval = retval.replace(/\\u00E7/ig, "c");
182    retval = retval.replace(/\\u00E[89AB]/ig, "e");
183    retval = retval.replace(/\\u(00E[EF]|00CE)/ig, "i");
184    retval = retval.replace(/\\u00F[46]/ig, "o");
185    retval = retval.replace(/\\u00F[9BC]/ig, "u");
186    retval = retval.replace(/\\u00FF/ig, "y");
187    retval = retval.replace(/\\u(00DF|021[89])/ig, "s");
188    retval = retval.replace(/\\u(0163i|021[AB])/ig, "t");
189    return retval;
190  }
191
192  // convert ASCII to wildcard
193  function addAccents(input)
194  {
195    var retval = input;
196    retval = retval.replace(/([ao])e/ig, "$1");
197    retval = retval.replace(/ss/ig, "s");
198    retval = retval.replace(/e/ig, "[eèéêë]");
199    retval = retval.replace(/c/ig, "[cç]");
200    retval = retval.replace(/i/ig, "[iîïí]");
201    retval = retval.replace(/u/ig, "[uùûüú]");
202    retval = retval.replace(/y/ig, "[yÿ]");
203    retval = retval.replace(/s/ig, "(ss|[sßș])");
204    retval = retval.replace(/t/ig, "([tţț])");
205    retval = retval.replace(/a/ig, "([aàâäăá]|ae)");
206    retval = retval.replace(/o/ig, "([oôöó]|oe)");
207	retval = retval.replace(/n/ig, "[nñ]");
208    return retval;
209  }
210
211  // added by Yanosh Kunsh to include utf-8 string comparison
212  function dec2hex4(textString)
213  {
214    var hexequiv = new Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F");
215    return hexequiv[(textString >> 12) & 0xF] + hexequiv[(textString >> 8) & 0xF] + hexequiv[(textString >> 4) & 0xF] + hexequiv[textString & 0xF];
216  }
217
218  // escape UNICODE characters in string
219  function escapeUnicode(str)
220  {
221    // convertCharStr2jEsc
222    // Converts a string of characters to JavaScript escapes
223    // str: sequence of Unicode characters
224    var highsurrogate = 0;
225    var suppCP;
226    var pad;
227    var n = 0;
228    var outputString = "";
229    for(var i=0; i < str.length; i++) {
230      var cc = str.charCodeAt(i);
231      if(cc < 0 || cc > 0xFFFF) {
232        outputString += '!Error in convertCharStr2UTF16: unexpected charCodeAt result, cc=' + cc + '!';
233      }
234      if(highsurrogate != 0) { // this is a supp char, and cc contains the low surrogate
235        if(0xDC00 <= cc && cc <= 0xDFFF) {
236          suppCP = 0x10000 + ((highsurrogate - 0xD800) << 10) + (cc - 0xDC00);
237          suppCP -= 0x10000;
238          outputString += '\\u' + dec2hex4(0xD800 | (suppCP >> 10)) + '\\u' + dec2hex4(0xDC00 | (suppCP & 0x3FF));
239          highsurrogate = 0;
240          continue;
241        } else {
242          outputString += 'Error in convertCharStr2UTF16: low surrogate expected, cc=' + cc + '!';
243          highsurrogate = 0;
244        }
245      }
246      if(0xD800 <= cc && cc <= 0xDBFF) { // start of supplementary character
247        highsurrogate = cc;
248      } else { // this is a BMP character
249        switch(cc)
250        {
251          case 0:
252            outputString += '\\0';
253            break;
254          case 8:
255            outputString += '\\b';
256            break;
257          case 9:
258            outputString += '\\t';
259            break;
260          case 10:
261            outputString += '\\n';
262            break;
263          case 13:
264            outputString += '\\r';
265            break;
266          case 11:
267            outputString += '\\v';
268            break;
269          case 12:
270            outputString += '\\f';
271            break;
272          case 34:
273            outputString += '\\\"';
274            break;
275          case 92:
276            outputString += '\\\\';
277            break;
278          default:
279            if(cc > 0x1f && cc < 0x7F) {
280              outputString += String.fromCharCode(cc);
281            } else {
282              pad = cc.toString(16).toUpperCase();
283              while(pad.length < 4) {
284                pad = '0' + pad;
285              }
286              outputString += '\\u' + pad;
287            }
288        }
289      }
290    }
291    return outputString;
292  }
293
294}

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.