-
Notifications
You must be signed in to change notification settings - Fork 0
/
hilitor.js
114 lines (96 loc) · 3.69 KB
/
hilitor.js
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
// Original JavaScript code by Chirp Internet: www.chirp.com.au
// Please acknowledge use of this code by including this header.
function Hilitor(id, tag) {
var targetNode = document.getElementById(id) || document.body;
var hiliteTag = tag || "EM";
var skipTags = new RegExp("^(?:" + hiliteTag + "|SCRIPT|FORM|SPAN)$");
var colors = ["#ff6", "#a0ffff", "#9f9", "#f99", "#f6f"];
var wordColor = [];
var colorIdx = 0;
var matchRegex = "";
var openLeft = false;
var openRight = false;
// characters to strip from start and end of the input string
var endCharRegex = new RegExp("^[^\\\w]+|[^\\\w]+$", "g");
// characters used to break up the input string into words
// var breakCharRegex = new RegExp("[^\\\w'-]+", "g");
var breakCharRegex = new RegExp("[&]", "g");
this.setMatchType = function (type) {
switch (type) {
case "left":
this.openLeft = false;
this.openRight = true;
break;
case "right":
this.openLeft = true;
this.openRight = false;
break;
case "open":
this.openLeft = this.openRight = true;
break;
default:
this.openLeft = this.openRight = false;
}
};
this.setRegex = function (input) {
input = input.replace(endCharRegex, "");
input = input.replace(breakCharRegex, "|");
input = input.replace(/^\||\|$/g, "");
if (input) {
var re = "(" + input + ")";
if (!this.openLeft) re = "\\b" + re;
if (!this.openRight) re = re + "\\b";
matchRegex = new RegExp(re, "i");
return true;
}
return false;
};
this.getRegex = function () {
var retval = matchRegex.toString();
retval = retval.replace(/(^\/(\\b)?|\(|\)|(\\b)?\/i$)/g, "");
retval = retval.replace(/\|/g, " ");
return retval;
};
// recursively apply word highlighting
this.hiliteWords = function (node) {
if (node === undefined || !node) return;
if (!matchRegex) return;
if (skipTags.test(node.nodeName)) return;
if (node.hasChildNodes()) {
for (var i = 0; i < node.childNodes.length; i++)
this.hiliteWords(node.childNodes[i]);
}
if (node.nodeType == 3) { // NODE_TEXT
if ((nv = node.nodeValue) && (regs = matchRegex.exec(nv))) {
if (!wordColor[regs[0].toLowerCase()]) {
wordColor[regs[0].toLowerCase()] = colors[colorIdx++ % colors.length];
}
var match = document.createElement(hiliteTag);
match.appendChild(document.createTextNode(regs[0]));
match.style.backgroundColor = wordColor[regs[0].toLowerCase()];
match.style.fontStyle = "inherit";
match.style.color = "#000";
var after = node.splitText(regs.index);
after.nodeValue = after.nodeValue.substring(regs[0].length);
node.parentNode.insertBefore(match, after);
}
}
};
// remove highlighting
this.remove = function () {
var arr = document.getElementsByTagName(hiliteTag);
while (arr.length && (el = arr[0])) {
var parent = el.parentNode;
parent.replaceChild(el.firstChild, el);
parent.normalize();
}
};
// start highlighting at target node
this.apply = function (input) {
this.remove();
if (input === undefined || !input) return;
if (this.setRegex(input)) {
this.hiliteWords(targetNode);
}
};
}