annotation_spec.js 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093
  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 _annotation = require('../../core/annotation');
  17. var _util = require('../../shared/util');
  18. var _primitives = require('../../core/primitives');
  19. var _parser = require('../../core/parser');
  20. var _stream = require('../../core/stream');
  21. var _test_utils = require('./test_utils');
  22. describe('annotation', function () {
  23. function PDFManagerMock(params) {
  24. this.docBaseUrl = params.docBaseUrl || null;
  25. }
  26. PDFManagerMock.prototype = {};
  27. function IdFactoryMock(params) {
  28. var uniquePrefix = params.prefix || 'p0_';
  29. var idCounters = { obj: params.startObjId || 0 };
  30. return {
  31. createObjId: function createObjId() {
  32. return uniquePrefix + ++idCounters.obj;
  33. }
  34. };
  35. }
  36. IdFactoryMock.prototype = {};
  37. var pdfManagerMock, idFactoryMock;
  38. beforeAll(function (done) {
  39. pdfManagerMock = new PDFManagerMock({ docBaseUrl: null });
  40. idFactoryMock = new IdFactoryMock({});
  41. done();
  42. });
  43. afterAll(function () {
  44. pdfManagerMock = null;
  45. idFactoryMock = null;
  46. });
  47. describe('AnnotationFactory', function () {
  48. it('should get id for annotation', function () {
  49. var annotationDict = new _primitives.Dict();
  50. annotationDict.set('Type', _primitives.Name.get('Annot'));
  51. annotationDict.set('Subtype', _primitives.Name.get('Link'));
  52. var annotationRef = new _primitives.Ref(10, 0);
  53. var xref = new _test_utils.XRefMock([{
  54. ref: annotationRef,
  55. data: annotationDict
  56. }]);
  57. var annotation = _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  58. var data = annotation.data;
  59. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  60. expect(data.id).toEqual('10R');
  61. });
  62. it('should handle, and get fallback id\'s for, annotations that are not ' + 'indirect objects (issue 7569)', function () {
  63. var annotationDict = new _primitives.Dict();
  64. annotationDict.set('Type', _primitives.Name.get('Annot'));
  65. annotationDict.set('Subtype', _primitives.Name.get('Link'));
  66. var xref = new _test_utils.XRefMock();
  67. var idFactory = new IdFactoryMock({
  68. prefix: 'p0_',
  69. startObjId: 0
  70. });
  71. var annotation1 = _annotation.AnnotationFactory.create(xref, annotationDict, pdfManagerMock, idFactory);
  72. var annotation2 = _annotation.AnnotationFactory.create(xref, annotationDict, pdfManagerMock, idFactory);
  73. var data1 = annotation1.data,
  74. data2 = annotation2.data;
  75. expect(data1.annotationType).toEqual(_util.AnnotationType.LINK);
  76. expect(data2.annotationType).toEqual(_util.AnnotationType.LINK);
  77. expect(data1.id).toEqual('annot_p0_1');
  78. expect(data2.id).toEqual('annot_p0_2');
  79. });
  80. it('should handle missing /Subtype', function () {
  81. var annotationDict = new _primitives.Dict();
  82. annotationDict.set('Type', _primitives.Name.get('Annot'));
  83. var annotationRef = new _primitives.Ref(1, 0);
  84. var xref = new _test_utils.XRefMock([{
  85. ref: annotationRef,
  86. data: annotationDict
  87. }]);
  88. var annotation = _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  89. var data = annotation.data;
  90. expect(data.annotationType).toBeUndefined();
  91. });
  92. });
  93. describe('Annotation', function () {
  94. var dict, ref;
  95. beforeAll(function (done) {
  96. dict = new _primitives.Dict();
  97. ref = new _primitives.Ref(1, 0);
  98. done();
  99. });
  100. afterAll(function () {
  101. dict = ref = null;
  102. });
  103. it('should set and get flags', function () {
  104. var annotation = new _annotation.Annotation({
  105. dict: dict,
  106. ref: ref
  107. });
  108. annotation.setFlags(13);
  109. expect(annotation.hasFlag(_util.AnnotationFlag.INVISIBLE)).toEqual(true);
  110. expect(annotation.hasFlag(_util.AnnotationFlag.NOZOOM)).toEqual(true);
  111. expect(annotation.hasFlag(_util.AnnotationFlag.PRINT)).toEqual(true);
  112. expect(annotation.hasFlag(_util.AnnotationFlag.READONLY)).toEqual(false);
  113. });
  114. it('should be viewable and not printable by default', function () {
  115. var annotation = new _annotation.Annotation({
  116. dict: dict,
  117. ref: ref
  118. });
  119. expect(annotation.viewable).toEqual(true);
  120. expect(annotation.printable).toEqual(false);
  121. });
  122. it('should set and get a valid rectangle', function () {
  123. var annotation = new _annotation.Annotation({
  124. dict: dict,
  125. ref: ref
  126. });
  127. annotation.setRectangle([117, 694, 164.298, 720]);
  128. expect(annotation.rectangle).toEqual([117, 694, 164.298, 720]);
  129. });
  130. it('should not set and get an invalid rectangle', function () {
  131. var annotation = new _annotation.Annotation({
  132. dict: dict,
  133. ref: ref
  134. });
  135. annotation.setRectangle([117, 694, 164.298]);
  136. expect(annotation.rectangle).toEqual([0, 0, 0, 0]);
  137. });
  138. it('should reject a color if it is not an array', function () {
  139. var annotation = new _annotation.Annotation({
  140. dict: dict,
  141. ref: ref
  142. });
  143. annotation.setColor('red');
  144. expect(annotation.color).toEqual(new Uint8Array([0, 0, 0]));
  145. });
  146. it('should set and get a transparent color', function () {
  147. var annotation = new _annotation.Annotation({
  148. dict: dict,
  149. ref: ref
  150. });
  151. annotation.setColor([]);
  152. expect(annotation.color).toEqual(null);
  153. });
  154. it('should set and get a grayscale color', function () {
  155. var annotation = new _annotation.Annotation({
  156. dict: dict,
  157. ref: ref
  158. });
  159. annotation.setColor([0.4]);
  160. expect(annotation.color).toEqual(new Uint8Array([102, 102, 102]));
  161. });
  162. it('should set and get an RGB color', function () {
  163. var annotation = new _annotation.Annotation({
  164. dict: dict,
  165. ref: ref
  166. });
  167. annotation.setColor([0, 0, 1]);
  168. expect(annotation.color).toEqual(new Uint8Array([0, 0, 255]));
  169. });
  170. it('should set and get a CMYK color', function () {
  171. var annotation = new _annotation.Annotation({
  172. dict: dict,
  173. ref: ref
  174. });
  175. annotation.setColor([0.1, 0.92, 0.84, 0.02]);
  176. expect(annotation.color).toEqual(new Uint8Array([233, 59, 47]));
  177. });
  178. it('should not set and get an invalid color', function () {
  179. var annotation = new _annotation.Annotation({
  180. dict: dict,
  181. ref: ref
  182. });
  183. annotation.setColor([0.4, 0.6]);
  184. expect(annotation.color).toEqual(new Uint8Array([0, 0, 0]));
  185. });
  186. });
  187. describe('AnnotationBorderStyle', function () {
  188. it('should set and get a valid width', function () {
  189. var borderStyle = new _annotation.AnnotationBorderStyle();
  190. borderStyle.setWidth(3);
  191. expect(borderStyle.width).toEqual(3);
  192. });
  193. it('should not set and get an invalid width', function () {
  194. var borderStyle = new _annotation.AnnotationBorderStyle();
  195. borderStyle.setWidth('three');
  196. expect(borderStyle.width).toEqual(1);
  197. });
  198. it('should set and get a valid style', function () {
  199. var borderStyle = new _annotation.AnnotationBorderStyle();
  200. borderStyle.setStyle(_primitives.Name.get('D'));
  201. expect(borderStyle.style).toEqual(_util.AnnotationBorderStyleType.DASHED);
  202. });
  203. it('should not set and get an invalid style', function () {
  204. var borderStyle = new _annotation.AnnotationBorderStyle();
  205. borderStyle.setStyle('Dashed');
  206. expect(borderStyle.style).toEqual(_util.AnnotationBorderStyleType.SOLID);
  207. });
  208. it('should set and get a valid dash array', function () {
  209. var borderStyle = new _annotation.AnnotationBorderStyle();
  210. borderStyle.setDashArray([1, 2, 3]);
  211. expect(borderStyle.dashArray).toEqual([1, 2, 3]);
  212. });
  213. it('should not set and get an invalid dash array', function () {
  214. var borderStyle = new _annotation.AnnotationBorderStyle();
  215. borderStyle.setDashArray([0, 0]);
  216. expect(borderStyle.dashArray).toEqual([3]);
  217. });
  218. it('should set and get a valid horizontal corner radius', function () {
  219. var borderStyle = new _annotation.AnnotationBorderStyle();
  220. borderStyle.setHorizontalCornerRadius(3);
  221. expect(borderStyle.horizontalCornerRadius).toEqual(3);
  222. });
  223. it('should not set and get an invalid horizontal corner radius', function () {
  224. var borderStyle = new _annotation.AnnotationBorderStyle();
  225. borderStyle.setHorizontalCornerRadius('three');
  226. expect(borderStyle.horizontalCornerRadius).toEqual(0);
  227. });
  228. it('should set and get a valid vertical corner radius', function () {
  229. var borderStyle = new _annotation.AnnotationBorderStyle();
  230. borderStyle.setVerticalCornerRadius(3);
  231. expect(borderStyle.verticalCornerRadius).toEqual(3);
  232. });
  233. it('should not set and get an invalid horizontal corner radius', function () {
  234. var borderStyle = new _annotation.AnnotationBorderStyle();
  235. borderStyle.setVerticalCornerRadius('three');
  236. expect(borderStyle.verticalCornerRadius).toEqual(0);
  237. });
  238. });
  239. describe('LinkAnnotation', function () {
  240. it('should correctly parse a URI action', function () {
  241. var actionDict = new _primitives.Dict();
  242. actionDict.set('Type', _primitives.Name.get('Action'));
  243. actionDict.set('S', _primitives.Name.get('URI'));
  244. actionDict.set('URI', 'http://www.ctan.org/tex-archive/info/lshort');
  245. var annotationDict = new _primitives.Dict();
  246. annotationDict.set('Type', _primitives.Name.get('Annot'));
  247. annotationDict.set('Subtype', _primitives.Name.get('Link'));
  248. annotationDict.set('A', actionDict);
  249. var annotationRef = new _primitives.Ref(820, 0);
  250. var xref = new _test_utils.XRefMock([{
  251. ref: annotationRef,
  252. data: annotationDict
  253. }]);
  254. var annotation = _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  255. var data = annotation.data;
  256. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  257. expect(data.url).toEqual('http://www.ctan.org/tex-archive/info/lshort');
  258. expect(data.unsafeUrl).toEqual('http://www.ctan.org/tex-archive/info/lshort');
  259. expect(data.dest).toBeUndefined();
  260. });
  261. it('should correctly parse a URI action, where the URI entry ' + 'is missing a protocol', function () {
  262. var actionDict = new _primitives.Dict();
  263. actionDict.set('Type', _primitives.Name.get('Action'));
  264. actionDict.set('S', _primitives.Name.get('URI'));
  265. actionDict.set('URI', 'www.hmrc.gov.uk');
  266. var annotationDict = new _primitives.Dict();
  267. annotationDict.set('Type', _primitives.Name.get('Annot'));
  268. annotationDict.set('Subtype', _primitives.Name.get('Link'));
  269. annotationDict.set('A', actionDict);
  270. var annotationRef = new _primitives.Ref(353, 0);
  271. var xref = new _test_utils.XRefMock([{
  272. ref: annotationRef,
  273. data: annotationDict
  274. }]);
  275. var annotation = _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  276. var data = annotation.data;
  277. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  278. expect(data.url).toEqual('http://www.hmrc.gov.uk/');
  279. expect(data.unsafeUrl).toEqual('http://www.hmrc.gov.uk');
  280. expect(data.dest).toBeUndefined();
  281. });
  282. it('should correctly parse a URI action, where the URI entry ' + 'has an incorrect encoding (bug 1122280)', function () {
  283. var actionStream = new _stream.StringStream('<<\n' + '/Type /Action\n' + '/S /URI\n' + '/URI (http://www.example.com/\\303\\274\\303\\266\\303\\244)\n' + '>>\n');
  284. var lexer = new _parser.Lexer(actionStream);
  285. var parser = new _parser.Parser(lexer);
  286. var actionDict = parser.getObj();
  287. var annotationDict = new _primitives.Dict();
  288. annotationDict.set('Type', _primitives.Name.get('Annot'));
  289. annotationDict.set('Subtype', _primitives.Name.get('Link'));
  290. annotationDict.set('A', actionDict);
  291. var annotationRef = new _primitives.Ref(8, 0);
  292. var xref = new _test_utils.XRefMock([{
  293. ref: annotationRef,
  294. data: annotationDict
  295. }]);
  296. var annotation = _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  297. var data = annotation.data;
  298. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  299. expect(data.url).toEqual(new URL((0, _util.stringToUTF8String)('http://www.example.com/\xC3\xBC\xC3\xB6\xC3\xA4')).href);
  300. expect(data.unsafeUrl).toEqual((0, _util.stringToUTF8String)('http://www.example.com/\xC3\xBC\xC3\xB6\xC3\xA4'));
  301. expect(data.dest).toBeUndefined();
  302. });
  303. it('should correctly parse a GoTo action', function () {
  304. var actionDict = new _primitives.Dict();
  305. actionDict.set('Type', _primitives.Name.get('Action'));
  306. actionDict.set('S', _primitives.Name.get('GoTo'));
  307. actionDict.set('D', 'page.157');
  308. var annotationDict = new _primitives.Dict();
  309. annotationDict.set('Type', _primitives.Name.get('Annot'));
  310. annotationDict.set('Subtype', _primitives.Name.get('Link'));
  311. annotationDict.set('A', actionDict);
  312. var annotationRef = new _primitives.Ref(798, 0);
  313. var xref = new _test_utils.XRefMock([{
  314. ref: annotationRef,
  315. data: annotationDict
  316. }]);
  317. var annotation = _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  318. var data = annotation.data;
  319. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  320. expect(data.url).toBeUndefined();
  321. expect(data.unsafeUrl).toBeUndefined();
  322. expect(data.dest).toEqual('page.157');
  323. });
  324. it('should correctly parse a GoToR action, where the FileSpec entry ' + 'is a string containing a relative URL', function () {
  325. var actionDict = new _primitives.Dict();
  326. actionDict.set('Type', _primitives.Name.get('Action'));
  327. actionDict.set('S', _primitives.Name.get('GoToR'));
  328. actionDict.set('F', '../../0013/001346/134685E.pdf');
  329. actionDict.set('D', '4.3');
  330. actionDict.set('NewWindow', true);
  331. var annotationDict = new _primitives.Dict();
  332. annotationDict.set('Type', _primitives.Name.get('Annot'));
  333. annotationDict.set('Subtype', _primitives.Name.get('Link'));
  334. annotationDict.set('A', actionDict);
  335. var annotationRef = new _primitives.Ref(489, 0);
  336. var xref = new _test_utils.XRefMock([{
  337. ref: annotationRef,
  338. data: annotationDict
  339. }]);
  340. var annotation = _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  341. var data = annotation.data;
  342. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  343. expect(data.url).toBeUndefined();
  344. expect(data.unsafeUrl).toEqual('../../0013/001346/134685E.pdf#4.3');
  345. expect(data.dest).toBeUndefined();
  346. expect(data.newWindow).toEqual(true);
  347. });
  348. it('should correctly parse a GoToR action, containing a relative URL, ' + 'with the "docBaseUrl" parameter specified', function () {
  349. var actionDict = new _primitives.Dict();
  350. actionDict.set('Type', _primitives.Name.get('Action'));
  351. actionDict.set('S', _primitives.Name.get('GoToR'));
  352. actionDict.set('F', '../../0013/001346/134685E.pdf');
  353. actionDict.set('D', '4.3');
  354. var annotationDict = new _primitives.Dict();
  355. annotationDict.set('Type', _primitives.Name.get('Annot'));
  356. annotationDict.set('Subtype', _primitives.Name.get('Link'));
  357. annotationDict.set('A', actionDict);
  358. var annotationRef = new _primitives.Ref(489, 0);
  359. var xref = new _test_utils.XRefMock([{
  360. ref: annotationRef,
  361. data: annotationDict
  362. }]);
  363. var pdfManager = new PDFManagerMock({ docBaseUrl: 'http://www.example.com/test/pdfs/qwerty.pdf' });
  364. var annotation = _annotation.AnnotationFactory.create(xref, annotationRef, pdfManager, idFactoryMock);
  365. var data = annotation.data;
  366. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  367. expect(data.url).toEqual('http://www.example.com/0013/001346/134685E.pdf#4.3');
  368. expect(data.unsafeUrl).toEqual('../../0013/001346/134685E.pdf#4.3');
  369. expect(data.dest).toBeUndefined();
  370. });
  371. it('should correctly parse a GoToR action, with named destination', function () {
  372. var actionDict = new _primitives.Dict();
  373. actionDict.set('Type', _primitives.Name.get('Action'));
  374. actionDict.set('S', _primitives.Name.get('GoToR'));
  375. actionDict.set('F', 'http://www.example.com/test.pdf');
  376. actionDict.set('D', '15');
  377. var annotationDict = new _primitives.Dict();
  378. annotationDict.set('Type', _primitives.Name.get('Annot'));
  379. annotationDict.set('Subtype', _primitives.Name.get('Link'));
  380. annotationDict.set('A', actionDict);
  381. var annotationRef = new _primitives.Ref(495, 0);
  382. var xref = new _test_utils.XRefMock([{
  383. ref: annotationRef,
  384. data: annotationDict
  385. }]);
  386. var annotation = _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  387. var data = annotation.data;
  388. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  389. expect(data.url).toEqual('http://www.example.com/test.pdf#15');
  390. expect(data.unsafeUrl).toEqual('http://www.example.com/test.pdf#15');
  391. expect(data.dest).toBeUndefined();
  392. expect(data.newWindow).toBeFalsy();
  393. });
  394. it('should correctly parse a GoToR action, with explicit destination array', function () {
  395. var actionDict = new _primitives.Dict();
  396. actionDict.set('Type', _primitives.Name.get('Action'));
  397. actionDict.set('S', _primitives.Name.get('GoToR'));
  398. actionDict.set('F', 'http://www.example.com/test.pdf');
  399. actionDict.set('D', [14, _primitives.Name.get('XYZ'), null, 298.043, null]);
  400. var annotationDict = new _primitives.Dict();
  401. annotationDict.set('Type', _primitives.Name.get('Annot'));
  402. annotationDict.set('Subtype', _primitives.Name.get('Link'));
  403. annotationDict.set('A', actionDict);
  404. var annotationRef = new _primitives.Ref(489, 0);
  405. var xref = new _test_utils.XRefMock([{
  406. ref: annotationRef,
  407. data: annotationDict
  408. }]);
  409. var annotation = _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  410. var data = annotation.data;
  411. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  412. expect(data.url).toEqual(new URL('http://www.example.com/test.pdf#' + '[14,{"name":"XYZ"},null,298.043,null]').href);
  413. expect(data.unsafeUrl).toEqual('http://www.example.com/test.pdf#' + '[14,{"name":"XYZ"},null,298.043,null]');
  414. expect(data.dest).toBeUndefined();
  415. expect(data.newWindow).toBeFalsy();
  416. });
  417. it('should correctly parse a Launch action, where the FileSpec dict ' + 'contains a relative URL, with the "docBaseUrl" parameter specified', function () {
  418. var fileSpecDict = new _primitives.Dict();
  419. fileSpecDict.set('Type', _primitives.Name.get('FileSpec'));
  420. fileSpecDict.set('F', 'Part II/Part II.pdf');
  421. fileSpecDict.set('UF', 'Part II/Part II.pdf');
  422. var actionDict = new _primitives.Dict();
  423. actionDict.set('Type', _primitives.Name.get('Action'));
  424. actionDict.set('S', _primitives.Name.get('Launch'));
  425. actionDict.set('F', fileSpecDict);
  426. actionDict.set('NewWindow', true);
  427. var annotationDict = new _primitives.Dict();
  428. annotationDict.set('Type', _primitives.Name.get('Annot'));
  429. annotationDict.set('Subtype', _primitives.Name.get('Link'));
  430. annotationDict.set('A', actionDict);
  431. var annotationRef = new _primitives.Ref(88, 0);
  432. var xref = new _test_utils.XRefMock([{
  433. ref: annotationRef,
  434. data: annotationDict
  435. }]);
  436. var pdfManager = new PDFManagerMock({ docBaseUrl: 'http://www.example.com/test/pdfs/qwerty.pdf' });
  437. var annotation = _annotation.AnnotationFactory.create(xref, annotationRef, pdfManager, idFactoryMock);
  438. var data = annotation.data;
  439. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  440. expect(data.url).toEqual(new URL('http://www.example.com/test/pdfs/Part II/Part II.pdf').href);
  441. expect(data.unsafeUrl).toEqual('Part II/Part II.pdf');
  442. expect(data.dest).toBeUndefined();
  443. expect(data.newWindow).toEqual(true);
  444. });
  445. it('should recover valid URLs from JavaScript actions having certain ' + 'white-listed formats', function () {
  446. function checkJsAction(params) {
  447. var jsEntry = params.jsEntry;
  448. var expectedUrl = params.expectedUrl;
  449. var expectedUnsafeUrl = params.expectedUnsafeUrl;
  450. var expectedNewWindow = params.expectedNewWindow;
  451. var actionDict = new _primitives.Dict();
  452. actionDict.set('Type', _primitives.Name.get('Action'));
  453. actionDict.set('S', _primitives.Name.get('JavaScript'));
  454. actionDict.set('JS', jsEntry);
  455. var annotationDict = new _primitives.Dict();
  456. annotationDict.set('Type', _primitives.Name.get('Annot'));
  457. annotationDict.set('Subtype', _primitives.Name.get('Link'));
  458. annotationDict.set('A', actionDict);
  459. var annotationRef = new _primitives.Ref(46, 0);
  460. var xref = new _test_utils.XRefMock([{
  461. ref: annotationRef,
  462. data: annotationDict
  463. }]);
  464. var annotation = _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  465. var data = annotation.data;
  466. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  467. expect(data.url).toEqual(expectedUrl);
  468. expect(data.unsafeUrl).toEqual(expectedUnsafeUrl);
  469. expect(data.dest).toBeUndefined();
  470. expect(data.newWindow).toEqual(expectedNewWindow);
  471. }
  472. checkJsAction({
  473. jsEntry: 'function someFun() { return "qwerty"; } someFun();',
  474. expectedUrl: undefined,
  475. expectedUnsafeUrl: undefined,
  476. expectedNewWindow: undefined
  477. });
  478. checkJsAction({
  479. jsEntry: 'window.open(\'http://www.example.com/test.pdf\')',
  480. expectedUrl: new URL('http://www.example.com/test.pdf').href,
  481. expectedUnsafeUrl: 'http://www.example.com/test.pdf',
  482. expectedNewWindow: undefined
  483. });
  484. checkJsAction({
  485. jsEntry: new _stream.StringStream('app.launchURL("http://www.example.com/test.pdf", true)'),
  486. expectedUrl: new URL('http://www.example.com/test.pdf').href,
  487. expectedUnsafeUrl: 'http://www.example.com/test.pdf',
  488. expectedNewWindow: true
  489. });
  490. });
  491. it('should correctly parse a Named action', function () {
  492. var actionDict = new _primitives.Dict();
  493. actionDict.set('Type', _primitives.Name.get('Action'));
  494. actionDict.set('S', _primitives.Name.get('Named'));
  495. actionDict.set('N', _primitives.Name.get('GoToPage'));
  496. var annotationDict = new _primitives.Dict();
  497. annotationDict.set('Type', _primitives.Name.get('Annot'));
  498. annotationDict.set('Subtype', _primitives.Name.get('Link'));
  499. annotationDict.set('A', actionDict);
  500. var annotationRef = new _primitives.Ref(12, 0);
  501. var xref = new _test_utils.XRefMock([{
  502. ref: annotationRef,
  503. data: annotationDict
  504. }]);
  505. var annotation = _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  506. var data = annotation.data;
  507. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  508. expect(data.url).toBeUndefined();
  509. expect(data.unsafeUrl).toBeUndefined();
  510. expect(data.action).toEqual('GoToPage');
  511. });
  512. it('should correctly parse a simple Dest', function () {
  513. var annotationDict = new _primitives.Dict();
  514. annotationDict.set('Type', _primitives.Name.get('Annot'));
  515. annotationDict.set('Subtype', _primitives.Name.get('Link'));
  516. annotationDict.set('Dest', _primitives.Name.get('LI0'));
  517. var annotationRef = new _primitives.Ref(583, 0);
  518. var xref = new _test_utils.XRefMock([{
  519. ref: annotationRef,
  520. data: annotationDict
  521. }]);
  522. var annotation = _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  523. var data = annotation.data;
  524. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  525. expect(data.url).toBeUndefined();
  526. expect(data.unsafeUrl).toBeUndefined();
  527. expect(data.dest).toEqual('LI0');
  528. });
  529. it('should correctly parse a simple Dest, with explicit destination array', function () {
  530. var annotationDict = new _primitives.Dict();
  531. annotationDict.set('Type', _primitives.Name.get('Annot'));
  532. annotationDict.set('Subtype', _primitives.Name.get('Link'));
  533. annotationDict.set('Dest', [new _primitives.Ref(17, 0), _primitives.Name.get('XYZ'), 0, 841.89, null]);
  534. var annotationRef = new _primitives.Ref(10, 0);
  535. var xref = new _test_utils.XRefMock([{
  536. ref: annotationRef,
  537. data: annotationDict
  538. }]);
  539. var annotation = _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  540. var data = annotation.data;
  541. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  542. expect(data.url).toBeUndefined();
  543. expect(data.unsafeUrl).toBeUndefined();
  544. expect(data.dest).toEqual([{
  545. num: 17,
  546. gen: 0
  547. }, { name: 'XYZ' }, 0, 841.89, null]);
  548. });
  549. it('should correctly parse a Dest, which violates the specification ' + 'by containing a dictionary', function () {
  550. var destDict = new _primitives.Dict();
  551. destDict.set('Type', _primitives.Name.get('Action'));
  552. destDict.set('S', _primitives.Name.get('GoTo'));
  553. destDict.set('D', 'page.157');
  554. var annotationDict = new _primitives.Dict();
  555. annotationDict.set('Type', _primitives.Name.get('Annot'));
  556. annotationDict.set('Subtype', _primitives.Name.get('Link'));
  557. annotationDict.set('Dest', destDict);
  558. var annotationRef = new _primitives.Ref(798, 0);
  559. var xref = new _test_utils.XRefMock([{
  560. ref: annotationRef,
  561. data: annotationDict
  562. }]);
  563. var annotation = _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  564. var data = annotation.data;
  565. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  566. expect(data.url).toBeUndefined();
  567. expect(data.unsafeUrl).toBeUndefined();
  568. expect(data.dest).toEqual('page.157');
  569. });
  570. });
  571. describe('WidgetAnnotation', function () {
  572. var widgetDict;
  573. beforeEach(function (done) {
  574. widgetDict = new _primitives.Dict();
  575. widgetDict.set('Type', _primitives.Name.get('Annot'));
  576. widgetDict.set('Subtype', _primitives.Name.get('Widget'));
  577. done();
  578. });
  579. afterEach(function () {
  580. widgetDict = null;
  581. });
  582. it('should handle unknown field names', function () {
  583. var widgetRef = new _primitives.Ref(20, 0);
  584. var xref = new _test_utils.XRefMock([{
  585. ref: widgetRef,
  586. data: widgetDict
  587. }]);
  588. var annotation = _annotation.AnnotationFactory.create(xref, widgetRef, pdfManagerMock, idFactoryMock);
  589. var data = annotation.data;
  590. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  591. expect(data.fieldName).toEqual('');
  592. });
  593. it('should construct the field name when there are no ancestors', function () {
  594. widgetDict.set('T', 'foo');
  595. var widgetRef = new _primitives.Ref(21, 0);
  596. var xref = new _test_utils.XRefMock([{
  597. ref: widgetRef,
  598. data: widgetDict
  599. }]);
  600. var annotation = _annotation.AnnotationFactory.create(xref, widgetRef, pdfManagerMock, idFactoryMock);
  601. var data = annotation.data;
  602. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  603. expect(data.fieldName).toEqual('foo');
  604. });
  605. it('should construct the field name when there are ancestors', function () {
  606. var firstParent = new _primitives.Dict();
  607. firstParent.set('T', 'foo');
  608. var secondParent = new _primitives.Dict();
  609. secondParent.set('Parent', firstParent);
  610. secondParent.set('T', 'bar');
  611. widgetDict.set('Parent', secondParent);
  612. widgetDict.set('T', 'baz');
  613. var widgetRef = new _primitives.Ref(22, 0);
  614. var xref = new _test_utils.XRefMock([{
  615. ref: widgetRef,
  616. data: widgetDict
  617. }]);
  618. var annotation = _annotation.AnnotationFactory.create(xref, widgetRef, pdfManagerMock, idFactoryMock);
  619. var data = annotation.data;
  620. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  621. expect(data.fieldName).toEqual('foo.bar.baz');
  622. });
  623. it('should construct the field name if a parent is not a dictionary ' + '(issue 8143)', function () {
  624. var parentDict = new _primitives.Dict();
  625. parentDict.set('Parent', null);
  626. parentDict.set('T', 'foo');
  627. widgetDict.set('Parent', parentDict);
  628. widgetDict.set('T', 'bar');
  629. var widgetRef = new _primitives.Ref(22, 0);
  630. var xref = new _test_utils.XRefMock([{
  631. ref: widgetRef,
  632. data: widgetDict
  633. }]);
  634. var annotation = _annotation.AnnotationFactory.create(xref, widgetRef, pdfManagerMock, idFactoryMock);
  635. var data = annotation.data;
  636. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  637. expect(data.fieldName).toEqual('foo.bar');
  638. });
  639. });
  640. describe('TextWidgetAnnotation', function () {
  641. var textWidgetDict;
  642. beforeEach(function (done) {
  643. textWidgetDict = new _primitives.Dict();
  644. textWidgetDict.set('Type', _primitives.Name.get('Annot'));
  645. textWidgetDict.set('Subtype', _primitives.Name.get('Widget'));
  646. textWidgetDict.set('FT', _primitives.Name.get('Tx'));
  647. done();
  648. });
  649. afterEach(function () {
  650. textWidgetDict = null;
  651. });
  652. it('should handle unknown text alignment, maximum length and flags', function () {
  653. var textWidgetRef = new _primitives.Ref(124, 0);
  654. var xref = new _test_utils.XRefMock([{
  655. ref: textWidgetRef,
  656. data: textWidgetDict
  657. }]);
  658. var annotation = _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
  659. var data = annotation.data;
  660. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  661. expect(data.textAlignment).toEqual(null);
  662. expect(data.maxLen).toEqual(null);
  663. expect(data.readOnly).toEqual(false);
  664. expect(data.multiLine).toEqual(false);
  665. expect(data.comb).toEqual(false);
  666. });
  667. it('should not set invalid text alignment, maximum length and flags', function () {
  668. textWidgetDict.set('Q', 'center');
  669. textWidgetDict.set('MaxLen', 'five');
  670. textWidgetDict.set('Ff', 'readonly');
  671. var textWidgetRef = new _primitives.Ref(43, 0);
  672. var xref = new _test_utils.XRefMock([{
  673. ref: textWidgetRef,
  674. data: textWidgetDict
  675. }]);
  676. var annotation = _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
  677. var data = annotation.data;
  678. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  679. expect(data.textAlignment).toEqual(null);
  680. expect(data.maxLen).toEqual(null);
  681. expect(data.readOnly).toEqual(false);
  682. expect(data.multiLine).toEqual(false);
  683. expect(data.comb).toEqual(false);
  684. });
  685. it('should set valid text alignment, maximum length and flags', function () {
  686. textWidgetDict.set('Q', 1);
  687. textWidgetDict.set('MaxLen', 20);
  688. textWidgetDict.set('Ff', _util.AnnotationFieldFlag.READONLY + _util.AnnotationFieldFlag.MULTILINE);
  689. var textWidgetRef = new _primitives.Ref(84, 0);
  690. var xref = new _test_utils.XRefMock([{
  691. ref: textWidgetRef,
  692. data: textWidgetDict
  693. }]);
  694. var annotation = _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
  695. var data = annotation.data;
  696. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  697. expect(data.textAlignment).toEqual(1);
  698. expect(data.maxLen).toEqual(20);
  699. expect(data.readOnly).toEqual(true);
  700. expect(data.multiLine).toEqual(true);
  701. });
  702. it('should reject comb fields without a maximum length', function () {
  703. textWidgetDict.set('Ff', _util.AnnotationFieldFlag.COMB);
  704. var textWidgetRef = new _primitives.Ref(46, 0);
  705. var xref = new _test_utils.XRefMock([{
  706. ref: textWidgetRef,
  707. data: textWidgetDict
  708. }]);
  709. var annotation = _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
  710. var data = annotation.data;
  711. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  712. expect(data.comb).toEqual(false);
  713. });
  714. it('should accept comb fields with a maximum length', function () {
  715. textWidgetDict.set('MaxLen', 20);
  716. textWidgetDict.set('Ff', _util.AnnotationFieldFlag.COMB);
  717. var textWidgetRef = new _primitives.Ref(46, 0);
  718. var xref = new _test_utils.XRefMock([{
  719. ref: textWidgetRef,
  720. data: textWidgetDict
  721. }]);
  722. var annotation = _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
  723. var data = annotation.data;
  724. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  725. expect(data.comb).toEqual(true);
  726. });
  727. it('should only accept comb fields when the flags are valid', function () {
  728. var invalidFieldFlags = [_util.AnnotationFieldFlag.MULTILINE, _util.AnnotationFieldFlag.PASSWORD, _util.AnnotationFieldFlag.FILESELECT];
  729. var flags = _util.AnnotationFieldFlag.COMB + _util.AnnotationFieldFlag.MULTILINE + _util.AnnotationFieldFlag.PASSWORD + _util.AnnotationFieldFlag.FILESELECT;
  730. for (var i = 0, ii = invalidFieldFlags.length; i <= ii; i++) {
  731. textWidgetDict.set('MaxLen', 20);
  732. textWidgetDict.set('Ff', flags);
  733. var textWidgetRef = new _primitives.Ref(93, 0);
  734. var xref = new _test_utils.XRefMock([{
  735. ref: textWidgetRef,
  736. data: textWidgetDict
  737. }]);
  738. var annotation = _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
  739. var data = annotation.data;
  740. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  741. var valid = invalidFieldFlags.length === 0;
  742. expect(data.comb).toEqual(valid);
  743. if (!valid) {
  744. flags -= invalidFieldFlags.splice(-1, 1);
  745. }
  746. }
  747. });
  748. });
  749. describe('ButtonWidgetAnnotation', function () {
  750. var buttonWidgetDict;
  751. beforeEach(function (done) {
  752. buttonWidgetDict = new _primitives.Dict();
  753. buttonWidgetDict.set('Type', _primitives.Name.get('Annot'));
  754. buttonWidgetDict.set('Subtype', _primitives.Name.get('Widget'));
  755. buttonWidgetDict.set('FT', _primitives.Name.get('Btn'));
  756. done();
  757. });
  758. afterEach(function () {
  759. buttonWidgetDict = null;
  760. });
  761. it('should handle checkboxes', function () {
  762. buttonWidgetDict.set('V', _primitives.Name.get('1'));
  763. var buttonWidgetRef = new _primitives.Ref(124, 0);
  764. var xref = new _test_utils.XRefMock([{
  765. ref: buttonWidgetRef,
  766. data: buttonWidgetDict
  767. }]);
  768. var annotation = _annotation.AnnotationFactory.create(xref, buttonWidgetRef, pdfManagerMock, idFactoryMock);
  769. var data = annotation.data;
  770. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  771. expect(data.checkBox).toEqual(true);
  772. expect(data.fieldValue).toEqual('1');
  773. expect(data.radioButton).toEqual(false);
  774. });
  775. it('should handle radio buttons with a field value', function () {
  776. var parentDict = new _primitives.Dict();
  777. parentDict.set('V', _primitives.Name.get('1'));
  778. var normalAppearanceStateDict = new _primitives.Dict();
  779. normalAppearanceStateDict.set('2', null);
  780. var appearanceStatesDict = new _primitives.Dict();
  781. appearanceStatesDict.set('N', normalAppearanceStateDict);
  782. buttonWidgetDict.set('Ff', _util.AnnotationFieldFlag.RADIO);
  783. buttonWidgetDict.set('Parent', parentDict);
  784. buttonWidgetDict.set('AP', appearanceStatesDict);
  785. var buttonWidgetRef = new _primitives.Ref(124, 0);
  786. var xref = new _test_utils.XRefMock([{
  787. ref: buttonWidgetRef,
  788. data: buttonWidgetDict
  789. }]);
  790. var annotation = _annotation.AnnotationFactory.create(xref, buttonWidgetRef, pdfManagerMock, idFactoryMock);
  791. var data = annotation.data;
  792. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  793. expect(data.checkBox).toEqual(false);
  794. expect(data.radioButton).toEqual(true);
  795. expect(data.fieldValue).toEqual('1');
  796. expect(data.buttonValue).toEqual('2');
  797. });
  798. it('should handle radio buttons without a field value', function () {
  799. var normalAppearanceStateDict = new _primitives.Dict();
  800. normalAppearanceStateDict.set('2', null);
  801. var appearanceStatesDict = new _primitives.Dict();
  802. appearanceStatesDict.set('N', normalAppearanceStateDict);
  803. buttonWidgetDict.set('Ff', _util.AnnotationFieldFlag.RADIO);
  804. buttonWidgetDict.set('AP', appearanceStatesDict);
  805. var buttonWidgetRef = new _primitives.Ref(124, 0);
  806. var xref = new _test_utils.XRefMock([{
  807. ref: buttonWidgetRef,
  808. data: buttonWidgetDict
  809. }]);
  810. var annotation = _annotation.AnnotationFactory.create(xref, buttonWidgetRef, pdfManagerMock, idFactoryMock);
  811. var data = annotation.data;
  812. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  813. expect(data.checkBox).toEqual(false);
  814. expect(data.radioButton).toEqual(true);
  815. expect(data.fieldValue).toEqual(null);
  816. expect(data.buttonValue).toEqual('2');
  817. });
  818. });
  819. describe('ChoiceWidgetAnnotation', function () {
  820. var choiceWidgetDict;
  821. beforeEach(function (done) {
  822. choiceWidgetDict = new _primitives.Dict();
  823. choiceWidgetDict.set('Type', _primitives.Name.get('Annot'));
  824. choiceWidgetDict.set('Subtype', _primitives.Name.get('Widget'));
  825. choiceWidgetDict.set('FT', _primitives.Name.get('Ch'));
  826. done();
  827. });
  828. afterEach(function () {
  829. choiceWidgetDict = null;
  830. });
  831. it('should handle missing option arrays', function () {
  832. var choiceWidgetRef = new _primitives.Ref(122, 0);
  833. var xref = new _test_utils.XRefMock([{
  834. ref: choiceWidgetRef,
  835. data: choiceWidgetDict
  836. }]);
  837. var annotation = _annotation.AnnotationFactory.create(xref, choiceWidgetRef, pdfManagerMock, idFactoryMock);
  838. var data = annotation.data;
  839. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  840. expect(data.options).toEqual([]);
  841. });
  842. it('should handle option arrays with array elements', function () {
  843. var optionBarRef = new _primitives.Ref(20, 0);
  844. var optionBarStr = 'Bar';
  845. var optionOneRef = new _primitives.Ref(10, 0);
  846. var optionOneArr = ['bar_export', optionBarRef];
  847. var options = [['foo_export', 'Foo'], optionOneRef];
  848. var expected = [{
  849. exportValue: 'foo_export',
  850. displayValue: 'Foo'
  851. }, {
  852. exportValue: 'bar_export',
  853. displayValue: 'Bar'
  854. }];
  855. choiceWidgetDict.set('Opt', options);
  856. var choiceWidgetRef = new _primitives.Ref(123, 0);
  857. var xref = new _test_utils.XRefMock([{
  858. ref: choiceWidgetRef,
  859. data: choiceWidgetDict
  860. }, {
  861. ref: optionBarRef,
  862. data: optionBarStr
  863. }, {
  864. ref: optionOneRef,
  865. data: optionOneArr
  866. }]);
  867. var annotation = _annotation.AnnotationFactory.create(xref, choiceWidgetRef, pdfManagerMock, idFactoryMock);
  868. var data = annotation.data;
  869. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  870. expect(data.options).toEqual(expected);
  871. });
  872. it('should handle option arrays with string elements', function () {
  873. var optionBarRef = new _primitives.Ref(10, 0);
  874. var optionBarStr = 'Bar';
  875. var options = ['Foo', optionBarRef];
  876. var expected = [{
  877. exportValue: 'Foo',
  878. displayValue: 'Foo'
  879. }, {
  880. exportValue: 'Bar',
  881. displayValue: 'Bar'
  882. }];
  883. choiceWidgetDict.set('Opt', options);
  884. var choiceWidgetRef = new _primitives.Ref(981, 0);
  885. var xref = new _test_utils.XRefMock([{
  886. ref: choiceWidgetRef,
  887. data: choiceWidgetDict
  888. }, {
  889. ref: optionBarRef,
  890. data: optionBarStr
  891. }]);
  892. var annotation = _annotation.AnnotationFactory.create(xref, choiceWidgetRef, pdfManagerMock, idFactoryMock);
  893. var data = annotation.data;
  894. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  895. expect(data.options).toEqual(expected);
  896. });
  897. it('should handle inherited option arrays (issue 8094)', function () {
  898. var options = [['Value1', 'Description1'], ['Value2', 'Description2']];
  899. var expected = [{
  900. exportValue: 'Value1',
  901. displayValue: 'Description1'
  902. }, {
  903. exportValue: 'Value2',
  904. displayValue: 'Description2'
  905. }];
  906. var parentDict = new _primitives.Dict();
  907. parentDict.set('Opt', options);
  908. choiceWidgetDict.set('Parent', parentDict);
  909. var choiceWidgetRef = new _primitives.Ref(123, 0);
  910. var xref = new _test_utils.XRefMock([{
  911. ref: choiceWidgetRef,
  912. data: choiceWidgetDict
  913. }]);
  914. var annotation = _annotation.AnnotationFactory.create(xref, choiceWidgetRef, pdfManagerMock, idFactoryMock);
  915. var data = annotation.data;
  916. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  917. expect(data.options).toEqual(expected);
  918. });
  919. it('should sanitize display values in option arrays (issue 8947)', function () {
  920. var options = ['\xFE\xFF\x00F\x00o\x00o'];
  921. var expected = [{
  922. exportValue: '\xFE\xFF\x00F\x00o\x00o',
  923. displayValue: 'Foo'
  924. }];
  925. choiceWidgetDict.set('Opt', options);
  926. var choiceWidgetRef = new _primitives.Ref(984, 0);
  927. var xref = new _test_utils.XRefMock([{
  928. ref: choiceWidgetRef,
  929. data: choiceWidgetDict
  930. }]);
  931. var annotation = _annotation.AnnotationFactory.create(xref, choiceWidgetRef, pdfManagerMock, idFactoryMock);
  932. var data = annotation.data;
  933. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  934. expect(data.options).toEqual(expected);
  935. });
  936. it('should handle array field values', function () {
  937. var fieldValue = ['Foo', 'Bar'];
  938. choiceWidgetDict.set('V', fieldValue);
  939. var choiceWidgetRef = new _primitives.Ref(968, 0);
  940. var xref = new _test_utils.XRefMock([{
  941. ref: choiceWidgetRef,
  942. data: choiceWidgetDict
  943. }]);
  944. var annotation = _annotation.AnnotationFactory.create(xref, choiceWidgetRef, pdfManagerMock, idFactoryMock);
  945. var data = annotation.data;
  946. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  947. expect(data.fieldValue).toEqual(fieldValue);
  948. });
  949. it('should handle string field values', function () {
  950. var fieldValue = 'Foo';
  951. choiceWidgetDict.set('V', fieldValue);
  952. var choiceWidgetRef = new _primitives.Ref(978, 0);
  953. var xref = new _test_utils.XRefMock([{
  954. ref: choiceWidgetRef,
  955. data: choiceWidgetDict
  956. }]);
  957. var annotation = _annotation.AnnotationFactory.create(xref, choiceWidgetRef, pdfManagerMock, idFactoryMock);
  958. var data = annotation.data;
  959. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  960. expect(data.fieldValue).toEqual([fieldValue]);
  961. });
  962. it('should handle unknown flags', function () {
  963. var choiceWidgetRef = new _primitives.Ref(166, 0);
  964. var xref = new _test_utils.XRefMock([{
  965. ref: choiceWidgetRef,
  966. data: choiceWidgetDict
  967. }]);
  968. var annotation = _annotation.AnnotationFactory.create(xref, choiceWidgetRef, pdfManagerMock, idFactoryMock);
  969. var data = annotation.data;
  970. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  971. expect(data.readOnly).toEqual(false);
  972. expect(data.combo).toEqual(false);
  973. expect(data.multiSelect).toEqual(false);
  974. });
  975. it('should not set invalid flags', function () {
  976. choiceWidgetDict.set('Ff', 'readonly');
  977. var choiceWidgetRef = new _primitives.Ref(165, 0);
  978. var xref = new _test_utils.XRefMock([{
  979. ref: choiceWidgetRef,
  980. data: choiceWidgetDict
  981. }]);
  982. var annotation = _annotation.AnnotationFactory.create(xref, choiceWidgetRef, pdfManagerMock, idFactoryMock);
  983. var data = annotation.data;
  984. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  985. expect(data.readOnly).toEqual(false);
  986. expect(data.combo).toEqual(false);
  987. expect(data.multiSelect).toEqual(false);
  988. });
  989. it('should set valid flags', function () {
  990. choiceWidgetDict.set('Ff', _util.AnnotationFieldFlag.READONLY + _util.AnnotationFieldFlag.COMBO + _util.AnnotationFieldFlag.MULTISELECT);
  991. var choiceWidgetRef = new _primitives.Ref(512, 0);
  992. var xref = new _test_utils.XRefMock([{
  993. ref: choiceWidgetRef,
  994. data: choiceWidgetDict
  995. }]);
  996. var annotation = _annotation.AnnotationFactory.create(xref, choiceWidgetRef, pdfManagerMock, idFactoryMock);
  997. var data = annotation.data;
  998. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  999. expect(data.readOnly).toEqual(true);
  1000. expect(data.combo).toEqual(true);
  1001. expect(data.multiSelect).toEqual(true);
  1002. });
  1003. });
  1004. describe('LineAnnotation', function () {
  1005. it('should set the line coordinates', function () {
  1006. var lineDict = new _primitives.Dict();
  1007. lineDict.set('Type', _primitives.Name.get('Annot'));
  1008. lineDict.set('Subtype', _primitives.Name.get('Line'));
  1009. lineDict.set('L', [1, 2, 3, 4]);
  1010. var lineRef = new _primitives.Ref(122, 0);
  1011. var xref = new _test_utils.XRefMock([{
  1012. ref: lineRef,
  1013. data: lineDict
  1014. }]);
  1015. var annotation = _annotation.AnnotationFactory.create(xref, lineRef, pdfManagerMock, idFactoryMock);
  1016. var data = annotation.data;
  1017. expect(data.annotationType).toEqual(_util.AnnotationType.LINE);
  1018. expect(data.lineCoordinates).toEqual([1, 2, 3, 4]);
  1019. });
  1020. });
  1021. describe('FileAttachmentAnnotation', function () {
  1022. it('should correctly parse a file attachment', function () {
  1023. var fileStream = new _stream.StringStream('<<\n' + '/Type /EmbeddedFile\n' + '/Subtype /text#2Fplain\n' + '>>\n' + 'stream\n' + 'Test attachment' + 'endstream\n');
  1024. var lexer = new _parser.Lexer(fileStream);
  1025. var parser = new _parser.Parser(lexer, true);
  1026. var fileStreamRef = new _primitives.Ref(18, 0);
  1027. var fileStreamDict = parser.getObj();
  1028. var embeddedFileDict = new _primitives.Dict();
  1029. embeddedFileDict.set('F', fileStreamRef);
  1030. var fileSpecRef = new _primitives.Ref(19, 0);
  1031. var fileSpecDict = new _primitives.Dict();
  1032. fileSpecDict.set('Type', _primitives.Name.get('Filespec'));
  1033. fileSpecDict.set('Desc', '');
  1034. fileSpecDict.set('EF', embeddedFileDict);
  1035. fileSpecDict.set('UF', 'Test.txt');
  1036. var fileAttachmentRef = new _primitives.Ref(20, 0);
  1037. var fileAttachmentDict = new _primitives.Dict();
  1038. fileAttachmentDict.set('Type', _primitives.Name.get('Annot'));
  1039. fileAttachmentDict.set('Subtype', _primitives.Name.get('FileAttachment'));
  1040. fileAttachmentDict.set('FS', fileSpecRef);
  1041. fileAttachmentDict.set('T', 'Topic');
  1042. fileAttachmentDict.set('Contents', 'Test.txt');
  1043. var xref = new _test_utils.XRefMock([{
  1044. ref: fileStreamRef,
  1045. data: fileStreamDict
  1046. }, {
  1047. ref: fileSpecRef,
  1048. data: fileSpecDict
  1049. }, {
  1050. ref: fileAttachmentRef,
  1051. data: fileAttachmentDict
  1052. }]);
  1053. embeddedFileDict.assignXref(xref);
  1054. fileSpecDict.assignXref(xref);
  1055. fileAttachmentDict.assignXref(xref);
  1056. var annotation = _annotation.AnnotationFactory.create(xref, fileAttachmentRef, pdfManagerMock, idFactoryMock);
  1057. var data = annotation.data;
  1058. expect(data.annotationType).toEqual(_util.AnnotationType.FILEATTACHMENT);
  1059. expect(data.file.filename).toEqual('Test.txt');
  1060. expect(data.file.content).toEqual((0, _util.stringToBytes)('Test attachment'));
  1061. });
  1062. });
  1063. describe('PopupAnnotation', function () {
  1064. it('should inherit the parent flags when the Popup is not viewable, ' + 'but the parent is (PR 7352)', function () {
  1065. var parentDict = new _primitives.Dict();
  1066. parentDict.set('Type', _primitives.Name.get('Annot'));
  1067. parentDict.set('Subtype', _primitives.Name.get('Text'));
  1068. parentDict.set('F', 28);
  1069. var popupDict = new _primitives.Dict();
  1070. popupDict.set('Type', _primitives.Name.get('Annot'));
  1071. popupDict.set('Subtype', _primitives.Name.get('Popup'));
  1072. popupDict.set('F', 25);
  1073. popupDict.set('Parent', parentDict);
  1074. var popupRef = new _primitives.Ref(13, 0);
  1075. var xref = new _test_utils.XRefMock([{
  1076. ref: popupRef,
  1077. data: popupDict
  1078. }]);
  1079. var annotation = _annotation.AnnotationFactory.create(xref, popupRef, pdfManagerMock, idFactoryMock);
  1080. var data = annotation.data;
  1081. expect(data.annotationType).toEqual(_util.AnnotationType.POPUP);
  1082. expect(data.annotationFlags).toEqual(25);
  1083. expect(annotation.viewable).toEqual(true);
  1084. });
  1085. });
  1086. });