git ssb

0+

cel / text-node-searcher



Tree: 773e0457b8ce91b62f7467c859c413529fe4c0a7

Files: 773e0457b8ce91b62f7467c859c413529fe4c0a7 / index.js

3574 bytesRaw
1(function (global) {
2
3function addAccents(str) {
4 // http://www.the-art-of-web.com/javascript/search-highlight/
5 return str
6 // .replace(/([ao])e/ig, "$1")
7 .replace(/e/ig, "[eèéêë]")
8 .replace(/a/ig, "([aàâä]|ae)")
9 .replace(/i/ig, "[iîï]")
10 .replace(/o/ig, "([oôö]|oe)")
11 .replace(/u/ig, "[uùûü]")
12 .replace(/y/ig, "[yÿ]");
13}
14
15function setSelection(startNode, startOffset, endNode, endOffset) {
16 var range = document.createRange();
17 range.setStart(startNode, startOffset);
18 range.setEnd(endNode, endOffset);
19
20 var sel = window.getSelection();
21 sel.removeAllRanges();
22 sel.addRange(range);
23}
24
25function TextNodeSearcher(container) {
26 this.container = container;
27}
28
29TextNodeSearcher.prototype.setQuery = function (str) {
30 if (str == this.queryStr)
31 return;
32
33 this.queryStr = str;
34 this.query = new RegExp(addAccents(str), "ig");
35};
36
37function shouldDescendInto(node) {
38 return node.nodeName != "SCRIPT" && node.nodeName != "STYLE";
39}
40
41function getNextTextNode(node, container, wrap) {
42 outer: do {
43 if (shouldDescendInto(node) && node.firstChild) {
44 node = node.firstChild;
45 } else if (node.nextSibling) {
46 node = node.nextSibling;
47 } else {
48 do {
49 if (node == container) {
50 if (!wrap)
51 return null;
52 wrap = false;
53 continue outer;
54 }
55 node = node.parentNode;
56 } while (!node.nextSibling);
57 node = node.nextSibling;
58 }
59 } while (node.nodeType != Node.TEXT_NODE);
60 return node;
61}
62
63function getPreviousTextNode(node, container, wrap) {
64 do {
65 if (node == container) {
66 if (!wrap)
67 return null;
68 while (shouldDescendInto(node) && node.lastChild)
69 node = node.lastChild;
70 wrap = false;
71 } else if (node.previousSibling) {
72 node = node.previousSibling;
73 while (shouldDescendInto(node) && node.lastChild)
74 node = node.lastChild;
75 } else {
76 node = node.parentNode;
77 }
78 } while (node.nodeType != Node.TEXT_NODE);
79 return node;
80}
81
82function matchLast(re, str) {
83 var last;
84 re.lastIndex = 0;
85 for (var m = re.exec(str); m; m = re.exec(str))
86 last = m;
87 return last;
88}
89
90TextNodeSearcher.prototype.selectNext = function () {
91 if (!this.queryStr)
92 return;
93
94 var sel = window.getSelection();
95 var startNode = sel.focusNode;
96 var startOffset = 0;
97 if (!startNode || startNode.nodeType != Node.TEXT_NODE ||
98 !this.container.contains(startNode))
99 startNode = getNextTextNode(startNode, this.container, true);
100 else
101 startOffset = sel.focusOffset;
102
103 for (var node = startNode; node;
104 node = getNextTextNode(node, this.container, true)) {
105 var str = node.data;
106 this.query.lastIndex = startOffset;
107 if (startOffset)
108 startOffset = 0;
109 var m = this.query.exec(str);
110 if (m) {
111 setSelection(node, m.index, node, m.index + m[0].length);
112 return;
113 }
114 }
115};
116
117TextNodeSearcher.prototype.selectPrevious = function () {
118 if (!this.queryStr)
119 return;
120
121 var sel = window.getSelection();
122 var endNode = sel.anchorNode;
123 var endOffset = 0;
124 if (!endNode || endNode.nodeType != Node.TEXT_NODE ||
125 !this.container.contains(endNode))
126 endNode = getPreviousTextNode(endNode, this.container, true);
127 else
128 endOffset = sel.anchorOffset;
129
130 for (var node = endNode; node;
131 node = getPreviousTextNode(node, this.container, true)) {
132 var str = node.data;
133 if (endOffset < Infinity) {
134 str = node.data.substr(0, endOffset);
135 endOffset = Infinity;
136 }
137 var m = matchLast(this.query, str);
138 if (m) {
139 setSelection(node, m.index, node, m.index + m[0].length);
140 return;
141 }
142 }
143};
144
145if (global.module)
146 module.exports = TextNodeSearcher;
147else
148 global.TextNodeSearcher = TextNodeSearcher;
149}(this));
150

Built with git-ssb-web