Before commit:
chrome-extension://EXTENSIONID/content/web/viewer.html?file=http%3A%2F%2Fexample.com%2Ffile.pdf
After commit:
chrome-extension://EXTENSIONID/http://example/file.pdf
Technical details:
- The extension's background page uses the webRequest API to intercept
requests for <extension host>/<real path to pdf>, and redirect it to
the viewer's URL.
- viewer.js uses history.replaceState to rewrite the URL, so that it's
easier for users to recognize and copy-paste URLs.
- The fake paths /http:, /https:, /file:, etc. have been added to the
web_accessible_resources section of the manifest file, in order to
avoid seeing chrome-extension://invalid/ instead of the actual URL
when using history back/forward to navigate from/to the PDF viewer.
- Since the relative path resolving doesn't work because relative URLs
are inaccurate, a <base> tag has been added. This method has already
been proven to work in the Firefox add-on.
Notes:
- This commit has been cherry-picked from crx-using-streams-api.
- Need to merge https://github.com/mozilla/pdf.js/pull/3582 to deal with
a bug in Chrome <=30
- In Chrome, getting the contents of a FTP file is not possible, so
there's no support for FTP files, even though the extension router
recognizes the ftp: scheme.
The current stable Chromium version is 29. Since the critical
bug that prevented use of incognito:split has been fixed, and
incognito:split is actually used, it's safe to drop the code
that disables the extension in incognito mode.
( fixed bug = http:/crbug.com/224094 )
And use split incognito mode
Previous method:
- Rewrite content type to XHTML, followed by a content script
to cancel and replace the document with the viewer.
( https://github.com/mozilla/pdf.js/pull/3017 )
New method:
- Cancel loading of the document, followed by a redirect to the viewer
Disadvantage of new method:
- URLs are no longer "nice". This will be addressed by cherry-picking
a commit from the crx-using-streams-api branch.
Advantages of new method:
- Idle time is minimal. In some cases (with large documents),
it took too much time before the content script was activated.
During this period, the page looked blank, and the contents of
the PDF file were still retrieved and **discarded**.
With the new method, the idle time is minimal, because the request
is immediately cancelled.
- No FOUXEP (Flash of unhidden XML error page), because the XHTML
Content-Type hack is no longer used.
Do NOT save the temporary <canvas> element as `this.canvas`.
`PDFViewer.pages[i].canvas` appears to be used to generate the thumbnail
icons. Well, that's no justification for preventing GC of those
temporary <canvas> elements used during mozPrintCallback.
With a document consisting of 79 pages, this resulted in a 600-700MB
leaked memory.
This shim does the following:
1. Intercept window.print()
2. For a window.print() call (if allowed, ie. no previous print job):
1. Dispatch the beforeprint event.
2. Render a printg progress dialog.
3. For each canvas, call mozPrintCallback if existent (one at a time, async).
4. During each mozPrintCallback callback, update the progress dialog.
5. When all <canvas>es have been rendered, invoke the real window.print().
6. Dispatch the afterprint event.
The shim is not included in Firefox through the preprocessor.
Keyboard shortcuts (Ctrl/Cmd + P) are intercepted and default behavior
(i.e. printing) is prevented, and the steps for window.print() are run.
window.attachEvent is used, in order to cancel printing in IE10 and
earlier (courtesy of Stack Overflow - http://stackoverflow.com/a/15302847).
Unfortunately, this doesn't work in IE11 - if Ctrl + P is used, the
print dialog will be shown twice: Once because of Ctrl + P, and again
when all pages have finished rendering.
This logic of this polyfill is not specific to PDF.js, so it can also
be used in other projects.
There's one additional modification in PDF.js's viewer.js: The printed
<canvas> element is wrapped in a <div>. This is needed, because Chrome
would otherwise print one canvas on two pages.
PDFJS does not work on Windows Safari, due to the lack of support for workers passing typed arrays. At some point, the code to set up the fake worker so that things work on Safari seems to have become broken and nobody noticed - it was just calling setupFakeWorker() without actually calling loadFakeWorkerFiles(). With this patch, the PDFJS works again on Windows Safari.