annotation_spec.js 128 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076
  1. /**
  2. * @licstart The following is the entire license notice for the
  3. * Javascript code in this page
  4. *
  5. * Copyright 2021 Mozilla Foundation
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. *
  19. * @licend The above is the entire license notice for the
  20. * Javascript code in this page
  21. */
  22. "use strict";
  23. var _annotation = require("../../core/annotation.js");
  24. var _util = require("../../shared/util.js");
  25. var _test_utils = require("./test_utils.js");
  26. var _primitives = require("../../core/primitives.js");
  27. var _parser = require("../../core/parser.js");
  28. var _api = require("../../display/api.js");
  29. var _evaluator = require("../../core/evaluator.js");
  30. var _stream = require("../../core/stream.js");
  31. var _worker = require("../../core/worker.js");
  32. describe("annotation", function () {
  33. class PDFManagerMock {
  34. constructor(params) {
  35. this.docBaseUrl = params.docBaseUrl || null;
  36. this.pdfDocument = {
  37. catalog: {
  38. acroForm: new _primitives.Dict()
  39. }
  40. };
  41. }
  42. ensure(obj, prop, args) {
  43. return new Promise(function (resolve) {
  44. const value = obj[prop];
  45. if (typeof value === "function") {
  46. resolve(value.apply(obj, args));
  47. } else {
  48. resolve(value);
  49. }
  50. });
  51. }
  52. ensureCatalog(prop, args) {
  53. return this.ensure(this.pdfDocument.catalog, prop, args);
  54. }
  55. ensureDoc(prop, args) {
  56. return this.ensure(this.pdfDocument, prop, args);
  57. }
  58. }
  59. function HandlerMock() {
  60. this.inputs = [];
  61. }
  62. HandlerMock.prototype = {
  63. send(name, data) {
  64. this.inputs.push({
  65. name,
  66. data
  67. });
  68. }
  69. };
  70. let pdfManagerMock, idFactoryMock, partialEvaluator;
  71. beforeAll(async function () {
  72. pdfManagerMock = new PDFManagerMock({
  73. docBaseUrl: null
  74. });
  75. const CMapReaderFactory = new _api.DefaultCMapReaderFactory({
  76. baseUrl: _test_utils.CMAP_PARAMS.cMapUrl,
  77. isCompressed: _test_utils.CMAP_PARAMS.cMapPacked
  78. });
  79. const builtInCMapCache = new Map();
  80. builtInCMapCache.set("UniJIS-UTF16-H", await CMapReaderFactory.fetch({
  81. name: "UniJIS-UTF16-H"
  82. }));
  83. builtInCMapCache.set("Adobe-Japan1-UCS2", await CMapReaderFactory.fetch({
  84. name: "Adobe-Japan1-UCS2"
  85. }));
  86. idFactoryMock = (0, _test_utils.createIdFactory)(0);
  87. partialEvaluator = new _evaluator.PartialEvaluator({
  88. xref: new _test_utils.XRefMock(),
  89. handler: new HandlerMock(),
  90. pageIndex: 0,
  91. idFactory: (0, _test_utils.createIdFactory)(0),
  92. fontCache: new _primitives.RefSetCache(),
  93. builtInCMapCache
  94. });
  95. });
  96. afterAll(function () {
  97. pdfManagerMock = null;
  98. idFactoryMock = null;
  99. partialEvaluator = null;
  100. });
  101. describe("AnnotationFactory", function () {
  102. it("should get id for annotation", async function () {
  103. const annotationDict = new _primitives.Dict();
  104. annotationDict.set("Type", _primitives.Name.get("Annot"));
  105. annotationDict.set("Subtype", _primitives.Name.get("Link"));
  106. const annotationRef = _primitives.Ref.get(10, 0);
  107. const xref = new _test_utils.XRefMock([{
  108. ref: annotationRef,
  109. data: annotationDict
  110. }]);
  111. const {
  112. data
  113. } = await _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  114. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  115. expect(data.id).toEqual("10R");
  116. });
  117. it("should handle, and get fallback IDs for, annotations that are not " + "indirect objects (issue 7569)", async function () {
  118. const annotationDict = new _primitives.Dict();
  119. annotationDict.set("Type", _primitives.Name.get("Annot"));
  120. annotationDict.set("Subtype", _primitives.Name.get("Link"));
  121. const xref = new _test_utils.XRefMock();
  122. const idFactory = (0, _test_utils.createIdFactory)(0);
  123. const annotation1 = _annotation.AnnotationFactory.create(xref, annotationDict, pdfManagerMock, idFactory).then(({
  124. data
  125. }) => {
  126. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  127. expect(data.id).toEqual("annot_p0_1");
  128. });
  129. const annotation2 = _annotation.AnnotationFactory.create(xref, annotationDict, pdfManagerMock, idFactory).then(({
  130. data
  131. }) => {
  132. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  133. expect(data.id).toEqual("annot_p0_2");
  134. });
  135. await Promise.all([annotation1, annotation2]);
  136. });
  137. it("should handle missing /Subtype", async function () {
  138. const annotationDict = new _primitives.Dict();
  139. annotationDict.set("Type", _primitives.Name.get("Annot"));
  140. const annotationRef = _primitives.Ref.get(1, 0);
  141. const xref = new _test_utils.XRefMock([{
  142. ref: annotationRef,
  143. data: annotationDict
  144. }]);
  145. const {
  146. data
  147. } = await _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  148. expect(data.annotationType).toBeUndefined();
  149. });
  150. });
  151. describe("getQuadPoints", function () {
  152. let dict, rect;
  153. beforeEach(function () {
  154. dict = new _primitives.Dict();
  155. rect = [];
  156. });
  157. afterEach(function () {
  158. dict = null;
  159. rect = null;
  160. });
  161. it("should ignore missing quadpoints", function () {
  162. expect((0, _annotation.getQuadPoints)(dict, rect)).toEqual(null);
  163. });
  164. it("should ignore non-array values", function () {
  165. dict.set("QuadPoints", "foo");
  166. expect((0, _annotation.getQuadPoints)(dict, rect)).toEqual(null);
  167. });
  168. it("should ignore arrays where the length is not a multiple of eight", function () {
  169. dict.set("QuadPoints", [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
  170. expect((0, _annotation.getQuadPoints)(dict, rect)).toEqual(null);
  171. });
  172. it("should ignore quadpoints if one coordinate lies outside the rectangle", function () {
  173. rect = [10, 10, 20, 20];
  174. const inputs = [[11, 11, 12, 12, 9, 13, 14, 14], [11, 11, 12, 12, 13, 9, 14, 14], [11, 11, 12, 12, 21, 13, 14, 14], [11, 11, 12, 12, 13, 21, 14, 14]];
  175. for (const input of inputs) {
  176. dict.set("QuadPoints", input);
  177. expect((0, _annotation.getQuadPoints)(dict, rect)).toEqual(null);
  178. }
  179. });
  180. it("should process quadpoints in the standard order", function () {
  181. rect = [10, 10, 20, 20];
  182. dict.set("QuadPoints", [10, 20, 20, 20, 10, 10, 20, 10, 11, 19, 19, 19, 11, 11, 19, 11]);
  183. expect((0, _annotation.getQuadPoints)(dict, rect)).toEqual([[{
  184. x: 10,
  185. y: 20
  186. }, {
  187. x: 20,
  188. y: 20
  189. }, {
  190. x: 10,
  191. y: 10
  192. }, {
  193. x: 20,
  194. y: 10
  195. }], [{
  196. x: 11,
  197. y: 19
  198. }, {
  199. x: 19,
  200. y: 19
  201. }, {
  202. x: 11,
  203. y: 11
  204. }, {
  205. x: 19,
  206. y: 11
  207. }]]);
  208. });
  209. it("should normalize and process quadpoints in non-standard orders", function () {
  210. rect = [10, 10, 20, 20];
  211. const nonStandardOrders = [[10, 20, 20, 20, 20, 10, 10, 10], [10, 10, 20, 10, 10, 20, 20, 20], [10, 10, 20, 10, 20, 20, 10, 20]];
  212. for (const nonStandardOrder of nonStandardOrders) {
  213. dict.set("QuadPoints", nonStandardOrder);
  214. expect((0, _annotation.getQuadPoints)(dict, rect)).toEqual([[{
  215. x: 10,
  216. y: 20
  217. }, {
  218. x: 20,
  219. y: 20
  220. }, {
  221. x: 10,
  222. y: 10
  223. }, {
  224. x: 20,
  225. y: 10
  226. }]]);
  227. }
  228. });
  229. });
  230. describe("Annotation", function () {
  231. let dict, ref;
  232. beforeAll(function () {
  233. dict = new _primitives.Dict();
  234. ref = _primitives.Ref.get(1, 0);
  235. });
  236. afterAll(function () {
  237. dict = ref = null;
  238. });
  239. it("should set and get valid contents", function () {
  240. const annotation = new _annotation.Annotation({
  241. dict,
  242. ref
  243. });
  244. annotation.setContents("Foo bar baz");
  245. expect(annotation.contents).toEqual("Foo bar baz");
  246. });
  247. it("should not set and get invalid contents", function () {
  248. const annotation = new _annotation.Annotation({
  249. dict,
  250. ref
  251. });
  252. annotation.setContents(undefined);
  253. expect(annotation.contents).toEqual("");
  254. });
  255. it("should set and get a valid modification date", function () {
  256. const annotation = new _annotation.Annotation({
  257. dict,
  258. ref
  259. });
  260. annotation.setModificationDate("D:20190422");
  261. expect(annotation.modificationDate).toEqual("D:20190422");
  262. });
  263. it("should not set and get an invalid modification date", function () {
  264. const annotation = new _annotation.Annotation({
  265. dict,
  266. ref
  267. });
  268. annotation.setModificationDate(undefined);
  269. expect(annotation.modificationDate).toEqual(null);
  270. });
  271. it("should set and get flags", function () {
  272. const annotation = new _annotation.Annotation({
  273. dict,
  274. ref
  275. });
  276. annotation.setFlags(13);
  277. expect(annotation.hasFlag(_util.AnnotationFlag.INVISIBLE)).toEqual(true);
  278. expect(annotation.hasFlag(_util.AnnotationFlag.NOZOOM)).toEqual(true);
  279. expect(annotation.hasFlag(_util.AnnotationFlag.PRINT)).toEqual(true);
  280. expect(annotation.hasFlag(_util.AnnotationFlag.READONLY)).toEqual(false);
  281. expect(annotation.hasFlag(_util.AnnotationFlag.HIDDEN)).toEqual(false);
  282. });
  283. it("should be viewable and not printable by default", function () {
  284. const annotation = new _annotation.Annotation({
  285. dict,
  286. ref
  287. });
  288. expect(annotation.viewable).toEqual(true);
  289. expect(annotation.printable).toEqual(false);
  290. });
  291. it("should set and get a valid rectangle", function () {
  292. const annotation = new _annotation.Annotation({
  293. dict,
  294. ref
  295. });
  296. annotation.setRectangle([117, 694, 164.298, 720]);
  297. expect(annotation.rectangle).toEqual([117, 694, 164.298, 720]);
  298. });
  299. it("should not set and get an invalid rectangle", function () {
  300. const annotation = new _annotation.Annotation({
  301. dict,
  302. ref
  303. });
  304. annotation.setRectangle([117, 694, 164.298]);
  305. expect(annotation.rectangle).toEqual([0, 0, 0, 0]);
  306. });
  307. it("should reject a color if it is not an array", function () {
  308. const annotation = new _annotation.Annotation({
  309. dict,
  310. ref
  311. });
  312. annotation.setColor("red");
  313. expect(annotation.color).toEqual(new Uint8ClampedArray([0, 0, 0]));
  314. });
  315. it("should set and get a transparent color", function () {
  316. const annotation = new _annotation.Annotation({
  317. dict,
  318. ref
  319. });
  320. annotation.setColor([]);
  321. expect(annotation.color).toEqual(null);
  322. });
  323. it("should set and get a grayscale color", function () {
  324. const annotation = new _annotation.Annotation({
  325. dict,
  326. ref
  327. });
  328. annotation.setColor([0.4]);
  329. expect(annotation.color).toEqual(new Uint8ClampedArray([102, 102, 102]));
  330. });
  331. it("should set and get an RGB color", function () {
  332. const annotation = new _annotation.Annotation({
  333. dict,
  334. ref
  335. });
  336. annotation.setColor([0, 0, 1]);
  337. expect(annotation.color).toEqual(new Uint8ClampedArray([0, 0, 255]));
  338. });
  339. it("should set and get a CMYK color", function () {
  340. const annotation = new _annotation.Annotation({
  341. dict,
  342. ref
  343. });
  344. annotation.setColor([0.1, 0.92, 0.84, 0.02]);
  345. expect(annotation.color).toEqual(new Uint8ClampedArray([234, 59, 48]));
  346. });
  347. it("should not set and get an invalid color", function () {
  348. const annotation = new _annotation.Annotation({
  349. dict,
  350. ref
  351. });
  352. annotation.setColor([0.4, 0.6]);
  353. expect(annotation.color).toEqual(new Uint8ClampedArray([0, 0, 0]));
  354. });
  355. });
  356. describe("AnnotationBorderStyle", function () {
  357. it("should set and get a valid width", function () {
  358. const borderStyle = new _annotation.AnnotationBorderStyle();
  359. borderStyle.setWidth(3);
  360. expect(borderStyle.width).toEqual(3);
  361. });
  362. it("should not set and get an invalid width", function () {
  363. const borderStyle = new _annotation.AnnotationBorderStyle();
  364. borderStyle.setWidth("three");
  365. expect(borderStyle.width).toEqual(1);
  366. });
  367. it("should set the width to zero, when the input is a `Name` (issue 10385)", function () {
  368. const borderStyleZero = new _annotation.AnnotationBorderStyle();
  369. borderStyleZero.setWidth(_primitives.Name.get("0"));
  370. const borderStyleFive = new _annotation.AnnotationBorderStyle();
  371. borderStyleFive.setWidth(_primitives.Name.get("5"));
  372. expect(borderStyleZero.width).toEqual(0);
  373. expect(borderStyleFive.width).toEqual(0);
  374. });
  375. it("should set and get a valid style", function () {
  376. const borderStyle = new _annotation.AnnotationBorderStyle();
  377. borderStyle.setStyle(_primitives.Name.get("D"));
  378. expect(borderStyle.style).toEqual(_util.AnnotationBorderStyleType.DASHED);
  379. });
  380. it("should not set and get an invalid style", function () {
  381. const borderStyle = new _annotation.AnnotationBorderStyle();
  382. borderStyle.setStyle("Dashed");
  383. expect(borderStyle.style).toEqual(_util.AnnotationBorderStyleType.SOLID);
  384. });
  385. it("should set and get a valid dash array", function () {
  386. const borderStyle = new _annotation.AnnotationBorderStyle();
  387. borderStyle.setDashArray([1, 2, 3]);
  388. expect(borderStyle.dashArray).toEqual([1, 2, 3]);
  389. });
  390. it("should not set and get an invalid dash array", function () {
  391. const borderStyle = new _annotation.AnnotationBorderStyle();
  392. borderStyle.setDashArray([0, 0]);
  393. expect(borderStyle.dashArray).toEqual([3]);
  394. });
  395. it("should set and get a valid horizontal corner radius", function () {
  396. const borderStyle = new _annotation.AnnotationBorderStyle();
  397. borderStyle.setHorizontalCornerRadius(3);
  398. expect(borderStyle.horizontalCornerRadius).toEqual(3);
  399. });
  400. it("should not set and get an invalid horizontal corner radius", function () {
  401. const borderStyle = new _annotation.AnnotationBorderStyle();
  402. borderStyle.setHorizontalCornerRadius("three");
  403. expect(borderStyle.horizontalCornerRadius).toEqual(0);
  404. });
  405. it("should set and get a valid vertical corner radius", function () {
  406. const borderStyle = new _annotation.AnnotationBorderStyle();
  407. borderStyle.setVerticalCornerRadius(3);
  408. expect(borderStyle.verticalCornerRadius).toEqual(3);
  409. });
  410. it("should not set and get an invalid vertical corner radius", function () {
  411. const borderStyle = new _annotation.AnnotationBorderStyle();
  412. borderStyle.setVerticalCornerRadius("three");
  413. expect(borderStyle.verticalCornerRadius).toEqual(0);
  414. });
  415. });
  416. describe("MarkupAnnotation", function () {
  417. let dict, ref;
  418. beforeAll(function () {
  419. dict = new _primitives.Dict();
  420. ref = _primitives.Ref.get(1, 0);
  421. });
  422. afterAll(function () {
  423. dict = ref = null;
  424. });
  425. it("should set and get a valid creation date", function () {
  426. const markupAnnotation = new _annotation.MarkupAnnotation({
  427. dict,
  428. ref
  429. });
  430. markupAnnotation.setCreationDate("D:20190422");
  431. expect(markupAnnotation.creationDate).toEqual("D:20190422");
  432. });
  433. it("should not set and get an invalid creation date", function () {
  434. const markupAnnotation = new _annotation.MarkupAnnotation({
  435. dict,
  436. ref
  437. });
  438. markupAnnotation.setCreationDate(undefined);
  439. expect(markupAnnotation.creationDate).toEqual(null);
  440. });
  441. it("should not parse IRT/RT when not defined", async function () {
  442. dict.set("Type", _primitives.Name.get("Annot"));
  443. dict.set("Subtype", _primitives.Name.get("Text"));
  444. const xref = new _test_utils.XRefMock([{
  445. ref,
  446. data: dict
  447. }]);
  448. const {
  449. data
  450. } = await _annotation.AnnotationFactory.create(xref, ref, pdfManagerMock, idFactoryMock);
  451. expect(data.inReplyTo).toBeUndefined();
  452. expect(data.replyType).toBeUndefined();
  453. });
  454. it("should parse IRT and set default RT when not defined", async function () {
  455. const annotationRef = _primitives.Ref.get(819, 0);
  456. const annotationDict = new _primitives.Dict();
  457. annotationDict.set("Type", _primitives.Name.get("Annot"));
  458. annotationDict.set("Subtype", _primitives.Name.get("Text"));
  459. const replyRef = _primitives.Ref.get(820, 0);
  460. const replyDict = new _primitives.Dict();
  461. replyDict.set("Type", _primitives.Name.get("Annot"));
  462. replyDict.set("Subtype", _primitives.Name.get("Text"));
  463. replyDict.set("IRT", annotationRef);
  464. const xref = new _test_utils.XRefMock([{
  465. ref: annotationRef,
  466. data: annotationDict
  467. }, {
  468. ref: replyRef,
  469. data: replyDict
  470. }]);
  471. annotationDict.assignXref(xref);
  472. replyDict.assignXref(xref);
  473. const {
  474. data
  475. } = await _annotation.AnnotationFactory.create(xref, replyRef, pdfManagerMock, idFactoryMock);
  476. expect(data.inReplyTo).toEqual(annotationRef.toString());
  477. expect(data.replyType).toEqual("R");
  478. });
  479. it("should parse IRT/RT for a group type", async function () {
  480. const annotationRef = _primitives.Ref.get(819, 0);
  481. const annotationDict = new _primitives.Dict();
  482. annotationDict.set("Type", _primitives.Name.get("Annot"));
  483. annotationDict.set("Subtype", _primitives.Name.get("Text"));
  484. annotationDict.set("T", "ParentTitle");
  485. annotationDict.set("Contents", "ParentText");
  486. annotationDict.set("CreationDate", "D:20180423");
  487. annotationDict.set("M", "D:20190423");
  488. annotationDict.set("C", [0, 0, 1]);
  489. const popupRef = _primitives.Ref.get(820, 0);
  490. const popupDict = new _primitives.Dict();
  491. popupDict.set("Type", _primitives.Name.get("Annot"));
  492. popupDict.set("Subtype", _primitives.Name.get("Popup"));
  493. popupDict.set("Parent", annotationRef);
  494. annotationDict.set("Popup", popupRef);
  495. const replyRef = _primitives.Ref.get(821, 0);
  496. const replyDict = new _primitives.Dict();
  497. replyDict.set("Type", _primitives.Name.get("Annot"));
  498. replyDict.set("Subtype", _primitives.Name.get("Text"));
  499. replyDict.set("IRT", annotationRef);
  500. replyDict.set("RT", _primitives.Name.get("Group"));
  501. replyDict.set("T", "ReplyTitle");
  502. replyDict.set("Contents", "ReplyText");
  503. replyDict.set("CreationDate", "D:20180523");
  504. replyDict.set("M", "D:20190523");
  505. replyDict.set("C", [0.4]);
  506. const xref = new _test_utils.XRefMock([{
  507. ref: annotationRef,
  508. data: annotationDict
  509. }, {
  510. ref: popupRef,
  511. data: popupDict
  512. }, {
  513. ref: replyRef,
  514. data: replyDict
  515. }]);
  516. annotationDict.assignXref(xref);
  517. popupDict.assignXref(xref);
  518. replyDict.assignXref(xref);
  519. const {
  520. data
  521. } = await _annotation.AnnotationFactory.create(xref, replyRef, pdfManagerMock, idFactoryMock);
  522. expect(data.inReplyTo).toEqual(annotationRef.toString());
  523. expect(data.replyType).toEqual("Group");
  524. expect(data.title).toEqual("ParentTitle");
  525. expect(data.contents).toEqual("ParentText");
  526. expect(data.creationDate).toEqual("D:20180423");
  527. expect(data.modificationDate).toEqual("D:20190423");
  528. expect(data.color).toEqual(new Uint8ClampedArray([0, 0, 255]));
  529. expect(data.hasPopup).toEqual(true);
  530. });
  531. it("should parse IRT/RT for a reply type", async function () {
  532. const annotationRef = _primitives.Ref.get(819, 0);
  533. const annotationDict = new _primitives.Dict();
  534. annotationDict.set("Type", _primitives.Name.get("Annot"));
  535. annotationDict.set("Subtype", _primitives.Name.get("Text"));
  536. annotationDict.set("T", "ParentTitle");
  537. annotationDict.set("Contents", "ParentText");
  538. annotationDict.set("CreationDate", "D:20180423");
  539. annotationDict.set("M", "D:20190423");
  540. annotationDict.set("C", [0, 0, 1]);
  541. const popupRef = _primitives.Ref.get(820, 0);
  542. const popupDict = new _primitives.Dict();
  543. popupDict.set("Type", _primitives.Name.get("Annot"));
  544. popupDict.set("Subtype", _primitives.Name.get("Popup"));
  545. popupDict.set("Parent", annotationRef);
  546. annotationDict.set("Popup", popupRef);
  547. const replyRef = _primitives.Ref.get(821, 0);
  548. const replyDict = new _primitives.Dict();
  549. replyDict.set("Type", _primitives.Name.get("Annot"));
  550. replyDict.set("Subtype", _primitives.Name.get("Text"));
  551. replyDict.set("IRT", annotationRef);
  552. replyDict.set("RT", _primitives.Name.get("R"));
  553. replyDict.set("T", "ReplyTitle");
  554. replyDict.set("Contents", "ReplyText");
  555. replyDict.set("CreationDate", "D:20180523");
  556. replyDict.set("M", "D:20190523");
  557. replyDict.set("C", [0.4]);
  558. const xref = new _test_utils.XRefMock([{
  559. ref: annotationRef,
  560. data: annotationDict
  561. }, {
  562. ref: popupRef,
  563. data: popupDict
  564. }, {
  565. ref: replyRef,
  566. data: replyDict
  567. }]);
  568. annotationDict.assignXref(xref);
  569. popupDict.assignXref(xref);
  570. replyDict.assignXref(xref);
  571. const {
  572. data
  573. } = await _annotation.AnnotationFactory.create(xref, replyRef, pdfManagerMock, idFactoryMock);
  574. expect(data.inReplyTo).toEqual(annotationRef.toString());
  575. expect(data.replyType).toEqual("R");
  576. expect(data.title).toEqual("ReplyTitle");
  577. expect(data.contents).toEqual("ReplyText");
  578. expect(data.creationDate).toEqual("D:20180523");
  579. expect(data.modificationDate).toEqual("D:20190523");
  580. expect(data.color).toEqual(new Uint8ClampedArray([102, 102, 102]));
  581. expect(data.hasPopup).toEqual(false);
  582. });
  583. });
  584. describe("TextAnnotation", function () {
  585. it("should not parse state model and state when not defined", async function () {
  586. const annotationRef = _primitives.Ref.get(819, 0);
  587. const annotationDict = new _primitives.Dict();
  588. annotationDict.set("Type", _primitives.Name.get("Annot"));
  589. annotationDict.set("Subtype", _primitives.Name.get("Text"));
  590. annotationDict.set("Contents", "TestText");
  591. const replyRef = _primitives.Ref.get(820, 0);
  592. const replyDict = new _primitives.Dict();
  593. replyDict.set("Type", _primitives.Name.get("Annot"));
  594. replyDict.set("Subtype", _primitives.Name.get("Text"));
  595. replyDict.set("IRT", annotationRef);
  596. replyDict.set("RT", _primitives.Name.get("R"));
  597. replyDict.set("Contents", "ReplyText");
  598. const xref = new _test_utils.XRefMock([{
  599. ref: annotationRef,
  600. data: annotationDict
  601. }, {
  602. ref: replyRef,
  603. data: replyDict
  604. }]);
  605. annotationDict.assignXref(xref);
  606. replyDict.assignXref(xref);
  607. const {
  608. data
  609. } = await _annotation.AnnotationFactory.create(xref, replyRef, pdfManagerMock, idFactoryMock);
  610. expect(data.stateModel).toBeNull();
  611. expect(data.state).toBeNull();
  612. });
  613. it("should correctly parse state model and state when defined", async function () {
  614. const annotationRef = _primitives.Ref.get(819, 0);
  615. const annotationDict = new _primitives.Dict();
  616. annotationDict.set("Type", _primitives.Name.get("Annot"));
  617. annotationDict.set("Subtype", _primitives.Name.get("Text"));
  618. const replyRef = _primitives.Ref.get(820, 0);
  619. const replyDict = new _primitives.Dict();
  620. replyDict.set("Type", _primitives.Name.get("Annot"));
  621. replyDict.set("Subtype", _primitives.Name.get("Text"));
  622. replyDict.set("IRT", annotationRef);
  623. replyDict.set("RT", _primitives.Name.get("R"));
  624. replyDict.set("StateModel", "Review");
  625. replyDict.set("State", "Rejected");
  626. const xref = new _test_utils.XRefMock([{
  627. ref: annotationRef,
  628. data: annotationDict
  629. }, {
  630. ref: replyRef,
  631. data: replyDict
  632. }]);
  633. annotationDict.assignXref(xref);
  634. replyDict.assignXref(xref);
  635. const {
  636. data
  637. } = await _annotation.AnnotationFactory.create(xref, replyRef, pdfManagerMock, idFactoryMock);
  638. expect(data.stateModel).toEqual("Review");
  639. expect(data.state).toEqual("Rejected");
  640. });
  641. });
  642. describe("LinkAnnotation", function () {
  643. it("should correctly parse a URI action", async function () {
  644. const actionDict = new _primitives.Dict();
  645. actionDict.set("Type", _primitives.Name.get("Action"));
  646. actionDict.set("S", _primitives.Name.get("URI"));
  647. actionDict.set("URI", "http://www.ctan.org/tex-archive/info/lshort");
  648. const annotationDict = new _primitives.Dict();
  649. annotationDict.set("Type", _primitives.Name.get("Annot"));
  650. annotationDict.set("Subtype", _primitives.Name.get("Link"));
  651. annotationDict.set("A", actionDict);
  652. const annotationRef = _primitives.Ref.get(820, 0);
  653. const xref = new _test_utils.XRefMock([{
  654. ref: annotationRef,
  655. data: annotationDict
  656. }]);
  657. const {
  658. data
  659. } = await _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  660. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  661. expect(data.url).toEqual("http://www.ctan.org/tex-archive/info/lshort");
  662. expect(data.unsafeUrl).toEqual("http://www.ctan.org/tex-archive/info/lshort");
  663. expect(data.dest).toBeUndefined();
  664. });
  665. it("should correctly parse a URI action, where the URI entry " + "is missing a protocol", async function () {
  666. const actionDict = new _primitives.Dict();
  667. actionDict.set("Type", _primitives.Name.get("Action"));
  668. actionDict.set("S", _primitives.Name.get("URI"));
  669. actionDict.set("URI", "www.hmrc.gov.uk");
  670. const annotationDict = new _primitives.Dict();
  671. annotationDict.set("Type", _primitives.Name.get("Annot"));
  672. annotationDict.set("Subtype", _primitives.Name.get("Link"));
  673. annotationDict.set("A", actionDict);
  674. const annotationRef = _primitives.Ref.get(353, 0);
  675. const xref = new _test_utils.XRefMock([{
  676. ref: annotationRef,
  677. data: annotationDict
  678. }]);
  679. const {
  680. data
  681. } = await _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  682. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  683. expect(data.url).toEqual("http://www.hmrc.gov.uk/");
  684. expect(data.unsafeUrl).toEqual("http://www.hmrc.gov.uk");
  685. expect(data.dest).toBeUndefined();
  686. });
  687. it("should correctly parse a URI action, where the URI entry " + "has an incorrect encoding (bug 1122280)", async function () {
  688. const actionStream = new _stream.StringStream("<<\n" + "/Type /Action\n" + "/S /URI\n" + "/URI (http://www.example.com/\\303\\274\\303\\266\\303\\244)\n" + ">>\n");
  689. const parser = new _parser.Parser({
  690. lexer: new _parser.Lexer(actionStream),
  691. xref: null
  692. });
  693. const actionDict = parser.getObj();
  694. const annotationDict = new _primitives.Dict();
  695. annotationDict.set("Type", _primitives.Name.get("Annot"));
  696. annotationDict.set("Subtype", _primitives.Name.get("Link"));
  697. annotationDict.set("A", actionDict);
  698. const annotationRef = _primitives.Ref.get(8, 0);
  699. const xref = new _test_utils.XRefMock([{
  700. ref: annotationRef,
  701. data: annotationDict
  702. }]);
  703. const {
  704. data
  705. } = await _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  706. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  707. expect(data.url).toEqual(new URL((0, _util.stringToUTF8String)("http://www.example.com/\xC3\xBC\xC3\xB6\xC3\xA4")).href);
  708. expect(data.unsafeUrl).toEqual((0, _util.stringToUTF8String)("http://www.example.com/\xC3\xBC\xC3\xB6\xC3\xA4"));
  709. expect(data.dest).toBeUndefined();
  710. });
  711. it("should correctly parse a GoTo action", async function () {
  712. const actionDict = new _primitives.Dict();
  713. actionDict.set("Type", _primitives.Name.get("Action"));
  714. actionDict.set("S", _primitives.Name.get("GoTo"));
  715. actionDict.set("D", "page.157");
  716. const annotationDict = new _primitives.Dict();
  717. annotationDict.set("Type", _primitives.Name.get("Annot"));
  718. annotationDict.set("Subtype", _primitives.Name.get("Link"));
  719. annotationDict.set("A", actionDict);
  720. const annotationRef = _primitives.Ref.get(798, 0);
  721. const xref = new _test_utils.XRefMock([{
  722. ref: annotationRef,
  723. data: annotationDict
  724. }]);
  725. const {
  726. data
  727. } = await _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  728. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  729. expect(data.url).toBeUndefined();
  730. expect(data.unsafeUrl).toBeUndefined();
  731. expect(data.dest).toEqual("page.157");
  732. });
  733. it("should correctly parse a GoToR action, where the FileSpec entry " + "is a string containing a relative URL", async function () {
  734. const actionDict = new _primitives.Dict();
  735. actionDict.set("Type", _primitives.Name.get("Action"));
  736. actionDict.set("S", _primitives.Name.get("GoToR"));
  737. actionDict.set("F", "../../0013/001346/134685E.pdf");
  738. actionDict.set("D", "4.3");
  739. actionDict.set("NewWindow", true);
  740. const annotationDict = new _primitives.Dict();
  741. annotationDict.set("Type", _primitives.Name.get("Annot"));
  742. annotationDict.set("Subtype", _primitives.Name.get("Link"));
  743. annotationDict.set("A", actionDict);
  744. const annotationRef = _primitives.Ref.get(489, 0);
  745. const xref = new _test_utils.XRefMock([{
  746. ref: annotationRef,
  747. data: annotationDict
  748. }]);
  749. const {
  750. data
  751. } = await _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  752. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  753. expect(data.url).toBeUndefined();
  754. expect(data.unsafeUrl).toEqual("../../0013/001346/134685E.pdf#4.3");
  755. expect(data.dest).toBeUndefined();
  756. expect(data.newWindow).toEqual(true);
  757. });
  758. it("should correctly parse a GoToR action, containing a relative URL, " + 'with the "docBaseUrl" parameter specified', async function () {
  759. const actionDict = new _primitives.Dict();
  760. actionDict.set("Type", _primitives.Name.get("Action"));
  761. actionDict.set("S", _primitives.Name.get("GoToR"));
  762. actionDict.set("F", "../../0013/001346/134685E.pdf");
  763. actionDict.set("D", "4.3");
  764. const annotationDict = new _primitives.Dict();
  765. annotationDict.set("Type", _primitives.Name.get("Annot"));
  766. annotationDict.set("Subtype", _primitives.Name.get("Link"));
  767. annotationDict.set("A", actionDict);
  768. const annotationRef = _primitives.Ref.get(489, 0);
  769. const xref = new _test_utils.XRefMock([{
  770. ref: annotationRef,
  771. data: annotationDict
  772. }]);
  773. const pdfManager = new PDFManagerMock({
  774. docBaseUrl: "http://www.example.com/test/pdfs/qwerty.pdf"
  775. });
  776. const {
  777. data
  778. } = await _annotation.AnnotationFactory.create(xref, annotationRef, pdfManager, idFactoryMock);
  779. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  780. expect(data.url).toEqual("http://www.example.com/0013/001346/134685E.pdf#4.3");
  781. expect(data.unsafeUrl).toEqual("../../0013/001346/134685E.pdf#4.3");
  782. expect(data.dest).toBeUndefined();
  783. });
  784. it("should correctly parse a GoToR action, with named destination", async function () {
  785. const actionDict = new _primitives.Dict();
  786. actionDict.set("Type", _primitives.Name.get("Action"));
  787. actionDict.set("S", _primitives.Name.get("GoToR"));
  788. actionDict.set("F", "http://www.example.com/test.pdf");
  789. actionDict.set("D", "15");
  790. const annotationDict = new _primitives.Dict();
  791. annotationDict.set("Type", _primitives.Name.get("Annot"));
  792. annotationDict.set("Subtype", _primitives.Name.get("Link"));
  793. annotationDict.set("A", actionDict);
  794. const annotationRef = _primitives.Ref.get(495, 0);
  795. const xref = new _test_utils.XRefMock([{
  796. ref: annotationRef,
  797. data: annotationDict
  798. }]);
  799. const {
  800. data
  801. } = await _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  802. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  803. expect(data.url).toEqual("http://www.example.com/test.pdf#15");
  804. expect(data.unsafeUrl).toEqual("http://www.example.com/test.pdf#15");
  805. expect(data.dest).toBeUndefined();
  806. expect(data.newWindow).toBeFalsy();
  807. });
  808. it("should correctly parse a GoToR action, with explicit destination array", async function () {
  809. const actionDict = new _primitives.Dict();
  810. actionDict.set("Type", _primitives.Name.get("Action"));
  811. actionDict.set("S", _primitives.Name.get("GoToR"));
  812. actionDict.set("F", "http://www.example.com/test.pdf");
  813. actionDict.set("D", [14, _primitives.Name.get("XYZ"), null, 298.043, null]);
  814. const annotationDict = new _primitives.Dict();
  815. annotationDict.set("Type", _primitives.Name.get("Annot"));
  816. annotationDict.set("Subtype", _primitives.Name.get("Link"));
  817. annotationDict.set("A", actionDict);
  818. const annotationRef = _primitives.Ref.get(489, 0);
  819. const xref = new _test_utils.XRefMock([{
  820. ref: annotationRef,
  821. data: annotationDict
  822. }]);
  823. const {
  824. data
  825. } = await _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  826. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  827. expect(data.url).toEqual(new URL("http://www.example.com/test.pdf#" + '[14,{"name":"XYZ"},null,298.043,null]').href);
  828. expect(data.unsafeUrl).toEqual("http://www.example.com/test.pdf#" + '[14,{"name":"XYZ"},null,298.043,null]');
  829. expect(data.dest).toBeUndefined();
  830. expect(data.newWindow).toBeFalsy();
  831. });
  832. it("should correctly parse a Launch action, where the FileSpec dict " + 'contains a relative URL, with the "docBaseUrl" parameter specified', async function () {
  833. const fileSpecDict = new _primitives.Dict();
  834. fileSpecDict.set("Type", _primitives.Name.get("FileSpec"));
  835. fileSpecDict.set("F", "Part II/Part II.pdf");
  836. fileSpecDict.set("UF", "Part II/Part II.pdf");
  837. const actionDict = new _primitives.Dict();
  838. actionDict.set("Type", _primitives.Name.get("Action"));
  839. actionDict.set("S", _primitives.Name.get("Launch"));
  840. actionDict.set("F", fileSpecDict);
  841. actionDict.set("NewWindow", true);
  842. const annotationDict = new _primitives.Dict();
  843. annotationDict.set("Type", _primitives.Name.get("Annot"));
  844. annotationDict.set("Subtype", _primitives.Name.get("Link"));
  845. annotationDict.set("A", actionDict);
  846. const annotationRef = _primitives.Ref.get(88, 0);
  847. const xref = new _test_utils.XRefMock([{
  848. ref: annotationRef,
  849. data: annotationDict
  850. }]);
  851. const pdfManager = new PDFManagerMock({
  852. docBaseUrl: "http://www.example.com/test/pdfs/qwerty.pdf"
  853. });
  854. const {
  855. data
  856. } = await _annotation.AnnotationFactory.create(xref, annotationRef, pdfManager, idFactoryMock);
  857. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  858. expect(data.url).toEqual(new URL("http://www.example.com/test/pdfs/Part II/Part II.pdf").href);
  859. expect(data.unsafeUrl).toEqual("Part II/Part II.pdf");
  860. expect(data.dest).toBeUndefined();
  861. expect(data.newWindow).toEqual(true);
  862. });
  863. it("should recover valid URLs from JavaScript actions having certain " + "white-listed formats", async function () {
  864. function checkJsAction(params) {
  865. const jsEntry = params.jsEntry;
  866. const expectedUrl = params.expectedUrl;
  867. const expectedUnsafeUrl = params.expectedUnsafeUrl;
  868. const expectedNewWindow = params.expectedNewWindow;
  869. const actionDict = new _primitives.Dict();
  870. actionDict.set("Type", _primitives.Name.get("Action"));
  871. actionDict.set("S", _primitives.Name.get("JavaScript"));
  872. actionDict.set("JS", jsEntry);
  873. const annotationDict = new _primitives.Dict();
  874. annotationDict.set("Type", _primitives.Name.get("Annot"));
  875. annotationDict.set("Subtype", _primitives.Name.get("Link"));
  876. annotationDict.set("A", actionDict);
  877. const annotationRef = _primitives.Ref.get(46, 0);
  878. const xref = new _test_utils.XRefMock([{
  879. ref: annotationRef,
  880. data: annotationDict
  881. }]);
  882. return _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock).then(({
  883. data
  884. }) => {
  885. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  886. expect(data.url).toEqual(expectedUrl);
  887. expect(data.unsafeUrl).toEqual(expectedUnsafeUrl);
  888. expect(data.dest).toBeUndefined();
  889. expect(data.newWindow).toEqual(expectedNewWindow);
  890. });
  891. }
  892. const annotation1 = checkJsAction({
  893. jsEntry: 'function someFun() { return "qwerty"; } someFun();',
  894. expectedUrl: undefined,
  895. expectedUnsafeUrl: undefined,
  896. expectedNewWindow: undefined
  897. });
  898. const annotation2 = checkJsAction({
  899. jsEntry: "window.open('http://www.example.com/test.pdf')",
  900. expectedUrl: new URL("http://www.example.com/test.pdf").href,
  901. expectedUnsafeUrl: "http://www.example.com/test.pdf",
  902. expectedNewWindow: undefined
  903. });
  904. const annotation3 = checkJsAction({
  905. jsEntry: new _stream.StringStream('app.launchURL("http://www.example.com/test.pdf", true)'),
  906. expectedUrl: new URL("http://www.example.com/test.pdf").href,
  907. expectedUnsafeUrl: "http://www.example.com/test.pdf",
  908. expectedNewWindow: true
  909. });
  910. await Promise.all([annotation1, annotation2, annotation3]);
  911. });
  912. it("should correctly parse a Named action", async function () {
  913. const actionDict = new _primitives.Dict();
  914. actionDict.set("Type", _primitives.Name.get("Action"));
  915. actionDict.set("S", _primitives.Name.get("Named"));
  916. actionDict.set("N", _primitives.Name.get("GoToPage"));
  917. const annotationDict = new _primitives.Dict();
  918. annotationDict.set("Type", _primitives.Name.get("Annot"));
  919. annotationDict.set("Subtype", _primitives.Name.get("Link"));
  920. annotationDict.set("A", actionDict);
  921. const annotationRef = _primitives.Ref.get(12, 0);
  922. const xref = new _test_utils.XRefMock([{
  923. ref: annotationRef,
  924. data: annotationDict
  925. }]);
  926. const {
  927. data
  928. } = await _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  929. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  930. expect(data.url).toBeUndefined();
  931. expect(data.unsafeUrl).toBeUndefined();
  932. expect(data.action).toEqual("GoToPage");
  933. });
  934. it("should correctly parse a simple Dest", async function () {
  935. const annotationDict = new _primitives.Dict();
  936. annotationDict.set("Type", _primitives.Name.get("Annot"));
  937. annotationDict.set("Subtype", _primitives.Name.get("Link"));
  938. annotationDict.set("Dest", _primitives.Name.get("LI0"));
  939. const annotationRef = _primitives.Ref.get(583, 0);
  940. const xref = new _test_utils.XRefMock([{
  941. ref: annotationRef,
  942. data: annotationDict
  943. }]);
  944. const {
  945. data
  946. } = await _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  947. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  948. expect(data.url).toBeUndefined();
  949. expect(data.unsafeUrl).toBeUndefined();
  950. expect(data.dest).toEqual("LI0");
  951. });
  952. it("should correctly parse a simple Dest, with explicit destination array", async function () {
  953. const annotationDict = new _primitives.Dict();
  954. annotationDict.set("Type", _primitives.Name.get("Annot"));
  955. annotationDict.set("Subtype", _primitives.Name.get("Link"));
  956. annotationDict.set("Dest", [_primitives.Ref.get(17, 0), _primitives.Name.get("XYZ"), 0, 841.89, null]);
  957. const annotationRef = _primitives.Ref.get(10, 0);
  958. const xref = new _test_utils.XRefMock([{
  959. ref: annotationRef,
  960. data: annotationDict
  961. }]);
  962. const {
  963. data
  964. } = await _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  965. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  966. expect(data.url).toBeUndefined();
  967. expect(data.unsafeUrl).toBeUndefined();
  968. expect(data.dest).toEqual([_primitives.Ref.get(17, 0), _primitives.Name.get("XYZ"), 0, 841.89, null]);
  969. });
  970. it("should correctly parse a Dest, which violates the specification " + "by containing a dictionary", async function () {
  971. const destDict = new _primitives.Dict();
  972. destDict.set("Type", _primitives.Name.get("Action"));
  973. destDict.set("S", _primitives.Name.get("GoTo"));
  974. destDict.set("D", "page.157");
  975. const annotationDict = new _primitives.Dict();
  976. annotationDict.set("Type", _primitives.Name.get("Annot"));
  977. annotationDict.set("Subtype", _primitives.Name.get("Link"));
  978. annotationDict.set("Dest", destDict);
  979. const annotationRef = _primitives.Ref.get(798, 0);
  980. const xref = new _test_utils.XRefMock([{
  981. ref: annotationRef,
  982. data: annotationDict
  983. }]);
  984. const {
  985. data
  986. } = await _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  987. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  988. expect(data.url).toBeUndefined();
  989. expect(data.unsafeUrl).toBeUndefined();
  990. expect(data.dest).toEqual("page.157");
  991. });
  992. it("should not set quadpoints if not defined", async function () {
  993. const annotationDict = new _primitives.Dict();
  994. annotationDict.set("Type", _primitives.Name.get("Annot"));
  995. annotationDict.set("Subtype", _primitives.Name.get("Link"));
  996. const annotationRef = _primitives.Ref.get(121, 0);
  997. const xref = new _test_utils.XRefMock([{
  998. ref: annotationRef,
  999. data: annotationDict
  1000. }]);
  1001. const {
  1002. data
  1003. } = await _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  1004. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  1005. expect(data.quadPoints).toBeUndefined();
  1006. });
  1007. it("should set quadpoints if defined", async function () {
  1008. const annotationDict = new _primitives.Dict();
  1009. annotationDict.set("Type", _primitives.Name.get("Annot"));
  1010. annotationDict.set("Subtype", _primitives.Name.get("Link"));
  1011. annotationDict.set("Rect", [10, 10, 20, 20]);
  1012. annotationDict.set("QuadPoints", [10, 20, 20, 20, 10, 10, 20, 10]);
  1013. const annotationRef = _primitives.Ref.get(121, 0);
  1014. const xref = new _test_utils.XRefMock([{
  1015. ref: annotationRef,
  1016. data: annotationDict
  1017. }]);
  1018. const {
  1019. data
  1020. } = await _annotation.AnnotationFactory.create(xref, annotationRef, pdfManagerMock, idFactoryMock);
  1021. expect(data.annotationType).toEqual(_util.AnnotationType.LINK);
  1022. expect(data.quadPoints).toEqual([[{
  1023. x: 10,
  1024. y: 20
  1025. }, {
  1026. x: 20,
  1027. y: 20
  1028. }, {
  1029. x: 10,
  1030. y: 10
  1031. }, {
  1032. x: 20,
  1033. y: 10
  1034. }]]);
  1035. });
  1036. });
  1037. describe("WidgetAnnotation", function () {
  1038. let widgetDict;
  1039. beforeEach(function () {
  1040. widgetDict = new _primitives.Dict();
  1041. widgetDict.set("Type", _primitives.Name.get("Annot"));
  1042. widgetDict.set("Subtype", _primitives.Name.get("Widget"));
  1043. });
  1044. afterEach(function () {
  1045. widgetDict = null;
  1046. });
  1047. it("should handle unknown field names", async function () {
  1048. const widgetRef = _primitives.Ref.get(20, 0);
  1049. const xref = new _test_utils.XRefMock([{
  1050. ref: widgetRef,
  1051. data: widgetDict
  1052. }]);
  1053. const {
  1054. data
  1055. } = await _annotation.AnnotationFactory.create(xref, widgetRef, pdfManagerMock, idFactoryMock);
  1056. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  1057. expect(data.fieldName).toEqual("");
  1058. });
  1059. it("should construct the field name when there are no ancestors", async function () {
  1060. widgetDict.set("T", "foo");
  1061. const widgetRef = _primitives.Ref.get(21, 0);
  1062. const xref = new _test_utils.XRefMock([{
  1063. ref: widgetRef,
  1064. data: widgetDict
  1065. }]);
  1066. const {
  1067. data
  1068. } = await _annotation.AnnotationFactory.create(xref, widgetRef, pdfManagerMock, idFactoryMock);
  1069. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  1070. expect(data.fieldName).toEqual("foo");
  1071. });
  1072. it("should construct the field name when there are ancestors", async function () {
  1073. const firstParent = new _primitives.Dict();
  1074. firstParent.set("T", "foo");
  1075. const secondParent = new _primitives.Dict();
  1076. secondParent.set("Parent", firstParent);
  1077. secondParent.set("T", "bar");
  1078. widgetDict.set("Parent", secondParent);
  1079. widgetDict.set("T", "baz");
  1080. const widgetRef = _primitives.Ref.get(22, 0);
  1081. const xref = new _test_utils.XRefMock([{
  1082. ref: widgetRef,
  1083. data: widgetDict
  1084. }]);
  1085. const {
  1086. data
  1087. } = await _annotation.AnnotationFactory.create(xref, widgetRef, pdfManagerMock, idFactoryMock);
  1088. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  1089. expect(data.fieldName).toEqual("foo.bar.baz");
  1090. });
  1091. it("should construct the field name if a parent is not a dictionary " + "(issue 8143)", async function () {
  1092. const parentDict = new _primitives.Dict();
  1093. parentDict.set("Parent", null);
  1094. parentDict.set("T", "foo");
  1095. widgetDict.set("Parent", parentDict);
  1096. widgetDict.set("T", "bar");
  1097. const widgetRef = _primitives.Ref.get(22, 0);
  1098. const xref = new _test_utils.XRefMock([{
  1099. ref: widgetRef,
  1100. data: widgetDict
  1101. }]);
  1102. const {
  1103. data
  1104. } = await _annotation.AnnotationFactory.create(xref, widgetRef, pdfManagerMock, idFactoryMock);
  1105. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  1106. expect(data.fieldName).toEqual("foo.bar");
  1107. });
  1108. });
  1109. describe("TextWidgetAnnotation", function () {
  1110. let textWidgetDict, helvRefObj, gothRefObj;
  1111. beforeEach(function () {
  1112. textWidgetDict = new _primitives.Dict();
  1113. textWidgetDict.set("Type", _primitives.Name.get("Annot"));
  1114. textWidgetDict.set("Subtype", _primitives.Name.get("Widget"));
  1115. textWidgetDict.set("FT", _primitives.Name.get("Tx"));
  1116. const helvDict = new _primitives.Dict();
  1117. helvDict.set("BaseFont", _primitives.Name.get("Helvetica"));
  1118. helvDict.set("Type", _primitives.Name.get("Font"));
  1119. helvDict.set("Subtype", _primitives.Name.get("Type1"));
  1120. const gothDict = new _primitives.Dict();
  1121. gothDict.set("BaseFont", _primitives.Name.get("MSGothic"));
  1122. gothDict.set("Type", _primitives.Name.get("Font"));
  1123. gothDict.set("Subtype", _primitives.Name.get("Type0"));
  1124. gothDict.set("Encoding", _primitives.Name.get("UniJIS-UTF16-H"));
  1125. gothDict.set("Name", _primitives.Name.get("MSGothic"));
  1126. const cidSysInfoDict = new _primitives.Dict();
  1127. cidSysInfoDict.set("Ordering", "Japan1");
  1128. cidSysInfoDict.set("Registry", "Adobe");
  1129. cidSysInfoDict.set("Supplement", "5");
  1130. const fontDescriptorDict = new _primitives.Dict();
  1131. fontDescriptorDict.set("FontName", _primitives.Name.get("MSGothic"));
  1132. fontDescriptorDict.set("CapHeight", "680");
  1133. const gothDescendantDict = new _primitives.Dict();
  1134. gothDescendantDict.set("BaseFont", _primitives.Name.get("MSGothic"));
  1135. gothDescendantDict.set("CIDSystemInfo", cidSysInfoDict);
  1136. gothDescendantDict.set("Subtype", _primitives.Name.get("CIDFontType2"));
  1137. gothDescendantDict.set("Type", _primitives.Name.get("Font"));
  1138. gothDescendantDict.set("FontDescriptor", fontDescriptorDict);
  1139. gothDict.set("DescendantFonts", [gothDescendantDict]);
  1140. const helvRef = _primitives.Ref.get(314, 0);
  1141. const gothRef = _primitives.Ref.get(159, 0);
  1142. helvRefObj = {
  1143. ref: helvRef,
  1144. data: helvDict
  1145. };
  1146. gothRefObj = {
  1147. ref: gothRef,
  1148. data: gothDict
  1149. };
  1150. const resourceDict = new _primitives.Dict();
  1151. const fontDict = new _primitives.Dict();
  1152. fontDict.set("Helv", helvRef);
  1153. resourceDict.set("Font", fontDict);
  1154. textWidgetDict.set("DA", "/Helv 5 Tf");
  1155. textWidgetDict.set("DR", resourceDict);
  1156. textWidgetDict.set("Rect", [0, 0, 32, 10]);
  1157. });
  1158. afterEach(function () {
  1159. textWidgetDict = helvRefObj = gothRefObj = null;
  1160. });
  1161. it("should handle unknown text alignment, maximum length and flags", async function () {
  1162. textWidgetDict.set("DV", "foo");
  1163. const textWidgetRef = _primitives.Ref.get(124, 0);
  1164. const xref = new _test_utils.XRefMock([{
  1165. ref: textWidgetRef,
  1166. data: textWidgetDict
  1167. }]);
  1168. const {
  1169. data
  1170. } = await _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
  1171. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  1172. expect(data.textAlignment).toEqual(null);
  1173. expect(data.maxLen).toEqual(null);
  1174. expect(data.readOnly).toEqual(false);
  1175. expect(data.hidden).toEqual(false);
  1176. expect(data.multiLine).toEqual(false);
  1177. expect(data.comb).toEqual(false);
  1178. expect(data.defaultFieldValue).toEqual("foo");
  1179. });
  1180. it("should not set invalid text alignment, maximum length and flags", async function () {
  1181. textWidgetDict.set("Q", "center");
  1182. textWidgetDict.set("MaxLen", "five");
  1183. textWidgetDict.set("Ff", "readonly");
  1184. const textWidgetRef = _primitives.Ref.get(43, 0);
  1185. const xref = new _test_utils.XRefMock([{
  1186. ref: textWidgetRef,
  1187. data: textWidgetDict
  1188. }]);
  1189. const {
  1190. data
  1191. } = await _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
  1192. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  1193. expect(data.textAlignment).toEqual(null);
  1194. expect(data.maxLen).toEqual(null);
  1195. expect(data.readOnly).toEqual(false);
  1196. expect(data.hidden).toEqual(false);
  1197. expect(data.multiLine).toEqual(false);
  1198. expect(data.comb).toEqual(false);
  1199. });
  1200. it("should set valid text alignment, maximum length and flags", async function () {
  1201. textWidgetDict.set("Q", 1);
  1202. textWidgetDict.set("MaxLen", 20);
  1203. textWidgetDict.set("Ff", _util.AnnotationFieldFlag.READONLY + _util.AnnotationFieldFlag.MULTILINE);
  1204. const textWidgetRef = _primitives.Ref.get(84, 0);
  1205. const xref = new _test_utils.XRefMock([{
  1206. ref: textWidgetRef,
  1207. data: textWidgetDict
  1208. }]);
  1209. const {
  1210. data
  1211. } = await _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
  1212. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  1213. expect(data.textAlignment).toEqual(1);
  1214. expect(data.maxLen).toEqual(20);
  1215. expect(data.readOnly).toEqual(true);
  1216. expect(data.hidden).toEqual(false);
  1217. expect(data.multiLine).toEqual(true);
  1218. });
  1219. it("should reject comb fields without a maximum length", async function () {
  1220. textWidgetDict.set("Ff", _util.AnnotationFieldFlag.COMB);
  1221. const textWidgetRef = _primitives.Ref.get(46, 0);
  1222. const xref = new _test_utils.XRefMock([{
  1223. ref: textWidgetRef,
  1224. data: textWidgetDict
  1225. }]);
  1226. const {
  1227. data
  1228. } = await _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
  1229. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  1230. expect(data.comb).toEqual(false);
  1231. });
  1232. it("should accept comb fields with a maximum length", async function () {
  1233. textWidgetDict.set("MaxLen", 20);
  1234. textWidgetDict.set("Ff", _util.AnnotationFieldFlag.COMB);
  1235. const textWidgetRef = _primitives.Ref.get(46, 0);
  1236. const xref = new _test_utils.XRefMock([{
  1237. ref: textWidgetRef,
  1238. data: textWidgetDict
  1239. }]);
  1240. const {
  1241. data
  1242. } = await _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
  1243. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  1244. expect(data.comb).toEqual(true);
  1245. });
  1246. it("should only accept comb fields when the flags are valid", async function () {
  1247. const invalidFieldFlags = [_util.AnnotationFieldFlag.MULTILINE, _util.AnnotationFieldFlag.PASSWORD, _util.AnnotationFieldFlag.FILESELECT];
  1248. let flags = _util.AnnotationFieldFlag.COMB + _util.AnnotationFieldFlag.MULTILINE + _util.AnnotationFieldFlag.PASSWORD + _util.AnnotationFieldFlag.FILESELECT;
  1249. let promise = Promise.resolve();
  1250. for (let i = 0, ii = invalidFieldFlags.length; i <= ii; i++) {
  1251. promise = promise.then(() => {
  1252. textWidgetDict.set("MaxLen", 20);
  1253. textWidgetDict.set("Ff", flags);
  1254. const textWidgetRef = _primitives.Ref.get(93, 0);
  1255. const xref = new _test_utils.XRefMock([{
  1256. ref: textWidgetRef,
  1257. data: textWidgetDict
  1258. }]);
  1259. return _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock).then(({
  1260. data
  1261. }) => {
  1262. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  1263. const valid = invalidFieldFlags.length === 0;
  1264. expect(data.comb).toEqual(valid);
  1265. if (!valid) {
  1266. flags -= invalidFieldFlags.pop();
  1267. }
  1268. });
  1269. });
  1270. }
  1271. await promise;
  1272. });
  1273. it("should render regular text for printing", async function () {
  1274. const textWidgetRef = _primitives.Ref.get(271, 0);
  1275. const xref = new _test_utils.XRefMock([{
  1276. ref: textWidgetRef,
  1277. data: textWidgetDict
  1278. }, helvRefObj]);
  1279. const task = new _worker.WorkerTask("test print");
  1280. partialEvaluator.xref = xref;
  1281. const annotation = await _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
  1282. const annotationStorage = new Map();
  1283. annotationStorage.set(annotation.data.id, {
  1284. value: "test\\print"
  1285. });
  1286. const appearance = await annotation._getAppearance(partialEvaluator, task, annotationStorage);
  1287. expect(appearance).toEqual("/Tx BMC q BT /Helv 5 Tf 1 0 0 1 0 0 Tm" + " 2.00 2.00 Td (test\\\\print) Tj ET Q EMC");
  1288. });
  1289. it("should render regular text in Japanese for printing", async function () {
  1290. textWidgetDict.get("DR").get("Font").set("Goth", gothRefObj.ref);
  1291. textWidgetDict.set("DA", "/Goth 5 Tf");
  1292. const textWidgetRef = _primitives.Ref.get(271, 0);
  1293. const xref = new _test_utils.XRefMock([{
  1294. ref: textWidgetRef,
  1295. data: textWidgetDict
  1296. }, gothRefObj]);
  1297. const task = new _worker.WorkerTask("test print");
  1298. partialEvaluator.xref = xref;
  1299. const annotation = await _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
  1300. const annotationStorage = new Map();
  1301. annotationStorage.set(annotation.data.id, {
  1302. value: "こんにちは世界の"
  1303. });
  1304. const appearance = await annotation._getAppearance(partialEvaluator, task, annotationStorage);
  1305. const utf16String = "\x30\x53\x30\x93\x30\x6b\x30\x61\x30\x6f\x4e\x16\x75\x4c\x30\x6e";
  1306. expect(appearance).toEqual("/Tx BMC q BT /Goth 5 Tf 1 0 0 1 0 0 Tm" + ` 2.00 2.00 Td (${utf16String}) Tj ET Q EMC`);
  1307. });
  1308. it("should render regular text for printing using normal appearance", async function () {
  1309. const textWidgetRef = _primitives.Ref.get(271, 0);
  1310. const appearanceStatesDict = new _primitives.Dict();
  1311. const normalAppearanceDict = new _primitives.Dict();
  1312. const normalAppearanceStream = new _stream.StringStream("0.1 0.2 0.3 rg");
  1313. normalAppearanceStream.dict = normalAppearanceDict;
  1314. appearanceStatesDict.set("N", normalAppearanceStream);
  1315. textWidgetDict.set("AP", appearanceStatesDict);
  1316. const xref = new _test_utils.XRefMock([{
  1317. ref: textWidgetRef,
  1318. data: textWidgetDict
  1319. }, helvRefObj]);
  1320. const task = new _worker.WorkerTask("test print");
  1321. partialEvaluator.xref = xref;
  1322. const annotation = await _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
  1323. const annotationStorage = new Map();
  1324. const operatorList = await annotation.getOperatorList(partialEvaluator, task, false, annotationStorage);
  1325. expect(operatorList.argsArray.length).toEqual(3);
  1326. expect(operatorList.fnArray).toEqual([_util.OPS.beginAnnotation, _util.OPS.setFillRGBColor, _util.OPS.endAnnotation]);
  1327. expect(operatorList.argsArray[1]).toEqual(new Uint8ClampedArray([26, 51, 76]));
  1328. });
  1329. it("should render auto-sized text for printing", async function () {
  1330. textWidgetDict.set("DA", "/Helv 0 Tf");
  1331. const textWidgetRef = _primitives.Ref.get(271, 0);
  1332. const xref = new _test_utils.XRefMock([{
  1333. ref: textWidgetRef,
  1334. data: textWidgetDict
  1335. }, helvRefObj]);
  1336. const task = new _worker.WorkerTask("test print");
  1337. partialEvaluator.xref = xref;
  1338. const annotation = await _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
  1339. const annotationStorage = new Map();
  1340. annotationStorage.set(annotation.data.id, {
  1341. value: "test (print)"
  1342. });
  1343. const appearance = await annotation._getAppearance(partialEvaluator, task, annotationStorage);
  1344. expect(appearance).toEqual("/Tx BMC q BT /Helv 8 Tf 0 g 1 0 0 1 0 0 Tm" + " 2.00 2.00 Td (test \\(print\\)) Tj ET Q EMC");
  1345. });
  1346. it("should render auto-sized text in Japanese for printing", async function () {
  1347. textWidgetDict.get("DR").get("Font").set("Goth", gothRefObj.ref);
  1348. textWidgetDict.set("DA", "/Goth 0 Tf");
  1349. const textWidgetRef = _primitives.Ref.get(271, 0);
  1350. const xref = new _test_utils.XRefMock([{
  1351. ref: textWidgetRef,
  1352. data: textWidgetDict
  1353. }, gothRefObj]);
  1354. const task = new _worker.WorkerTask("test print");
  1355. partialEvaluator.xref = xref;
  1356. const annotation = await _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
  1357. const annotationStorage = new Map();
  1358. annotationStorage.set(annotation.data.id, {
  1359. value: "こんにちは世界の"
  1360. });
  1361. const appearance = await annotation._getAppearance(partialEvaluator, task, annotationStorage);
  1362. const utf16String = "\x30\x53\x30\x93\x30\x6b\x30\x61\x30\x6f\x4e\x16\x75\x4c\x30\x6e";
  1363. expect(appearance).toEqual("/Tx BMC q BT /Goth 8 Tf 0 g 1 0 0 1 0 0 Tm" + ` 2.00 2.00 Td (${utf16String}) Tj ET Q EMC`);
  1364. });
  1365. it("should not render a password for printing", async function () {
  1366. textWidgetDict.set("Ff", _util.AnnotationFieldFlag.PASSWORD);
  1367. const textWidgetRef = _primitives.Ref.get(271, 0);
  1368. const xref = new _test_utils.XRefMock([{
  1369. ref: textWidgetRef,
  1370. data: textWidgetDict
  1371. }, helvRefObj]);
  1372. const task = new _worker.WorkerTask("test print");
  1373. partialEvaluator.xref = xref;
  1374. const annotation = await _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
  1375. const annotationStorage = new Map();
  1376. annotationStorage.set(annotation.data.id, {
  1377. value: "mypassword"
  1378. });
  1379. const appearance = await annotation._getAppearance(partialEvaluator, task, annotationStorage);
  1380. expect(appearance).toEqual(null);
  1381. });
  1382. it("should render multiline text for printing", async function () {
  1383. textWidgetDict.set("Ff", _util.AnnotationFieldFlag.MULTILINE);
  1384. const textWidgetRef = _primitives.Ref.get(271, 0);
  1385. const xref = new _test_utils.XRefMock([{
  1386. ref: textWidgetRef,
  1387. data: textWidgetDict
  1388. }, helvRefObj]);
  1389. const task = new _worker.WorkerTask("test print");
  1390. partialEvaluator.xref = xref;
  1391. const annotation = await _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
  1392. const annotationStorage = new Map();
  1393. annotationStorage.set(annotation.data.id, {
  1394. value: "a aa aaa aaaa aaaaa aaaaaa " + "pneumonoultramicroscopicsilicovolcanoconiosis"
  1395. });
  1396. const appearance = await annotation._getAppearance(partialEvaluator, task, annotationStorage);
  1397. expect(appearance).toEqual("/Tx BMC q BT /Helv 5 Tf 1 0 0 1 0 10 Tm " + "2.00 -5.00 Td (a aa aaa ) Tj\n" + "0.00 -5.00 Td (aaaa aaaaa ) Tj\n" + "0.00 -5.00 Td (aaaaaa ) Tj\n" + "0.00 -5.00 Td (pneumonoultr) Tj\n" + "0.00 -5.00 Td (amicroscopi) Tj\n" + "0.00 -5.00 Td (csilicovolca) Tj\n" + "0.00 -5.00 Td (noconiosis) Tj ET Q EMC");
  1398. });
  1399. it("should render multiline text in Japanese for printing", async function () {
  1400. textWidgetDict.set("Ff", _util.AnnotationFieldFlag.MULTILINE);
  1401. textWidgetDict.get("DR").get("Font").set("Goth", gothRefObj.ref);
  1402. textWidgetDict.set("DA", "/Goth 5 Tf");
  1403. const textWidgetRef = _primitives.Ref.get(271, 0);
  1404. const xref = new _test_utils.XRefMock([{
  1405. ref: textWidgetRef,
  1406. data: textWidgetDict
  1407. }, gothRefObj]);
  1408. const task = new _worker.WorkerTask("test print");
  1409. partialEvaluator.xref = xref;
  1410. const annotation = await _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
  1411. const annotationStorage = new Map();
  1412. annotationStorage.set(annotation.data.id, {
  1413. value: "こんにちは世界の"
  1414. });
  1415. const appearance = await annotation._getAppearance(partialEvaluator, task, annotationStorage);
  1416. expect(appearance).toEqual("/Tx BMC q BT /Goth 5 Tf 1 0 0 1 0 10 Tm " + "2.00 -5.00 Td (\x30\x53\x30\x93\x30\x6b\x30\x61\x30\x6f) Tj\n" + "0.00 -5.00 Td (\x4e\x16\x75\x4c\x30\x6e) Tj ET Q EMC");
  1417. });
  1418. it("should render multiline text with various EOL for printing", async function () {
  1419. textWidgetDict.set("Ff", _util.AnnotationFieldFlag.MULTILINE);
  1420. textWidgetDict.set("Rect", [0, 0, 128, 10]);
  1421. const textWidgetRef = _primitives.Ref.get(271, 0);
  1422. const xref = new _test_utils.XRefMock([{
  1423. ref: textWidgetRef,
  1424. data: textWidgetDict
  1425. }, helvRefObj]);
  1426. const task = new _worker.WorkerTask("test print");
  1427. partialEvaluator.xref = xref;
  1428. const expectedAppearance = "/Tx BMC q BT /Helv 5 Tf 1 0 0 1 0 10 Tm " + "2.00 -5.00 Td " + "(Lorem ipsum dolor sit amet, consectetur adipiscing elit.) Tj\n" + "0.00 -5.00 Td " + "(Aliquam vitae felis ac lectus bibendum ultricies quis non) Tj\n" + "0.00 -5.00 Td " + "( diam.) Tj\n" + "0.00 -5.00 Td " + "(Morbi id porttitor quam, a iaculis dui.) Tj\n" + "0.00 -5.00 Td " + "(Pellentesque habitant morbi tristique senectus et netus ) Tj\n" + "0.00 -5.00 Td " + "(et malesuada fames ac turpis egestas.) Tj\n" + "0.00 -5.00 Td () Tj\n" + "0.00 -5.00 Td () Tj\n" + "0.00 -5.00 Td " + "(Nulla consectetur, ligula in tincidunt placerat, velit ) Tj\n" + "0.00 -5.00 Td " + "(augue consectetur orci, sed mattis libero nunc ut massa.) Tj\n" + "0.00 -5.00 Td " + "(Etiam facilisis tempus interdum.) Tj ET Q EMC";
  1429. const annotation = await _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
  1430. const annotationStorage = new Map();
  1431. annotationStorage.set(annotation.data.id, {
  1432. value: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\r" + "Aliquam vitae felis ac lectus bibendum ultricies quis non diam.\n" + "Morbi id porttitor quam, a iaculis dui.\r\n" + "Pellentesque habitant morbi tristique senectus et " + "netus et malesuada fames ac turpis egestas.\n\r\n\r" + "Nulla consectetur, ligula in tincidunt placerat, " + "velit augue consectetur orci, sed mattis libero nunc ut massa.\r" + "Etiam facilisis tempus interdum."
  1433. });
  1434. const appearance = await annotation._getAppearance(partialEvaluator, task, annotationStorage);
  1435. expect(appearance).toEqual(expectedAppearance);
  1436. });
  1437. it("should render comb for printing", async function () {
  1438. textWidgetDict.set("Ff", _util.AnnotationFieldFlag.COMB);
  1439. textWidgetDict.set("MaxLen", 4);
  1440. const textWidgetRef = _primitives.Ref.get(271, 0);
  1441. const xref = new _test_utils.XRefMock([{
  1442. ref: textWidgetRef,
  1443. data: textWidgetDict
  1444. }, helvRefObj]);
  1445. const task = new _worker.WorkerTask("test print");
  1446. partialEvaluator.xref = xref;
  1447. const annotation = await _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
  1448. const annotationStorage = new Map();
  1449. annotationStorage.set(annotation.data.id, {
  1450. value: "aa(aa)a\\"
  1451. });
  1452. const appearance = await annotation._getAppearance(partialEvaluator, task, annotationStorage);
  1453. expect(appearance).toEqual("/Tx BMC q BT /Helv 5 Tf 1 0 0 1 2 2 Tm" + " (a) Tj 8.00 0 Td (a) Tj 8.00 0 Td (\\() Tj" + " 8.00 0 Td (a) Tj 8.00 0 Td (a) Tj" + " 8.00 0 Td (\\)) Tj 8.00 0 Td (a) Tj" + " 8.00 0 Td (\\\\) Tj ET Q EMC");
  1454. });
  1455. it("should render comb with Japanese text for printing", async function () {
  1456. textWidgetDict.set("Ff", _util.AnnotationFieldFlag.COMB);
  1457. textWidgetDict.set("MaxLen", 4);
  1458. textWidgetDict.get("DR").get("Font").set("Goth", gothRefObj.ref);
  1459. textWidgetDict.set("DA", "/Goth 5 Tf");
  1460. textWidgetDict.set("Rect", [0, 0, 32, 10]);
  1461. const textWidgetRef = _primitives.Ref.get(271, 0);
  1462. const xref = new _test_utils.XRefMock([{
  1463. ref: textWidgetRef,
  1464. data: textWidgetDict
  1465. }, gothRefObj]);
  1466. const task = new _worker.WorkerTask("test print");
  1467. partialEvaluator.xref = xref;
  1468. const annotation = await _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
  1469. const annotationStorage = new Map();
  1470. annotationStorage.set(annotation.data.id, {
  1471. value: "こんにちは世界の"
  1472. });
  1473. const appearance = await annotation._getAppearance(partialEvaluator, task, annotationStorage);
  1474. expect(appearance).toEqual("/Tx BMC q BT /Goth 5 Tf 1 0 0 1 2 2 Tm" + " (\x30\x53) Tj 8.00 0 Td (\x30\x93) Tj 8.00 0 Td (\x30\x6b) Tj" + " 8.00 0 Td (\x30\x61) Tj 8.00 0 Td (\x30\x6f) Tj" + " 8.00 0 Td (\x4e\x16) Tj 8.00 0 Td (\x75\x4c) Tj" + " 8.00 0 Td (\x30\x6e) Tj ET Q EMC");
  1475. });
  1476. it("should save text", async function () {
  1477. const textWidgetRef = _primitives.Ref.get(123, 0);
  1478. const xref = new _test_utils.XRefMock([{
  1479. ref: textWidgetRef,
  1480. data: textWidgetDict
  1481. }, helvRefObj]);
  1482. partialEvaluator.xref = xref;
  1483. const task = new _worker.WorkerTask("test save");
  1484. const annotation = await _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
  1485. const annotationStorage = new Map();
  1486. annotationStorage.set(annotation.data.id, {
  1487. value: "hello world"
  1488. });
  1489. const data = await annotation.save(partialEvaluator, task, annotationStorage);
  1490. expect(data.length).toEqual(2);
  1491. const [oldData, newData] = data;
  1492. expect(oldData.ref).toEqual(_primitives.Ref.get(123, 0));
  1493. expect(newData.ref).toEqual(_primitives.Ref.get(2, 0));
  1494. oldData.data = oldData.data.replace(/\(D:[0-9]+\)/, "(date)");
  1495. expect(oldData.data).toEqual("123 0 obj\n" + "<< /Type /Annot /Subtype /Widget /FT /Tx /DA (/Helv 5 Tf) /DR " + "<< /Font << /Helv 314 0 R>>>> /Rect [0 0 32 10] " + "/V (hello world) /AP << /N 2 0 R>> /M (date)>>\nendobj\n");
  1496. expect(newData.data).toEqual("2 0 obj\n<< /Length 77 /Subtype /Form /Resources " + "<< /Font << /Helv 314 0 R>>>> /BBox [0 0 32 10]>> stream\n" + "/Tx BMC q BT /Helv 5 Tf 1 0 0 1 0 0 Tm 2.00 2.00 Td (hello world) Tj " + "ET Q EMC\nendstream\nendobj\n");
  1497. });
  1498. it("should get field object for usage in JS sandbox", async function () {
  1499. const textWidgetRef = _primitives.Ref.get(123, 0);
  1500. const xDictRef = _primitives.Ref.get(141, 0);
  1501. const dDictRef = _primitives.Ref.get(262, 0);
  1502. const next0Ref = _primitives.Ref.get(314, 0);
  1503. const next1Ref = _primitives.Ref.get(271, 0);
  1504. const next2Ref = _primitives.Ref.get(577, 0);
  1505. const next00Ref = _primitives.Ref.get(413, 0);
  1506. const xDict = new _primitives.Dict();
  1507. const dDict = new _primitives.Dict();
  1508. const next0Dict = new _primitives.Dict();
  1509. const next1Dict = new _primitives.Dict();
  1510. const next2Dict = new _primitives.Dict();
  1511. const next00Dict = new _primitives.Dict();
  1512. const xref = new _test_utils.XRefMock([{
  1513. ref: textWidgetRef,
  1514. data: textWidgetDict
  1515. }, {
  1516. ref: xDictRef,
  1517. data: xDict
  1518. }, {
  1519. ref: dDictRef,
  1520. data: dDict
  1521. }, {
  1522. ref: next0Ref,
  1523. data: next0Dict
  1524. }, {
  1525. ref: next00Ref,
  1526. data: next00Dict
  1527. }, {
  1528. ref: next1Ref,
  1529. data: next1Dict
  1530. }, {
  1531. ref: next2Ref,
  1532. data: next2Dict
  1533. }]);
  1534. const JS = _primitives.Name.get("JavaScript");
  1535. const additionalActionsDict = new _primitives.Dict();
  1536. const eDict = new _primitives.Dict();
  1537. eDict.set("JS", "hello()");
  1538. eDict.set("S", JS);
  1539. additionalActionsDict.set("E", eDict);
  1540. xDict.set("JS", "world()");
  1541. xDict.set("S", JS);
  1542. xDict.set("Next", [next0Ref, next1Ref, next2Ref, xDictRef]);
  1543. next0Dict.set("JS", "olleh()");
  1544. next0Dict.set("S", JS);
  1545. next0Dict.set("Next", next00Ref);
  1546. next00Dict.set("JS", "foo()");
  1547. next00Dict.set("S", JS);
  1548. next00Dict.set("Next", next0Ref);
  1549. next1Dict.set("JS", "dlrow()");
  1550. next1Dict.set("S", JS);
  1551. next1Dict.set("Next", xDictRef);
  1552. next2Dict.set("JS", "oof()");
  1553. next2Dict.set("S", JS);
  1554. dDict.set("JS", "bar()");
  1555. dDict.set("S", JS);
  1556. dDict.set("Next", dDictRef);
  1557. additionalActionsDict.set("D", dDictRef);
  1558. additionalActionsDict.set("X", xDictRef);
  1559. textWidgetDict.set("AA", additionalActionsDict);
  1560. partialEvaluator.xref = xref;
  1561. const annotation = await _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
  1562. const fieldObject = await annotation.getFieldObject();
  1563. const actions = fieldObject.actions;
  1564. expect(actions["Mouse Enter"]).toEqual(["hello()"]);
  1565. expect(actions["Mouse Exit"]).toEqual(["world()", "olleh()", "foo()", "dlrow()", "oof()"]);
  1566. expect(actions["Mouse Down"]).toEqual(["bar()"]);
  1567. });
  1568. it("should save Japanese text", async function () {
  1569. textWidgetDict.get("DR").get("Font").set("Goth", gothRefObj.ref);
  1570. textWidgetDict.set("DA", "/Goth 5 Tf");
  1571. const textWidgetRef = _primitives.Ref.get(123, 0);
  1572. const xref = new _test_utils.XRefMock([{
  1573. ref: textWidgetRef,
  1574. data: textWidgetDict
  1575. }, gothRefObj]);
  1576. partialEvaluator.xref = xref;
  1577. const task = new _worker.WorkerTask("test save");
  1578. const annotation = await _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
  1579. const annotationStorage = new Map();
  1580. annotationStorage.set(annotation.data.id, {
  1581. value: "こんにちは世界の"
  1582. });
  1583. const data = await annotation.save(partialEvaluator, task, annotationStorage);
  1584. const utf16String = "\x30\x53\x30\x93\x30\x6b\x30\x61\x30\x6f\x4e\x16\x75\x4c\x30\x6e";
  1585. expect(data.length).toEqual(2);
  1586. const [oldData, newData] = data;
  1587. expect(oldData.ref).toEqual(_primitives.Ref.get(123, 0));
  1588. expect(newData.ref).toEqual(_primitives.Ref.get(2, 0));
  1589. oldData.data = oldData.data.replace(/\(D:[0-9]+\)/, "(date)");
  1590. expect(oldData.data).toEqual("123 0 obj\n" + "<< /Type /Annot /Subtype /Widget /FT /Tx /DA (/Goth 5 Tf) /DR " + "<< /Font << /Helv 314 0 R /Goth 159 0 R>>>> /Rect [0 0 32 10] " + `/V (\xfe\xff${utf16String}) /AP << /N 2 0 R>> /M (date)>>\nendobj\n`);
  1591. expect(newData.data).toEqual("2 0 obj\n<< /Length 82 /Subtype /Form /Resources " + "<< /Font << /Helv 314 0 R /Goth 159 0 R>>>> /BBox [0 0 32 10]>> stream\n" + `/Tx BMC q BT /Goth 5 Tf 1 0 0 1 0 0 Tm 2.00 2.00 Td (${utf16String}) Tj ` + "ET Q EMC\nendstream\nendobj\n");
  1592. });
  1593. });
  1594. describe("ButtonWidgetAnnotation", function () {
  1595. let buttonWidgetDict;
  1596. beforeEach(function () {
  1597. buttonWidgetDict = new _primitives.Dict();
  1598. buttonWidgetDict.set("Type", _primitives.Name.get("Annot"));
  1599. buttonWidgetDict.set("Subtype", _primitives.Name.get("Widget"));
  1600. buttonWidgetDict.set("FT", _primitives.Name.get("Btn"));
  1601. });
  1602. afterEach(function () {
  1603. buttonWidgetDict = null;
  1604. });
  1605. it("should handle checkboxes with export value", async function () {
  1606. buttonWidgetDict.set("V", _primitives.Name.get("1"));
  1607. buttonWidgetDict.set("DV", _primitives.Name.get("2"));
  1608. const appearanceStatesDict = new _primitives.Dict();
  1609. const normalAppearanceDict = new _primitives.Dict();
  1610. normalAppearanceDict.set("Off", 0);
  1611. normalAppearanceDict.set("Checked", 1);
  1612. appearanceStatesDict.set("N", normalAppearanceDict);
  1613. buttonWidgetDict.set("AP", appearanceStatesDict);
  1614. const buttonWidgetRef = _primitives.Ref.get(124, 0);
  1615. const xref = new _test_utils.XRefMock([{
  1616. ref: buttonWidgetRef,
  1617. data: buttonWidgetDict
  1618. }]);
  1619. const {
  1620. data
  1621. } = await _annotation.AnnotationFactory.create(xref, buttonWidgetRef, pdfManagerMock, idFactoryMock);
  1622. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  1623. expect(data.checkBox).toEqual(true);
  1624. expect(data.fieldValue).toEqual("1");
  1625. expect(data.defaultFieldValue).toEqual("2");
  1626. expect(data.radioButton).toEqual(false);
  1627. expect(data.exportValue).toEqual("Checked");
  1628. });
  1629. it("should handle checkboxes without export value", async function () {
  1630. buttonWidgetDict.set("V", _primitives.Name.get("1"));
  1631. buttonWidgetDict.set("DV", _primitives.Name.get("2"));
  1632. const buttonWidgetRef = _primitives.Ref.get(124, 0);
  1633. const xref = new _test_utils.XRefMock([{
  1634. ref: buttonWidgetRef,
  1635. data: buttonWidgetDict
  1636. }]);
  1637. const {
  1638. data
  1639. } = await _annotation.AnnotationFactory.create(xref, buttonWidgetRef, pdfManagerMock, idFactoryMock);
  1640. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  1641. expect(data.checkBox).toEqual(true);
  1642. expect(data.fieldValue).toEqual("1");
  1643. expect(data.defaultFieldValue).toEqual("2");
  1644. expect(data.radioButton).toEqual(false);
  1645. });
  1646. it("should handle checkboxes without /Off appearance", async function () {
  1647. buttonWidgetDict.set("V", _primitives.Name.get("1"));
  1648. buttonWidgetDict.set("DV", _primitives.Name.get("2"));
  1649. const appearanceStatesDict = new _primitives.Dict();
  1650. const normalAppearanceDict = new _primitives.Dict();
  1651. normalAppearanceDict.set("Checked", 1);
  1652. appearanceStatesDict.set("N", normalAppearanceDict);
  1653. buttonWidgetDict.set("AP", appearanceStatesDict);
  1654. const buttonWidgetRef = _primitives.Ref.get(124, 0);
  1655. const xref = new _test_utils.XRefMock([{
  1656. ref: buttonWidgetRef,
  1657. data: buttonWidgetDict
  1658. }]);
  1659. const {
  1660. data
  1661. } = await _annotation.AnnotationFactory.create(xref, buttonWidgetRef, pdfManagerMock, idFactoryMock);
  1662. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  1663. expect(data.checkBox).toEqual(true);
  1664. expect(data.fieldValue).toEqual("1");
  1665. expect(data.defaultFieldValue).toEqual("2");
  1666. expect(data.radioButton).toEqual(false);
  1667. expect(data.exportValue).toEqual("Checked");
  1668. });
  1669. it("should render checkbox with fallback font for printing", async function () {
  1670. const appearanceStatesDict = new _primitives.Dict();
  1671. const normalAppearanceDict = new _primitives.Dict();
  1672. const checkedAppearanceDict = new _primitives.Dict();
  1673. const uncheckedAppearanceDict = new _primitives.Dict();
  1674. const checkedStream = new _stream.StringStream("/ 12 Tf (4) Tj");
  1675. checkedStream.dict = checkedAppearanceDict;
  1676. const uncheckedStream = new _stream.StringStream("");
  1677. uncheckedStream.dict = uncheckedAppearanceDict;
  1678. checkedAppearanceDict.set("BBox", [0, 0, 8, 8]);
  1679. checkedAppearanceDict.set("FormType", 1);
  1680. checkedAppearanceDict.set("Matrix", [1, 0, 0, 1, 0, 0]);
  1681. normalAppearanceDict.set("Checked", checkedStream);
  1682. normalAppearanceDict.set("Off", uncheckedStream);
  1683. appearanceStatesDict.set("N", normalAppearanceDict);
  1684. buttonWidgetDict.set("AP", appearanceStatesDict);
  1685. const buttonWidgetRef = _primitives.Ref.get(124, 0);
  1686. const xref = new _test_utils.XRefMock([{
  1687. ref: buttonWidgetRef,
  1688. data: buttonWidgetDict
  1689. }]);
  1690. const task = new _worker.WorkerTask("test print");
  1691. partialEvaluator.options = {
  1692. ignoreErrors: true
  1693. };
  1694. const annotation = await _annotation.AnnotationFactory.create(xref, buttonWidgetRef, pdfManagerMock, idFactoryMock);
  1695. const annotationStorage = new Map();
  1696. annotationStorage.set(annotation.data.id, {
  1697. value: true
  1698. });
  1699. const operatorList = await annotation.getOperatorList(partialEvaluator, task, false, annotationStorage);
  1700. expect(operatorList.argsArray.length).toEqual(5);
  1701. expect(operatorList.fnArray).toEqual([_util.OPS.beginAnnotation, _util.OPS.dependency, _util.OPS.setFont, _util.OPS.showText, _util.OPS.endAnnotation]);
  1702. expect(operatorList.argsArray[3][0][0].fontChar).toEqual("✔");
  1703. });
  1704. it("should render checkboxes for printing", async function () {
  1705. const appearanceStatesDict = new _primitives.Dict();
  1706. const normalAppearanceDict = new _primitives.Dict();
  1707. const checkedAppearanceDict = new _primitives.Dict();
  1708. const uncheckedAppearanceDict = new _primitives.Dict();
  1709. const checkedStream = new _stream.StringStream("0.1 0.2 0.3 rg");
  1710. checkedStream.dict = checkedAppearanceDict;
  1711. const uncheckedStream = new _stream.StringStream("0.3 0.2 0.1 rg");
  1712. uncheckedStream.dict = uncheckedAppearanceDict;
  1713. checkedAppearanceDict.set("BBox", [0, 0, 8, 8]);
  1714. checkedAppearanceDict.set("FormType", 1);
  1715. checkedAppearanceDict.set("Matrix", [1, 0, 0, 1, 0, 0]);
  1716. normalAppearanceDict.set("Checked", checkedStream);
  1717. normalAppearanceDict.set("Off", uncheckedStream);
  1718. appearanceStatesDict.set("N", normalAppearanceDict);
  1719. buttonWidgetDict.set("AP", appearanceStatesDict);
  1720. const buttonWidgetRef = _primitives.Ref.get(124, 0);
  1721. const xref = new _test_utils.XRefMock([{
  1722. ref: buttonWidgetRef,
  1723. data: buttonWidgetDict
  1724. }]);
  1725. const task = new _worker.WorkerTask("test print");
  1726. const annotation = await _annotation.AnnotationFactory.create(xref, buttonWidgetRef, pdfManagerMock, idFactoryMock);
  1727. const annotationStorage = new Map();
  1728. annotationStorage.set(annotation.data.id, {
  1729. value: true
  1730. });
  1731. let operatorList = await annotation.getOperatorList(partialEvaluator, task, false, annotationStorage);
  1732. expect(operatorList.argsArray.length).toEqual(3);
  1733. expect(operatorList.fnArray).toEqual([_util.OPS.beginAnnotation, _util.OPS.setFillRGBColor, _util.OPS.endAnnotation]);
  1734. expect(operatorList.argsArray[1]).toEqual(new Uint8ClampedArray([26, 51, 76]));
  1735. annotationStorage.set(annotation.data.id, {
  1736. value: false
  1737. });
  1738. operatorList = await annotation.getOperatorList(partialEvaluator, task, false, annotationStorage);
  1739. expect(operatorList.argsArray.length).toEqual(3);
  1740. expect(operatorList.fnArray).toEqual([_util.OPS.beginAnnotation, _util.OPS.setFillRGBColor, _util.OPS.endAnnotation]);
  1741. expect(operatorList.argsArray[1]).toEqual(new Uint8ClampedArray([76, 51, 26]));
  1742. });
  1743. it("should render checkboxes for printing twice", async function () {
  1744. const appearanceStatesDict = new _primitives.Dict();
  1745. const normalAppearanceDict = new _primitives.Dict();
  1746. const checkedAppearanceDict = new _primitives.Dict();
  1747. const uncheckedAppearanceDict = new _primitives.Dict();
  1748. const checkedStream = new _stream.StringStream("0.1 0.2 0.3 rg");
  1749. checkedStream.dict = checkedAppearanceDict;
  1750. const uncheckedStream = new _stream.StringStream("0.3 0.2 0.1 rg");
  1751. uncheckedStream.dict = uncheckedAppearanceDict;
  1752. checkedAppearanceDict.set("BBox", [0, 0, 8, 8]);
  1753. checkedAppearanceDict.set("FormType", 1);
  1754. checkedAppearanceDict.set("Matrix", [1, 0, 0, 1, 0, 0]);
  1755. normalAppearanceDict.set("Checked", checkedStream);
  1756. normalAppearanceDict.set("Off", uncheckedStream);
  1757. appearanceStatesDict.set("N", normalAppearanceDict);
  1758. buttonWidgetDict.set("AP", appearanceStatesDict);
  1759. buttonWidgetDict.set("AS", _primitives.Name.get("Off"));
  1760. const buttonWidgetRef = _primitives.Ref.get(1249, 0);
  1761. const xref = new _test_utils.XRefMock([{
  1762. ref: buttonWidgetRef,
  1763. data: buttonWidgetDict
  1764. }]);
  1765. const task = new _worker.WorkerTask("test print");
  1766. const annotation = await _annotation.AnnotationFactory.create(xref, buttonWidgetRef, pdfManagerMock, idFactoryMock);
  1767. const annotationStorage = new Map();
  1768. for (let i = 0; i < 2; i++) {
  1769. annotationStorage.set(annotation.data.id, {
  1770. value: true
  1771. });
  1772. const operatorList = await annotation.getOperatorList(partialEvaluator, task, false, annotationStorage);
  1773. expect(operatorList.argsArray.length).toEqual(3);
  1774. expect(operatorList.fnArray).toEqual([_util.OPS.beginAnnotation, _util.OPS.setFillRGBColor, _util.OPS.endAnnotation]);
  1775. expect(operatorList.argsArray[1]).toEqual(new Uint8ClampedArray([26, 51, 76]));
  1776. }
  1777. });
  1778. it("should render checkboxes for printing using normal appearance", async function () {
  1779. const appearanceStatesDict = new _primitives.Dict();
  1780. const normalAppearanceDict = new _primitives.Dict();
  1781. const checkedAppearanceDict = new _primitives.Dict();
  1782. const uncheckedAppearanceDict = new _primitives.Dict();
  1783. const checkedStream = new _stream.StringStream("0.1 0.2 0.3 rg");
  1784. checkedStream.dict = checkedAppearanceDict;
  1785. const uncheckedStream = new _stream.StringStream("0.3 0.2 0.1 rg");
  1786. uncheckedStream.dict = uncheckedAppearanceDict;
  1787. checkedAppearanceDict.set("BBox", [0, 0, 8, 8]);
  1788. checkedAppearanceDict.set("FormType", 1);
  1789. checkedAppearanceDict.set("Matrix", [1, 0, 0, 1, 0, 0]);
  1790. normalAppearanceDict.set("Checked", checkedStream);
  1791. normalAppearanceDict.set("Off", uncheckedStream);
  1792. appearanceStatesDict.set("N", normalAppearanceDict);
  1793. buttonWidgetDict.set("AP", appearanceStatesDict);
  1794. buttonWidgetDict.set("AS", _primitives.Name.get("Checked"));
  1795. const buttonWidgetRef = _primitives.Ref.get(124, 0);
  1796. const xref = new _test_utils.XRefMock([{
  1797. ref: buttonWidgetRef,
  1798. data: buttonWidgetDict
  1799. }]);
  1800. const task = new _worker.WorkerTask("test print");
  1801. const annotation = await _annotation.AnnotationFactory.create(xref, buttonWidgetRef, pdfManagerMock, idFactoryMock);
  1802. const annotationStorage = new Map();
  1803. const operatorList = await annotation.getOperatorList(partialEvaluator, task, false, annotationStorage);
  1804. expect(operatorList.argsArray.length).toEqual(3);
  1805. expect(operatorList.fnArray).toEqual([_util.OPS.beginAnnotation, _util.OPS.setFillRGBColor, _util.OPS.endAnnotation]);
  1806. expect(operatorList.argsArray[1]).toEqual(new Uint8ClampedArray([26, 51, 76]));
  1807. });
  1808. it("should save checkboxes", async function () {
  1809. const appearanceStatesDict = new _primitives.Dict();
  1810. const normalAppearanceDict = new _primitives.Dict();
  1811. normalAppearanceDict.set("Checked", _primitives.Ref.get(314, 0));
  1812. normalAppearanceDict.set("Off", _primitives.Ref.get(271, 0));
  1813. appearanceStatesDict.set("N", normalAppearanceDict);
  1814. buttonWidgetDict.set("AP", appearanceStatesDict);
  1815. buttonWidgetDict.set("V", _primitives.Name.get("Off"));
  1816. const buttonWidgetRef = _primitives.Ref.get(123, 0);
  1817. const xref = new _test_utils.XRefMock([{
  1818. ref: buttonWidgetRef,
  1819. data: buttonWidgetDict
  1820. }]);
  1821. partialEvaluator.xref = xref;
  1822. const task = new _worker.WorkerTask("test save");
  1823. const annotation = await _annotation.AnnotationFactory.create(xref, buttonWidgetRef, pdfManagerMock, idFactoryMock);
  1824. const annotationStorage = new Map();
  1825. annotationStorage.set(annotation.data.id, {
  1826. value: true
  1827. });
  1828. const [oldData] = await annotation.save(partialEvaluator, task, annotationStorage);
  1829. oldData.data = oldData.data.replace(/\(D:[0-9]+\)/, "(date)");
  1830. expect(oldData.ref).toEqual(_primitives.Ref.get(123, 0));
  1831. expect(oldData.data).toEqual("123 0 obj\n" + "<< /Type /Annot /Subtype /Widget /FT /Btn " + "/AP << /N << /Checked 314 0 R /Off 271 0 R>>>> " + "/V /Checked /AS /Checked /M (date)>>\nendobj\n");
  1832. annotationStorage.set(annotation.data.id, {
  1833. value: false
  1834. });
  1835. const data = await annotation.save(partialEvaluator, task, annotationStorage);
  1836. expect(data).toEqual(null);
  1837. });
  1838. it("should handle radio buttons with a field value", async function () {
  1839. const parentDict = new _primitives.Dict();
  1840. parentDict.set("V", _primitives.Name.get("1"));
  1841. const normalAppearanceStateDict = new _primitives.Dict();
  1842. normalAppearanceStateDict.set("2", null);
  1843. const appearanceStatesDict = new _primitives.Dict();
  1844. appearanceStatesDict.set("N", normalAppearanceStateDict);
  1845. buttonWidgetDict.set("Ff", _util.AnnotationFieldFlag.RADIO);
  1846. buttonWidgetDict.set("Parent", parentDict);
  1847. buttonWidgetDict.set("AP", appearanceStatesDict);
  1848. const buttonWidgetRef = _primitives.Ref.get(124, 0);
  1849. const xref = new _test_utils.XRefMock([{
  1850. ref: buttonWidgetRef,
  1851. data: buttonWidgetDict
  1852. }]);
  1853. const {
  1854. data
  1855. } = await _annotation.AnnotationFactory.create(xref, buttonWidgetRef, pdfManagerMock, idFactoryMock);
  1856. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  1857. expect(data.checkBox).toEqual(false);
  1858. expect(data.radioButton).toEqual(true);
  1859. expect(data.fieldValue).toEqual("1");
  1860. expect(data.buttonValue).toEqual("2");
  1861. });
  1862. it("should handle radio buttons with a field value that's not an ASCII string", async function () {
  1863. const parentDict = new _primitives.Dict();
  1864. parentDict.set("V", _primitives.Name.get("\x91I=\x91\xf0\x93\xe0\x97e3"));
  1865. const normalAppearanceStateDict = new _primitives.Dict();
  1866. normalAppearanceStateDict.set("\x91I=\x91\xf0\x93\xe0\x97e3", null);
  1867. const appearanceStatesDict = new _primitives.Dict();
  1868. appearanceStatesDict.set("N", normalAppearanceStateDict);
  1869. buttonWidgetDict.set("Ff", _util.AnnotationFieldFlag.RADIO);
  1870. buttonWidgetDict.set("Parent", parentDict);
  1871. buttonWidgetDict.set("AP", appearanceStatesDict);
  1872. const buttonWidgetRef = _primitives.Ref.get(124, 0);
  1873. const xref = new _test_utils.XRefMock([{
  1874. ref: buttonWidgetRef,
  1875. data: buttonWidgetDict
  1876. }]);
  1877. const {
  1878. data
  1879. } = await _annotation.AnnotationFactory.create(xref, buttonWidgetRef, pdfManagerMock, idFactoryMock);
  1880. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  1881. expect(data.checkBox).toEqual(false);
  1882. expect(data.radioButton).toEqual(true);
  1883. expect(data.fieldValue).toEqual("‚I=‚ðfiàŠe3");
  1884. expect(data.buttonValue).toEqual("‚I=‚ðfiàŠe3");
  1885. });
  1886. it("should handle radio buttons without a field value", async function () {
  1887. const normalAppearanceStateDict = new _primitives.Dict();
  1888. normalAppearanceStateDict.set("2", null);
  1889. const appearanceStatesDict = new _primitives.Dict();
  1890. appearanceStatesDict.set("N", normalAppearanceStateDict);
  1891. buttonWidgetDict.set("Ff", _util.AnnotationFieldFlag.RADIO);
  1892. buttonWidgetDict.set("AP", appearanceStatesDict);
  1893. const buttonWidgetRef = _primitives.Ref.get(124, 0);
  1894. const xref = new _test_utils.XRefMock([{
  1895. ref: buttonWidgetRef,
  1896. data: buttonWidgetDict
  1897. }]);
  1898. const {
  1899. data
  1900. } = await _annotation.AnnotationFactory.create(xref, buttonWidgetRef, pdfManagerMock, idFactoryMock);
  1901. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  1902. expect(data.checkBox).toEqual(false);
  1903. expect(data.radioButton).toEqual(true);
  1904. expect(data.fieldValue).toEqual(null);
  1905. expect(data.buttonValue).toEqual("2");
  1906. });
  1907. it("should render radio buttons for printing", async function () {
  1908. const appearanceStatesDict = new _primitives.Dict();
  1909. const normalAppearanceDict = new _primitives.Dict();
  1910. const checkedAppearanceDict = new _primitives.Dict();
  1911. const uncheckedAppearanceDict = new _primitives.Dict();
  1912. const checkedStream = new _stream.StringStream("0.1 0.2 0.3 rg");
  1913. checkedStream.dict = checkedAppearanceDict;
  1914. const uncheckedStream = new _stream.StringStream("0.3 0.2 0.1 rg");
  1915. uncheckedStream.dict = uncheckedAppearanceDict;
  1916. checkedAppearanceDict.set("BBox", [0, 0, 8, 8]);
  1917. checkedAppearanceDict.set("FormType", 1);
  1918. checkedAppearanceDict.set("Matrix", [1, 0, 0, 1, 0, 0]);
  1919. normalAppearanceDict.set("Checked", checkedStream);
  1920. normalAppearanceDict.set("Off", uncheckedStream);
  1921. appearanceStatesDict.set("N", normalAppearanceDict);
  1922. buttonWidgetDict.set("Ff", _util.AnnotationFieldFlag.RADIO);
  1923. buttonWidgetDict.set("AP", appearanceStatesDict);
  1924. const buttonWidgetRef = _primitives.Ref.get(124, 0);
  1925. const xref = new _test_utils.XRefMock([{
  1926. ref: buttonWidgetRef,
  1927. data: buttonWidgetDict
  1928. }]);
  1929. const task = new _worker.WorkerTask("test print");
  1930. const annotation = await _annotation.AnnotationFactory.create(xref, buttonWidgetRef, pdfManagerMock, idFactoryMock);
  1931. const annotationStorage = new Map();
  1932. annotationStorage.set(annotation.data.id, {
  1933. value: true
  1934. });
  1935. let operatorList = await annotation.getOperatorList(partialEvaluator, task, false, annotationStorage);
  1936. expect(operatorList.argsArray.length).toEqual(3);
  1937. expect(operatorList.fnArray).toEqual([_util.OPS.beginAnnotation, _util.OPS.setFillRGBColor, _util.OPS.endAnnotation]);
  1938. expect(operatorList.argsArray[1]).toEqual(new Uint8ClampedArray([26, 51, 76]));
  1939. annotationStorage.set(annotation.data.id, {
  1940. value: false
  1941. });
  1942. operatorList = await annotation.getOperatorList(partialEvaluator, task, false, annotationStorage);
  1943. expect(operatorList.argsArray.length).toEqual(3);
  1944. expect(operatorList.fnArray).toEqual([_util.OPS.beginAnnotation, _util.OPS.setFillRGBColor, _util.OPS.endAnnotation]);
  1945. expect(operatorList.argsArray[1]).toEqual(new Uint8ClampedArray([76, 51, 26]));
  1946. });
  1947. it("should render radio buttons for printing using normal appearance", async function () {
  1948. const appearanceStatesDict = new _primitives.Dict();
  1949. const normalAppearanceDict = new _primitives.Dict();
  1950. const checkedAppearanceDict = new _primitives.Dict();
  1951. const uncheckedAppearanceDict = new _primitives.Dict();
  1952. const checkedStream = new _stream.StringStream("0.1 0.2 0.3 rg");
  1953. checkedStream.dict = checkedAppearanceDict;
  1954. const uncheckedStream = new _stream.StringStream("0.3 0.2 0.1 rg");
  1955. uncheckedStream.dict = uncheckedAppearanceDict;
  1956. checkedAppearanceDict.set("BBox", [0, 0, 8, 8]);
  1957. checkedAppearanceDict.set("FormType", 1);
  1958. checkedAppearanceDict.set("Matrix", [1, 0, 0, 1, 0, 0]);
  1959. normalAppearanceDict.set("Checked", checkedStream);
  1960. normalAppearanceDict.set("Off", uncheckedStream);
  1961. appearanceStatesDict.set("N", normalAppearanceDict);
  1962. buttonWidgetDict.set("Ff", _util.AnnotationFieldFlag.RADIO);
  1963. buttonWidgetDict.set("AP", appearanceStatesDict);
  1964. buttonWidgetDict.set("AS", _primitives.Name.get("Off"));
  1965. const buttonWidgetRef = _primitives.Ref.get(124, 0);
  1966. const xref = new _test_utils.XRefMock([{
  1967. ref: buttonWidgetRef,
  1968. data: buttonWidgetDict
  1969. }]);
  1970. const task = new _worker.WorkerTask("test print");
  1971. const annotation = await _annotation.AnnotationFactory.create(xref, buttonWidgetRef, pdfManagerMock, idFactoryMock);
  1972. const annotationStorage = new Map();
  1973. const operatorList = await annotation.getOperatorList(partialEvaluator, task, false, annotationStorage);
  1974. expect(operatorList.argsArray.length).toEqual(3);
  1975. expect(operatorList.fnArray).toEqual([_util.OPS.beginAnnotation, _util.OPS.setFillRGBColor, _util.OPS.endAnnotation]);
  1976. expect(operatorList.argsArray[1]).toEqual(new Uint8ClampedArray([76, 51, 26]));
  1977. });
  1978. it("should save radio buttons", async function () {
  1979. const appearanceStatesDict = new _primitives.Dict();
  1980. const normalAppearanceDict = new _primitives.Dict();
  1981. normalAppearanceDict.set("Checked", _primitives.Ref.get(314, 0));
  1982. normalAppearanceDict.set("Off", _primitives.Ref.get(271, 0));
  1983. appearanceStatesDict.set("N", normalAppearanceDict);
  1984. buttonWidgetDict.set("Ff", _util.AnnotationFieldFlag.RADIO);
  1985. buttonWidgetDict.set("AP", appearanceStatesDict);
  1986. const buttonWidgetRef = _primitives.Ref.get(123, 0);
  1987. const parentRef = _primitives.Ref.get(456, 0);
  1988. const parentDict = new _primitives.Dict();
  1989. parentDict.set("V", _primitives.Name.get("Off"));
  1990. parentDict.set("Kids", [buttonWidgetRef]);
  1991. buttonWidgetDict.set("Parent", parentRef);
  1992. const xref = new _test_utils.XRefMock([{
  1993. ref: buttonWidgetRef,
  1994. data: buttonWidgetDict
  1995. }, {
  1996. ref: parentRef,
  1997. data: parentDict
  1998. }]);
  1999. parentDict.xref = xref;
  2000. buttonWidgetDict.xref = xref;
  2001. partialEvaluator.xref = xref;
  2002. const task = new _worker.WorkerTask("test save");
  2003. const annotation = await _annotation.AnnotationFactory.create(xref, buttonWidgetRef, pdfManagerMock, idFactoryMock);
  2004. const annotationStorage = new Map();
  2005. annotationStorage.set(annotation.data.id, {
  2006. value: true
  2007. });
  2008. let data = await annotation.save(partialEvaluator, task, annotationStorage);
  2009. expect(data.length).toEqual(2);
  2010. const [radioData, parentData] = data;
  2011. radioData.data = radioData.data.replace(/\(D:[0-9]+\)/, "(date)");
  2012. expect(radioData.ref).toEqual(_primitives.Ref.get(123, 0));
  2013. expect(radioData.data).toEqual("123 0 obj\n" + "<< /Type /Annot /Subtype /Widget /FT /Btn /Ff 32768 " + "/AP << /N << /Checked 314 0 R /Off 271 0 R>>>> " + "/Parent 456 0 R /AS /Checked /M (date)>>\nendobj\n");
  2014. expect(parentData.ref).toEqual(_primitives.Ref.get(456, 0));
  2015. expect(parentData.data).toEqual("456 0 obj\n<< /V /Checked /Kids [123 0 R]>>\nendobj\n");
  2016. annotationStorage.set(annotation.data.id, {
  2017. value: false
  2018. });
  2019. data = await annotation.save(partialEvaluator, task, annotationStorage);
  2020. expect(data).toEqual(null);
  2021. });
  2022. it("should save radio buttons without a field value", async function () {
  2023. const appearanceStatesDict = new _primitives.Dict();
  2024. const normalAppearanceDict = new _primitives.Dict();
  2025. normalAppearanceDict.set("Checked", _primitives.Ref.get(314, 0));
  2026. normalAppearanceDict.set("Off", _primitives.Ref.get(271, 0));
  2027. appearanceStatesDict.set("N", normalAppearanceDict);
  2028. buttonWidgetDict.set("Ff", _util.AnnotationFieldFlag.RADIO);
  2029. buttonWidgetDict.set("AP", appearanceStatesDict);
  2030. const buttonWidgetRef = _primitives.Ref.get(123, 0);
  2031. const parentRef = _primitives.Ref.get(456, 0);
  2032. const parentDict = new _primitives.Dict();
  2033. parentDict.set("Kids", [buttonWidgetRef]);
  2034. buttonWidgetDict.set("Parent", parentRef);
  2035. const xref = new _test_utils.XRefMock([{
  2036. ref: buttonWidgetRef,
  2037. data: buttonWidgetDict
  2038. }, {
  2039. ref: parentRef,
  2040. data: parentDict
  2041. }]);
  2042. parentDict.xref = xref;
  2043. buttonWidgetDict.xref = xref;
  2044. partialEvaluator.xref = xref;
  2045. const task = new _worker.WorkerTask("test save");
  2046. const annotation = await _annotation.AnnotationFactory.create(xref, buttonWidgetRef, pdfManagerMock, idFactoryMock);
  2047. const annotationStorage = new Map();
  2048. annotationStorage.set(annotation.data.id, {
  2049. value: true
  2050. });
  2051. const data = await annotation.save(partialEvaluator, task, annotationStorage);
  2052. expect(data.length).toEqual(2);
  2053. const [radioData, parentData] = data;
  2054. radioData.data = radioData.data.replace(/\(D:[0-9]+\)/, "(date)");
  2055. expect(radioData.ref).toEqual(_primitives.Ref.get(123, 0));
  2056. expect(radioData.data).toEqual("123 0 obj\n" + "<< /Type /Annot /Subtype /Widget /FT /Btn /Ff 32768 " + "/AP << /N << /Checked 314 0 R /Off 271 0 R>>>> " + "/Parent 456 0 R /AS /Checked /M (date)>>\nendobj\n");
  2057. expect(parentData.ref).toEqual(_primitives.Ref.get(456, 0));
  2058. expect(parentData.data).toEqual("456 0 obj\n<< /Kids [123 0 R] /V /Checked>>\nendobj\n");
  2059. });
  2060. it("should save nothing", async function () {
  2061. const buttonWidgetRef = _primitives.Ref.get(124, 0);
  2062. const xref = new _test_utils.XRefMock([{
  2063. ref: buttonWidgetRef,
  2064. data: buttonWidgetDict
  2065. }]);
  2066. const task = new _worker.WorkerTask("test save");
  2067. const annotation = await _annotation.AnnotationFactory.create(xref, buttonWidgetRef, pdfManagerMock, idFactoryMock);
  2068. const annotationStorage = new Map();
  2069. const data = await annotation.save(partialEvaluator, task, annotationStorage);
  2070. expect(data).toEqual(null);
  2071. });
  2072. it("should handle push buttons", async function () {
  2073. const buttonWidgetRef = _primitives.Ref.get(124, 0);
  2074. buttonWidgetDict.set("Ff", _util.AnnotationFieldFlag.PUSHBUTTON);
  2075. const actionDict = new _primitives.Dict();
  2076. actionDict.set("S", _primitives.Name.get("JavaScript"));
  2077. actionDict.set("JS", "do_something();");
  2078. buttonWidgetDict.set("A", actionDict);
  2079. const xref = new _test_utils.XRefMock([{
  2080. ref: buttonWidgetRef,
  2081. data: buttonWidgetDict
  2082. }]);
  2083. const {
  2084. data
  2085. } = await _annotation.AnnotationFactory.create(xref, buttonWidgetRef, pdfManagerMock, idFactoryMock);
  2086. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  2087. expect(data.pushButton).toEqual(true);
  2088. expect(data.actions.Action).toEqual(["do_something();"]);
  2089. });
  2090. it("should handle push buttons that act as a tooltip only", async function () {
  2091. const buttonWidgetRef = _primitives.Ref.get(124, 0);
  2092. buttonWidgetDict.set("Ff", _util.AnnotationFieldFlag.PUSHBUTTON);
  2093. buttonWidgetDict.set("TU", "An alternative text");
  2094. const xref = new _test_utils.XRefMock([{
  2095. ref: buttonWidgetRef,
  2096. data: buttonWidgetDict
  2097. }]);
  2098. const {
  2099. data
  2100. } = await _annotation.AnnotationFactory.create(xref, buttonWidgetRef, pdfManagerMock, idFactoryMock);
  2101. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  2102. expect(data.pushButton).toEqual(true);
  2103. expect(data.alternativeText).toEqual("An alternative text");
  2104. });
  2105. it("should handle URL in A dict in push buttons", async function () {
  2106. const buttonWidgetRef = _primitives.Ref.get(124, 0);
  2107. buttonWidgetDict.set("Ff", _util.AnnotationFieldFlag.PUSHBUTTON);
  2108. const actionDict = new _primitives.Dict();
  2109. actionDict.set("S", _primitives.Name.get("JavaScript"));
  2110. actionDict.set("JS", "app.launchURL('https://developer.mozilla.org/en-US/', true)");
  2111. buttonWidgetDict.set("A", actionDict);
  2112. const xref = new _test_utils.XRefMock([{
  2113. ref: buttonWidgetRef,
  2114. data: buttonWidgetDict
  2115. }]);
  2116. const {
  2117. data
  2118. } = await _annotation.AnnotationFactory.create(xref, buttonWidgetRef, pdfManagerMock, idFactoryMock);
  2119. expect(data.url).toEqual("https://developer.mozilla.org/en-US/");
  2120. });
  2121. it("should handle URL in AA dict in push buttons", async function () {
  2122. const buttonWidgetRef = _primitives.Ref.get(124, 0);
  2123. buttonWidgetDict.set("Ff", _util.AnnotationFieldFlag.PUSHBUTTON);
  2124. const dDict = new _primitives.Dict();
  2125. dDict.set("S", _primitives.Name.get("JavaScript"));
  2126. dDict.set("JS", "app.launchURL('https://developer.mozilla.org/en-US/', true)");
  2127. const actionDict = new _primitives.Dict();
  2128. actionDict.set("D", dDict);
  2129. buttonWidgetDict.set("AA", actionDict);
  2130. const xref = new _test_utils.XRefMock([{
  2131. ref: buttonWidgetRef,
  2132. data: buttonWidgetDict
  2133. }]);
  2134. const {
  2135. data
  2136. } = await _annotation.AnnotationFactory.create(xref, buttonWidgetRef, pdfManagerMock, idFactoryMock);
  2137. expect(data.url).toEqual("https://developer.mozilla.org/en-US/");
  2138. });
  2139. });
  2140. describe("ChoiceWidgetAnnotation", function () {
  2141. let choiceWidgetDict, fontRefObj;
  2142. beforeEach(function () {
  2143. choiceWidgetDict = new _primitives.Dict();
  2144. choiceWidgetDict.set("Type", _primitives.Name.get("Annot"));
  2145. choiceWidgetDict.set("Subtype", _primitives.Name.get("Widget"));
  2146. choiceWidgetDict.set("FT", _primitives.Name.get("Ch"));
  2147. const helvDict = new _primitives.Dict();
  2148. helvDict.set("BaseFont", _primitives.Name.get("Helvetica"));
  2149. helvDict.set("Type", _primitives.Name.get("Font"));
  2150. helvDict.set("Subtype", _primitives.Name.get("Type1"));
  2151. const fontRef = _primitives.Ref.get(314, 0);
  2152. fontRefObj = {
  2153. ref: fontRef,
  2154. data: helvDict
  2155. };
  2156. const resourceDict = new _primitives.Dict();
  2157. const fontDict = new _primitives.Dict();
  2158. fontDict.set("Helv", fontRef);
  2159. resourceDict.set("Font", fontDict);
  2160. choiceWidgetDict.set("DA", "/Helv 5 Tf");
  2161. choiceWidgetDict.set("DR", resourceDict);
  2162. choiceWidgetDict.set("Rect", [0, 0, 32, 10]);
  2163. });
  2164. afterEach(function () {
  2165. choiceWidgetDict = fontRefObj = null;
  2166. });
  2167. it("should handle missing option arrays", async function () {
  2168. const choiceWidgetRef = _primitives.Ref.get(122, 0);
  2169. const xref = new _test_utils.XRefMock([{
  2170. ref: choiceWidgetRef,
  2171. data: choiceWidgetDict
  2172. }]);
  2173. const {
  2174. data
  2175. } = await _annotation.AnnotationFactory.create(xref, choiceWidgetRef, pdfManagerMock, idFactoryMock);
  2176. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  2177. expect(data.options).toEqual([]);
  2178. });
  2179. it("should handle option arrays with array elements", async function () {
  2180. const optionBarRef = _primitives.Ref.get(20, 0);
  2181. const optionBarStr = "Bar";
  2182. const optionOneRef = _primitives.Ref.get(10, 0);
  2183. const optionOneArr = ["bar_export", optionBarRef];
  2184. const options = [["foo_export", "Foo"], optionOneRef];
  2185. const expected = [{
  2186. exportValue: "foo_export",
  2187. displayValue: "Foo"
  2188. }, {
  2189. exportValue: "bar_export",
  2190. displayValue: "Bar"
  2191. }];
  2192. choiceWidgetDict.set("Opt", options);
  2193. const choiceWidgetRef = _primitives.Ref.get(123, 0);
  2194. const xref = new _test_utils.XRefMock([{
  2195. ref: choiceWidgetRef,
  2196. data: choiceWidgetDict
  2197. }, {
  2198. ref: optionBarRef,
  2199. data: optionBarStr
  2200. }, {
  2201. ref: optionOneRef,
  2202. data: optionOneArr
  2203. }]);
  2204. const {
  2205. data
  2206. } = await _annotation.AnnotationFactory.create(xref, choiceWidgetRef, pdfManagerMock, idFactoryMock);
  2207. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  2208. expect(data.options).toEqual(expected);
  2209. });
  2210. it("should handle option arrays with string elements", async function () {
  2211. const optionBarRef = _primitives.Ref.get(10, 0);
  2212. const optionBarStr = "Bar";
  2213. const options = ["Foo", optionBarRef];
  2214. const expected = [{
  2215. exportValue: "Foo",
  2216. displayValue: "Foo"
  2217. }, {
  2218. exportValue: "Bar",
  2219. displayValue: "Bar"
  2220. }];
  2221. choiceWidgetDict.set("Opt", options);
  2222. const choiceWidgetRef = _primitives.Ref.get(981, 0);
  2223. const xref = new _test_utils.XRefMock([{
  2224. ref: choiceWidgetRef,
  2225. data: choiceWidgetDict
  2226. }, {
  2227. ref: optionBarRef,
  2228. data: optionBarStr
  2229. }]);
  2230. const {
  2231. data
  2232. } = await _annotation.AnnotationFactory.create(xref, choiceWidgetRef, pdfManagerMock, idFactoryMock);
  2233. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  2234. expect(data.options).toEqual(expected);
  2235. });
  2236. it("should handle inherited option arrays (issue 8094)", async function () {
  2237. const options = [["Value1", "Description1"], ["Value2", "Description2"]];
  2238. const expected = [{
  2239. exportValue: "Value1",
  2240. displayValue: "Description1"
  2241. }, {
  2242. exportValue: "Value2",
  2243. displayValue: "Description2"
  2244. }];
  2245. const parentDict = new _primitives.Dict();
  2246. parentDict.set("Opt", options);
  2247. choiceWidgetDict.set("Parent", parentDict);
  2248. const choiceWidgetRef = _primitives.Ref.get(123, 0);
  2249. const xref = new _test_utils.XRefMock([{
  2250. ref: choiceWidgetRef,
  2251. data: choiceWidgetDict
  2252. }]);
  2253. const {
  2254. data
  2255. } = await _annotation.AnnotationFactory.create(xref, choiceWidgetRef, pdfManagerMock, idFactoryMock);
  2256. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  2257. expect(data.options).toEqual(expected);
  2258. });
  2259. it("should decode form values", async function () {
  2260. const encodedString = "\xFE\xFF\x00F\x00o\x00o";
  2261. const decodedString = "Foo";
  2262. choiceWidgetDict.set("Opt", [encodedString]);
  2263. choiceWidgetDict.set("V", encodedString);
  2264. choiceWidgetDict.set("DV", _primitives.Name.get("foo"));
  2265. const choiceWidgetRef = _primitives.Ref.get(984, 0);
  2266. const xref = new _test_utils.XRefMock([{
  2267. ref: choiceWidgetRef,
  2268. data: choiceWidgetDict
  2269. }]);
  2270. const {
  2271. data
  2272. } = await _annotation.AnnotationFactory.create(xref, choiceWidgetRef, pdfManagerMock, idFactoryMock);
  2273. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  2274. expect(data.fieldValue).toEqual([decodedString]);
  2275. expect(data.defaultFieldValue).toEqual("foo");
  2276. expect(data.options).toEqual([{
  2277. exportValue: decodedString,
  2278. displayValue: decodedString
  2279. }]);
  2280. });
  2281. it("should convert the field value to an array", async function () {
  2282. const inputs = [null, "Foo", ["Foo", "Bar"]];
  2283. const outputs = [[], ["Foo"], ["Foo", "Bar"]];
  2284. let promise = Promise.resolve();
  2285. for (let i = 0, ii = inputs.length; i < ii; i++) {
  2286. promise = promise.then(() => {
  2287. choiceWidgetDict.set("V", inputs[i]);
  2288. const choiceWidgetRef = _primitives.Ref.get(968, 0);
  2289. const xref = new _test_utils.XRefMock([{
  2290. ref: choiceWidgetRef,
  2291. data: choiceWidgetDict
  2292. }]);
  2293. return _annotation.AnnotationFactory.create(xref, choiceWidgetRef, pdfManagerMock, idFactoryMock).then(({
  2294. data
  2295. }) => {
  2296. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  2297. expect(data.fieldValue).toEqual(outputs[i]);
  2298. });
  2299. });
  2300. }
  2301. await promise;
  2302. });
  2303. it("should handle unknown flags", async function () {
  2304. const choiceWidgetRef = _primitives.Ref.get(166, 0);
  2305. const xref = new _test_utils.XRefMock([{
  2306. ref: choiceWidgetRef,
  2307. data: choiceWidgetDict
  2308. }]);
  2309. const {
  2310. data
  2311. } = await _annotation.AnnotationFactory.create(xref, choiceWidgetRef, pdfManagerMock, idFactoryMock);
  2312. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  2313. expect(data.readOnly).toEqual(false);
  2314. expect(data.hidden).toEqual(false);
  2315. expect(data.combo).toEqual(false);
  2316. expect(data.multiSelect).toEqual(false);
  2317. });
  2318. it("should not set invalid flags", async function () {
  2319. choiceWidgetDict.set("Ff", "readonly");
  2320. const choiceWidgetRef = _primitives.Ref.get(165, 0);
  2321. const xref = new _test_utils.XRefMock([{
  2322. ref: choiceWidgetRef,
  2323. data: choiceWidgetDict
  2324. }]);
  2325. const {
  2326. data
  2327. } = await _annotation.AnnotationFactory.create(xref, choiceWidgetRef, pdfManagerMock, idFactoryMock);
  2328. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  2329. expect(data.readOnly).toEqual(false);
  2330. expect(data.hidden).toEqual(false);
  2331. expect(data.combo).toEqual(false);
  2332. expect(data.multiSelect).toEqual(false);
  2333. });
  2334. it("should set valid flags", async function () {
  2335. choiceWidgetDict.set("Ff", _util.AnnotationFieldFlag.READONLY + _util.AnnotationFieldFlag.COMBO + _util.AnnotationFieldFlag.MULTISELECT);
  2336. const choiceWidgetRef = _primitives.Ref.get(512, 0);
  2337. const xref = new _test_utils.XRefMock([{
  2338. ref: choiceWidgetRef,
  2339. data: choiceWidgetDict
  2340. }]);
  2341. const {
  2342. data
  2343. } = await _annotation.AnnotationFactory.create(xref, choiceWidgetRef, pdfManagerMock, idFactoryMock);
  2344. expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
  2345. expect(data.readOnly).toEqual(true);
  2346. expect(data.hidden).toEqual(false);
  2347. expect(data.combo).toEqual(true);
  2348. expect(data.multiSelect).toEqual(true);
  2349. });
  2350. it("should render choice for printing", async function () {
  2351. const choiceWidgetRef = _primitives.Ref.get(271, 0);
  2352. const xref = new _test_utils.XRefMock([{
  2353. ref: choiceWidgetRef,
  2354. data: choiceWidgetDict
  2355. }, fontRefObj]);
  2356. const task = new _worker.WorkerTask("test print");
  2357. partialEvaluator.xref = xref;
  2358. const annotation = await _annotation.AnnotationFactory.create(xref, choiceWidgetRef, pdfManagerMock, idFactoryMock);
  2359. const annotationStorage = new Map();
  2360. annotationStorage.set(annotation.data.id, {
  2361. value: "a value"
  2362. });
  2363. const appearance = await annotation._getAppearance(partialEvaluator, task, annotationStorage);
  2364. expect(appearance).toEqual("/Tx BMC q BT /Helv 5 Tf 1 0 0 1 0 0 Tm" + " 2.00 2.00 Td (a value) Tj ET Q EMC");
  2365. });
  2366. it("should save choice", async function () {
  2367. choiceWidgetDict.set("Opt", ["A", "B", "C"]);
  2368. choiceWidgetDict.set("V", "A");
  2369. const choiceWidgetRef = _primitives.Ref.get(123, 0);
  2370. const xref = new _test_utils.XRefMock([{
  2371. ref: choiceWidgetRef,
  2372. data: choiceWidgetDict
  2373. }]);
  2374. partialEvaluator.xref = xref;
  2375. const task = new _worker.WorkerTask("test save");
  2376. const annotation = await _annotation.AnnotationFactory.create(xref, choiceWidgetRef, pdfManagerMock, idFactoryMock);
  2377. const annotationStorage = new Map();
  2378. annotationStorage.set(annotation.data.id, {
  2379. value: "C"
  2380. });
  2381. const data = await annotation.save(partialEvaluator, task, annotationStorage);
  2382. expect(data.length).toEqual(2);
  2383. const [oldData, newData] = data;
  2384. expect(oldData.ref).toEqual(_primitives.Ref.get(123, 0));
  2385. expect(newData.ref).toEqual(_primitives.Ref.get(1, 0));
  2386. oldData.data = oldData.data.replace(/\(D:[0-9]+\)/, "(date)");
  2387. expect(oldData.data).toEqual("123 0 obj\n" + "<< /Type /Annot /Subtype /Widget /FT /Ch /DA (/Helv 5 Tf) /DR " + "<< /Font << /Helv 314 0 R>>>> " + "/Rect [0 0 32 10] /Opt [(A) (B) (C)] /V (C) " + "/AP << /N 1 0 R>> /M (date)>>\nendobj\n");
  2388. expect(newData.data).toEqual("1 0 obj\n" + "<< /Length 67 /Subtype /Form /Resources << /Font << /Helv 314 0 R>>>> " + "/BBox [0 0 32 10]>> stream\n" + "/Tx BMC q BT /Helv 5 Tf 1 0 0 1 0 0 Tm 2.00 2.00 Td (C) Tj ET Q EMC\n" + "endstream\nendobj\n");
  2389. });
  2390. });
  2391. describe("LineAnnotation", function () {
  2392. it("should set the line coordinates", async function () {
  2393. const lineDict = new _primitives.Dict();
  2394. lineDict.set("Type", _primitives.Name.get("Annot"));
  2395. lineDict.set("Subtype", _primitives.Name.get("Line"));
  2396. lineDict.set("L", [1, 2, 3, 4]);
  2397. const lineRef = _primitives.Ref.get(122, 0);
  2398. const xref = new _test_utils.XRefMock([{
  2399. ref: lineRef,
  2400. data: lineDict
  2401. }]);
  2402. const {
  2403. data
  2404. } = await _annotation.AnnotationFactory.create(xref, lineRef, pdfManagerMock, idFactoryMock);
  2405. expect(data.annotationType).toEqual(_util.AnnotationType.LINE);
  2406. expect(data.lineCoordinates).toEqual([1, 2, 3, 4]);
  2407. });
  2408. });
  2409. describe("FileAttachmentAnnotation", function () {
  2410. it("should correctly parse a file attachment", async function () {
  2411. const fileStream = new _stream.StringStream("<<\n" + "/Type /EmbeddedFile\n" + "/Subtype /text#2Fplain\n" + ">>\n" + "stream\n" + "Test attachment" + "endstream\n");
  2412. const parser = new _parser.Parser({
  2413. lexer: new _parser.Lexer(fileStream),
  2414. xref: null,
  2415. allowStreams: true
  2416. });
  2417. const fileStreamRef = _primitives.Ref.get(18, 0);
  2418. const fileStreamDict = parser.getObj();
  2419. const embeddedFileDict = new _primitives.Dict();
  2420. embeddedFileDict.set("F", fileStreamRef);
  2421. const fileSpecRef = _primitives.Ref.get(19, 0);
  2422. const fileSpecDict = new _primitives.Dict();
  2423. fileSpecDict.set("Type", _primitives.Name.get("Filespec"));
  2424. fileSpecDict.set("Desc", "");
  2425. fileSpecDict.set("EF", embeddedFileDict);
  2426. fileSpecDict.set("UF", "Test.txt");
  2427. const fileAttachmentRef = _primitives.Ref.get(20, 0);
  2428. const fileAttachmentDict = new _primitives.Dict();
  2429. fileAttachmentDict.set("Type", _primitives.Name.get("Annot"));
  2430. fileAttachmentDict.set("Subtype", _primitives.Name.get("FileAttachment"));
  2431. fileAttachmentDict.set("FS", fileSpecRef);
  2432. fileAttachmentDict.set("T", "Topic");
  2433. fileAttachmentDict.set("Contents", "Test.txt");
  2434. const xref = new _test_utils.XRefMock([{
  2435. ref: fileStreamRef,
  2436. data: fileStreamDict
  2437. }, {
  2438. ref: fileSpecRef,
  2439. data: fileSpecDict
  2440. }, {
  2441. ref: fileAttachmentRef,
  2442. data: fileAttachmentDict
  2443. }]);
  2444. embeddedFileDict.assignXref(xref);
  2445. fileSpecDict.assignXref(xref);
  2446. fileAttachmentDict.assignXref(xref);
  2447. const {
  2448. data
  2449. } = await _annotation.AnnotationFactory.create(xref, fileAttachmentRef, pdfManagerMock, idFactoryMock);
  2450. expect(data.annotationType).toEqual(_util.AnnotationType.FILEATTACHMENT);
  2451. expect(data.file.filename).toEqual("Test.txt");
  2452. expect(data.file.content).toEqual((0, _util.stringToBytes)("Test attachment"));
  2453. });
  2454. });
  2455. describe("PopupAnnotation", function () {
  2456. it("should inherit properties from its parent", async function () {
  2457. const parentDict = new _primitives.Dict();
  2458. parentDict.set("Type", _primitives.Name.get("Annot"));
  2459. parentDict.set("Subtype", _primitives.Name.get("Text"));
  2460. parentDict.set("M", "D:20190423");
  2461. parentDict.set("C", [0, 0, 1]);
  2462. const popupDict = new _primitives.Dict();
  2463. popupDict.set("Type", _primitives.Name.get("Annot"));
  2464. popupDict.set("Subtype", _primitives.Name.get("Popup"));
  2465. popupDict.set("Parent", parentDict);
  2466. const popupRef = _primitives.Ref.get(13, 0);
  2467. const xref = new _test_utils.XRefMock([{
  2468. ref: popupRef,
  2469. data: popupDict
  2470. }]);
  2471. const {
  2472. data
  2473. } = await _annotation.AnnotationFactory.create(xref, popupRef, pdfManagerMock, idFactoryMock);
  2474. expect(data.annotationType).toEqual(_util.AnnotationType.POPUP);
  2475. expect(data.modificationDate).toEqual("D:20190423");
  2476. expect(data.color).toEqual(new Uint8ClampedArray([0, 0, 255]));
  2477. });
  2478. it("should handle missing parent properties", async function () {
  2479. const parentDict = new _primitives.Dict();
  2480. parentDict.set("Type", _primitives.Name.get("Annot"));
  2481. parentDict.set("Subtype", _primitives.Name.get("Text"));
  2482. const popupDict = new _primitives.Dict();
  2483. popupDict.set("Type", _primitives.Name.get("Annot"));
  2484. popupDict.set("Subtype", _primitives.Name.get("Popup"));
  2485. popupDict.set("Parent", parentDict);
  2486. const popupRef = _primitives.Ref.get(13, 0);
  2487. const xref = new _test_utils.XRefMock([{
  2488. ref: popupRef,
  2489. data: popupDict
  2490. }]);
  2491. const {
  2492. data
  2493. } = await _annotation.AnnotationFactory.create(xref, popupRef, pdfManagerMock, idFactoryMock);
  2494. expect(data.annotationType).toEqual(_util.AnnotationType.POPUP);
  2495. expect(data.modificationDate).toEqual(null);
  2496. expect(data.color).toEqual(null);
  2497. });
  2498. it("should inherit the parent flags when the Popup is not viewable, " + "but the parent is (PR 7352)", async function () {
  2499. const parentDict = new _primitives.Dict();
  2500. parentDict.set("Type", _primitives.Name.get("Annot"));
  2501. parentDict.set("Subtype", _primitives.Name.get("Text"));
  2502. parentDict.set("F", 28);
  2503. const popupDict = new _primitives.Dict();
  2504. popupDict.set("Type", _primitives.Name.get("Annot"));
  2505. popupDict.set("Subtype", _primitives.Name.get("Popup"));
  2506. popupDict.set("F", 25);
  2507. popupDict.set("Parent", parentDict);
  2508. const popupRef = _primitives.Ref.get(13, 0);
  2509. const xref = new _test_utils.XRefMock([{
  2510. ref: popupRef,
  2511. data: popupDict
  2512. }]);
  2513. const {
  2514. data,
  2515. viewable
  2516. } = await _annotation.AnnotationFactory.create(xref, popupRef, pdfManagerMock, idFactoryMock);
  2517. expect(data.annotationType).toEqual(_util.AnnotationType.POPUP);
  2518. expect(data.annotationFlags).toEqual(25);
  2519. expect(viewable).toEqual(true);
  2520. });
  2521. it("should correctly inherit Contents from group-master annotation " + "if parent has ReplyType == Group", async function () {
  2522. const annotationRef = _primitives.Ref.get(819, 0);
  2523. const annotationDict = new _primitives.Dict();
  2524. annotationDict.set("Type", _primitives.Name.get("Annot"));
  2525. annotationDict.set("Subtype", _primitives.Name.get("Text"));
  2526. annotationDict.set("T", "Correct Title");
  2527. annotationDict.set("Contents", "Correct Text");
  2528. annotationDict.set("M", "D:20190423");
  2529. annotationDict.set("C", [0, 0, 1]);
  2530. const replyRef = _primitives.Ref.get(820, 0);
  2531. const replyDict = new _primitives.Dict();
  2532. replyDict.set("Type", _primitives.Name.get("Annot"));
  2533. replyDict.set("Subtype", _primitives.Name.get("Text"));
  2534. replyDict.set("IRT", annotationRef);
  2535. replyDict.set("RT", _primitives.Name.get("Group"));
  2536. replyDict.set("T", "Reply Title");
  2537. replyDict.set("Contents", "Reply Text");
  2538. replyDict.set("M", "D:20190523");
  2539. replyDict.set("C", [0.4]);
  2540. const popupRef = _primitives.Ref.get(821, 0);
  2541. const popupDict = new _primitives.Dict();
  2542. popupDict.set("Type", _primitives.Name.get("Annot"));
  2543. popupDict.set("Subtype", _primitives.Name.get("Popup"));
  2544. popupDict.set("T", "Wrong Title");
  2545. popupDict.set("Contents", "Wrong Text");
  2546. popupDict.set("Parent", replyRef);
  2547. popupDict.set("M", "D:20190623");
  2548. popupDict.set("C", [0.8]);
  2549. replyDict.set("Popup", popupRef);
  2550. const xref = new _test_utils.XRefMock([{
  2551. ref: annotationRef,
  2552. data: annotationDict
  2553. }, {
  2554. ref: replyRef,
  2555. data: replyDict
  2556. }, {
  2557. ref: popupRef,
  2558. data: popupDict
  2559. }]);
  2560. annotationDict.assignXref(xref);
  2561. popupDict.assignXref(xref);
  2562. replyDict.assignXref(xref);
  2563. const {
  2564. data
  2565. } = await _annotation.AnnotationFactory.create(xref, popupRef, pdfManagerMock, idFactoryMock);
  2566. expect(data.title).toEqual("Correct Title");
  2567. expect(data.contents).toEqual("Correct Text");
  2568. expect(data.modificationDate).toEqual("D:20190423");
  2569. expect(data.color).toEqual(new Uint8ClampedArray([0, 0, 255]));
  2570. });
  2571. });
  2572. describe("InkAnnotation", function () {
  2573. it("should handle a single ink list", async function () {
  2574. const inkDict = new _primitives.Dict();
  2575. inkDict.set("Type", _primitives.Name.get("Annot"));
  2576. inkDict.set("Subtype", _primitives.Name.get("Ink"));
  2577. inkDict.set("InkList", [[1, 1, 1, 2, 2, 2, 3, 3]]);
  2578. const inkRef = _primitives.Ref.get(142, 0);
  2579. const xref = new _test_utils.XRefMock([{
  2580. ref: inkRef,
  2581. data: inkDict
  2582. }]);
  2583. const {
  2584. data
  2585. } = await _annotation.AnnotationFactory.create(xref, inkRef, pdfManagerMock, idFactoryMock);
  2586. expect(data.annotationType).toEqual(_util.AnnotationType.INK);
  2587. expect(data.inkLists.length).toEqual(1);
  2588. expect(data.inkLists[0]).toEqual([{
  2589. x: 1,
  2590. y: 1
  2591. }, {
  2592. x: 1,
  2593. y: 2
  2594. }, {
  2595. x: 2,
  2596. y: 2
  2597. }, {
  2598. x: 3,
  2599. y: 3
  2600. }]);
  2601. });
  2602. it("should handle multiple ink lists", async function () {
  2603. const inkDict = new _primitives.Dict();
  2604. inkDict.set("Type", _primitives.Name.get("Annot"));
  2605. inkDict.set("Subtype", _primitives.Name.get("Ink"));
  2606. inkDict.set("InkList", [[1, 1, 1, 2], [3, 3, 4, 5]]);
  2607. const inkRef = _primitives.Ref.get(143, 0);
  2608. const xref = new _test_utils.XRefMock([{
  2609. ref: inkRef,
  2610. data: inkDict
  2611. }]);
  2612. const {
  2613. data
  2614. } = await _annotation.AnnotationFactory.create(xref, inkRef, pdfManagerMock, idFactoryMock);
  2615. expect(data.annotationType).toEqual(_util.AnnotationType.INK);
  2616. expect(data.inkLists.length).toEqual(2);
  2617. expect(data.inkLists[0]).toEqual([{
  2618. x: 1,
  2619. y: 1
  2620. }, {
  2621. x: 1,
  2622. y: 2
  2623. }]);
  2624. expect(data.inkLists[1]).toEqual([{
  2625. x: 3,
  2626. y: 3
  2627. }, {
  2628. x: 4,
  2629. y: 5
  2630. }]);
  2631. });
  2632. });
  2633. describe("HightlightAnnotation", function () {
  2634. it("should set quadpoints to null if not defined", async function () {
  2635. const highlightDict = new _primitives.Dict();
  2636. highlightDict.set("Type", _primitives.Name.get("Annot"));
  2637. highlightDict.set("Subtype", _primitives.Name.get("Highlight"));
  2638. const highlightRef = _primitives.Ref.get(121, 0);
  2639. const xref = new _test_utils.XRefMock([{
  2640. ref: highlightRef,
  2641. data: highlightDict
  2642. }]);
  2643. const {
  2644. data
  2645. } = await _annotation.AnnotationFactory.create(xref, highlightRef, pdfManagerMock, idFactoryMock);
  2646. expect(data.annotationType).toEqual(_util.AnnotationType.HIGHLIGHT);
  2647. expect(data.quadPoints).toEqual(null);
  2648. });
  2649. it("should set quadpoints if defined", async function () {
  2650. const highlightDict = new _primitives.Dict();
  2651. highlightDict.set("Type", _primitives.Name.get("Annot"));
  2652. highlightDict.set("Subtype", _primitives.Name.get("Highlight"));
  2653. highlightDict.set("Rect", [10, 10, 20, 20]);
  2654. highlightDict.set("QuadPoints", [10, 20, 20, 20, 10, 10, 20, 10]);
  2655. const highlightRef = _primitives.Ref.get(121, 0);
  2656. const xref = new _test_utils.XRefMock([{
  2657. ref: highlightRef,
  2658. data: highlightDict
  2659. }]);
  2660. const {
  2661. data
  2662. } = await _annotation.AnnotationFactory.create(xref, highlightRef, pdfManagerMock, idFactoryMock);
  2663. expect(data.annotationType).toEqual(_util.AnnotationType.HIGHLIGHT);
  2664. expect(data.quadPoints).toEqual([[{
  2665. x: 10,
  2666. y: 20
  2667. }, {
  2668. x: 20,
  2669. y: 20
  2670. }, {
  2671. x: 10,
  2672. y: 10
  2673. }, {
  2674. x: 20,
  2675. y: 10
  2676. }]]);
  2677. });
  2678. it("should set quadpoints to null when empty", async function () {
  2679. const highlightDict = new _primitives.Dict();
  2680. highlightDict.set("Type", _primitives.Name.get("Annot"));
  2681. highlightDict.set("Subtype", _primitives.Name.get("Highlight"));
  2682. highlightDict.set("Rect", [10, 10, 20, 20]);
  2683. highlightDict.set("QuadPoints", []);
  2684. const highlightRef = _primitives.Ref.get(121, 0);
  2685. const xref = new _test_utils.XRefMock([{
  2686. ref: highlightRef,
  2687. data: highlightDict
  2688. }]);
  2689. const {
  2690. data
  2691. } = await _annotation.AnnotationFactory.create(xref, highlightRef, pdfManagerMock, idFactoryMock);
  2692. expect(data.annotationType).toEqual(_util.AnnotationType.HIGHLIGHT);
  2693. expect(data.quadPoints).toEqual(null);
  2694. });
  2695. });
  2696. describe("UnderlineAnnotation", function () {
  2697. it("should set quadpoints to null if not defined", async function () {
  2698. const underlineDict = new _primitives.Dict();
  2699. underlineDict.set("Type", _primitives.Name.get("Annot"));
  2700. underlineDict.set("Subtype", _primitives.Name.get("Underline"));
  2701. const underlineRef = _primitives.Ref.get(121, 0);
  2702. const xref = new _test_utils.XRefMock([{
  2703. ref: underlineRef,
  2704. data: underlineDict
  2705. }]);
  2706. const {
  2707. data
  2708. } = await _annotation.AnnotationFactory.create(xref, underlineRef, pdfManagerMock, idFactoryMock);
  2709. expect(data.annotationType).toEqual(_util.AnnotationType.UNDERLINE);
  2710. expect(data.quadPoints).toEqual(null);
  2711. });
  2712. it("should set quadpoints if defined", async function () {
  2713. const underlineDict = new _primitives.Dict();
  2714. underlineDict.set("Type", _primitives.Name.get("Annot"));
  2715. underlineDict.set("Subtype", _primitives.Name.get("Underline"));
  2716. underlineDict.set("Rect", [10, 10, 20, 20]);
  2717. underlineDict.set("QuadPoints", [10, 20, 20, 20, 10, 10, 20, 10]);
  2718. const underlineRef = _primitives.Ref.get(121, 0);
  2719. const xref = new _test_utils.XRefMock([{
  2720. ref: underlineRef,
  2721. data: underlineDict
  2722. }]);
  2723. const {
  2724. data
  2725. } = await _annotation.AnnotationFactory.create(xref, underlineRef, pdfManagerMock, idFactoryMock);
  2726. expect(data.annotationType).toEqual(_util.AnnotationType.UNDERLINE);
  2727. expect(data.quadPoints).toEqual([[{
  2728. x: 10,
  2729. y: 20
  2730. }, {
  2731. x: 20,
  2732. y: 20
  2733. }, {
  2734. x: 10,
  2735. y: 10
  2736. }, {
  2737. x: 20,
  2738. y: 10
  2739. }]]);
  2740. });
  2741. });
  2742. describe("SquigglyAnnotation", function () {
  2743. it("should set quadpoints to null if not defined", async function () {
  2744. const squigglyDict = new _primitives.Dict();
  2745. squigglyDict.set("Type", _primitives.Name.get("Annot"));
  2746. squigglyDict.set("Subtype", _primitives.Name.get("Squiggly"));
  2747. const squigglyRef = _primitives.Ref.get(121, 0);
  2748. const xref = new _test_utils.XRefMock([{
  2749. ref: squigglyRef,
  2750. data: squigglyDict
  2751. }]);
  2752. const {
  2753. data
  2754. } = await _annotation.AnnotationFactory.create(xref, squigglyRef, pdfManagerMock, idFactoryMock);
  2755. expect(data.annotationType).toEqual(_util.AnnotationType.SQUIGGLY);
  2756. expect(data.quadPoints).toEqual(null);
  2757. });
  2758. it("should set quadpoints if defined", async function () {
  2759. const squigglyDict = new _primitives.Dict();
  2760. squigglyDict.set("Type", _primitives.Name.get("Annot"));
  2761. squigglyDict.set("Subtype", _primitives.Name.get("Squiggly"));
  2762. squigglyDict.set("Rect", [10, 10, 20, 20]);
  2763. squigglyDict.set("QuadPoints", [10, 20, 20, 20, 10, 10, 20, 10]);
  2764. const squigglyRef = _primitives.Ref.get(121, 0);
  2765. const xref = new _test_utils.XRefMock([{
  2766. ref: squigglyRef,
  2767. data: squigglyDict
  2768. }]);
  2769. const {
  2770. data
  2771. } = await _annotation.AnnotationFactory.create(xref, squigglyRef, pdfManagerMock, idFactoryMock);
  2772. expect(data.annotationType).toEqual(_util.AnnotationType.SQUIGGLY);
  2773. expect(data.quadPoints).toEqual([[{
  2774. x: 10,
  2775. y: 20
  2776. }, {
  2777. x: 20,
  2778. y: 20
  2779. }, {
  2780. x: 10,
  2781. y: 10
  2782. }, {
  2783. x: 20,
  2784. y: 10
  2785. }]]);
  2786. });
  2787. });
  2788. describe("StrikeOutAnnotation", function () {
  2789. it("should set quadpoints to null if not defined", async function () {
  2790. const strikeOutDict = new _primitives.Dict();
  2791. strikeOutDict.set("Type", _primitives.Name.get("Annot"));
  2792. strikeOutDict.set("Subtype", _primitives.Name.get("StrikeOut"));
  2793. const strikeOutRef = _primitives.Ref.get(121, 0);
  2794. const xref = new _test_utils.XRefMock([{
  2795. ref: strikeOutRef,
  2796. data: strikeOutDict
  2797. }]);
  2798. const {
  2799. data
  2800. } = await _annotation.AnnotationFactory.create(xref, strikeOutRef, pdfManagerMock, idFactoryMock);
  2801. expect(data.annotationType).toEqual(_util.AnnotationType.STRIKEOUT);
  2802. expect(data.quadPoints).toEqual(null);
  2803. });
  2804. it("should set quadpoints if defined", async function () {
  2805. const strikeOutDict = new _primitives.Dict();
  2806. strikeOutDict.set("Type", _primitives.Name.get("Annot"));
  2807. strikeOutDict.set("Subtype", _primitives.Name.get("StrikeOut"));
  2808. strikeOutDict.set("Rect", [10, 10, 20, 20]);
  2809. strikeOutDict.set("QuadPoints", [10, 20, 20, 20, 10, 10, 20, 10]);
  2810. const strikeOutRef = _primitives.Ref.get(121, 0);
  2811. const xref = new _test_utils.XRefMock([{
  2812. ref: strikeOutRef,
  2813. data: strikeOutDict
  2814. }]);
  2815. const {
  2816. data
  2817. } = await _annotation.AnnotationFactory.create(xref, strikeOutRef, pdfManagerMock, idFactoryMock);
  2818. expect(data.annotationType).toEqual(_util.AnnotationType.STRIKEOUT);
  2819. expect(data.quadPoints).toEqual([[{
  2820. x: 10,
  2821. y: 20
  2822. }, {
  2823. x: 20,
  2824. y: 20
  2825. }, {
  2826. x: 10,
  2827. y: 10
  2828. }, {
  2829. x: 20,
  2830. y: 10
  2831. }]]);
  2832. });
  2833. });
  2834. });