This patch updates the minimum supported environments as follows:
- Node.js 18, which was released on 2022-04-19; see https://en.wikipedia.org/wiki/Node.js#Releases
Note also that Node.js 16 will soon reach EOL, and thus no longer receive any security updates.
Now that https://bugzilla.mozilla.org/show_bug.cgi?id=1247687 has landed in Firefox, we're able to use worker-modules during development :-)
This removes the final piece of SystemJS usage from the PDF.js library, thus allowing a fair bit of clean-up, and we now use *only* native `import`/`export` statements everywhere in development mode.
The latest version of `eslint-plugin-mozilla` removed the Prettier dependency, see https://bugzilla.mozilla.org/show_bug.cgi?id=1677562, which means that we no longer need to use `npm install --force` in the PDF.js library.
This patch updates the minimum supported environments as follows:
- Node.js 16, which was released on 2021-04-20; see https://en.wikipedia.org/wiki/Node.js#Releases
Note also that Node.js 14 will very soon reach EOL, and thus no longer receive any security updates.
Until just recently the only existing `Path2D` polyfill didn't have support for Node.js and/or the `node-canvas` package. Given that this was just fixed, in the latest version, we can now finally remove our inline-checks at the relevant call-sites; please also see https://github.com/nilzona/path2d-polyfill#usage-with-node-canvas
Fewer dependencies shouldn't be a bad idea in general, and given that the `node-canvas` package already include a `DOMMatrix` polyfill we can simply use that one instead.
Currently we simply use the Babel `preset-env` in the `legacy`-builds of the PDF.js library. This has the side-effect of transpiling the code for *very old* browsers/environments, including ones that we (since many years) no longer support which unnecessarily bloats the size of the `legacy`-builds.
For the CSS files we're only targeting *the supported browsers*, and it's thus possible to extend that to also apply to Babel.
One of the most significant changes, with this patch, is that we'll no longer polyfill `async`/`await` in the `legacy`-builds. However, this shouldn't be an issue given the browsers that we currently support in PDF.js; please refer to:
- https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions#faq-support
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function#browser_compatibility
Rather than including all of this external code in the PDF.js repository, we should be using the npm package instead.
Unfortunately this is slightly more complicated than you'd hope, since the `fit-curve` package (which is older) isn't directly compatible with modern JavaScript modules.
In particular, the following cases needed to be considered:
- For the development viewer (i.e. `gulp server`) and the unit-tests, we thus need to build a fitCurve-bundle that can be directly `import`ed.
- For the actual PDF.js build-targets, we can slightly reduce the sizes by depending on the "raw" `fit-curve` source-code.
- For the Node.js unit-tests, the `fit-curve` package can be used as-is.
Note that even though Puppeteer got a major version bump the changelog
doesn't include compatibility changes that are relevant to us; please
see https://github.com/puppeteer/puppeteer/releases.
Unfortunately newer versions either caused breakage when running the
unit tests manually in a browser or when serving the development viewer.
Given that we hope to use native import maps soon and this dependency
will then be removed anyway, let's pin it for the time being.
There are two notable changes here:
- `dommatrix` is a major version upgrade, but looking through the commit
history of their `package.json` file at https://github.com/thednp/dommatrix/commits/master/package.json
(due to the lack of a changelog) I couldn't find any breaking changes.
- `es-module-shims` is a regular update, but it was previously pinned
for causing intermittent breakage when running the unit tests in a
browser manually. Fortunately this cannot be reproduced anymore with
the most recent version, so we can also put the caret back now.
Because of a bug in previous `core-js` versions, which caused an Error to be thrown if its `structuredClone` polyfill was called with an *explicit* `null`/`undefined` transfer-parameter, the `LoopbackPort`-class contained a work-around.
In the latest `core-js` version this has been fixed, and we can thus simplify our code ever so slightly; please see https://github.com/zloirock/core-js/releases/tag/v3.22.0
Please note that this patch is purposely quite basic, e.g. it doesn't add the polyfill-CSS in order to simplify the build process, and things such as `::backdrop` thus isn't working.
However, this patch does ensure that older browsers can at least still *access* all of the previous overlays and that things like e.g. opening of password-protected documents respectively printing still works.
Note that the Prettier update made it possible to move a couple of comments after `default:`-cases back to their original/intended positions, please see https://prettier.io/blog/2022/03/16/2.6.0.html
Since the Autoprefixer plugin indirectly depends on this, it seems like a good idea to add this as a direct dependency in the PDF.js project to hopefully avoid having to manually update `caniuse-lite` in the future; see https://github.com/browserslist/browserslist#browsers-data-updating
Also, slightly tweaks the Autoprefixer config for GENERIC-builds of the PDF.js library; note that this change doesn't affect the contents of the *built* `web/viewer.js` file.
This allows us to remove the manually implemented `structuredClone` polyfill, thus reducing the maintenance burden for the `LoopbackPort` class; refer to https://github.com/zloirock/core-js#structuredclone
*Please note:* While `structuredClone` support landed already in Firefox 94, Google Chrome only added it in version 98 (currently in Beta). However, given that the `LoopbackPort` will only be used together with *fake workers* in browsers this shouldn't be too much of a problem.[1]
For Node.js environments, where *fake workers* are unfortunately necessary, using a `legacy/`-build is already required which thus guarantees that the `structuredClone` polyfill is available.
Also, the patch updates core-js to the latest version since that one includes `structuredClone` improvements; please see https://github.com/zloirock/core-js/releases/tag/v3.20.3
---
[1] Given that we only support browsers with proper worker support, if *fake workers* are being used that essentially indicates a configuration problem/error.
This patch circumvents the issues seen when trying to update TypeScript to version `4.5`, by "simply" fixing the broken/missing JSDocs and `typedef`s such that `gulp typestest` now passes.
As always, given that I don't really know anything about TypeScript, I cannot tell if this is a "correct" and/or proper way of doing things; we'll need TypeScript users to help out with testing!
*Please note:* I'm sorry about the size of this patch, but given how intertwined all of this unfortunately is it just didn't seem easy to split this into smaller parts.
However, one good thing about this TypeScript update is that it helped uncover a number of pre-existing bugs in our JSDocs comments.
With ESLint 8 we should now finally be able to start using modern `class` features, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Public_class_fields and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields
However, while both ESLint and Acorn now support this, it unfortunately turns out that Escodegen (which we use during building) still lack the necessary support. Looking at https://github.com/estools/escodegen there's not been any updates since last year, and there's also open PRs adding support for these new `class` features.
To avoid blocking usage of these `class` features in the PDF.js code-base, in particular *private* fields/methods, this patch thus proposes that we (hopefully temporarily) switch to an `escodegen` fork that has the necessary support; please see https://www.npmjs.com/package/@javascript-obfuscator/escodegen
While I have no reason to doubt the security of the `escodegen` fork, this patch nonetheless pins the version number. Furthermore, I've also diffed the output of the two `.js`-files in this forked package against the original files without finding anything that looks immediately "dangerous".
This command was added all the way back when basic CI-support was first introduced (using Travis at the time), however it's never really intended to be used e.g. for local development.
By having a `npm test`-command listed in the `package.json` file, there's a very real risk that someone unfamiliar with the code-base would only run that one and thus miss all the other (more important) test-suites[1].
Hence this patch which removes the `npm test`-command, and instead simply calls the relevant gulp-task[2] directly in the GitHub Actions configuration.
---
[1] Which consist of the unit-tests (run in browsers), the font-tests (potentially), the reference-tests, and the integration-tests.
[2] Which is also renamed slightly, to better fit its current usage.
According to https://docs.npmjs.com/cli/v7/configuring-npm/package-json#version, the "version" field is not required[1]:
> If you don't plan to publish your package, the name and version fields are optional.
Hence it shouldn't be necessary to have a "dummy" `version` field in the `package.json` file, and it seems quite unfortunate to have an essentially meaningless entry in that file.[2]
Furthermore, I'd even go as far as suggesting that it's actually doing more harm than good in practice, since it's not uncommon for people to open issues where they simply quote the `package.json`-entry when filling out the ISSUE_TEMPLATE thus causing confusion as to which *exact* version is actually used.
Unless I'm misremembering, I believe that the only reason for adding the `version` field was that is was necessary in order for things to work back when testing was run on Travis.
Now we're using GitHub Actions instead, where things seem to work just find even without a `version` field; hence why I think it makes sense to remove this.
---
[1] Please note that this patch doesn't affect the `pdfjs-dist` package, since the `package.json` file used there is created in `gulpfile.js` during building.
[2] Trying to, automatically, update the `version` field on *every* commit really doesn't seem worth it to me.