- Welcome to the Kancolle Wiki!
- If you have any questions regarding site content, account registration, etc., please visit the KanColle Wiki Discord
Difference between revisions of "User:Lrb/common.js"
< User:Lrb
Jump to navigation
Jump to search
Line 1: | Line 1: | ||
− | // < | + | /** <pre> |
− | if ($( | + | * highlightTable.js |
− | + | * | |
− | } | + | * Description: |
− | // </ | + | * Adds row highlighting to tables |
+ | * | ||
+ | * Version 1.0: Row highlighting - Quarenon | ||
+ | * Version 1.1: Update from pengLocations.js v1.0 - Quarenon | ||
+ | * Version 2.0: pengLocations v2.1, Granular cookie - Saftzie | ||
+ | * Version 2.1: Made compatible with jquery.tablesorter - Cqm | ||
+ | */ | ||
+ | |||
+ | ;(function ($, mw) { | ||
+ | |||
+ | 'use strict'; | ||
+ | |||
+ | function highlightTable() { | ||
+ | |||
+ | // requires CSS classes named in lightOnClass and mouseOverClass | ||
+ | var wgPageName = mw.config.get('wgPageName'), | ||
+ | cookiePrefix = 'lightTable', | ||
+ | tableClass = 'lighttable', | ||
+ | lightOnClass = 'highlight-on', | ||
+ | mouseOverClass = 'highlight-over', | ||
+ | base64url = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_', | ||
+ | pageSeparator = '!', | ||
+ | tableSeparator = '.', | ||
+ | hashPageName, | ||
+ | rows = [], | ||
+ | columns, | ||
+ | tables, | ||
+ | cookie; | ||
+ | |||
+ | // hash a string into a 32-bit hex string, msb first | ||
+ | function crc32c(s) { | ||
+ | var polynomial = 0x04C11DB7, // Castagnoli polynomial | ||
+ | retVal, | ||
+ | table = [], | ||
+ | i, | ||
+ | j, | ||
+ | k; | ||
+ | |||
+ | // guarantee 8-bit chars | ||
+ | s = window.unescape(window.encodeURI(s)); | ||
+ | |||
+ | // calculate the crc for all 8-bit data | ||
+ | // bit-wise operations discard anything left of bit 31 | ||
+ | for (i = 0; i < 256; i += 1) { | ||
+ | k = (i << 24); | ||
+ | for (j = 0; j < 8; j += 1) { | ||
+ | k = (k << 1) ^ ((k >>> 31) * polynomial); | ||
+ | } | ||
+ | table[i] = k; | ||
+ | } | ||
+ | |||
+ | // the actual calculation | ||
+ | retVal = 0; | ||
+ | for (i = 0; i < s.length; i += 1) { | ||
+ | retVal = (retVal << 8) ^ table[(retVal >>> 24) ^ s.charCodeAt(i)]; | ||
+ | } | ||
+ | |||
+ | // make negative numbers unsigned | ||
+ | if (retVal < 0) { | ||
+ | retVal += 4294967296; | ||
+ | } | ||
+ | // 32-bit hex string, padded on the left | ||
+ | retVal = '0000000' + retVal.toString(16).toUpperCase(); | ||
+ | retVal = retVal.substr(retVal.length - 8); | ||
+ | |||
+ | return retVal; | ||
+ | } | ||
+ | |||
+ | // change the row bg color based on mouse events | ||
+ | function setHighlight(el, val) { | ||
+ | $(el).removeClass(mouseOverClass).removeClass(lightOnClass); | ||
+ | switch (val) { | ||
+ | case 1: // light on | ||
+ | $(el).addClass(lightOnClass); | ||
+ | break; | ||
+ | case 2: // mouse-over | ||
+ | $(el).addClass(mouseOverClass); | ||
+ | break; | ||
+ | default: // same as case 0, light off | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // load the cookie and parse it for the page | ||
+ | // cookie info is saved in 1 of 16 browser cookies, based on page name hash | ||
+ | // global cookie[][] supports multiple tables and multiple pages | ||
+ | // uses global hashPageName | ||
+ | function loadCookie(numTables) { | ||
+ | var cookieName = cookiePrefix + '-' + hashPageName.charAt(0), | ||
+ | pageCookies, | ||
+ | tableCookies, | ||
+ | iPage, | ||
+ | iTable, | ||
+ | i, | ||
+ | j, | ||
+ | k; | ||
+ | |||
+ | cookie = []; | ||
+ | if ($.cookie(cookieName) !== null) { | ||
+ | pageCookies = $.cookie(cookieName).split(pageSeparator); | ||
+ | for (iPage = 0; iPage < pageCookies.length; iPage += 1) { | ||
+ | if (hashPageName === pageCookies[iPage].substr(0, 8)) { | ||
+ | tableCookies = pageCookies[iPage].substr(8).split(tableSeparator); | ||
+ | // trim the cookie array of arrays, if needed | ||
+ | while (tableCookies.length > numTables) { | ||
+ | tableCookies.pop(); | ||
+ | } | ||
+ | // extract the row info per table | ||
+ | // use Base64url to compress 6 rows to 1 character | ||
+ | for (iTable = 0; iTable < tableCookies.length; iTable += 1) { | ||
+ | cookie[iTable] = []; | ||
+ | for (i = 0; i < tableCookies[iTable].length; i += 1) { | ||
+ | k = base64url.indexOf(tableCookies[iTable].charAt(i)); | ||
+ | if (k < 0) { // input validation | ||
+ | k = 0; | ||
+ | } | ||
+ | for (j = 5; j >= 0; j -= 1) { | ||
+ | cookie[iTable][6 * i + j] = (k & 0x1); | ||
+ | k >>= 1; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // initialize the cookie array of arrays, if needed | ||
+ | while (cookie.length < numTables) { | ||
+ | cookie.push([]); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // save/update the cookie for page reloads | ||
+ | // cookie info is saved in 1 of 16 browser cookies, based on page name hash | ||
+ | // global cookie[][] supports multiple tables and multiple pages | ||
+ | // uses global hashPageName | ||
+ | function saveCookie() { | ||
+ | var cookieName = cookiePrefix + '-' + hashPageName.charAt(0), | ||
+ | pageCookies, | ||
+ | tableCookies, | ||
+ | iPage, | ||
+ | iTable, | ||
+ | i, | ||
+ | j, | ||
+ | k, | ||
+ | updated; | ||
+ | |||
+ | // create the cookie for the tables on the current page | ||
+ | // use Base64url to compress 6 rows to 1 character | ||
+ | tableCookies = hashPageName; | ||
+ | for (iTable = 0; iTable < cookie.length; iTable += 1) { | ||
+ | if (iTable > 0) { | ||
+ | tableCookies += tableSeparator; | ||
+ | } | ||
+ | for (i = 0; i < Math.ceil(cookie[iTable].length / 6); i += 1) { | ||
+ | k = cookie[iTable][6 * i]; | ||
+ | for (j = 1; j < 6; j += 1) { | ||
+ | k = 2 * k + ((6 * i + j < cookie[iTable].length) ? cookie[iTable][6 * i + j] : 0); | ||
+ | } | ||
+ | tableCookies += base64url.charAt(k); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | updated = 0; | ||
+ | pageCookies = []; | ||
+ | if ($.cookie(cookieName) !== null) { | ||
+ | // get all the page cookies | ||
+ | // another page might have updated them since this page | ||
+ | pageCookies = $.cookie(cookieName).split(pageSeparator); | ||
+ | // update the page cookie if it already exists | ||
+ | for (iPage = 0; iPage < pageCookies.length; iPage += 1) { | ||
+ | if (hashPageName === pageCookies[iPage].substr(0, 8)) { | ||
+ | updated = 1; | ||
+ | pageCookies[iPage] = tableCookies; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | // add the page cookie if it doesn't exist yet | ||
+ | if (updated === 0) { | ||
+ | pageCookies.push(tableCookies); | ||
+ | } | ||
+ | |||
+ | // set path to / so it works for /wiki/, /index.php, etc | ||
+ | $.cookie(cookieName, pageCookies.join(pageSeparator), { | ||
+ | expires: 7, | ||
+ | path: '/' | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | tables = $('table.' + tableClass); | ||
+ | // don't bother doing anything unless there's really something to do | ||
+ | if (tables.length > 0) { | ||
+ | // hash the page name to an 8-char hex string | ||
+ | hashPageName = crc32c(wgPageName); | ||
+ | loadCookie(tables.length); | ||
+ | |||
+ | tables.each(function (iTable) { | ||
+ | rows[iTable] = $(this).find('tr:has(td)'); // data rows | ||
+ | |||
+ | // init or trim the cookie array of rows, if needed | ||
+ | while (cookie[iTable].length < rows[iTable].length) { | ||
+ | cookie[iTable].push(0); | ||
+ | } | ||
+ | while (cookie[iTable].length > rows[iTable].length) { | ||
+ | cookie[iTable].pop(); | ||
+ | } | ||
+ | |||
+ | // don't rely on headers to find # of columns | ||
+ | // count them dynamically | ||
+ | columns = 1; | ||
+ | |||
+ | rows[iTable].each(function (iRow) { | ||
+ | // update column count as we go | ||
+ | // a smarter approach would count colspans, but this is good for now | ||
+ | columns = Math.max(columns, $(this).children('th,td').length); | ||
+ | |||
+ | // initialize highlighting based on the cookie | ||
+ | setHighlight(this, cookie[iTable][iRow]); | ||
+ | |||
+ | // set mouse events | ||
+ | $(this).mouseover(function () { | ||
+ | setHighlight(this, 2); | ||
+ | }).mouseout(function () { | ||
+ | setHighlight(this, cookie[iTable][iRow]); | ||
+ | }).click(function (e) { | ||
+ | // don't toggle highlight when clicking links | ||
+ | if ((e.target.tagName !== 'A') && (e.target.tagName !== 'IMG')) { | ||
+ | cookie[iTable][iRow] = 1 - cookie[iTable][iRow]; | ||
+ | setHighlight(this, cookie[iTable][iRow]); | ||
+ | saveCookie(); | ||
+ | } | ||
+ | }); | ||
+ | }); | ||
+ | |||
+ | // add a button for reset | ||
+ | $(this).append( | ||
+ | $('<tfoot/>') | ||
+ | .append( | ||
+ | $('<tr/>') | ||
+ | .append( | ||
+ | $('<th/>') | ||
+ | .attr('colspan', columns) | ||
+ | .append( | ||
+ | $('<input>') | ||
+ | .attr({ | ||
+ | 'type': 'button', | ||
+ | 'value': 'Reset' | ||
+ | }) | ||
+ | .click(function () { | ||
+ | rows[iTable].each(function (iRow) { | ||
+ | cookie[iTable][iRow] = 0; | ||
+ | setHighlight(this, 0); | ||
+ | }); | ||
+ | saveCookie(); | ||
+ | }) | ||
+ | ) | ||
+ | ) | ||
+ | ) | ||
+ | ); | ||
+ | }); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | $(highlightTable); | ||
+ | |||
+ | }(this.jQuery, this.mediaWiki)); | ||
+ | |||
+ | /* </pre> */ |
Revision as of 00:01, 8 January 2021
/** <pre>
* highlightTable.js
*
* Description:
* Adds row highlighting to tables
*
* Version 1.0: Row highlighting - Quarenon
* Version 1.1: Update from pengLocations.js v1.0 - Quarenon
* Version 2.0: pengLocations v2.1, Granular cookie - Saftzie
* Version 2.1: Made compatible with jquery.tablesorter - Cqm
*/
;(function ($, mw) {
'use strict';
function highlightTable() {
// requires CSS classes named in lightOnClass and mouseOverClass
var wgPageName = mw.config.get('wgPageName'),
cookiePrefix = 'lightTable',
tableClass = 'lighttable',
lightOnClass = 'highlight-on',
mouseOverClass = 'highlight-over',
base64url = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',
pageSeparator = '!',
tableSeparator = '.',
hashPageName,
rows = [],
columns,
tables,
cookie;
// hash a string into a 32-bit hex string, msb first
function crc32c(s) {
var polynomial = 0x04C11DB7, // Castagnoli polynomial
retVal,
table = [],
i,
j,
k;
// guarantee 8-bit chars
s = window.unescape(window.encodeURI(s));
// calculate the crc for all 8-bit data
// bit-wise operations discard anything left of bit 31
for (i = 0; i < 256; i += 1) {
k = (i << 24);
for (j = 0; j < 8; j += 1) {
k = (k << 1) ^ ((k >>> 31) * polynomial);
}
table[i] = k;
}
// the actual calculation
retVal = 0;
for (i = 0; i < s.length; i += 1) {
retVal = (retVal << 8) ^ table[(retVal >>> 24) ^ s.charCodeAt(i)];
}
// make negative numbers unsigned
if (retVal < 0) {
retVal += 4294967296;
}
// 32-bit hex string, padded on the left
retVal = '0000000' + retVal.toString(16).toUpperCase();
retVal = retVal.substr(retVal.length - 8);
return retVal;
}
// change the row bg color based on mouse events
function setHighlight(el, val) {
$(el).removeClass(mouseOverClass).removeClass(lightOnClass);
switch (val) {
case 1: // light on
$(el).addClass(lightOnClass);
break;
case 2: // mouse-over
$(el).addClass(mouseOverClass);
break;
default: // same as case 0, light off
}
}
// load the cookie and parse it for the page
// cookie info is saved in 1 of 16 browser cookies, based on page name hash
// global cookie[][] supports multiple tables and multiple pages
// uses global hashPageName
function loadCookie(numTables) {
var cookieName = cookiePrefix + '-' + hashPageName.charAt(0),
pageCookies,
tableCookies,
iPage,
iTable,
i,
j,
k;
cookie = [];
if ($.cookie(cookieName) !== null) {
pageCookies = $.cookie(cookieName).split(pageSeparator);
for (iPage = 0; iPage < pageCookies.length; iPage += 1) {
if (hashPageName === pageCookies[iPage].substr(0, 8)) {
tableCookies = pageCookies[iPage].substr(8).split(tableSeparator);
// trim the cookie array of arrays, if needed
while (tableCookies.length > numTables) {
tableCookies.pop();
}
// extract the row info per table
// use Base64url to compress 6 rows to 1 character
for (iTable = 0; iTable < tableCookies.length; iTable += 1) {
cookie[iTable] = [];
for (i = 0; i < tableCookies[iTable].length; i += 1) {
k = base64url.indexOf(tableCookies[iTable].charAt(i));
if (k < 0) { // input validation
k = 0;
}
for (j = 5; j >= 0; j -= 1) {
cookie[iTable][6 * i + j] = (k & 0x1);
k >>= 1;
}
}
}
}
}
}
// initialize the cookie array of arrays, if needed
while (cookie.length < numTables) {
cookie.push([]);
}
}
// save/update the cookie for page reloads
// cookie info is saved in 1 of 16 browser cookies, based on page name hash
// global cookie[][] supports multiple tables and multiple pages
// uses global hashPageName
function saveCookie() {
var cookieName = cookiePrefix + '-' + hashPageName.charAt(0),
pageCookies,
tableCookies,
iPage,
iTable,
i,
j,
k,
updated;
// create the cookie for the tables on the current page
// use Base64url to compress 6 rows to 1 character
tableCookies = hashPageName;
for (iTable = 0; iTable < cookie.length; iTable += 1) {
if (iTable > 0) {
tableCookies += tableSeparator;
}
for (i = 0; i < Math.ceil(cookie[iTable].length / 6); i += 1) {
k = cookie[iTable][6 * i];
for (j = 1; j < 6; j += 1) {
k = 2 * k + ((6 * i + j < cookie[iTable].length) ? cookie[iTable][6 * i + j] : 0);
}
tableCookies += base64url.charAt(k);
}
}
updated = 0;
pageCookies = [];
if ($.cookie(cookieName) !== null) {
// get all the page cookies
// another page might have updated them since this page
pageCookies = $.cookie(cookieName).split(pageSeparator);
// update the page cookie if it already exists
for (iPage = 0; iPage < pageCookies.length; iPage += 1) {
if (hashPageName === pageCookies[iPage].substr(0, 8)) {
updated = 1;
pageCookies[iPage] = tableCookies;
}
}
}
// add the page cookie if it doesn't exist yet
if (updated === 0) {
pageCookies.push(tableCookies);
}
// set path to / so it works for /wiki/, /index.php, etc
$.cookie(cookieName, pageCookies.join(pageSeparator), {
expires: 7,
path: '/'
});
}
tables = $('table.' + tableClass);
// don't bother doing anything unless there's really something to do
if (tables.length > 0) {
// hash the page name to an 8-char hex string
hashPageName = crc32c(wgPageName);
loadCookie(tables.length);
tables.each(function (iTable) {
rows[iTable] = $(this).find('tr:has(td)'); // data rows
// init or trim the cookie array of rows, if needed
while (cookie[iTable].length < rows[iTable].length) {
cookie[iTable].push(0);
}
while (cookie[iTable].length > rows[iTable].length) {
cookie[iTable].pop();
}
// don't rely on headers to find # of columns
// count them dynamically
columns = 1;
rows[iTable].each(function (iRow) {
// update column count as we go
// a smarter approach would count colspans, but this is good for now
columns = Math.max(columns, $(this).children('th,td').length);
// initialize highlighting based on the cookie
setHighlight(this, cookie[iTable][iRow]);
// set mouse events
$(this).mouseover(function () {
setHighlight(this, 2);
}).mouseout(function () {
setHighlight(this, cookie[iTable][iRow]);
}).click(function (e) {
// don't toggle highlight when clicking links
if ((e.target.tagName !== 'A') && (e.target.tagName !== 'IMG')) {
cookie[iTable][iRow] = 1 - cookie[iTable][iRow];
setHighlight(this, cookie[iTable][iRow]);
saveCookie();
}
});
});
// add a button for reset
$(this).append(
$('<tfoot/>')
.append(
$('<tr/>')
.append(
$('<th/>')
.attr('colspan', columns)
.append(
$('<input>')
.attr({
'type': 'button',
'value': 'Reset'
})
.click(function () {
rows[iTable].each(function (iRow) {
cookie[iTable][iRow] = 0;
setHighlight(this, 0);
});
saveCookie();
})
)
)
)
);
});
}
}
$(highlightTable);
}(this.jQuery, this.mediaWiki));
/* </pre> */