xfa_parser_spec.js 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323
  1. /**
  2. * @licstart The following is the entire license notice for the
  3. * JavaScript code in this page
  4. *
  5. * Copyright 2022 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 _xfa_object = require("../../core/xfa/xfa_object.js");
  24. var _bind = require("../../core/xfa/bind.js");
  25. var _som = require("../../core/xfa/som.js");
  26. var _parser = require("../../core/xfa/parser.js");
  27. describe("XFAParser", function () {
  28. describe("Parse XFA", function () {
  29. it("should parse a xfa document and create an object to represent it", function () {
  30. const xml = `
  31. <?xml version="1.0"?>
  32. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/" uuid="1234" invalid="foo">
  33. <config xmlns="http://www.xfa.org/schema/xci/3.1/">
  34. <present>
  35. <pdf name="hello">
  36. <adobeExtensionLevel>
  37. 7
  38. </adobeExtensionLevel>
  39. </pdf>
  40. <invalid><a>foobar</a></invalid>
  41. </present>
  42. <acrobat>
  43. <submitUrl>http://a.b.c</submitUrl>
  44. <acrobat7>
  45. <dynamicRender>
  46. forbidden
  47. </dynamicRender>
  48. </acrobat7>
  49. <autoSave>enabled</autoSave>
  50. <submitUrl>
  51. http://d.e.f
  52. </submitUrl>
  53. <submitUrl>http://g.h.i</submitUrl>
  54. <validate>foobar</validate>
  55. </acrobat>
  56. </config>
  57. <template baseProfile="full" xmlns="http://www.xfa.org/schema/xfa-template/3.3">
  58. <extras>
  59. <float>1.23</float>
  60. <boolean>1</boolean>
  61. <integer>314</integer>
  62. <float>2.71</float>
  63. </extras>
  64. <subform>
  65. <proto>
  66. <area x="hello" y="-3.14in" relevant="-foo +bar" />
  67. <color value="111, 222, 123" />
  68. <color value="111, abc, 123" />
  69. <medium imagingBBox="1,2in,3.4cm,5.67px" />
  70. <medium imagingBBox="1,2in,-3cm,4px" />
  71. </proto>
  72. </subform>
  73. </template>
  74. </xdp:xdp>
  75. `;
  76. const attributes = {
  77. id: "",
  78. name: "",
  79. use: "",
  80. usehref: ""
  81. };
  82. const mediumAttributes = {
  83. id: "",
  84. long: 0,
  85. orientation: "portrait",
  86. short: 0,
  87. stock: "",
  88. trayIn: "auto",
  89. trayOut: "auto",
  90. use: "",
  91. usehref: ""
  92. };
  93. const colorAttributes = {
  94. cSpace: "SRGB",
  95. id: "",
  96. use: "",
  97. usehref: ""
  98. };
  99. const root = new _parser.XFAParser().parse(xml);
  100. const expected = {
  101. uuid: "1234",
  102. timeStamp: "",
  103. template: {
  104. baseProfile: "full",
  105. extras: {
  106. ...attributes,
  107. float: [{
  108. ...attributes,
  109. $content: 1.23
  110. }, {
  111. ...attributes,
  112. $content: 2.71
  113. }],
  114. boolean: {
  115. ...attributes,
  116. $content: 1
  117. },
  118. integer: {
  119. ...attributes,
  120. $content: 314
  121. }
  122. },
  123. subform: {
  124. access: "open",
  125. allowMacro: 0,
  126. anchorType: "topLeft",
  127. colSpan: 1,
  128. columnWidths: [0],
  129. h: "",
  130. hAlign: "left",
  131. id: "",
  132. layout: "position",
  133. locale: "",
  134. maxH: 0,
  135. maxW: 0,
  136. mergeMode: "consumeData",
  137. minH: 0,
  138. minW: 0,
  139. name: "",
  140. presence: "visible",
  141. relevant: [],
  142. restoreState: "manual",
  143. scope: "name",
  144. use: "",
  145. usehref: "",
  146. w: "",
  147. x: 0,
  148. y: 0,
  149. proto: {
  150. area: {
  151. ...attributes,
  152. colSpan: 1,
  153. x: 0,
  154. y: -226.08,
  155. relevant: [{
  156. excluded: true,
  157. viewname: "foo"
  158. }, {
  159. excluded: false,
  160. viewname: "bar"
  161. }]
  162. },
  163. color: [{
  164. ...colorAttributes,
  165. value: {
  166. r: 111,
  167. g: 222,
  168. b: 123
  169. }
  170. }, {
  171. ...colorAttributes,
  172. value: {
  173. r: 111,
  174. g: 0,
  175. b: 123
  176. }
  177. }],
  178. medium: [{
  179. ...mediumAttributes,
  180. imagingBBox: {
  181. x: 1,
  182. y: 144,
  183. width: 96.3779527559055,
  184. height: 5.67
  185. }
  186. }, {
  187. ...mediumAttributes,
  188. imagingBBox: {
  189. x: -1,
  190. y: -1,
  191. width: -1,
  192. height: -1
  193. }
  194. }]
  195. }
  196. }
  197. },
  198. config: {
  199. acrobat: {
  200. acrobat7: {
  201. dynamicRender: {
  202. $content: "forbidden"
  203. }
  204. },
  205. autoSave: {
  206. $content: "enabled"
  207. },
  208. validate: {
  209. $content: "preSubmit"
  210. },
  211. submitUrl: [{
  212. $content: "http://a.b.c"
  213. }, {
  214. $content: "http://d.e.f"
  215. }, {
  216. $content: "http://g.h.i"
  217. }]
  218. },
  219. present: {
  220. pdf: {
  221. name: "hello",
  222. adobeExtensionLevel: {
  223. $content: 7
  224. }
  225. }
  226. }
  227. }
  228. };
  229. expect(root[_xfa_object.$dump]()).toEqual(expected);
  230. });
  231. it("should parse a xfa document and check namespaces", function () {
  232. const xml = `
  233. <?xml version="1.0"?>
  234. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  235. <config xmlns:foo="http:/www.foo.com" xmlns="http://www.xfa.org/schema/xci/3.1/">
  236. <present xmlns="http://www.mozilla.org">
  237. <pdf name="hello">
  238. <adobeExtensionLevel>
  239. 7
  240. </adobeExtensionLevel>
  241. </pdf>
  242. </present>
  243. <acrobat>
  244. <foo:submitUrl>http://a.b.c</foo:submitUrl>
  245. <submitUrl>http://c.b.a</submitUrl>
  246. </acrobat>
  247. </config>
  248. <template baseProfile="full" xmlns="http://www.allizom.org">
  249. <extras>
  250. <float>1.23</float>
  251. </extras>
  252. </template>
  253. </xdp:xdp>
  254. `;
  255. const root = new _parser.XFAParser().parse(xml);
  256. const expected = {
  257. uuid: "",
  258. timeStamp: "",
  259. config: {
  260. acrobat: {
  261. submitUrl: {
  262. $content: "http://c.b.a"
  263. }
  264. }
  265. }
  266. };
  267. expect(root[_xfa_object.$dump]()).toEqual(expected);
  268. });
  269. it("should parse a xfa document and parse CDATA when needed", function () {
  270. const xml = `
  271. <?xml version="1.0"?>
  272. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  273. <template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
  274. <subform>
  275. <field>
  276. <extras>
  277. <exData contentType="text/html" name="foo">
  278. <![CDATA[<body xmlns="http://www.w3.org/1999/xhtml">
  279. <span>hello</span></body>]]>
  280. </exData>
  281. </extra>
  282. </field>
  283. </subform>
  284. </template>
  285. </xdp:xdp>
  286. `;
  287. const root = new _parser.XFAParser().parse(xml);
  288. const exdata = (0, _som.searchNode)(root, root, "foo")[0];
  289. const body = exdata[_xfa_object.$dump]().$content[_xfa_object.$dump]();
  290. const expected = {
  291. $name: "body",
  292. attributes: {},
  293. children: [{
  294. $content: "hello",
  295. $name: "span",
  296. attributes: {},
  297. children: []
  298. }]
  299. };
  300. expect(body).toEqual(expected);
  301. });
  302. it("should parse a xfa document and apply some prototypes", function () {
  303. const xml = `
  304. <?xml version="1.0"?>
  305. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  306. <template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
  307. <subform>
  308. <proto>
  309. <font id="id1" typeface="Foo" size="123pt" weight="bold" posture="italic">
  310. <fill>
  311. <color value="1,2,3"/>
  312. </fill>
  313. </font>
  314. </proto>
  315. <field>
  316. <font use="#id1"/>
  317. </field>
  318. <field>
  319. <font use="#id1" size="456pt" weight="bold" posture="normal">
  320. <fill>
  321. <color value="4,5,6"/>
  322. </fill>
  323. <extras id="id2"/>
  324. </font>
  325. </field>
  326. </subform>
  327. </template>
  328. </xdp:xdp>
  329. `;
  330. const root = new _parser.XFAParser().parse(xml)[_xfa_object.$dump]();
  331. let font = root.template.subform.field[0].font;
  332. expect(font.typeface).toEqual("Foo");
  333. expect(font.overline).toEqual(0);
  334. expect(font.size).toEqual(123);
  335. expect(font.weight).toEqual("bold");
  336. expect(font.posture).toEqual("italic");
  337. expect(font.fill.color.value).toEqual({
  338. r: 1,
  339. g: 2,
  340. b: 3
  341. });
  342. expect(font.extras).toEqual(undefined);
  343. font = root.template.subform.field[1].font;
  344. expect(font.typeface).toEqual("Foo");
  345. expect(font.overline).toEqual(0);
  346. expect(font.size).toEqual(456);
  347. expect(font.weight).toEqual("bold");
  348. expect(font.posture).toEqual("normal");
  349. expect(font.fill.color.value).toEqual({
  350. r: 4,
  351. g: 5,
  352. b: 6
  353. });
  354. expect(font.extras.id).toEqual("id2");
  355. });
  356. it("should parse a xfa document and apply some prototypes through usehref", function () {
  357. const xml = `
  358. <?xml version="1.0"?>
  359. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  360. <template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
  361. <subform>
  362. <proto>
  363. <draw name="foo">
  364. <font typeface="Foo" size="123pt" weight="bold" posture="italic">
  365. <fill>
  366. <color value="1,2,3"/>
  367. </fill>
  368. </font>
  369. </draw>
  370. </proto>
  371. <field>
  372. <font usehref=".#som($template.#subform.foo.#font)"/>
  373. </field>
  374. <field>
  375. <font usehref=".#som($template.#subform.foo.#font)" size="456pt" weight="bold" posture="normal">
  376. <fill>
  377. <color value="4,5,6"/>
  378. </fill>
  379. <extras id="id2"/>
  380. </font>
  381. </field>
  382. </subform>
  383. </template>
  384. </xdp:xdp>
  385. `;
  386. const root = new _parser.XFAParser().parse(xml)[_xfa_object.$dump]();
  387. let font = root.template.subform.field[0].font;
  388. expect(font.typeface).toEqual("Foo");
  389. expect(font.overline).toEqual(0);
  390. expect(font.size).toEqual(123);
  391. expect(font.weight).toEqual("bold");
  392. expect(font.posture).toEqual("italic");
  393. expect(font.fill.color.value).toEqual({
  394. r: 1,
  395. g: 2,
  396. b: 3
  397. });
  398. expect(font.extras).toEqual(undefined);
  399. font = root.template.subform.field[1].font;
  400. expect(font.typeface).toEqual("Foo");
  401. expect(font.overline).toEqual(0);
  402. expect(font.size).toEqual(456);
  403. expect(font.weight).toEqual("bold");
  404. expect(font.posture).toEqual("normal");
  405. expect(font.fill.color.value).toEqual({
  406. r: 4,
  407. g: 5,
  408. b: 6
  409. });
  410. expect(font.extras.id).toEqual("id2");
  411. });
  412. it("should parse a xfa document with xhtml", function () {
  413. const xml = `
  414. <?xml version="1.0"?>
  415. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  416. <template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
  417. <extras>
  418. <text>
  419. <body xmlns="http://www.w3.org/1999/xhtml">
  420. <p style="foo: bar; text-indent:0.5in; line-height:11px;bar:foo;tab-stop: left 0.5in">
  421. The first line of this paragraph is indented a half-inch.<br/>
  422. Successive lines are not indented.<br/>
  423. This is the last line of the paragraph.<br/>
  424. </p>
  425. </body>
  426. </text>
  427. </extras>
  428. </template>
  429. </xdp:xdp>
  430. `;
  431. const root = new _parser.XFAParser().parse(xml)[_xfa_object.$dump]();
  432. const p = root.template.extras.text.$content[_xfa_object.$getChildren]()[0];
  433. expect(p.style).toEqual("text-indent:0.5in;line-height:11px;tab-stop:left 0.5in");
  434. expect(p[_xfa_object.$text]()).toEqual([" The first line of this paragraph is indented a half-inch.\n", " Successive lines are not indented.\n", " This is the last line of the paragraph.\n "].join(""));
  435. });
  436. it("should parse a xfa document and apply some prototypes with cycle", function () {
  437. const xml = `
  438. <?xml version="1.0"?>
  439. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  440. <template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
  441. <subform>
  442. <proto>
  443. <subform id="id1">
  444. <subform use="#id1"/>
  445. </subform>
  446. </proto>
  447. </subform>
  448. <subform use="#id1"/>
  449. </template>
  450. </xdp:xdp>
  451. `;
  452. const root = new _parser.XFAParser().parse(xml)[_xfa_object.$dump]();
  453. const subform = root.template.subform[1];
  454. expect(subform.id).toEqual("id1");
  455. expect(subform.subform.id).toEqual("id1");
  456. });
  457. it("should parse a xfa document and apply some nested prototypes", function () {
  458. const xml = `
  459. <?xml version="1.0"?>
  460. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  461. <template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
  462. <subform>
  463. <proto>
  464. <color id="RED" value="7, 8, 9"/>
  465. <font id="HELV" typeface="helvetica" size="31pt" weight="normal" posture="italic"> </font>
  466. <font id="HELV-RED" use="#HELV">
  467. <fill>
  468. <color use="#RED"/>
  469. </fill>
  470. </font>
  471. </proto>
  472. <field>
  473. <font use="#HELV-RED"/>
  474. </field>
  475. </subform>
  476. </template>
  477. </xdp:xdp>
  478. `;
  479. const root = new _parser.XFAParser().parse(xml)[_xfa_object.$dump]();
  480. const font = root.template.subform.field.font;
  481. expect(font.typeface).toEqual("helvetica");
  482. expect(font.overline).toEqual(0);
  483. expect(font.size).toEqual(31);
  484. expect(font.weight).toEqual("normal");
  485. expect(font.posture).toEqual("italic");
  486. expect(font.fill.color.value).toEqual({
  487. r: 7,
  488. g: 8,
  489. b: 9
  490. });
  491. });
  492. it("should parse a xfa document and apply a prototype with content", function () {
  493. const xml = `
  494. <?xml version="1.0"?>
  495. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  496. <template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
  497. <subform>
  498. <proto>
  499. <text id="TEXT">default TEXT</text>
  500. </proto>
  501. <field>
  502. <value>
  503. <text use="#TEXT"></text>
  504. </value>
  505. </field>
  506. <field>
  507. <value>
  508. <text use="#TEXT">Overriding text</text>
  509. </value>
  510. </field>
  511. </subform>
  512. </template>
  513. </xdp:xdp>
  514. `;
  515. const root = new _parser.XFAParser().parse(xml)[_xfa_object.$dump]();
  516. let field = root.template.subform.field[0];
  517. expect(field.value.text.$content).toEqual("default TEXT");
  518. field = root.template.subform.field[1];
  519. expect(field.value.text.$content).toEqual("Overriding text");
  520. });
  521. });
  522. describe("Search in XFA", function () {
  523. it("should search some nodes in a template object", function () {
  524. const xml = `
  525. <?xml version="1.0"?>
  526. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  527. <template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
  528. <subform name="Receipt" id="l">
  529. <subform id="m">
  530. <field name="Description" id="a"> </field>
  531. <field name="Units" id="b"> </field>
  532. <field name="Unit_Price" id="c"> </field>
  533. <field name="Total_Price" id="d"> </field>
  534. </subform>
  535. <subform id="n">
  536. <field name="Description" id="e"> </field>
  537. <field name="Units" id="f"> </field>
  538. <field name="Unit_Price" id="g"> </field>
  539. <field name="Total_Price" id="h"> </field>
  540. </subform>
  541. <subform name="foo" id="o">
  542. <field name="Description" id="p"> </field>
  543. <field name="Units" id="q"> </field>
  544. <field name="Unit_Price" id="r"> </field>
  545. <field name="Total_Price" id="s"> </field>
  546. </subform>
  547. <field name="Sub_Total" id="i"> </field>
  548. <field name="Tax" id="j"> </field>
  549. <field name="Total_Price" id="k"> </field>
  550. </subform>
  551. </template>
  552. </xdp:xdp>
  553. `;
  554. const root = new _parser.XFAParser().parse(xml);
  555. let found = root[_xfa_object.$getChildrenByName]("subform", true);
  556. expect(found.map(x => x.id)).toEqual(["l", "m", "n", "o"]);
  557. found = root[_xfa_object.$getChildrenByName]("Total_Price", true);
  558. expect(found.map(x => x.id)).toEqual(["d", "h", "s", "k"]);
  559. found = root.template[_xfa_object.$getChildrenByName]("Receipt", false);
  560. const receipt = found[0];
  561. found = receipt[_xfa_object.$getChildrenByName]("Total_Price", false);
  562. expect(found.map(x => x.id)).toEqual(["d", "h", "k"]);
  563. expect(receipt[_xfa_object.$getChildrenByClass]("name")).toEqual("Receipt");
  564. const subforms = receipt[_xfa_object.$getChildrenByClass]("subform");
  565. expect(subforms.children.map(x => x.id)).toEqual(["m", "n", "o"]);
  566. });
  567. it("should search some nodes in a template object using SOM", function () {
  568. const xml = `
  569. <?xml version="1.0"?>
  570. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  571. <template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
  572. <subform name="Receipt" id="l">
  573. <subform id="m">
  574. <field name="Description" id="a"> </field>
  575. <field name="Units" id="b"> </field>
  576. <field name="Unit_Price" id="c"> </field>
  577. <field name="Total_Price" id="d"> </field>
  578. </subform>
  579. <subform id="n">
  580. <field name="Description" id="e"> </field>
  581. <field name="Units" id="f"> </field>
  582. <field name="Unit_Price" id="g"> </field>
  583. <field name="Total_Price" id="h"> </field>
  584. </subform>
  585. <subform name="foo" id="o">
  586. <field name="Description" id="p"> </field>
  587. <field name="Units" id="q"> </field>
  588. <field name="Unit_Price" id="r"> </field>
  589. <field name="Total_Price" id="s"> </field>
  590. </subform>
  591. <field name="Sub_Total" id="i"> </field>
  592. <field name="Tax" id="j"> </field>
  593. <field name="Total_Price" id="k"> </field>
  594. </subform>
  595. </template>
  596. </xdp:xdp>
  597. `;
  598. const root = new _parser.XFAParser().parse(xml);
  599. expect((0, _som.searchNode)(root, null, "$template..Description.id")[0][_xfa_object.$text]()).toBe("a");
  600. expect((0, _som.searchNode)(root, null, "$template..Description.id")[0][_xfa_object.$text]()).toBe("a");
  601. expect((0, _som.searchNode)(root, null, "$template..Description[0].id")[0][_xfa_object.$text]()).toBe("a");
  602. expect((0, _som.searchNode)(root, null, "$template..Description[1].id")[0][_xfa_object.$text]()).toBe("e");
  603. expect((0, _som.searchNode)(root, null, "$template..Description[2].id")[0][_xfa_object.$text]()).toBe("p");
  604. expect((0, _som.searchNode)(root, null, "$template.Receipt.id")[0][_xfa_object.$text]()).toBe("l");
  605. expect((0, _som.searchNode)(root, null, "$template.Receipt.Description[1].id")[0][_xfa_object.$text]()).toBe("e");
  606. expect((0, _som.searchNode)(root, null, "$template.Receipt.Description[2]")).toBe(null);
  607. expect((0, _som.searchNode)(root, null, "$template.Receipt.foo.Description.id")[0][_xfa_object.$text]()).toBe("p");
  608. expect((0, _som.searchNode)(root, null, "$template.#subform.Sub_Total.id")[0][_xfa_object.$text]()).toBe("i");
  609. expect((0, _som.searchNode)(root, null, "$template.#subform.Units.id")[0][_xfa_object.$text]()).toBe("b");
  610. expect((0, _som.searchNode)(root, null, "$template.#subform.Units.parent.id")[0][_xfa_object.$text]()).toBe("m");
  611. });
  612. it("should search some nodes in a datasets object", function () {
  613. const xml = `
  614. <?xml version="1.0"?>
  615. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  616. <xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
  617. <xfa:data>
  618. <Receipt>
  619. <Page>1</Page>
  620. <Detail PartNo="GS001">
  621. <Description>Giant Slingshot</Description>
  622. <Units>1</Units>
  623. <Unit_Price>250.00</Unit_Price>
  624. <Total_Price>250.00</Total_Price>
  625. </Detail>
  626. <Page>2</Page>
  627. <Detail PartNo="RRB-LB">
  628. <Description>Road Runner Bait, large bag</Description>
  629. <Units>5</Units>
  630. <Unit_Price>12.00</Unit_Price>
  631. <Total_Price>60.00</Total_Price>
  632. </Detail>
  633. <Sub_Total>310.00</Sub_Total>
  634. <Tax>24.80</Tax>
  635. <Total_Price>334.80</Total_Price>
  636. </Receipt>
  637. </xfa:data>
  638. </xfa:datasets>
  639. </xdp:xdp>
  640. `;
  641. const root = new _parser.XFAParser().parse(xml);
  642. const data = root.datasets.data;
  643. let found = data[_xfa_object.$getChildrenByName]("Description", true);
  644. expect(found.map(x => x[_xfa_object.$text]())).toEqual(["Giant Slingshot", "Road Runner Bait, large bag"]);
  645. found = data[_xfa_object.$getChildrenByName]("Total_Price", true);
  646. expect(found.map(x => x[_xfa_object.$text]())).toEqual(["250.00", "60.00", "334.80"]);
  647. });
  648. it("should search some nodes using SOM from a non-root node", function () {
  649. const xml = `
  650. <?xml version="1.0"?>
  651. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  652. <xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
  653. <xfa:data>
  654. <Receipt>
  655. <Page>1</Page>
  656. <Detail PartNo="GS001">
  657. <Description>Giant Slingshot</Description>
  658. <Units>1</Units>
  659. <Unit_Price>250.00</Unit_Price>
  660. <Total_Price>250.00</Total_Price>
  661. </Detail>
  662. <Page>2</Page>
  663. <Detail PartNo="RRB-LB">
  664. <Description>Road Runner Bait, large bag</Description>
  665. <Units>5</Units>
  666. <Unit_Price>12.00</Unit_Price>
  667. <Total_Price>60.00</Total_Price>
  668. </Detail>
  669. <Sub_Total>310.00</Sub_Total>
  670. <Tax>24.80</Tax>
  671. <Total_Price>334.80</Total_Price>
  672. </Receipt>
  673. </xfa:data>
  674. </xfa:datasets>
  675. </xdp:xdp>
  676. `;
  677. const root = new _parser.XFAParser().parse(xml);
  678. const [receipt] = root.datasets.data[_xfa_object.$getChildren]("Receipt");
  679. expect((0, _som.searchNode)(root, receipt, "Detail[*].Total_Price").map(x => x[_xfa_object.$text]())).toEqual(["250.00", "60.00"]);
  680. const [units] = (0, _som.searchNode)(root, receipt, "Detail[1].Units");
  681. expect(units[_xfa_object.$text]()).toBe("5");
  682. let [found] = (0, _som.searchNode)(root, units, "Total_Price");
  683. expect(found[_xfa_object.$text]()).toBe("60.00");
  684. found = (0, _som.searchNode)(root, units, "Total_Pric");
  685. expect(found).toEqual(null);
  686. });
  687. it("should search some nodes in a datasets object using SOM", function () {
  688. const xml = `
  689. <?xml version="1.0"?>
  690. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  691. <xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
  692. <xfa:data>
  693. <Receipt Detail="Acme">
  694. <Detail>foo</Detail>
  695. <Detail>bar</Detail>
  696. </Receipt>
  697. </xfa:data>
  698. </xfa:datasets>
  699. </xdp:xdp>
  700. `;
  701. const root = new _parser.XFAParser().parse(xml);
  702. expect((0, _som.searchNode)(root, null, "$data.Receipt.Detail")[0][_xfa_object.$text]()).toBe("Acme");
  703. expect((0, _som.searchNode)(root, null, "$data.Receipt.Detail[0]")[0][_xfa_object.$text]()).toBe("Acme");
  704. expect((0, _som.searchNode)(root, null, "$data.Receipt.Detail[1]")[0][_xfa_object.$text]()).toBe("foo");
  705. expect((0, _som.searchNode)(root, null, "$data.Receipt.Detail[2]")[0][_xfa_object.$text]()).toBe("bar");
  706. });
  707. });
  708. describe("Bind data into form", function () {
  709. it("should make a basic binding", function () {
  710. const xml = `
  711. <?xml version="1.0"?>
  712. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  713. <template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
  714. <subform name="A">
  715. <subform name="B">
  716. <field name="C">
  717. </field>
  718. <field name="D">
  719. </field>
  720. </subform>
  721. </subform>
  722. </template>
  723. <xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
  724. <xfa:data>
  725. <A>
  726. <C>xyz</C>
  727. </A>
  728. </xfa:data>
  729. </xfa:datasets>
  730. </xdp:xdp>
  731. `;
  732. const root = new _parser.XFAParser().parse(xml);
  733. const form = new _bind.Binder(root).bind();
  734. expect((0, _som.searchNode)(form, form, "A.B.C.value.text")[0][_xfa_object.$dump]().$content).toBe("xyz");
  735. });
  736. it("should make a basic binding and create a non-existing node", function () {
  737. const xml = `
  738. <?xml version="1.0"?>
  739. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  740. <template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
  741. <subform name="A" mergeMode="matchTemplate">
  742. <subform name="B">
  743. <field name="C">
  744. </field>
  745. <field name="D">
  746. <value>
  747. <text>foobar</text>
  748. </value>
  749. </field>
  750. </subform>
  751. </subform>
  752. </template>
  753. <xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
  754. <xfa:data>
  755. <A>
  756. </A>
  757. </xfa:data>
  758. </xfa:datasets>
  759. </xdp:xdp>
  760. `;
  761. const root = new _parser.XFAParser().parse(xml);
  762. const binder = new _bind.Binder(root);
  763. const form = binder.bind();
  764. const data = binder.getData();
  765. expect((0, _som.searchNode)(form, form, "A.B.D.value.text")[0][_xfa_object.$dump]().$content).toBe("foobar");
  766. const expected = {
  767. $name: "A",
  768. attributes: {},
  769. children: [{
  770. $name: "B",
  771. attributes: {},
  772. children: [{
  773. $name: "C",
  774. attributes: {},
  775. children: []
  776. }, {
  777. $name: "D",
  778. attributes: {},
  779. children: []
  780. }]
  781. }]
  782. };
  783. expect((0, _som.searchNode)(data, data, "A")[0][_xfa_object.$dump]()).toEqual(expected);
  784. });
  785. it("should make a basic binding and create a non-existing node with namespaceId equal to -1", function () {
  786. const xml = `
  787. <?xml version="1.0"?>
  788. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  789. <template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
  790. <subform name="A">
  791. <subform name="B">
  792. <field name="C">
  793. </field>
  794. <field name="D">
  795. <value>
  796. <text>foobar</text>
  797. </value>
  798. </field>
  799. </subform>
  800. </subform>
  801. </template>
  802. </xdp:xdp>
  803. `;
  804. const root = new _parser.XFAParser().parse(xml);
  805. const binder = new _bind.Binder(root);
  806. const form = binder.bind();
  807. const data = binder.getData();
  808. expect((0, _som.searchNode)(form, form, "A.B.D.value.text")[0][_xfa_object.$dump]().$content).toBe("foobar");
  809. const expected = {
  810. $name: "A",
  811. $ns: -1,
  812. attributes: {},
  813. children: [{
  814. $name: "B",
  815. $ns: -1,
  816. attributes: {},
  817. children: [{
  818. $name: "C",
  819. $ns: -1,
  820. attributes: {},
  821. children: []
  822. }, {
  823. $name: "D",
  824. $ns: -1,
  825. attributes: {},
  826. children: []
  827. }]
  828. }]
  829. };
  830. expect((0, _som.searchNode)(data, data, "A")[0][_xfa_object.$dump](true)).toEqual(expected);
  831. });
  832. it("should make another basic binding", function () {
  833. const xml = `
  834. <?xml version="1.0"?>
  835. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  836. <template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
  837. <subform name="registration">
  838. <field name="first"> </field>
  839. <field name="last"> </field>
  840. <field name="apt"> </field>
  841. <field name="street"> </field>
  842. <field name="city"> </field>
  843. <field name="country"> </field>
  844. <field name="postalcode"/>
  845. </subform>
  846. </template>
  847. <xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
  848. <xfa:data>
  849. <registration>
  850. <first>Jack</first>
  851. <last>Spratt</last>
  852. <apt/>
  853. <street>99 Candlestick Lane</street>
  854. <city>London</city>
  855. <country>UK</country>
  856. <postalcode>SW1</postalcode>
  857. </registration>
  858. </xfa:data>
  859. </xfa:datasets>
  860. </xdp:xdp>
  861. `;
  862. const root = new _parser.XFAParser().parse(xml);
  863. const form = new _bind.Binder(root).bind();
  864. expect((0, _som.searchNode)(form, form, "registration.first..text")[0][_xfa_object.$dump]().$content).toBe("Jack");
  865. expect((0, _som.searchNode)(form, form, "registration.last..text")[0][_xfa_object.$dump]().$content).toBe("Spratt");
  866. expect((0, _som.searchNode)(form, form, "registration.apt..text")[0][_xfa_object.$dump]().$content).toBe(undefined);
  867. expect((0, _som.searchNode)(form, form, "registration.street..text")[0][_xfa_object.$dump]().$content).toBe("99 Candlestick Lane");
  868. expect((0, _som.searchNode)(form, form, "registration.city..text")[0][_xfa_object.$dump]().$content).toBe("London");
  869. expect((0, _som.searchNode)(form, form, "registration.country..text")[0][_xfa_object.$dump]().$content).toBe("UK");
  870. expect((0, _som.searchNode)(form, form, "registration.postalcode..text")[0][_xfa_object.$dump]().$content).toBe("SW1");
  871. });
  872. it("should make basic binding with extra subform", function () {
  873. const xml = `
  874. <?xml version="1.0"?>
  875. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  876. <template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
  877. <subform name="registration">
  878. <field name="first"> </field>
  879. <field name="last"> </field>
  880. <subform name="address">
  881. <field name="apt"> </field>
  882. <field name="street"> </field>
  883. <field name="city"> </field>
  884. <field name="country"> </field>
  885. <field name="postalcode"> </field>
  886. </subform>
  887. </subform>
  888. </template>
  889. <xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
  890. <xfa:data>
  891. <registration>
  892. <first>Jack</first>
  893. <last>Spratt</last>
  894. <apt/>
  895. <street>99 Candlestick Lane</street>
  896. <city>London</city>
  897. <country>UK</country>
  898. <postalcode>SW1</postalcode>
  899. </registration>
  900. </xfa:data>
  901. </xfa:datasets>
  902. </xdp:xdp>
  903. `;
  904. const root = new _parser.XFAParser().parse(xml);
  905. const form = new _bind.Binder(root).bind();
  906. expect((0, _som.searchNode)(form, form, "registration..first..text")[0][_xfa_object.$dump]().$content).toBe("Jack");
  907. expect((0, _som.searchNode)(form, form, "registration..last..text")[0][_xfa_object.$dump]().$content).toBe("Spratt");
  908. expect((0, _som.searchNode)(form, form, "registration..apt..text")[0][_xfa_object.$dump]().$content).toBe(undefined);
  909. expect((0, _som.searchNode)(form, form, "registration..street..text")[0][_xfa_object.$dump]().$content).toBe("99 Candlestick Lane");
  910. expect((0, _som.searchNode)(form, form, "registration..city..text")[0][_xfa_object.$dump]().$content).toBe("London");
  911. expect((0, _som.searchNode)(form, form, "registration..country..text")[0][_xfa_object.$dump]().$content).toBe("UK");
  912. expect((0, _som.searchNode)(form, form, "registration..postalcode..text")[0][_xfa_object.$dump]().$content).toBe("SW1");
  913. });
  914. it("should make basic binding with extra subform", function () {
  915. const xml = `
  916. <?xml version="1.0"?>
  917. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  918. <template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
  919. <subform name="registration" mergeMode="consumeData">
  920. <subform name="address">
  921. <field name="first"/>
  922. <field name="last"/>
  923. <field name="apt"/>
  924. <field name="street"/>
  925. <field name="city"/>
  926. </subform>
  927. </subform>
  928. </template>
  929. <xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
  930. <xfa:data>
  931. <registration>
  932. <first>Jack</first>
  933. <last>Spratt</last>
  934. <address>
  935. <apt>7</apt>
  936. <street>99 Candlestick Lane</street>
  937. <city>London</city>
  938. </address>
  939. </registration>
  940. </xfa:data>
  941. </xfa:datasets>
  942. </xdp:xdp>
  943. `;
  944. const root = new _parser.XFAParser().parse(xml);
  945. const form = new _bind.Binder(root).bind();
  946. expect((0, _som.searchNode)(form, form, "registration..first..text")[0][_xfa_object.$dump]().$content).toBe("Jack");
  947. expect((0, _som.searchNode)(form, form, "registration..last..text")[0][_xfa_object.$dump]().$content).toBe("Spratt");
  948. expect((0, _som.searchNode)(form, form, "registration..apt..text")[0][_xfa_object.$dump]().$content).toBe("7");
  949. expect((0, _som.searchNode)(form, form, "registration..street..text")[0][_xfa_object.$dump]().$content).toBe("99 Candlestick Lane");
  950. expect((0, _som.searchNode)(form, form, "registration..city..text")[0][_xfa_object.$dump]().$content).toBe("London");
  951. });
  952. it("should make basic binding with same names in different parts", function () {
  953. const xml = `
  954. <?xml version="1.0"?>
  955. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  956. <template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
  957. <subform name="application" mergeMode="consumeData">
  958. <subform name="sponsor">
  959. <field name="lastname"> </field>
  960. <!-- sponsor's last name -->
  961. </subform>
  962. <field name="lastname"> </field>
  963. <!-- applicant's last name -->
  964. </subform>
  965. </template>
  966. <xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
  967. <xfa:data>
  968. <application>
  969. <lastname>Abott</lastname>
  970. <sponsor>
  971. <lastname>Costello</lastname>
  972. </sponsor>
  973. </application>
  974. </xfa:data>
  975. </xfa:datasets>
  976. </xdp:xdp>
  977. `;
  978. const root = new _parser.XFAParser().parse(xml);
  979. const form = new _bind.Binder(root).bind();
  980. expect((0, _som.searchNode)(form, form, "application.sponsor.lastname..text")[0][_xfa_object.$dump]().$content).toBe("Costello");
  981. expect((0, _som.searchNode)(form, form, "application.lastname..text")[0][_xfa_object.$dump]().$content).toBe("Abott");
  982. });
  983. it("should make binding and create nodes in data", function () {
  984. const xml = `
  985. <?xml version="1.0"?>
  986. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  987. <template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
  988. <subform name="root" mergeMode="matchTemplate">
  989. <subform name="A">
  990. <field name="a"/>
  991. <field name="b"/>
  992. <subform name="B">
  993. <field name="c"/>
  994. <field name="d"/>
  995. <subform name="C">
  996. <field name="e"/>
  997. <field name="f"/>
  998. </subform>
  999. </subform>
  1000. </subform>
  1001. </subform>
  1002. </template>
  1003. <xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
  1004. <xfa:data>
  1005. <root>
  1006. <A>
  1007. <b>1</b>
  1008. </A>
  1009. </root>
  1010. </xfa:data>
  1011. </xfa:datasets>
  1012. </xdp:xdp>
  1013. `;
  1014. const root = new _parser.XFAParser().parse(xml);
  1015. const binder = new _bind.Binder(root);
  1016. const form = binder.bind();
  1017. const data = binder.getData();
  1018. expect((0, _som.searchNode)(form, form, "root..b..text")[0][_xfa_object.$dump]().$content).toBe("1");
  1019. expect((0, _som.searchNode)(data, data, "root.A.a")[0][_xfa_object.$dump]().$name).toBe("a");
  1020. expect((0, _som.searchNode)(data, data, "root.A.B.c")[0][_xfa_object.$dump]().$name).toBe("c");
  1021. expect((0, _som.searchNode)(data, data, "root.A.B.d")[0][_xfa_object.$dump]().$name).toBe("d");
  1022. expect((0, _som.searchNode)(data, data, "root.A.B.C.e")[0][_xfa_object.$dump]().$name).toBe("e");
  1023. expect((0, _som.searchNode)(data, data, "root.A.B.C.f")[0][_xfa_object.$dump]().$name).toBe("f");
  1024. });
  1025. it("should make binding and set properties", function () {
  1026. const xml = `
  1027. <?xml version="1.0"?>
  1028. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  1029. <template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
  1030. <subform name="Id">
  1031. <field name="LastName">
  1032. <setProperty ref="$data.Main.Style.NameFont" target="font.typeface"/>
  1033. <setProperty ref="$data.Main.Style.NameSize" target="font.size"/>
  1034. <setProperty ref="$data.Main.Help.LastName" target="assist.toolTip"/>
  1035. <font></font>
  1036. <assist>
  1037. <toolTip>
  1038. </toolTip>
  1039. </assist>
  1040. </field>
  1041. </subform>
  1042. </template>
  1043. <xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
  1044. <xfa:data>
  1045. <Id>
  1046. <LastName>foo</LastName>
  1047. </Id>
  1048. <Main>
  1049. <Style>
  1050. <NameFont>myfont</NameFont>
  1051. <NameSize>123.4pt</NameSize>
  1052. </Style>
  1053. <Help>
  1054. <LastName>Give the name!</LastName>
  1055. </Help>
  1056. </Main>
  1057. </xfa:data>
  1058. </xfa:datasets>
  1059. </xdp:xdp>
  1060. `;
  1061. const root = new _parser.XFAParser().parse(xml);
  1062. const form = new _bind.Binder(root).bind();
  1063. expect((0, _som.searchNode)(form, form, "Id.LastName..text")[0][_xfa_object.$dump]().$content).toBe("foo");
  1064. expect((0, _som.searchNode)(form, form, "Id.LastName.font.typeface")[0][_xfa_object.$text]()).toBe("myfont");
  1065. expect((0, _som.searchNode)(form, form, "Id.LastName.font.size")[0][_xfa_object.$text]()).toEqual(123.4);
  1066. expect((0, _som.searchNode)(form, form, "Id.LastName.assist.toolTip")[0][_xfa_object.$dump]().$content).toBe("Give the name!");
  1067. });
  1068. it("should make binding and bind items", function () {
  1069. const xml = `
  1070. <?xml version="1.0"?>
  1071. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  1072. <template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
  1073. <subform name="main">
  1074. <field name="CardName">
  1075. <bindItems ref="$data.main.ccs.cc[*]" labelRef="uiname" valueRef="token"/>
  1076. <ui>
  1077. <choiceList/>
  1078. </ui>
  1079. </field>
  1080. </subform>
  1081. </template>
  1082. <xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
  1083. <xfa:data>
  1084. <main>
  1085. <ccs>
  1086. <cc uiname="Visa" token="VISA"/>
  1087. <cc uiname="Mastercard" token="MC"/>
  1088. <cc uiname="American Express" token="AMEX"/>
  1089. </ccs>
  1090. <CardName>MC</CardName>
  1091. </main>
  1092. </xfa:data>
  1093. </xfa:datasets>
  1094. </xdp:xdp>
  1095. `;
  1096. const root = new _parser.XFAParser().parse(xml);
  1097. const form = new _bind.Binder(root).bind();
  1098. expect((0, _som.searchNode)(form, form, "subform.CardName.items[*].text[*]").map(x => x[_xfa_object.$text]())).toEqual(["Visa", "Mastercard", "American Express", "VISA", "MC", "AMEX"]);
  1099. });
  1100. it("should make binding and bind items with a ref", function () {
  1101. const xml = `
  1102. <?xml version="1.0"?>
  1103. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  1104. <template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
  1105. <subform name="main">
  1106. <field name="CardName">
  1107. <bind match="dataRef" ref="$data.main.value"/>
  1108. <bindItems ref="$data.main.ccs.cc[*]" labelRef="uiname" valueRef="token"/>
  1109. <ui>
  1110. <choiceList/>
  1111. </ui>
  1112. </field>
  1113. </subform>
  1114. </template>
  1115. <xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
  1116. <xfa:data>
  1117. <main>
  1118. <value>VISA</value>
  1119. <ccs>
  1120. <cc uiname="Visa" token="VISA"/>
  1121. <cc uiname="Mastercard" token="MC"/>
  1122. <cc uiname="American Express" token="AMEX"/>
  1123. </ccs>
  1124. <CardName>MC</CardName>
  1125. </main>
  1126. </xfa:data>
  1127. </xfa:datasets>
  1128. </xdp:xdp>
  1129. `;
  1130. const root = new _parser.XFAParser().parse(xml);
  1131. const form = new _bind.Binder(root).bind();
  1132. expect((0, _som.searchNode)(form, form, "subform.CardName.value.text").map(x => x[_xfa_object.$text]())).toEqual(["VISA"]);
  1133. expect((0, _som.searchNode)(form, form, "subform.CardName.items[*].text[*]").map(x => x[_xfa_object.$text]())).toEqual(["Visa", "Mastercard", "American Express", "VISA", "MC", "AMEX"]);
  1134. });
  1135. it("should make binding with occurrences in consumeData mode", function () {
  1136. const xml = `
  1137. <?xml version="1.0"?>
  1138. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  1139. <template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
  1140. <subform name="root" mergeMode="consumeData">
  1141. <subform name="section" id="section1">
  1142. <occur min="0" max="-1"/>
  1143. <bind match="dataRef" ref="$.section[*]"/>
  1144. <field name="line-item"/>
  1145. </subform>
  1146. <subform name="section" id="section2">
  1147. <occur min="0" max="-1"/>
  1148. <bind match="dataRef" ref="$.section[*]"/>
  1149. <field name="line-item"/>
  1150. </subform>
  1151. </subform>
  1152. </template>
  1153. <xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
  1154. <xfa:data>
  1155. <root>
  1156. <section>
  1157. <line-item>item1</line-item>
  1158. </section>
  1159. <section>
  1160. <line-item>item2</line-item>
  1161. </section>
  1162. </root>
  1163. </xfa:data>
  1164. </xfa:datasets>
  1165. </xdp:xdp>
  1166. `;
  1167. const root = new _parser.XFAParser().parse(xml);
  1168. const form = new _bind.Binder(root).bind();
  1169. expect((0, _som.searchNode)(form, form, "root.section[*].id").map(x => x[_xfa_object.$text]())).toEqual(["section1", "section1"]);
  1170. expect((0, _som.searchNode)(form, form, "root.section[*].line-item..text").map(x => x[_xfa_object.$text]())).toEqual(["item1", "item2"]);
  1171. });
  1172. it("should make binding with occurrences in matchTemplate mode", function () {
  1173. const xml = `
  1174. <?xml version="1.0"?>
  1175. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  1176. <template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
  1177. <subform name="root" mergeMode="matchTemplate">
  1178. <subform name="section" id="section1">
  1179. <occur min="0" max="-1"/>
  1180. <bind match="dataRef" ref="$.section[*]"/>
  1181. <field name="line-item"/>
  1182. </subform>
  1183. <subform name="section" id="section2">
  1184. <occur min="0" max="-1"/>
  1185. <bind match="dataRef" ref="$.section[*]"/>
  1186. <field name="line-item"/>
  1187. </subform>
  1188. </subform>
  1189. </template>
  1190. <xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
  1191. <xfa:data>
  1192. <root>
  1193. <section>
  1194. <line-item>item1</line-item>
  1195. </section>
  1196. <section>
  1197. <line-item>item2</line-item>
  1198. </section>
  1199. </root>
  1200. </xfa:data>
  1201. </xfa:datasets>
  1202. </xdp:xdp>
  1203. `;
  1204. const root = new _parser.XFAParser().parse(xml);
  1205. const form = new _bind.Binder(root).bind();
  1206. expect((0, _som.searchNode)(form, form, "root.section[*].id").map(x => x[_xfa_object.$text]())).toEqual(["section1", "section1", "section2", "section2"]);
  1207. expect((0, _som.searchNode)(form, form, "root.section[*].line-item..text").map(x => x[_xfa_object.$text]())).toEqual(["item1", "item2", "item1", "item2"]);
  1208. });
  1209. it("should make binding and create nodes in data with some bind tag", function () {
  1210. const xml = `
  1211. <?xml version="1.0"?>
  1212. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  1213. <template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
  1214. <subform name="root" mergeMode="matchTemplate">
  1215. <subform name="A">
  1216. <occur max="-1"/>
  1217. <bind ref="$.root.foo[*]" match="dataRef"/>
  1218. </subform>
  1219. <subform name="B">
  1220. <occur max="2"/>
  1221. <bind ref="$.root.bar[2]" match="dataRef"/>
  1222. </subform>
  1223. </subform>
  1224. </template>
  1225. <xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
  1226. <xfa:data>
  1227. <root>
  1228. </root>
  1229. </xfa:data>
  1230. </xfa:datasets>
  1231. </xdp:xdp>
  1232. `;
  1233. const root = new _parser.XFAParser().parse(xml);
  1234. const binder = new _bind.Binder(root);
  1235. binder.bind();
  1236. const data = binder.getData();
  1237. const expected = {
  1238. $name: "root",
  1239. children: [{
  1240. $name: "root",
  1241. children: [{
  1242. $name: "foo",
  1243. children: [],
  1244. attributes: {}
  1245. }, {
  1246. $name: "bar",
  1247. children: [],
  1248. attributes: {}
  1249. }, {
  1250. $name: "bar",
  1251. children: [],
  1252. attributes: {}
  1253. }, {
  1254. $name: "bar",
  1255. children: [],
  1256. attributes: {}
  1257. }],
  1258. attributes: {}
  1259. }],
  1260. attributes: {}
  1261. };
  1262. expect((0, _som.searchNode)(data, data, "root")[0][_xfa_object.$dump]()).toEqual(expected);
  1263. });
  1264. it("should make a binding with a bindItems", function () {
  1265. const xml = `
  1266. <?xml version="1.0"?>
  1267. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  1268. <template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
  1269. <subform name="A" mergeMode="matchTemplate">
  1270. <subform name="B">
  1271. <field name="C">
  1272. <ui>
  1273. <choicelist/>
  1274. </ui>
  1275. <bindItems ref="xfa.datasets.foo.bar[*]" labelRef="$" valueRef="oof"/>
  1276. </field>
  1277. </subform>
  1278. </subform>
  1279. </template>
  1280. <xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
  1281. <foo>
  1282. <bar oof="a">1</bar>
  1283. <bar oof="b">2</bar>
  1284. <bar oof="c">3</bar>
  1285. <bar oof="d">4</bar>
  1286. <bar oof="e">5</bar>
  1287. </foo>
  1288. <xfa:data>
  1289. <A><B></B></A>
  1290. </xfa:data>
  1291. </xfa:datasets>
  1292. </xdp:xdp>
  1293. `;
  1294. const root = new _parser.XFAParser().parse(xml);
  1295. const form = new _bind.Binder(root).bind();
  1296. expect((0, _som.searchNode)(form, form, "A.B.C.items[0].text[*]").map(x => x[_xfa_object.$dump]().$content)).toEqual(["1", "2", "3", "4", "5"]);
  1297. expect((0, _som.searchNode)(form, form, "A.B.C.items[1].text[*]").map(x => x[_xfa_object.$dump]().$content)).toEqual(["a", "b", "c", "d", "e"]);
  1298. });
  1299. });
  1300. it("should make a binding with a element in an area", function () {
  1301. const xml = `
  1302. <?xml version="1.0"?>
  1303. <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  1304. <template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
  1305. <subform name="A" mergeMode="matchTemplate">
  1306. <area>
  1307. <field name="B"/>
  1308. </area>
  1309. </subform>
  1310. </template>
  1311. <xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
  1312. <xfa:data>
  1313. <A><B>foobar</B></A>
  1314. </xfa:data>
  1315. </xfa:datasets>
  1316. </xdp:xdp>
  1317. `;
  1318. const root = new _parser.XFAParser().parse(xml);
  1319. const form = new _bind.Binder(root).bind();
  1320. expect((0, _som.searchNode)(form, form, "A..B..text")[0][_xfa_object.$dump]().$content).toBe("foobar");
  1321. });
  1322. });