1/*! Widget: sort2Hash (BETA) - updated 9/27/2017 (v2.29.0) */ 2/* Requires tablesorter v2.8+ and jQuery 1.7+ 3 * by Rob Garrison 4 */ 5;( function( $ ) { 6 'use strict'; 7 var ts = $.tablesorter || {}, 8 s2h = ts.sort2Hash = { 9 init : function( c, wo ) { 10 var filter, temp, page, size, 11 table = c.table, 12 pager = c.pager, 13 hasSaveSort = ts.hasWidget( table, 'saveSort' ), 14 sort = s2h.decodeHash( c, wo, 'sort' ); 15 if ( ( sort && !hasSaveSort ) || ( sort && hasSaveSort && wo.sort2Hash_overrideSaveSort ) ) { 16 s2h.convertString2Sort( c, wo, sort ); 17 } 18 if ( ts.hasWidget( c.table, 'pager' ) ) { 19 temp = parseInt( s2h.decodeHash( c, wo, 'page' ), 10 ); 20 page = pager.page = ( temp < 0 ? 0 : ( temp > pager.totalPages ? pager.totalPages - 1 : temp ) ); 21 size = pager.size = parseInt( s2h.decodeHash( c, wo, 'size' ), 10 ); 22 } 23 if ( ts.hasWidget( table, 'filter' ) ) { 24 filter = s2h.decodeHash( c, wo, 'filter' ); 25 if ( filter ) { 26 filter = filter.split( wo.sort2Hash_separator ); 27 c.$table.one( 'tablesorter-ready', function() { 28 setTimeout(function() { 29 c.$table.one( 'filterEnd', function() { 30 $(this).triggerHandler( 'pageAndSize', [ page, size ] ); 31 }); 32 // use the newest filter comparison code 33 if ( ts.filter.equalFilters ) { 34 temp = ts.filter.equalFilters( c, c.lastSearch, filter ); 35 } else { 36 // quick n' dirty comparison... it will miss filter changes of 37 // the same value in a different column, see #1363 38 temp = ( c.lastSearch || [] ).join( '' ) !== ( filter || [] ).join( '' ); 39 } 40 // don't set filters if they haven't changed 41 if ( !temp ) { 42 $.tablesorter.setFilters( table, filter, true ); 43 } 44 }, 100 ); 45 }); 46 } 47 } 48 if ( !filter ) { 49 c.$table.one( 'tablesorter-ready', function() { 50 c.$table.triggerHandler( 'pageAndSize', [ page, size ] ); 51 }); 52 } 53 54 c.$table.on( 'sortEnd.sort2hash filterEnd.sort2hash pagerComplete.sort2Hash', function() { 55 if ( this.hasInitialized ) { 56 s2h.setHash( this.config, this.config.widgetOptions ); 57 } 58 }); 59 }, 60 61 getTableId : function( c, wo ) { 62 // option > table id > table index on page 63 return wo.sort2Hash_tableId || 64 c.table.id || 65 'table' + $( 'table' ).index( c.$table ); 66 }, 67 regexEscape : function( v ) { 68 return v.replace( /([\.\^\$\*\+\-\?\(\)\[\]\{\}\\\|])/g, '\\$1'); 69 }, 70 // convert 'first%20name,asc,last%20name,desc' into [[0,0], [1,1]] 71 convertString2Sort : function( c, wo, sortHash ) { 72 var regex, column, direction, temp, index, $cell, 73 arry = sortHash.split( wo.sort2Hash_separator ), 74 indx = 0, 75 len = arry.length, 76 sort = []; 77 while ( indx < len ) { 78 // column index or text 79 column = arry[ indx++ ]; 80 temp = parseInt( column, 10 ); 81 // ignore wo.sort2Hash_useHeaderText setting & 82 // just see if column contains a number 83 if ( isNaN( temp ) || temp > c.columns ) { 84 regex = new RegExp( '(' + s2h.regexEscape( column ) + ')', 'i' ); 85 for ( index = 0; index < c.columns; index++ ) { 86 $cell = c.$headerIndexed[ index ]; 87 if ( regex.test( $cell.attr( wo.sort2Hash_headerTextAttr ) ) ) { 88 column = index; 89 index = c.columns; 90 } 91 } 92 } 93 direction = arry[ indx++ ]; 94 // ignore unpaired values 95 if ( typeof column !== 'undefined' && typeof direction !== 'undefined' ) { 96 // convert text to 0, 1 97 if ( isNaN( direction ) ) { 98 // default to ascending sort 99 direction = direction.indexOf( wo.sort2Hash_directionText[ 1 ] ) > -1 ? 1 : 0; 100 } 101 sort.push( [ column, direction ] ); 102 } 103 } 104 if ( sort.length ) { 105 c.sortList = sort; 106 } 107 }, 108 109 // convert [[0,0],[1,1]] to 'first%20name,asc,last%20name,desc' 110 convertSort2String : function( c, wo ) { 111 var index, txt, column, direction, 112 sort = [], 113 arry = c.sortList || [], 114 len = arry.length; 115 for ( index = 0; index < len; index++ ) { 116 column = arry[ index ][ 0 ]; 117 txt = $.trim( c.$headerIndexed[ column ].attr( wo.sort2Hash_headerTextAttr ) ); 118 sort.push( txt !== '' ? encodeURIComponent( txt ) : column ); 119 direction = wo.sort2Hash_directionText[ arry[ index ][ 1 ] ]; 120 sort.push( direction ); 121 } 122 // join with separator 123 return sort.join( wo.sort2Hash_separator ); 124 }, 125 126 convertFilter2String : function( c, wo ) { 127 var index, txt, column, direction, 128 sort = [], 129 arry = c.sortList || [], 130 len = arry.length; 131 for ( index = 0; index < len; index++ ) { 132 column = arry[ index ][ 0 ]; 133 txt = $.trim( c.$headerIndexed[ column ].attr( wo.sort2Hash_headerTextAttr ) ); 134 column = typeof txt !== 'undefined' ? encodeURIComponent( txt ) : column; 135 sort.push( column ); 136 direction = wo.sort2Hash_directionText[ arry[ index ][ 1 ] ]; 137 sort.push( direction ); 138 } 139 // join with separator 140 return sort.join( wo.sort2Hash_separator ); 141 }, 142 143 // Get URL Parameters (getParam) 144 // modified from http://www.netlobo.com/url_query_string_javascript.html 145 getParam : function ( name, hash, returnRegex ) { 146 if ( !hash ) { hash = window.location.hash; } 147 var regex = new RegExp( '[\\?&]' + s2h.regexEscape( name ) + '=([^&#]*)' ), 148 match = regex.exec( hash ); 149 if ( returnRegex ) { return regex; } 150 return match === null ? '' : decodeURIComponent( match[ 1 ] ); 151 }, 152 153 // remove parameter from hash 154 removeParam : function( name, hash ) { 155 if ( !hash ) { hash = window.location.hash; } 156 var index, 157 regex = s2h.getParam( name, hash, true ), 158 result = [], 159 parts = hash.split( '&' ), 160 len = parts.length; 161 for ( index = 0; index < len; index++ ) { 162 // regex expects a leading '&'... 163 if ( !regex.test( '&' + parts[ index ] ) ) { 164 result.push( parts[ index ] ); 165 } 166 } 167 return result.length ? result.join( '&' ) : ''; 168 }, 169 170 encodeHash : function( c, wo, component, value, rawValue ) { 171 var result = false, 172 tableId = s2h.getTableId( c, wo ); 173 if ( typeof wo.sort2Hash_encodeHash === 'function' ) { 174 result = wo.sort2Hash_encodeHash( c, tableId, component, value, rawValue || value ); 175 } 176 if ( result === false ) { 177 result = '&' + component + '[' + tableId + ']=' + value; 178 } 179 return result; 180 }, 181 182 decodeHash : function( c, wo, component ) { 183 var result = false, 184 tableId = s2h.getTableId( c, wo ); 185 if ( typeof wo.sort2Hash_decodeHash === 'function' ) { 186 // return a string 187 result = wo.sort2Hash_decodeHash( c, tableId, component ); 188 } 189 if ( result === false ) { 190 result = s2h.getParam( component + '[' + tableId + ']' ); 191 } 192 return result || ''; 193 }, 194 195 cleanHash : function( c, wo, component, hash ) { 196 var result = false, 197 tableId = s2h.getTableId( c, wo ); 198 if ( typeof wo.sort2Hash_cleanHash === 'function' ) { 199 // can return an array or string 200 result = wo.sort2Hash_cleanHash( c, tableId, component, hash ); 201 } 202 if ( result === false ) { 203 // parameter example: 'sort[table0]=0,0' 204 result = s2h.removeParam( component + '[' + tableId + ']', hash ); 205 } 206 return result || ''; 207 }, 208 209 setHash : function( c, wo ) { 210 var str = '', 211 hash = window.location.hash, 212 hasPager = ts.hasWidget( c.table, 'pager' ), 213 hasFilter = ts.hasWidget( c.table, 'filter' ), 214 sortList = s2h.convertSort2String( c, wo ), 215 filters = ( hasFilter && c.lastSearch.join('') !== '' ? c.lastSearch : [] ), 216 filtersStr = encodeURIComponent( filters.join( c.widgetOptions.sort2Hash_separator ) ), 217 components = { 218 'sort' : sortList ? s2h.encodeHash( c, wo, 'sort', sortList, c.sortList ) : '', 219 'page' : hasPager ? s2h.encodeHash( c, wo, 'page', c.pager.page + 1 ) : '', 220 'size' : hasPager ? s2h.encodeHash( c, wo, 'size', c.pager.size ) : '', 221 'filter' : filtersStr ? s2h.encodeHash( c, wo, 'filter', filtersStr, filters ) : '' 222 }; 223 // remove old hash 224 $.each( components, function( component, value ) { 225 hash = s2h.cleanHash( c, wo, component, hash ); 226 str += value; 227 }); 228 229 var hashChar = wo.sort2Hash_hash; 230 // Combine new hash with any existing hashes 231 var newHash = ( 232 ( window.location.hash || '' ).replace( hashChar, '' ).length ? 233 hash : hashChar 234 ) + str; 235 236 if (wo.sort2Hash_replaceHistory) { 237 var baseUrl = window.location.href.split(hashChar)[0]; 238 // Ensure that there is a leading hash character 239 var firstChar = newHash[0]; 240 if (firstChar !== hashChar) { 241 newHash = hashChar + newHash; 242 } 243 // Update URL in browser 244 window.location.replace(baseUrl + newHash); 245 } else { 246 // Add updated hash 247 window.location.hash = newHash; 248 } 249 } 250 }; 251 252 ts.addWidget({ 253 id: 'sort2Hash', 254 priority: 60, // after saveSort & pager 255 options: { 256 sort2Hash_hash : '#', // hash prefix 257 sort2Hash_separator : '-', // don't '#' or '=' here 258 sort2Hash_headerTextAttr : 'data-header', // data attribute containing alternate header text 259 sort2Hash_directionText : [ 0, 1 ], // [ 'asc', 'desc' ], 260 sort2Hash_overrideSaveSort : false, // if true, override saveSort widget if saved sort available 261 sort2Hash_replaceHistory : false, // if true, hash changes are not saved to browser history 262 263 // this option > table ID > table index on page 264 sort2Hash_tableId : null, 265 // custom hash processing functions 266 sort2Hash_encodeHash : null, 267 sort2Hash_decodeHash : null, 268 sort2Hash_cleanHash : null 269 }, 270 init: function(table, thisWidget, c, wo) { 271 s2h.init( c, wo ); 272 }, 273 remove: function(table, c) { 274 c.$table.off( '.sort2hash' ); 275 } 276 }); 277 278})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.