Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Fix for web worker test in Safari #1849

Merged
merged 9 commits into from

5 participants

Tim de Koning Yury Delendik pdf.js test bot Brendan Dahl Julian Viereck
Tim de Koning

Safari can not read or write typed arrays to 'web workers'. This will cause Safari on the iPhone and iPad to crash. The desktop version of Safari just throws a weird error.

This behaviour is tested by pdf.js while a pdf is being downloaded from a URL. However, sometimes the pdf has finished downloading BEFORE the web worker-test has finished! In that case the rendering of the final pdf would cause errors, because the web workers have not yet been disabled.

This patch fixes this and the issues #1314, #1627, #1643, #1846 and #1805 .

src/api.js
@@ -49,23 +50,26 @@ PDFJS.getDocument = function getDocument(source) {
url: url,
progress: function getPDFProgress(evt) {
if (evt.lengthComputable)
- promise.progress({
+ workerReadyPromise.progress({
Yury Delendik Owner

Indentation is wrong

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
src/api.js
((6 lines not shown))
loaded: evt.loaded,
total: evt.total
});
},
error: function getPDFError(e) {
- promise.reject('Unexpected server response of ' +
+ workerReadyPromise.reject('Unexpected server response of ' +
Yury Delendik Owner

Indentation is wrong

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
src/api.js
((13 lines not shown))
e.target.status + '.');
},
headers: headers
},
function getPDFLoad(data) {
- transport.sendData(data, parameters);
+ //we have to wait for the WorkerTransport to finalize worker-support detection! This may take a while...
Yury Delendik Owner

Not complete/useful comment. Please add your issue description text here: "Sometimes the pdf has finished downloading before the web worker-test has finished. In that case the rendering of the final pdf would cause errors." (without capitalization and exclamation points); then "We have to wait for the WorkerTransport to finalize worker-support detection."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Yury Delendik

/botio-linux lint

pdf.js test bot
Collaborator

From: Bot.io (Linux)


Received

Command cmd_lint from @yurydelendik received. Current queue size: 0

Live output at: http://107.21.233.14:8877/14c05dc01cdbab4/output.txt

pdf.js test bot
Collaborator

From: Bot.io (Linux)


Failed

Full output at http://107.21.233.14:8877/14c05dc01cdbab4/output.txt

Total script time: 1.17 mins

  • Lint: FAILED
Yury Delendik

Thank you for investigating this. Please address the long lines, illegal tabs and other lint issues.

Also, this patch might conflict with #1840.

/botio-windows preview

pdf.js test bot
Collaborator

From: Bot.io (Windows)


Received

Command cmd_preview from @yurydelendik received. Current queue size: 0

Live output at: http://107.22.172.223:8877/2dd123771760a8a/output.txt

Tim de Koning

Hmmm i just found out that iPhone / iPad support needs some more love... will look further into that...

Tim de Koning

pdf.js now is actually working on iOS again. I found out that Uint8array on Safari 5 is lacking the subarray-method and has another issue with Object.defineProperty and DOM objects. This is now fixed and the code is made lint-compliant.

web/compatibility.js
@@ -69,8 +79,10 @@
// Object.defineProperty() ?
(function checkObjectDefinePropertyCompatibility() {
- if (typeof Object.defineProperty !== 'undefined')
- return;
+ // safari 5 cannot use this on DOM objects and thus is unusable,
+ // see http://kangax.github.com/es5-compat-table/
+ if ((typeof Object.defineProperty !== 'undefined') &&
+ /Safari\/5/.test(navigator.userAgent)) return;
Yury Delendik Owner

Looks like it shall be !/Safari\/5/.test(navigator.userAgent)

Tim de Koning
Reggino added a note

Wow, great catch!

The reason this slipped through is because my iPad seems to be running Safari 6 and that browser is still having the same issue. Fixed it, thanks @yurydelendik

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Yury Delendik

/botio-windows lint

pdf.js test bot
Collaborator

From: Bot.io (Windows)


Received

Command cmd_lint from @yurydelendik received. Current queue size: 0

Live output at: http://107.22.172.223:8877/257ea6e3d31d34b/output.txt

Yury Delendik

/botio-linux preview

pdf.js test bot
Collaborator

From: Bot.io (Linux)


Received

Command cmd_preview from @yurydelendik received. Current queue size: 0

Live output at: http://107.21.233.14:8877/fc664b957bebc0c/output.txt

pdf.js test bot
Collaborator

From: Bot.io (Windows)


Success

Full output at http://107.22.172.223:8877/257ea6e3d31d34b/output.txt

Total script time: 1.19 mins

  • Lint: Passed
web/compatibility.js
@@ -69,8 +79,9 @@
// Object.defineProperty() ?
(function checkObjectDefinePropertyCompatibility() {
- if (typeof Object.defineProperty !== 'undefined')
- return;
+ // safari 5 and 6 cannot use this on DOM objects and thus it's unusable,
+ if ((typeof Object.defineProperty !== 'undefined') &&
+ !/Safari/.test(navigator.userAgent)) return;
Brendan Dahl Owner

We should not be looking at the user agent. Use feature detection instead. See https://github.com/kriskowal/es5-shim/blob/master/es5-shim.js#L599 for inspiration.

Tim de Koning
Reggino added a note

I agree. I've updated the test accordingly... Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Brendan Dahl
Owner

/botio-windows lint
/botio-linux preview

pdf.js test bot
Collaborator

From: Bot.io (Linux)


Received

Command cmd_preview from @brendandahl received. Current queue size: 0

Live output at: http://107.21.233.14:8877/87d064919c336a3/output.txt

pdf.js test bot
Collaborator

From: Bot.io (Windows)


Received

Command cmd_lint from @brendandahl received. Current queue size: 0

Live output at: http://107.22.172.223:8877/820df6c19fffd51/output.txt

pdf.js test bot
Collaborator

From: Bot.io (Windows)


Success

Full output at http://107.22.172.223:8877/820df6c19fffd51/output.txt

Total script time: 1.31 mins

  • Lint: Passed
Tim de Koning

/botio-windows lint
/botio-linux preview

Julian Viereck
Collaborator

/botio-windows lint
/botio-linux preview

pdf.js test bot
Collaborator

From: Bot.io (Windows)


Received

Command cmd_lint from @jviereck received. Current queue size: 0

Live output at: http://107.22.172.223:8877/04043f768493b8a/output.txt

pdf.js test bot
Collaborator

From: Bot.io (Linux)


Received

Command cmd_preview from @jviereck received. Current queue size: 0

Live output at: http://107.21.233.14:8877/9ce7abdaeeccada/output.txt

pdf.js test bot
Collaborator

From: Bot.io (Windows)


Success

Full output at http://107.22.172.223:8877/04043f768493b8a/output.txt

Total script time: 1.23 mins

  • Lint: Passed
Yury Delendik yurydelendik merged commit 665ff0d into from
Yury Delendik

Thank you for the patch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jun 26, 2012
  1. Tim de Koning
Commits on Jun 27, 2012
  1. Merge branch 'master' of github.com:kingsquare/pdf.js

    Tim de Koning authored
  2. Fixed Safari / Iphone / Ipad support further

    Tim de Koning authored
  3. lint compliance

    Tim de Koning authored
  4. Bug, seen by @yurydelendik, thanx!

    Tim de Koning authored
  5. We should use feature detection. Thanks @brendandahl

    Tim de Koning authored
Commits on Jun 28, 2012
  1. We should use feature detection. Thanks @brendandahl

    Tim de Koning authored
  2. - Feature detection for setProperty feature detection should not retu…

    Tim de Koning authored
    …rn value
    
    - Minor comment update
This page is out of date. Refresh to see the latest.
Showing with 43 additions and 12 deletions.
  1. +22 −10 src/api.js
  2. +21 −2 web/compatibility.js
32 src/api.js
View
@@ -18,7 +18,9 @@
* @return {Promise} A promise that is resolved with {PDFDocumentProxy} object.
*/
PDFJS.getDocument = function getDocument(source) {
- var url, data, headers, password, parameters = {};
+ var url, data, headers, password, parameters = {}, workerInitializedPromise,
+ workerReadyPromise, transport;
+
if (typeof source === 'string') {
url = source;
} else if (isArrayBuffer(source)) {
@@ -37,8 +39,9 @@ PDFJS.getDocument = function getDocument(source) {
'string or a parameter object');
}
- var promise = new PDFJS.Promise();
- var transport = new WorkerTransport(promise);
+ workerInitializedPromise = new PDFJS.Promise();
+ workerReadyPromise = new PDFJS.Promise();
+ transport = new WorkerTransport(workerInitializedPromise, workerReadyPromise);
if (data) {
// assuming the data is array, instantiating directly from it
transport.sendData(data, parameters);
@@ -48,24 +51,31 @@ PDFJS.getDocument = function getDocument(source) {
{
url: url,
progress: function getPDFProgress(evt) {
- if (evt.lengthComputable)
- promise.progress({
+ if (evt.lengthComputable) {
+ workerReadyPromise.progress({
loaded: evt.loaded,
total: evt.total
});
+ }
},
error: function getPDFError(e) {
- promise.reject('Unexpected server response of ' +
+ workerReadyPromise.reject('Unexpected server response of ' +
e.target.status + '.');
},
headers: headers
},
function getPDFLoad(data) {
- transport.sendData(data, parameters);
+ // sometimes the pdf has finished downloading before the web worker-test
+ // has finished. In that case the rendering of the final pdf would cause
+ // errors. We have to wait for the WorkerTransport to finalize worker-
+ // support detection
+ workerInitializedPromise.then(function workerInitialized() {
+ transport.sendData(data, parameters);
+ });
});
}
- return promise;
+ return workerReadyPromise;
};
/**
@@ -414,8 +424,8 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
* For internal use only.
*/
var WorkerTransport = (function WorkerTransportClosure() {
- function WorkerTransport(promise) {
- this.workerReadyPromise = promise;
+ function WorkerTransport(workerInitializedPromise, workerReadyPromise) {
+ this.workerReadyPromise = workerReadyPromise;
this.objs = new PDFObjects();
this.pageCache = [];
@@ -459,6 +469,7 @@ var WorkerTransport = (function WorkerTransportClosure() {
globalScope.PDFJS.disableWorker = true;
this.setupFakeWorker();
}
+ workerInitializedPromise.resolve();
}.bind(this));
var testObj = new Uint8Array(1);
@@ -474,6 +485,7 @@ var WorkerTransport = (function WorkerTransportClosure() {
// Thus, we fallback to a faked worker.
globalScope.PDFJS.disableWorker = true;
this.setupFakeWorker();
+ workerInitializedPromise.resolve();
}
WorkerTransport.prototype = {
destroy: function WorkerTransport_destroy() {
23 web/compatibility.js
View
@@ -6,6 +6,16 @@
// Checking if the typed arrays are supported
(function checkTypedArrayCompatibility() {
if (typeof Uint8Array !== 'undefined') {
+ // some mobile versions do not support subarray (e.g. safari 5 / iOS)
+ if (typeof Uint8Array.prototype.subarray === 'undefined') {
+ Uint8Array.prototype.subarray = function subarray(start, end) {
+ return new Uint8Array(this.slice(start, end));
+ };
+ Float32Array.prototype.subarray = function subarray(start, end) {
+ return new Float32Array(this.slice(start, end));
+ };
+ }
+
// some mobile version might not support Float64Array
if (typeof Float64Array === 'undefined')
window.Float64Array = Float32Array;
@@ -69,8 +79,17 @@
// Object.defineProperty() ?
(function checkObjectDefinePropertyCompatibility() {
- if (typeof Object.defineProperty !== 'undefined')
- return;
+ if (typeof Object.defineProperty !== 'undefined') {
+ // some browsers (e.g. safari) cannot use defineProperty() on DOM objects
+ // and thus the native version is not sufficient
+ var definePropertyPossible = true;
+ try {
+ Object.defineProperty(new Image(), 'id', { value: 'test' });
+ } catch (e) {
+ definePropertyPossible = false;
+ }
+ if (definePropertyPossible) return;
+ }
Object.defineProperty = function objectDefineProperty(obj, name, def) {
delete obj[name];
Something went wrong with that request. Please try again.