Add JS files

This commit is contained in:
2025-05-12 15:45:17 +00:00
parent 7ddd15c4fa
commit 967007b0c7
3239 changed files with 1157078 additions and 0 deletions

View File

@@ -0,0 +1,81 @@
/*!
* Extract out date parsers
*/
/*jshint jquery:true */
;(function($){
"use strict";
/*! extract US Long Date (ignore any other text)
* e.g. "Sue's Birthday! Jun 26, 2004 7:22 AM (8# 2oz)"
* demo: http://jsfiddle.net/abkNM/2293/
*/
$.tablesorter.addParser({
id: "extractUSLongDate",
is: function (s) {
// don't auto detect this parser
return false;
},
format: function (s, table) {
var date = s.match(/[A-Z]{3,10}\.?\s+\d{1,2},?\s+(?:\d{4})(?:\s+\d{1,2}:\d{2}(?::\d{2})?(?:\s+[AP]M)?)?/i);
return date ? $.tablesorter.formatFloat((new Date(date[0]).getTime() || ''), table) || s : s;
},
type: "numeric"
});
/*! extract MMDDYYYY (ignore any other text)
* demo: http://jsfiddle.net/Mottie/abkNM/2418/
*/
$.tablesorter.addParser({
id: "extractMMDDYYYY",
is: function (s) {
// don't auto detect this parser
return false;
},
format: function (s, table) {
var date = s.replace(/\s+/g," ").replace(/[\-.,]/g, "/").match(/(\d{1,2}[\/\s]\d{1,2}[\/\s]\d{4}(\s+\d{1,2}:\d{2}(:\d{2})?(\s+[AP]M)?)?)/i);
return date ? $.tablesorter.formatFloat((new Date(date[0]).getTime() || ''), table) || s : s;
},
type: "numeric"
});
/*! extract DDMMYYYY (ignore any other text)
* demo: http://jsfiddle.net/Mottie/abkNM/2419/
*/
$.tablesorter.addParser({
id: "extractDDMMYYYY",
is: function (s) {
// don't auto detect this parser
return false;
},
format: function (s, table) {
var date = s.replace(/\s+/g," ").replace(/[\-.,]/g, "/").match(/(\d{1,2}[\/\s]\d{1,2}[\/\s]\d{4}(\s+\d{1,2}:\d{2}(:\d{2})?(\s+[AP]M)?)?)/i);
if (date) {
date = date[0].replace(/(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/, "$2/$1/$3");
return $.tablesorter.formatFloat((new Date(date).getTime() || ''), table) || s;
}
return s;
},
type: "numeric"
});
/*! extract YYYYMMDD (ignore any other text)
* demo: http://jsfiddle.net/Mottie/abkNM/2420/
*/
$.tablesorter.addParser({
id: "extractYYYYMMDD",
is: function (s) {
// don't auto detect this parser
return false;
},
format: function (s, table) {
var date = s.replace(/\s+/g," ").replace(/[\-.,]/g, "/").match(/(\d{4}[\/\s]\d{1,2}[\/\s]\d{1,2}(\s+\d{1,2}:\d{2}(:\d{2})?(\s+[AP]M)?)?)/i);
if (date) {
date = date[0].replace(/(\d{4})[\/\s](\d{1,2})[\/\s](\d{1,2})/, "$2/$3/$1");
return $.tablesorter.formatFloat((new Date(date).getTime() || ''), table) || s;
}
return s;
},
type: "numeric"
});
})(jQuery);

View File

@@ -0,0 +1,34 @@
/*! ISO-8601 date parser
* This parser will work with dates in ISO8601 format
* 2013-02-18T18:18:44+00:00
* Written by Sean Ellingham :https://github.com/seanellingham
* See https://github.com/Mottie/tablesorter/issues/247
*/
/*global jQuery: false */
;(function($){
"use strict";
var iso8601date = /^([0-9]{4})(-([0-9]{2})(-([0-9]{2})(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?$/;
$.tablesorter.addParser({
id : 'iso8601date',
is : function(s) {
return s.match(iso8601date);
},
format : function(s) {
var result = s.match(iso8601date);
if (result) {
var date = new Date(result[1], 0, 1);
if (result[3]) { date.setMonth(result[3] - 1); }
if (result[5]) { date.setDate(result[5]); }
if (result[7]) { date.setHours(result[7]); }
if (result[8]) { date.setMinutes(result[8]); }
if (result[10]) { date.setSeconds(result[10]); }
if (result[12]) { date.setMilliseconds(Number('0.' + result[12]) * 1000); }
return date;
}
return s;
},
type : 'numeric'
});
})(jQuery);

View File

@@ -0,0 +1,33 @@
/*! Month parser
* Demo: http://jsfiddle.net/Mottie/abkNM/477/
*/
/*jshint jquery:true */
;(function($){
"use strict";
var ts = $.tablesorter;
ts.dates = $.extend({}, ts.dates, {
// *** modify this array to change match the language ***
monthCased : [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
});
ts.dates.monthLower = ts.dates.monthCased.join(',').toLocaleLowerCase().split(',');
ts.addParser({
id: "month",
is: function(){
return false;
},
format: function(s, table) {
var j = -1, c = table.config,
n = c.ignoreCase ? s.toLocaleLowerCase() : s;
$.each(ts.dates[ 'month' + (c.ignoreCase ? 'Lower' : 'Cased') ], function(i,v){
if (j < 0 && n.match(v)) { j = i; }
});
// return s (original string) if there isn't a match
// (non-weekdays will sort separately and empty cells will sort as expected)
return j < 0 ? s : j;
},
type: "numeric"
});
})(jQuery);

View File

@@ -0,0 +1,74 @@
/*! Two digit year parser
* Demo: http://jsfiddle.net/Mottie/abkNM/427/
*/
/*jshint jquery:true */
;(function($){
"use strict";
var ts = $.tablesorter,
// Make the date be within +/- range of the 2 digit year
// so if the current year is 2020, and the 2 digit year is 80 (2080 - 2020 > 50), it becomes 1980
// if the 2 digit year is 50 (2050 - 2020 < 50), then it becomes 2050.
range = 50;
ts.dates = $.extend({}, ts.dates, {
regxxxxyy: /(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{2})/,
regyyxxxx: /(\d{2})[\/\s](\d{1,2})[\/\s](\d{1,2})/
});
ts.formatDate = function(s, regex, format, table){
var n = s
// replace separators
.replace(/\s+/g," ").replace(/[-.,]/g, "/")
// reformat xx/xx/xx to mm/dd/19yy;
.replace(regex, format),
d = new Date(n),
y = d.getFullYear(),
rng = table && table.config.dateRange || range,
now = new Date().getFullYear();
// if date > 50 years old (set range), add 100 years
// this will work when people start using "50" and mean "2050"
while (now - y > rng) {
y += 100;
}
return d.setFullYear(y) || s;
};
$.tablesorter.addParser({
id: "ddmmyy",
is: function() {
return false;
},
format: function(s, table) {
// reformat dd/mm/yy to mm/dd/19yy;
return ts.formatDate(s, ts.dates.regxxxxyy, "$2/$1/19$3", table);
},
type: "numeric"
});
$.tablesorter.addParser({
id: "mmddyy",
is: function() {
return false;
},
format: function(s, table) {
// reformat mm/dd/yy to mm/dd/19yy
return ts.formatDate(s, ts.dates.regxxxxyy, "$1/$2/19$3", table);
},
type: "numeric"
});
$.tablesorter.addParser({
id: "yymmdd",
is: function() {
return false;
},
format: function(s, table) {
// reformat yy/mm/dd to mm/dd/19yy
return ts.formatDate(s, ts.dates.regyyxxxx, "$2/$3/19$1", table);
},
type: "numeric"
});
})(jQuery);

View File

@@ -0,0 +1,33 @@
/*! Weekday parser
* Demo: http://jsfiddle.net/Mottie/abkNM/477/
*/
/*jshint jquery:true */
;(function($){
"use strict";
var ts = $.tablesorter;
ts.dates = $.extend({}, ts.dates, {
// *** modify this array to change match the language ***
weekdayCased : [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ]
});
ts.dates.weekdayLower = ts.dates.weekdayCased.join(',').toLocaleLowerCase().split(',');
ts.addParser({
id: "weekday",
is: function(){
return false;
},
format: function(s, table) {
var j = -1, c = table.config;
s = c.ignoreCase ? s.toLocaleLowerCase() : s;
$.each(ts.dates[ 'weekday' + (c.ignoreCase ? 'Lower' : 'Cased') ], function(i,v){
if (j < 0 && s.match(v)) { j = i; }
});
// return s (original string) if there isn't a match
// (non-weekdays will sort separately and empty cells will sort as expected)
return j < 0 ? s : j;
},
type: "numeric"
});
})(jQuery);

View File

@@ -0,0 +1,36 @@
/*!
* Extract dates using popular natural language date parsers
*/
/*jshint jquery:true */
;(function($){
"use strict";
/*! Sugar (http://sugarjs.com/dates#comparing_dates)
* demo: http://jsfiddle.net/Mottie/abkNM/551/
*/
$.tablesorter.addParser({
id: "sugar",
is: function() {
return false;
},
format: function(s) {
return Date.create ? Date.create(s).getTime() || s : new Date(s).getTime() || s;
},
type: "numeric"
});
/*! Datejs (http://www.datejs.com/)
* demo: http://jsfiddle.net/Mottie/abkNM/550/
*/
$.tablesorter.addParser({
id: "datejs",
is: function() {
return false;
},
format: function(s) {
return Date.parse && Date.parse(s) || s;
},
type: "numeric"
});
})(jQuery);

View File

@@ -0,0 +1,40 @@
/*! Duration parser
*/
/*jshint jquery:true, unused:false */
;(function($){
"use strict";
// If any number > 9999, then set table.config.durationLength = 5
// The below regex matches this duration example: 1y 23d 12h 44m 9s
$.tablesorter.addParser({
id: "duration",
is: function() {
return false;
},
format: function(s, table) {
var i, time,
c = table.config,
t = '',
duration = '',
len = c.durationLength || 4,
str = new Array(len + 1).join('0'),
labels = (c.durationLabels || '(?:years|year|y),(?:days|day|d),(?:hours|hour|h),(?:minutes|minute|min|m),(?:seconds|second|sec|s)').split(/\s*,\s*/),
llen = labels.length;
// build regex
if (!c.durationRegex) {
for (i = 0; i < llen; i++) {
t += '(?:(\\d+)\\s*' + labels[i] + '\\s*)?';
}
c.durationRegex = new RegExp(t, 'i');
}
// remove commas from value
time = ( c.usNumberFormat ? s.replace(/,/g, '') : s.replace( /(\d)(?:\.|\s*)(\d)/g, '$1$2') ).match(c.durationRegex);
for (i = 1; i < llen + 1; i++) {
duration += ( str + ( time[i] || 0 ) ).slice(-len);
}
return duration;
},
type: "text"
});
})(jQuery);

View File

@@ -0,0 +1,63 @@
/*! Distance parser
* This parser will parser numbers like 5'10" (5 foot 10 inches)
* and 31½ into sortable values.
* Demo: http://jsfiddle.net/Mottie/abkNM/154/
*/
/*global jQuery: false */
;(function($){
"use strict";
var ts = $.tablesorter;
ts.symbolRegex = /[\u215b\u215c\u215d\u215e\u00bc\u00bd\u00be]/g;
ts.processFractions = function(n, table) {
if (n) {
var t, p = 0;
n = $.trim(n.replace(/\"/,''));
// look for a space in the first part of the number: "10 3/4" and save the "10"
if (/\s/.test(n)) {
p = ts.formatFloat(n.split(' ')[0], table);
// remove stuff to the left of the space
n = $.trim(n.substring(n.indexOf(' '), n.length));
}
// look for a "/" to calculate fractions
if (/\//g.test(n)) {
t = n.split('/');
// turn 3/4 into .75; make sure we don't divide by zero
n = p + parseInt(t[0], 10) / parseInt(t[1] || 1, 10);
// look for fraction symbols
} else if (ts.symbolRegex.test(n)) {
n = p + n.replace(ts.symbolRegex, function(m){
return {
'\u215b' : '.125', // 1/8
'\u215c' : '.375', // 3/8
'\u215d' : '.625', // 5/8
'\u215e' : '.875', // 7/8
'\u00bc' : '.25', // 1/4
'\u00bd' : '.5', // 1/2
'\u00be' : '.75' // 3/4
}[m];
});
}
}
return n || 0;
};
$.tablesorter.addParser({
id: 'distance',
is: function() {
// return false so this parser is not auto detected
return false;
},
format: function(s, table) {
if (s === '') { return ''; }
// look for feet symbol = '
// very generic test to catch 1.1', 1 1/2' and 1½'
var d = (/^\s*\S*(\s+\S+)?\s*\'/.test(s)) ? s.split("'") : [0,s],
f = ts.processFractions(d[0], table), // feet
i = ts.processFractions(d[1], table); // inches
return (/[\'\"]/).test(s) ? parseFloat(f) + (parseFloat(i)/12 || 0) : parseFloat(f) + parseFloat(i);
},
type: 'numeric'
});
})(jQuery);

View File

@@ -0,0 +1,73 @@
/*! File Type parser
* When a file type extension is found, the equivalent name is
* prefixed into the parsed data, so sorting occurs in groups
*/
/*global jQuery: false */
;(function($){
"use strict";
// basic list from http://en.wikipedia.org/wiki/List_of_file_formats
// To add a custom equivalent, define:
// $.tablesorter.fileTypes.equivalents['xx'] = "A|B|C";
$.tablesorter.fileTypes = {
// divides filetype extensions in the equivalent list below
separator : '|',
equivalents : {
"3D Image" : "3dm|3ds|dwg|max|obj",
"Audio" : "aif|aac|ape|flac|la|m4a|mid|midi|mp2|mp3|ogg|ra|raw|rm|wav|wma",
"Compressed" : "7z|bin|cab|cbr|gz|gzip|iso|lha|lz|rar|tar|tgz|zip|zipx|zoo",
"Database" : "csv|dat|db|dbf|json|ldb|mdb|myd|pdb|sql|tsv|wdb|wmdb|xlr|xls|xlsx|xml",
"Development" : "asm|c|class|cls|cpp|cc|cs|cxx|cbp|cs|dba|fla|h|java|lua|pl|py|pyc|pyo|sh|sln|r|rb|vb",
"Document" : "doc|docx|odt|ott|pages|pdf|rtf|tex|wpd|wps|wrd|wri",
"Executable" : "apk|app|com|exe|gadget|lnk|msi",
"Fonts" : "eot|fnt|fon|otf|ttf|woff",
"Icons" : "ani|cur|icns|ico",
"Images" : "bmp|gif|jpg|jpeg|jpe|jp2|pic|png|psd|tga|tif|tiff|wmf|webp",
"Presentation" : "pps|ppt",
"Published" : "chp|epub|lit|pub|ppp|fm|mobi",
"Script" : "as|bat|cgi|cmd|jar|js|lua|scpt|scptd|sh|vbs|vb|wsf",
"Styles" : "css|less|sass",
"Text" : "info|log|md|markdown|nfo|tex|text|txt",
"Vectors" : "awg|ai|eps|cdr|ps|svg",
"Video" : "asf|avi|flv|m4v|mkv|mov|mp4|mpe|mpeg|mpg|ogg|rm|rv|swf|vob|wmv",
"Web" : "asp|aspx|cer|cfm|htm|html|php|url|xhtml"
}
};
$.tablesorter.addParser({
id: 'filetype',
is: function() {
return false;
},
format: function(s, table) {
var t,
c = table.config,
wo = c.widgetOptions,
i = s.lastIndexOf('.'),
sep = $.tablesorter.fileTypes.separator,
m = $.tablesorter.fileTypes.matching,
types = $.tablesorter.fileTypes.equivalents;
if (!m) {
// make a string to "quick" match the existing equivalents
var t = [];
$.each(types, function(i,v){
t.push(v);
});
m = $.tablesorter.fileTypes.matching = sep + t.join(sep) + sep;
}
if (i >= 0) {
t = sep + s.substring(i + 1, s.length) + sep;
if (m.indexOf(t) >= 0) {
for (i in types) {
if ((sep + types[i] + sep).indexOf(t) >= 0) {
return i + (wo.group_separator ? wo.group_separator : '-') + s;
}
}
}
}
return s;
},
type: 'text'
});
})(jQuery);

View File

@@ -0,0 +1,61 @@
/*! Title parser - updated 9/15/2014 (v2.17.8)
* This parser will remove "The", "A" and "An" from the beginning of a book
* or movie title, so it sorts by the second word or number
* Demo: http://jsfiddle.net/Mottie/abkNM/5/
*/
/*jshint browser: true, jquery:true, unused:false */
;(function($){
"use strict";
var ts = $.tablesorter;
// basic list from http://en.wikipedia.org/wiki/Article_%28grammar%29
ts.ignoreArticles = {
"en" : "the, a, an",
"de" : "der, die, das, des, dem, den, ein, eine, einer, eines, einem, einen",
"nl" : "de, het, de, een",
"es" : "el, la, lo, los, las, un, una, unos, unas",
"pt" : "o, a, os, as, um, uma, uns, umas",
"fr" : "le, la, l'_, les, un, une, des",
"it" : "il, lo, la, l'_, i, gli, le, un', uno, una, un",
"hu" : "a, az, egy"
};
// To add a custom parser, define:
// $.tablesorter.ignoreArticles['xx'] = "A, B, C";
// and then set the language id 'xx' in the headers option
// ignoreArticles : 'xx'
ts.addParser({
id: 'ignoreArticles',
is: function() {
return false;
},
format: function(s, table, cell, cellIndex) {
var art, ignore, lang,
c = table.config,
str = s || '';
if ( !(c.headers && c.headers[cellIndex] && c.headers[cellIndex].ignoreArticlesRegex) ) {
// initialize - save regex in c.headers[cellIndex].ignoreArticlesRegex
if (!c.headers) { c.headers = {}; }
if (!c.headers[cellIndex]) { c.headers[cellIndex] = {}; }
lang = ts.getData( c.$headers.eq(cellIndex), ts.getColumnData( table, c.headers, cellIndex ), 'ignoreArticles' );
art = (ts.ignoreArticles[lang] || "the, a, an" ) + "";
c.headers[cellIndex].ignoreArticlesRegex = new RegExp('^(' + $.trim( art.split(/\s*\,\s*/).join('\\s|') + "\\s" ).replace("_\\s","") + ')', 'i');
// exception regex stored in c.headers[cellIndex].ignoreArticlesRegex2
ignore = ts.getData( c.$headers.eq(cellIndex), ts.getColumnData( table, c.headers, cellIndex ), 'ignoreArticlesExcept' );
c.headers[cellIndex].ignoreArticlesRegex2 = ignore !== '' ? new RegExp('^(' + ignore.replace(/\s/g, "\\s") + ')', 'i') : '';
}
art = c.headers[cellIndex].ignoreArticlesRegex;
if (art.test(str)) {
ignore = c.headers[cellIndex].ignoreArticlesRegex2;
if ( !(ignore && ignore.test(str)) ) {
return str.replace(art, '');
}
}
return str;
},
type: 'text'
});
})(jQuery);

View File

@@ -0,0 +1,20 @@
/*! image alt attribute parser for jQuery 1.7+ & tablesorter 2.7.11+
* New 7/17/2014 (v2.17.5)
*/
/*jshint jquery:true, unused:false */
;(function($){
"use strict";
$.tablesorter.addParser({
id: "image",
is: function(){
return false;
},
format: function(s, table, cell) {
return $(cell).find('img').attr(table.config.imgAttr || 'alt') || s;
},
parsed : true, // filter widget flag
type: "text"
});
})(jQuery);

View File

@@ -0,0 +1,161 @@
/*! input & select parsers for jQuery 1.7+ & tablesorter 2.7.11+
* Updated 9/15/2014 (v2.17.8)
* Demo: http://mottie.github.com/tablesorter/docs/example-widget-grouping.html
*/
/*jshint browser: true, jquery:true, unused:false */
;(function($){
"use strict";
var resort = true, // resort table after update
updateServer = function(event, $table, $input){
// do something here to update your server, if needed
// event = change event object
// $table = jQuery object of the table that was just updated
// $input = jQuery object of the input or select that was modified
};
// Custom parser for parsing input values
// updated dynamically using the "change" function below
$.tablesorter.addParser({
id: "inputs",
is: function(){
return false;
},
format: function(s, table, cell) {
return $(cell).find('input').val() || s;
},
parsed : true, // filter widget flag
type: "text"
});
// Custom parser for including checkbox status if using the grouping widget
// updated dynamically using the "change" function below
$.tablesorter.addParser({
id: "checkbox",
is: function(){
return false;
},
format: function(s, table, cell, cellIndex) {
var $c = $(cell),
$input = $c.find('input[type="checkbox"]'),
isChecked = $input.length ? $input[0].checked : '';
// adding class to row, indicating that a checkbox is checked; includes
// a column index in case more than one checkbox happens to be in a row
$c.closest('tr').toggleClass('checked-' + cellIndex, isChecked);
// returning plain language here because this is what is shown in the
// group headers - change it as desired
return $input.length ? isChecked ? 'checked' : 'unchecked' : s;
},
parsed : true, // filter widget flag
type: "text"
});
// Custom parser which returns the currently selected options
// updated dynamically using the "change" function below
$.tablesorter.addParser({
id: "select",
is: function(){
return false;
},
format: function(s, table, cell) {
return $(cell).find('select').val() || s;
},
parsed : true, // filter widget flag
type: "text"
});
// Select parser to get the selected text
$.tablesorter.addParser({
id: "select-text",
is: function(){
return false;
},
format: function(s, table, cell) {
var $s = $(cell).find('select');
return $s.length ? $s.find('option:selected').text() || '' : s;
},
parsed : true, // filter widget flag
type: "text"
});
// Custom parser for parsing textarea values
// updated dynamically using the "change" function below
$.tablesorter.addParser({
id: "textarea",
is: function(){
return false;
},
format: function(s, table, cell) {
return $(cell).find('textarea').val() || s;
},
parsed : true, // filter widget flag
type: "text"
});
// update select and all input types in the tablesorter cache when the change event fires.
// This method only works with jQuery 1.7+
// you can change it to use delegate (v1.4.3+) or live (v1.3+) as desired
// if this code interferes somehow, target the specific table $('#mytable'), instead of $('table')
$(function(){
$('table').on('tablesorter-initialized', function(){
// this flag prevents the updateCell event from being spammed
// it happens when you modify input text and hit enter
var focused = false,
restoreValue = function(isTbody){
// focused = false; // uncomment this line to prevent auto-accepting changes
// make sure we restore original values
// isTbody is needed to prevent the select from closing in IE
// see https://connect.microsoft.com/IE/feedbackdetail/view/962618/
if (isTbody) {
$(':focus').blur();
}
return;
};
// bind to .tablesorter (default class name)
$(this).children('tbody')
.on('mouseleave', function(e){
restoreValue(e.target.tagName === 'TBODY');
})
.on('focus', 'select, input, textarea', function(){
focused = true;
$(this).data('ts-original-value', this.value);
})
.on('blur', 'input, textarea', function(){
// restore input value;
// "change" is triggered before "blur" so this doesn't replace the new update with the original
this.value = $(this).data('ts-original-value');
})
.on('change keyup', 'select, input, textarea', function(e){
if ( e.which === 27 ) {
// escape: restore original value
this.value = $(this).data('ts-original-value');
return;
}
// Update cell cache using... select: change, input: enter or textarea: alt + enter
if ( ( e.type === 'change' && focused ) ||
( e.type === 'keyup' && e.which === 13 && ( e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' && e.altKey ) ) ) {
var $tar = $(e.target),
$cell = $tar.closest('td'),
$table = $cell.closest('table'),
indx = $cell[0].cellIndex,
c = $table[0].config || false,
$hdr = c && c.$headers && c.$headers.eq(indx);
// abort if not a tablesorter table, or
// don't use updateCell if column is set to "sorter-false" and "filter-false", or column is set to "parser-false"
if ( !c || ( $hdr && $hdr.length && ( $hdr.hasClass('parser-false') || ( $hdr.hasClass('sorter-false') && $hdr.hasClass('filter-false') ) ) ) ) {
return restoreValue();
}
// ignore change event if nothing changed
if ($tar.val() !== $tar.data('ts-original-value')) {
$tar.data('ts-original-value', $tar.val());
$table.trigger('updateCell', [ $tar.closest('td'), resort, function(){
updateServer(e, $table, $tar);
setTimeout(function(){ focused = false; }, 10);
} ]);
}
}
});
});
});
})(jQuery);

View File

@@ -0,0 +1,76 @@
/*! IPv6 Address parser (WIP)
* IPv6 Address (ffff:0000:0000:0000:0000:0000:0000:0000)
* needs to support short versions like "::8" or "1:2::7:8"
* and "::00:192.168.10.184" (embedded IPv4 address)
* see http://www.intermapper.com/support/tools/IPV6-Validator.aspx
*/
/*global jQuery: false */
;(function($){
"use strict";
var ts = $.tablesorter;
$.extend( ts.regex, {}, {
ipv4Validate : /((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})/,
ipv4Extract : /([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/,
// simplified regex from http://www.intermapper.com/support/tools/IPV6-Validator.aspx
// (specifically from http://download.dartware.com/thirdparty/ipv6validator.js)
ipv6Validate : /^\s*((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/i
});
ts.addParser({
id: "ipv6Address",
is: function(s) {
return ts.regex.ipv6Validate.test(s);
},
format: function(address, table) {
// code modified from http://forrst.com/posts/JS_Expand_Abbreviated_IPv6_Addresses-1OR
var i, t, sides, groups, groupsPresent,
hex = table ? (typeof table === "boolean" ? table : table && table.config.ipv6HexFormat || false) : false,
fullAddress = '',
expandedAddress = '',
validGroupCount = 8,
validGroupSize = 4;
// remove any extra spaces
address = address.replace(/\s*/g, '');
// look for embedded ipv4
if (ts.regex.ipv4Validate.test(address)) {
groups = address.match(ts.regex.ipv4Extract);
t = '';
for (i = 1; i < groups.length; i++){
t += ('00' + (parseInt(groups[i], 10).toString(16)) ).slice(-2) + ( i === 2 ? ':' : '' );
}
address = address.replace( ts.regex.ipv4Extract, t );
}
if (address.indexOf("::") == -1) {
// All eight groups are present
fullAddress = address;
} else {
// Consecutive groups of zeroes have been collapsed with "::".
sides = address.split("::");
groupsPresent = 0;
for (i = 0; i < sides.length; i++) {
groupsPresent += sides[i].split(":").length;
}
fullAddress += sides[0] + ":";
for (i = 0; i < validGroupCount - groupsPresent; i++) {
fullAddress += "0000:";
}
fullAddress += sides[1];
}
groups = fullAddress.split(":");
for (i = 0; i < validGroupCount; i++) {
// it's fastest & easiest for tablesorter to sort decimal values (vs hex)
groups[i] = hex ? ('0000' + groups[i]).slice(-4) :
('00000' + (parseInt(groups[i], 16) || 0)).slice(-5);
expandedAddress += ( i != validGroupCount-1) ? groups[i] + ':' : groups[i];
}
return hex ? expandedAddress : expandedAddress.replace(/:/g, '');
},
// uses natural sort hex compare
type: "numeric"
});
})(jQuery);

View File

@@ -0,0 +1,77 @@
/*! Metric parser
* Demo: http://jsfiddle.net/Mottie/abkNM/382/
* Set the metric name in the header (defaults to "m|meter"), e.g.
* <th data-metric-name="b|byte">HDD Size</th>
* <th data-metric-name="m|meter">Distance</th>
*/
/*jshint jquery:true */
;(function($){
"use strict";
var prefixes = {
// "prefix" : [ base 10, base 2 ]
// skipping IEEE 1541 defined prefixes: kibibyte, mebibyte, etc, for now.
"Y|Yotta|yotta" : [ 1e24, Math.pow(1024, 8) ], // 1024^8
"Z|Zetta|zetta" : [ 1e21, Math.pow(1024, 7) ], // 1024^7
"E|Exa|exa" : [ 1e18, Math.pow(1024, 6) ], // 1024^6
"P|Peta|peta" : [ 1e15, Math.pow(1024, 5) ], // 1024^5
"T|Tera|tera" : [ 1e12, Math.pow(1024, 4) ], // 1024^4
"G|Giga|giga" : [ 1e9, Math.pow(1024, 3) ], // 1024^3
"M|Mega|mega" : [ 1e6, Math.pow(1024, 2) ], // 1024^2
"k|Kilo|kilo" : [ 1e3, 1024 ], // 1024
// prefixes below here are rarely, if ever, used in binary
"h|hecto" : [ 1e2, 1e2 ],
"da|deka" : [ 1e1, 1e1 ],
"d|deci" : [ 1e-1, 1e-1 ],
"c|centi" : [ 1e-2, 1e-2],
"m|milli" : [ 1e-3, 1e-3 ],
"µ|micro" : [ 1e-6, 1e-6 ],
"n|nano" : [ 1e-9, 1e-9 ],
"p|pico" : [ 1e-12, 1e-12 ],
"f|femto" : [ 1e-15, 1e-15 ],
"a|atto" : [ 1e-18, 1e-18 ],
"z|zepto" : [ 1e-21, 1e-21 ],
"y|yocto" : [ 1e-24, 1e-24 ]
},
// the \\d+ will not catch digits with spaces, commas or decimals; so use the value from n instead
RegLong = "(\\d+)(\\s+)?([Zz]etta|[Ee]xa|[Pp]eta|[Tt]era|[Gg]iga|[Mm]ega|kilo|hecto|deka|deci|centi|milli|micro|nano|pico|femto|atto|zepto|yocto)(",
RegAbbr = "(\\d+)(\\s+)?(Z|E|P|T|G|M|k|h|da|d|c|m|µ|n|p|f|a|z|y)(";
$.tablesorter.addParser({
id: 'metric',
is: function() {
return false;
},
format: function(s, table, cell, cellIndex) {
var v = 'm|meter',
b, t,
// process number here to get a numerical format (us or eu)
n = $.tablesorter.formatFloat(s.replace(/[^\w,. \-()]/g, ""), table),
$t = table.config.$headers.filter('[data-column="' + cellIndex + '"]'),
m = $t.data('metric');
if (!m) {
// stored values
t = ($t.attr('data-metric-name') || v).split('|');
m = [ t[1] || t[0].substring(1), t[0] ];
m[2] = new RegExp(RegLong + m[0] + "|" + m[1] + ")");
m[3] = new RegExp(RegAbbr + m[1] + ")");
$t.data('metric', m);
}
// find match to full name or abbreviation
t = s.match(m[2]) || s.match(m[3]);
if (t) {
for (v in prefixes) {
if (t[3].match(v)) {
// exception when using binary prefix
// change base for binary use
b = /^[b|bit|byte|o|octet]/.test(t[4]) ? 1 : 0;
return n * prefixes[v][b];
}
}
}
return n;
},
type: 'numeric'
});
})(jQuery);

View File

@@ -0,0 +1,117 @@
/*! Roman numeral parsers
* code modified from both:
* Steven Levithan @ http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter
* Jonathan Snook comment @ http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter#comment-16140
*/
/*jshint jquery:true, unused:false */
;(function($){
"use strict";
// allow lower case roman numerals, since lists use i, ii, iii, etc.
var validator = /^M*(?:D?C{0,3}|C[MD])(?:L?X{0,3}|X[CL])(?:V?I{0,3}|I[XV])$/i,
matcher = /\b([MCDLXVI]+\b)/gi,
lookup = { I:1, V:5, X:10, L:50, C:100, D:500, M:1000 };
$.tablesorter.addParser({
id: 'roman',
is: function(){
return false;
},
format: function(s) {
var val,
roman = s.toUpperCase().split(''),
num = 0;
// roman numerals not found!
if ( !(s && validator.test(s)) ) {
return s;
}
while (roman.length) {
val = lookup[roman.shift()];
num += val * (val < lookup[roman[0]] ? -1 : 1);
}
return num;
},
type: "numeric"
});
$.tablesorter.addParser({
id: 'roman-ignore',
is: function(){
return false;
},
format: function(s, table, cell, column) {
var val, orig,
c = table.config,
ignore = $.isArray(c.roman_ignore) ? c.roman_ignore[column] : 0,
// find roman numerals
roman = ( isNaN(ignore) ?
// ignore can be a regex or string
$.trim( s.replace(ignore, '') ) :
// or a number to ignore the last x letters...
$.trim( s.substring(0, s.length - ignore) )
).match(matcher),
v = validator.test(roman),
num = 0;
// roman numerals not found!
if ( !(v) ) {
return s;
}
// save roman numeral for replacement
orig = roman[0];
roman = orig.toUpperCase().split('');
while (roman.length) {
val = lookup[roman.shift()];
// ignore non-roman numerals
if (val) {
num += val * (val < lookup[roman[0]] ? -1 : 1);
}
}
return num ? s.replace(orig, num) : s;
},
type: "text"
});
$.tablesorter.addParser({
id: 'roman-extract',
is: function(){
return false;
},
format: function(s) {
var val,
// find roman numerals
roman = $.grep(s.split(/\b/), function(v, i){
return validator.test(v) ? v : '';
}).join('').match(matcher),
v = roman ? validator.test(roman) : 0,
num = 0;
// roman numerals not found!
if ( !(v) ) {
return s;
}
// save roman numeral for replacement
roman = roman[0].toUpperCase().split('');
while (roman.length) {
val = lookup[roman.shift()];
// ignore non-roman numerals
if (val) {
num += val * (val < lookup[roman[0]] ? -1 : 1);
}
}
return num ? num : s;
},
type: "numeric"
});
})(jQuery);