forked from knownasilya/jquery-highlight
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjquery.highlight.js
158 lines (144 loc) · 5.52 KB
/
jquery.highlight.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
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
/*
* jQuery Highlight plugin
*
* Based on highlight v3 by Johann Burkard
* http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html
*
* Code a little bit refactored and cleaned (in my humble opinion).
* Most important changes:
* - has an option to highlight only entire words (wordsOnly - false by default),
* - has an option to be case sensitive (caseSensitive - false by default)
* - highlight element tag and class names can be specified in options
*
* Usage:
* // wrap every occurrance of text 'lorem' in content
* // with <span class='highlight'> (default options)
* $('#content').highlight('lorem');
*
* // search for and highlight more terms at once
* // so you can save some time on traversing DOM
* $('#content').highlight(['lorem', 'ipsum']);
* $('#content').highlight('lorem ipsum');
*
* // search only for entire word 'lorem'
* $('#content').highlight('lorem', { wordsOnly: true });
*
* // don't ignore case during search of term 'lorem'
* $('#content').highlight('lorem', { caseSensitive: true });
*
* // wrap every occurrance of term 'ipsum' in content
* // with <em class='important'>
* $('#content').highlight('ipsum', { element: 'em', className: 'important' });
*
* // remove default highlight
* $('#content').unhighlight();
*
* // remove custom highlight
* $('#content').unhighlight({ element: 'em', className: 'important' });
*
*
* Copyright (c) 2009 Bartek Szopka
*
* Licensed under MIT license.
*
*/
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node/CommonJS
factory(require('jquery'));
} else {
// Browser globals
factory(jQuery);
}
}(function (jQuery) {
jQuery.extend({
highlight: function (node, re, nodeName, className, ignoreDiacritics) {
if (node.nodeType === 3) {
var subject = ignoreDiacritics ? jQuery.removeDiacritcs(node.data) : node.data;
var match = subject.match(re);
if (match) {
var highlight = document.createElement(nodeName || 'span');
highlight.className = className || 'highlight';
var wordNode = node.splitText(match.index);
wordNode.splitText(match[0].length);
var wordClone = wordNode.cloneNode(true);
highlight.appendChild(wordClone);
wordNode.parentNode.replaceChild(highlight, wordNode);
return 1; //skip added node in parent
}
} else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children
!/(script|style)/i.test(node.tagName) && // ignore script and style nodes
!(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted
for (var i = 0; i < node.childNodes.length; i++) {
i += jQuery.highlight(node.childNodes[i], re, nodeName, className, ignoreDiacritics);
}
}
return 0;
},
removeDiacritcs: function (word) {
return word
.replace(/[\u00c0-\u00c6]/g, 'A')
.replace(/[\u00e0-\u00e6]/g, 'a')
.replace(/[\u00c7]/g, 'C')
.replace(/[\u00e7]/g, 'c')
.replace(/[\u00c8-\u00cb]/g, 'E')
.replace(/[\u00e8-\u00eb]/g, 'e')
.replace(/[\u00cc-\u00cf]/g, 'I')
.replace(/[\u00ec-\u00ef]/g, 'i')
.replace(/[\u00d1|\u0147]/g, 'N')
.replace(/[\u00f1|\u0148]/g, 'n')
.replace(/[\u00d2-\u00d8|\u0150]/g, 'O')
.replace(/[\u00f2-\u00f8|\u0151]/g, 'o')
.replace(/[\u0160]/g, 'S')
.replace(/[\u0161]/g, 's')
.replace(/[\u00d9-\u00dc]/g, 'U')
.replace(/[\u00f9-\u00fc]/g, 'u')
.replace(/[\u00dd]/g, 'Y')
.replace(/[\u00fd]/g, 'y');
}
});
jQuery.fn.unhighlight = function (options) {
var settings = { className: 'highlight', element: 'span' };
jQuery.extend(settings, options);
return this.find(settings.element + '.' + settings.className).each(function () {
var parent = this.parentNode;
parent.replaceChild(this.firstChild, this);
parent.normalize();
}).end();
};
jQuery.fn.highlight = function (words, options) {
var settings = {
className: 'highlight',
element: 'span',
caseSensitive: false,
wordsOnly: false,
ignoreDiacritics: false,
};
jQuery.extend(settings, options);
if (words.constructor === String) {
words = [words];
}
words = jQuery.grep(words, function(word) {
return word !== '';
});
words = jQuery.map(words, function(word) {
if (settings.ignoreDiacritics) {
word = jQuery.removeDiacritcs(word);
}
return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
});
if (words.length === 0) { return this; }
var flag = settings.caseSensitive ? '' : 'i';
var pattern = '(' + words.join('|') + ')';
if (settings.wordsOnly) {
pattern = '\\b' + pattern + '\\b';
}
var re = new RegExp(pattern, flag);
return this.each(function () {
jQuery.highlight(this, re, settings.element, settings.className, settings.ignoreDiacritics);
});
};
}));