Pdf.js: Habilite a compatibilidade do IE 11 com Angular + pdf.js

Criado em 24 mar. 2017  ·  10Comentários  ·  Fonte: mozilla/pdf.js

Configuração:

  • Navegador da web e sua versão: IE 11
  • Sistema operacional e sua versão: Qualquer
  • Versão PDF.js: 1.4.0
  • Versão do AngularJs: 1.5.11

Etapas para reproduzir o problema:

  1. Use AngularJS 1.5.11 com inicialização automática
  2. Incluir PDF.js versão 1.4.0 ANTES das tags de script do Angular

Qual é o comportamento esperado? (adicionar captura de tela)

  • Angular funciona perfeitamente em conjunto com PDF.js
  • PDF.js envolve a API ausente em funções que usarão a versão corrigida se a versão nativa não estiver disponível.

O que deu errado? (adicionar captura de tela)

  • Veja https://github.com/angular/angular.js/issues/15772
    Atualmente, pdf.js define document.currentScript, mas não link.origin nem link.protocol. Se o angular iniciar, ele verifica se é permitido inicializar automaticamente, ele verifica o currentScript e assume que isso será suficiente para filtrar o IE, o que significa que se o currentScript não for definido, podemos inicializar automaticamente. Esta verificação não funcionará em combinação com pdf.js.

As bibliotecas não devem modificar propriedades de objetos que não possuem, pois isso causa problemas como este. Se eles precisarem de uma API específica que está faltando em alguns ambientes com suporte, eles podem envolver seu uso em uma função que usará a versão com shim se a nativa não estiver disponível.

Link para um visualizador (se hospedado em um site diferente de mozilla.github.io/pdf.js ou como extensão do Firefox / Chrome):
http://plnkr.co/edit/YFCQM2Px0QU0KnGzsAlM?p=preview

1-other

Todos 10 comentários

Soa como transferir a culpa de uma verificação de segurança incompleta do IE11 para o polyfill PDF.js ... tudo bem. Marcando como um bug simples para corrigir essa lacuna:

  1. document.location.origin deve ser definido para o novo URL (document.location.href) .origin se a propriedade 'origin' estiver ausente
  2. HTMLScriptElement.prototype deve ter os getters de origem e protocolo com a lógica semelhante à anterior.

@yurydelendik Para mim, isso é análogo à situação em que algumas APIs da Web tiveram que mudar seus nomes porque a MooTools estava aplicando polyfills parciais e o código na Web começou a depender disso.

Polyfilling é arriscado, IMO deve ser feito apenas com polyfills completos e apenas em aplicativos finais, não em bibliotecas. Se as bibliotecas precisam de uma API específica que não está disponível em todos os lugares, elas devem envolver a API nativa em uma função de utilitário e usar essa função; que remove toda a classe de possíveis bugs como este.

Resumindo: o código da biblioteca não deve modificar os objetos que não possui, por exemplo, globais do navegador nativo.

Polyfilling é arriscado

@mgol oh, eu concordo. Todo o aplicativo visualizador de PDF.js deve residir em sua própria sandbox (eu recomendo iframe), mas as pessoas continuam usando-o em aplicativos maiores. Portanto, temos que reagir de acordo.

o código da biblioteca não deve modificar objetos que não possui, por exemplo, globais de navegador nativos.

Vamos dar outro exemplo, sem arrays digitados e a biblioteca Promise PDF.js não seria a mesma. E, ao não modificar objetos globais, tornaríamos nosso código ilegível e provavelmente com menos desempenho para a maioria dos navegadores modernos.

Vamos dar outro exemplo, sem os arrays digitados e a biblioteca Promise PDF.js não seria a mesma. E, ao não modificar objetos globais, tornaríamos nosso código ilegível e provavelmente com menos desempenho para a maioria dos navegadores modernos.

Não necessariamente. Você pode manter seu próprio conjunto interno de variáveis ​​que sombreiam os globais. Isso pode não abranger todos os casos, mas pelo menos as promessas devem ser suficientes. Algo como:

var Promise = window.Promise || PROMISE_POLYFILL;

na parte superior do PDF.js. Nesse caso, você não está tocando no global e ainda pode usar Promise em seu código sem qualquer alteração.

Isso não deve afetar o desempenho em navegadores modernos, pois é um apelido simples para eles.

Eu entendo que pode não ser tão fácil em todos os casos, porém (por exemplo, se apenas alguns métodos precisam ser polyfilled)

O código PDF.js está se transformando para usar módulos ES6. A abordagem acima pode ser problemática atm, a menos que um empacotador forneça automaticamente um polyfill.

Eu não gostaria de transformar esse problema em discussão sobre lógica angular ou abordagem de compatibilidade de pdf.js, será bom consertar um polyfill nosso, então vamos jogar bem com angular. Um PR é bem-vindo :)

Pensando bem, vamos fechar este problema porque não vai resolver. Não há confirmação de que existem usos no mundo real do Angular + PDF.js + IE11; se houver, a correção pode ser feita facilmente no lado angular corrigindo o Angular.js.

Olá, sei que este é um tópico antigo, mas estou encontrando o problema descrito acima.

Eu tenho um projeto em que estou usando o Angular 5 com PDF.js e sou obrigado a oferecer suporte ao IE11. Eu sou um novato no Angular, então não tenho certeza de como faria "patch do Angular.js" - você pode me dar alguma orientação sobre como posso contornar esse defeito? Desde já, obrigado.

@elliotstoner, esse problema é sobre a compatibilidade do AngularJS, não do Angular (2+) e só se aplica se você usar ng-app vez de inicialização manual. O Angular 2+ nem mesmo oferece suporte a inicialização automática, portanto, esse problema não se aplica aqui.

@mgol Ah ok - vou criar um novo problema então, obrigado.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

dmisdm picture dmisdm  ·  3Comentários

smit-modi picture smit-modi  ·  3Comentários

hp011235 picture hp011235  ·  4Comentários

BrennanDuffey picture BrennanDuffey  ·  3Comentários

zerr0s picture zerr0s  ·  3Comentários