diff --git a/src/index.js b/src/index.js index c88d41ce2..bcc4af868 100644 --- a/src/index.js +++ b/src/index.js @@ -1,3 +1,4 @@ +import "./libs/textEncoding.js"; import { jsPDF } from "./jspdf.js"; export * from "./jspdf.js"; diff --git a/src/libs/textEncoding.js b/src/libs/textEncoding.js new file mode 100644 index 000000000..e78a2052c --- /dev/null +++ b/src/libs/textEncoding.js @@ -0,0 +1,50 @@ +import { globalObject as global } from "./globalObject.js"; + +var bufferAvailable = typeof global.Buffer !== "undefined"; + +if (typeof global.TextEncoder === "undefined" && bufferAvailable) { + class JsPDFTextEncoder { + encode(input) { + if (input === void 0) { + input = ""; + } + return Buffer.from(String(input), "utf-8"); + } + } + + global.TextEncoder = JsPDFTextEncoder; +} + +if (typeof global.TextDecoder === "undefined" && bufferAvailable) { + class JsPDFTextDecoder { + constructor(encoding) { + this.encoding = encoding || "utf-8"; + } + + decode(input) { + if (input == null) { + return ""; + } + + var buffer; + + if (Buffer.isBuffer(input)) { + buffer = input; + } else if (input instanceof ArrayBuffer) { + buffer = Buffer.from(input); + } else if (ArrayBuffer.isView(input)) { + buffer = Buffer.from(input.buffer, input.byteOffset, input.byteLength); + } else if (Array.isArray(input)) { + buffer = Buffer.from(input); + } else { + throw new TypeError( + "The provided value is not of type '(ArrayBuffer or ArrayBufferView)'" + ); + } + + return buffer.toString(this.encoding); + } + } + + global.TextDecoder = JsPDFTextDecoder; +} diff --git a/src/polyfills.js b/src/polyfills.js index 017b29b83..76fc2cab2 100644 --- a/src/polyfills.js +++ b/src/polyfills.js @@ -18,6 +18,7 @@ import "core-js/es/typed-array/reduce"; import "./libs/Blob"; import { globalObject as global } from "./libs/globalObject.js"; +import "./libs/textEncoding.js"; var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; diff --git a/test/specs/textEncodingFallback.spec.js b/test/specs/textEncodingFallback.spec.js new file mode 100644 index 000000000..0d01a5b36 --- /dev/null +++ b/test/specs/textEncodingFallback.spec.js @@ -0,0 +1,47 @@ +describe("TextEncoder/TextDecoder fallback", function() { + var originalTextEncoder; + var originalTextDecoder; + var modulePath; + + beforeAll(function() { + originalTextEncoder = global.TextEncoder; + originalTextDecoder = global.TextDecoder; + modulePath = require.resolve("../../dist/jspdf.node.js"); + }); + + afterAll(function() { + if (modulePath) { + delete require.cache[modulePath]; + } + global.TextEncoder = originalTextEncoder; + global.TextDecoder = originalTextDecoder; + if (typeof loadGlobals === "function") { + loadGlobals(); + } + }); + + it("provides polyfills when globals are missing", function() { + delete require.cache[modulePath]; + + delete global.TextEncoder; + delete global.TextDecoder; + + var jsPDFModule = require(modulePath); + + expect(typeof global.TextEncoder).toBe("function"); + expect(typeof global.TextDecoder).toBe("function"); + + var encoder = new global.TextEncoder(); + var decoder = new global.TextDecoder(); + var sample = "jsPDF"; + var encoded = encoder.encode(sample); + + expect( + encoded instanceof Uint8Array || Buffer.isBuffer(encoded) + ).toBeTrue(); + expect(decoder.decode(encoded)).toBe(sample); + + // ensure jsPDF module still exports expected API + expect(typeof jsPDFModule.jsPDF).toBe("function"); + }); +});