pdfjs-dist 2.6.347 → 2.7.570

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pdfjs-dist might be problematic. Click here for more details.

Files changed (158) hide show
  1. package/README.md +3 -3
  2. package/bower.json +1 -1
  3. package/build/pdf.js +2050 -1087
  4. package/build/pdf.js.map +1 -1
  5. package/build/pdf.min.js +1 -1
  6. package/build/pdf.worker.js +18219 -10436
  7. package/build/pdf.worker.js.map +1 -1
  8. package/build/pdf.worker.min.js +1 -1
  9. package/es5/build/pdf.d.ts +1 -0
  10. package/es5/build/pdf.js +6623 -6654
  11. package/es5/build/pdf.js.map +1 -1
  12. package/es5/build/pdf.min.js +1 -1
  13. package/es5/build/pdf.worker.js +20815 -13888
  14. package/es5/build/pdf.worker.js.map +1 -1
  15. package/es5/build/pdf.worker.min.js +1 -1
  16. package/es5/image_decoders/pdf.image_decoders.js +3817 -4946
  17. package/es5/image_decoders/pdf.image_decoders.js.map +1 -1
  18. package/es5/image_decoders/pdf.image_decoders.min.js +1 -1
  19. package/es5/web/pdf_viewer.css +18 -15
  20. package/es5/web/pdf_viewer.js +1094 -514
  21. package/es5/web/pdf_viewer.js.map +1 -1
  22. package/image_decoders/pdf.image_decoders.js +774 -168
  23. package/image_decoders/pdf.image_decoders.js.map +1 -1
  24. package/image_decoders/pdf.image_decoders.min.js +1 -1
  25. package/lib/core/annotation.js +556 -108
  26. package/lib/core/cff_parser.js +7 -1
  27. package/lib/core/charsets.js +1 -1
  28. package/lib/core/cmap.js +20 -1
  29. package/lib/core/core_utils.js +162 -3
  30. package/lib/core/crypto.js +1 -1
  31. package/lib/core/default_appearance.js +132 -0
  32. package/lib/core/document.js +115 -9
  33. package/lib/core/encodings.js +1 -1
  34. package/lib/core/evaluator.js +168 -74
  35. package/lib/core/fonts.js +97 -11
  36. package/lib/core/function.js +5 -10
  37. package/lib/core/glyphlist.js +11 -4529
  38. package/lib/core/image_utils.js +30 -1
  39. package/lib/core/jpg.js +1 -1
  40. package/lib/core/jpx.js +5 -5
  41. package/lib/core/murmurhash3.js +1 -1
  42. package/lib/core/obj.js +123 -39
  43. package/lib/core/pattern.js +4 -4
  44. package/lib/core/primitives.js +24 -5
  45. package/lib/core/standard_fonts.js +1 -1
  46. package/lib/core/stream.js +5 -1
  47. package/lib/core/unicode.js +15 -1387
  48. package/lib/core/worker.js +58 -17
  49. package/lib/core/writer.js +68 -4
  50. package/lib/display/annotation_layer.js +712 -119
  51. package/lib/display/annotation_storage.js +21 -4
  52. package/lib/display/api.js +88 -18
  53. package/lib/display/canvas.js +414 -375
  54. package/lib/display/display_utils.js +11 -4
  55. package/lib/display/fetch_stream.js +3 -3
  56. package/lib/display/font_loader.js +2 -3
  57. package/lib/display/metadata.js +54 -20
  58. package/lib/display/node_stream.js +1 -1
  59. package/lib/display/optional_content_config.js +1 -1
  60. package/lib/display/pattern_helper.js +109 -113
  61. package/lib/display/svg.js +5 -5
  62. package/lib/display/text_layer.js +54 -54
  63. package/lib/display/transport_stream.js +4 -4
  64. package/lib/display/webgl.js +65 -68
  65. package/lib/examples/node/domstubs.js +9 -4
  66. package/lib/pdf.js +2 -2
  67. package/lib/pdf.sandbox.js +311 -0
  68. package/lib/pdf.worker.js +2 -2
  69. package/lib/shared/scripting_utils.js +84 -0
  70. package/lib/shared/util.js +129 -14
  71. package/lib/{display → shared}/xml_parser.js +112 -4
  72. package/lib/test/unit/annotation_spec.js +831 -109
  73. package/lib/test/unit/annotation_storage_spec.js +28 -10
  74. package/lib/test/unit/api_spec.js +190 -160
  75. package/lib/test/unit/bidi_spec.js +6 -6
  76. package/lib/test/unit/cff_parser_spec.js +73 -73
  77. package/lib/test/unit/clitests_helper.js +2 -0
  78. package/lib/test/unit/cmap_spec.js +48 -74
  79. package/lib/test/unit/core_utils_spec.js +34 -0
  80. package/lib/test/unit/crypto_spec.js +162 -199
  81. package/lib/test/unit/custom_spec.js +7 -18
  82. package/lib/test/unit/default_appearance_spec.js +54 -0
  83. package/lib/test/unit/display_svg_spec.js +24 -19
  84. package/lib/test/unit/display_utils_spec.js +1 -1
  85. package/lib/test/unit/document_spec.js +187 -20
  86. package/lib/test/unit/evaluator_spec.js +30 -30
  87. package/lib/test/unit/function_spec.js +165 -165
  88. package/lib/test/unit/jasmine-boot.js +52 -53
  89. package/lib/test/unit/metadata_spec.js +2 -2
  90. package/lib/test/unit/murmurhash3_spec.js +29 -16
  91. package/lib/test/unit/network_spec.js +21 -21
  92. package/lib/test/unit/pdf_find_controller_spec.js +131 -69
  93. package/lib/test/unit/pdf_find_utils_spec.js +10 -10
  94. package/lib/test/unit/scripting_spec.js +1104 -0
  95. package/lib/test/unit/stream_spec.js +8 -8
  96. package/lib/test/unit/test_utils.js +16 -19
  97. package/lib/test/unit/testreporter.js +11 -4
  98. package/lib/test/unit/type1_parser_spec.js +23 -23
  99. package/lib/test/unit/ui_utils_spec.js +78 -35
  100. package/lib/test/unit/unicode_spec.js +7 -7
  101. package/lib/test/unit/util_spec.js +26 -3
  102. package/lib/test/unit/writer_spec.js +16 -1
  103. package/lib/test/unit/xml_spec.js +117 -0
  104. package/lib/web/annotation_layer_builder.js +18 -6
  105. package/lib/web/app.js +579 -161
  106. package/lib/web/app_options.js +14 -0
  107. package/lib/web/base_tree_viewer.js +50 -0
  108. package/lib/web/base_viewer.js +350 -14
  109. package/lib/web/chromecom.js +9 -1
  110. package/lib/web/debugger.js +1 -2
  111. package/lib/web/download_manager.js +0 -15
  112. package/lib/web/firefox_print_service.js +6 -4
  113. package/lib/web/firefoxcom.js +84 -69
  114. package/lib/web/generic_scripting.js +55 -0
  115. package/lib/web/genericcom.js +9 -1
  116. package/lib/web/grab_to_pan.js +1 -1
  117. package/lib/web/interfaces.js +9 -3
  118. package/lib/web/pdf_attachment_viewer.js +1 -3
  119. package/lib/web/pdf_cursor_tools.js +20 -13
  120. package/lib/web/pdf_document_properties.js +48 -61
  121. package/lib/web/pdf_find_bar.js +1 -3
  122. package/lib/web/pdf_find_controller.js +58 -12
  123. package/lib/web/pdf_history.js +43 -21
  124. package/lib/web/pdf_layer_viewer.js +1 -9
  125. package/lib/web/pdf_link_service.js +108 -78
  126. package/lib/web/pdf_outline_viewer.js +166 -10
  127. package/lib/web/pdf_page_view.js +14 -14
  128. package/lib/web/pdf_presentation_mode.js +21 -31
  129. package/lib/web/pdf_rendering_queue.js +8 -1
  130. package/lib/web/pdf_sidebar.js +62 -107
  131. package/lib/web/pdf_sidebar_resizer.js +11 -21
  132. package/lib/web/pdf_single_page_viewer.js +8 -0
  133. package/lib/web/pdf_thumbnail_view.js +26 -26
  134. package/lib/web/pdf_thumbnail_viewer.js +13 -2
  135. package/lib/web/pdf_viewer.component.js +2 -2
  136. package/lib/web/pdf_viewer.js +3 -1
  137. package/lib/web/preferences.js +33 -44
  138. package/lib/web/text_layer_builder.js +2 -9
  139. package/lib/web/ui_utils.js +78 -46
  140. package/lib/web/viewer_compatibility.js +1 -2
  141. package/package.json +4 -1
  142. package/types/display/annotation_layer.d.ts +18 -3
  143. package/types/display/api.d.ts +110 -54
  144. package/types/display/canvas.d.ts +1 -1
  145. package/types/display/display_utils.d.ts +96 -95
  146. package/types/display/fetch_stream.d.ts +2 -2
  147. package/types/display/metadata.d.ts +4 -0
  148. package/types/display/pattern_helper.d.ts +1 -1
  149. package/types/display/text_layer.d.ts +7 -7
  150. package/types/display/transport_stream.d.ts +1 -1
  151. package/types/shared/scripting_utils.d.ts +12 -0
  152. package/types/shared/util.d.ts +281 -250
  153. package/types/shared/xml_parser.d.ts +64 -0
  154. package/web/pdf_viewer.css +18 -15
  155. package/web/pdf_viewer.js +809 -408
  156. package/web/pdf_viewer.js.map +1 -1
  157. package/webpack.js +1 -1
  158. package/types/display/xml_parser.d.ts +0 -35
