MediaWiki:BuffLines.js
Appearance
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
// List of classes that cast buffs
var eqClasses = ['Bard', 'Cleric', 'Druid', 'Enchanter', 'Magician', 'Necromancer', 'Paladin', 'Ranger', 'Shadow Knight', 'Shaman', 'Wizard']
var sources = ['Consumable', 'Clickable', 'Proc', 'Spell', 'Worn'];
var itemSources = ['Consumable', 'Clickable', 'Proc', 'Worn'];
var targets = ['Group', 'Self-only', 'Single'];
/**
* Converts a class/source/target into an ID, eg. Group => groupFilter
*/
var makeId = function(thing) {
if (thing === 'Self-only') return 'selfOnlyFilter';
if (thing === 'Shadow Knight') return 'shadowKnightFilter';
return thing.toLowerCase() + 'Filter';
};
/**
* @returns the HTML for a label/checkbox combination for one filter type
*/
var buildCheckboxLine = function(type, label) {
label = isNaN(label) ? label : type;
return ' <label><input id="' + makeId(type) + '"checked class="filter" type="checkbox"/> ' + label + '</label>';
};
var isChecked = function(thingToCheck) {
return $('#' + makeId(thingToCheck)).is(':checked');
};
var isItemSource = function(line) {
return (
doesLineMatchThisAndType('Consumable', line) ||
doesLineMatchThisAndType('Clickable', line) ||
doesLineMatchThisAndType('Proc', line) ||
doesLineMatchThisAndType('Worn', line)
);
}
var isSingle = function(line) {
var isGroup = line.toLowerCase().indexOf('group') !== -1;
var isSelfOnly = line.toLowerCase().indexOf('self-only') !== -1;
return !isGroup && !isSelfOnly;
}
/**
* Checks whether the provided line matches the provided type
* eg. doesLineMatchThisAndType('target', 'single', line) would only
* return true if the line was for a single-target buff (ie. it had no
* "self-only" or "group")
*/
var doesLineMatchThisAndType = function(type, line) {
line = line.toLowerCase();
type = type.toLowerCase();
// "Spell" matches if none of the item sources match
if (type === 'spell') return !isItemSource(line);
// Single matches if neither a group nor self-only match
if (type === 'single') return isSingle(line);
return line.indexOf(type) !== -1;
};
/**
* Higher Order function which returns a function that returns true only if
* the line both matches the provided type and if that type
* should be shown (ie. is checked)
*/
var hasTypeInLineAndTypeIsShown = function(line) {
return function(type) {
// If this type (eg. Shaman spells) isn't checked, don't show it
if (!isChecked(type)) return false;
// Otherwise, show it if this line matches (eg. it is a Shaman spell)
return doesLineMatchThisAndType(type, line);
};
};
/**
* @returns true if the provided line matches an item source that is checked
*/
var hasMatchingItemSource = function(line) {
return itemSources.some(hasTypeInLineAndTypeIsShown(line));
};
/**
* @returns true if the provided line matches a class that is checked, and the
* "Spell" source is currently checked
*/
var hasMatchingSpellSource = function(line) {
return isChecked('Spell') &&
eqClasses.some(hasTypeInLineAndTypeIsShown(line));
};
/**
* @returns true if the provided line matches a target that has been checked
*/
var hasMatchingTarget = function(line) {
return targets.some(hasTypeInLineAndTypeIsShown(line));
};
var shouldShow = function(line) {
var isBuff = line.startsWith('+');
var itemSourceIsShown = hasMatchingItemSource(line);
var spellSourceIsShown = hasMatchingSpellSource(line);
var targetIsShown = hasMatchingTarget(line);
var isShown = !isBuff || ( // non-buff lines are always shown
// line must match a class or item source
(itemSourceIsShown || spellSourceIsShown) &&
// line must also match a target
targetIsShown
);
//if (!isShown) console.log(line, 'isBuff, itemSourceIsShown, spellSourceIsShown, targetIsShown', isBuff, itemSourceIsShown, spellSourceIsShown, targetIsShown);
return isShown;
};
var areAllClassCheckboxesChecked = function() {
return eqClasses.every(function(eqClass) {
return $('#' + makeId(eqClass)).is(':checked')
});
};
var areAllClassCheckboxesUnchecked = function() {
return eqClasses.every(function(eqClass) {
return !$('#' + makeId(eqClass)).is(':checked')
});
};
var checkAllClassBoxes = function() {
eqClasses.forEach(function(eqClass) {
$('#' + makeId(eqClass)).trigger('click').prop('checked', true);
});
};
var uncheckAllClassBoxes = function() {
eqClasses.forEach(function(eqClass) {
$('#' + makeId(eqClass)).trigger('click').prop('checked', false);
});
};
// Filter buffs when a buff checkbox is clicked
var handleFilterCheckboxClick = function(e) {
$('#content li').each(function(i, el) {
var line = $(el).text().trim();
var shouldBeShown = shouldShow(line);
$(el).toggle(shouldBeShown);
});
// If all of the checkboxes are checked, ensure the All box is checked
// (and vice versa if they're all unchecked)
if (!areAllClassCheckboxesChecked()) {
$('#allClassFilter').prop('checked', false);
} else if (!areAllClassCheckboxesUnchecked()) {
$('#allClassFilter').prop('checked', true);
}
};
var handleAllClassCheckboxChange = function(e) {
if (e.target.checked && !areAllClassCheckboxesChecked()) {
checkAllClassBoxes();
} else if (!e.target.checked && !areAllClassCheckboxesUnchecked()) {
uncheckAllClassBoxes();
}
};
$(function() {
// Replace placeholder with checkboxes (since wiki doesn't allow checkboxesw)
$('#checkboxesPlaceHolder').replaceWith(
'<div>' +
' <div><strong>Source:</strong> ' +
sources.map(buildCheckboxLine).join(' ') + '</div>' +
' <div><strong>Target:</strong> ' +
targets.map(buildCheckboxLine).join(' ') + '</div>' +
' <div>' +
' <strong>Class:</strong> ' +
' <label><input id="allClassFilter"checked type="checkbox"/> All</label>' +
eqClasses.map(buildCheckboxLine).join(' ') +
' </div>' +
'</div>'
);
// When they are clicked, filter
$('.filter').click(handleFilterCheckboxClick);
$('#allClassFilter').change(handleAllClassCheckboxChange);
});