mirror of
https://github.com/smogon/pokemon-showdown-client.git
synced 2026-03-21 17:50:29 -05:00
Some checks are pending
Node.js CI / build (22.x) (push) Waiting to run
This finally removes the tslint dependency and switches to eslint. There are a lot of other changes here, too, to bring the codebase up to server standards. TSLint never had much in the way of indentation enforcement. Not very happy about eslint splitting itself up over 6 dependencies, or its documentation over three websites, nor how poorly documented the new flat config is, but I mean, eslint's gonna eslint. Customizing would be even harder if we tried to use Biome or something. They mostly seem to go full Prettier. Also here are some changes to our style rules. In particular: - Curly brackets (for objects etc) now have spaces inside them. Sorry for the huge change. ESLint doesn't support our old style, and most projects use Prettier style, so we might as well match them in this way. See https://github.com/eslint-stylistic/eslint-stylistic/issues/415 - String + number concatenation is no longer allowed (except in ES3 code). We otherwise now consistently use template strings for this.
800 lines
29 KiB
JavaScript
800 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 = 9;
|
|
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: "ZU",
|
|
nfe: "NFE",
|
|
lc: "LC",
|
|
cap: "CAP",
|
|
caplc: "CAP LC",
|
|
capnfe: "CAP NFE",
|
|
uubl: "UUBL",
|
|
rubl: "RUBL",
|
|
nubl: "NUBL",
|
|
publ: "PUBL",
|
|
zubl: "ZUBL"
|
|
};
|
|
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 ? this.engine.dex.gen : 9;
|
|
|
|
// 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) {
|
|
if (i === 'spd' && gen === 1) continue;
|
|
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 pp = (move.pp === 1 || move.noPPBoosts ? move.pp : move.pp * 8 / 5);
|
|
if (this.engine && this.engine.dex.gen < 3) pp = Math.min(61, pp);
|
|
buf += '<span class="col labelcol">' + (move.category !== 'Status' ? ('<em>Power</em><br />' + (move.basePower || '—')) : '') + '</span> ';
|
|
buf += '<span class="col widelabelcol"><em>Accuracy</em><br />' + (move.accuracy && move.accuracy !== true ? move.accuracy + '%' : '—') + '</span> ';
|
|
buf += '<span class="col pplabelcol"><em>PP</em><br />' + pp + '</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
|
|
var pp = (move.pp === 1 || move.noPPBoosts ? move.pp : move.pp * 8 / 5);
|
|
if (this.engine && this.engine.dex.gen < 3) pp = Math.min(61, pp);
|
|
buf += '<span class="col labelcol">' + (move.category !== 'Status' ? ('<em>Power</em><br />' + (move.basePower || '—')) : '') + '</span> ';
|
|
buf += '<span class="col widelabelcol"><em>Accuracy</em><br />' + (move.accuracy && move.accuracy !== true ? move.accuracy + '%' : '—') + '</span> ';
|
|
buf += '<span class="col pplabelcol"><em>PP</em><br />' + pp + '</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 || '—')) : '') + '</span> ';
|
|
buf += '<span class="col widelabelcol"><em>Accuracy</em><br />' + (move.accuracy && move.accuracy !== true ? move.accuracy + '%' : '—') + '</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 = 9;
|
|
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);
|