pokemon-showdown-client/js/search.js
2021-05-11 20:19:08 -07:00

795 lines
29 KiB
JavaScript

/**
* Search
*
* Basically just an improved version of utilichart
*
* Dependencies: jQuery, battledata, search-index
* Optional dependencies: pokedex, moves, items, abilities
*
* @author Guangcong Luo <guangcongluo@gmail.com>
*/
(function (exports, $) {
'use strict';
function Search(elem, viewport) {
this.$el = $(elem);
this.el = this.$el[0];
this.$viewport = (viewport ? $(viewport) : $(window));
this.urlRoot = '';
this.q = undefined; // uninitialized
this.exactMatch = false;
this.resultSet = null;
this.filters = null;
this.sortCol = null;
this.renderedIndex = 0;
this.renderingDone = true;
this.externalFilter = false;
this.cur = {};
this.$inputEl = null;
this.gen = 8;
this.mod = null;
this.engine = new DexSearch();
window.search = this;
var self = this;
this.$el.on('click', '.more button', function (e) {
e.preventDefault();
self.updateScroll(true);
});
this.$el.on('click', '.filter', function (e) {
e.preventDefault();
self.removeFilter(e);
if (self.$inputEl) self.$inputEl.focus();
});
this.$el.on('click', '.sortcol', function (e) {
e.preventDefault();
e.stopPropagation();
var sortCol = e.currentTarget.dataset.sort;
self.engine.toggleSort(sortCol);
self.sortCol = self.engine.sortCol;
self.find('');
});
}
Search.prototype.$ = function (query) {
return this.$el.find(query);
};
//
// Search functions
//
Search.prototype.find = function (query, firstElem) {
if (!this.engine.find(query)) return; // nothing changed
this.exactMatch = this.engine.exactMatch;
this.q = this.engine.query;
this.resultSet = this.engine.results;
if (firstElem) {
this.resultSet = [[this.engine.typedSearch.searchType, firstElem]].concat(this.resultSet);
if (this.resultSet.length > 1 && ['sortpokemon', 'sortmove'].includes(this.resultSet[1][0])) {
var sortRow = this.resultSet[1];
this.resultSet[1] = this.resultSet[0];
this.resultSet[0] = sortRow;
}
}
if (this.filters) {
this.resultSet = [['html', this.getFilterText()]].concat(this.resultSet);
}
this.renderedIndex = 0;
this.renderingDone = false;
this.updateScroll();
return true;
};
Search.prototype.addFilter = function (node) {
if (!node.dataset.entry) return false;
var entry = node.dataset.entry.split('|');
var result = this.engine.addFilter(entry);
this.filters = this.engine.filters;
return result;
};
Search.prototype.removeFilter = function (e) {
var result;
if (e) {
result = this.engine.removeFilter(e.currentTarget.value.split(':'));
} else {
result = this.engine.removeFilter();
}
this.filters = this.engine.filters;
this.find('');
return result;
};
Search.prototype.getFilterText = function (q) {
var buf = '<p>Filters: ';
for (var i = 0; i < this.filters.length; i++) {
var text = this.filters[i][1];
if (this.filters[i][0] === 'move') text = Dex.moves.get(text).name;
if (this.filters[i][0] === 'pokemon') text = Dex.species.get(text).name;
buf += '<button class="filter" value="' + BattleLog.escapeHTML(this.filters[i].join(':')) + '">' + text + ' <i class="fa fa-times-circle"></i></button> ';
}
if (!q) buf += '<small style="color: #888">(backspace = delete filter)</small>';
return buf + '</p>';
};
Search.prototype.updateScroll = function (forceAdd) {
if (this.renderingDone) return;
var top = this.$viewport.scrollTop();
var bottom = top + this.$viewport.height();
var windowHeight = $(window).height();
var i = this.renderedIndex;
var finalIndex = Math.floor(bottom / 33) + 1;
if (!forceAdd && finalIndex <= i) return;
if (finalIndex < i + 20) finalIndex = i + 20;
if (bottom - top > windowHeight && !i) finalIndex = 20;
if (forceAdd && finalIndex > i + 40) finalIndex = i + 40;
var resultSet = this.resultSet;
var buf = '';
while (i < finalIndex) {
if (!resultSet[i]) {
this.renderingDone = true;
break;
}
var row = resultSet[i];
var errorMessage = '';
var label;
if ((label = this.engine.filterLabel(row[0]))) {
errorMessage = '<span class="col filtercol"><em>' + label + '</em></span>';
} else if ((label = this.engine.illegalLabel(row[1]))) {
errorMessage = '<span class="col illegalcol"><em>' + label + '</em></span>';
}
var mStart = 0;
var mEnd = 0;
if (row.length > 3) {
mStart = row[2];
mEnd = row[3];
}
buf += this.renderRow(row[1], row[0], mStart, mEnd, errorMessage, row[1] in this.cur ? ' class="cur"' : '');
i++;
}
if (!this.renderedIndex) {
this.el.innerHTML = '<ul class="utilichart" style="height:' + (resultSet.length * 33) + 'px">' + buf + (!this.renderingDone ? '<li class="result more"><p><button class="button big">More</button></p></li>' : '') + '</ul>';
this.moreVisible = true;
} else {
if (this.moreVisible) {
this.$el.find('.more').remove();
if (!forceAdd) this.moreVisible = false;
}
$(this.el.firstChild).append(buf + (forceAdd && !this.renderingDone ? '<li class="result more"><p><button class="button big">More</button></p></li>' : ''));
}
this.renderedIndex = i;
};
Search.prototype.setType = function (qType, format, set, cur) {
this.engine.setType(qType, format, set);
this.filters = this.engine.filters;
this.sortCol = this.engine.sortCol;
this.cur = cur || {};
var firstElem;
for (var id in cur) {
firstElem = id;
break;
}
this.find('', firstElem);
};
/*********************************************************
* Rendering functions
*********************************************************/
// These all have static versions
Search.prototype.renderRow = function (id, type, matchStart, matchLength, errorMessage, attrs) {
// errorMessage = '<span class="col illegalcol"><em>' + errorMessage + '</em></span>';
switch (type) {
case 'html':
return '<li class="result">' + id + '</li>';
case 'header':
return '<li class="result"><h3>' + id + '</h3></li>';
case 'sortpokemon':
return this.renderPokemonSortRow();
case 'sortmove':
return this.renderMoveSortRow();
case 'pokemon':
var pokemon = this.engine.dex.species.get(id);
return this.renderPokemonRow(pokemon, matchStart, matchLength, errorMessage, attrs);
case 'move':
var move = this.engine.dex.moves.get(id);
return this.renderMoveRow(move, matchStart, matchLength, errorMessage, attrs);
case 'item':
var item = this.engine.dex.items.get(id);
return this.renderItemRow(item, matchStart, matchLength, errorMessage, attrs);
case 'ability':
var ability = this.engine.dex.abilities.get(id);
return this.renderAbilityRow(ability, matchStart, matchLength, errorMessage, attrs);
case 'type':
var type = {name: id[0].toUpperCase() + id.substr(1)};
return this.renderTypeRow(type, matchStart, matchLength, errorMessage);
case 'egggroup':
// very hardcode
var egName;
if (id === 'humanlike') egName = 'Human-Like';
else if (id === 'water1') egName = 'Water 1';
else if (id === 'water2') egName = 'Water 2';
else if (id === 'water3') egName = 'Water 3';
if (egName) {
if (matchLength > 5) matchLength++;
} else {
egName = id[0].toUpperCase() + id.substr(1);
}
var egggroup = {name: egName};
return this.renderEggGroupRow(egggroup, matchStart, matchLength, errorMessage);
case 'tier':
// very hardcode
var tierTable = {
uber: "Uber",
ou: "OU",
uu: "UU",
ru: "RU",
nu: "NU",
pu: "PU",
zu: "(PU)",
nfe: "NFE",
lc: "LC",
cap: "CAP",
caplc: "CAP LC",
capnfe: "CAP NFE",
uubl: "UUBL",
rubl: "RUBL",
nubl: "NUBL",
publ: "PUBL"
};
var tier = {name: tierTable[id]};
return this.renderTierRow(tier, matchStart, matchLength, errorMessage);
case 'category':
var category = {name: id[0].toUpperCase() + id.substr(1), id: id};
return this.renderCategoryRow(category, matchStart, matchLength, errorMessage);
case 'article':
var articleTitle = (window.BattleArticleTitles && BattleArticleTitles[id]) || (id[0].toUpperCase() + id.substr(1));
var article = {name: articleTitle, id: id};
return this.renderArticleRow(article, matchStart, matchLength, errorMessage);
}
return 'Error: not found';
};
Search.prototype.renderPokemonSortRow = function () {
var buf = '<li class="result"><div class="sortrow">';
buf += '<button class="sortcol numsortcol' + (!this.sortCol ? ' cur' : '') + '">' + (!this.sortCol ? 'Sort: ' : this.engine.firstPokemonColumn) + '</button>';
buf += '<button class="sortcol pnamesortcol' + (this.sortCol === 'name' ? ' cur' : '') + '" data-sort="name">Name</button>';
buf += '<button class="sortcol typesortcol' + (this.sortCol === 'type' ? ' cur' : '') + '" data-sort="type">Types</button>';
buf += '<button class="sortcol abilitysortcol' + (this.sortCol === 'ability' ? ' cur' : '') + '" data-sort="ability">Abilities</button>';
buf += '<button class="sortcol statsortcol' + (this.sortCol === 'hp' ? ' cur' : '') + '" data-sort="hp">HP</button>';
buf += '<button class="sortcol statsortcol' + (this.sortCol === 'atk' ? ' cur' : '') + '" data-sort="atk">Atk</button>';
buf += '<button class="sortcol statsortcol' + (this.sortCol === 'def' ? ' cur' : '') + '" data-sort="def">Def</button>';
if (this.engine.dex.gen >= 2) {
buf += '<button class="sortcol statsortcol' + (this.sortCol === 'spa' ? ' cur' : '') + '" data-sort="spa">SpA</button>';
buf += '<button class="sortcol statsortcol' + (this.sortCol === 'spd' ? ' cur' : '') + '" data-sort="spd">SpD</button>';
} else {
buf += '<button class="sortcol statsortcol' + (this.sortCol === 'spa' ? ' cur' : '') + '" data-sort="spa">Spc</button>';
}
buf += '<button class="sortcol statsortcol' + (this.sortCol === 'spe' ? ' cur' : '') + '" data-sort="spe">Spe</button>';
buf += '<button class="sortcol statsortcol' + (this.sortCol === 'bst' ? ' cur' : '') + '" data-sort="bst">BST</button>';
buf += '</div></li>';
return buf;
};
Search.prototype.renderMoveSortRow = function () {
var buf = '<li class="result"><div class="sortrow">';
buf += '<button class="sortcol movenamesortcol' + (this.sortCol === 'name' ? ' cur' : '') + '" data-sort="name">Name</button>';
buf += '<button class="sortcol movetypesortcol' + (this.sortCol === 'type' ? ' cur' : '') + '" data-sort="type">Type</button>';
buf += '<button class="sortcol movetypesortcol' + (this.sortCol === 'category' ? ' cur' : '') + '" data-sort="category">Cat</button>';
buf += '<button class="sortcol powersortcol' + (this.sortCol === 'power' ? ' cur' : '') + '" data-sort="power">Pow</button>';
buf += '<button class="sortcol accuracysortcol' + (this.sortCol === 'accuracy' ? ' cur' : '') + '" data-sort="accuracy">Acc</button>';
buf += '<button class="sortcol ppsortcol' + (this.sortCol === 'pp' ? ' cur' : '') + '" data-sort="pp">PP</button>';
buf += '</div></li>';
return buf;
};
Search.prototype.renderPokemonRow = function (pokemon, matchStart, matchLength, errorMessage, attrs) {
if (!attrs) attrs = '';
if (!pokemon) return '<li class="result">Unrecognized pokemon</li>';
var id = toID(pokemon.name);
if (Search.urlRoot) attrs += ' href="' + Search.urlRoot + 'pokemon/' + id + '" data-target="push"';
var buf = '<li class="result"><a' + attrs + ' data-entry="pokemon|' + BattleLog.escapeHTML(pokemon.name) + '">';
// number
var tier = this.engine ? this.engine.getTier(pokemon) : pokemon.num;
// buf += '<span class="col numcol">' + (pokemon.num >= 0 ? pokemon.num : 'CAP') + '</span> ';
buf += '<span class="col numcol">' + tier + '</span> ';
// icon
buf += '<span class="col iconcol">';
buf += '<span style="' + Dex.getPokemonIcon(pokemon.name) + '"></span>';
buf += '</span> ';
// name
var name = pokemon.name;
var tagStart = (pokemon.forme ? name.length - pokemon.forme.length - 1 : 0);
if (tagStart) name = name.substr(0, tagStart);
if (matchLength) {
name = name.substr(0, matchStart) + '<b>' + name.substr(matchStart, matchLength) + '</b>' + name.substr(matchStart + matchLength);
}
if (tagStart) {
if (matchLength && matchStart + matchLength > tagStart) {
if (matchStart < tagStart) {
matchLength -= tagStart - matchStart;
matchStart = tagStart;
}
name += '<small>' + pokemon.name.substr(tagStart, matchStart - tagStart) + '<b>' + pokemon.name.substr(matchStart, matchLength) + '</b>' + pokemon.name.substr(matchStart + matchLength) + '</small>';
} else {
name += '<small>' + pokemon.name.substr(tagStart) + '</small>';
}
}
buf += '<span class="col pokemonnamecol">' + name + '</span> ';
// error
if (errorMessage) {
buf += errorMessage + '</a></li>';
return buf;
}
var gen = this.engine.dex.gen;
// type
buf += '<span class="col typecol">';
var types = pokemon.types;
for (var i = 0; i < types.length; i++) {
buf += Dex.getTypeIcon(types[i]);
}
buf += '</span> ';
// abilities
if (gen >= 3) {
var abilities = Dex.forGen(gen).species.get(id).abilities;
if (gen >= 5) {
if (abilities['1']) {
buf += '<span class="col twoabilitycol">' + abilities['0'] + '<br />' +
abilities['1'] + '</span>';
} else {
buf += '<span class="col abilitycol">' + abilities['0'] + '</span>';
}
var unreleasedHidden = pokemon.unreleasedHidden;
if (unreleasedHidden === 'Past' && (this.mod === 'natdex' || gen < 8)) unreleasedHidden = false;
if (abilities['S']) {
if (abilities['H']) {
buf += '<span class="col twoabilitycol' + (unreleasedHidden ? ' unreleasedhacol' : '') + '">' + (abilities['H'] || '') + '<br />(' + abilities['S'] + ')</span>';
} else {
buf += '<span class="col abilitycol">(' + abilities['S'] + ')</span>';
}
} else if (abilities['H']) {
buf += '<span class="col abilitycol' + (unreleasedHidden ? ' unreleasedhacol' : '') + '">' + abilities['H'] + '</span>';
} else {
buf += '<span class="col abilitycol"></span>';
}
} else {
buf += '<span class="col abilitycol">' + abilities['0'] + '</span>';
buf += '<span class="col abilitycol">' + (abilities['1'] ? abilities['1'] : '') + '</span>';
}
} else {
buf += '<span class="col abilitycol"></span>';
buf += '<span class="col abilitycol"></span>';
}
// base stats
var stats = pokemon.baseStats;
buf += '<span class="col statcol"><em>HP</em><br />' + stats.hp + '</span> ';
buf += '<span class="col statcol"><em>Atk</em><br />' + stats.atk + '</span> ';
buf += '<span class="col statcol"><em>Def</em><br />' + stats.def + '</span> ';
if (gen >= 2) {
buf += '<span class="col statcol"><em>SpA</em><br />' + stats.spa + '</span> ';
buf += '<span class="col statcol"><em>SpD</em><br />' + stats.spd + '</span> ';
} else {
buf += '<span class="col statcol"><em>Spc</em><br />' + stats.spa + '</span> ';
}
buf += '<span class="col statcol"><em>Spe</em><br />' + stats.spe + '</span> ';
var bst = 0;
for (i in stats) bst += stats[i];
buf += '<span class="col bstcol"><em>BST<br />' + bst + '</em></span> ';
buf += '</a></li>';
return buf;
};
Search.prototype.renderTaggedPokemonRowInner = function (pokemon, tag, errorMessage) {
var attrs = '';
if (Search.urlRoot) attrs = ' href="' + Search.urlRoot + 'pokemon/' + toID(pokemon.name) + '" data-target="push"';
var buf = '<a' + attrs + ' data-entry="pokemon|' + BattleLog.escapeHTML(pokemon.name) + '">';
// tag
buf += '<span class="col tagcol shorttagcol">' + tag + '</span> ';
// icon
buf += '<span class="col iconcol">';
buf += '<span style="' + Dex.getPokemonIcon(pokemon.name) + '"></span>';
buf += '</span> ';
// name
var name = pokemon.name;
var tagStart = (pokemon.forme ? name.length - pokemon.forme.length - 1 : 0);
if (tagStart) name = name.substr(0, tagStart) + '<small>' + pokemon.name.substr(tagStart) + '</small>';
buf += '<span class="col shortpokemonnamecol">' + name + '</span> ';
// error
if (errorMessage) {
buf += errorMessage + '</a></li>';
return buf;
}
// type
buf += '<span class="col typecol">';
for (var i = 0; i < pokemon.types.length; i++) {
buf += Dex.getTypeIcon(pokemon.types[i]);
}
buf += '</span> ';
// abilities
buf += '<span style="float:left;min-height:26px">';
if (pokemon.abilities['1']) {
buf += '<span class="col twoabilitycol">';
} else {
buf += '<span class="col abilitycol">';
}
for (var i in pokemon.abilities) {
var ability = pokemon.abilities[i];
if (!ability) continue;
if (i === '1') buf += '<br />';
if (i === 'H') ability = '</span><span class="col abilitycol"><em>' + pokemon.abilities[i] + '</em>';
buf += ability;
}
if (!pokemon.abilities['H']) buf += '</span><span class="col abilitycol">';
buf += '</span>';
buf += '</span>';
// base stats
buf += '<span style="float:left;min-height:26px">';
buf += '<span class="col statcol"><em>HP</em><br />' + pokemon.baseStats.hp + '</span> ';
buf += '<span class="col statcol"><em>Atk</em><br />' + pokemon.baseStats.atk + '</span> ';
buf += '<span class="col statcol"><em>Def</em><br />' + pokemon.baseStats.def + '</span> ';
buf += '<span class="col statcol"><em>SpA</em><br />' + pokemon.baseStats.spa + '</span> ';
buf += '<span class="col statcol"><em>SpD</em><br />' + pokemon.baseStats.spd + '</span> ';
buf += '<span class="col statcol"><em>Spe</em><br />' + pokemon.baseStats.spe + '</span> ';
var bst = 0;
for (i in pokemon.baseStats) bst += pokemon.baseStats[i];
buf += '<span class="col bstcol"><em>BST<br />' + bst + '</em></span> ';
buf += '</span>';
buf += '</a>';
return buf;
};
Search.prototype.renderItemRow = function (item, matchStart, matchLength, errorMessage, attrs) {
if (!attrs) attrs = '';
if (!item) return '<li class="result">Unrecognized item</li>';
var id = toID(item.name);
if (Search.urlRoot) attrs += ' href="' + Search.urlRoot + 'items/' + id + '" data-target="push"';
var buf = '<li class="result"><a' + attrs + ' data-entry="item|' + BattleLog.escapeHTML(item.name) + '">';
// icon
buf += '<span class="col itemiconcol">';
buf += '<span style="' + Dex.getItemIcon(item) + '"></span>';
buf += '</span> ';
// name
var name = item.name;
if (matchLength) {
name = name.substr(0, matchStart) + '<b>' + name.substr(matchStart, matchLength) + '</b>' + name.substr(matchStart + matchLength);
}
buf += '<span class="col namecol">' + name + '</span> ';
// error
if (errorMessage) {
buf += errorMessage + '</a></li>';
return buf;
}
// desc
buf += '<span class="col itemdesccol">' + BattleLog.escapeHTML(item.shortDesc) + '</span> ';
buf += '</a></li>';
return buf;
};
Search.prototype.renderAbilityRow = function (ability, matchStart, matchLength, errorMessage, attrs) {
if (!attrs) attrs = '';
if (!ability) return '<li class="result">Unrecognized ability</li>';
var id = toID(ability.name);
if (Search.urlRoot) attrs += ' href="' + Search.urlRoot + 'abilities/' + id + '" data-target="push"';
var buf = '<li class="result"><a' + attrs + ' data-entry="ability|' + BattleLog.escapeHTML(ability.name) + '">';
// name
var name = ability.name;
if (matchLength) {
name = name.substr(0, matchStart) + '<b>' + name.substr(matchStart, matchLength) + '</b>' + name.substr(matchStart + matchLength);
}
buf += '<span class="col namecol">' + name + '</span> ';
// error
if (errorMessage) {
buf += errorMessage + '</a></li>';
return buf;
}
buf += '<span class="col abilitydesccol">' + BattleLog.escapeHTML(ability.shortDesc) + '</span> ';
buf += '</a></li>';
return buf;
};
Search.prototype.renderMoveRow = function (move, matchStart, matchLength, errorMessage, attrs) {
if (!attrs) attrs = '';
if (!move) return '<li class="result">Unrecognized move</li>';
var id = toID(move.name);
if (Search.urlRoot) attrs += ' href="' + Search.urlRoot + 'moves/' + id + '" data-target="push"';
var buf = '<li class="result"><a' + attrs + ' data-entry="move|' + BattleLog.escapeHTML(move.name) + '">';
// name
var name = move.name;
var tagStart = (name.substr(0, 12) === 'Hidden Power' ? 12 : 0);
if (tagStart) name = name.substr(0, tagStart);
if (matchLength) {
name = name.substr(0, matchStart) + '<b>' + name.substr(matchStart, matchLength) + '</b>' + name.substr(matchStart + matchLength);
}
if (tagStart) {
if (matchLength && matchStart + matchLength > tagStart) {
if (matchStart < tagStart) {
matchLength -= tagStart - matchStart;
matchStart = tagStart;
}
name += '<small>' + move.name.substr(tagStart, matchStart - tagStart) + '<b>' + move.name.substr(matchStart, matchLength) + '</b>' + move.name.substr(matchStart + matchLength) + '</small>';
} else {
name += '<small>' + move.name.substr(tagStart) + '</small>';
}
}
buf += '<span class="col movenamecol">' + name + '</span> ';
// error
if (errorMessage) {
buf += errorMessage + '</a></li>';
return buf;
}
// type
buf += '<span class="col typecol">';
buf += Dex.getTypeIcon(move.type);
buf += Dex.getCategoryIcon(move.category);
buf += '</span> ';
// power, accuracy, pp
var basePower = move.basePower;
var accuracy = move.accuracy;
var pp = move.pp;
buf += '<span class="col labelcol">' + (move.category !== 'Status' ? ('<em>Power</em><br />' + (basePower || '&mdash;')) : '') + '</span> ';
buf += '<span class="col widelabelcol"><em>Accuracy</em><br />' + (accuracy && accuracy !== true ? accuracy + '%' : '&mdash;') + '</span> ';
buf += '<span class="col pplabelcol"><em>PP</em><br />' + (pp === 1 || move.noPPBoosts ? pp : pp * 8 / 5) + '</span> ';
// desc
buf += '<span class="col movedesccol">' + BattleLog.escapeHTML(move.shortDesc) + '</span> ';
buf += '</a></li>';
return buf;
};
Search.prototype.renderMoveRowInner = function (move, errorMessage) {
var attrs = '';
if (Search.urlRoot) attrs = ' href="' + Search.urlRoot + 'moves/' + toID(move.name) + '" data-target="push"';
var buf = '<a' + attrs + ' data-entry="move|' + BattleLog.escapeHTML(move.name) + '">';
// name
var name = move.name;
var tagStart = (name.substr(0, 12) === 'Hidden Power' ? 12 : 0);
if (tagStart) name = name.substr(0, tagStart) + '<small>' + move.name.substr(tagStart) + '</small>';
buf += '<span class="col movenamecol">' + name + '</span> ';
// error
if (errorMessage) {
buf += errorMessage + '</a></li>';
return buf;
}
// type
buf += '<span class="col typecol">';
buf += Dex.getTypeIcon(move.type);
buf += Dex.getCategoryIcon(move.category);
buf += '</span> ';
// power, accuracy, pp
buf += '<span class="col labelcol">' + (move.category !== 'Status' ? ('<em>Power</em><br />' + (move.basePower || '&mdash;')) : '') + '</span> ';
buf += '<span class="col widelabelcol"><em>Accuracy</em><br />' + (move.accuracy && move.accuracy !== true ? move.accuracy + '%' : '&mdash;') + '</span> ';
buf += '<span class="col pplabelcol"><em>PP</em><br />' + (move.pp === 1 || move.noPPBoosts ? move.pp : move.pp * 8 / 5) + '</span> ';
// desc
buf += '<span class="col movedesccol">' + BattleLog.escapeHTML(move.shortDesc || move.desc) + '</span> ';
buf += '</a>';
return buf;
};
Search.prototype.renderTaggedMoveRow = function (move, tag, errorMessage) {
var attrs = '';
if (Search.urlRoot) attrs = ' href="' + Search.urlRoot + 'moves/' + toID(move.name) + '" data-target="push"';
var buf = '<li class="result"><a' + attrs + ' data-entry="move|' + BattleLog.escapeHTML(move.name) + '">';
// tag
buf += '<span class="col tagcol">' + tag + '</span> ';
// name
var name = move.name;
if (name.substr(0, 12) === 'Hidden Power') name = 'Hidden Power';
buf += '<span class="col shortmovenamecol">' + name + '</span> ';
// error
if (errorMessage) {
buf += errorMessage + '</a></li>';
return buf;
}
// type
buf += '<span class="col typecol">';
buf += Dex.getTypeIcon(move.type);
buf += Dex.getCategoryIcon(move.category);
buf += '</span> ';
// power, accuracy, pp
buf += '<span class="col labelcol">' + (move.category !== 'Status' ? ('<em>Power</em><br />' + (move.basePower || '&mdash;')) : '') + '</span> ';
buf += '<span class="col widelabelcol"><em>Accuracy</em><br />' + (move.accuracy && move.accuracy !== true ? move.accuracy + '%' : '&mdash;') + '</span> ';
buf += '<span class="col pplabelcol"><em>PP</em><br />' + (move.pp !== 1 ? move.pp * 8 / 5 : move.pp) + '</span> ';
// desc
buf += '<span class="col movedesccol">' + BattleLog.escapeHTML(move.shortDesc || move.desc) + '</span> ';
buf += '</a></li>';
return buf;
};
Search.prototype.renderTypeRow = function (type, matchStart, matchLength, errorMessage) {
var attrs = '';
if (Search.urlRoot) attrs = ' href="' + Search.urlRoot + 'types/' + toID(type.name) + '" data-target="push"';
var buf = '<li class="result"><a' + attrs + ' data-entry="type|' + BattleLog.escapeHTML(type.name) + '">';
// name
var name = type.name;
if (matchLength) {
name = name.substr(0, matchStart) + '<b>' + name.substr(matchStart, matchLength) + '</b>' + name.substr(matchStart + matchLength);
}
buf += '<span class="col namecol">' + name + '</span> ';
// type
buf += '<span class="col typecol">';
buf += Dex.getTypeIcon(type.name);
buf += '</span> ';
// error
if (errorMessage) {
buf += errorMessage + '</a></li>';
return buf;
}
buf += '</a></li>';
return buf;
};
Search.prototype.renderCategoryRow = function (category, matchStart, matchLength, errorMessage) {
var attrs = '';
if (Search.urlRoot) attrs = ' href="' + Search.urlRoot + 'categories/' + category.id + '" data-target="push"';
var buf = '<li class="result"><a' + attrs + ' data-entry="category|' + BattleLog.escapeHTML(category.name) + '">';
// name
var name = category.name;
if (matchLength) {
name = name.substr(0, matchStart) + '<b>' + name.substr(matchStart, matchLength) + '</b>' + name.substr(matchStart + matchLength);
}
buf += '<span class="col namecol">' + name + '</span> ';
// category
buf += '<span class="col typecol">' + Dex.getCategoryIcon(category.name) + '</span> ';
// error
if (errorMessage) {
buf += errorMessage + '</a></li>';
return buf;
}
buf += '</a></li>';
return buf;
};
Search.prototype.renderArticleRow = function (article, matchStart, matchLength, errorMessage) {
var attrs = '';
if (Search.urlRoot) attrs = ' href="' + Search.urlRoot + 'articles/' + article.id + '" data-target="push"';
var isSearchType = (article.id === 'pokemon' || article.id === 'moves');
if (isSearchType) attrs = ' href="' + article.id + '/" data-target="replace"';
var buf = '<li class="result"><a' + attrs + ' data-entry="article|' + BattleLog.escapeHTML(article.name) + '">';
// name
var name = article.name;
if (matchLength) {
name = name.substr(0, matchStart) + '<b>' + name.substr(matchStart, matchLength) + '</b>' + name.substr(matchStart + matchLength);
}
buf += '<span class="col namecol">' + name + '</span> ';
// article
if (isSearchType) {
buf += '<span class="col movedesccol">(search type)</span> ';
} else {
buf += '<span class="col movedesccol">(article)</span> ';
}
// error
if (errorMessage) {
buf += errorMessage + '</a></li>';
return buf;
}
buf += '</a></li>';
return buf;
};
Search.prototype.renderEggGroupRow = function (egggroup, matchStart, matchLength, errorMessage) {
var attrs = '';
if (Search.urlRoot) attrs = ' href="' + Search.urlRoot + 'egggroups/' + toID(egggroup.name) + '" data-target="push"';
var buf = '<li class="result"><a' + attrs + ' data-entry="egggroup|' + BattleLog.escapeHTML(egggroup.name) + '">';
// name
var name = egggroup.name;
if (matchLength) {
name = name.substr(0, matchStart) + '<b>' + name.substr(matchStart, matchLength) + '</b>' + name.substr(matchStart + matchLength);
}
buf += '<span class="col namecol">' + name + '</span> ';
// error
if (errorMessage) {
buf += errorMessage + '</a></li>';
return buf;
}
buf += '</a></li>';
return buf;
};
Search.prototype.renderTierRow = function (tier, matchStart, matchLength, errorMessage) {
var attrs = '';
if (Search.urlRoot) attrs = ' href="' + Search.urlRoot + 'tiers/' + toID(tier.name) + '" data-target="push"';
var buf = '<li class="result"><a' + attrs + ' data-entry="tier|' + BattleLog.escapeHTML(tier.name) + '">';
// name
var name = tier.name;
if (matchLength) {
name = name.substr(0, matchStart) + '<b>' + name.substr(matchStart, matchLength) + '</b>' + name.substr(matchStart + matchLength);
}
buf += '<span class="col namecol">' + name + '</span> ';
// error
if (errorMessage) {
buf += errorMessage + '</a></li>';
return buf;
}
buf += '</a></li>';
return buf;
};
Search.gen = 8;
Search.renderRow = Search.prototype.renderRow;
Search.renderPokemonRow = Search.prototype.renderPokemonRow;
Search.renderTaggedPokemonRowInner = Search.prototype.renderTaggedPokemonRowInner;
Search.renderItemRow = Search.prototype.renderItemRow;
Search.renderAbilityRow = Search.prototype.renderAbilityRow;
Search.renderMoveRow = Search.prototype.renderMoveRow;
Search.renderMoveRowInner = Search.prototype.renderMoveRowInner;
Search.renderTaggedMoveRow = Search.prototype.renderTaggedMoveRow;
Search.renderTypeRow = Search.prototype.renderTypeRow;
Search.renderCategoryRow = Search.prototype.renderCategoryRow;
Search.renderEggGroupRow = Search.prototype.renderEggGroupRow;
Search.renderTierRow = Search.prototype.renderTierRow;
exports.BattleSearch = Search;
})(window, jQuery);