diff --git a/js/battledata.js b/js/battledata.js
index 606103e2a..48ff46ff4 100644
--- a/js/battledata.js
+++ b/js/battledata.js
@@ -134,7 +134,7 @@ function jsEscape(str) {
}
function messageSanitize(str) {
- return sanitize(str).replace(/\`\`([^< ]([^<`]*?[^< ])?)\`\`/g, '$1').replace(/\~\~([^< ]([^<]*?[^< ])?)\~\~/g, '$1').replace(/(https?\:\/\/[a-z0-9-.]+(\/([^\s]*[^\s?.,])?)?|[a-z0-9]([a-z0-9-\.]*[a-z0-9])?\.(com|org|net|edu|tk)((\/([^\s]*[^\s?.,])?)?|\b))/ig, '$1').replace(/$1').replace(/(\bgl ?\[([^\]<]+)\])/ig, '$1').replace(/(\bwiki ?\[([^\]<]+)\])/ig, '$1').replace(/\[\[([^< ]([^<`]*?[^< ])?)\]\]/ig, '$1').replace(/\_\_([^< ]([^<]*?[^< ])?)\_\_/g, '$1').replace(/\*\*([^< ]([^<]*?[^< ])?)\*\*/g, '$1');
+ return sanitize(str).replace(/\`\`([^< ]([^<`]*?[^< ])?)\`\`/g, '$1').replace(/\~\~([^< ]([^<]*?[^< ])?)\~\~/g, '$1').replace(/(https?\:\/\/[a-z0-9-.]+(\/([^\s]*[^\s?.,])?)?|[a-z0-9]([a-z0-9-\.]*[a-z0-9])?\.(com|org|net|edu|tk)((\/([^\s]*[^\s?.,])?)?|\b))/ig, '$1').replace(/$1').replace(/(\bgl ?\[([^\]<]+)\])/ig, '$1').replace(/(\bwiki ?\[([^\]<]+)\])/ig, '$1').replace(/\[\[([^< ]([^<`]*?[^< ])?)\]\]/ig, '$1').replace(/\_\_([^< ]([^<]*?[^< ])?)\_\_/g, '$1').replace(/\*\*([^< ]([^<]*?[^< ])?)\*\*/g, '$1');
}
function toId(text) {
@@ -303,6 +303,50 @@ var basespecieschart = {
var Tools = {
+ showInterstice: (function() {
+ var whitelist = [
+ /pokemonshowdown\.com/i,
+ /smogon\.com/i,
+ /upokecenter\.com/i,
+ /wikipedia\.org/i,
+ /wikimedia\.org/i,
+ /github\.com/i,
+ /veekun\.com/i,
+ /bulbagarden\.net/i,
+ /serebii\.net/i,
+ /nuggetbridge\.com/i,
+ /reddit\.com/i,
+ /gamefaqs\.com/i,
+ /facebook\.com/i,
+ /twitter\.com/i,
+ /deviantart\.com/i,
+ /pokecommunity\.com/i,
+ /pokemonlab\.com/i,
+ /shoddybattle\.com/i,
+ /pokemon-online\.eu/i,
+ /pokecheck\.org/i,
+ /youtube\.com/i,
+ /challonge.com\.com/i
+ ];
+ var pattern = /^https?:\/\/([A-Za-z0-9\-]*\.)?(([^\\\/]*)\.(com|org|net|eu))(\/.*)?/i;
+ return function(uri) {
+ var m = pattern.exec(uri);
+ if (m) {
+ for (var i = 0; i < whitelist.length; ++i) {
+ if (whitelist[i].test(m[2])) return;
+ }
+ }
+ // This has to work in the replay viewer as well as in sim.js,
+ // so use an absolute URI.
+ window.open(
+ 'http://www.pokemonshowdown.com/interstice?uri=' +
+ encodeURIComponent(uri),
+ 'interstice'
+ );
+ return false;
+ };
+ })(),
+
htmlSanitize: (function() {
var uriRewriter = function(uri) {
// For now, allow all URIs.
@@ -316,10 +360,13 @@ var Tools = {
// In addition to the normal whitelist, allow target='_blank'.
// html.sanitizeAttribs is not very customisable, so this a bit ugly.
var blankIdx = undefined;
- var extra = [];
+ var extra = {};
if (tagName === 'a') {
for (var i = 0; i < attribs.length - 1; i += 2) {
switch (attribs[i]) {
+ case 'href':
+ extra['onclick'] = 'return Tools.showInterstice(this.href);';
+ break;
case 'target':
if (attribs[i + 1] === '_blank') {
blankIdx = i + 1;
@@ -334,8 +381,7 @@ var Tools = {
// Bogus roomid - could be used to inject JavaScript.
break;
}
- extra.push('onclick');
- extra.push('return selectTab(\'' + attribs[i + 1] + '\');');
+ extra['onclick'] = 'return selectTab(\'' + attribs[i + 1] + '\');';
break;
}
}
@@ -344,8 +390,9 @@ var Tools = {
if (blankIdx !== undefined) {
attribs[blankIdx] = '_blank';
}
- if (extra.length > 0) {
- attribs = attribs.concat(extra);
+ for (var i in extra) {
+ attribs.push(i);
+ attribs.push(extra[i]);
}
return {attribs: attribs};
};