1
0
Fork 0
mirror of https://github.com/koalyptus/TableFilter.git synced 2024-05-23 16:52:26 +02:00
TableFilter/src/modules/highlightKeywords.js
2016-05-20 18:08:39 +10:00

123 lines
3.9 KiB
JavaScript

import Dom from '../dom';
import {isArray} from '../types';
export class HighlightKeyword {
/**
* HighlightKeyword, highlight matched keyword
* @param {Object} tf TableFilter instance
*/
constructor(tf) {
let f = tf.config();
//defines css class for highlighting
this.highlightCssClass = f.highlight_css_class || 'keyword';
this.tf = tf;
this.emitter = tf.emitter;
}
init() {
this.emitter.on(
['before-filtering', 'destroy'],
() => this.unhighlightAll()
);
this.emitter.on(
['highlight-keyword'],
(tf, cell, word) =>
this.highlight(cell, word, this.highlightCssClass)
);
}
/**
* highlight occurences of searched term in passed node
* @param {Node} node
* @param {String} word Searched term
* @param {String} cssClass Css class name
*
* TODO: refactor this method
*/
highlight(node, word, cssClass) {
// Iterate into this nodes childNodes
if (node.hasChildNodes) {
let children = node.childNodes;
for (let i = 0; i < children.length; i++) {
this.highlight(children[i], word, cssClass);
}
}
if (node.nodeType === 3) {
let tempNodeVal = node.nodeValue.toLowerCase();
let tempWordVal = word.toLowerCase();
if (tempNodeVal.indexOf(tempWordVal) !== -1) {
let pn = node.parentNode;
if (pn && pn.className !== cssClass) {
// word not highlighted yet
let nv = node.nodeValue,
ni = tempNodeVal.indexOf(tempWordVal),
// Create a load of replacement nodes
before = Dom.text(nv.substr(0, ni)),
docWordVal = nv.substr(ni, word.length),
after = Dom.text(nv.substr(ni + word.length)),
hiwordtext = Dom.text(docWordVal),
hiword = Dom.create('span');
hiword.className = cssClass;
hiword.appendChild(hiwordtext);
pn.insertBefore(before, node);
pn.insertBefore(hiword, node);
pn.insertBefore(after, node);
pn.removeChild(node);
}
}
}
}
/**
* Removes highlight to nodes matching passed string
* @param {String} word
* @param {String} cssClass Css class to remove
*/
unhighlight(word, cssClass) {
let highlightedNodes = this.tf.tbl.querySelectorAll(`.${cssClass}`);
for (let i = 0; i < highlightedNodes.length; i++) {
let n = highlightedNodes[i];
let nodeVal = Dom.getText(n),
tempNodeVal = nodeVal.toLowerCase(),
tempWordVal = word.toLowerCase();
if (tempNodeVal.indexOf(tempWordVal) !== -1) {
n.parentNode.replaceChild(Dom.text(nodeVal), n);
}
}
}
/**
* Clear all occurrences of highlighted nodes
*/
unhighlightAll() {
if (!this.tf.highlightKeywords) {
return;
}
// iterate filters values to unhighlight all values
this.tf.getFiltersValue().forEach((val) => {
if (isArray(val)) {
val.forEach((item) =>
this.unhighlight(item, this.highlightCssClass));
} else {
this.unhighlight(val, this.highlightCssClass);
}
});
}
destroy() {
this.emitter.off(
['before-filtering', 'destroy'],
() => this.unhighlightAll()
);
this.emitter.off(
['highlight-keyword'],
(tf, cell, word) =>
this.highlight(cell, word, this.highlightCssClass)
);
}
}