Jump to content

Edit filter log

Details for log entry 28721036

02:10, 26 January 2021: Jon (WMF) (talk | contribs) triggered filter 960, performing the action "edit" on User:Tcncv/sorttables.js. Actions taken: none; Filter description: Log edits to other user's scripts (examine | diff)

Changes made in edit

var idnum = 0;
var idnum = 0;
// Find all tables with class sortable and make them sortable
// Find all tables with class sortable and make them sortable
var tables = getElementsByClassName(document, "table", "tsx_sortable");
var tables = document.querySelectorAll("table.tsx_sortable");
for (var ti = 0; ti < tables.length ; ti++) {
for (var ti = 0; ti < tables.length ; ti++) {
if (!tables[ti].id) {
if (!tables[ti].id) {
// Delete any other arrows there may be showing
// Delete any other arrows there may be showing
for (var r = 0; r < rowStart; r++) {
for (var r = 0; r < rowStart; r++) {
var spans = getElementsByClassName(table.rows[r], "span", "sortarrow");
var spans = table.rows[r].querySelectorAll("span.sortarrow");
for (var i = 0; i < spans.length; i++) {
for (var i = 0; i < spans.length; i++) {
spans[i].innerHTML = '<img src="'+ tsx_image_path + tsx_image_none + '" alt="&#x21C5;"/>';
spans[i].innerHTML = '<img src="'+ tsx_image_path + tsx_image_none + '" alt="&#x21C5;"/>';

Action parameters

VariableValue
Edit count of the user (user_editcount)
239
Name of the user account (user_name)
'Jon (WMF)'
Age of the user account (user_age)
282401907
Groups (including implicit) the user is in (user_groups)
[ 0 => '*', 1 => 'user', 2 => 'autoconfirmed' ]
Rights that the user has (user_rights)
[ 0 => 'autoconfirmed', 1 => 'edit', 2 => 'editcontentmodel', 3 => 'editeditorprotected', 4 => 'editextendedsemiprotected', 5 => 'editinterface', 6 => 'editprotected', 7 => 'editsemiprotected', 8 => 'editsitecss', 9 => 'editsitejs', 10 => 'editsitejson', 11 => 'editusercss', 12 => 'edituserjs', 13 => 'extendedconfirmed', 14 => 'oathauth-enable', 15 => 'protect', 16 => 'suppressredirect', 17 => 'tboverride', 18 => 'templateeditor', 19 => 'abusefilter-hidden-log', 20 => 'abusefilter-hide-log', 21 => 'abusefilter-log', 22 => 'abusefilter-log-detail', 23 => 'abusefilter-log-private', 24 => 'abusefilter-modify', 25 => 'abusefilter-modify-global', 26 => 'abusefilter-modify-restricted', 27 => 'abusefilter-revert', 28 => 'abusefilter-view', 29 => 'abusefilter-view-private', 30 => 'apihighlimits', 31 => 'autopatrol', 32 => 'bigdelete', 33 => 'block', 34 => 'blockemail', 35 => 'browsearchive', 36 => 'centralauth-lock', 37 => 'centralauth-merge', 38 => 'centralauth-oversight', 39 => 'centralauth-unmerge', 40 => 'delete', 41 => 'deletechangetags', 42 => 'deletedhistory', 43 => 'deletedtext', 44 => 'deletelogentry', 45 => 'deleterevision', 46 => 'edituserjson', 47 => 'flow-create-board', 48 => 'flow-delete', 49 => 'globalgroupmembership', 50 => 'globalgrouppermissions', 51 => 'ipblock-exempt', 52 => 'override-export-depth', 53 => 'skipcaptcha', 54 => 'tboverride-account', 55 => 'unblockself', 56 => 'undelete', 57 => 'upload_by_url', 58 => 'userrights', 59 => 'userrights-interwiki', 60 => 'createaccount', 61 => 'read', 62 => 'createtalk', 63 => 'writeapi', 64 => 'viewmywatchlist', 65 => 'editmywatchlist', 66 => 'viewmyprivateinfo', 67 => 'editmyprivateinfo', 68 => 'editmyoptions', 69 => 'vipsscaler-test', 70 => 'collectionsaveasuserpage', 71 => 'reupload-own', 72 => 'move-rootuserpages', 73 => 'createpage', 74 => 'minoredit', 75 => 'editmyusercss', 76 => 'editmyuserjson', 77 => 'editmyuserjs', 78 => 'purge', 79 => 'sendemail', 80 => 'applychangetags', 81 => 'spamblacklistlog', 82 => 'mwoauthmanagemygrants', 83 => 'reupload', 84 => 'upload', 85 => 'move', 86 => 'collectionsaveascommunitypage', 87 => 'transcode-reset', 88 => 'createpagemainns', 89 => 'movestable', 90 => 'autoreview' ]
Whether the user is editing from mobile app (user_app)
false
Whether or not a user is editing through the mobile interface (user_mobile)
false
Page ID (page_id)
20955842
Page namespace (page_namespace)
2
Page title without namespace (page_title)
'Tcncv/sorttables.js'
Full page title (page_prefixedtitle)
'User:Tcncv/sorttables.js'
Edit protection level of the page (page_restrictions_edit)
[]
Page age in seconds (page_age)
380509730
Action (action)
'edit'
Edit summary/reason (summary)
'maintenance: [[metawiki:User:Jon_(WMF)/Edit_to_user_or_gadget_script|more info]] ReferenceError: getElementsByClassName is not defined '
Old content model (old_content_model)
'javascript'
New content model (new_content_model)
'javascript'
Old page wikitext, before the edit (old_wikitext)
'/* * Draft fix for: https://bugzilla.wikimedia.org/show_bug.cgi?id=8028 * * Current status: Shelved due to limited interest. * * Enhancements: * 1. Will explode rowspans, so that rows are self contained and can be sorted * without corrupting the table structure. * 2. Will recognize colspans, so that the proper value is retrieved from each * row. Each column in a colspan range is treated as having the same value. * Colspans are preserved during sorting; they are not split. * 3. After sorting, some cell ranges may be recombined under certain restrictive * conditions. The class="autorowspan" option can be applied to column * headers or the entire table to enable more aggressive rowspan combines, such * as combining cells in the currently sorted column that were not originally * combined. Current merge rules: * a. Only merge cells in adjacent sorted columns, selected right to left. * b. Only merge if cells to left also merged, or if leftmost sorted column. * c. Only merge if cells have same ID or if class="autorowspan" is active. * d. And of course, cells must be equivalent (content and attributes). * e. Do not merge header, footer (sortbottom) or fixed (unsortable) rows. * 4. Supports multi-row headers with a mix of rowspans and colspans. Clicking on * the sort icon in a colspan'd header will perform a multi-column sort. The * "unsortable" class name can be used in the header to limit sort icon creation. * * Bugs/Limitations: * 1. Conflicting (partially overlapping) rowspans/colspans are not supported. (This * is invalid in HTML, so is not a worry.) * 2. Rowspans that add extra table rows are not supported. * 3. Table row attributes are not compared when combining cells. * 4. Some intermittent problems observed very early in development when using table * sorting + Twinkle + IE + with complex pages having large amounts of table data. * (This problem has not been duplicated.) * * Todo: * 1. Restore thead/tbody/tfoot support (see bugzilla bug id 4740) * 2. Merge with any recent released source changes. * 3. Test on other browser configurations. * 4. Solicit feature discussion and code review. * 5. Prepare formal test cases and submit to bugzilla. * * Related: * 1. [[Help:Sorting]] - Document new capabilities with examples. * 2. [[Wikipedia:Catalogue of CSS classes]] - Add new "autorowspan" class and * update "unsortable" to document new use. * * Other possible enhancements (extra complexity may not be justified): * 1. Consider if it be useful to apply autorowspan to the original table before * its initial display? (Might same some tedious table formatting effort.) * 2. Option to automatically apply initial sort. * 3. Implement mixed mode sorting option (numbers, dates, and text) in a manner * similar to Excel, and possibly compound sorting of mixed data (9Z < 10A). * 4. Support fixed columns whose cells do not move with the sort (a lot of work). * */ /* The following is based on code extracted from wikibits * (/trunk/phase3/skins/common/wikibits.js) revision 45304, Fri Jan 2, 2009. * (http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/skins/common/wikibits.js?view=log) * All global variables and functions were renamed from a "ts_" prefix to * "tsx_" (Table Sort eXperimental) prefix. The table class affected was * changed from "sortable" to "tsx_sortable". */ /* * Table sorting script based on one (c) 1997-2006 Stuart Langridge and Joost * de Valk: * http://www.joostdevalk.nl/code/sortable-table/ * http://www.kryogenix.org/code/browser/sorttable/ * * @todo don't break on colspans/rowspans (bug 8028) * @todo language-specific digit grouping/decimals (bug 8063) * @todo support all accepted date formats (bug 8226) */ var tsx_image_path = stylepath+"/common/images/"; var tsx_image_up = "sort_up.gif"; var tsx_image_down = "sort_down.gif"; var tsx_image_none = "sort_none.gif"; var tsx_europeandate = wgContentLanguage != "en"; // The non-American-inclined can change to "true" var tsx_alternate_row_colors = false; var tsx_number_transform_table = null; var tsx_number_regex = null; var tsx_SortedColumnRanges = new Array; function tsx_sortables_init() { var idnum = 0; // Find all tables with class sortable and make them sortable var tables = getElementsByClassName(document, "table", "tsx_sortable"); for (var ti = 0; ti < tables.length ; ti++) { if (!tables[ti].id) { tables[ti].setAttribute('id','sortable_table_id_tsx_'+idnum); ++idnum; } tsx_makeSortable(tables[ti]); } } addOnloadHook(tsx_sortables_init); function tsx_makeSortable(table) { if (!table.rows || table.rows.length == 0) return; // Count header rows. First row is always considered part of the header. // Also include rows having class=sortheader" or containing only TH cells. var numHeaders = 1; // Also equals rowStart var isHeader = true; for (var r = 1; r < table.rows.length && isHeader; r++) { if ((" "+table.rows[r].className+" ").indexOf(" sortheader ") == -1) { for (var i = 0; i < table.rows[r].cells.length && isHeader; i++) { if (table.rows[r].cells[i].nodeName.toUpperCase() != "TH") { isHeader = false; } } } if (isHeader) numHeaders = r + 1; } if (table.rows.length - numHeaders < 2) return; var repeatedCells = new Array(); for (var r = 0; r < numHeaders; r++) { var row = table.rows[r]; var c = 0; // column number and repeatedCells index var i = 0; // cells index (may be less than column number) while (i < row.cells.length || c < repeatedCells.length) { if (c < repeatedCells.length && repeatedCells[c] && repeatedCells[c].remaining > 0) { // Use repeated cell repeatedCells[c].remaining--; // remaining_repeats c += repeatedCells[c].cell.colSpan; } else if (i < row.cells.length ) { // Use existing defined cell. If rowspan, save for later duplication. var cell = row.cells[i]; if ((" "+cell.className+" ").indexOf(" unsortable ") == -1) { cell.innerHTML += '&nbsp;&nbsp;' + '<a href="#" class="sortheader" ' + 'onclick="tsx_resortTable(this,' + numHeaders.toString() + ',' + c.toString() + ',' + cell.colSpan.toString() + ');return false;">' + '<span class="sortarrow">' + '<img src="' + tsx_image_path + tsx_image_none + '" alt="&#x21C5;"/></span></a>'; } if (cell.rowSpan > 1) { repeatedCells[c] = new tsx_RepeatedCell(cell); } c += cell.colSpan; i++; } else { c += 1; //undefined cell i++; } } } if (tsx_alternate_row_colors) { tsx_alternate(table); } } function tsx_copyCell(to_cell, from_cell) { to_cell.innerHTML = from_cell.innerHTML; from_cell.innerHTML = from_cell.innerHTML; // Copy to self - IE morphs some values for (var i = 0; i < from_cell.attributes.length; i++) { var nodeName = from_cell.attributes[i].nodeName; var nodeValue = from_cell.getAttribute(nodeName); var nodeValueType = typeof nodeValue; if (nodeValue!=null && (nodeValueType == "string" || nodeValueType == "number" || nodeValueType == "boolean")) { to_cell.setAttribute(nodeName, nodeValue); } } to_cell.innerHTML = from_cell.innerHTML; // Overkill from_cell.innerHTML = from_cell.innerHTML; // Overkill } function tsx_compareCells(lhs, rhs) { if (lhs.innerHTML != rhs.innerHTML) return false; for (var i = 0; i < lhs.attributes.length; i++) { var nodeName = lhs.attributes[i].nodeName; var nodeNameLower = nodeName.toLowerCase(); /* IE uses mixed case */ var nodeValue = lhs.attributes[i].nodeValue; var nodeValueType = typeof nodeValue; if (nodeNameLower != "id" && nodeNameLower != "rowspan" && nodeValue!=null && (nodeValueType == "string" || nodeValueType == "number" || nodeValueType == "boolean")) { if (rhs.getAttribute(nodeName) != lhs.getAttribute(nodeName)) { return false; } } } for (var i = 0; i < rhs.attributes.length; i++) { var nodeName = rhs.attributes[i].nodeName; var nodeNameLower = nodeName.toLowerCase(); /* IE uses mixed case */ var nodeValue = rhs.attributes[i].nodeValue; var nodeValueType = typeof nodeValue; if (nodeNameLower != "id" && nodeNameLower != "rowspan" && nodeValue!=null && (nodeValueType == "string" || nodeValueType == "number" || nodeValueType == "boolean")) { if (rhs.getAttribute(nodeName) != lhs.getAttribute(nodeName)) { return false; } } } return true; } // Construct object to track remaining occurrences or rowspanned cell function tsx_RepeatedCell(cell) { this.cell = cell; this.remaining = cell.rowSpan - 1; } // Identify and duplicate rowspanned cells so that each row has its own copy function tsx_explodeRowspans(table, rowStart) { var rowspangroup_seq = 0; // Used to generate ids for rowspan cell groups var repeatedCells = new Array(); for (var r = rowStart; r < table.rows.length; r++) { var row = table.rows[r]; var c = 0; // column number and repeatedCells index var i = 0; // cells index (may be less than column number) while (i < row.cells.length || c < repeatedCells.length) { if (c < repeatedCells.length && repeatedCells[c] && repeatedCells[c].remaining > 0) { // Use repeated cell row.insertCell(i); tsx_copyCell(row.cells[i], repeatedCells[c].cell); row.cells[i].rowSpan = 1; repeatedCells[c].remaining--; // remaining_repeats } else if (i < row.cells.length ) { // Use existing defined cell. If rowspan, save for later duplication. if (row.cells[i].rowSpan > 1) { if (row.cells[i].id == "" ) { row.cells[i].id = table.id + ".rowspangroup." + (++rowspangroup_seq); } repeatedCells[c] = new tsx_RepeatedCell(row.cells[i]); row.cells[i].rowSpan = 1; } } else { // Insert filler cell row.insertCell(i); } c += row.cells[i].colSpan; // Note: Conflicting rowspan/colspan are not supported i++; } // Trim any trailing completed rowspans (and trailing null elements) while (repeatedCells.length > 0 && (!repeatedCells[repeatedCells.length-1] || repeatedCells[repeatedCells.length-1].remaining == 0)) repeatedCells.length--; } } // Construct object to hold range of adjacent sorted columns function tsx_SortedColumnRange(table, sortColumn, sortSpan) { this.id = table.id; this.from = sortColumn; this.thru = sortColumn + sortSpan - 1; this.extend = function tsx_SortedColumnRange_extend(sortColumn, sortSpan) { // Track columns sorted in sequence from right to left. Reset if jump var sortThru = sortColumn + sortSpan - 1; if (sortThru < this.from - 1 || sortThru > this.thru ) this.thru = sortThru; this.from = sortColumn; return this; } } // Get and extend range of sorted columns function tsx_GetSortedColumnRange(table, sortColumn, sortSpan) { for (var i = 0; i < tsx_SortedColumnRanges.length; i++) { if (table.id == tsx_SortedColumnRanges[i].id) { return tsx_SortedColumnRanges[i].extend(sortColumn, sortSpan); } } tsx_SortedColumnRanges.push(new tsx_SortedColumnRange(table, sortColumn, sortSpan)); return tsx_SortedColumnRanges[tsx_SortedColumnRanges.length-1]; } // Build array, indexed by column number, with a flag indicating if autorowspan is enabled function tsx_GetAutoRowSpanColumns(table, rowStart, sortColumn, sortSpan) { var autoRowSpanTable = ((" "+table.className+" ").indexOf(" autorowspan ") >= 0); var autoRowSpanColumns = new Array(); var repeatedCells = new Array(); for (var r = 0; r < rowStart; r++) { var row = table.rows[r]; var c = 0; // column number and repeatedCells index var i = 0; // cells index (may be less than column number) while (i < row.cells.length || c < repeatedCells.length) { if (c < repeatedCells.length && repeatedCells[c] && repeatedCells[c].remaining > 0) { // Repeat prior rowspanned cell repeatedCells[c].remaining--; // remaining_repeats c += repeatedCells[c].cell.colSpan; } else if (i < row.cells.length ) { // Use given cell var cell = row.cells[i]; if ( autoRowSpanTable || (" "+cell.className+" ").indexOf(" autorowspan ") >= 0 ) { for (var j = 0; j < cell.colSpan; j++) { autoRowSpanColumns[c+j] = true; } } if (cell.rowSpan > 1) { repeatedCells[c] = new tsx_RepeatedCell(cell); } c += cell.colSpan; i++; } else { // Skip undefined cell c += 1; i++; } } } return autoRowSpanColumns; } // After sorting, scan for and combine repeated cells, where allowed function tsx_combineRowspans(table, rowStart, sortColumn, sortSpan) { var SortedColumnRange = tsx_GetSortedColumnRange(table, sortColumn, sortSpan); var autoRowSpanColumns = tsx_GetAutoRowSpanColumns(table, rowStart, sortColumn, sortSpan); var priorCells = new Array(); for (var r = rowStart; r < table.rows.length; r++) { var row = table.rows[r]; if ((" "+row.className+" ").indexOf(" unsortable ") != -1 || (" "+row.className+" ").indexOf(" sortbottom ") != -1) { priorCells.length = 0; // Reset - Do skip and not span across fixed rows } else { var c = 0; // column number and priorCells index var i = 0; // cells index (may be less than column number) var merging = false; while (i < row.cells.length) { // (1) Only merge cells in adjacent sorted columns, selected right to left. // (2) Only merge if cells to left also merged, or if leftmost sorted column. // (3) Merge only if cells have same ID or class="autorowspan" is active // (4) And of course, cells must be equivalent. if (c >= SortedColumnRange.from && c <= SortedColumnRange.thru && (c == sortColumn || merging) && c < priorCells.length && priorCells[c] && ( (autoRowSpanColumns.length > c && autoRowSpanColumns[c]) || (row.cells[i].id != "" && row.cells[i].id == priorCells[c].id) ) && tsx_compareCells(row.cells[i],priorCells[c]) ) { merging = true; // Match - update rowspan in prior row's tableCell and delete current. priorCells[c].rowSpan++; for (var j = 1; j < row.cells[i].colSpan; j++) priorCells[c+j] = null; // Skipped c += row.cells[i].colSpan; row.deleteCell(i); } else { merging = false; // No match or not allowed - save, but leave unchanged. priorCells[c] = row.cells[i]; for (var j = 1; j < row.cells[i].colSpan; j++) priorCells[c+j] = null; c += row.cells[i].colSpan; i++; } } priorCells.length = c; } } } function tsx_getInnerText(row,column) { var i = 0; var c = 0; var ncells = row.cells.length; while (i < ncells && c <= column) { if (column >= c && column < c + row.cells[i].colSpan) { return getInnerText( row.cells[i] ); } c += row.cells[i].colSpan; i++; } return ""; } function tsx_resortTable(lnk, rowStart, sortColumn, sortSpan) { // Get the span containing the sort icon and determine sort direction var span = lnk.getElementsByTagName('span')[0]; var reverse = (span.getAttribute("sortdir") == 'down'); // Get the table var td = lnk.parentNode; var tr = td.parentNode; var table = tr.parentNode; while (table && !(table.tagName && table.tagName.toLowerCase() == 'table')) table = table.parentNode; if (!table) return; // Generate the number transform table if it's not done already if (tsx_number_transform_table == null) { tsx_initTransformTable(); } // Expand any rowspan'ed cells that could potentially be split by sort tsx_explodeRowspans(table,rowStart); // Sort each column in the selected range from right to left for (var i = sortSpan - 1; i >= 0 ; i--) { tsx_sortColumn(table, rowStart, sortColumn + i, reverse); } // Merge cells into rowspans, where possible tsx_combineRowspans(table, rowStart, sortColumn, sortSpan); var arrowHTML; if (reverse) { arrowHTML = '<img src="'+ tsx_image_path + tsx_image_down + '" alt="&darr;"/>'; span.setAttribute('sortdir','up'); } else { arrowHTML = '<img src="'+ tsx_image_path + tsx_image_up + '" alt="&uarr;"/>'; span.setAttribute('sortdir','down'); } // Delete any other arrows there may be showing for (var r = 0; r < rowStart; r++) { var spans = getElementsByClassName(table.rows[r], "span", "sortarrow"); for (var i = 0; i < spans.length; i++) { spans[i].innerHTML = '<img src="'+ tsx_image_path + tsx_image_none + '" alt="&#x21C5;"/>'; } } span.innerHTML = arrowHTML; if (tsx_alternate_row_colors) { tsx_alternate(table); } } function tsx_sortColumn(table, rowStart, column, reverse) { // Work out a type for the column var itm = ""; for (var i = rowStart; i < table.rows.length; i++) { if (table.rows[i].cells.length > column) { itm = tsx_getInnerText(table.rows[i],column); itm = itm.replace(/^[\s\xa0]+/, "").replace(/[\s\xa0]+$/, ""); if (itm != "") break; } } // TODO: bug 8226, localised date formats var sortfn = tsx_sort_generic; var preprocessor = tsx_toLowerCase; if (/^\d\d[\/. -][a-zA-Z]{3}[\/. -]\d\d\d\d$/.test(itm)) { preprocessor = tsx_dateToSortKey; } else if (/^\d\d[\/.-]\d\d[\/.-]\d\d\d\d$/.test(itm)) { preprocessor = tsx_dateToSortKey; } else if (/^\d\d[\/.-]\d\d[\/.-]\d\d$/.test(itm)) { preprocessor = tsx_dateToSortKey; // pound dollar euro yen currency cents } else if (/(^[\u00a3$\u20ac\u00a4\u00a5]|\u00a2$)/.test(itm)) { preprocessor = tsx_currencyToSortKey; } else if (tsx_number_regex.test(itm)) { preprocessor = tsx_parseFloat; } var newRows = new Array(); var staticRows = new Array(); for (var j = rowStart; j < table.rows.length; j++) { var row = table.rows[j]; if((" "+row.className+" ").indexOf(" unsortable ") < 0) { var keyText = tsx_getInnerText(row,column); var oldIndex = (reverse ? -j : j); var preprocessed = preprocessor( keyText ); newRows[newRows.length] = new Array(row, preprocessed, oldIndex); } else staticRows[staticRows.length] = new Array(row, false, j-rowStart); } newRows.sort(sortfn); if (reverse) newRows.reverse(); for (var i = 0; i < staticRows.length; i++) { var row = staticRows[i]; newRows.splice(row[2], 0, row); } // We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones // don't do sortbottom rows for (var i = 0; i < newRows.length; i++) { if ((" "+newRows[i][0].className+" ").indexOf(" sortbottom ") == -1) table.tBodies[0].appendChild(newRows[i][0]); } // do sortbottom rows only for (var i = 0; i < newRows.length; i++) { if ((" "+newRows[i][0].className+" ").indexOf(" sortbottom ") != -1) table.tBodies[0].appendChild(newRows[i][0]); } } function tsx_initTransformTable() { if ( typeof wgSeparatorTransformTable == "undefined" || ( wgSeparatorTransformTable[0] == '' && wgDigitTransformTable[2] == '' ) ) { digitClass = "[0-9,.]"; tsx_number_transform_table = false; } else { tsx_number_transform_table = {}; // Unpack the transform table // Separators ascii = wgSeparatorTransformTable[0].split("\t"); localised = wgSeparatorTransformTable[1].split("\t"); for ( var i = 0; i < ascii.length; i++ ) { tsx_number_transform_table[localised[i]] = ascii[i]; } // Digits ascii = wgDigitTransformTable[0].split("\t"); localised = wgDigitTransformTable[1].split("\t"); for ( var i = 0; i < ascii.length; i++ ) { tsx_number_transform_table[localised[i]] = ascii[i]; } // Construct regex for number identification digits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ',', '\\.']; maxDigitLength = 1; for ( var digit in tsx_number_transform_table ) { // Escape regex metacharacters digits.push( digit.replace( /[\\\\$\*\+\?\.\(\)\|\{\}\[\]\-]/, function( s ) { return '\\' + s; } ) ); if (digit.length > maxDigitLength) { maxDigitLength = digit.length; } } if ( maxDigitLength > 1 ) { digitClass = '[' + digits.join( '', digits ) + ']'; } else { digitClass = '(' + digits.join( '|', digits ) + ')'; } } // We allow a trailing percent sign, which we just strip. This works fine // if percents and regular numbers aren't being mixed. tsx_number_regex = new RegExp( "^(" + "[+-]?[0-9][0-9,]*(\\.[0-9,]*)?(E[+-]?[0-9][0-9,]*)?" + // Fortran-style scientific "|" + "[+-]?" + digitClass + "+%?" + // Generic localised ")$", "i" ); } function tsx_toLowerCase( s ) { return s.toLowerCase(); } function tsx_dateToSortKey(date) { // y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX if (date.length == 11) { switch (date.substr(3,3).toLowerCase()) { case "jan": var month = "01"; break; case "feb": var month = "02"; break; case "mar": var month = "03"; break; case "apr": var month = "04"; break; case "may": var month = "05"; break; case "jun": var month = "06"; break; case "jul": var month = "07"; break; case "aug": var month = "08"; break; case "sep": var month = "09"; break; case "oct": var month = "10"; break; case "nov": var month = "11"; break; case "dec": var month = "12"; break; // default: var month = "00"; } return date.substr(7,4)+month+date.substr(0,2); } else if (date.length == 10) { if (tsx_europeandate == false) { return date.substr(6,4)+date.substr(0,2)+date.substr(3,2); } else { return date.substr(6,4)+date.substr(3,2)+date.substr(0,2); } } else if (date.length == 8) { yr = date.substr(6,2); if (parseInt(yr) < 50) { yr = '20'+yr; } else { yr = '19'+yr; } if (tsx_europeandate == true) { return yr+date.substr(3,2)+date.substr(0,2); } else { return yr+date.substr(0,2)+date.substr(3,2); } } return "00000000"; } function tsx_parseFloat( s ) { if ( !s ) { return 0; } if (tsx_number_transform_table != false) { var newNum = '', c; for ( var p = 0; p < s.length; p++ ) { c = s.charAt( p ); if (c in tsx_number_transform_table) { newNum += tsx_number_transform_table[c]; } else { newNum += c; } } s = newNum; } num = parseFloat(s.replace(/,/g, "")); return (isNaN(num) ? s : num); } function tsx_currencyToSortKey( s ) { return tsx_parseFloat(s.replace(/[^0-9.,]/g,'')); } function tsx_sort_generic(a, b) { return a[1] < b[1] ? -1 : a[1] > b[1] ? 1 : a[2] - b[2]; } function tsx_alternate(table) { // Take object table and get all it's tbodies. var tableBodies = table.getElementsByTagName("tbody"); // Loop through these tbodies for (var i = 0; i < tableBodies.length; i++) { // Take the tbody, and get all it's rows var tableRows = tableBodies[i].getElementsByTagName("tr"); // Loop through these rows // Start at 1 because we want to leave the heading row untouched for (var j = 0; j < tableRows.length; j++) { // Check if j is even, and apply classes for both possible results var oldClasses = tableRows[j].className.split(" "); var newClassName = ""; for (var k = 0; k < oldClasses.length; k++) { if (oldClasses[k] != "" && oldClasses[k] != "even" && oldClasses[k] != "odd") newClassName += oldClasses[k] + " "; } tableRows[j].className = newClassName + (j % 2 == 0 ? "even" : "odd"); } } } /* * End of table sorting code */'
New page wikitext, after the edit (new_wikitext)
'/* * Draft fix for: https://bugzilla.wikimedia.org/show_bug.cgi?id=8028 * * Current status: Shelved due to limited interest. * * Enhancements: * 1. Will explode rowspans, so that rows are self contained and can be sorted * without corrupting the table structure. * 2. Will recognize colspans, so that the proper value is retrieved from each * row. Each column in a colspan range is treated as having the same value. * Colspans are preserved during sorting; they are not split. * 3. After sorting, some cell ranges may be recombined under certain restrictive * conditions. The class="autorowspan" option can be applied to column * headers or the entire table to enable more aggressive rowspan combines, such * as combining cells in the currently sorted column that were not originally * combined. Current merge rules: * a. Only merge cells in adjacent sorted columns, selected right to left. * b. Only merge if cells to left also merged, or if leftmost sorted column. * c. Only merge if cells have same ID or if class="autorowspan" is active. * d. And of course, cells must be equivalent (content and attributes). * e. Do not merge header, footer (sortbottom) or fixed (unsortable) rows. * 4. Supports multi-row headers with a mix of rowspans and colspans. Clicking on * the sort icon in a colspan'd header will perform a multi-column sort. The * "unsortable" class name can be used in the header to limit sort icon creation. * * Bugs/Limitations: * 1. Conflicting (partially overlapping) rowspans/colspans are not supported. (This * is invalid in HTML, so is not a worry.) * 2. Rowspans that add extra table rows are not supported. * 3. Table row attributes are not compared when combining cells. * 4. Some intermittent problems observed very early in development when using table * sorting + Twinkle + IE + with complex pages having large amounts of table data. * (This problem has not been duplicated.) * * Todo: * 1. Restore thead/tbody/tfoot support (see bugzilla bug id 4740) * 2. Merge with any recent released source changes. * 3. Test on other browser configurations. * 4. Solicit feature discussion and code review. * 5. Prepare formal test cases and submit to bugzilla. * * Related: * 1. [[Help:Sorting]] - Document new capabilities with examples. * 2. [[Wikipedia:Catalogue of CSS classes]] - Add new "autorowspan" class and * update "unsortable" to document new use. * * Other possible enhancements (extra complexity may not be justified): * 1. Consider if it be useful to apply autorowspan to the original table before * its initial display? (Might same some tedious table formatting effort.) * 2. Option to automatically apply initial sort. * 3. Implement mixed mode sorting option (numbers, dates, and text) in a manner * similar to Excel, and possibly compound sorting of mixed data (9Z < 10A). * 4. Support fixed columns whose cells do not move with the sort (a lot of work). * */ /* The following is based on code extracted from wikibits * (/trunk/phase3/skins/common/wikibits.js) revision 45304, Fri Jan 2, 2009. * (http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/skins/common/wikibits.js?view=log) * All global variables and functions were renamed from a "ts_" prefix to * "tsx_" (Table Sort eXperimental) prefix. The table class affected was * changed from "sortable" to "tsx_sortable". */ /* * Table sorting script based on one (c) 1997-2006 Stuart Langridge and Joost * de Valk: * http://www.joostdevalk.nl/code/sortable-table/ * http://www.kryogenix.org/code/browser/sorttable/ * * @todo don't break on colspans/rowspans (bug 8028) * @todo language-specific digit grouping/decimals (bug 8063) * @todo support all accepted date formats (bug 8226) */ var tsx_image_path = stylepath+"/common/images/"; var tsx_image_up = "sort_up.gif"; var tsx_image_down = "sort_down.gif"; var tsx_image_none = "sort_none.gif"; var tsx_europeandate = wgContentLanguage != "en"; // The non-American-inclined can change to "true" var tsx_alternate_row_colors = false; var tsx_number_transform_table = null; var tsx_number_regex = null; var tsx_SortedColumnRanges = new Array; function tsx_sortables_init() { var idnum = 0; // Find all tables with class sortable and make them sortable var tables = document.querySelectorAll("table.tsx_sortable"); for (var ti = 0; ti < tables.length ; ti++) { if (!tables[ti].id) { tables[ti].setAttribute('id','sortable_table_id_tsx_'+idnum); ++idnum; } tsx_makeSortable(tables[ti]); } } addOnloadHook(tsx_sortables_init); function tsx_makeSortable(table) { if (!table.rows || table.rows.length == 0) return; // Count header rows. First row is always considered part of the header. // Also include rows having class=sortheader" or containing only TH cells. var numHeaders = 1; // Also equals rowStart var isHeader = true; for (var r = 1; r < table.rows.length && isHeader; r++) { if ((" "+table.rows[r].className+" ").indexOf(" sortheader ") == -1) { for (var i = 0; i < table.rows[r].cells.length && isHeader; i++) { if (table.rows[r].cells[i].nodeName.toUpperCase() != "TH") { isHeader = false; } } } if (isHeader) numHeaders = r + 1; } if (table.rows.length - numHeaders < 2) return; var repeatedCells = new Array(); for (var r = 0; r < numHeaders; r++) { var row = table.rows[r]; var c = 0; // column number and repeatedCells index var i = 0; // cells index (may be less than column number) while (i < row.cells.length || c < repeatedCells.length) { if (c < repeatedCells.length && repeatedCells[c] && repeatedCells[c].remaining > 0) { // Use repeated cell repeatedCells[c].remaining--; // remaining_repeats c += repeatedCells[c].cell.colSpan; } else if (i < row.cells.length ) { // Use existing defined cell. If rowspan, save for later duplication. var cell = row.cells[i]; if ((" "+cell.className+" ").indexOf(" unsortable ") == -1) { cell.innerHTML += '&nbsp;&nbsp;' + '<a href="#" class="sortheader" ' + 'onclick="tsx_resortTable(this,' + numHeaders.toString() + ',' + c.toString() + ',' + cell.colSpan.toString() + ');return false;">' + '<span class="sortarrow">' + '<img src="' + tsx_image_path + tsx_image_none + '" alt="&#x21C5;"/></span></a>'; } if (cell.rowSpan > 1) { repeatedCells[c] = new tsx_RepeatedCell(cell); } c += cell.colSpan; i++; } else { c += 1; //undefined cell i++; } } } if (tsx_alternate_row_colors) { tsx_alternate(table); } } function tsx_copyCell(to_cell, from_cell) { to_cell.innerHTML = from_cell.innerHTML; from_cell.innerHTML = from_cell.innerHTML; // Copy to self - IE morphs some values for (var i = 0; i < from_cell.attributes.length; i++) { var nodeName = from_cell.attributes[i].nodeName; var nodeValue = from_cell.getAttribute(nodeName); var nodeValueType = typeof nodeValue; if (nodeValue!=null && (nodeValueType == "string" || nodeValueType == "number" || nodeValueType == "boolean")) { to_cell.setAttribute(nodeName, nodeValue); } } to_cell.innerHTML = from_cell.innerHTML; // Overkill from_cell.innerHTML = from_cell.innerHTML; // Overkill } function tsx_compareCells(lhs, rhs) { if (lhs.innerHTML != rhs.innerHTML) return false; for (var i = 0; i < lhs.attributes.length; i++) { var nodeName = lhs.attributes[i].nodeName; var nodeNameLower = nodeName.toLowerCase(); /* IE uses mixed case */ var nodeValue = lhs.attributes[i].nodeValue; var nodeValueType = typeof nodeValue; if (nodeNameLower != "id" && nodeNameLower != "rowspan" && nodeValue!=null && (nodeValueType == "string" || nodeValueType == "number" || nodeValueType == "boolean")) { if (rhs.getAttribute(nodeName) != lhs.getAttribute(nodeName)) { return false; } } } for (var i = 0; i < rhs.attributes.length; i++) { var nodeName = rhs.attributes[i].nodeName; var nodeNameLower = nodeName.toLowerCase(); /* IE uses mixed case */ var nodeValue = rhs.attributes[i].nodeValue; var nodeValueType = typeof nodeValue; if (nodeNameLower != "id" && nodeNameLower != "rowspan" && nodeValue!=null && (nodeValueType == "string" || nodeValueType == "number" || nodeValueType == "boolean")) { if (rhs.getAttribute(nodeName) != lhs.getAttribute(nodeName)) { return false; } } } return true; } // Construct object to track remaining occurrences or rowspanned cell function tsx_RepeatedCell(cell) { this.cell = cell; this.remaining = cell.rowSpan - 1; } // Identify and duplicate rowspanned cells so that each row has its own copy function tsx_explodeRowspans(table, rowStart) { var rowspangroup_seq = 0; // Used to generate ids for rowspan cell groups var repeatedCells = new Array(); for (var r = rowStart; r < table.rows.length; r++) { var row = table.rows[r]; var c = 0; // column number and repeatedCells index var i = 0; // cells index (may be less than column number) while (i < row.cells.length || c < repeatedCells.length) { if (c < repeatedCells.length && repeatedCells[c] && repeatedCells[c].remaining > 0) { // Use repeated cell row.insertCell(i); tsx_copyCell(row.cells[i], repeatedCells[c].cell); row.cells[i].rowSpan = 1; repeatedCells[c].remaining--; // remaining_repeats } else if (i < row.cells.length ) { // Use existing defined cell. If rowspan, save for later duplication. if (row.cells[i].rowSpan > 1) { if (row.cells[i].id == "" ) { row.cells[i].id = table.id + ".rowspangroup." + (++rowspangroup_seq); } repeatedCells[c] = new tsx_RepeatedCell(row.cells[i]); row.cells[i].rowSpan = 1; } } else { // Insert filler cell row.insertCell(i); } c += row.cells[i].colSpan; // Note: Conflicting rowspan/colspan are not supported i++; } // Trim any trailing completed rowspans (and trailing null elements) while (repeatedCells.length > 0 && (!repeatedCells[repeatedCells.length-1] || repeatedCells[repeatedCells.length-1].remaining == 0)) repeatedCells.length--; } } // Construct object to hold range of adjacent sorted columns function tsx_SortedColumnRange(table, sortColumn, sortSpan) { this.id = table.id; this.from = sortColumn; this.thru = sortColumn + sortSpan - 1; this.extend = function tsx_SortedColumnRange_extend(sortColumn, sortSpan) { // Track columns sorted in sequence from right to left. Reset if jump var sortThru = sortColumn + sortSpan - 1; if (sortThru < this.from - 1 || sortThru > this.thru ) this.thru = sortThru; this.from = sortColumn; return this; } } // Get and extend range of sorted columns function tsx_GetSortedColumnRange(table, sortColumn, sortSpan) { for (var i = 0; i < tsx_SortedColumnRanges.length; i++) { if (table.id == tsx_SortedColumnRanges[i].id) { return tsx_SortedColumnRanges[i].extend(sortColumn, sortSpan); } } tsx_SortedColumnRanges.push(new tsx_SortedColumnRange(table, sortColumn, sortSpan)); return tsx_SortedColumnRanges[tsx_SortedColumnRanges.length-1]; } // Build array, indexed by column number, with a flag indicating if autorowspan is enabled function tsx_GetAutoRowSpanColumns(table, rowStart, sortColumn, sortSpan) { var autoRowSpanTable = ((" "+table.className+" ").indexOf(" autorowspan ") >= 0); var autoRowSpanColumns = new Array(); var repeatedCells = new Array(); for (var r = 0; r < rowStart; r++) { var row = table.rows[r]; var c = 0; // column number and repeatedCells index var i = 0; // cells index (may be less than column number) while (i < row.cells.length || c < repeatedCells.length) { if (c < repeatedCells.length && repeatedCells[c] && repeatedCells[c].remaining > 0) { // Repeat prior rowspanned cell repeatedCells[c].remaining--; // remaining_repeats c += repeatedCells[c].cell.colSpan; } else if (i < row.cells.length ) { // Use given cell var cell = row.cells[i]; if ( autoRowSpanTable || (" "+cell.className+" ").indexOf(" autorowspan ") >= 0 ) { for (var j = 0; j < cell.colSpan; j++) { autoRowSpanColumns[c+j] = true; } } if (cell.rowSpan > 1) { repeatedCells[c] = new tsx_RepeatedCell(cell); } c += cell.colSpan; i++; } else { // Skip undefined cell c += 1; i++; } } } return autoRowSpanColumns; } // After sorting, scan for and combine repeated cells, where allowed function tsx_combineRowspans(table, rowStart, sortColumn, sortSpan) { var SortedColumnRange = tsx_GetSortedColumnRange(table, sortColumn, sortSpan); var autoRowSpanColumns = tsx_GetAutoRowSpanColumns(table, rowStart, sortColumn, sortSpan); var priorCells = new Array(); for (var r = rowStart; r < table.rows.length; r++) { var row = table.rows[r]; if ((" "+row.className+" ").indexOf(" unsortable ") != -1 || (" "+row.className+" ").indexOf(" sortbottom ") != -1) { priorCells.length = 0; // Reset - Do skip and not span across fixed rows } else { var c = 0; // column number and priorCells index var i = 0; // cells index (may be less than column number) var merging = false; while (i < row.cells.length) { // (1) Only merge cells in adjacent sorted columns, selected right to left. // (2) Only merge if cells to left also merged, or if leftmost sorted column. // (3) Merge only if cells have same ID or class="autorowspan" is active // (4) And of course, cells must be equivalent. if (c >= SortedColumnRange.from && c <= SortedColumnRange.thru && (c == sortColumn || merging) && c < priorCells.length && priorCells[c] && ( (autoRowSpanColumns.length > c && autoRowSpanColumns[c]) || (row.cells[i].id != "" && row.cells[i].id == priorCells[c].id) ) && tsx_compareCells(row.cells[i],priorCells[c]) ) { merging = true; // Match - update rowspan in prior row's tableCell and delete current. priorCells[c].rowSpan++; for (var j = 1; j < row.cells[i].colSpan; j++) priorCells[c+j] = null; // Skipped c += row.cells[i].colSpan; row.deleteCell(i); } else { merging = false; // No match or not allowed - save, but leave unchanged. priorCells[c] = row.cells[i]; for (var j = 1; j < row.cells[i].colSpan; j++) priorCells[c+j] = null; c += row.cells[i].colSpan; i++; } } priorCells.length = c; } } } function tsx_getInnerText(row,column) { var i = 0; var c = 0; var ncells = row.cells.length; while (i < ncells && c <= column) { if (column >= c && column < c + row.cells[i].colSpan) { return getInnerText( row.cells[i] ); } c += row.cells[i].colSpan; i++; } return ""; } function tsx_resortTable(lnk, rowStart, sortColumn, sortSpan) { // Get the span containing the sort icon and determine sort direction var span = lnk.getElementsByTagName('span')[0]; var reverse = (span.getAttribute("sortdir") == 'down'); // Get the table var td = lnk.parentNode; var tr = td.parentNode; var table = tr.parentNode; while (table && !(table.tagName && table.tagName.toLowerCase() == 'table')) table = table.parentNode; if (!table) return; // Generate the number transform table if it's not done already if (tsx_number_transform_table == null) { tsx_initTransformTable(); } // Expand any rowspan'ed cells that could potentially be split by sort tsx_explodeRowspans(table,rowStart); // Sort each column in the selected range from right to left for (var i = sortSpan - 1; i >= 0 ; i--) { tsx_sortColumn(table, rowStart, sortColumn + i, reverse); } // Merge cells into rowspans, where possible tsx_combineRowspans(table, rowStart, sortColumn, sortSpan); var arrowHTML; if (reverse) { arrowHTML = '<img src="'+ tsx_image_path + tsx_image_down + '" alt="&darr;"/>'; span.setAttribute('sortdir','up'); } else { arrowHTML = '<img src="'+ tsx_image_path + tsx_image_up + '" alt="&uarr;"/>'; span.setAttribute('sortdir','down'); } // Delete any other arrows there may be showing for (var r = 0; r < rowStart; r++) { var spans = table.rows[r].querySelectorAll("span.sortarrow"); for (var i = 0; i < spans.length; i++) { spans[i].innerHTML = '<img src="'+ tsx_image_path + tsx_image_none + '" alt="&#x21C5;"/>'; } } span.innerHTML = arrowHTML; if (tsx_alternate_row_colors) { tsx_alternate(table); } } function tsx_sortColumn(table, rowStart, column, reverse) { // Work out a type for the column var itm = ""; for (var i = rowStart; i < table.rows.length; i++) { if (table.rows[i].cells.length > column) { itm = tsx_getInnerText(table.rows[i],column); itm = itm.replace(/^[\s\xa0]+/, "").replace(/[\s\xa0]+$/, ""); if (itm != "") break; } } // TODO: bug 8226, localised date formats var sortfn = tsx_sort_generic; var preprocessor = tsx_toLowerCase; if (/^\d\d[\/. -][a-zA-Z]{3}[\/. -]\d\d\d\d$/.test(itm)) { preprocessor = tsx_dateToSortKey; } else if (/^\d\d[\/.-]\d\d[\/.-]\d\d\d\d$/.test(itm)) { preprocessor = tsx_dateToSortKey; } else if (/^\d\d[\/.-]\d\d[\/.-]\d\d$/.test(itm)) { preprocessor = tsx_dateToSortKey; // pound dollar euro yen currency cents } else if (/(^[\u00a3$\u20ac\u00a4\u00a5]|\u00a2$)/.test(itm)) { preprocessor = tsx_currencyToSortKey; } else if (tsx_number_regex.test(itm)) { preprocessor = tsx_parseFloat; } var newRows = new Array(); var staticRows = new Array(); for (var j = rowStart; j < table.rows.length; j++) { var row = table.rows[j]; if((" "+row.className+" ").indexOf(" unsortable ") < 0) { var keyText = tsx_getInnerText(row,column); var oldIndex = (reverse ? -j : j); var preprocessed = preprocessor( keyText ); newRows[newRows.length] = new Array(row, preprocessed, oldIndex); } else staticRows[staticRows.length] = new Array(row, false, j-rowStart); } newRows.sort(sortfn); if (reverse) newRows.reverse(); for (var i = 0; i < staticRows.length; i++) { var row = staticRows[i]; newRows.splice(row[2], 0, row); } // We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones // don't do sortbottom rows for (var i = 0; i < newRows.length; i++) { if ((" "+newRows[i][0].className+" ").indexOf(" sortbottom ") == -1) table.tBodies[0].appendChild(newRows[i][0]); } // do sortbottom rows only for (var i = 0; i < newRows.length; i++) { if ((" "+newRows[i][0].className+" ").indexOf(" sortbottom ") != -1) table.tBodies[0].appendChild(newRows[i][0]); } } function tsx_initTransformTable() { if ( typeof wgSeparatorTransformTable == "undefined" || ( wgSeparatorTransformTable[0] == '' && wgDigitTransformTable[2] == '' ) ) { digitClass = "[0-9,.]"; tsx_number_transform_table = false; } else { tsx_number_transform_table = {}; // Unpack the transform table // Separators ascii = wgSeparatorTransformTable[0].split("\t"); localised = wgSeparatorTransformTable[1].split("\t"); for ( var i = 0; i < ascii.length; i++ ) { tsx_number_transform_table[localised[i]] = ascii[i]; } // Digits ascii = wgDigitTransformTable[0].split("\t"); localised = wgDigitTransformTable[1].split("\t"); for ( var i = 0; i < ascii.length; i++ ) { tsx_number_transform_table[localised[i]] = ascii[i]; } // Construct regex for number identification digits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ',', '\\.']; maxDigitLength = 1; for ( var digit in tsx_number_transform_table ) { // Escape regex metacharacters digits.push( digit.replace( /[\\\\$\*\+\?\.\(\)\|\{\}\[\]\-]/, function( s ) { return '\\' + s; } ) ); if (digit.length > maxDigitLength) { maxDigitLength = digit.length; } } if ( maxDigitLength > 1 ) { digitClass = '[' + digits.join( '', digits ) + ']'; } else { digitClass = '(' + digits.join( '|', digits ) + ')'; } } // We allow a trailing percent sign, which we just strip. This works fine // if percents and regular numbers aren't being mixed. tsx_number_regex = new RegExp( "^(" + "[+-]?[0-9][0-9,]*(\\.[0-9,]*)?(E[+-]?[0-9][0-9,]*)?" + // Fortran-style scientific "|" + "[+-]?" + digitClass + "+%?" + // Generic localised ")$", "i" ); } function tsx_toLowerCase( s ) { return s.toLowerCase(); } function tsx_dateToSortKey(date) { // y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX if (date.length == 11) { switch (date.substr(3,3).toLowerCase()) { case "jan": var month = "01"; break; case "feb": var month = "02"; break; case "mar": var month = "03"; break; case "apr": var month = "04"; break; case "may": var month = "05"; break; case "jun": var month = "06"; break; case "jul": var month = "07"; break; case "aug": var month = "08"; break; case "sep": var month = "09"; break; case "oct": var month = "10"; break; case "nov": var month = "11"; break; case "dec": var month = "12"; break; // default: var month = "00"; } return date.substr(7,4)+month+date.substr(0,2); } else if (date.length == 10) { if (tsx_europeandate == false) { return date.substr(6,4)+date.substr(0,2)+date.substr(3,2); } else { return date.substr(6,4)+date.substr(3,2)+date.substr(0,2); } } else if (date.length == 8) { yr = date.substr(6,2); if (parseInt(yr) < 50) { yr = '20'+yr; } else { yr = '19'+yr; } if (tsx_europeandate == true) { return yr+date.substr(3,2)+date.substr(0,2); } else { return yr+date.substr(0,2)+date.substr(3,2); } } return "00000000"; } function tsx_parseFloat( s ) { if ( !s ) { return 0; } if (tsx_number_transform_table != false) { var newNum = '', c; for ( var p = 0; p < s.length; p++ ) { c = s.charAt( p ); if (c in tsx_number_transform_table) { newNum += tsx_number_transform_table[c]; } else { newNum += c; } } s = newNum; } num = parseFloat(s.replace(/,/g, "")); return (isNaN(num) ? s : num); } function tsx_currencyToSortKey( s ) { return tsx_parseFloat(s.replace(/[^0-9.,]/g,'')); } function tsx_sort_generic(a, b) { return a[1] < b[1] ? -1 : a[1] > b[1] ? 1 : a[2] - b[2]; } function tsx_alternate(table) { // Take object table and get all it's tbodies. var tableBodies = table.getElementsByTagName("tbody"); // Loop through these tbodies for (var i = 0; i < tableBodies.length; i++) { // Take the tbody, and get all it's rows var tableRows = tableBodies[i].getElementsByTagName("tr"); // Loop through these rows // Start at 1 because we want to leave the heading row untouched for (var j = 0; j < tableRows.length; j++) { // Check if j is even, and apply classes for both possible results var oldClasses = tableRows[j].className.split(" "); var newClassName = ""; for (var k = 0; k < oldClasses.length; k++) { if (oldClasses[k] != "" && oldClasses[k] != "even" && oldClasses[k] != "odd") newClassName += oldClasses[k] + " "; } tableRows[j].className = newClassName + (j % 2 == 0 ? "even" : "odd"); } } } /* * End of table sorting code */'
Unified diff of changes made by edit (edit_diff)
'@@ -89,5 +89,5 @@ var idnum = 0; // Find all tables with class sortable and make them sortable - var tables = getElementsByClassName(document, "table", "tsx_sortable"); + var tables = document.querySelectorAll("table.tsx_sortable"); for (var ti = 0; ti < tables.length ; ti++) { if (!tables[ti].id) { @@ -433,5 +433,5 @@ // Delete any other arrows there may be showing for (var r = 0; r < rowStart; r++) { - var spans = getElementsByClassName(table.rows[r], "span", "sortarrow"); + var spans = table.rows[r].querySelectorAll("span.sortarrow"); for (var i = 0; i < spans.length; i++) { spans[i].innerHTML = '<img src="'+ tsx_image_path + tsx_image_none + '" alt="&#x21C5;"/>'; '
New page size (new_size)
23295
Old page size (old_size)
23315
Size change in edit (edit_delta)
-20
Lines added in edit (added_lines)
[ 0 => ' var tables = document.querySelectorAll("table.tsx_sortable");', 1 => ' var spans = table.rows[r].querySelectorAll("span.sortarrow");' ]
Lines removed in edit (removed_lines)
[ 0 => ' var tables = getElementsByClassName(document, "table", "tsx_sortable");', 1 => ' var spans = getElementsByClassName(table.rows[r], "span", "sortarrow");' ]
Whether or not the change was made through a Tor exit node (tor_exit_node)
false
Unix timestamp of change (timestamp)
1611627015