/*! Widget: mark.js - updated 7/31/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 );