User:Jberkel/visibilityToggles.js
Note: You may have to bypass your browser’s cache to see the changes. In addition, after saving a sitewide CSS file such as MediaWiki:Common.css, it will take 5-10 minutes before the changes take effect, even if you clear your cache.
- Mozilla / Firefox / Safari: hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (Command-R on a Macintosh);
- Konqueror and Chrome: click Reload or press F5;
- Opera: clear the cache in Tools → Preferences;
- Internet Explorer: hold Ctrl while clicking Refresh, or press Ctrl-F5.
- This script lacks a documentation subpage. Please create it.
- Useful links: root page • root page’s subpages • links • redirects • your own
var VisibilityToggles = window.VisibilityToggles = {
// toggles[category] = [[show, hide],...]; statuses[category] = [true, false,...]; buttons = <li>
toggles: {},
statuses: {},
buttons: null,
// Add a new toggle, adds a Show/Hide category button in the toolbar,
// and will call showFunction and hideFunction once on register, and every alternate click.
register: function (category, showFunction, hideFunction, visibleByDefault) {
if (!this.toggles[category]) {
this.toggles[category] = [];
this.statuses[category] = [];
}
var id = this.toggles[category].length;
this.toggles[category].push([showFunction, hideFunction]);
this.statuses[category].push(this.currentStatus(category, visibleByDefault));
this.addGlobalToggle(category);
(this.statuses[category][id] ? showFunction : hideFunction)();
return function() {
this.statuses[category][id] = !this.statuses[category][id];
this.checkGlobalToggle(category);
return (this.statuses[category][id] ? showFunction : hideFunction)();
}.bind(this);
},
// Add a new global toggle to the side bar
addGlobalToggle: function (category) {
if (this.globalToggleElement(category)) {
return;
}
if (this.buttons === null) {
this.buttons = $('<ul>');
var collapsed = mw.cookie.get('vector-nav-p-visibility') === 'false';
var toolbox = $('<div>')
.attr('id', 'p-visibility')
.addClass('portal portlet')
.addClass(collapsed ? 'collapsed' : 'expanded')
.append('<h3>Visibility</h3>')
.append(
$('<div>').addClass('pBody body')
.css('display', 'block')
.append(this.buttons)
);
var insert = document.getElementById('p-lang') ||
document.getElementById('p-feedback');
if (insert) {
$(insert).before(toolbox);
} else {
var sidebar = document.getElementById('mw-panel') || document.getElementById('column-one');
$(sidebar).appendChild(toolbox);
}
}
var status = this.statuses[category][0];
var newToggle = $('<li>').append($('<a>')
.attr('id', 'p-visibility-' + category)
.attr('href', '#visibility-' + category)
.css('cursor', 'pointer')
.text((status ? 'Hide ' : 'Show ') + category)
.click(function() {
this.toggleGlobal(category);
return false;
}.bind(this)));
this.buttons.children().filter(function(i, elem) {
return elem.id < newToggle.id;
}).first().before(newToggle);
this.buttons.append(newToggle);
},
// Update the toggle-all buttons when all things are toggled one way
checkGlobalToggle: function (category) {
var statuses = this.statuses[category];
var status = statuses[0];
for (var i = 1; i < statuses.length; i++) {
if (status != statuses[i])
return;
}
this.globalToggleElement(category).innerHTML = (status ? 'Hide ' : 'Show ') + category;
},
// Toggle all un-toggled elements when the global button is clicked
toggleGlobal: function (category) {
var status = this.globalToggleElement(category).innerHTML.indexOf('Show ') === 0;
for (var i = 0; i < this.toggles[category].length; i++) {
if (this.statuses[category][i] != status) {
this.toggles[category][i][status ? 0 : 1]();
this.statuses[category][i] = status;
}
}
this.globalToggleElement(category).innerHTML = (status ? 'Hide ' : 'Show ') + category;
this.cookie(category).set(status);
},
currentStatus: function (category, visibleByDefault) {
if (location.hash.toLowerCase().split('_')[0] == '#' + category.toLowerCase())
return true;
else if (location.href.search(/[?](.*&)?hidecats=/) > 0) {
var hidecats = location.href.replace(/^[^?]+[?]((?!hidecats=)[^&]*&)*hidecats=/, '')
.replace(/&.*/, '')
.split(',');
for (var i=0; i<hidecats.length; ++i)
if (hidecats[i] == category || hidecats[i] == 'all')
return false;
else if (hidecats[i] == '!' + category || hidecats[i] == 'none')
return true;
}
else if (mw.cookie.get('WiktionaryPreferencesShowNav') == 'true')
return true;
// TODO check category-specific cookies
else return this.cookie(category).get(visibleByDefault);
},
globalToggleElement: function(category) {
return document.getElementById('p-visibility-' + category);
},
cookie: function(category) {
var name = 'Visibility';
var regex = new RegExp(';' + category + '(?:=(\\d))?;', 'g');
return {
get: function(defaultValue) {
var matches = regex.exec(mw.cookie.get(name) || '');
if (matches) {
return matches.length > 1 ? parseInt(matches[1]) == 1 : true;
} else {
return defaultValue || false;
}
},
set: function(status) {
var value = (mw.cookie.get(name) || ';').replace(regex, ';');
mw.cookie.set(name, value + category + '=' + (status ? '1' : '0') + ';');
}
};
}
};