tablesorter/js/widgets/widget-mark.js
2016-07-27 18:51:55 -05:00

136 lines
4.2 KiB
JavaScript

/*! Widget: mark.js - updated 7/27/2016 (v2.27.0) *//*
* Requires tablesorter v2.8+ and jQuery 1.7+
* by Rob Garrison
*/
;( function( $ ) {
'use strict';
var ts = $.tablesorter;
ts.mark = {
init : function( c, wo ) {
if ( typeof $.fn.mark === 'function' ) {
var tmp,
update = c.widgetOptions.mark_tsUpdate;
c.$table.on( 'filterEnd.tsmark' + ( update ? ' ' + update : '' ), function( e, filters ) {
// filterEnd passes "config" as the param
ts.mark.update( c, e.type === 'filterEnd' ? '' : filters );
});
// Regex to split up a query
tmp = '(?:<|=|>|\\||\"|' + "\\'|" +
'\\s+(?:&&|-|' +
( ts.language.and || 'and' ) + '|' +
( ts.language.or || 'or' ) + '|' +
( ts.language.to || 'to' ) + ')\\s+)';
ts.mark.regex.filter = new RegExp(tmp, 'gim');
} else {
console.warn('Widget-mark not initialized: missing "jquery.mark.js"');
}
},
regex : {
mark : /^mark_(.+)$/,
// test for regex (e.g. "/(lorem|ipsum)/gi")
pure : /^\/((?:\\\/|[^\/])+)\/([mig]{0,3})?$/
},
checkRegex : function( regex ) {
if ( regex instanceof RegExp ) {
// prevent lock up of mark.js (see https://github.com/julmot/mark.js/issues/55)
var result = '\u0001\u0002\u0003\u0004\u0005'.match( regex );
return result === null || result.length < 5;
}
return false;
},
cleanMatches : function( matches ) {
var results = [],
indx = matches && matches.length || 0;
while ( indx-- ) {
if ( matches[indx] !== "" ) {
results[ results.length ] = matches[ indx ];
}
}
return results;
},
update : function( c, filters ) {
var options = {},
regex = ts.mark.regex,
$rows = c.$table
.find( 'tbody tr' )
.unmark()
.not( '.' + ( c.widgetOptions.filter_filteredRow || 'filtered' ) ),
filters = filters || $.tablesorter.getFilters( c.$table );
// extract & save mark options from widgetOptions (prefixed with "mark_")
// update dynamically
$.each( filters, function( indx, filter ) {
if ( filter ) {
var testRegex = null,
matches = filter,
useRegex = false,
col = indx === c.columns ? '' : ':nth-child(' + ( indx + 1 ) + ')';
// regular expression entered
if ( regex.pure.test( filter ) ) {
matches = regex.pure.exec( filter );
// ignore "all" matches (i.e. /.*/)
if (matches[1] === '.*') {
matches[1] = '';
}
try {
// make sure to include global flag when testing regex
testRegex = new RegExp( matches[ 1 ], 'gim' );
matches = new RegExp( matches[ 1 ], matches[ 2 ] );
} catch (err) {
matches = null;
}
if ( ts.mark.checkRegex( testRegex ) ) {
$rows.children( col ).markRegExp( matches, options );
}
// matches is either null, invalid, or done my markRegExp
return;
}
// all special querys (or, and, wild cards & fuzzy)
// regex seems to not be consistent here; so use string indexOf
// fuzzy or wild card matches
if ( filter.indexOf( '~' ) === 0 ) {
useRegex = true;
// fuzzy search separate each letter
matches = filter.replace( /~/g, '' ).split( '' );
} else {
// wild card matching
if ( filter.indexOf( '?' ) > -1 ) {
useRegex = true;
filter = filter.replace( /\?/g, '\\S{1}' );
}
if ( filter.indexOf( '*' ) > -1 ) {
useRegex = true;
filter = filter.replace( /\*/g, '\\S*' );
}
matches = filter.split( regex.filter );
}
if ( useRegex && matches && matches.length ) {
matches = new RegExp( ts.mark.cleanMatches( matches ).join( '.*' ), 'gim' );
if ( ts.mark.checkRegex( matches ) ) {
$rows.children( col ).markRegExp( matches, options );
}
} else {
// pass an array of matches
$rows.children( col ).mark( ts.mark.cleanMatches( matches ), options );
}
}
});
}
};
ts.addWidget({
id: 'mark',
options: {
mark_tsUpdate : "markUpdate"
},
init : function( table, thisWidget, c, wo ) {
ts.mark.init( c, wo );
},
remove : function( table, c ) {
var update = c.widgetOptions.mark_tsUpdate;
c.$table.off( 'filterEnd.tsmark' + ( update ? ' ' + update : '' ) );
}
});
})( jQuery );