2
0

api_spec.js 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037
  1. /* Copyright 2017 Mozilla Foundation
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. 'use strict';
  16. var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
  17. var _util = require('../../shared/util');
  18. var _dom_utils = require('../../display/dom_utils');
  19. var _api = require('../../display/api');
  20. var _global = require('../../display/global');
  21. describe('api', function () {
  22. var basicApiUrl = new URL('../pdfs/basicapi.pdf', window.location).href;
  23. var basicApiFileLength = 105779;
  24. var CanvasFactory;
  25. beforeAll(function (done) {
  26. CanvasFactory = new _dom_utils.DOMCanvasFactory();
  27. done();
  28. });
  29. afterAll(function () {
  30. CanvasFactory = null;
  31. });
  32. function waitSome(callback) {
  33. var WAIT_TIMEOUT = 10;
  34. setTimeout(function () {
  35. callback();
  36. }, WAIT_TIMEOUT);
  37. }
  38. describe('PDFJS', function () {
  39. describe('getDocument', function () {
  40. it('creates pdf doc from URL', function (done) {
  41. var loadingTask = _global.PDFJS.getDocument(basicApiUrl);
  42. var isProgressReportedResolved = false;
  43. var progressReportedCapability = (0, _util.createPromiseCapability)();
  44. loadingTask.onProgress = function (progressData) {
  45. if (!isProgressReportedResolved) {
  46. isProgressReportedResolved = true;
  47. progressReportedCapability.resolve(progressData);
  48. }
  49. };
  50. var promises = [progressReportedCapability.promise, loadingTask.promise];
  51. Promise.all(promises).then(function (data) {
  52. expect(data[0].loaded / data[0].total > 0).toEqual(true);
  53. expect(data[1] instanceof _api.PDFDocumentProxy).toEqual(true);
  54. expect(loadingTask).toEqual(data[1].loadingTask);
  55. loadingTask.destroy().then(done);
  56. }).catch(function (reason) {
  57. done.fail(reason);
  58. });
  59. });
  60. it('creates pdf doc from URL and aborts before worker initialized', function (done) {
  61. var loadingTask = _global.PDFJS.getDocument(basicApiUrl);
  62. var destroyed = loadingTask.destroy();
  63. loadingTask.promise.then(function (reason) {
  64. done.fail('shall fail loading');
  65. }).catch(function (reason) {
  66. expect(true).toEqual(true);
  67. destroyed.then(done);
  68. });
  69. });
  70. it('creates pdf doc from URL and aborts loading after worker initialized', function (done) {
  71. var loadingTask = _global.PDFJS.getDocument(basicApiUrl);
  72. var destroyed = loadingTask._worker.promise.then(function () {
  73. return loadingTask.destroy();
  74. });
  75. destroyed.then(function (data) {
  76. expect(true).toEqual(true);
  77. done();
  78. }).catch(function (reason) {
  79. done.fail(reason);
  80. });
  81. });
  82. it('creates pdf doc from typed array', function (done) {
  83. var nonBinaryRequest = _global.PDFJS.disableWorker;
  84. var request = new XMLHttpRequest();
  85. request.open('GET', basicApiUrl, false);
  86. if (!nonBinaryRequest) {
  87. try {
  88. request.responseType = 'arraybuffer';
  89. nonBinaryRequest = request.responseType !== 'arraybuffer';
  90. } catch (e) {
  91. nonBinaryRequest = true;
  92. }
  93. }
  94. if (nonBinaryRequest && request.overrideMimeType) {
  95. request.overrideMimeType('text/plain; charset=x-user-defined');
  96. }
  97. request.send(null);
  98. var typedArrayPdf;
  99. if (nonBinaryRequest) {
  100. var data = Array.prototype.map.call(request.responseText, function (ch) {
  101. return ch.charCodeAt(0) & 0xFF;
  102. });
  103. typedArrayPdf = new Uint8Array(data);
  104. } else {
  105. typedArrayPdf = new Uint8Array(request.response);
  106. }
  107. expect(typedArrayPdf.length).toEqual(basicApiFileLength);
  108. var loadingTask = _global.PDFJS.getDocument(typedArrayPdf);
  109. loadingTask.promise.then(function (data) {
  110. expect(data instanceof _api.PDFDocumentProxy).toEqual(true);
  111. loadingTask.destroy().then(done);
  112. }).catch(function (reason) {
  113. done.fail(reason);
  114. });
  115. });
  116. it('creates pdf doc from invalid PDF file', function (done) {
  117. var url = new URL('../pdfs/bug1020226.pdf', window.location).href;
  118. var loadingTask = _global.PDFJS.getDocument(url);
  119. loadingTask.promise.then(function () {
  120. done.fail('shall fail loading');
  121. }).catch(function (error) {
  122. expect(error instanceof _util.InvalidPDFException).toEqual(true);
  123. loadingTask.destroy().then(done);
  124. });
  125. });
  126. it('creates pdf doc from non-existent URL', function (done) {
  127. var nonExistentUrl = new URL('../pdfs/non-existent.pdf', window.location).href;
  128. var loadingTask = _global.PDFJS.getDocument(nonExistentUrl);
  129. loadingTask.promise.then(function (error) {
  130. done.fail('shall fail loading');
  131. }).catch(function (error) {
  132. expect(error instanceof _util.MissingPDFException).toEqual(true);
  133. loadingTask.destroy().then(done);
  134. });
  135. });
  136. it('creates pdf doc from PDF file protected with user and owner password', function (done) {
  137. var url = new URL('../pdfs/pr6531_1.pdf', window.location).href;
  138. var loadingTask = _global.PDFJS.getDocument(url);
  139. var isPasswordNeededResolved = false;
  140. var passwordNeededCapability = (0, _util.createPromiseCapability)();
  141. var isPasswordIncorrectResolved = false;
  142. var passwordIncorrectCapability = (0, _util.createPromiseCapability)();
  143. loadingTask.onPassword = function (updatePassword, reason) {
  144. if (reason === _util.PasswordResponses.NEED_PASSWORD && !isPasswordNeededResolved) {
  145. isPasswordNeededResolved = true;
  146. passwordNeededCapability.resolve();
  147. updatePassword('qwerty');
  148. return;
  149. }
  150. if (reason === _util.PasswordResponses.INCORRECT_PASSWORD && !isPasswordIncorrectResolved) {
  151. isPasswordIncorrectResolved = true;
  152. passwordIncorrectCapability.resolve();
  153. updatePassword('asdfasdf');
  154. return;
  155. }
  156. expect(false).toEqual(true);
  157. };
  158. var promises = [passwordNeededCapability.promise, passwordIncorrectCapability.promise, loadingTask.promise];
  159. Promise.all(promises).then(function (data) {
  160. expect(data[2] instanceof _api.PDFDocumentProxy).toEqual(true);
  161. loadingTask.destroy().then(done);
  162. }).catch(function (reason) {
  163. done.fail(reason);
  164. });
  165. });
  166. it('creates pdf doc from PDF file protected with only a user password', function (done) {
  167. var url = new URL('../pdfs/pr6531_2.pdf', window.location).href;
  168. var passwordNeededLoadingTask = _global.PDFJS.getDocument({
  169. url: url,
  170. password: ''
  171. });
  172. var result1 = passwordNeededLoadingTask.promise.then(function () {
  173. done.fail('shall fail with no password');
  174. return Promise.reject(new Error('loadingTask should be rejected'));
  175. }, function (data) {
  176. expect(data instanceof _util.PasswordException).toEqual(true);
  177. expect(data.code).toEqual(_util.PasswordResponses.NEED_PASSWORD);
  178. return passwordNeededLoadingTask.destroy();
  179. });
  180. var passwordIncorrectLoadingTask = _global.PDFJS.getDocument({
  181. url: url,
  182. password: 'qwerty'
  183. });
  184. var result2 = passwordIncorrectLoadingTask.promise.then(function () {
  185. done.fail('shall fail with wrong password');
  186. return Promise.reject(new Error('loadingTask should be rejected'));
  187. }, function (data) {
  188. expect(data instanceof _util.PasswordException).toEqual(true);
  189. expect(data.code).toEqual(_util.PasswordResponses.INCORRECT_PASSWORD);
  190. return passwordIncorrectLoadingTask.destroy();
  191. });
  192. var passwordAcceptedLoadingTask = _global.PDFJS.getDocument({
  193. url: url,
  194. password: 'asdfasdf'
  195. });
  196. var result3 = passwordAcceptedLoadingTask.promise.then(function (data) {
  197. expect(data instanceof _api.PDFDocumentProxy).toEqual(true);
  198. return passwordAcceptedLoadingTask.destroy();
  199. });
  200. Promise.all([result1, result2, result3]).then(function () {
  201. done();
  202. }).catch(function (reason) {
  203. done.fail(reason);
  204. });
  205. });
  206. it('creates pdf doc from password protected PDF file and aborts/throws ' + 'in the onPassword callback (issue 7806)', function (done) {
  207. var url = new URL('../pdfs/issue3371.pdf', window.location).href;
  208. var passwordNeededLoadingTask = _global.PDFJS.getDocument(url);
  209. var passwordIncorrectLoadingTask = _global.PDFJS.getDocument({
  210. url: url,
  211. password: 'qwerty'
  212. });
  213. var passwordNeededDestroyed = void 0;
  214. passwordNeededLoadingTask.onPassword = function (callback, reason) {
  215. if (reason === _util.PasswordResponses.NEED_PASSWORD) {
  216. passwordNeededDestroyed = passwordNeededLoadingTask.destroy();
  217. return;
  218. }
  219. expect(false).toEqual(true);
  220. };
  221. var result1 = passwordNeededLoadingTask.promise.then(function () {
  222. done.fail('shall fail since the loadingTask should be destroyed');
  223. return Promise.reject(new Error('loadingTask should be rejected'));
  224. }, function (reason) {
  225. expect(reason instanceof _util.PasswordException).toEqual(true);
  226. expect(reason.code).toEqual(_util.PasswordResponses.NEED_PASSWORD);
  227. return passwordNeededDestroyed;
  228. });
  229. passwordIncorrectLoadingTask.onPassword = function (callback, reason) {
  230. if (reason === _util.PasswordResponses.INCORRECT_PASSWORD) {
  231. throw new Error('Incorrect password');
  232. }
  233. expect(false).toEqual(true);
  234. };
  235. var result2 = passwordIncorrectLoadingTask.promise.then(function () {
  236. done.fail('shall fail since the onPassword callback should throw');
  237. return Promise.reject(new Error('loadingTask should be rejected'));
  238. }, function (reason) {
  239. expect(reason instanceof _util.PasswordException).toEqual(true);
  240. expect(reason.code).toEqual(_util.PasswordResponses.INCORRECT_PASSWORD);
  241. return passwordIncorrectLoadingTask.destroy();
  242. });
  243. Promise.all([result1, result2]).then(function () {
  244. done();
  245. }).catch(function (reason) {
  246. done.fail(reason);
  247. });
  248. });
  249. });
  250. });
  251. describe('PDFWorker', function () {
  252. it('worker created or destroyed', function (done) {
  253. var worker = new _global.PDFJS.PDFWorker('test1');
  254. worker.promise.then(function () {
  255. expect(worker.name).toEqual('test1');
  256. expect(!!worker.port).toEqual(true);
  257. expect(worker.destroyed).toEqual(false);
  258. expect(!!worker._webWorker).toEqual(true);
  259. expect(worker.port === worker._webWorker).toEqual(true);
  260. worker.destroy();
  261. expect(!!worker.port).toEqual(false);
  262. expect(worker.destroyed).toEqual(true);
  263. done();
  264. }).catch(function (reason) {
  265. done.fail(reason);
  266. });
  267. });
  268. it('worker created or destroyed by getDocument', function (done) {
  269. var loadingTask = _global.PDFJS.getDocument(basicApiUrl);
  270. var worker;
  271. loadingTask.promise.then(function () {
  272. worker = loadingTask._worker;
  273. expect(!!worker).toEqual(true);
  274. });
  275. var destroyPromise = loadingTask.promise.then(function () {
  276. return loadingTask.destroy();
  277. });
  278. destroyPromise.then(function () {
  279. var destroyedWorker = loadingTask._worker;
  280. expect(!!destroyedWorker).toEqual(false);
  281. expect(worker.destroyed).toEqual(true);
  282. done();
  283. }).catch(function (reason) {
  284. done.fail(reason);
  285. });
  286. });
  287. it('worker created and can be used in getDocument', function (done) {
  288. var worker = new _global.PDFJS.PDFWorker('test1');
  289. var loadingTask = _global.PDFJS.getDocument({
  290. url: basicApiUrl,
  291. worker: worker
  292. });
  293. loadingTask.promise.then(function () {
  294. var docWorker = loadingTask._worker;
  295. expect(!!docWorker).toEqual(false);
  296. var messageHandlerPort = loadingTask._transport.messageHandler.comObj;
  297. expect(messageHandlerPort === worker.port).toEqual(true);
  298. });
  299. var destroyPromise = loadingTask.promise.then(function () {
  300. return loadingTask.destroy();
  301. });
  302. destroyPromise.then(function () {
  303. expect(worker.destroyed).toEqual(false);
  304. worker.destroy();
  305. done();
  306. }).catch(function (reason) {
  307. done.fail(reason);
  308. });
  309. });
  310. it('creates more than one worker', function (done) {
  311. var worker1 = new _global.PDFJS.PDFWorker('test1');
  312. var worker2 = new _global.PDFJS.PDFWorker('test2');
  313. var worker3 = new _global.PDFJS.PDFWorker('test3');
  314. var ready = Promise.all([worker1.promise, worker2.promise, worker3.promise]);
  315. ready.then(function () {
  316. expect(worker1.port !== worker2.port && worker1.port !== worker3.port && worker2.port !== worker3.port).toEqual(true);
  317. worker1.destroy();
  318. worker2.destroy();
  319. worker3.destroy();
  320. done();
  321. }).catch(function (reason) {
  322. done.fail(reason);
  323. });
  324. });
  325. });
  326. describe('PDFDocument', function () {
  327. var loadingTask;
  328. var doc;
  329. beforeAll(function (done) {
  330. loadingTask = _global.PDFJS.getDocument(basicApiUrl);
  331. loadingTask.promise.then(function (data) {
  332. doc = data;
  333. done();
  334. });
  335. });
  336. afterAll(function (done) {
  337. loadingTask.destroy().then(done);
  338. });
  339. it('gets number of pages', function () {
  340. expect(doc.numPages).toEqual(3);
  341. });
  342. it('gets fingerprint', function () {
  343. var fingerprint = doc.fingerprint;
  344. expect(typeof fingerprint === 'undefined' ? 'undefined' : _typeof(fingerprint)).toEqual('string');
  345. expect(fingerprint.length > 0).toEqual(true);
  346. });
  347. it('gets page', function (done) {
  348. var promise = doc.getPage(1);
  349. promise.then(function (data) {
  350. expect(data instanceof _api.PDFPageProxy).toEqual(true);
  351. expect(data.pageIndex).toEqual(0);
  352. done();
  353. }).catch(function (reason) {
  354. done.fail(reason);
  355. });
  356. });
  357. it('gets non-existent page', function (done) {
  358. var outOfRangePromise = doc.getPage(100);
  359. var nonIntegerPromise = doc.getPage(2.5);
  360. var nonNumberPromise = doc.getPage('1');
  361. outOfRangePromise = outOfRangePromise.then(function () {
  362. throw new Error('shall fail for out-of-range pageNumber parameter');
  363. }, function (reason) {
  364. expect(reason instanceof Error).toEqual(true);
  365. });
  366. nonIntegerPromise = nonIntegerPromise.then(function () {
  367. throw new Error('shall fail for non-integer pageNumber parameter');
  368. }, function (reason) {
  369. expect(reason instanceof Error).toEqual(true);
  370. });
  371. nonNumberPromise = nonNumberPromise.then(function () {
  372. throw new Error('shall fail for non-number pageNumber parameter');
  373. }, function (reason) {
  374. expect(reason instanceof Error).toEqual(true);
  375. });
  376. Promise.all([outOfRangePromise, nonIntegerPromise, nonNumberPromise]).then(function () {
  377. done();
  378. }).catch(function (reason) {
  379. done.fail(reason);
  380. });
  381. });
  382. it('gets page index', function (done) {
  383. var ref = {
  384. num: 17,
  385. gen: 0
  386. };
  387. var promise = doc.getPageIndex(ref);
  388. promise.then(function (pageIndex) {
  389. expect(pageIndex).toEqual(1);
  390. done();
  391. }).catch(function (reason) {
  392. done.fail(reason);
  393. });
  394. });
  395. it('gets invalid page index', function (done) {
  396. var ref = {
  397. num: 3,
  398. gen: 0
  399. };
  400. var promise = doc.getPageIndex(ref);
  401. promise.then(function () {
  402. done.fail('shall fail for invalid page reference.');
  403. }).catch(function (reason) {
  404. expect(reason instanceof Error).toEqual(true);
  405. done();
  406. });
  407. });
  408. it('gets destinations, from /Dests dictionary', function (done) {
  409. var promise = doc.getDestinations();
  410. promise.then(function (data) {
  411. expect(data).toEqual({
  412. chapter1: [{
  413. gen: 0,
  414. num: 17
  415. }, { name: 'XYZ' }, 0, 841.89, null]
  416. });
  417. done();
  418. }).catch(function (reason) {
  419. done.fail(reason);
  420. });
  421. });
  422. it('gets a destination, from /Dests dictionary', function (done) {
  423. var promise = doc.getDestination('chapter1');
  424. promise.then(function (data) {
  425. expect(data).toEqual([{
  426. gen: 0,
  427. num: 17
  428. }, { name: 'XYZ' }, 0, 841.89, null]);
  429. done();
  430. }).catch(function (reason) {
  431. done.fail(reason);
  432. });
  433. });
  434. it('gets a non-existent destination, from /Dests dictionary', function (done) {
  435. var promise = doc.getDestination('non-existent-named-destination');
  436. promise.then(function (data) {
  437. expect(data).toEqual(null);
  438. done();
  439. }).catch(function (reason) {
  440. done.fail(reason);
  441. });
  442. });
  443. it('gets destinations, from /Names (NameTree) dictionary', function (done) {
  444. var url = new URL('../pdfs/issue6204.pdf', window.location).href;
  445. var loadingTask = _global.PDFJS.getDocument(url);
  446. var promise = loadingTask.promise.then(function (pdfDocument) {
  447. return pdfDocument.getDestinations();
  448. });
  449. promise.then(function (destinations) {
  450. expect(destinations).toEqual({
  451. 'Page.1': [{
  452. num: 1,
  453. gen: 0
  454. }, { name: 'XYZ' }, 0, 375, null],
  455. 'Page.2': [{
  456. num: 6,
  457. gen: 0
  458. }, { name: 'XYZ' }, 0, 375, null]
  459. });
  460. loadingTask.destroy().then(done);
  461. }).catch(function (reason) {
  462. done.fail(reason);
  463. });
  464. });
  465. it('gets a destination, from /Names (NameTree) dictionary', function (done) {
  466. var url = new URL('../pdfs/issue6204.pdf', window.location).href;
  467. var loadingTask = _global.PDFJS.getDocument(url);
  468. var promise = loadingTask.promise.then(function (pdfDocument) {
  469. return pdfDocument.getDestination('Page.1');
  470. });
  471. promise.then(function (destination) {
  472. expect(destination).toEqual([{
  473. num: 1,
  474. gen: 0
  475. }, { name: 'XYZ' }, 0, 375, null]);
  476. loadingTask.destroy().then(done);
  477. }).catch(function (reason) {
  478. done.fail(reason);
  479. });
  480. });
  481. it('gets a non-existent destination, from /Names (NameTree) dictionary', function (done) {
  482. var url = new URL('../pdfs/issue6204.pdf', window.location).href;
  483. var loadingTask = _global.PDFJS.getDocument(url);
  484. var promise = loadingTask.promise.then(function (pdfDocument) {
  485. return pdfDocument.getDestination('non-existent-named-destination');
  486. });
  487. promise.then(function (destination) {
  488. expect(destination).toEqual(null);
  489. loadingTask.destroy().then(done);
  490. }).catch(function (reason) {
  491. done.fail(reason);
  492. });
  493. });
  494. it('gets non-existent page labels', function (done) {
  495. var promise = doc.getPageLabels();
  496. promise.then(function (data) {
  497. expect(data).toEqual(null);
  498. done();
  499. }).catch(function (reason) {
  500. done.fail(reason);
  501. });
  502. });
  503. it('gets page labels', function (done) {
  504. var url0 = new URL('../pdfs/bug793632.pdf', window.location).href;
  505. var loadingTask0 = _global.PDFJS.getDocument(url0);
  506. var promise0 = loadingTask0.promise.then(function (pdfDoc) {
  507. return pdfDoc.getPageLabels();
  508. });
  509. var url1 = new URL('../pdfs/issue1453.pdf', window.location).href;
  510. var loadingTask1 = _global.PDFJS.getDocument(url1);
  511. var promise1 = loadingTask1.promise.then(function (pdfDoc) {
  512. return pdfDoc.getPageLabels();
  513. });
  514. var url2 = new URL('../pdfs/rotation.pdf', window.location).href;
  515. var loadingTask2 = _global.PDFJS.getDocument(url2);
  516. var promise2 = loadingTask2.promise.then(function (pdfDoc) {
  517. return pdfDoc.getPageLabels();
  518. });
  519. var url3 = new URL('../pdfs/bad-PageLabels.pdf', window.location).href;
  520. var loadingTask3 = _global.PDFJS.getDocument(url3);
  521. var promise3 = loadingTask3.promise.then(function (pdfDoc) {
  522. return pdfDoc.getPageLabels();
  523. });
  524. Promise.all([promise0, promise1, promise2, promise3]).then(function (pageLabels) {
  525. expect(pageLabels[0]).toEqual(['i', 'ii', 'iii', '1']);
  526. expect(pageLabels[1]).toEqual(['Front Page1']);
  527. expect(pageLabels[2]).toEqual(['1', '2']);
  528. expect(pageLabels[3]).toEqual(['X3']);
  529. Promise.all([loadingTask0.destroy(), loadingTask1.destroy(), loadingTask2.destroy(), loadingTask3.destroy()]).then(done);
  530. }).catch(function (reason) {
  531. done.fail(reason);
  532. });
  533. });
  534. it('gets non-existent attachments', function (done) {
  535. var promise = doc.getAttachments();
  536. promise.then(function (data) {
  537. expect(data).toEqual(null);
  538. done();
  539. }).catch(function (reason) {
  540. done.fail(reason);
  541. });
  542. });
  543. it('gets attachments', function (done) {
  544. var url = new URL('../pdfs/bug766138.pdf', window.location).href;
  545. var loadingTask = _global.PDFJS.getDocument(url);
  546. var promise = loadingTask.promise.then(function (pdfDoc) {
  547. return pdfDoc.getAttachments();
  548. });
  549. promise.then(function (data) {
  550. var attachment = data['Press Quality.joboptions'];
  551. expect(attachment.filename).toEqual('Press Quality.joboptions');
  552. expect(attachment.content instanceof Uint8Array).toBeTruthy();
  553. expect(attachment.content.length).toEqual(30098);
  554. loadingTask.destroy().then(done);
  555. }).catch(function (reason) {
  556. done.fail(reason);
  557. });
  558. });
  559. it('gets javascript', function (done) {
  560. var promise = doc.getJavaScript();
  561. promise.then(function (data) {
  562. expect(data).toEqual([]);
  563. done();
  564. }).catch(function (reason) {
  565. done.fail(reason);
  566. });
  567. });
  568. var viewerPrintRegExp = /\bprint\s*\(/;
  569. it('gets javascript with printing instructions (Print action)', function (done) {
  570. var pdfUrl = new URL('../pdfs/bug1001080.pdf', window.location).href;
  571. var loadingTask = _global.PDFJS.getDocument(pdfUrl);
  572. var promise = loadingTask.promise.then(function (doc) {
  573. return doc.getJavaScript();
  574. });
  575. promise.then(function (data) {
  576. expect(data).toEqual(['print({});']);
  577. expect(data[0]).toMatch(viewerPrintRegExp);
  578. loadingTask.destroy().then(done);
  579. }).catch(function (reason) {
  580. done.fail(reason);
  581. });
  582. });
  583. it('gets javascript with printing instructions (JS action)', function (done) {
  584. var pdfUrl = new URL('../pdfs/issue6106.pdf', window.location).href;
  585. var loadingTask = _global.PDFJS.getDocument(pdfUrl);
  586. var promise = loadingTask.promise.then(function (doc) {
  587. return doc.getJavaScript();
  588. });
  589. promise.then(function (data) {
  590. expect(data).toEqual(['this.print({bUI:true,bSilent:false,bShrinkToFit:true});']);
  591. expect(data[0]).toMatch(viewerPrintRegExp);
  592. loadingTask.destroy().then(done);
  593. }).catch(function (reason) {
  594. done.fail(reason);
  595. });
  596. });
  597. it('gets non-existent outline', function (done) {
  598. var url = new URL('../pdfs/tracemonkey.pdf', window.location).href;
  599. var loadingTask = _global.PDFJS.getDocument(url);
  600. var promise = loadingTask.promise.then(function (pdfDocument) {
  601. return pdfDocument.getOutline();
  602. });
  603. promise.then(function (outline) {
  604. expect(outline).toEqual(null);
  605. loadingTask.destroy().then(done);
  606. }).catch(function (reason) {
  607. done.fail(reason);
  608. });
  609. });
  610. it('gets outline', function (done) {
  611. var promise = doc.getOutline();
  612. promise.then(function (outline) {
  613. expect(outline instanceof Array).toEqual(true);
  614. expect(outline.length).toEqual(2);
  615. var outlineItem = outline[1];
  616. expect(outlineItem.title).toEqual('Chapter 1');
  617. expect(outlineItem.dest instanceof Array).toEqual(true);
  618. expect(outlineItem.url).toEqual(null);
  619. expect(outlineItem.unsafeUrl).toBeUndefined();
  620. expect(outlineItem.newWindow).toBeUndefined();
  621. expect(outlineItem.bold).toEqual(true);
  622. expect(outlineItem.italic).toEqual(false);
  623. expect(outlineItem.color).toEqual(new Uint8Array([0, 64, 128]));
  624. expect(outlineItem.items.length).toEqual(1);
  625. expect(outlineItem.items[0].title).toEqual('Paragraph 1.1');
  626. done();
  627. }).catch(function (reason) {
  628. done.fail(reason);
  629. });
  630. });
  631. it('gets outline containing a url', function (done) {
  632. var pdfUrl = new URL('../pdfs/issue3214.pdf', window.location).href;
  633. var loadingTask = _global.PDFJS.getDocument(pdfUrl);
  634. loadingTask.promise.then(function (pdfDocument) {
  635. pdfDocument.getOutline().then(function (outline) {
  636. expect(outline instanceof Array).toEqual(true);
  637. expect(outline.length).toEqual(5);
  638. var outlineItemTwo = outline[2];
  639. expect(_typeof(outlineItemTwo.title)).toEqual('string');
  640. expect(outlineItemTwo.dest).toEqual(null);
  641. expect(outlineItemTwo.url).toEqual('http://google.com/');
  642. expect(outlineItemTwo.unsafeUrl).toEqual('http://google.com');
  643. expect(outlineItemTwo.newWindow).toBeUndefined();
  644. var outlineItemOne = outline[1];
  645. expect(outlineItemOne.bold).toEqual(false);
  646. expect(outlineItemOne.italic).toEqual(true);
  647. expect(outlineItemOne.color).toEqual(new Uint8Array([0, 0, 0]));
  648. loadingTask.destroy().then(done);
  649. });
  650. }).catch(function (reason) {
  651. done.fail(reason);
  652. });
  653. });
  654. it('gets metadata', function (done) {
  655. var promise = doc.getMetadata();
  656. promise.then(function (metadata) {
  657. expect(metadata.info['Title']).toEqual('Basic API Test');
  658. expect(metadata.info['PDFFormatVersion']).toEqual('1.7');
  659. expect(metadata.metadata.get('dc:title')).toEqual('Basic API Test');
  660. done();
  661. }).catch(function (reason) {
  662. done.fail(reason);
  663. });
  664. });
  665. it('gets data', function (done) {
  666. var promise = doc.getData();
  667. promise.then(function (data) {
  668. expect(data instanceof Uint8Array).toEqual(true);
  669. expect(data.length).toEqual(basicApiFileLength);
  670. done();
  671. }).catch(function (reason) {
  672. done.fail(reason);
  673. });
  674. });
  675. it('gets download info', function (done) {
  676. var promise = doc.getDownloadInfo();
  677. promise.then(function (data) {
  678. expect(data).toEqual({ length: basicApiFileLength });
  679. done();
  680. }).catch(function (reason) {
  681. done.fail(reason);
  682. });
  683. });
  684. it('gets stats', function (done) {
  685. var promise = doc.getStats();
  686. promise.then(function (stats) {
  687. expect(stats).toEqual({
  688. streamTypes: [],
  689. fontTypes: []
  690. });
  691. done();
  692. }).catch(function (reason) {
  693. done.fail(reason);
  694. });
  695. });
  696. it('checks that fingerprints are unique', function (done) {
  697. var url1 = new URL('../pdfs/issue4436r.pdf', window.location).href;
  698. var loadingTask1 = _global.PDFJS.getDocument(url1);
  699. var url2 = new URL('../pdfs/issue4575.pdf', window.location).href;
  700. var loadingTask2 = _global.PDFJS.getDocument(url2);
  701. var promises = [loadingTask1.promise, loadingTask2.promise];
  702. Promise.all(promises).then(function (data) {
  703. var fingerprint1 = data[0].fingerprint;
  704. expect(typeof fingerprint1 === 'undefined' ? 'undefined' : _typeof(fingerprint1)).toEqual('string');
  705. expect(fingerprint1.length > 0).toEqual(true);
  706. var fingerprint2 = data[1].fingerprint;
  707. expect(typeof fingerprint2 === 'undefined' ? 'undefined' : _typeof(fingerprint2)).toEqual('string');
  708. expect(fingerprint2.length > 0).toEqual(true);
  709. expect(fingerprint1).not.toEqual(fingerprint2);
  710. Promise.all([loadingTask1.destroy(), loadingTask2.destroy()]).then(done);
  711. }).catch(function (reason) {
  712. done.fail(reason);
  713. });
  714. });
  715. });
  716. describe('Page', function () {
  717. var loadingTask;
  718. var pdfDocument, page;
  719. beforeAll(function (done) {
  720. loadingTask = _global.PDFJS.getDocument(basicApiUrl);
  721. loadingTask.promise.then(function (doc) {
  722. pdfDocument = doc;
  723. pdfDocument.getPage(1).then(function (data) {
  724. page = data;
  725. done();
  726. });
  727. }).catch(function (reason) {
  728. done.fail(reason);
  729. });
  730. });
  731. afterAll(function (done) {
  732. loadingTask.destroy().then(done);
  733. });
  734. it('gets page number', function () {
  735. expect(page.pageNumber).toEqual(1);
  736. });
  737. it('gets rotate', function () {
  738. expect(page.rotate).toEqual(0);
  739. });
  740. it('gets ref', function () {
  741. expect(page.ref).toEqual({
  742. num: 15,
  743. gen: 0
  744. });
  745. });
  746. it('gets userUnit', function () {
  747. expect(page.userUnit).toEqual(1.0);
  748. });
  749. it('gets view', function () {
  750. expect(page.view).toEqual([0, 0, 595.28, 841.89]);
  751. });
  752. it('gets viewport', function () {
  753. var viewport = page.getViewport(1.5, 90);
  754. expect(viewport.viewBox).toEqual(page.view);
  755. expect(viewport.scale).toEqual(1.5);
  756. expect(viewport.rotation).toEqual(90);
  757. expect(viewport.transform).toEqual([0, 1.5, 1.5, 0, 0, 0]);
  758. expect(viewport.width).toEqual(1262.835);
  759. expect(viewport.height).toEqual(892.92);
  760. });
  761. it('gets annotations', function (done) {
  762. var defaultPromise = page.getAnnotations().then(function (data) {
  763. expect(data.length).toEqual(4);
  764. });
  765. var displayPromise = page.getAnnotations({ intent: 'display' }).then(function (data) {
  766. expect(data.length).toEqual(4);
  767. });
  768. var printPromise = page.getAnnotations({ intent: 'print' }).then(function (data) {
  769. expect(data.length).toEqual(4);
  770. });
  771. Promise.all([defaultPromise, displayPromise, printPromise]).then(function () {
  772. done();
  773. }).catch(function (reason) {
  774. done.fail(reason);
  775. });
  776. });
  777. it('gets annotations containing relative URLs (bug 766086)', function (done) {
  778. var url = new URL('../pdfs/bug766086.pdf', window.location).href;
  779. var defaultLoadingTask = _global.PDFJS.getDocument(url);
  780. var defaultPromise = defaultLoadingTask.promise.then(function (pdfDoc) {
  781. return pdfDoc.getPage(1).then(function (pdfPage) {
  782. return pdfPage.getAnnotations();
  783. });
  784. });
  785. var docBaseUrlLoadingTask = _global.PDFJS.getDocument({
  786. url: url,
  787. docBaseUrl: 'http://www.example.com/test/pdfs/qwerty.pdf'
  788. });
  789. var docBaseUrlPromise = docBaseUrlLoadingTask.promise.then(function (pdfDoc) {
  790. return pdfDoc.getPage(1).then(function (pdfPage) {
  791. return pdfPage.getAnnotations();
  792. });
  793. });
  794. var invalidDocBaseUrlLoadingTask = _global.PDFJS.getDocument({
  795. url: url,
  796. docBaseUrl: 'qwerty.pdf'
  797. });
  798. var invalidDocBaseUrlPromise = invalidDocBaseUrlLoadingTask.promise.then(function (pdfDoc) {
  799. return pdfDoc.getPage(1).then(function (pdfPage) {
  800. return pdfPage.getAnnotations();
  801. });
  802. });
  803. Promise.all([defaultPromise, docBaseUrlPromise, invalidDocBaseUrlPromise]).then(function (data) {
  804. var defaultAnnotations = data[0];
  805. var docBaseUrlAnnotations = data[1];
  806. var invalidDocBaseUrlAnnotations = data[2];
  807. expect(defaultAnnotations[0].url).toBeUndefined();
  808. expect(defaultAnnotations[0].unsafeUrl).toEqual('../../0021/002156/215675E.pdf#nameddest=15');
  809. expect(docBaseUrlAnnotations[0].url).toEqual('http://www.example.com/0021/002156/215675E.pdf#nameddest=15');
  810. expect(docBaseUrlAnnotations[0].unsafeUrl).toEqual('../../0021/002156/215675E.pdf#nameddest=15');
  811. expect(invalidDocBaseUrlAnnotations[0].url).toBeUndefined();
  812. expect(invalidDocBaseUrlAnnotations[0].unsafeUrl).toEqual('../../0021/002156/215675E.pdf#nameddest=15');
  813. Promise.all([defaultLoadingTask.destroy(), docBaseUrlLoadingTask.destroy(), invalidDocBaseUrlLoadingTask.destroy()]).then(done);
  814. }).catch(function (reason) {
  815. done.fail(reason);
  816. });
  817. });
  818. it('gets text content', function (done) {
  819. var defaultPromise = page.getTextContent();
  820. var parametersPromise = page.getTextContent({
  821. normalizeWhitespace: true,
  822. disableCombineTextItems: true
  823. });
  824. var promises = [defaultPromise, parametersPromise];
  825. Promise.all(promises).then(function (data) {
  826. expect(!!data[0].items).toEqual(true);
  827. expect(data[0].items.length).toEqual(7);
  828. expect(!!data[0].styles).toEqual(true);
  829. expect(JSON.stringify(data[0])).toEqual(JSON.stringify(data[1]));
  830. done();
  831. }).catch(function (reason) {
  832. done.fail(reason);
  833. });
  834. });
  835. it('gets operator list', function (done) {
  836. var promise = page.getOperatorList();
  837. promise.then(function (oplist) {
  838. expect(!!oplist.fnArray).toEqual(true);
  839. expect(!!oplist.argsArray).toEqual(true);
  840. expect(oplist.lastChunk).toEqual(true);
  841. done();
  842. }).catch(function (reason) {
  843. done.fail(reason);
  844. });
  845. });
  846. it('gets stats after parsing page', function (done) {
  847. var promise = page.getOperatorList().then(function () {
  848. return pdfDocument.getStats();
  849. });
  850. var expectedStreamTypes = [];
  851. expectedStreamTypes[_util.StreamType.FLATE] = true;
  852. var expectedFontTypes = [];
  853. expectedFontTypes[_util.FontType.TYPE1] = true;
  854. expectedFontTypes[_util.FontType.CIDFONTTYPE2] = true;
  855. promise.then(function (stats) {
  856. expect(stats).toEqual({
  857. streamTypes: expectedStreamTypes,
  858. fontTypes: expectedFontTypes
  859. });
  860. done();
  861. }).catch(function (reason) {
  862. done.fail(reason);
  863. });
  864. });
  865. it('cancels rendering of page', function (done) {
  866. var viewport = page.getViewport(1);
  867. var canvasAndCtx = CanvasFactory.create(viewport.width, viewport.height);
  868. var renderTask = page.render({
  869. canvasContext: canvasAndCtx.context,
  870. viewport: viewport
  871. });
  872. renderTask.cancel();
  873. renderTask.promise.then(function () {
  874. done.fail('shall cancel rendering');
  875. }).catch(function (error) {
  876. expect(error instanceof _dom_utils.RenderingCancelledException).toEqual(true);
  877. expect(error.type).toEqual('canvas');
  878. CanvasFactory.destroy(canvasAndCtx);
  879. done();
  880. });
  881. });
  882. });
  883. describe('Multiple PDFJS instances', function () {
  884. var pdf1 = new URL('../pdfs/tracemonkey.pdf', window.location).href;
  885. var pdf2 = new URL('../pdfs/TAMReview.pdf', window.location).href;
  886. var pdf3 = new URL('../pdfs/issue6068.pdf', window.location).href;
  887. var loadingTasks = [];
  888. var pdfDocuments = [];
  889. function renderPDF(filename) {
  890. var loadingTask = _global.PDFJS.getDocument(filename);
  891. loadingTasks.push(loadingTask);
  892. return loadingTask.promise.then(function (pdf) {
  893. pdfDocuments.push(pdf);
  894. return pdf.getPage(1);
  895. }).then(function (page) {
  896. var viewport = page.getViewport(1.2);
  897. var canvasAndCtx = CanvasFactory.create(viewport.width, viewport.height);
  898. return page.render({
  899. canvasContext: canvasAndCtx.context,
  900. viewport: viewport
  901. }).then(function () {
  902. var data = canvasAndCtx.canvas.toDataURL();
  903. CanvasFactory.destroy(canvasAndCtx);
  904. return data;
  905. });
  906. });
  907. }
  908. afterEach(function (done) {
  909. var destroyPromises = pdfDocuments.map(function (pdfDocument) {
  910. return pdfDocument.destroy();
  911. });
  912. var destroyPromises2 = loadingTasks.map(function (loadingTask) {
  913. return loadingTask.destroy();
  914. });
  915. Promise.all(destroyPromises.concat(destroyPromises2)).then(function () {
  916. done();
  917. });
  918. });
  919. it('should correctly render PDFs in parallel', function (done) {
  920. var baseline1, baseline2, baseline3;
  921. var promiseDone = renderPDF(pdf1).then(function (data1) {
  922. baseline1 = data1;
  923. return renderPDF(pdf2);
  924. }).then(function (data2) {
  925. baseline2 = data2;
  926. return renderPDF(pdf3);
  927. }).then(function (data3) {
  928. baseline3 = data3;
  929. return Promise.all([renderPDF(pdf1), renderPDF(pdf2), renderPDF(pdf3)]);
  930. }).then(function (dataUrls) {
  931. expect(dataUrls[0]).toEqual(baseline1);
  932. expect(dataUrls[1]).toEqual(baseline2);
  933. expect(dataUrls[2]).toEqual(baseline3);
  934. return true;
  935. });
  936. promiseDone.then(function () {
  937. done();
  938. }).catch(function (reason) {
  939. done.fail(reason);
  940. });
  941. });
  942. });
  943. describe('PDFDataRangeTransport', function () {
  944. var pdfPath = new URL('../pdfs/tracemonkey.pdf', window.location).href;
  945. var loadPromise;
  946. function getDocumentData() {
  947. if (loadPromise) {
  948. return loadPromise;
  949. }
  950. loadPromise = new Promise(function (resolve, reject) {
  951. var xhr = new XMLHttpRequest(pdfPath);
  952. xhr.open('GET', pdfPath);
  953. xhr.responseType = 'arraybuffer';
  954. xhr.onload = function () {
  955. resolve(new Uint8Array(xhr.response));
  956. };
  957. xhr.onerror = function () {
  958. reject(new Error('PDF is not loaded'));
  959. };
  960. xhr.send();
  961. });
  962. return loadPromise;
  963. }
  964. it('should fetch document info and page using ranges', function (done) {
  965. var transport;
  966. var initialDataLength = 4000;
  967. var fetches = 0;
  968. var getDocumentPromise = getDocumentData().then(function (data) {
  969. var initialData = data.subarray(0, initialDataLength);
  970. transport = new _global.PDFJS.PDFDataRangeTransport(data.length, initialData);
  971. transport.requestDataRange = function (begin, end) {
  972. fetches++;
  973. waitSome(function () {
  974. transport.onDataProgress(4000);
  975. transport.onDataRange(begin, data.subarray(begin, end));
  976. });
  977. };
  978. var loadingTask = _global.PDFJS.getDocument(transport);
  979. return loadingTask.promise;
  980. });
  981. var pdfDocument;
  982. var getPagePromise = getDocumentPromise.then(function (pdfDocument_) {
  983. pdfDocument = pdfDocument_;
  984. var pagePromise = pdfDocument.getPage(10);
  985. return pagePromise;
  986. });
  987. getPagePromise.then(function (page) {
  988. expect(pdfDocument.numPages).toEqual(14);
  989. expect(page.rotate).toEqual(0);
  990. expect(fetches).toBeGreaterThan(2);
  991. done();
  992. }).catch(function (reason) {
  993. done.fail(reason);
  994. });
  995. });
  996. it('should fetch document info and page using range and streaming', function (done) {
  997. var transport;
  998. var initialDataLength = 4000;
  999. var fetches = 0;
  1000. var getDocumentPromise = getDocumentData().then(function (data) {
  1001. var initialData = data.subarray(0, initialDataLength);
  1002. transport = new _global.PDFJS.PDFDataRangeTransport(data.length, initialData);
  1003. transport.requestDataRange = function (begin, end) {
  1004. fetches++;
  1005. if (fetches === 1) {
  1006. transport.onDataProgressiveRead(data.subarray(initialDataLength));
  1007. }
  1008. waitSome(function () {
  1009. transport.onDataRange(begin, data.subarray(begin, end));
  1010. });
  1011. };
  1012. var loadingTask = _global.PDFJS.getDocument(transport);
  1013. return loadingTask.promise;
  1014. });
  1015. var pdfDocument;
  1016. var getPagePromise = getDocumentPromise.then(function (pdfDocument_) {
  1017. pdfDocument = pdfDocument_;
  1018. var pagePromise = pdfDocument.getPage(10);
  1019. return pagePromise;
  1020. });
  1021. getPagePromise.then(function (page) {
  1022. expect(pdfDocument.numPages).toEqual(14);
  1023. expect(page.rotate).toEqual(0);
  1024. expect(fetches).toEqual(1);
  1025. done();
  1026. }).catch(function (reason) {
  1027. done.fail(reason);
  1028. });
  1029. });
  1030. });
  1031. });