Skip to content

Commit

Permalink
Use <script nomodule> for polyfills (smogon#1549)
Browse files Browse the repository at this point in the history
This should make PS marginally slower on really old browsers,
marginally faster on modern browsers, neither of which should be
remotely noticeable.

The intended actual impact is to make it easier to maintain
(`battle-dex` is clearly the wrong place for polyfills) and easier
to reuse outside of PS.
  • Loading branch information
Zarel authored Jul 23, 2020
1 parent c113549 commit 57d239c
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 84 deletions.
1 change: 1 addition & 0 deletions index.template.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ <h3><button class="closebutton" tabindex="-1"><i class="fa fa-times-circle"></i>
var LM = document.getElementById('loading-message');
LM.innerHTML += ' DONE<br />Loading libraries...';
</script>
<script nomodule src="//play.pokemonshowdown.com/js/lib/ps-polyfill.js"></script>
<script src="//play.pokemonshowdown.com/config/config.js?"></script>
<script src="//play.pokemonshowdown.com/js/lib/jquery-2.1.4.min.js"></script>
<script src="//play.pokemonshowdown.com/js/lib/jquery-cookie.js"></script>
Expand Down
117 changes: 117 additions & 0 deletions js/lib/ps-polyfill.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/**
* PS polyfill
*
* PS uses its own polyfills optimized for performance rather than
* standards-compliance (we simply don't use the features these
* polyfills don't provide).
*
* The biggest relevant difference is that we don't use
* `Object.defineProperty`, so you can't use `for...in` on Arrays,
* which everyone tells you not to do, anyway - you should be using
* `for...i` loops (or `for...of` with Babel's `assumeArray` setting).
*
* This polyfill is intended to be used in <script nomodule>. All
* polyfills here already exist in all browsers supporting nomodule.
*
* For convenience, I've marked all these with the ES spec they were
* introduced in (note that ES2015 is ES6 here).
*
* @license MIT
* @author Guangcong Luo <[email protected]>
*/

// ES5
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function indexOf(searchElement, fromIndex) {
for (var i = (fromIndex || 0); i < this.length; i++) {
if (this[i] === searchElement) return i;
}
return -1;
};
}
// ES2016, predates nomodule
if (!Array.prototype.includes) {
Array.prototype.includes = function includes(thing) {
return this.indexOf(thing) !== -1;
};
}
// ES5
if (!Array.isArray) {
Array.isArray = function isArray(thing) {
return Object.prototype.toString.call(thing) === '[object Array]';
};
}
// ES6
if (!String.prototype.includes) {
String.prototype.includes = function includes(thing) {
return this.indexOf(thing) !== -1;
};
}
// ES6
if (!String.prototype.startsWith) {
String.prototype.startsWith = function startsWith(thing) {
return this.slice(0, thing.length) === thing;
};
}
// ES6
if (!String.prototype.endsWith) {
String.prototype.endsWith = function endsWith(thing) {
return this.slice(-thing.length) === thing;
};
}
// ES5
if (!String.prototype.trim) {
String.prototype.trim = function trim() {
return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
};
}
// ES6
if (!Object.assign) {
Object.assign = function assign(thing, rest) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var k in source) {
thing[k] = source[k];
}
}
return thing;
};
}
// ES2017, predates nomodule
if (!Object.values) {
Object.values = function values(thing) {
var out = [];
for (var k in thing) {
out.push(thing[k]);
}
return out;
};
}
// ES5
if (!Object.keys) {
Object.keys = function keys(thing) {
var out = [];
for (var k in thing) {
out.push(k);
}
return out;
};
}
// ES2017, predates nomodule
if (!Object.entries) {
Object.entries = function entries(thing) {
var out = [];
for (var k in thing) {
out.push([k, thing[k]]);
}
return out;
};
}
// ES5
if (!Object.create) {
Object.create = function (proto) {
function F() {}
F.prototype = proto;
return new F();
};
}
1 change: 1 addition & 0 deletions js/replay-embed.template.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ linkStyle('https://play.pokemonshowdown.com/style/battle.css?a7');
linkStyle('https://play.pokemonshowdown.com/style/replay.css?a7');
linkStyle('https://play.pokemonshowdown.com/style/utilichart.css?a7');