@@ -0,0 +1,1104 @@
1
+ /**
2
+ * @licstart The following is the entire license notice for the
3
+ * Javascript code in this page
4
+ *
5
+ * Copyright 2020 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
+
24
+ var _display_utils = require("../../display/display_utils.js");
25
+
26
+ const sandboxBundleSrc = "../../build/generic/build/pdf.sandbox.js";
27
+ describe("Scripting", function () {
28
+ let sandbox, send_queue, test_id, ref;
29
+
30
+ function getId() {
31
+ const id = `${ref++}R`;
32
+ return id;
33
+ }
34
+
35
+ function myeval(code) {
36
+ const key = (test_id++).toString();
37
+ return sandbox.eval(code, key).then(() => {
38
+ const result = send_queue.get(key).result;
39
+ send_queue.delete(key);
40
+ return result;
41
+ });
42
+ }
43
+
44
+ beforeAll(function (done) {
45
+ test_id = 0;
46
+ ref = 1;
47
+ send_queue = new Map();
48
+
49
+ window.dispatchEvent = event => {
50
+ if (event.detail.command) {
51
+ send_queue.set(event.detail.command, event.detail);
52
+ } else if (send_queue.has(event.detail.id)) {
53
+ const prev = send_queue.get(event.detail.id);
54
+ Object.assign(prev, event.detail);
55
+ } else {
56
+ send_queue.set(event.detail.id, event.detail);
57
+ }
58
+ };
59
+
60
+ window.alert = value => {
61
+ const command = "alert";
62
+ send_queue.set(command, {
63
+ command,
64
+ value
65
+ });
66
+ };
67
+
68
+ const promise = (0, _display_utils.loadScript)(sandboxBundleSrc).then(() => {
69
+ return window.pdfjsSandbox.QuickJSSandbox();
70
+ });
71
+ sandbox = {
72
+ createSandbox(data) {
73
+ promise.then(sbx => sbx.create(data));
74
+ },
75
+
76
+ dispatchEventInSandbox(data) {
77
+ return promise.then(sbx => sbx.dispatchEvent(data));
78
+ },
79
+
80
+ nukeSandbox() {
81
+ promise.then(sbx => sbx.nukeSandbox());
82
+ },
83
+
84
+ eval(code, key) {
85
+ return promise.then(sbx => sbx.evalForTesting(code, key));
86
+ }
87
+
88
+ };
89
+ done();
90
+ });
91
+ afterAll(function () {
92
+ sandbox.nukeSandbox();
93
+ sandbox = null;
94
+ send_queue = null;
95
+ });
96
+ describe("Sandbox", function () {
97
+ it("should send a value, execute an action and get back a new value", function (done) {
98
+ function compute(n) {
99
+ let s = 0;
100
+
101
+ for (let i = 0; i < n; i++) {
102
+ s += i;
103
+ }
104
+
105
+ return s;
106
+ }
107
+
108
+ const number = 123;
109
+ const expected = ((number - 1) * number / 2).toString();
110
+ const refId = getId();
111
+ const data = {
112
+ objects: {
113
+ field: [{
114
+ id: refId,
115
+ value: "",
116
+ actions: {
117
+ Keystroke: [`${compute.toString()}event.value = compute(parseInt(event.value));`]
118
+ },
119
+ type: "text"
120
+ }]
121
+ },
122
+ calculationOrder: [],
123
+ appInfo: {
124
+ language: "en-US",
125
+ platform: "Linux x86_64"
126
+ }
127
+ };
128
+ sandbox.createSandbox(data);
129
+ sandbox.dispatchEventInSandbox({
130
+ id: refId,
131
+ value: `${number}`,
132
+ name: "Keystroke",
133
+ willCommit: true
134
+ }).then(() => {
135
+ expect(send_queue.has(refId)).toEqual(true);
136
+ expect(send_queue.get(refId)).toEqual({
137
+ id: refId,
138
+ valueAsString: expected
139
+ });
140
+ done();
141
+ }).catch(done.fail);
142
+ });
143
+ });
144
+ describe("Doc", function () {
145
+ it("should treat globalThis as the doc", async function (done) {
146
+ const refId = getId();
147
+ const data = {
148
+ objects: {
149
+ field: [{
150
+ id: refId,
151
+ value: "",
152
+ actions: {},
153
+ type: "text"
154
+ }]
155
+ },
156
+ appInfo: {
157
+ language: "en-US",
158
+ platform: "Linux x86_64"
159
+ },
160
+ calculationOrder: [],
161
+ dispatchEventName: "_dispatchMe"
162
+ };
163
+ sandbox.createSandbox(data);
164
+
165
+ try {
166
+ await myeval(`(this.foobar = 123456, 0)`);
167
+ await myeval(`this.getField("field").doc.foobar`).then(value => {
168
+ expect(value).toEqual(123456);
169
+ });
170
+ done();
171
+ } catch (ex) {
172
+ done.fail(ex);
173
+ }
174
+ });
175
+ });
176
+ describe("Util", function () {
177
+ beforeAll(function (done) {
178
+ sandbox.createSandbox({
179
+ appInfo: {
180
+ language: "en-US",
181
+ platform: "Linux x86_64"
182
+ },
183
+ objects: {},
184
+ calculationOrder: []
185
+ });
186
+ done();
187
+ });
188
+ describe("printd", function () {
189
+ it("should print a date according to a format", function (done) {
190
+ const date = `new Date("Sun Apr 15 2007 03:14:15")`;
191
+ Promise.all([myeval(`util.printd(0, ${date})`).then(value => {
192
+ expect(value).toEqual("D:20070415031415");
193
+ }), myeval(`util.printd(1, ${date})`).then(value => {
194
+ expect(value).toEqual("2007.04.15 03:14:15");
195
+ }), myeval(`util.printd(2, ${date})`).then(value => {
196
+ expect(value).toEqual("4/15/07 3:14:15 am");
197
+ }), myeval(`util.printd("mmmm mmm mm m", ${date})`).then(value => {
198
+ expect(value).toEqual("April Apr 04 4");
199
+ }), myeval(`util.printd("dddd ddd dd d", ${date})`).then(value => {
200
+ expect(value).toEqual("Sunday Sun 15 15");
201
+ })]).then(() => done());
202
+ });
203
+ });
204
+ describe("scand", function () {
205
+ it("should parse a date according to a format", function (done) {
206
+ const date = new Date("Sun Apr 15 2007 03:14:15");
207
+ Promise.all([myeval(`util.scand(0, "D:20070415031415").toString()`).then(value => {
208
+ expect(new Date(value)).toEqual(date);
209
+ }), myeval(`util.scand(1, "2007.04.15 03:14:15").toString()`).then(value => {
210
+ expect(new Date(value)).toEqual(date);
211
+ }), myeval(`util.scand(2, "4/15/07 3:14:15 am").toString()`).then(value => {
212
+ expect(new Date(value)).toEqual(date);
213
+ })]).then(() => done());
214
+ });
215
+ });
216
+ describe("printf", function () {
217
+ it("should print some data according to a format", function (done) {
218
+ Promise.all([myeval(`util.printf("Integer numbers: %d, %d,...", 1.234, 56.789)`).then(value => {
219
+ expect(value).toEqual("Integer numbers: 1, 56,...");
220
+ }), myeval(`util.printf("Hex numbers: %x, %x,...", 1234, 56789)`).then(value => {
221
+ expect(value).toEqual("Hex numbers: 4D2, DDD5,...");
222
+ }), myeval(`util.printf("Hex numbers with 0x: %#x, %#x,...", 1234, 56789)`).then(value => {
223
+ expect(value).toEqual("Hex numbers with 0x: 0x4D2, 0xDDD5,...");
224
+ }), myeval(`util.printf("Decimal number: %,0+.3f", 1234567.89123)`).then(value => {
225
+ expect(value).toEqual("Decimal number: +1,234,567.891");
226
+ }), myeval(`util.printf("Decimal number: %,0+8.3f", 1.234567)`).then(value => {
227
+ expect(value).toEqual("Decimal number: + 1.235");
228
+ }), myeval(`util.printf("Decimal number: %,0.2f", -12.34567)`).then(value => {
229
+ expect(value).toEqual("Decimal number: -12.35");
230
+ })]).then(() => done());
231
+ });
232
+ it("should print a string with no argument", function (done) {
233
+ myeval(`util.printf("hello world")`).then(value => {
234
+ expect(value).toEqual("hello world");
235
+ }).then(() => done());
236
+ });
237
+ it("print a string with a percent", function (done) {
238
+ myeval(`util.printf("%%s")`).then(value => {
239
+ expect(value).toEqual("%%s");
240
+ }).then(() => done());
241
+ });
242
+ });
243
+ describe("printx", function () {
244
+ it("should print some data according to a format", function (done) {
245
+ myeval(`util.printx("9 (999) 999-9999", "aaa14159697489zzz")`).then(value => {
246
+ expect(value).toEqual("1 (415) 969-7489");
247
+ }).then(() => done());
248
+ });
249
+ });
250
+ });
251
+ describe("Events", function () {
252
+ it("should trigger an event and modify the source", function (done) {
253
+ const refId = getId();
254
+ const data = {
255
+ objects: {
256
+ field: [{
257
+ id: refId,
258
+ value: "",
259
+ actions: {
260
+ test: [`event.source.value = "123";`]
261
+ },
262
+ type: "text"
263
+ }]
264
+ },
265
+ appInfo: {
266
+ language: "en-US",
267
+ platform: "Linux x86_64"
268
+ },
269
+ calculationOrder: []
270
+ };
271
+ sandbox.createSandbox(data);
272
+ sandbox.dispatchEventInSandbox({
273
+ id: refId,
274
+ value: "",
275
+ name: "test",
276
+ willCommit: true
277
+ }).then(() => {
278
+ expect(send_queue.has(refId)).toEqual(true);
279
+ expect(send_queue.get(refId)).toEqual({
280
+ id: refId,
281
+ value: "123"
282
+ });
283
+ done();
284
+ }).catch(done.fail);
285
+ });
286
+ it("should trigger a Keystroke event and invalidate it", function (done) {
287
+ const refId = getId();
288
+ const data = {
289
+ objects: {
290
+ field: [{
291
+ id: refId,
292
+ value: "",
293
+ actions: {
294
+ Keystroke: [`event.rc = false;`]
295
+ },
296
+ type: "text"
297
+ }]
298
+ },
299
+ appInfo: {
300
+ language: "en-US",
301
+ platform: "Linux x86_64"
302
+ },
303
+ calculationOrder: []
304
+ };
305
+ sandbox.createSandbox(data);
306
+ sandbox.dispatchEventInSandbox({
307
+ id: refId,
308
+ value: "hell",
309
+ name: "Keystroke",
310
+ willCommit: false,
311
+ change: "o",
312
+ selStart: 4,
313
+ selEnd: 4
314
+ }).then(() => {
315
+ expect(send_queue.has(refId)).toEqual(true);
316
+ expect(send_queue.get(refId)).toEqual({
317
+ id: refId,
318
+ value: "hell",
319
+ selRange: [4, 4]
320
+ });
321
+ done();
322
+ }).catch(done.fail);
323
+ });
324
+ it("should trigger a Keystroke event and change it", function (done) {
325
+ const refId = getId();
326
+ const data = {
327
+ objects: {
328
+ field: [{
329
+ id: refId,
330
+ value: "",
331
+ actions: {
332
+ Keystroke: [`event.change = "a";`]
333
+ },
334
+ type: "text"
335
+ }]
336
+ },
337
+ appInfo: {
338
+ language: "en-US",
339
+ platform: "Linux x86_64"
340
+ },
341
+ calculationOrder: []
342
+ };
343
+ sandbox.createSandbox(data);
344
+ sandbox.dispatchEventInSandbox({
345
+ id: refId,
346
+ value: "hell",
347
+ name: "Keystroke",
348
+ willCommit: false,
349
+ change: "o",
350
+ selStart: 4,
351
+ selEnd: 4
352
+ }).then(() => {
353
+ expect(send_queue.has(refId)).toEqual(true);
354
+ expect(send_queue.get(refId)).toEqual({
355
+ id: refId,
356
+ value: "hella"
357
+ });
358
+ done();
359
+ }).catch(done.fail);
360
+ });
361
+ it("should trigger an invalid commit Keystroke event", function (done) {
362
+ const refId = getId();
363
+ const data = {
364
+ objects: {
365
+ field: [{
366
+ id: refId,
367
+ value: "",
368
+ actions: {
369
+ test: [`event.rc = false;`]
370
+ },
371
+ type: "text"
372
+ }]
373
+ },
374
+ appInfo: {
375
+ language: "en-US",
376
+ platform: "Linux x86_64"
377
+ },
378
+ calculationOrder: []
379
+ };
380
+ sandbox.createSandbox(data);
381
+ sandbox.dispatchEventInSandbox({
382
+ id: refId,
383
+ value: "",
384
+ name: "test",
385
+ willCommit: true
386
+ }).then(() => {
387
+ expect(send_queue.has(refId)).toEqual(false);
388
+ done();
389
+ }).catch(done.fail);
390
+ });
391
+ it("should trigger a valid commit Keystroke event", function (done) {
392
+ const refId1 = getId();
393
+ const refId2 = getId();
394
+ const data = {
395
+ objects: {
396
+ field1: [{
397
+ id: refId1,
398
+ value: "",
399
+ actions: {
400
+ Validate: [`event.value = "world";`]
401
+ },
402
+ type: "text"
403
+ }],
404
+ field2: [{
405
+ id: refId2,
406
+ value: "",
407
+ actions: {
408
+ Calculate: [`event.value = "hello";`]
409
+ },
410
+ type: "text"
411
+ }]
412
+ },
413
+ appInfo: {
414
+ language: "en-US",
415
+ platform: "Linux x86_64"
416
+ },
417
+ calculationOrder: [refId2]
418
+ };
419
+ sandbox.createSandbox(data);
420
+ sandbox.dispatchEventInSandbox({
421
+ id: refId1,
422
+ value: "hello",
423
+ name: "Keystroke",
424
+ willCommit: true
425
+ }).then(() => {
426
+ expect(send_queue.has(refId1)).toEqual(true);
427
+ expect(send_queue.get(refId1)).toEqual({
428
+ id: refId1,
429
+ value: "world",
430
+ valueAsString: "world"
431
+ });
432
+ done();
433
+ }).catch(done.fail);
434
+ });
435
+ });
436
+ describe("Color", function () {
437
+ beforeAll(function (done) {
438
+ sandbox.createSandbox({
439
+ appInfo: {
440
+ language: "en-US",
441
+ platform: "Linux x86_64"
442
+ },
443
+ objects: {},
444
+ calculationOrder: []
445
+ });
446
+ done();
447
+ });
448
+
449
+ function round(color) {
450
+ return [color[0], ...color.slice(1).map(x => Math.round(x * 1000) / 1000)];
451
+ }
452
+
453
+ it("should convert RGB color for different color spaces", function (done) {
454
+ Promise.all([myeval(`color.convert(["RGB", 0.1, 0.2, 0.3], "T")`).then(value => {
455
+ expect(round(value)).toEqual(["T"]);
456
+ }), myeval(`color.convert(["RGB", 0.1, 0.2, 0.3], "G")`).then(value => {
457
+ expect(round(value)).toEqual(["G", 0.181]);
458
+ }), myeval(`color.convert(["RGB", 0.1, 0.2, 0.3], "RGB")`).then(value => {
459
+ expect(round(value)).toEqual(["RGB", 0.1, 0.2, 0.3]);
460
+ }), myeval(`color.convert(["RGB", 0.1, 0.2, 0.3], "CMYK")`).then(value => {
461
+ expect(round(value)).toEqual(["CMYK", 0.9, 0.8, 0.7, 0.7]);
462
+ })]).then(() => done());
463
+ });
464
+ it("should convert CMYK color for different color spaces", function (done) {
465
+ Promise.all([myeval(`color.convert(["CMYK", 0.1, 0.2, 0.3, 0.4], "T")`).then(value => {
466
+ expect(round(value)).toEqual(["T"]);
467
+ }), myeval(`color.convert(["CMYK", 0.1, 0.2, 0.3, 0.4], "G")`).then(value => {
468
+ expect(round(value)).toEqual(["G", 0.371]);
469
+ }), myeval(`color.convert(["CMYK", 0.1, 0.2, 0.3, 0.4], "RGB")`).then(value => {
470
+ expect(round(value)).toEqual(["RGB", 0.5, 0.3, 0.4]);
471
+ }), myeval(`color.convert(["CMYK", 0.1, 0.2, 0.3, 0.4], "CMYK")`).then(value => {
472
+ expect(round(value)).toEqual(["CMYK", 0.1, 0.2, 0.3, 0.4]);
473
+ })]).then(() => done());
474
+ });
475
+ it("should convert Gray color for different color spaces", function (done) {
476
+ Promise.all([myeval(`color.convert(["G", 0.1], "T")`).then(value => {
477
+ expect(round(value)).toEqual(["T"]);
478
+ }), myeval(`color.convert(["G", 0.1], "G")`).then(value => {
479
+ expect(round(value)).toEqual(["G", 0.1]);
480
+ }), myeval(`color.convert(["G", 0.1], "RGB")`).then(value => {
481
+ expect(round(value)).toEqual(["RGB", 0.1, 0.1, 0.1]);
482
+ }), myeval(`color.convert(["G", 0.1], "CMYK")`).then(value => {
483
+ expect(round(value)).toEqual(["CMYK", 0, 0, 0, 0.9]);
484
+ })]).then(() => done());
485
+ });
486
+ it("should convert Transparent color for different color spaces", function (done) {
487
+ Promise.all([myeval(`color.convert(["T"], "T")`).then(value => {
488
+ expect(round(value)).toEqual(["T"]);
489
+ }), myeval(`color.convert(["T"], "G")`).then(value => {
490
+ expect(round(value)).toEqual(["G", 0]);
491
+ }), myeval(`color.convert(["T"], "RGB")`).then(value => {
492
+ expect(round(value)).toEqual(["RGB", 0, 0, 0]);
493
+ }), myeval(`color.convert(["T"], "CMYK")`).then(value => {
494
+ expect(round(value)).toEqual(["CMYK", 0, 0, 0, 1]);
495
+ })]).then(() => done());
496
+ });
497
+ });
498
+ describe("App", function () {
499
+ beforeAll(function (done) {
500
+ sandbox.createSandbox({
501
+ appInfo: {
502
+ language: "en-US",
503
+ platform: "Linux x86_64"
504
+ },
505
+ objects: {},
506
+ calculationOrder: []
507
+ });
508
+ done();
509
+ });
510
+ it("should test language", function (done) {
511
+ Promise.all([myeval(`app.language`).then(value => {
512
+ expect(value).toEqual("ENU");
513
+ }), myeval(`app.language = "hello"`).then(value => {
514
+ expect(value).toEqual("app.language is read-only");
515
+ })]).then(() => done());
516
+ });
517
+ it("should test platform", function (done) {
518
+ Promise.all([myeval(`app.platform`).then(value => {
519
+ expect(value).toEqual("UNIX");
520
+ }), myeval(`app.platform = "hello"`).then(value => {
521
+ expect(value).toEqual("app.platform is read-only");
522
+ })]).then(() => done());
523
+ });
524
+ });
525
+ describe("AForm", function () {
526
+ beforeAll(function (done) {
527
+ sandbox.createSandbox({
528
+ appInfo: {
529
+ language: "en-US",
530
+ platform: "Linux x86_64"
531
+ },
532
+ objects: {},
533
+ calculationOrder: [],
534
+ dispatchEventName: "_dispatchMe"
535
+ });
536
+ done();
537
+ });
538
+ describe("AFExtractNums", function () {
539
+ it("should extract numbers", function (done) {
540
+ Promise.all([myeval(`AFExtractNums("123 456 789")`).then(value => {
541
+ expect(value).toEqual(["123", "456", "789"]);
542
+ }), myeval(`AFExtractNums("123.456")`).then(value => {
543
+ expect(value).toEqual(["123", "456"]);
544
+ }), myeval(`AFExtractNums("123")`).then(value => {
545
+ expect(value).toEqual(["123"]);
546
+ }), myeval(`AFExtractNums(".123")`).then(value => {
547
+ expect(value).toEqual(["0", "123"]);
548
+ }), myeval(`AFExtractNums(",123")`).then(value => {
549
+ expect(value).toEqual(["0", "123"]);
550
+ })]).then(() => done());
551
+ });
552
+ });
553
+ describe("AFMakeNumber", function () {
554
+ it("should convert string to number", function (done) {
555
+ Promise.all([myeval(`AFMakeNumber("123.456")`).then(value => {
556
+ expect(value).toEqual(123.456);
557
+ }), myeval(`AFMakeNumber(123.456)`).then(value => {
558
+ expect(value).toEqual(123.456);
559
+ }), myeval(`AFMakeNumber("-123.456")`).then(value => {
560
+ expect(value).toEqual(-123.456);
561
+ }), myeval(`AFMakeNumber("-123,456")`).then(value => {
562
+ expect(value).toEqual(-123.456);
563
+ }), myeval(`AFMakeNumber("not a number")`).then(value => {
564
+ expect(value).toEqual(null);
565
+ })]).then(() => done());
566
+ });
567
+ });
568
+ describe("AFMakeArrayFromList", function () {
569
+ it("should split a string into an array of strings", async function (done) {
570
+ const value = await myeval(`AFMakeArrayFromList("aaaa, bbbbbbb,cc,ddd, e")`);
571
+ expect(value).toEqual(["aaaa", " bbbbbbb", "cc", "ddd", "e"]);
572
+ done();
573
+ });
574
+ });
575
+ describe("AFNumber_format", function () {
576
+ it("should format a number", async function (done) {
577
+ const refId = getId();
578
+ const data = {
579
+ objects: {
580
+ field: [{
581
+ id: refId,
582
+ value: "",
583
+ actions: {
584
+ test1: [`AFNumber_Format(2, 0, 0, 0, "€", false);` + `event.source.value = event.value;`],
585
+ test2: [`AFNumber_Format(1, 3, 0, 0, "$", true);` + `event.source.value = event.value;`],
586
+ test3: [`AFNumber_Format(2, 0, 1, 0, "€", false);` + `event.source.value = event.value;`],
587
+ test4: [`AFNumber_Format(2, 0, 2, 0, "€", false);` + `event.source.value = event.value;`],
588
+ test5: [`AFNumber_Format(2, 0, 3, 0, "€", false);` + `event.source.value = event.value;`]
589
+ },
590
+ type: "text"
591
+ }]
592
+ },
593
+ appInfo: {
594
+ language: "en-US",
595
+ platform: "Linux x86_64"
596
+ },
597
+ calculationOrder: [],
598
+ dispatchEventName: "_dispatchMe"
599
+ };
600
+
601
+ try {
602
+ sandbox.createSandbox(data);
603
+ await sandbox.dispatchEventInSandbox({
604
+ id: refId,
605
+ value: "123456.789",
606
+ name: "test1"
607
+ });
608
+ expect(send_queue.has(refId)).toEqual(true);
609
+ expect(send_queue.get(refId)).toEqual({
610
+ id: refId,
611
+ value: "123,456.79€"
612
+ });
613
+ send_queue.delete(refId);
614
+ await sandbox.dispatchEventInSandbox({
615
+ id: refId,
616
+ value: "223456.789",
617
+ name: "test2"
618
+ });
619
+ expect(send_queue.has(refId)).toEqual(true);
620
+ expect(send_queue.get(refId)).toEqual({
621
+ id: refId,
622
+ value: "$223456,8"
623
+ });
624
+ send_queue.delete(refId);
625
+ await sandbox.dispatchEventInSandbox({
626
+ id: refId,
627
+ value: "-323456.789",
628
+ name: "test3"
629
+ });
630
+ expect(send_queue.has(refId)).toEqual(true);
631
+ expect(send_queue.get(refId)).toEqual({
632
+ id: refId,
633
+ value: "323,456.79€",
634
+ textColor: ["RGB", 1, 0, 0]
635
+ });
636
+ send_queue.delete(refId);
637
+ await sandbox.dispatchEventInSandbox({
638
+ id: refId,
639
+ value: "-423456.789",
640
+ name: "test4"
641
+ });
642
+ expect(send_queue.has(refId)).toEqual(true);
643
+ expect(send_queue.get(refId)).toEqual({
644
+ id: refId,
645
+ value: "(423,456.79€)"
646
+ });
647
+ send_queue.delete(refId);
648
+ await sandbox.dispatchEventInSandbox({
649
+ id: refId,
650
+ value: "-52345.678",
651
+ name: "test5"
652
+ });
653
+ expect(send_queue.has(refId)).toEqual(true);
654
+ expect(send_queue.get(refId)).toEqual({
655
+ id: refId,
656
+ value: "(52,345.68€)",
657
+ textColor: ["RGB", 1, 0, 0]
658
+ });
659
+ done();
660
+ } catch (ex) {
661
+ done.fail(ex);
662
+ }
663
+ });
664
+ });
665
+ describe("AFNumber_Keystroke", function () {
666
+ it("should validate a number on a keystroke event", async function (done) {
667
+ const refId = getId();
668
+ const data = {
669
+ objects: {
670
+ field: [{
671
+ id: refId,
672
+ value: "",
673
+ actions: {
674
+ Validate: [`AFNumber_Keystroke(null, 0, null, null, null, null);`]
675
+ },
676
+ type: "text",
677
+ name: "MyField"
678
+ }]
679
+ },
680
+ appInfo: {
681
+ language: "en-US",
682
+ platform: "Linux x86_64"
683
+ },
684
+ calculationOrder: [],
685
+ dispatchEventName: "_dispatchMe"
686
+ };
687
+
688
+ try {
689
+ sandbox.createSandbox(data);
690
+ await sandbox.dispatchEventInSandbox({
691
+ id: refId,
692
+ value: "123456.789",
693
+ name: "Keystroke",
694
+ willCommit: true
695
+ });
696
+ expect(send_queue.has(refId)).toEqual(true);
697
+ expect(send_queue.get(refId)).toEqual({
698
+ id: refId,
699
+ value: "123456.789",
700
+ valueAsString: "123456.789"
701
+ });
702
+ done();
703
+ } catch (ex) {
704
+ done.fail(ex);
705
+ }
706
+ });
707
+ it("should not validate a number on a keystroke event", async function (done) {
708
+ const refId = getId();
709
+ const data = {
710
+ objects: {
711
+ field: [{
712
+ id: refId,
713
+ value: "",
714
+ actions: {
715
+ Validate: [`AFNumber_Keystroke(null, 0, null, null, null, null);`]
716
+ },
717
+ type: "text",
718
+ name: "MyField"
719
+ }]
720
+ },
721
+ appInfo: {
722
+ language: "en-US",
723
+ platform: "Linux x86_64"
724
+ },
725
+ calculationOrder: [],
726
+ dispatchEventName: "_dispatchMe"
727
+ };
728
+
729
+ try {
730
+ sandbox.createSandbox(data);
731
+ await sandbox.dispatchEventInSandbox({
732
+ id: refId,
733
+ value: "123s456.789",
734
+ name: "Keystroke",
735
+ willCommit: true
736
+ });
737
+ expect(send_queue.has("alert")).toEqual(true);
738
+ expect(send_queue.get("alert")).toEqual({
739
+ command: "alert",
740
+ value: "The value entered does not match the format of the field [ MyField ]"
741
+ });
742
+ done();
743
+ } catch (ex) {
744
+ done.fail(ex);
745
+ }
746
+ });
747
+ });
748
+ describe("AFPercent_Format", function () {
749
+ it("should format a percentage", async function (done) {
750
+ const refId = getId();
751
+ const data = {
752
+ objects: {
753
+ field: [{
754
+ id: refId,
755
+ value: "",
756
+ actions: {
757
+ test1: [`AFPercent_Format(2, 1, false);` + `event.source.value = event.value;`],
758
+ test2: [`AFPercent_Format(2, 1, true);` + `event.source.value = event.value;`]
759
+ },
760
+ type: "text"
761
+ }]
762
+ },
763
+ appInfo: {
764
+ language: "en-US",
765
+ platform: "Linux x86_64"
766
+ },
767
+ calculationOrder: [],
768
+ dispatchEventName: "_dispatchMe"
769
+ };
770
+
771
+ try {
772
+ sandbox.createSandbox(data);
773
+ await sandbox.dispatchEventInSandbox({
774
+ id: refId,
775
+ value: "0.456789",
776
+ name: "test1"
777
+ });
778
+ expect(send_queue.has(refId)).toEqual(true);
779
+ expect(send_queue.get(refId)).toEqual({
780
+ id: refId,
781
+ value: "45.68%"
782
+ });
783
+ send_queue.delete(refId);
784
+ await sandbox.dispatchEventInSandbox({
785
+ id: refId,
786
+ value: "0.456789",
787
+ name: "test2"
788
+ });
789
+ expect(send_queue.has(refId)).toEqual(true);
790
+ expect(send_queue.get(refId)).toEqual({
791
+ id: refId,
792
+ value: "%45.68"
793
+ });
794
+ done();
795
+ } catch (ex) {
796
+ done.fail(ex);
797
+ }
798
+ });
799
+ });
800
+ describe("AFDate_Format", function () {
801
+ it("should format a date", async function (done) {
802
+ const refId = getId();
803
+ const data = {
804
+ objects: {
805
+ field: [{
806
+ id: refId,
807
+ value: "",
808
+ actions: {
809
+ test1: [`AFDate_Format(0);event.source.value = event.value;`],
810
+ test2: [`AFDate_Format(12);event.source.value = event.value;`]
811
+ },
812
+ type: "text"
813
+ }]
814
+ },
815
+ appInfo: {
816
+ language: "en-US",
817
+ platform: "Linux x86_64"
818
+ },
819
+ calculationOrder: [],
820
+ dispatchEventName: "_dispatchMe"
821
+ };
822
+
823
+ try {
824
+ sandbox.createSandbox(data);
825
+ await sandbox.dispatchEventInSandbox({
826
+ id: refId,
827
+ value: "Sun Apr 15 2007 03:14:15",
828
+ name: "test1"
829
+ });
830
+ expect(send_queue.has(refId)).toEqual(true);
831
+ expect(send_queue.get(refId)).toEqual({
832
+ id: refId,
833
+ value: "4/15"
834
+ });
835
+ send_queue.delete(refId);
836
+ await sandbox.dispatchEventInSandbox({
837
+ id: refId,
838
+ value: "Sun Apr 15 2007 03:14:15",
839
+ name: "test2"
840
+ });
841
+ expect(send_queue.has(refId)).toEqual(true);
842
+ expect(send_queue.get(refId)).toEqual({
843
+ id: refId,
844
+ value: "4/15/07 3:14 am"
845
+ });
846
+ done();
847
+ } catch (ex) {
848
+ done.fail(ex);
849
+ }
850
+ });
851
+ });
852
+ describe("AFRange_Validate", function () {
853
+ it("should validate a number in range [a, b]", async function (done) {
854
+ const refId = getId();
855
+ const data = {
856
+ objects: {
857
+ field: [{
858
+ id: refId,
859
+ value: "",
860
+ actions: {
861
+ Validate: [`AFRange_Validate(true, 123, true, 456);`]
862
+ },
863
+ type: "text"
864
+ }]
865
+ },
866
+ appInfo: {
867
+ language: "en-US",
868
+ platform: "Linux x86_64"
869
+ },
870
+ calculationOrder: [],
871
+ dispatchEventName: "_dispatchMe"
872
+ };
873
+
874
+ try {
875
+ sandbox.createSandbox(data);
876
+ await sandbox.dispatchEventInSandbox({
877
+ id: refId,
878
+ value: "321",
879
+ name: "Keystroke",
880
+ willCommit: true
881
+ });
882
+ expect(send_queue.has(refId)).toEqual(true);
883
+ expect(send_queue.get(refId)).toEqual({
884
+ id: refId,
885
+ value: "321",
886
+ valueAsString: "321"
887
+ });
888
+ done();
889
+ } catch (ex) {
890
+ done.fail(ex);
891
+ }
892
+ });
893
+ it("should invalidate a number out of range [a, b]", async function (done) {
894
+ const refId = getId();
895
+ const data = {
896
+ objects: {
897
+ field: [{
898
+ id: refId,
899
+ value: "",
900
+ actions: {
901
+ Validate: [`AFRange_Validate(true, 123, true, 456);`]
902
+ },
903
+ type: "text"
904
+ }]
905
+ },
906
+ appInfo: {
907
+ language: "en-US",
908
+ platform: "Linux x86_64"
909
+ },
910
+ calculationOrder: [],
911
+ dispatchEventName: "_dispatchMe"
912
+ };
913
+
914
+ try {
915
+ sandbox.createSandbox(data);
916
+ await sandbox.dispatchEventInSandbox({
917
+ id: refId,
918
+ value: "12",
919
+ name: "Keystroke",
920
+ willCommit: true
921
+ });
922
+ expect(send_queue.has("alert")).toEqual(true);
923
+ expect(send_queue.get("alert")).toEqual({
924
+ command: "alert",
925
+ value: "Invalid value: must be greater than or equal to 123 and less than or equal to 456."
926
+ });
927
+ done();
928
+ } catch (ex) {
929
+ done.fail(ex);
930
+ }
931
+ });
932
+ });
933
+ describe("ASSimple_Calculate", function () {
934
+ it("should compute the sum of several fields", async function (done) {
935
+ const refIds = [0, 1, 2, 3].map(_ => getId());
936
+ const data = {
937
+ objects: {
938
+ field1: [{
939
+ id: refIds[0],
940
+ value: "",
941
+ actions: {},
942
+ type: "text"
943
+ }],
944
+ field2: [{
945
+ id: refIds[1],
946
+ value: "",
947
+ actions: {},
948
+ type: "text"
949
+ }],
950
+ field3: [{
951
+ id: refIds[2],
952
+ value: "",
953
+ actions: {},
954
+ type: "text"
955
+ }],
956
+ field4: [{
957
+ id: refIds[3],
958
+ value: "",
959
+ actions: {
960
+ Calculate: [`AFSimple_Calculate("SUM", ["field1", "field2", "field3"]);`]
961
+ },
962
+ type: "text"
963
+ }]
964
+ },
965
+ appInfo: {
966
+ language: "en-US",
967
+ platform: "Linux x86_64"
968
+ },
969
+ calculationOrder: [refIds[3]],
970
+ dispatchEventName: "_dispatchMe"
971
+ };
972
+
973
+ try {
974
+ sandbox.createSandbox(data);
975
+ await sandbox.dispatchEventInSandbox({
976
+ id: refIds[0],
977
+ value: "1",
978
+ name: "Keystroke",
979
+ willCommit: true
980
+ });
981
+ expect(send_queue.has(refIds[3])).toEqual(true);
982
+ expect(send_queue.get(refIds[3])).toEqual({
983
+ id: refIds[3],
984
+ value: 1,
985
+ valueAsString: "1"
986
+ });
987
+ await sandbox.dispatchEventInSandbox({
988
+ id: refIds[1],
989
+ value: "2",
990
+ name: "Keystroke",
991
+ willCommit: true
992
+ });
993
+ expect(send_queue.has(refIds[3])).toEqual(true);
994
+ expect(send_queue.get(refIds[3])).toEqual({
995
+ id: refIds[3],
996
+ value: 3,
997
+ valueAsString: "3"
998
+ });
999
+ await sandbox.dispatchEventInSandbox({
1000
+ id: refIds[2],
1001
+ value: "3",
1002
+ name: "Keystroke",
1003
+ willCommit: true
1004
+ });
1005
+ expect(send_queue.has(refIds[3])).toEqual(true);
1006
+ expect(send_queue.get(refIds[3])).toEqual({
1007
+ id: refIds[3],
1008
+ value: 6,
1009
+ valueAsString: "6"
1010
+ });
1011
+ done();
1012
+ } catch (ex) {
1013
+ done.fail(ex);
1014
+ }
1015
+ });
1016
+ });
1017
+ describe("AFSpecial_KeystrokeEx", function () {
1018
+ it("should validate a phone number on a keystroke event", async function (done) {
1019
+ const refId = getId();
1020
+ const data = {
1021
+ objects: {
1022
+ field: [{
1023
+ id: refId,
1024
+ value: "",
1025
+ actions: {
1026
+ Keystroke: [`AFSpecial_KeystrokeEx("9AXO");`]
1027
+ },
1028
+ type: "text"
1029
+ }]
1030
+ },
1031
+ appInfo: {
1032
+ language: "en-US",
1033
+ platform: "Linux x86_64"
1034
+ },
1035
+ calculationOrder: [],
1036
+ dispatchEventName: "_dispatchMe"
1037
+ };
1038
+
1039
+ try {
1040
+ sandbox.createSandbox(data);
1041
+ await sandbox.dispatchEventInSandbox({
1042
+ id: refId,
1043
+ value: "",
1044
+ change: "3",
1045
+ name: "Keystroke",
1046
+ willCommit: false,
1047
+ selStart: 0,
1048
+ selEnd: 0
1049
+ });
1050
+ expect(send_queue.has(refId)).toEqual(false);
1051
+ await sandbox.dispatchEventInSandbox({
1052
+ id: refId,
1053
+ value: "3",
1054
+ change: "F",
1055
+ name: "Keystroke",
1056
+ willCommit: false,
1057
+ selStart: 1,
1058
+ selEnd: 1
1059
+ });
1060
+ expect(send_queue.has(refId)).toEqual(false);
1061
+ await sandbox.dispatchEventInSandbox({
1062
+ id: refId,
1063
+ value: "3F",
1064
+ change: "?",
1065
+ name: "Keystroke",
1066
+ willCommit: false,
1067
+ selStart: 2,
1068
+ selEnd: 2
1069
+ });
1070
+ expect(send_queue.has(refId)).toEqual(false);
1071
+ await sandbox.dispatchEventInSandbox({
1072
+ id: refId,
1073
+ value: "3F?",
1074
+ change: "@",
1075
+ name: "Keystroke",
1076
+ willCommit: false,
1077
+ selStart: 3,
1078
+ selEnd: 3
1079
+ });
1080
+ expect(send_queue.has(refId)).toEqual(true);
1081
+ expect(send_queue.get(refId)).toEqual({
1082
+ id: refId,
1083
+ value: "3F?",
1084
+ selRange: [3, 3]
1085
+ });
1086
+ done();
1087
+ } catch (ex) {
1088
+ done.fail(ex);
1089
+ }
1090
+ });
1091
+ });
1092
+ describe("eMailValidate", function () {
1093
+ it("should validate an e-mail address", function (done) {
1094
+ Promise.all([myeval(`eMailValidate(123)`).then(value => {
1095
+ expect(value).toEqual(false);
1096
+ }), myeval(`eMailValidate("foo@bar.com")`).then(value => {
1097
+ expect(value).toEqual(true);
1098
+ }), myeval(`eMailValidate("foo bar")`).then(value => {
1099
+ expect(value).toEqual(false);
1100
+ })]).then(() => done());
1101
+ });
1102
+ });
1103
+ });
1104
+ });