mirror of
https://github.com/samuelclay/NewsBlur.git
synced 2025-08-05 16:58:59 +00:00
127 lines
No EOL
3.9 KiB
JavaScript
127 lines
No EOL
3.9 KiB
JavaScript
/*
|
|
* jQuery TinySort - A plugin to sort child nodes by (sub) contents or attributes.
|
|
*
|
|
* Version: 1.0.4
|
|
*
|
|
* Copyright (c) 2008 Ron Valstar
|
|
*
|
|
* Dual licensed under the MIT and GPL licenses:
|
|
* http://www.opensource.org/licenses/mit-license.php
|
|
* http://www.gnu.org/licenses/gpl.html
|
|
*
|
|
* description
|
|
* - A plugin to sort child nodes by (sub) contents or attributes.
|
|
*
|
|
* Usage:
|
|
* $("ul#people>li").tsort();
|
|
* $("ul#people>li").tsort("span.surname");
|
|
* $("ul#people>li").tsort("span.surname",{order:"desc"});
|
|
* $("ul#people>li").tsort({place:"end"});
|
|
*
|
|
* Change default like so:
|
|
* $.tinysort.defaults.order = "desc";
|
|
*
|
|
* in this update:
|
|
* - changed setArray to pushStack
|
|
*
|
|
* in last update:
|
|
* - tested with jQuery 1.4.1
|
|
* - correct isNum return
|
|
*
|
|
* Todos
|
|
* - fix mixed literal/numeral values
|
|
* - determine if I have to use pushStack or pushStack
|
|
*
|
|
*/
|
|
;(function($) {
|
|
// default settings
|
|
$.tinysort = {
|
|
id: "TinySort"
|
|
,version: "1.0.4"
|
|
,defaults: {
|
|
order: "asc" // order: asc, desc or rand
|
|
,attr: "" // order by attribute value
|
|
,place: "start" // place ordered elements at position: start, end, org (original position), first
|
|
,returns: false // return all elements or only the sorted ones (true/false)
|
|
}
|
|
};
|
|
$.fn.extend({
|
|
tinysort: function(_find,_settings) {
|
|
if (_find&&typeof(_find)!="string") {
|
|
_settings = _find;
|
|
_find = null;
|
|
}
|
|
|
|
var oSettings = $.extend({}, $.tinysort.defaults, _settings);
|
|
|
|
var oElements = {}; // contains sortable- and non-sortable list per parent
|
|
this.each(function(i) {
|
|
// element or sub selection
|
|
var mElm = (!_find||_find=="")?$(this):$(this).find(_find);
|
|
// text or attribute value
|
|
var sSort = oSettings.order=="rand"?""+Math.random():(oSettings.attr==""?mElm.text():mElm.attr(oSettings.attr));
|
|
// to sort or not to sort
|
|
var mParent = $(this).parent();
|
|
if (!oElements[mParent]) oElements[mParent] = {s:[],n:[]}; // s: sort, n: not sort
|
|
if (mElm.length>0) oElements[mParent].s.push({s:sSort,e:$(this),n:i}); // s:string, e:element, n:number
|
|
else oElements[mParent].n.push({e:$(this),n:i});
|
|
});
|
|
//
|
|
// sort
|
|
for (var sParent in oElements) {
|
|
var oParent = oElements[sParent];
|
|
oParent.s.sort(
|
|
function zeSort(a,b) {
|
|
var x = a.s.toLowerCase?a.s.toLowerCase():a.s;
|
|
var y = b.s.toLowerCase?b.s.toLowerCase():b.s;
|
|
if (isNum(a.s)&&isNum(b.s)) {
|
|
x = parseFloat(a.s);
|
|
y = parseFloat(b.s);
|
|
}
|
|
return (oSettings.order=="asc"?1:-1)*(x<y?-1:(x>y?1:0));
|
|
}
|
|
);
|
|
}
|
|
//
|
|
// order elements and fill new order
|
|
var aNewOrder = [];
|
|
for (var sParent in oElements) {
|
|
var oParent = oElements[sParent];
|
|
var aOrg = []; // list for original position
|
|
var iLow = $(this).length;
|
|
switch (oSettings.place) {
|
|
case "first": $.each(oParent.s,function(i,obj) { iLow = Math.min(iLow,obj.n) }); break;
|
|
case "org": $.each(oParent.s,function(i,obj) { aOrg.push(obj.n) }); break;
|
|
case "end": iLow = oParent.n.length; break;
|
|
default: iLow = 0;
|
|
}
|
|
var aCnt = [0,0]; // count how much we've sorted for retreival from either the sort list or the non-sort list (oParent.s/oParent.n)
|
|
for (var i=0;i<$(this).length;i++) {
|
|
var bSList = i>=iLow&&i<iLow+oParent.s.length;
|
|
if (contains(aOrg,i)) bSList = true;
|
|
var mEl = (bSList?oParent.s:oParent.n)[aCnt[bSList?0:1]].e;
|
|
mEl.parent().append(mEl);
|
|
if (bSList||!oSettings.returns) aNewOrder.push(mEl.get(0));
|
|
aCnt[bSList?0:1]++;
|
|
}
|
|
}
|
|
//
|
|
return this.pushStack(aNewOrder); // pushStack or pushStack?
|
|
}
|
|
});
|
|
// is numeric
|
|
function isNum(n) {
|
|
var x = /^\s*?[\+-]?(\d*\.?\d*?)\s*?$/.exec(n);
|
|
return x&&x.length>0?x[1]:false;
|
|
};
|
|
// array contains
|
|
function contains(a,n) {
|
|
var bInside = false;
|
|
$.each(a,function(i,m) {
|
|
if (!bInside) bInside = m==n;
|
|
});
|
|
return bInside;
|
|
};
|
|
// set functions
|
|
$.fn.TinySort = $.fn.Tinysort = $.fn.tsort = $.fn.tinysort;
|
|
})(jQuery); |