requireScript('https://play.pokemonshowdown.com/js/lib/ps-polyfill.js');
requireScript('https://play.pokemonshowdown.com/config/config.js?a7');
requireScript('https://play.pokemonshowdown.com/js/lib/jquery-1.11.0.min.js');
requireScript('https://play.pokemonshowdown.com/js/lib/lodash.compat.js');
Expand Down
1 change: 1 addition & 0 deletions preactalpha.template.html
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ <h3><button class="closebutton" tabindex="-1" aria-label="Close"><i class="fa fa
</script>
<script defer src="/config/config.js?"></script>
<script defer src="/js/client-core.js?"></script>
<script nomodule defer src="/js/lib/ps-polyfill.js"></script>

<script defer src="/js/battle-dex.js?"></script>
<script defer src="/js/battle-text-parser.js?"></script>
Expand Down
84 changes: 0 additions & 84 deletions src/battle-dex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,90 +21,6 @@
declare var require: any;
declare var global: any;

if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function indexOf(searchElement, fromIndex) {
for (let i = (fromIndex || 0); i < this.length; i++) {
if (this[i] === searchElement) return i;
}
return -1;
};
}
if (!Array.prototype.includes) {
Array.prototype.includes = function includes(thing) {
return this.indexOf(thing) !== -1;
};
}
if (!Array.isArray) {
Array.isArray = function isArray(thing): thing is any[] {
return Object.prototype.toString.call(thing) === '[object Array]';
};
}
if (!String.prototype.includes) {
String.prototype.includes = function includes(thing) {
return this.indexOf(thing) !== -1;
};
}
if (!String.prototype.startsWith) {
String.prototype.startsWith = function startsWith(thing) {
return this.slice(0, thing.length) === thing;
};
}
if (!String.prototype.endsWith) {
String.prototype.endsWith = function endsWith(thing) {
return this.slice(-thing.length) === thing;
};
}
if (!String.prototype.trim) {
String.prototype.trim = function trim() {
return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
};
}
if (!Object.assign) {
Object.assign = function assign(thing: any, rest: any) {
for (let i = 1; i < arguments.length; i++) {
let source = arguments[i];
for (let k in source) {
thing[k] = source[k];
}
}
return thing;
};
}
if (!Object.values) {
Object.values = function values(thing: any) {
let out: any[] = [];
for (let k in thing) {
out.push(thing[k]);
}
return out;
};
}
if (!Object.keys) {
Object.keys = function keys(thing: any) {
let out: any[] = [];
for (let k in thing) {
out.push(k);
}
return out;
};
}
if (!Object.entries) {
Object.entries = function entries(thing: any) {
let out: any[] = [];
for (let k in thing) {
out.push([k, thing[k]]);
}
return out;
};
}
if (!Object.create) {
Object.create = function (proto: any) {
function F() {}
F.prototype = proto;
return new (F as any)();
};
}

if (typeof window === 'undefined') {
// Node
(global as any).window = global;
Expand Down
1 change: 1 addition & 0 deletions testclient-beta.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ <h3><button class="closebutton" tabindex="-1" aria-label="Close"><i class="fa fa
<script src="https://play.pokemonshowdown.com/config/config.js"></script>
<script src="config/testclient-key.js"></script>
<script src="js/client-core.js"></script>
<script nomodule src="/js/lib/ps-polyfill.js"></script>

<script src="js/battle-dex.js"></script>
<script src="js/battle-text-parser.js"></script>
Expand Down
1 change: 1 addition & 0 deletions testclient.html
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ <h3><button class="closebutton" tabindex="-1" aria-label="Close"><i class="fa fa
<script>
document.getElementById('loading-message').innerHTML += ' DONE<br />Loading libraries...';
</script>
<script nomodule src="/js/lib/ps-polyfill.js"></script>
<script src="js/lib/jquery-2.1.4.min.js"></script>
<script src="js/lib/jquery-cookie.js"></script>
<script src="js/lib/autoresize.jquery.min.js"></script>
Expand Down

0 comments on commit 57d239c

Please sign in to comment.