Pdf.js: Library not working with Ember.js because of extended array prototype

Created on 18 Dec 2019  路  5Comments  路  Source: mozilla/pdf.js

Configuration:

  • Web browser and its version: chrome Version 78.0.3904.108
  • Operating system and its version: MacOs
  • PDF.js version: 2.0.943
  • Is a browser extension:

This is not an issue with the lib itself, but hopefully I can ask for feedback and help.

I am using this library in an ember.js project. Usually, everything works well, but some pdf do not render the text correctly, and I get Error during font loading: this._map[t].charCodeAt is not a function as an error. Searching around, I found #7064 and #7318 that explains that the fact that Ember extend the Array prototype and make them enumerable seems to be causing a problem.

A fix that works is to disable globally Ember array extension, but our app is quite large and manually going into the code to make sure every array is an Ember Array would be extremely cumbersome.

So, my questions:

1) Is there any possible reason why some file would display correctly why other won't? Could it be a font or encodage issue? I tried loading a file that does not display correctly with the simple viewer demo provided and it works, so I am thinking this is possibly not the issue, but it's still weird that some file work correctly while some don't.

The way it works is that an external user add text to the pdf with an editing pdf program, and then upload the pdf to our web site that they then use a PDF.js based viewer to look at, and this is where sometime the text does not get displayed with the error.

2) Is there any modification I could make to the library code itself that would make this work, without having to disable globally my ember array extension?

I found this commit and I tried to make the same modification to my node_modules/pdfjs-dist/lib/core/fonts.js file but it had no effect. That kind of solution would be perfect for me though, even if I lose some performance.

Thank you very much!

Most helpful comment

PDF.js requires that array are implemented in a standard way, so either a native implementation or one that implements everything from the specification. If not, you'll need to polyfill the implementation yourself. There are existing polyfills for arrays, for example in core-js. However, this is outside of the scope of PDF.js and we would recommend to disable any Ember-specific overrides of native JavaScript primitives because you're bound to run into issues sooner or later.

Is there any possible reason why some file would display correctly why other won't?

Depending on the PDF file itself (based on encoding, font types, et cetera), other code paths will be taken, so not all may require charCodeAt to be present. It's not possible to say in general without code inspection.

Is there any modification I could make to the library code itself that would make this work, without having to disable globally my ember array extension?

The extensions are in fact breaking normal JavaScript behavior, so it's very much not recommended, but if you really need to you can use existing polyfills at outlined above. They might conflict with Ember's modifications though, but for that you'll need to ask Ember developers for support.

All 5 comments

PDF.js requires that array are implemented in a standard way, so either a native implementation or one that implements everything from the specification. If not, you'll need to polyfill the implementation yourself. There are existing polyfills for arrays, for example in core-js. However, this is outside of the scope of PDF.js and we would recommend to disable any Ember-specific overrides of native JavaScript primitives because you're bound to run into issues sooner or later.

Is there any possible reason why some file would display correctly why other won't?

Depending on the PDF file itself (based on encoding, font types, et cetera), other code paths will be taken, so not all may require charCodeAt to be present. It's not possible to say in general without code inspection.

Is there any modification I could make to the library code itself that would make this work, without having to disable globally my ember array extension?

The extensions are in fact breaking normal JavaScript behavior, so it's very much not recommended, but if you really need to you can use existing polyfills at outlined above. They might conflict with Ember's modifications though, but for that you'll need to ask Ember developers for support.

PDF.js requires that array are implemented in a standard way,

I'm actually wondering if it would make sense to attempt to implement checks for GENERIC builds, perhaps placed in getDocument, to error/warn if Arrays contain unexpected enumerable properties!?

@timvandermeij

Thank you very much for your help and time.

If I may ask one last thing, why is it that the solution proposed in the commit

 forEach: function(callback) {
      for (var charCode in this._map) {
        if (!this._map.hasOwnProperty(charCode)) {
          continue;
        }
        callback(charCode, this._map[charCode].charCodeAt(0));
      }
    },

is not working for me, or would not be a suitable solution to my problem?

The problem is described in https://github.com/mozilla/pdf.js/pull/5411#issuecomment-59098223. Basically it's not acceptable for the library because adding additional checks in such often called code causes runtime delays and it's only required for non-standard changes. Therefore, if users need this because e.g., their framework requires it, then we ask those users to change/polyfill it themselves. The library should be generic and work in all standards-compliant environments, we in general we don't include environment-specific hacks. Hopefully that answers your question.

Yes, thank you very much for your help!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sujit-baniya picture sujit-baniya  路  3Comments

zerr0s picture zerr0s  路  3Comments

liuzhen2008 picture liuzhen2008  路  4Comments

jigskpatel picture jigskpatel  路  3Comments

AlexP3 picture AlexP3  路  3Comments