From 3596437361ebc8e01202d1c0f0920654215f319e Mon Sep 17 00:00:00 2001 From: Zachary Miller Date: Sat, 7 Nov 2026 14:07:15 -0500 Subject: [PATCH 1/5] Build for the 2.0 browser targets The supported browsers are declared in .browserslistrc as "baseline 2021 with downstream" (Chrome and Edge 96, Firefox 95, Safari 15.2). The build minifies for those versions instead of ES5. The syntax check now allows ES2021 (acorn) and also runs es-check, which reads .browserslistrc and fails on built-ins those browsers lack, such as Array.prototype.at. pace.js itself is unchanged. --- .browserslistrc | 2 + pace.min.js | 2 +- package-lock.json | 411 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 3 +- scripts/build.mjs | 7 +- 5 files changed, 421 insertions(+), 4 deletions(-) create mode 100644 .browserslistrc diff --git a/.browserslistrc b/.browserslistrc new file mode 100644 index 0000000..9f68e7e --- /dev/null +++ b/.browserslistrc @@ -0,0 +1,2 @@ +# Supported browsers for pace-js 2.x, frozen for the whole major version: https://web.dev/baseline +baseline 2021 with downstream diff --git a/pace.min.js b/pace.min.js index 6b6be08..d5bd368 100644 --- a/pace.min.js +++ b/pace.min.js @@ -2,4 +2,4 @@ * pace.js v1.3.1 * https://github.com/CodeByZach/pace/ * Licensed MIT © HubSpot, Inc. - */(function(){var O,Y,Q,V,Z,$,ee,C,q,u,te,re,F,ne,se,E,w,ie,g,R,x,X,v,L,oe,U,D,y,ue,d,l,T,I,ae,b,H,P,p,_,W,k,M,z,A,j,le,ce,B,fe,pe,S=[].slice,he={}.hasOwnProperty,ge=function(t,e){for(var r in e)he.call(e,r)&&(t[r]=e[r]);function n(){this.constructor=t}return n.prototype=e.prototype,t.prototype=new n,t.__super__=e.prototype,t},we=[].indexOf||function(t){for(var e=0,r=this.length;e=33?(e=d(),t(n,function(){return T(r)})):setTimeout(r,33-n)},r()},I=function(){var t,e,r;return r=arguments[0],e=arguments[1],t=3<=arguments.length?S.call(arguments,2):[],typeof r[e]=="function"?r[e].apply(r,t):r[e]},v=function(){var t,e,r,n,s,i,o;for(e=arguments[0],n=2<=arguments.length?S.call(arguments,1):[],i=0,o=n.length;i=100?n="99":(n=this.progress<10?"0":"",n+=this.progress|0),e.children[0].setAttribute("data-progress",""+n)),u.trigger("change",this.progress),this.lastRenderedProgress=this.progress},t.prototype.done=function(){return this.progress>=100},t})(),C=(function(){function t(){this.bindings={}}return t.prototype.trigger=function(e,r){var n,s,i,o,a;if(this.bindings[e]!=null){for(o=this.bindings[e],a=[],s=0,i=o.length;s=0)return!0}return!1},te=(function(t){ge(e,t);function e(){var r,n=this;e.__super__.constructor.apply(this,arguments),r=function(s){var i;return i=s.open,s.open=function(o,a,f){return P(o)&&n.trigger("request",{type:o,url:a,request:s}),i.apply(s,arguments)}},window.XMLHttpRequest=function(s){var i;return i=new z(s),r(i),i};try{L(window.XMLHttpRequest,z)}catch(s){}if(M!=null){window.XDomainRequest=function(){var s;return s=new M,r(s),s};try{L(window.XDomainRequest,M)}catch(s){}}if(k!=null&&l.ajax.trackWebSockets){window.WebSocket=function(s,i){var o;return i!=null?o=new k(s,i):o=new k(s),P("socket")&&n.trigger("request",{type:"socket",url:s,protocols:i,request:o}),o};try{L(window.WebSocket,k)}catch(s){}}}return e})(C),j=null,U=function(){return j==null&&(j=new te),j},H=function(t){var e,r,n,s;for(s=l.ajax.ignoreURLs,r=0,n=s.length;re.sampleCount&&o.shift(),r=ie(o),++i>=e.minSamples&&r=100&&(this.done=!0),r===this.last?this.sinceLastUpdate+=e:(this.sinceLastUpdate&&(this.rate=(r-this.last)/this.sinceLastUpdate),this.catchup=(r-this.progress)/l.catchupTime,this.sinceLastUpdate=0,this.last=r),r>this.progress&&(this.progress+=this.catchup*e),n=1-Math.pow(this.progress/100,l.easeFactor),this.progress+=n*this.rate*e,this.progress=Math.min(this.lastProgress+l.maxProgressPerFrame,this.progress),this.progress=Math.max(0,this.progress),this.progress=Math.min(100,this.progress),this.lastProgress=this.progress,this.progress},t})(),_=null,b=null,g=null,W=null,w=null,R=null,u.running=!1,D=function(){if(l.restartOnPushState)return u.restart()},window.history.pushState!=null&&(ce=window.history.pushState,window.history.pushState=function(){return D(),ce.apply(window.history,arguments)}),window.history.replaceState!=null&&(pe=window.history.replaceState,window.history.replaceState=function(){return D(),pe.apply(window.history,arguments)}),re={ajax:O,elements:V,document:Q,eventLag:$},(ue=function(){var t,e,r,n,s,i,o,a;for(u.sources=_=[],i=["ajax","elements","document","eventLag"],e=0,n=i.length;e=33?(e=d(),t(n,function(){return T(r)})):setTimeout(r,33-n)},r()},I=function(){var t,e,r;return r=arguments[0],e=arguments[1],t=3<=arguments.length?S.call(arguments,2):[],typeof r[e]=="function"?r[e].apply(r,t):r[e]},v=function(){var t,e,r,n,s,i,o;for(e=arguments[0],n=2<=arguments.length?S.call(arguments,1):[],i=0,o=n.length;i=100?n="99":(n=this.progress<10?"0":"",n+=this.progress|0),e.children[0].setAttribute("data-progress",""+n)),u.trigger("change",this.progress),this.lastRenderedProgress=this.progress},t.prototype.done=function(){return this.progress>=100},t})(),C=(function(){function t(){this.bindings={}}return t.prototype.trigger=function(e,r){var n,s,i,o,a;if(this.bindings[e]!=null){for(o=this.bindings[e],a=[],s=0,i=o.length;s=0)return!0}return!1},te=(function(t){ge(e,t);function e(){var r,n=this;e.__super__.constructor.apply(this,arguments),r=function(s){var i;return i=s.open,s.open=function(o,a,f){return P(o)&&n.trigger("request",{type:o,url:a,request:s}),i.apply(s,arguments)}},window.XMLHttpRequest=function(s){var i;return i=new z(s),r(i),i};try{L(window.XMLHttpRequest,z)}catch{}if(M!=null){window.XDomainRequest=function(){var s;return s=new M,r(s),s};try{L(window.XDomainRequest,M)}catch{}}if(k!=null&&l.ajax.trackWebSockets){window.WebSocket=function(s,i){var o;return i!=null?o=new k(s,i):o=new k(s),P("socket")&&n.trigger("request",{type:"socket",url:s,protocols:i,request:o}),o};try{L(window.WebSocket,k)}catch{}}}return e})(C),j=null,U=function(){return j==null&&(j=new te),j},H=function(t){var e,r,n,s;for(s=l.ajax.ignoreURLs,r=0,n=s.length;re.sampleCount&&o.shift(),r=ie(o),++i>=e.minSamples&&r=100&&(this.done=!0),r===this.last?this.sinceLastUpdate+=e:(this.sinceLastUpdate&&(this.rate=(r-this.last)/this.sinceLastUpdate),this.catchup=(r-this.progress)/l.catchupTime,this.sinceLastUpdate=0,this.last=r),r>this.progress&&(this.progress+=this.catchup*e),n=1-Math.pow(this.progress/100,l.easeFactor),this.progress+=n*this.rate*e,this.progress=Math.min(this.lastProgress+l.maxProgressPerFrame,this.progress),this.progress=Math.max(0,this.progress),this.progress=Math.min(100,this.progress),this.lastProgress=this.progress,this.progress},t})(),_=null,b=null,g=null,W=null,w=null,R=null,u.running=!1,D=function(){if(l.restartOnPushState)return u.restart()},window.history.pushState!=null&&(ce=window.history.pushState,window.history.pushState=function(){return D(),ce.apply(window.history,arguments)}),window.history.replaceState!=null&&(pe=window.history.replaceState,window.history.replaceState=function(){return D(),pe.apply(window.history,arguments)}),re={ajax:O,elements:V,document:Q,eventLag:$},(ue=function(){var t,e,r,n,s,i,o,a;for(u.sources=_=[],i=["ajax","elements","document","eventLag"],e=0,n=i.length;e=18" } }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/@playwright/test": { "version": "1.64.1", "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.64.1.tgz", @@ -485,6 +524,128 @@ "node": ">=0.4.0" } }, + "node_modules/baseline-browser-mapping": { + "version": "2.11.35", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.35.tgz", + "integrity": "sha512-GNk8KX52CHqeNKGk8+7tZnQab/2k1t/BgrUHPKNdijzpEhF1saPQZHVKb6m5loSAxB39gyrTYw34Qf9CQ3u1qQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.29.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.0.tgz", + "integrity": "sha512-3GSvyjvDI4Dur1Meg2BekJquu5uF+9R9a1+5M1Mde192eZoXbeXjzgOsgqPS2V8D5wrrip0gR5Hf/GhWQ9ZzaA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.11.23", + "caniuse-lite": "^1.0.30001810", + "electron-to-chromium": "^1.5.427", + "node-releases": "^2.0.55", + "update-browserslist-db": "^1.3.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001823", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001823.tgz", + "integrity": "sha512-TQ5s/djDjNk1axreUW+4rULH+BmdCMLiJkhaXnO5wqivG7tITkSUj4ItIdzqdZHKaXcHAV8dhH3JxOM7/7bwqw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.478", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.478.tgz", + "integrity": "sha512-pftG+ma5Lm8O6/p45bhYT6StBN5ziQymaRzmCZwFl8DwWHKPPD93FdOmP1aqftcepolQYvrcyTLa17kE8Yf+jg==", + "dev": true, + "license": "ISC" + }, + "node_modules/es-check": { + "version": "9.8.1", + "resolved": "https://registry.npmjs.org/es-check/-/es-check-9.8.1.tgz", + "integrity": "sha512-F6bumjRmN+OWpEUh3ewhE/S1ey6cHKGMNXPn0iE2tBnict3O855Uij6UYbuHnLS1E3eILvg61KdH6kHbGi9www==", + "dev": true, + "license": "MIT", + "workspaces": [ + "site" + ], + "dependencies": { + "acorn": "8.18.0", + "browserslist": "4.29.0", + "fast-glob": "^3.3.3" + }, + "bin": { + "es-check": "lib/cli/index.js" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/es-check/node_modules/acorn": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", + "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/esbuild": { "version": "0.28.2", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz", @@ -527,6 +688,156 @@ "@esbuild/win32-x64": "0.28.2" } }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.3.tgz", + "integrity": "sha512-XKv5nnLs6nLF71NgiKJLIZFLkPyIEuOselLG7ujZnGrRfQK8HpvY+WqKhAJUAdLomwVHErVS4LfxFlPq0/FTAw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/node-releases": { + "version": "2.0.63", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.63.tgz", + "integrity": "sha512-6li2QanLsAXpIH2R6j77MzRyvOyrvdTqlKtO4CgBdHGNvN99ZZfyxszHc5o5+IZBWD5u6Hzwg83JoGXmqZNG9Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/playwright": { "version": "1.64.1", "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.64.1.tgz", @@ -555,6 +866,106 @@ "engines": { "node": ">=20" } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.4.tgz", + "integrity": "sha512-t8wonIOdQyOjtPd2VktlBu6QjTVTks6v8bSi7kd0r2Vll8TK1JYDZtRRdbmCHOAMphkZgrzK+L+vXK4pyZ8t4A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } } } } diff --git a/package.json b/package.json index 9ac2b11..d5daf16 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "scripts": { "build": "node scripts/build.mjs", "test": "npm run test:syntax && npm run test:browsers", - "test:syntax": "acorn --ecma5 --silent pace.js pace.min.js", + "test:syntax": "acorn --ecma2021 --silent pace.js pace.min.js && es-check checkBrowser --checkFeatures --quiet pace.js pace.min.js", "test:browsers": "playwright test" }, "repository": { @@ -47,6 +47,7 @@ "devDependencies": { "@playwright/test": "1.64.1", "acorn": "8.19.0", + "es-check": "9.8.1", "esbuild": "0.28.2" } } diff --git a/scripts/build.mjs b/scripts/build.mjs index 38d4058..c157fc1 100644 --- a/scripts/build.mjs +++ b/scripts/build.mjs @@ -17,8 +17,11 @@ import { Color } from './color.mjs'; const root = path.resolve(import.meta.dirname, '..'); -// pace.js is ES5, and so is its minified build (as in 1.2.4). -const TARGET = 'es5'; +// The oldest browser versions in .browserslistrc ("baseline 2021 with +// downstream"). esbuild doesn't read Browserslist, so they're listed here: +// https://esbuild.github.io/api/#target. `npm test` checks the minified build +// against .browserslistrc, so the two can't drift apart unnoticed. +const TARGET = ['chrome96', 'edge96', 'firefox95', 'safari15.2', 'ios15.2']; // The 10 theme colors, from the original Gruntfile.coffee `themeColors`. const PALETTE = { From d571904fa95a08c6cc7c733c0f5cb32c1581c999 Mon Sep 17 00:00:00 2001 From: Zachary Miller Date: Sat, 7 Nov 2026 15:27:19 -0500 Subject: [PATCH 2/5] Replace CoffeeScript helpers with built-in features pace.js was compiled from CoffeeScript, which added small helper functions for things JavaScript now has built in: rest parameters instead of slicing `arguments`, Array.prototype.includes instead of an indexOf polyfill, and Function.prototype.bind. __extends stays until the classes are rewritten. No behavior changes, apart from the wording of the error thrown when ajax.trackMethods is missing (as with `Pace.start({ ajax: true })`). --- pace.js | 38 ++++++++++++++------------------------ pace.min.js | 2 +- 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/pace.js b/pace.js index 5c60305..e2578b8 100644 --- a/pace.js +++ b/pace.js @@ -5,11 +5,8 @@ */ (function() { var AjaxMonitor, Bar, DocumentMonitor, ElementMonitor, ElementTracker, EventLagMonitor, Evented, Events, NoTargetError, Pace, RequestIntercept, SOURCE_KEYS, Scaler, SocketRequestTracker, XHRRequestTracker, addEventListener, animation, avgAmplitude, bar, cancelAnimation, cancelAnimationFrame, defaultOptions, extend, extendNative, getFromDOM, getIntercept, handlePushState, ignoreStack, init, now, options, requestAnimationFrame, result, runAnimation, scalers, shouldIgnoreURL, shouldTrack, source, sources, uniScaler, _WebSocket, _XDomainRequest, _XMLHttpRequest, _i, _intercept, _len, _pushState, _ref, _ref1, _replaceState, - __slice = [].slice, __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, - __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, - __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; defaultOptions = { className: '', @@ -97,9 +94,7 @@ return tick(); }; - result = function() { - var args, key, obj; - obj = arguments[0], key = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : []; + result = function(obj, key, ...args) { if (typeof obj[key] === 'function') { return obj[key].apply(obj, args); } else { @@ -107,14 +102,13 @@ } }; - extend = function() { - var key, out, source, sources, val, _i, _len; - out = arguments[0], sources = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + extend = function(out, ...sources) { + var key, source, val, _i, _len; for (_i = 0, _len = sources.length; _i < _len; _i++) { source = sources[_i]; if (source) { for (key in source) { - if (!__hasProp.call(source, key)) continue; + if (!Object.prototype.hasOwnProperty.call(source, key)) continue; if (key === '__proto__' || key === 'constructor' || key === 'prototype') continue; val = source[key]; if ((out[key] != null) && typeof out[key] === 'object' && (val != null) && typeof val === 'object') { @@ -209,9 +203,8 @@ } }; - Evented.prototype.trigger = function() { - var args, ctx, event, handler, i, once, _ref, _ref1, _results; - event = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + Evented.prototype.trigger = function(event, ...args) { + var ctx, handler, i, once, _ref, _ref1, _results; if ((_ref = this.bindings) != null ? _ref[event] : void 0) { i = 0; _results = []; @@ -416,18 +409,16 @@ ignoreStack = []; - Pace.ignore = function() { - var args, fn, ret; - fn = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + Pace.ignore = function(fn, ...args) { + var ret; ignoreStack.unshift('ignore'); ret = fn.apply(null, args); ignoreStack.shift(); return ret; }; - Pace.track = function() { - var args, fn, ret; - fn = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + Pace.track = function(fn, ...args) { + var ret; ignoreStack.unshift('track'); ret = fn.apply(null, args); ignoreStack.shift(); @@ -435,7 +426,6 @@ }; shouldTrack = function(method) { - var _ref2; if (method == null) { method = 'GET'; } @@ -445,7 +435,7 @@ if (!ignoreStack.length && options.ajax) { if (method === 'socket' && options.ajax.trackWebSockets) { return true; - } else if (_ref2 = method.toUpperCase(), __indexOf.call(options.ajax.trackMethods, _ref2) >= 0) { + } else if (options.ajax.trackMethods.includes(method.toUpperCase())) { return true; } } @@ -588,7 +578,7 @@ AjaxMonitor = (function() { function AjaxMonitor() { - this.complete = __bind(this.complete, this); + this.complete = this.complete.bind(this); var _this = this; this.elements = []; getIntercept().on('request', function() { @@ -686,7 +676,7 @@ if (options == null) { options = {}; } - this.complete = __bind(this.complete, this); + this.complete = this.complete.bind(this); this.elements = []; if (options.selectors == null) { options.selectors = []; diff --git a/pace.min.js b/pace.min.js index d5bd368..ee9b05c 100644 --- a/pace.min.js +++ b/pace.min.js @@ -2,4 +2,4 @@ * pace.js v1.3.1 * https://github.com/CodeByZach/pace/ * Licensed MIT © HubSpot, Inc. - */(function(){var O,Y,Q,V,Z,$,ee,C,q,u,te,re,F,ne,se,E,w,ie,g,R,x,X,v,L,oe,U,D,y,ue,d,l,T,I,ae,b,H,P,p,_,W,k,M,z,A,j,le,ce,B,fe,pe,S=[].slice,he={}.hasOwnProperty,ge=function(t,e){for(var r in e)he.call(e,r)&&(t[r]=e[r]);function n(){this.constructor=t}return n.prototype=e.prototype,t.prototype=new n,t.__super__=e.prototype,t},we=[].indexOf||function(t){for(var e=0,r=this.length;e=33?(e=d(),t(n,function(){return T(r)})):setTimeout(r,33-n)},r()},I=function(){var t,e,r;return r=arguments[0],e=arguments[1],t=3<=arguments.length?S.call(arguments,2):[],typeof r[e]=="function"?r[e].apply(r,t):r[e]},v=function(){var t,e,r,n,s,i,o;for(e=arguments[0],n=2<=arguments.length?S.call(arguments,1):[],i=0,o=n.length;i=100?n="99":(n=this.progress<10?"0":"",n+=this.progress|0),e.children[0].setAttribute("data-progress",""+n)),u.trigger("change",this.progress),this.lastRenderedProgress=this.progress},t.prototype.done=function(){return this.progress>=100},t})(),C=(function(){function t(){this.bindings={}}return t.prototype.trigger=function(e,r){var n,s,i,o,a;if(this.bindings[e]!=null){for(o=this.bindings[e],a=[],s=0,i=o.length;s=0)return!0}return!1},te=(function(t){ge(e,t);function e(){var r,n=this;e.__super__.constructor.apply(this,arguments),r=function(s){var i;return i=s.open,s.open=function(o,a,f){return P(o)&&n.trigger("request",{type:o,url:a,request:s}),i.apply(s,arguments)}},window.XMLHttpRequest=function(s){var i;return i=new z(s),r(i),i};try{L(window.XMLHttpRequest,z)}catch{}if(M!=null){window.XDomainRequest=function(){var s;return s=new M,r(s),s};try{L(window.XDomainRequest,M)}catch{}}if(k!=null&&l.ajax.trackWebSockets){window.WebSocket=function(s,i){var o;return i!=null?o=new k(s,i):o=new k(s),P("socket")&&n.trigger("request",{type:"socket",url:s,protocols:i,request:o}),o};try{L(window.WebSocket,k)}catch{}}}return e})(C),j=null,U=function(){return j==null&&(j=new te),j},H=function(t){var e,r,n,s;for(s=l.ajax.ignoreURLs,r=0,n=s.length;re.sampleCount&&o.shift(),r=ie(o),++i>=e.minSamples&&r=100&&(this.done=!0),r===this.last?this.sinceLastUpdate+=e:(this.sinceLastUpdate&&(this.rate=(r-this.last)/this.sinceLastUpdate),this.catchup=(r-this.progress)/l.catchupTime,this.sinceLastUpdate=0,this.last=r),r>this.progress&&(this.progress+=this.catchup*e),n=1-Math.pow(this.progress/100,l.easeFactor),this.progress+=n*this.rate*e,this.progress=Math.min(this.lastProgress+l.maxProgressPerFrame,this.progress),this.progress=Math.max(0,this.progress),this.progress=Math.min(100,this.progress),this.lastProgress=this.progress,this.progress},t})(),_=null,b=null,g=null,W=null,w=null,R=null,u.running=!1,D=function(){if(l.restartOnPushState)return u.restart()},window.history.pushState!=null&&(ce=window.history.pushState,window.history.pushState=function(){return D(),ce.apply(window.history,arguments)}),window.history.replaceState!=null&&(pe=window.history.replaceState,window.history.replaceState=function(){return D(),pe.apply(window.history,arguments)}),re={ajax:O,elements:V,document:Q,eventLag:$},(ue=function(){var t,e,r,n,s,i,o,a;for(u.sources=_=[],i=["ajax","elements","document","eventLag"],e=0,n=i.length;e=33?(e=g(),t(n,function(){return L(r)})):setTimeout(r,33-n)},r()},D=function(t,e,...r){return typeof t[e]=="function"?t[e].apply(t,r):t[e]},v=function(t,...e){var r,n,s,i,o;for(i=0,o=e.length;i=100?n="99":(n=this.progress<10?"0":"",n+=this.progress|0),e.children[0].setAttribute("data-progress",""+n)),u.trigger("change",this.progress),this.lastRenderedProgress=this.progress},t.prototype.done=function(){return this.progress>=100},t})(),j=(function(){function t(){this.bindings={}}return t.prototype.trigger=function(e,r){var n,s,i,o,a;if(this.bindings[e]!=null){for(o=this.bindings[e],a=[],s=0,i=o.length;se.sampleCount&&o.shift(),r=se(o),++i>=e.minSamples&&r=100&&(this.done=!0),r===this.last?this.sinceLastUpdate+=e:(this.sinceLastUpdate&&(this.rate=(r-this.last)/this.sinceLastUpdate),this.catchup=(r-this.progress)/l.catchupTime,this.sinceLastUpdate=0,this.last=r),r>this.progress&&(this.progress+=this.catchup*e),n=1-Math.pow(this.progress/100,l.easeFactor),this.progress+=n*this.rate*e,this.progress=Math.min(this.lastProgress+l.maxProgressPerFrame,this.progress),this.progress=Math.max(0,this.progress),this.progress=Math.min(100,this.progress),this.lastProgress=this.progress,this.progress},t})(),_=null,b=null,d=null,H=null,w=null,E=null,u.running=!1,U=function(){if(l.restartOnPushState)return u.restart()},window.history.pushState!=null&&(le=window.history.pushState,window.history.pushState=function(){return U(),le.apply(window.history,arguments)}),window.history.replaceState!=null&&(fe=window.history.replaceState,window.history.replaceState=function(){return U(),fe.apply(window.history,arguments)}),te={ajax:O,elements:Q,document:Y,eventLag:Z},(oe=function(){var t,e,r,n,s,i,o,a;for(u.sources=_=[],i=["ajax","elements","document","eventLag"],e=0,n=i.length;e Date: Sat, 7 Nov 2026 15:33:38 -0500 Subject: [PATCH 3/5] Remove code for browsers 2.0 doesn't support Every supported browser has these, so the fallbacks never run: - performance.now() (no Date fallback) - unprefixed requestAnimationFrame and cancelAnimationFrame (no prefixed versions or setTimeout fallback) - addEventListener on XHR and WebSocket objects (no on fallback) - XHR progress events (no onreadystatechange fallback) - the unprefixed transform property (no webkitTransform or msTransform) - Object.defineProperty, WebSocket, history.pushState/replaceState, console XDomainRequest only existed in Internet Explorer, so pace no longer wraps it. requestAnimationFrame and cancelAnimationFrame are still saved when pace loads, so a later replacement of window.requestAnimationFrame (zone.js patches it, for example) doesn't change what pace calls. No behavior changes. --- pace.js | 161 ++++++++++++++-------------------------------------- pace.min.js | 2 +- 2 files changed, 44 insertions(+), 119 deletions(-) diff --git a/pace.js b/pace.js index e2578b8..52a418d 100644 --- a/pace.js +++ b/pace.js @@ -4,7 +4,7 @@ * Licensed MIT © HubSpot, Inc. */ (function() { - var AjaxMonitor, Bar, DocumentMonitor, ElementMonitor, ElementTracker, EventLagMonitor, Evented, Events, NoTargetError, Pace, RequestIntercept, SOURCE_KEYS, Scaler, SocketRequestTracker, XHRRequestTracker, addEventListener, animation, avgAmplitude, bar, cancelAnimation, cancelAnimationFrame, defaultOptions, extend, extendNative, getFromDOM, getIntercept, handlePushState, ignoreStack, init, now, options, requestAnimationFrame, result, runAnimation, scalers, shouldIgnoreURL, shouldTrack, source, sources, uniScaler, _WebSocket, _XDomainRequest, _XMLHttpRequest, _i, _intercept, _len, _pushState, _ref, _ref1, _replaceState, + var AjaxMonitor, Bar, DocumentMonitor, ElementMonitor, ElementTracker, EventLagMonitor, Evented, Events, NoTargetError, Pace, RequestIntercept, SOURCE_KEYS, Scaler, SocketRequestTracker, XHRRequestTracker, animation, avgAmplitude, bar, cancelAnimation, cancelAnimationFrame, defaultOptions, extend, extendNative, getFromDOM, getIntercept, handlePushState, ignoreStack, init, now, options, requestAnimationFrame, result, runAnimation, scalers, shouldIgnoreURL, shouldTrack, source, sources, uniScaler, _WebSocket, _XMLHttpRequest, _i, _intercept, _len, _pushState, _ref, _ref1, _replaceState, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; @@ -37,44 +37,12 @@ }; now = function() { - var _ref; - return (_ref = typeof performance !== "undefined" && performance !== null ? typeof performance.now === "function" ? performance.now() : void 0 : void 0) != null ? _ref : +(new Date); + return performance.now(); }; - requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; + requestAnimationFrame = window.requestAnimationFrame; - cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame; - - addEventListener = function(obj, event, callback) { - if (typeof obj.addEventListener === "function") { - return obj.addEventListener(event, callback, false); - } else { - return function() { - if (typeof obj["on" + event] !== "function" || typeof obj["on" + event].eventListeners !== "object") { - var eventListeners = new Events(); - if (typeof obj["on" + event] === "function") { - eventListeners.on(event, obj["on" + event]); - } - obj["on" + event] = function(evt) { - return eventListeners.trigger(event, evt); - }; - obj["on" + event].eventListeners = eventListeners; - } else { - var eventListeners = obj["on" + event].eventListeners; - } - eventListeners.on(event, callback); - }(); - } - }; - - if (requestAnimationFrame == null) { - requestAnimationFrame = function(fn) { - return setTimeout(fn, 50); - }; - cancelAnimationFrame = function(id) { - return clearTimeout(id); - }; - } + cancelAnimationFrame = window.cancelAnimationFrame; runAnimation = function(fn) { var last, tick; @@ -153,7 +121,7 @@ return JSON.parse(data); } catch (_error) { e = _error; - return typeof console !== "undefined" && console !== null ? console.error("Error parsing inline pace options", e) : void 0; + return console.error("Error parsing inline pace options", e); } }; @@ -309,17 +277,12 @@ }; Bar.prototype.render = function() { - var el, key, progressStr, transform, _j, _len1, _ref2; + var el, progressStr; if (document.querySelector(options.target) == null) { return false; } el = this.getElement(); - transform = "translate3d(" + this.progress + "%, 0, 0)"; - _ref2 = ['webkitTransform', 'msTransform', 'transform']; - for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { - key = _ref2[_j]; - el.children[0].style[key] = transform; - } + el.children[0].style.transform = "translate3d(" + this.progress + "%, 0, 0)"; if (!this.lastRenderedProgress || this.lastRenderedProgress | 0 !== this.progress | 0) { el.children[0].setAttribute('data-progress-text', "" + (this.progress | 0) + "%"); if (this.progress >= 100) { @@ -374,8 +337,6 @@ _XMLHttpRequest = window.XMLHttpRequest; - _XDomainRequest = window.XDomainRequest; - _WebSocket = window.WebSocket; extendNative = function(to, from) { @@ -384,19 +345,15 @@ for (key in from.prototype) { try { if ((to[key] == null) && typeof from[key] !== 'function') { - if (typeof Object.defineProperty === 'function') { - _results.push(Object.defineProperty(to, key, { - get: (function(key) { - return function() { - return from.prototype[key]; - }; - })(key), - configurable: true, - enumerable: true - })); - } else { - _results.push(to[key] = from.prototype[key]); - } + _results.push(Object.defineProperty(to, key, { + get: (function(key) { + return function() { + return from.prototype[key]; + }; + })(key), + configurable: true, + enumerable: true + })); } else { _results.push(void 0); } @@ -472,18 +429,7 @@ try { extendNative(window.XMLHttpRequest, _XMLHttpRequest); } catch (_error) {} - if (_XDomainRequest != null) { - window.XDomainRequest = function() { - var req; - req = new _XDomainRequest; - monitorXHR(req); - return req; - }; - try { - extendNative(window.XDomainRequest, _XDomainRequest); - } catch (_error) {} - } - if ((_WebSocket != null) && options.ajax.trackWebSockets) { + if (options.ajax.trackWebSockets) { window.WebSocket = function(url, protocols) { var req; if (protocols != null) { @@ -612,38 +558,23 @@ XHRRequestTracker = (function() { function XHRRequestTracker(request, completeCallback) { - var event, size, _j, _len1, _onreadystatechange, _ref2, + var event, _j, _len1, _ref2, _this = this; this.progress = 0; - if (window.ProgressEvent != null) { - size = null; - addEventListener(request, 'progress', function(evt) { - if (evt.lengthComputable) { - return _this.progress = 100 * evt.loaded / evt.total; - } else { - return _this.progress = _this.progress + (100 - _this.progress) / 2; - } - }, false); - _ref2 = ['load', 'abort', 'timeout', 'error']; - for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { - event = _ref2[_j]; - addEventListener(request, event, function() { - completeCallback(_this); - return _this.progress = 100; - }, false); + request.addEventListener('progress', function(evt) { + if (evt.lengthComputable) { + return _this.progress = 100 * evt.loaded / evt.total; + } else { + return _this.progress = _this.progress + (100 - _this.progress) / 2; } - } else { - _onreadystatechange = request.onreadystatechange; - request.onreadystatechange = function() { - var _ref3; - if ((_ref3 = request.readyState) === 0 || _ref3 === 4) { - completeCallback(_this); - _this.progress = 100; - } else if (request.readyState === 3) { - _this.progress = 50; - } - return typeof _onreadystatechange === "function" ? _onreadystatechange.apply(null, arguments) : void 0; - }; + }, false); + _ref2 = ['load', 'abort', 'timeout', 'error']; + for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { + event = _ref2[_j]; + request.addEventListener(event, function() { + completeCallback(_this); + return _this.progress = 100; + }, false); } } @@ -659,7 +590,7 @@ _ref2 = ['error', 'open']; for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { event = _ref2[_j]; - addEventListener(request, event, function() { + request.addEventListener(event, function() { completeCallback(_this); return _this.progress = 100; }, false); @@ -848,21 +779,17 @@ } }; - if (window.history.pushState != null) { - _pushState = window.history.pushState; - window.history.pushState = function() { - handlePushState(); - return _pushState.apply(window.history, arguments); - }; - } + _pushState = window.history.pushState; + window.history.pushState = function() { + handlePushState(); + return _pushState.apply(window.history, arguments); + }; - if (window.history.replaceState != null) { - _replaceState = window.history.replaceState; - window.history.replaceState = function() { - handlePushState(); - return _replaceState.apply(window.history, arguments); - }; - } + _replaceState = window.history.replaceState; + window.history.replaceState = function() { + handlePushState(); + return _replaceState.apply(window.history, arguments); + }; SOURCE_KEYS = { ajax: AjaxMonitor, @@ -897,9 +824,7 @@ bar.destroy(); cancelAnimation = true; if (animation != null) { - if (typeof cancelAnimationFrame === "function") { - cancelAnimationFrame(animation); - } + cancelAnimationFrame(animation); animation = null; } return init(); diff --git a/pace.min.js b/pace.min.js index ee9b05c..39d89ce 100644 --- a/pace.min.js +++ b/pace.min.js @@ -2,4 +2,4 @@ * pace.js v1.3.1 * https://github.com/CodeByZach/pace/ * Licensed MIT © HubSpot, Inc. - */(function(){var O,K,Y,Q,V,Z,$,j,k,u,ee,te,C,re,ne,q,w,se,d,E,R,F,v,x,ie,X,U,y,oe,g,l,L,D,ue,b,I,T,p,_,H,S,P,W,M,A,ae,le,z,ce,fe,me={}.hasOwnProperty,pe=function(t,e){for(var r in e)me.call(e,r)&&(t[r]=e[r]);function n(){this.constructor=t}return n.prototype=e.prototype,t.prototype=new n,t.__super__=e.prototype,t};for(F={className:"",catchupTime:100,initialRate:.03,minTime:250,ghostTime:100,maxProgressPerFrame:20,easeFactor:1.25,startOnPageLoad:!0,restartOnPushState:!0,restartOnRequestAfter:500,target:"body",elements:{checkInterval:100,selectors:["body"]},eventLag:{minSamples:10,sampleCount:3,lagThreshold:3},ajax:{trackMethods:["GET"],trackWebSockets:!0,ignoreURLs:[]}},g=function(){var t;return(t=typeof performance<"u"&&performance!==null&&typeof performance.now=="function"?performance.now():void 0)!=null?t:+new Date},L=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame,R=window.cancelAnimationFrame||window.mozCancelAnimationFrame,q=function(t,e,r){return typeof t.addEventListener=="function"?t.addEventListener(e,r,!1):(function(){if(typeof t["on"+e]!="function"||typeof t["on"+e].eventListeners!="object"){var n=new j;typeof t["on"+e]=="function"&&n.on(e,t["on"+e]),t["on"+e]=function(s){return n.trigger(e,s)},t["on"+e].eventListeners=n}else var n=t["on"+e].eventListeners;n.on(e,r)})()},L==null&&(L=function(t){return setTimeout(t,50)},R=function(t){return clearTimeout(t)}),ue=function(t){var e,r;return e=g(),r=function(){var n;return n=g()-e,n>=33?(e=g(),t(n,function(){return L(r)})):setTimeout(r,33-n)},r()},D=function(t,e,...r){return typeof t[e]=="function"?t[e].apply(t,r):t[e]},v=function(t,...e){var r,n,s,i,o;for(i=0,o=e.length;i=100?n="99":(n=this.progress<10?"0":"",n+=this.progress|0),e.children[0].setAttribute("data-progress",""+n)),u.trigger("change",this.progress),this.lastRenderedProgress=this.progress},t.prototype.done=function(){return this.progress>=100},t})(),j=(function(){function t(){this.bindings={}}return t.prototype.trigger=function(e,r){var n,s,i,o,a;if(this.bindings[e]!=null){for(o=this.bindings[e],a=[],s=0,i=o.length;se.sampleCount&&o.shift(),r=se(o),++i>=e.minSamples&&r=100&&(this.done=!0),r===this.last?this.sinceLastUpdate+=e:(this.sinceLastUpdate&&(this.rate=(r-this.last)/this.sinceLastUpdate),this.catchup=(r-this.progress)/l.catchupTime,this.sinceLastUpdate=0,this.last=r),r>this.progress&&(this.progress+=this.catchup*e),n=1-Math.pow(this.progress/100,l.easeFactor),this.progress+=n*this.rate*e,this.progress=Math.min(this.lastProgress+l.maxProgressPerFrame,this.progress),this.progress=Math.max(0,this.progress),this.progress=Math.min(100,this.progress),this.lastProgress=this.progress,this.progress},t})(),_=null,b=null,d=null,H=null,w=null,E=null,u.running=!1,U=function(){if(l.restartOnPushState)return u.restart()},window.history.pushState!=null&&(le=window.history.pushState,window.history.pushState=function(){return U(),le.apply(window.history,arguments)}),window.history.replaceState!=null&&(fe=window.history.replaceState,window.history.replaceState=function(){return U(),fe.apply(window.history,arguments)}),te={ajax:O,elements:Q,document:Y,eventLag:Z},(oe=function(){var t,e,r,n,s,i,o,a;for(u.sources=_=[],i=["ajax","elements","document","eventLag"],e=0,n=i.length;e=33?(e=g(),r(n,function(){return se(t)})):setTimeout(t,33-n)},t()},A=function(r,e,...t){return typeof r[e]=="function"?r[e].apply(r,t):r[e]},v=function(r,...e){var t,n,s,i,o;for(i=0,o=e.length;i=100?t="99":(t=this.progress<10?"0":"",t+=this.progress|0),e.children[0].setAttribute("data-progress",""+t)),u.trigger("change",this.progress),this.lastRenderedProgress=this.progress)},r.prototype.done=function(){return this.progress>=100},r})(),z=(function(){function r(){this.bindings={}}return r.prototype.trigger=function(e,t){var n,s,i,o,a;if(this.bindings[e]!=null){for(o=this.bindings[e],a=[],s=0,i=o.length;se.sampleCount&&o.shift(),t=ee(o),++i>=e.minSamples&&t=100&&(this.done=!0),t===this.last?this.sinceLastUpdate+=e:(this.sinceLastUpdate&&(this.rate=(t-this.last)/this.sinceLastUpdate),this.catchup=(t-this.progress)/l.catchupTime,this.sinceLastUpdate=0,this.last=t),t>this.progress&&(this.progress+=this.catchup*e),n=1-Math.pow(this.progress/100,l.easeFactor),this.progress+=n*this.rate*e,this.progress=Math.min(this.lastProgress+l.maxProgressPerFrame,this.progress),this.progress=Math.max(0,this.progress),this.progress=Math.min(100,this.progress),this.lastProgress=this.progress,this.progress},r})(),y=null,w=null,h=null,U=null,_=null,S=null,u.running=!1,O=function(){if(l.restartOnPushState)return u.restart()},ue=window.history.pushState,window.history.pushState=function(){return O(),ue.apply(window.history,arguments)},le=window.history.replaceState,window.history.replaceState=function(){return O(),le.apply(window.history,arguments)},V={ajax:M,elements:G,document:D,eventLag:K},(ne=function(){var r,e,t,n,s,i,o,a;for(u.sources=y=[],i=["ajax","elements","document","eventLag"],e=0,n=i.length;e Date: Sat, 7 Nov 2026 16:02:09 -0500 Subject: [PATCH 4/5] Rewrite pace.js in modern JavaScript Replaces the CoffeeScript output with ES2021: classes instead of prototype functions and __extends, const/let, arrow functions instead of `_this`, and destructuring, optional chaining and ??= instead of temporary variables. The logic is unchanged, including its known bugs, which get fixed separately with tests. Kept as before on purpose: - Loops over options and sources read the length once and index into the list, so non-array values (`extraSources: false`, an HTMLCollection as a source's elements) are handled exactly as before. - The XHR and WebSocket wrappers are installed outside a class body, so a read-only window.XMLHttpRequest is still skipped silently instead of throwing in strict mode. - requestAnimationFrame is still read once, when pace loads. Small differences: - Pace.on/once/off/trigger/start/stop/restart/go, and the methods of Pace.bar and Pace.sources, no longer return CoffeeScript's leftover values (array lengths, timer ids, class names). Pace.track and Pace.ignore still return the callback's result. - Methods of Pace.bar and Pace.sources are class methods, so `for...in` no longer lists them. - The error thrown when the target element is missing is a NoTargetError instead of a plain Error. --- pace.js | 871 +++++++++++++++++++++------------------------------- pace.min.js | 2 +- 2 files changed, 345 insertions(+), 528 deletions(-) diff --git a/pace.js b/pace.js index 52a418d..c5e4770 100644 --- a/pace.js +++ b/pace.js @@ -3,15 +3,11 @@ * https://github.com/CodeByZach/pace/ * Licensed MIT © HubSpot, Inc. */ -(function() { - var AjaxMonitor, Bar, DocumentMonitor, ElementMonitor, ElementTracker, EventLagMonitor, Evented, Events, NoTargetError, Pace, RequestIntercept, SOURCE_KEYS, Scaler, SocketRequestTracker, XHRRequestTracker, animation, avgAmplitude, bar, cancelAnimation, cancelAnimationFrame, defaultOptions, extend, extendNative, getFromDOM, getIntercept, handlePushState, ignoreStack, init, now, options, requestAnimationFrame, result, runAnimation, scalers, shouldIgnoreURL, shouldTrack, source, sources, uniScaler, _WebSocket, _XMLHttpRequest, _i, _intercept, _len, _pushState, _ref, _ref1, _replaceState, - __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; - - defaultOptions = { +(function () { + const defaultOptions = { className: '', catchupTime: 100, - initialRate: .03, + initialRate: 0.03, minTime: 250, ghostTime: 100, maxProgressPerFrame: 20, @@ -22,226 +18,171 @@ target: 'body', elements: { checkInterval: 100, - selectors: ['body'] + selectors: ['body'], }, eventLag: { minSamples: 10, sampleCount: 3, - lagThreshold: 3 + lagThreshold: 3, }, ajax: { trackMethods: ['GET'], trackWebSockets: true, - ignoreURLs: [] - } - }; - - now = function() { - return performance.now(); + ignoreURLs: [], + }, }; - requestAnimationFrame = window.requestAnimationFrame; + const now = () => performance.now(); - cancelAnimationFrame = window.cancelAnimationFrame; + const requestAnimationFrame = window.requestAnimationFrame; + const cancelAnimationFrame = window.cancelAnimationFrame; - runAnimation = function(fn) { - var last, tick; - last = now(); - tick = function() { - var diff; - diff = now() - last; + const runAnimation = (fn) => { + let last = now(); + const tick = () => { + const diff = now() - last; if (diff >= 33) { last = now(); - return fn(diff, function() { - return requestAnimationFrame(tick); - }); - } else { - return setTimeout(tick, 33 - diff); + return fn(diff, () => requestAnimationFrame(tick)); } + return setTimeout(tick, 33 - diff); }; return tick(); }; - result = function(obj, key, ...args) { + const result = (obj, key, ...args) => { if (typeof obj[key] === 'function') { return obj[key].apply(obj, args); - } else { - return obj[key]; } + return obj[key]; }; - extend = function(out, ...sources) { - var key, source, val, _i, _len; - for (_i = 0, _len = sources.length; _i < _len; _i++) { - source = sources[_i]; - if (source) { - for (key in source) { - if (!Object.prototype.hasOwnProperty.call(source, key)) continue; - if (key === '__proto__' || key === 'constructor' || key === 'prototype') continue; - val = source[key]; - if ((out[key] != null) && typeof out[key] === 'object' && (val != null) && typeof val === 'object') { - extend(out[key], val); - } else { - out[key] = val; - } + const extend = (out, ...sources) => { + for (const source of sources) { + if (!source) { + continue; + } + for (const key in source) { + if (!Object.prototype.hasOwnProperty.call(source, key)) continue; + if (key === '__proto__' || key === 'constructor' || key === 'prototype') continue; + const val = source[key]; + if (out[key] != null && typeof out[key] === 'object' && val != null && typeof val === 'object') { + extend(out[key], val); + } else { + out[key] = val; } } } return out; }; - avgAmplitude = function(arr) { - var count, sum, v, _i, _len; - sum = count = 0; - for (_i = 0, _len = arr.length; _i < _len; _i++) { - v = arr[_i]; + const avgAmplitude = (arr) => { + let sum = 0; + let count = 0; + for (const v of arr) { sum += Math.abs(v); count++; } return sum / count; }; - getFromDOM = function(key, json) { - var data, e, el; - if (key == null) { - key = 'options'; - } - if (json == null) { - json = true; - } - el = document.querySelector("script[data-pace-" + key + "]"); + const getFromDOM = (key = 'options', json = true) => { + const el = document.querySelector(`script[data-pace-${key}]`); if (!el) { return; } - data = el.getAttribute("data-pace-" + key); + const data = el.getAttribute(`data-pace-${key}`); if (!json) { return data; } try { return JSON.parse(data); - } catch (_error) { - e = _error; - return console.error("Error parsing inline pace options", e); + } catch (e) { + console.error('Error parsing inline pace options', e); } }; - Evented = (function() { - function Evented() {} + const Pace = window.Pace || {}; - Evented.prototype.on = function(event, handler, ctx, once) { - var _base; - if (once == null) { - once = false; - } - if (this.bindings == null) { - this.bindings = {}; - } - if ((_base = this.bindings)[event] == null) { - _base[event] = []; - } - return this.bindings[event].push({ - handler: handler, - ctx: ctx, - once: once - }); - }; + window.Pace = Pace; - Evented.prototype.once = function(event, handler, ctx) { - return this.on(event, handler, ctx, true); - }; + Object.assign(Pace, { + on(event, handler, ctx, once) { + once ??= false; + this.bindings ??= {}; + this.bindings[event] ??= []; + this.bindings[event].push({ handler, ctx, once }); + }, - Evented.prototype.off = function(event, handler) { - var i, _ref, _results; - if (((_ref = this.bindings) != null ? _ref[event] : void 0) == null) { + once(event, handler, ctx) { + this.on(event, handler, ctx, true); + }, + + off(event, handler) { + if (this.bindings?.[event] == null) { return; } if (handler == null) { - return delete this.bindings[event]; - } else { - i = 0; - _results = []; - while (i < this.bindings[event].length) { - if (this.bindings[event][i].handler === handler) { - _results.push(this.bindings[event].splice(i, 1)); - } else { - _results.push(i++); - } + delete this.bindings[event]; + return; + } + let i = 0; + while (i < this.bindings[event].length) { + if (this.bindings[event][i].handler === handler) { + this.bindings[event].splice(i, 1); + } else { + i++; } - return _results; } - }; + }, - Evented.prototype.trigger = function(event, ...args) { - var ctx, handler, i, once, _ref, _ref1, _results; - if ((_ref = this.bindings) != null ? _ref[event] : void 0) { - i = 0; - _results = []; - while (i < this.bindings[event].length) { - _ref1 = this.bindings[event][i], handler = _ref1.handler, ctx = _ref1.ctx, once = _ref1.once; - handler.apply(ctx != null ? ctx : this, args); - if (once) { - _results.push(this.bindings[event].splice(i, 1)); - } else { - _results.push(i++); - } + trigger(event, ...args) { + if (!this.bindings?.[event]) { + return; + } + let i = 0; + while (i < this.bindings[event].length) { + const { handler, ctx, once } = this.bindings[event][i]; + handler.apply(ctx ?? this, args); + if (once) { + this.bindings[event].splice(i, 1); + } else { + i++; } - return _results; } - }; - - return Evented; - - })(); - - Pace = window.Pace || {}; - - window.Pace = Pace; - - extend(Pace, Evented.prototype); + }, + }); - options = Pace.options = extend({}, defaultOptions, window.paceOptions, getFromDOM()); + const options = (Pace.options = extend({}, defaultOptions, window.paceOptions, getFromDOM())); - _ref = ['ajax', 'document', 'eventLag', 'elements']; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - source = _ref[_i]; - if (options[source] === true) { - options[source] = defaultOptions[source]; + for (const key of ['ajax', 'document', 'eventLag', 'elements']) { + if (options[key] === true) { + options[key] = defaultOptions[key]; } } - NoTargetError = (function(_super) { - __extends(NoTargetError, _super); + class NoTargetError extends Error {} - function NoTargetError() { - _ref1 = NoTargetError.__super__.constructor.apply(this, arguments); - return _ref1; - } - - return NoTargetError; - - })(Error); - - Bar = (function() { - function Bar() { + class Bar { + constructor() { this.progress = 0; } - Bar.prototype.getElement = function() { - var activity, inner, progress, targetElement; + getElement() { if (this.el == null) { - targetElement = document.querySelector(options.target); + const targetElement = document.querySelector(options.target); if (!targetElement) { - throw new NoTargetError; + throw new NoTargetError(); } this.el = document.createElement('div'); - this.el.className = "pace pace-active"; + this.el.className = 'pace pace-active'; document.body.className = document.body.className.replace(/(pace-done )|/, 'pace-running '); - progress = document.createElement('div'); + const progress = document.createElement('div'); progress.className = 'pace-progress' + (options.className !== '' ? ' ' + options.className : ''); - inner = document.createElement('div'); + const inner = document.createElement('div'); inner.className = 'pace-progress-inner'; progress.appendChild(inner); - activity = document.createElement('div'); + const activity = document.createElement('div'); activity.className = 'pace-activity'; this.el.appendChild(progress); this.el.appendChild(activity); @@ -252,140 +193,111 @@ } } return this.el; - }; + } - Bar.prototype.finish = function() { - var el; - el = this.getElement(); + finish() { + const el = this.getElement(); el.className = el.className.replace('pace-active', 'pace-inactive'); - return document.body.className = document.body.className.replace('pace-running ', 'pace-done '); - }; + document.body.className = document.body.className.replace('pace-running ', 'pace-done '); + } - Bar.prototype.update = function(prog) { + update(prog) { this.progress = prog; Pace.trigger('progress', prog); - return this.render(); - }; + this.render(); + } - Bar.prototype.destroy = function() { + destroy() { try { this.getElement().parentNode.removeChild(this.getElement()); - } catch (_error) { - NoTargetError = _error; + } catch (error) { + NoTargetError = error; } - return this.el = void 0; - }; + this.el = undefined; + } - Bar.prototype.render = function() { - var el, progressStr; + render() { if (document.querySelector(options.target) == null) { - return false; + return; } - el = this.getElement(); - el.children[0].style.transform = "translate3d(" + this.progress + "%, 0, 0)"; + const el = this.getElement(); + el.children[0].style.transform = `translate3d(${this.progress}%, 0, 0)`; if (!this.lastRenderedProgress || this.lastRenderedProgress | 0 !== this.progress | 0) { - el.children[0].setAttribute('data-progress-text', "" + (this.progress | 0) + "%"); + el.children[0].setAttribute('data-progress-text', `${this.progress | 0}%`); + let progressStr; if (this.progress >= 100) { progressStr = '99'; } else { - progressStr = this.progress < 10 ? "0" : ""; + progressStr = this.progress < 10 ? '0' : ''; progressStr += this.progress | 0; } - el.children[0].setAttribute('data-progress', "" + progressStr); + el.children[0].setAttribute('data-progress', progressStr); } Pace.trigger('change', this.progress); - return this.lastRenderedProgress = this.progress; - }; + this.lastRenderedProgress = this.progress; + } - Bar.prototype.done = function() { + done() { return this.progress >= 100; - }; - - return Bar; - - })(); + } + } - Events = (function() { - function Events() { + class Events { + constructor() { this.bindings = {}; } - Events.prototype.trigger = function(name, val) { - var binding, _j, _len1, _ref2, _results; + trigger(name, val) { if (this.bindings[name] != null) { - _ref2 = this.bindings[name]; - _results = []; - for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { - binding = _ref2[_j]; - _results.push(binding.call(this, val)); + // A copy, so listeners added while this runs wait for the next trigger. + for (const binding of this.bindings[name].slice()) { + binding.call(this, val); } - return _results; - } - }; - - Events.prototype.on = function(name, fn) { - var _base; - if ((_base = this.bindings)[name] == null) { - _base[name] = []; } - return this.bindings[name].push(fn); - }; - - return Events; + } - })(); + on(name, fn) { + this.bindings[name] ??= []; + this.bindings[name].push(fn); + } + } - _XMLHttpRequest = window.XMLHttpRequest; + const _XMLHttpRequest = window.XMLHttpRequest; - _WebSocket = window.WebSocket; + const _WebSocket = window.WebSocket; - extendNative = function(to, from) { - var e, key, _results; - _results = []; - for (key in from.prototype) { + const extendNative = (to, from) => { + for (const key in from.prototype) { try { - if ((to[key] == null) && typeof from[key] !== 'function') { - _results.push(Object.defineProperty(to, key, { - get: (function(key) { - return function() { - return from.prototype[key]; - }; - })(key), + if (to[key] == null && typeof from[key] !== 'function') { + Object.defineProperty(to, key, { + get: () => from.prototype[key], configurable: true, - enumerable: true - })); - } else { - _results.push(void 0); + enumerable: true, + }); } - } catch (_error) { - e = _error; - } + } catch {} } - return _results; }; - ignoreStack = []; + const ignoreStack = []; - Pace.ignore = function(fn, ...args) { - var ret; + Pace.ignore = (fn, ...args) => { ignoreStack.unshift('ignore'); - ret = fn.apply(null, args); + const ret = fn.apply(null, args); ignoreStack.shift(); return ret; }; - Pace.track = function(fn, ...args) { - var ret; + Pace.track = (fn, ...args) => { ignoreStack.unshift('track'); - ret = fn.apply(null, args); + const ret = fn.apply(null, args); ignoreStack.shift(); return ret; }; - shouldTrack = function(method) { - if (method == null) { - method = 'GET'; - } + const shouldTrack = (method) => { + method ??= 'GET'; if (ignoreStack[0] === 'track') { return 'force'; } @@ -399,301 +311,231 @@ return false; }; - RequestIntercept = (function(_super) { - __extends(RequestIntercept, _super); - - function RequestIntercept() { - var monitorXHR, - _this = this; - RequestIntercept.__super__.constructor.apply(this, arguments); - monitorXHR = function(req) { - var _open; - _open = req.open; - return req.open = function(type, url, async) { - if (shouldTrack(type)) { - _this.trigger('request', { - type: type, - url: url, - request: req - }); - } - return _open.apply(req, arguments); - }; + // Outside the class on purpose: class bodies are strict mode, where assigning + // to a read-only property (a page may lock window.XMLHttpRequest) throws. + const installIntercepts = (intercept) => { + const monitorXHR = (req) => { + const _open = req.open; + req.open = (...args) => { + const [type, url] = args; + if (shouldTrack(type)) { + intercept.trigger('request', { type, url, request: req }); + } + return _open.apply(req, args); }; - window.XMLHttpRequest = function(flags) { - var req; - req = new _XMLHttpRequest(flags); - monitorXHR(req); + }; + // Plain functions, not arrow functions: pages call these with `new`. + window.XMLHttpRequest = function (flags) { + const req = new _XMLHttpRequest(flags); + monitorXHR(req); + return req; + }; + try { + extendNative(window.XMLHttpRequest, _XMLHttpRequest); + } catch {} + if (options.ajax.trackWebSockets) { + window.WebSocket = function (url, protocols) { + let req; + if (protocols != null) { + req = new _WebSocket(url, protocols); + } else { + req = new _WebSocket(url); + } + if (shouldTrack('socket')) { + intercept.trigger('request', { type: 'socket', url, protocols, request: req }); + } return req; }; try { - extendNative(window.XMLHttpRequest, _XMLHttpRequest); - } catch (_error) {} - if (options.ajax.trackWebSockets) { - window.WebSocket = function(url, protocols) { - var req; - if (protocols != null) { - req = new _WebSocket(url, protocols); - } else { - req = new _WebSocket(url); - } - if (shouldTrack('socket')) { - _this.trigger('request', { - type: 'socket', - url: url, - protocols: protocols, - request: req - }); - } - return req; - }; - try { - extendNative(window.WebSocket, _WebSocket); - } catch (_error) {} - } + extendNative(window.WebSocket, _WebSocket); + } catch {} } + }; - return RequestIntercept; - - })(Events); + class RequestIntercept extends Events { + constructor() { + super(); + installIntercepts(this); + } + } - _intercept = null; + let _intercept = null; - getIntercept = function() { - if (_intercept == null) { - _intercept = new RequestIntercept; - } + const getIntercept = () => { + _intercept ??= new RequestIntercept(); return _intercept; }; - shouldIgnoreURL = function(url) { - var pattern, _j, _len1, _ref2; - _ref2 = options.ajax.ignoreURLs; - for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { - pattern = _ref2[_j]; + const shouldIgnoreURL = (url) => { + const patterns = options.ajax.ignoreURLs; + for (let i = 0, n = patterns.length; i < n; i++) { + const pattern = patterns[i]; if (typeof pattern === 'string') { if (url.indexOf(pattern) !== -1) { return true; } - } else { - if (pattern.test(url)) { - return true; - } + } else if (pattern.test(url)) { + return true; } } return false; }; - getIntercept().on('request', function(_arg) { - var after, args, request, type, url; - type = _arg.type, request = _arg.request, url = _arg.url; + getIntercept().on('request', (event) => { + const { type, request, url } = event; if (shouldIgnoreURL(url)) { return; } if (!Pace.running && (options.restartOnRequestAfter !== false || shouldTrack(type) === 'force')) { - args = arguments; - after = options.restartOnRequestAfter || 0; + let after = options.restartOnRequestAfter || 0; if (typeof after === 'boolean') { after = 0; } - return setTimeout(function() { - var stillActive, _j, _len1, _ref2, _ref3, _results; + setTimeout(() => { + let stillActive; if (type === 'socket') { stillActive = request.readyState < 1; } else { - stillActive = (0 < (_ref2 = request.readyState) && _ref2 < 4); + stillActive = 0 < request.readyState && request.readyState < 4; } if (stillActive) { Pace.restart(); - _ref3 = Pace.sources; - _results = []; - for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) { - source = _ref3[_j]; + for (let i = 0, n = Pace.sources.length; i < n; i++) { + const source = Pace.sources[i]; if (source instanceof AjaxMonitor) { - source.watch.apply(source, args); + source.watch(event); break; - } else { - _results.push(void 0); } } - return _results; } }, after); } }); - AjaxMonitor = (function() { - function AjaxMonitor() { + class AjaxMonitor { + constructor() { this.complete = this.complete.bind(this); - var _this = this; this.elements = []; - getIntercept().on('request', function() { - return _this.watch.apply(_this, arguments); - }); + getIntercept().on('request', (event) => this.watch(event)); } - AjaxMonitor.prototype.watch = function(_arg) { - var request, tracker, type, url; - type = _arg.type, request = _arg.request, url = _arg.url; + watch({ type, request, url }) { if (shouldIgnoreURL(url)) { return; } + let tracker; if (type === 'socket') { tracker = new SocketRequestTracker(request, this.complete); } else { tracker = new XHRRequestTracker(request, this.complete); } - return this.elements.push(tracker); - }; - - AjaxMonitor.prototype.complete = function(tracker) { - return this.elements = this.elements.filter(function(e) { - return e !== tracker; - }); - }; - - return AjaxMonitor; + this.elements.push(tracker); + } - })(); + complete(tracker) { + this.elements = this.elements.filter((e) => e !== tracker); + } + } - XHRRequestTracker = (function() { - function XHRRequestTracker(request, completeCallback) { - var event, _j, _len1, _ref2, - _this = this; + class XHRRequestTracker { + constructor(request, completeCallback) { this.progress = 0; - request.addEventListener('progress', function(evt) { + request.addEventListener('progress', (evt) => { if (evt.lengthComputable) { - return _this.progress = 100 * evt.loaded / evt.total; + this.progress = (100 * evt.loaded) / evt.total; } else { - return _this.progress = _this.progress + (100 - _this.progress) / 2; + this.progress = this.progress + (100 - this.progress) / 2; } }, false); - _ref2 = ['load', 'abort', 'timeout', 'error']; - for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { - event = _ref2[_j]; - request.addEventListener(event, function() { - completeCallback(_this); - return _this.progress = 100; + for (const event of ['load', 'abort', 'timeout', 'error']) { + request.addEventListener(event, () => { + completeCallback(this); + this.progress = 100; }, false); } } + } - return XHRRequestTracker; - - })(); - - SocketRequestTracker = (function() { - function SocketRequestTracker(request, completeCallback) { - var event, _j, _len1, _ref2, - _this = this; + class SocketRequestTracker { + constructor(request, completeCallback) { this.progress = 0; - _ref2 = ['error', 'open']; - for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { - event = _ref2[_j]; - request.addEventListener(event, function() { - completeCallback(_this); - return _this.progress = 100; + for (const event of ['error', 'open']) { + request.addEventListener(event, () => { + completeCallback(this); + this.progress = 100; }, false); } } + } - return SocketRequestTracker; - - })(); - - ElementMonitor = (function() { - function ElementMonitor(options) { - var selector, _j, _len1, _ref2; - if (options == null) { - options = {}; - } + class ElementMonitor { + constructor(settings) { + settings ??= {}; this.complete = this.complete.bind(this); this.elements = []; - if (options.selectors == null) { - options.selectors = []; - } - _ref2 = options.selectors; - for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { - selector = _ref2[_j]; - this.elements.push(new ElementTracker(selector, this.complete)); + settings.selectors ??= []; + const selectors = settings.selectors; + for (let i = 0, n = selectors.length; i < n; i++) { + this.elements.push(new ElementTracker(selectors[i], this.complete)); } } - ElementMonitor.prototype.complete = function(tracker) { - return this.elements = this.elements.filter(function(e) { - return e !== tracker; - }); - }; - - return ElementMonitor; - - })(); + complete(tracker) { + this.elements = this.elements.filter((e) => e !== tracker); + } + } - ElementTracker = (function() { - function ElementTracker(selector, completeCallback) { + class ElementTracker { + constructor(selector, completeCallback) { this.selector = selector; this.completeCallback = completeCallback; this.progress = 0; this.check(); } - ElementTracker.prototype.check = function() { - var _this = this; + check() { if (document.querySelector(this.selector)) { - return this.done(); + this.done(); } else { - return setTimeout((function() { - return _this.check(); - }), options.elements.checkInterval); + setTimeout(() => this.check(), options.elements.checkInterval); } - }; + } - ElementTracker.prototype.done = function() { + done() { this.completeCallback(this); this.completeCallback = null; - return this.progress = 100; - }; - - return ElementTracker; - - })(); - - DocumentMonitor = (function() { - DocumentMonitor.prototype.states = { - loading: 0, - interactive: 50, - complete: 100 - }; + this.progress = 100; + } + } - function DocumentMonitor() { - var _onreadystatechange, _ref2, - _this = this; - this.progress = (_ref2 = this.states[document.readyState]) != null ? _ref2 : 100; - _onreadystatechange = document.onreadystatechange; - document.onreadystatechange = function() { - if (_this.states[document.readyState] != null) { - _this.progress = _this.states[document.readyState]; + class DocumentMonitor { + constructor() { + this.progress = this.states[document.readyState] ?? 100; + const _onreadystatechange = document.onreadystatechange; + document.onreadystatechange = (...args) => { + if (this.states[document.readyState] != null) { + this.progress = this.states[document.readyState]; } - return typeof _onreadystatechange === "function" ? _onreadystatechange.apply(null, arguments) : void 0; + return typeof _onreadystatechange === 'function' ? _onreadystatechange.apply(null, args) : undefined; }; } + } - return DocumentMonitor; - - })(); + DocumentMonitor.prototype.states = { + loading: 0, + interactive: 50, + complete: 100, + }; - EventLagMonitor = (function() { - function EventLagMonitor(settings) { - var avg, interval, last, points, samples, - _this = this; + class EventLagMonitor { + constructor(settings) { this.progress = 0; - avg = 0; - samples = []; - points = 0; - last = now(); - interval = setInterval(function() { - var diff; - diff = now() - last - 50; + let avg = 0; + const samples = []; + let points = 0; + let last = now(); + const interval = setInterval(() => { + const diff = now() - last - 50; last = now(); samples.push(diff); if (samples.length > settings.sampleCount) { @@ -701,20 +543,17 @@ } avg = avgAmplitude(samples); if (++points >= settings.minSamples && avg < settings.lagThreshold) { - _this.progress = 100; - return clearInterval(interval); + this.progress = 100; + clearInterval(interval); } else { - return _this.progress = 100 * (3 / (avg + 3)); + this.progress = 100 * (3 / (avg + 3)); } }, 50); } + } - return EventLagMonitor; - - })(); - - Scaler = (function() { - function Scaler(source) { + class Scaler { + constructor(source) { this.source = source; this.last = this.sinceLastUpdate = 0; this.rate = options.initialRate; @@ -725,11 +564,8 @@ } } - Scaler.prototype.tick = function(frameTime, val) { - var scaling; - if (val == null) { - val = result(this.source, 'progress'); - } + tick(frameTime, val) { + val ??= result(this.source, 'progress'); if (val >= 100) { this.done = true; } @@ -746,79 +582,69 @@ if (val > this.progress) { this.progress += this.catchup * frameTime; } - scaling = 1 - Math.pow(this.progress / 100, options.easeFactor); + const scaling = 1 - Math.pow(this.progress / 100, options.easeFactor); this.progress += scaling * this.rate * frameTime; this.progress = Math.min(this.lastProgress + options.maxProgressPerFrame, this.progress); this.progress = Math.max(0, this.progress); this.progress = Math.min(100, this.progress); this.lastProgress = this.progress; return this.progress; - }; - - return Scaler; - - })(); - - sources = null; - - scalers = null; - - bar = null; - - uniScaler = null; - - animation = null; + } + } - cancelAnimation = null; + let sources = null; + let scalers = null; + let bar = null; + let uniScaler = null; + let animation = null; + let cancelAnimation = null; Pace.running = false; - handlePushState = function() { + const handlePushState = () => { if (options.restartOnPushState) { - return Pace.restart(); + Pace.restart(); } }; - _pushState = window.history.pushState; - window.history.pushState = function() { + const _pushState = window.history.pushState; + window.history.pushState = (...args) => { handlePushState(); - return _pushState.apply(window.history, arguments); + return _pushState.apply(window.history, args); }; - _replaceState = window.history.replaceState; - window.history.replaceState = function() { + const _replaceState = window.history.replaceState; + window.history.replaceState = (...args) => { handlePushState(); - return _replaceState.apply(window.history, arguments); + return _replaceState.apply(window.history, args); }; - SOURCE_KEYS = { + const SOURCE_KEYS = { ajax: AjaxMonitor, elements: ElementMonitor, document: DocumentMonitor, - eventLag: EventLagMonitor + eventLag: EventLagMonitor, }; - (init = function() { - var type, _j, _k, _len1, _len2, _ref2, _ref3, _ref4; + const init = () => { Pace.sources = sources = []; - _ref2 = ['ajax', 'elements', 'document', 'eventLag']; - for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { - type = _ref2[_j]; + for (const type of ['ajax', 'elements', 'document', 'eventLag']) { if (options[type] !== false) { sources.push(new SOURCE_KEYS[type](options[type])); } } - _ref4 = (_ref3 = options.extraSources) != null ? _ref3 : []; - for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) { - source = _ref4[_k]; - sources.push(new source(options)); + const extraSources = options.extraSources ?? []; + for (let i = 0, n = extraSources.length; i < n; i++) { + sources.push(new extraSources[i](options)); } - Pace.bar = bar = new Bar; + Pace.bar = bar = new Bar(); scalers = []; - return uniScaler = new Scaler; - })(); + uniScaler = new Scaler(); + }; + + init(); - Pace.stop = function() { + Pace.stop = () => { Pace.trigger('stop'); Pace.running = false; bar.destroy(); @@ -827,33 +653,30 @@ cancelAnimationFrame(animation); animation = null; } - return init(); + init(); }; - Pace.restart = function() { + Pace.restart = () => { Pace.trigger('restart'); Pace.stop(); - return Pace.start(); + Pace.start(); }; - Pace.go = function() { - var start; + Pace.go = () => { Pace.running = true; bar.render(); - start = now(); + const start = now(); cancelAnimation = false; - return animation = runAnimation(function(frameTime, enqueueNextFrame) { - var avg, count, done, element, elements, i, j, remaining, scaler, scalerList, sum, _j, _k, _len1, _len2, _ref2; - remaining = 100 - bar.progress; - count = sum = 0; - done = true; - for (i = _j = 0, _len1 = sources.length; _j < _len1; i = ++_j) { - source = sources[i]; - scalerList = scalers[i] != null ? scalers[i] : scalers[i] = []; - elements = (_ref2 = source.elements) != null ? _ref2 : [source]; - for (j = _k = 0, _len2 = elements.length; _k < _len2; j = ++_k) { - element = elements[j]; - scaler = scalerList[j] != null ? scalerList[j] : scalerList[j] = new Scaler(element); + animation = runAnimation((frameTime, enqueueNextFrame) => { + let count = 0; + let sum = 0; + let done = true; + for (let i = 0, n = sources.length; i < n; i++) { + const source = sources[i]; + const scalerList = (scalers[i] ??= []); + const elements = source.elements ?? [source]; + for (let j = 0, m = elements.length; j < m; j++) { + const scaler = (scalerList[j] ??= new Scaler(elements[j])); done &= scaler.done; if (scaler.done) { continue; @@ -862,48 +685,42 @@ sum += scaler.tick(frameTime); } } - avg = sum / count; + const avg = sum / count; bar.update(uniScaler.tick(frameTime, avg)); if (bar.done() || done || cancelAnimation) { bar.update(100); Pace.trigger('done'); - return setTimeout(function() { + return setTimeout(() => { bar.finish(); Pace.running = false; - return Pace.trigger('hide'); + Pace.trigger('hide'); }, Math.max(options.ghostTime, Math.max(options.minTime - (now() - start), 0))); - } else { - return enqueueNextFrame(); } + return enqueueNextFrame(); }); }; - Pace.start = function(_options) { + Pace.start = (_options) => { extend(options, _options); Pace.running = true; try { bar.render(); - } catch (_error) { - NoTargetError = _error; + } catch (error) { + NoTargetError = error; } if (!document.querySelector('.pace')) { - return setTimeout(Pace.start, 50); + setTimeout(Pace.start, 50); } else { Pace.trigger('start'); - return Pace.go(); + Pace.go(); } }; if (typeof define === 'function' && define.amd) { - define(function() { - return Pace; - }); + define(() => Pace); } else if (typeof exports === 'object') { module.exports = Pace; - } else { - if (options.startOnPageLoad) { - Pace.start(); - } + } else if (options.startOnPageLoad) { + Pace.start(); } - -}).call(this); \ No newline at end of file +})(); diff --git a/pace.min.js b/pace.min.js index 39d89ce..7fed67c 100644 --- a/pace.min.js +++ b/pace.min.js @@ -2,4 +2,4 @@ * pace.js v1.3.1 * https://github.com/CodeByZach/pace/ * Licensed MIT © HubSpot, Inc. - */(function(){var M,B,D,G,J,K,Y,z,k,u,Q,V,P,Z,$,_,ee,h,S,te,T,v,j,re,N,O,m,ne,g,l,se,A,ie,w,C,E,f,y,U,q,F,x,R,oe,ue,I,ae,le,ge={}.hasOwnProperty,ce=function(r,e){for(var t in e)ge.call(e,t)&&(r[t]=e[t]);function n(){this.constructor=r}return n.prototype=e.prototype,r.prototype=new n,r.__super__=e.prototype,r};for(T={className:"",catchupTime:100,initialRate:.03,minTime:250,ghostTime:100,maxProgressPerFrame:20,easeFactor:1.25,startOnPageLoad:!0,restartOnPushState:!0,restartOnRequestAfter:500,target:"body",elements:{checkInterval:100,selectors:["body"]},eventLag:{minSamples:10,sampleCount:3,lagThreshold:3},ajax:{trackMethods:["GET"],trackWebSockets:!0,ignoreURLs:[]}},g=function(){return performance.now()},se=window.requestAnimationFrame,te=window.cancelAnimationFrame,ie=function(r){var e,t;return e=g(),t=function(){var n;return n=g()-e,n>=33?(e=g(),r(n,function(){return se(t)})):setTimeout(t,33-n)},t()},A=function(r,e,...t){return typeof r[e]=="function"?r[e].apply(r,t):r[e]},v=function(r,...e){var t,n,s,i,o;for(i=0,o=e.length;i=100?t="99":(t=this.progress<10?"0":"",t+=this.progress|0),e.children[0].setAttribute("data-progress",""+t)),u.trigger("change",this.progress),this.lastRenderedProgress=this.progress)},r.prototype.done=function(){return this.progress>=100},r})(),z=(function(){function r(){this.bindings={}}return r.prototype.trigger=function(e,t){var n,s,i,o,a;if(this.bindings[e]!=null){for(o=this.bindings[e],a=[],s=0,i=o.length;se.sampleCount&&o.shift(),t=ee(o),++i>=e.minSamples&&t=100&&(this.done=!0),t===this.last?this.sinceLastUpdate+=e:(this.sinceLastUpdate&&(this.rate=(t-this.last)/this.sinceLastUpdate),this.catchup=(t-this.progress)/l.catchupTime,this.sinceLastUpdate=0,this.last=t),t>this.progress&&(this.progress+=this.catchup*e),n=1-Math.pow(this.progress/100,l.easeFactor),this.progress+=n*this.rate*e,this.progress=Math.min(this.lastProgress+l.maxProgressPerFrame,this.progress),this.progress=Math.max(0,this.progress),this.progress=Math.min(100,this.progress),this.lastProgress=this.progress,this.progress},r})(),y=null,w=null,h=null,U=null,_=null,S=null,u.running=!1,O=function(){if(l.restartOnPushState)return u.restart()},ue=window.history.pushState,window.history.pushState=function(){return O(),ue.apply(window.history,arguments)},le=window.history.replaceState,window.history.replaceState=function(){return O(),le.apply(window.history,arguments)},V={ajax:M,elements:G,document:D,eventLag:K},(ne=function(){var r,e,t,n,s,i,o,a;for(u.sources=y=[],i=["ajax","elements","document","eventLag"],e=0,n=i.length;eperformance.now(),I=window.requestAnimationFrame,W=window.cancelAnimationFrame,H=s=>{let e=l();const t=()=>{const r=l()-e;return r>=33?(e=l(),s(r,()=>I(t))):setTimeout(t,33-r)};return t()},L=(s,e,...t)=>typeof s[e]=="function"?s[e].apply(s,t):s[e],y=(s,...e)=>{for(const t of e)if(t)for(const r in t){if(!Object.prototype.hasOwnProperty.call(t,r)||r==="__proto__"||r==="constructor"||r==="prototype")continue;const n=t[r];s[r]!=null&&typeof s[r]=="object"&&n!=null&&typeof n=="object"?y(s[r],n):s[r]=n}return s},X=s=>{let e=0,t=0;for(const r of s)e+=Math.abs(r),t++;return e/t},$=(s="options",e=!0)=>{const t=document.querySelector(`script[data-pace-${s}]`);if(!t)return;const r=t.getAttribute(`data-pace-${s}`);if(!e)return r;try{return JSON.parse(r)}catch(n){console.error("Error parsing inline pace options",n)}},i=window.Pace||{};window.Pace=i,Object.assign(i,{on(s,e,t,r){r??=!1,this.bindings??={},this.bindings[s]??=[],this.bindings[s].push({handler:e,ctx:t,once:r})},once(s,e,t){this.on(s,e,t,!0)},off(s,e){if(this.bindings?.[s]==null)return;if(e==null){delete this.bindings[s];return}let t=0;for(;t=100?t="99":(t=this.progress<10?"0":"",t+=this.progress|0),e.children[0].setAttribute("data-progress",t)}i.trigger("change",this.progress),this.lastRenderedProgress=this.progress}done(){return this.progress>=100}}class D{constructor(){this.bindings={}}trigger(e,t){if(this.bindings[e]!=null)for(const r of this.bindings[e].slice())r.call(this,t)}on(e,t){this.bindings[e]??=[],this.bindings[e].push(t)}}const q=window.XMLHttpRequest,b=window.WebSocket,R=(s,e)=>{for(const t in e.prototype)try{s[t]==null&&typeof e[t]!="function"&&Object.defineProperty(s,t,{get:()=>e.prototype[t],configurable:!0,enumerable:!0})}catch{}},p=[];i.ignore=(s,...e)=>{p.unshift("ignore");const t=s.apply(null,e);return p.shift(),t},i.track=(s,...e)=>{p.unshift("track");const t=s.apply(null,e);return p.shift(),t};const k=s=>{if(s??="GET",p[0]==="track")return"force";if(!p.length&&o.ajax){if(s==="socket"&&o.ajax.trackWebSockets)return!0;if(o.ajax.trackMethods.includes(s.toUpperCase()))return!0}return!1},G=s=>{const e=t=>{const r=t.open;t.open=(...n)=>{const[a,c]=n;return k(a)&&s.trigger("request",{type:a,url:c,request:t}),r.apply(t,n)}};window.XMLHttpRequest=function(t){const r=new q(t);return e(r),r};try{R(window.XMLHttpRequest,q)}catch{}if(o.ajax.trackWebSockets){window.WebSocket=function(t,r){let n;return r!=null?n=new b(t,r):n=new b(t),k("socket")&&s.trigger("request",{type:"socket",url:t,protocols:r,request:n}),n};try{R(window.WebSocket,b)}catch{}}};class J extends D{constructor(){super(),G(this)}}let P=null;const M=()=>(P??=new J,P),v=s=>{const e=o.ajax.ignoreURLs;for(let t=0,r=e.length;t{const{type:e,request:t,url:r}=s;if(!v(r)&&!i.running&&(o.restartOnRequestAfter!==!1||k(e)==="force")){let n=o.restartOnRequestAfter||0;typeof n=="boolean"&&(n=0),setTimeout(()=>{let a;if(e==="socket"?a=t.readyState<1:a=0this.watch(e))}watch({type:e,request:t,url:r}){if(v(r))return;let n;e==="socket"?n=new Y(t,this.complete):n=new K(t,this.complete),this.elements.push(n)}complete(e){this.elements=this.elements.filter(t=>t!==e)}}class K{constructor(e,t){this.progress=0,e.addEventListener("progress",r=>{r.lengthComputable?this.progress=100*r.loaded/r.total:this.progress=this.progress+(100-this.progress)/2},!1);for(const r of["load","abort","timeout","error"])e.addEventListener(r,()=>{t(this),this.progress=100},!1)}}class Y{constructor(e,t){this.progress=0;for(const r of["error","open"])e.addEventListener(r,()=>{t(this),this.progress=100},!1)}}class z{constructor(e){e??={},this.complete=this.complete.bind(this),this.elements=[],e.selectors??=[];const t=e.selectors;for(let r=0,n=t.length;rt!==e)}}class Q{constructor(e,t){this.selector=e,this.completeCallback=t,this.progress=0,this.check()}check(){document.querySelector(this.selector)?this.done():setTimeout(()=>this.check(),o.elements.checkInterval)}done(){this.completeCallback(this),this.completeCallback=null,this.progress=100}}class O{constructor(){this.progress=this.states[document.readyState]??100;const e=document.onreadystatechange;document.onreadystatechange=(...t)=>(this.states[document.readyState]!=null&&(this.progress=this.states[document.readyState]),typeof e=="function"?e.apply(null,t):void 0)}}O.prototype.states={loading:0,interactive:50,complete:100};class V{constructor(e){this.progress=0;let t=0;const r=[];let n=0,a=l();const c=setInterval(()=>{const u=l()-a-50;a=l(),r.push(u),r.length>e.sampleCount&&r.shift(),t=X(r),++n>=e.minSamples&&t=100&&(this.done=!0),t===this.last?this.sinceLastUpdate+=e:(this.sinceLastUpdate&&(this.rate=(t-this.last)/this.sinceLastUpdate),this.catchup=(t-this.progress)/o.catchupTime,this.sinceLastUpdate=0,this.last=t),t>this.progress&&(this.progress+=this.catchup*e);const r=1-Math.pow(this.progress/100,o.easeFactor);return this.progress+=r*this.rate*e,this.progress=Math.min(this.lastProgress+o.maxProgressPerFrame,this.progress),this.progress=Math.max(0,this.progress),this.progress=Math.min(100,this.progress),this.lastProgress=this.progress,this.progress}}let d=null,A=null,h=null,C=null,g=null,S=null;i.running=!1;const j=()=>{o.restartOnPushState&&i.restart()},Z=window.history.pushState;window.history.pushState=(...s)=>(j(),Z.apply(window.history,s));const ee=window.history.replaceState;window.history.replaceState=(...s)=>(j(),ee.apply(window.history,s));const te={ajax:N,elements:z,document:O,eventLag:V},_=()=>{i.sources=d=[];for(const e of["ajax","elements","document","eventLag"])o[e]!==!1&&d.push(new te[e](o[e]));const s=o.extraSources??[];for(let e=0,t=s.length;e{i.trigger("stop"),i.running=!1,h.destroy(),S=!0,g!=null&&(W(g),g=null),_()},i.restart=()=>{i.trigger("restart"),i.stop(),i.start()},i.go=()=>{i.running=!0,h.render();const s=l();S=!1,g=H((e,t)=>{let r=0,n=0,a=!0;for(let u=0,f=d.length;u{h.finish(),i.running=!1,i.trigger("hide")},Math.max(o.ghostTime,Math.max(o.minTime-(l()-s),0)))):t()})},i.start=s=>{y(o,s),i.running=!0;try{h.render()}catch(e){w=e}document.querySelector(".pace")?(i.trigger("start"),i.go()):setTimeout(i.start,50)},typeof define=="function"&&define.amd?define(()=>i):typeof exports=="object"?module.exports=i:o.startOnPageLoad&&i.start()})(); From 960274cd811e53e09d9bc63de5571e92b3072997 Mon Sep 17 00:00:00 2001 From: Zachary Miller Date: Sat, 7 Nov 2026 16:08:21 -0500 Subject: [PATCH 5/5] Update the README's browser support and size Lists the browsers from .browserslistrc and points users of older browsers to pace-js 1.x. The sizes are measured: pace.min.js is 3.6 kB gzipped, and the blue themes are 0.2 to 3.2 kB. --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 94fa562..640739f 100644 --- a/README.md +++ b/README.md @@ -297,14 +297,15 @@ None! Support ------- -Pace is designed to support IE8+ (standards mode), FF 3.5+, Chrome, Safari 4+, Opera 10.5+, and all modern -mobile browsers. If you run into a compatibility issue, or can make a case for supporting something else, -please create an issue. +Pace supports Chrome and Edge 96+, Firefox 95+, and Safari 15.2+ on macOS and iOS, plus browsers built +on the same engines, such as Opera and Samsung Internet. For older browsers, use pace-js 1.x. + +If you run into a compatibility issue, please create an issue. Size ---- -pace.js is 4kb minified and gzipped. The themes vary between 0.5 and 4kb. +pace.min.js is under 4 kB gzipped. The themes are between 0.2 and 3.2 kB gzipped. Issues ------