Wikipedysta:Nux/LongTableFilters.js
Wygląd
Uwaga: aby zobaczyć zmiany po opublikowaniu, może zajść potrzeba wyczyszczenia pamięci podręcznej przeglądarki.
- Firefox / Safari: Przytrzymaj Shift podczas klikania Odśwież bieżącą stronę, lub naciśnij klawisze Ctrl+F5, lub Ctrl+R (⌘-R na komputerze Mac)
- Google Chrome: Naciśnij Ctrl-Shift-R (⌘-Shift-R na komputerze Mac)
- Edge: Przytrzymaj Ctrl, jednocześnie klikając Odśwież, lub naciśnij klawisze Ctrl+F5.
- Opera: Naciśnij klawisze Ctrl+F5.
/* global mw, $ */
/**
* Long table filtering.
*
* Assumes only tables longer then 20 rows are worth filtering.
* [[Wikipedysta:Nux/ViewFilter.js]]
*/
// for table filter
mw.loader.load("https://pl.wikipedia.org/w/index.php?action=raw&ctype=text/javascript&smaxage=21600&maxage=86400&title=Wikipedysta:Nux/ViewFilter.js");
/* Translatable strings */
mw.messages.set({
'nuxltf-refresh': 'Odśwież',
'nuxltf-action-init': 'Filtr tabel',
});
// mw.msg('nuxltf-action-init')
/**
* Main class.
*/
class LongTableFilters {
constructor(ViewFilter) {
this.ViewFilter = ViewFilter;
}
/** Init when ready. */
init() {
if (!this.validate()) {
return;
}
if (!this.createControlsContainer()) {
return;
}
this.prepareTable();
}
/** Find all long tables in the article. */
findLongTables() {
return Array.from(document.querySelectorAll( "#content table" ))
.filter(t=>t.querySelectorAll('tr').length > 20)
;
}
/** Check if there are some tables to filter */
validate() {
if (this.findLongTables().length < 1) {
console.log('[table filter]', 'no long tables found');
return false;
}
return true;
}
/** Create filtering form container. */
createControlsContainer() {
// find controls context
var context = this.findLongTables();
if (!context.length) {
console.warn('[table filter]', 'context not found');
return false;
}
context = context[0];
// create controls container
context.insertAdjacentHTML("beforebegin", "<div class='table-filter-controls'/>");
return true;
}
/** Prepare filtering. */
prepareTable() {
// define view filter
const tableFilter = new this.ViewFilter();
this.tableFilter = tableFilter;
tableFilter.itemProperty = 'LongTableFilters_text';
// custom text
tableFilter.itemToText = (item) => {
return this.itemToText(item);
};
// filter for MalarzBOT pages
let pageName = mw.config.get('wgPageName');
if (pageName.indexOf(':MalarzBOT') > 0) {
$('.sortable td small').remove(); // remove replay links etc
}
// mark long tables
let longTables = this.findLongTables();
longTables.forEach((t) => {
t.classList.add('nuxlongtable');
});
// insert controls and pre-parse items
// assumes header row(s) are in thead and not in tbody (should be true in MW)
tableFilter.init(".table-filter-controls", ".nuxlongtable tbody tr");
// refresh button
this.prepareRefreshButton(this.tableFilter.container);
}
/** @private */
itemToText (item) {
// construct text from both `::before` (from CSS) and `textContent`
let text = '';
const allChildren = this.children(item);
for (const child of allChildren) {
if (child.nodeType === Node.ELEMENT_NODE) {
// append ::before from CSS
const before = window.getComputedStyle(child, '::before').getPropertyValue('content');
if (before && before !== 'none') {
text += this.cssContentToText(before);
}
} else if (child.nodeType === Node.TEXT_NODE) {
text += child.textContent;
}
}
//console.log('[LTF]', {item, text});
return text;
}
/** @private Translate value from ComputedStyle to actual text. */
cssContentToText(cssValue) {
return cssValue
// strip opening and closing quotes
.replace(/^['"]/, '').replace(/['"]$/, '')
// should we translate unicode maybe?
;
}
/** @private All children in order. */
children(node) {
const ret = [];
for (let i = 0; i < node.childNodes.length; i++) {
const child = node.childNodes[i];
ret.push(child, ...this.children(child));
}
return ret;
}
/**
* Extra refresh button.
* @param {Element} container The field container.
*/
prepareRefreshButton(container) {
var _self = this;
var inputPhrase = document.createElement("input");
inputPhrase.setAttribute("type", "button");
inputPhrase.setAttribute("value", mw.msg('nuxltf-refresh'));
inputPhrase.addEventListener('click', function() {
_self.refresh();
});
container.appendChild(inputPhrase);
this.inputPhrase = inputPhrase;
}
/** Refresh table cache. */
refresh() {
this.tableFilter.preParseItems();
}
}
//
// on load
//
mw.hook('userjs.ViewFilter.loaded').add(function (ViewFilter) {
$(function(){
const filters = new LongTableFilters(ViewFilter);
if (filters.validate()) {
var portletId = mw.config.get('skin') === 'timeless' ? 'p-pagemisc' : 'p-tb';
var link = mw.util.addPortletLink(portletId, '#', '💧 ' + mw.msg('nuxltf-action-init'), 't-LongTableFilters', null);
var $link = $(link);
$link.click((e) => {
e.preventDefault();
if ($link.data('waiting')) {
return;
}
$link.data('waiting', true);
filters.init();
setTimeout(function() {
$link.data('waiting', false);
}, 500);
});
}
});
});