PageSourceSearch

https://www.egydes.com/_autoindex/assets/js/tablesort.js

js egydes.com collected 2026-09-26 08:25:41 UTC 7,706 bytes, 277 lines download raw bytes

1;(function() {
2  function Tablesort(el, options) {
3    if (!(this instanceof Tablesort)) return new Tablesort(el, options);
4
5    if (!el || el.tagName !== 'TABLE') {
6      throw new Error('Element must be a table');
7    }
8    this.init(el, options || {});
9  }
10
11  var sortOptions = [];
12
13  var createEvent = function(name) {
14    var evt;
15
16    if (!window.CustomEvent || typeof window.CustomEvent !== 'function') {
17      evt = document.createEvent('CustomEvent');
18      evt.initCustomEvent(name, false, false, undefined);
19    } else {
20      evt = new CustomEvent(name);
21    }
22
23    return evt;
24  };
25
26  var getInnerText = function(el) {
27    return el.getAttribute('data-sort') || el.textContent || el.innerText || '';
28  };
29
30  // Default sort method if no better sort method is found
31  var caseInsensitiveSort = function(a, b) {
32    a = a.trim().toLowerCase();
33    b = b.trim().toLowerCase();
34
35    if (a === b) return 0;
36    if (a < b) return 1;
37
38    return -1;
39  };
40
41  var getCellByKey = function(cells, key) {
42    return [].slice.call(cells).find(function(cell) {
43      return cell.getAttribute('data-sort-column-key') === key;
44    });
45  };
46
47  // Stable sort function
48  // If two elements are equal under the original sort function,
49  // then there relative order is reversed
50  var stabilize = function(sort, antiStabilize) {
51    return function(a, b) {
52      var unstableResult = sort(a.td, b.td);
53
54      if (unstableResult === 0) {
55        if (antiStabilize) return b.index - a.index;
56        return a.index - b.index;
57      }
58
59      return unstableResult;
60    };
61  };
62
63  Tablesort.extend = function(name, pattern, sort) {
64    if (typeof pattern !== 'function' || typeof sort !== 'function') {
65      throw new Error('Pattern and sort must be a function');
66    }
67
68    sortOptions.push({
69      name: name,
70      pattern: pattern,
71      sort: sort
72    });
73  };
74
75  Tablesort.prototype = {
76
77    init: function(el, options) {
78      var that = this,
79          firstRow,
80          defaultSort,
81          i,
82          cell;
83
84      that.table = el;
85      that.thead = false;
86      that.options = options;
87
88      if (el.rows && el.rows.length > 0) {
89        if (el.tHead && el.tHead.rows.length > 0) {
90          for (i = 0; i < el.tHead.rows.length; i++) {
91            if (el.tHead.rows[i].getAttribute('data-sort-method') === 'thead') {
92              firstRow = el.tHead.rows[i];
93              break;
94            }
95          }
96          if (!firstRow) {
97            firstRow = el.tHead.rows[el.tHead.rows.length - 1];
98          }
99          that.thead = true;
100        } else {
101          firstRow = el.rows[0];
102        }
103      }
104
105      if (!firstRow) return;
106
107      var onClick = function() {
108        if (that.current && that.current !== this) {
109          that.current.removeAttribute('aria-sort');
110        }
111
112        that.current = this;
113        that.sortTable(this);
114      };
115
116      // Assume first row is the header and attach a click handler to each.
117      for (i = 0; i < firstRow.cells.length; i++) {
118        cell = firstRow.cells[i];
119        cell.setAttribute('role','columnheader');
120        if (cell.getAttribute('data-sort-method') !== 'none') {
121          cell.tabindex = 0;
122          cell.addEventListener('click', onClick, false);
123
124          if (cell.getAttribute('data-sort-default') !== null) {
125            defaultSort = cell;
126          }
127        }
128      }
129
130      if (defaultSort) {
131        that.current = defaultSort;
132        that.sortTable(defaultSort);
133      }
134    },
135
136    sortTable: function(header, update) {
137      var that = this,
138          columnKey = header.getAttribute('data-sort-column-key'),
139          column = header.cellIndex,
140          sortFunction = caseInsensitiveSort,
141          item = '',
142          items = [],
143          i = that.thead ? 0 : 1,
144          sortMethod = header.getAttribute('data-sort-method'),
145          sortOrder = header.getAttribute('aria-sort');
146
147      that.table.dispatchEvent(createEvent('beforeSort'));
148
149      // If updating an existing sort, direction should remain unchanged.
150      if (!update) {
151        if (sortOrder === 'ascending') {
152          sortOrder = 'descending';
153        } else if (sortOrder === 'descending') {
154          sortOrder = 'ascending';
155        } else {
156          sortOrder = that.options.descending ? 'descending' : 'ascending';
157        }
158
159        header.setAttribute('aria-sort', sortOrder);
160      }
161
162      if (that.table.rows.length < 2) return;
163
164      // If we force a sort method, it is not necessary to check rows
165      if (!sortMethod) {
166        var cell;
167        while (items.length < 3 && i < that.table.tBodies[0].rows.length) {
168          if(columnKey) {
169            cell = getCellByKey(that.table.tBodies[0].rows[i].cells, columnKey);
170          } else {
171            cell = that.table.tBodies[0].rows[i].cells[column];
172          }
173
174          // Treat missing cells as empty cells
175          item = cell ? getInnerText(cell) : "";
176
177          item = item.trim();
178
179          if (item.length > 0) {
180            items.push(item);
181          }
182
183          i++;
184        }
185
186        if (!items) return;
187      }
188
189      for (i = 0; i < sortOptions.length; i++) {
190        item = sortOptions[i];
191
192        if (sortMethod) {
193          if (item.name === sortMethod) {
194            sortFunction = item.sort;
195            break;
196          }
197        } else if (items.every(item.pattern)) {
198          sortFunction = item.sort;
199          break;
200        }
201      }
202
203      that.col = column;
204
205      for (i = 0; i < that.table.tBodies.length; i++) {
206        var newRows = [],
207            noSorts = {},
208            j,
209            totalRows = 0,
210            noSortsSoFar = 0;
211
212        if (that.table.tBodies[i].rows.length < 2) continue;
213
214        for (j = 0; j < that.table.tBodies[i].rows.length; j++) {
215          var cell;
216
217          item = that.table.tBodies[i].rows[j];
218          if (item.getAttribute('data-sort-method') === 'none') {
219            // keep no-sorts in separate list to be able to insert
220            // them back at their original position later
221            noSorts[totalRows] = item;
222          } else {
223            if (columnKey) {
224              cell = getCellByKey(item.cells, columnKey);
225            } else {
226              cell = item.cells[that.col];
227            }
228            // Save the index for stable sorting
229            newRows.push({
230              tr: item,
231              td: cell ? getInnerText(cell) : '',
232              index: totalRows
233            });
234          }
235          totalRows++;
236        }
237        // Before we append should we reverse the new array or not?
238        // If we reverse, the sort needs to be `anti-stable` so that
239        // the double negatives cancel out
240        if (sortOrder === 'descending') {
241          newRows.sort(stabilize(sortFunction, true));
242        } else {
243          newRows.sort(stabilize(sortFunction, false));
244          newRows.reverse();
245        }
246
247        // append rows that already exist rather than creating new ones
248        for (j = 0; j < totalRows; j++) {
249          if (noSorts[j]) {
250            // We have a no-sort row for this position, insert it here.
251            item = noSorts[j];
252            noSortsSoFar++;
253          } else {
254            item = newRows[j - noSortsSoFar].tr;
255          }
256
257          // appendChild(x) moves x if already present somewhere else in the DOM
258          that.table.tBodies[i].appendChild(item);
259        }
260      }
261
262      that.table.dispatchEvent(createEvent('afterSort'));
263    },
264
265    refresh: function() {
266      if (this.current !== undefined) {
267        this.sortTable(this.current, true);
268      }
269    }
270  };
271
272  if (typeof module !== 'undefined' && module.exports) {
273    module.exports = Tablesort;
274  } else {
275    window.Tablesort = Tablesort;
276  }
277})();

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.