@bnsights/bbsf-utilities 1.0.42 → 1.0.44

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.
Files changed (126) hide show
  1. package/README.md +87 -66
  2. package/bnsights-bbsf-utilities-1.0.44.tgz +0 -0
  3. package/{esm2020 → esm2022}/bnsights-bbsf-utilities.mjs +4 -4
  4. package/{esm2020 → esm2022}/lib/bbsf-utilities.module.mjs +59 -59
  5. package/esm2022/lib/shared/authentication/auth.service.mjs +211 -0
  6. package/{esm2020 → esm2022}/lib/shared/authentication/index.mjs +1 -1
  7. package/{esm2020 → esm2022}/lib/shared/config/environment.mjs +11 -11
  8. package/{esm2020 → esm2022}/lib/shared/config/word/constants.mjs +104 -104
  9. package/{esm2020 → esm2022}/lib/shared/config/word/docx-document.mjs +347 -347
  10. package/{esm2020 → esm2022}/lib/shared/config/word/helpers/index.mjs +3 -3
  11. package/{esm2020 → esm2022}/lib/shared/config/word/helpers/render-document-file.mjs +153 -153
  12. package/{esm2020 → esm2022}/lib/shared/config/word/helpers/xml-builder.mjs +1835 -1835
  13. package/{esm2020 → esm2022}/lib/shared/config/word/html-to-docx.mjs +186 -186
  14. package/{esm2020 → esm2022}/lib/shared/config/word/index.mjs +49 -49
  15. package/{esm2020 → esm2022}/lib/shared/config/word/namespaces.mjs +36 -36
  16. package/{esm2020 → esm2022}/lib/shared/config/word/schemas/content-types.mjs +2 -2
  17. package/{esm2020 → esm2022}/lib/shared/config/word/schemas/core.mjs +6 -6
  18. package/{esm2020 → esm2022}/lib/shared/config/word/schemas/document-rels.mjs +3 -3
  19. package/{esm2020 → esm2022}/lib/shared/config/word/schemas/document.template.mjs +17 -17
  20. package/{esm2020 → esm2022}/lib/shared/config/word/schemas/font-table.mjs +3 -3
  21. package/{esm2020 → esm2022}/lib/shared/config/word/schemas/generic-rels.mjs +2 -2
  22. package/{esm2020 → esm2022}/lib/shared/config/word/schemas/index.mjs +12 -12
  23. package/{esm2020 → esm2022}/lib/shared/config/word/schemas/numbering.mjs +3 -3
  24. package/{esm2020 → esm2022}/lib/shared/config/word/schemas/rels.mjs +3 -3
  25. package/{esm2020 → esm2022}/lib/shared/config/word/schemas/settings.mjs +3 -3
  26. package/{esm2020 → esm2022}/lib/shared/config/word/schemas/styles.mjs +4 -4
  27. package/{esm2020 → esm2022}/lib/shared/config/word/schemas/theme.mjs +3 -3
  28. package/{esm2020 → esm2022}/lib/shared/config/word/schemas/web-settings.mjs +3 -3
  29. package/{esm2020 → esm2022}/lib/shared/config/word/utils/color-conversion.mjs +59 -59
  30. package/{esm2020 → esm2022}/lib/shared/config/word/utils/list.mjs +50 -50
  31. package/{esm2020 → esm2022}/lib/shared/config/word/utils/unit-conversion.mjs +29 -29
  32. package/{esm2020 → esm2022}/lib/shared/config/word/utils/url.mjs +6 -6
  33. package/{esm2020 → esm2022}/lib/shared/config/word/utils/vnode.mjs +2 -2
  34. package/{esm2020 → esm2022}/lib/shared/config/word/word-work/templates/documentTemplate.mjs +12 -12
  35. package/{esm2020 → esm2022}/lib/shared/config/word/word-work/templates/index.mjs +3 -3
  36. package/{esm2020 → esm2022}/lib/shared/config/word/word-work/templates/mhtDocumentTemplate.mjs +4 -4
  37. package/{esm2020 → esm2022}/lib/shared/config/word/word-work/templates/mhtPartTemplate.mjs +3 -3
  38. package/{esm2020 → esm2022}/lib/shared/config/word/word-work/utils.mjs +25 -25
  39. package/{esm2020 → esm2022}/lib/shared/enums/authentication-modes-enums.mjs +7 -7
  40. package/{esm2020 → esm2022}/lib/shared/index.mjs +3 -3
  41. package/{esm2020 → esm2022}/lib/shared/models/UserModel.mjs +2 -2
  42. package/{esm2020 → esm2022}/lib/shared/models/area-model.mjs +2 -2
  43. package/{esm2020 → esm2022}/lib/shared/models/error-model.mjs +2 -2
  44. package/{esm2020 → esm2022}/lib/shared/models/index.mjs +4 -4
  45. package/{esm2020 → esm2022}/lib/shared/models/request-options-model.mjs +10 -10
  46. package/{esm2020 → esm2022}/lib/shared/models/word-document-model.mjs +7 -7
  47. package/{esm2020 → esm2022}/lib/shared/services/appearance-configuration.service.mjs +35 -35
  48. package/esm2022/lib/shared/services/configuration.service.mjs +24 -0
  49. package/{esm2020 → esm2022}/lib/shared/services/control-validation.service.mjs +173 -173
  50. package/esm2022/lib/shared/services/environment.service.mjs +75 -0
  51. package/{esm2020 → esm2022}/lib/shared/services/index.mjs +11 -11
  52. package/{esm2020 → esm2022}/lib/shared/services/master-layout.service.mjs +72 -72
  53. package/{esm2020 → esm2022}/lib/shared/services/request-handler.service.mjs +219 -199
  54. package/{esm2020 → esm2022}/lib/shared/services/styles-bundle.service.mjs +55 -55
  55. package/{esm2020 → esm2022}/lib/shared/services/translate.service.mjs +14 -14
  56. package/{esm2020 → esm2022}/lib/shared/services/translation-resolver.service.mjs +6 -6
  57. package/{esm2020 → esm2022}/lib/shared/services/utility.service.mjs +87 -87
  58. package/{esm2020 → esm2022}/lib/shared/services/word-document.service.mjs +38 -38
  59. package/{esm2020 → esm2022}/public-api.mjs +29 -29
  60. package/{fesm2020 → fesm2022}/bnsights-bbsf-utilities.mjs +3856 -3836
  61. package/fesm2022/bnsights-bbsf-utilities.mjs.map +1 -0
  62. package/index.d.ts +5 -5
  63. package/lib/bbsf-utilities.module.d.ts +10 -10
  64. package/lib/shared/authentication/auth.service.d.ts +52 -52
  65. package/lib/shared/authentication/index.d.ts +1 -1
  66. package/lib/shared/config/environment.d.ts +1 -1
  67. package/lib/shared/config/word/constants.d.ts +124 -124
  68. package/lib/shared/config/word/docx-document.d.ts +73 -73
  69. package/lib/shared/config/word/helpers/index.d.ts +1 -1
  70. package/lib/shared/config/word/helpers/render-document-file.d.ts +2 -2
  71. package/lib/shared/config/word/helpers/xml-builder.d.ts +16 -16
  72. package/lib/shared/config/word/html-to-docx.d.ts +1 -1
  73. package/lib/shared/config/word/index.d.ts +1 -1
  74. package/lib/shared/config/word/namespaces.d.ts +36 -36
  75. package/lib/shared/config/word/schemas/content-types.d.ts +1 -1
  76. package/lib/shared/config/word/schemas/core.d.ts +1 -1
  77. package/lib/shared/config/word/schemas/document-rels.d.ts +1 -1
  78. package/lib/shared/config/word/schemas/document.template.d.ts +4 -4
  79. package/lib/shared/config/word/schemas/font-table.d.ts +1 -1
  80. package/lib/shared/config/word/schemas/generic-rels.d.ts +1 -1
  81. package/lib/shared/config/word/schemas/index.d.ts +12 -12
  82. package/lib/shared/config/word/schemas/numbering.d.ts +1 -1
  83. package/lib/shared/config/word/schemas/rels.d.ts +1 -1
  84. package/lib/shared/config/word/schemas/settings.d.ts +1 -1
  85. package/lib/shared/config/word/schemas/styles.d.ts +1 -1
  86. package/lib/shared/config/word/schemas/theme.d.ts +1 -1
  87. package/lib/shared/config/word/schemas/web-settings.d.ts +1 -1
  88. package/lib/shared/config/word/utils/color-conversion.d.ts +7 -7
  89. package/lib/shared/config/word/utils/list.d.ts +6 -6
  90. package/lib/shared/config/word/utils/unit-conversion.d.ts +29 -29
  91. package/lib/shared/config/word/utils/url.d.ts +1 -1
  92. package/lib/shared/config/word/utils/vnode.d.ts +1 -1
  93. package/lib/shared/config/word/word-work/templates/documentTemplate.d.ts +12 -12
  94. package/lib/shared/config/word/word-work/templates/index.d.ts +3 -3
  95. package/lib/shared/config/word/word-work/templates/mhtDocumentTemplate.d.ts +1 -1
  96. package/lib/shared/config/word/word-work/templates/mhtPartTemplate.d.ts +1 -1
  97. package/lib/shared/config/word/word-work/utils.d.ts +1 -1
  98. package/lib/shared/enums/authentication-modes-enums.d.ts +6 -6
  99. package/lib/shared/index.d.ts +3 -3
  100. package/lib/shared/models/UserModel.d.ts +6 -6
  101. package/lib/shared/models/area-model.d.ts +4 -4
  102. package/lib/shared/models/error-model.d.ts +5 -5
  103. package/lib/shared/models/index.d.ts +4 -4
  104. package/lib/shared/models/request-options-model.d.ts +11 -11
  105. package/lib/shared/models/word-document-model.d.ts +16 -16
  106. package/lib/shared/services/appearance-configuration.service.d.ts +14 -14
  107. package/lib/shared/services/configuration.service.d.ts +10 -10
  108. package/lib/shared/services/control-validation.service.d.ts +23 -23
  109. package/lib/shared/services/environment.service.d.ts +25 -25
  110. package/lib/shared/services/index.d.ts +11 -11
  111. package/lib/shared/services/master-layout.service.d.ts +24 -24
  112. package/lib/shared/services/request-handler.service.d.ts +35 -33
  113. package/lib/shared/services/styles-bundle.service.d.ts +12 -12
  114. package/lib/shared/services/translate.service.d.ts +6 -6
  115. package/lib/shared/services/translation-resolver.service.d.ts +2 -2
  116. package/lib/shared/services/utility.service.d.ts +23 -23
  117. package/lib/shared/services/word-document.service.d.ts +8 -8
  118. package/package.json +28 -29
  119. package/public-api.d.ts +17 -17
  120. package/bnsights-bbsf-utilities-1.0.42.tgz +0 -0
  121. package/esm2020/lib/shared/authentication/auth.service.mjs +0 -211
  122. package/esm2020/lib/shared/services/configuration.service.mjs +0 -24
  123. package/esm2020/lib/shared/services/environment.service.mjs +0 -75
  124. package/fesm2015/bnsights-bbsf-utilities.mjs +0 -4555
  125. package/fesm2015/bnsights-bbsf-utilities.mjs.map +0 -1
  126. package/fesm2020/bnsights-bbsf-utilities.mjs.map +0 -1
@@ -1,4555 +0,0 @@
1
- import { DOCUMENT, CommonModule } from '@angular/common';
2
- import * as i0 from '@angular/core';
3
- import { Injectable, Inject, inject, NgModule } from '@angular/core';
4
- import * as i1$1 from '@angular/router';
5
- import { RouterModule } from '@angular/router';
6
- import * as i4 from '@ngx-translate/core';
7
- import { TranslateService } from '@ngx-translate/core';
8
- import * as i1$2 from 'ng-block-ui';
9
- import { BlockUI, BlockUIModule } from 'ng-block-ui';
10
- import * as i2 from 'ngx-toastr';
11
- import { ToastrService, ToastrModule } from 'ngx-toastr';
12
- import * as i4$1 from 'ngx-cookie-service';
13
- import { CookieService } from 'ngx-cookie-service';
14
- import { __decorate, __awaiter, __rest } from 'tslib';
15
- import * as i1 from '@angular/common/http';
16
- import { HttpParams, HttpHeaders } from '@angular/common/http';
17
- import { Subject, Observable, throwError, BehaviorSubject } from 'rxjs';
18
- import { JwtHelperService } from '@auth0/angular-jwt';
19
- import { plainToClass } from 'class-transformer';
20
- import { takeUntil, tap, map } from 'rxjs/operators';
21
- import JSZip from 'jszip';
22
- import { fragment, create } from 'xmlbuilder2';
23
- import VNode$1 from 'virtual-dom/vnode/vnode';
24
- import VText from 'virtual-dom/vnode/vtext';
25
- import HTMLToVDOM from 'html-to-vdom';
26
- import { cloneDeep } from 'lodash';
27
- import { nanoid } from 'nanoid';
28
- import isVNode from 'virtual-dom/vnode/is-vnode';
29
- import isVText from 'virtual-dom/vnode/is-vtext';
30
- import escape from 'escape-html';
31
- import colorNames from 'color-name';
32
- import imageToBase64 from 'image-to-base64';
33
- import mimeTypes from 'mime-types';
34
- import sizeOf from 'image-size';
35
-
36
- class User {
37
- }
38
-
39
- var AuthenticationModes;
40
- (function (AuthenticationModes) {
41
- AuthenticationModes["Forms"] = "Forms";
42
- AuthenticationModes["UAEPass"] = "UAEPass";
43
- AuthenticationModes["WindowsAD"] = "WindowsAD";
44
- AuthenticationModes["AzureAD"] = "AzureAD";
45
- })(AuthenticationModes || (AuthenticationModes = {}));
46
-
47
- class AppearanceConfigurationService {
48
- constructor(configService) {
49
- this.configService = configService;
50
- }
51
- getLayoutTheme() {
52
- return this.configService.getConfigurationValue('AnonymousLayout_Theme');
53
- }
54
- getFooterText() {
55
- return this.configService.getConfigurationValue('AnonymousLayout_FooterText');
56
- }
57
- getPageTitle() {
58
- return this.configService.getConfigurationValue('AnonymousLayout_PageTitle');
59
- }
60
- getFavIcon() {
61
- return this.configService.getConfigurationValue('AnonymousLayout_FavIcon');
62
- }
63
- getCustomStyles() {
64
- return this.configService.getConfigurationValue('AnonymousLayout_CustomStyles');
65
- }
66
- getLogo() {
67
- return this.configService.getConfigurationValue('AnonymousLayout_Logo');
68
- }
69
- }
70
- AppearanceConfigurationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AppearanceConfigurationService, deps: [{ token: ConfigurationService }], target: i0.ɵɵFactoryTarget.Injectable });
71
- AppearanceConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AppearanceConfigurationService, providedIn: 'root' });
72
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AppearanceConfigurationService, decorators: [{
73
- type: Injectable,
74
- args: [{
75
- providedIn: 'root'
76
- }]
77
- }], ctorParameters: function () { return [{ type: ConfigurationService }]; } });
78
-
79
- class ConfigurationService {
80
- constructor(httpClient) {
81
- this.httpClient = httpClient;
82
- this.httpClient.get("./assets/config/configurations.json").subscribe(data => {
83
- ConfigurationService.JsonData = data;
84
- });
85
- }
86
- getConfigurationValue(key) {
87
- return ConfigurationService.JsonData[key];
88
- }
89
- }
90
- ConfigurationService.JsonData = [];
91
- ConfigurationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ConfigurationService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
92
- ConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ConfigurationService, providedIn: 'root' });
93
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ConfigurationService, decorators: [{
94
- type: Injectable,
95
- args: [{
96
- providedIn: 'root'
97
- }]
98
- }], ctorParameters: function () { return [{ type: i1.HttpClient }]; } });
99
-
100
- class AreaModel {
101
- }
102
-
103
- class ErrorModel {
104
- }
105
-
106
- class RequestOptionsModel {
107
- constructor() {
108
- this.disableSuccessNotification = false;
109
- this.disableBlockUI = false;
110
- this.disableErrorHandler = false;
111
- this.responseType = "";
112
- this.formGroup = null;
113
- this.castResponsetoClass = true;
114
- }
115
- }
116
-
117
- class WordDocumentModel {
118
- constructor() {
119
- this.options = new DocumentOptionsModel();
120
- }
121
- }
122
- class DocumentOptionsModel {
123
- }
124
-
125
- class ControlValidationService {
126
- constructor(utilityService) {
127
- this.utilityService = utilityService;
128
- this.requestOptions = new RequestOptionsModel();
129
- this.isCreatedBefor = false;
130
- }
131
- showGlobalError(errorMessage, formId, deleteOld) {
132
- let globalErorrElement = document.getElementsByClassName('alert alert-InvalidValidation bg-light-danger text-danger');
133
- if (globalErorrElement.length > 0) {
134
- this.removeElementsByClass('alert alert-InvalidValidation bg-light-danger text-danger');
135
- }
136
- if (this.isCreatedBefor == true) {
137
- this.removeElementsByClass('alert alert-InvalidValidation bg-light-danger text-danger');
138
- }
139
- // tslint:disable-next-line: prefer-const
140
- if (!formId)
141
- formId = "currentForm";
142
- var object = document.getElementById(formId);
143
- const tagName = 'div';
144
- // tslint:disable-next-line: prefer-const
145
- var elementToAppend = document.createElement(tagName); // Your tag name here
146
- let message = "";
147
- if (!errorMessage || (typeof errorMessage == "string")) {
148
- if (localStorage.getItem('language') == "ar")
149
- message = errorMessage ? errorMessage : "لديك بعص الأخطاء . من فضلك قم بالمراجعه ";
150
- else
151
- message = errorMessage ? errorMessage : "You have some validation errors. Please check below";
152
- elementToAppend.innerHTML = "<ul class='list-unstyled m-0 py-3 d-flex align-items-center fs-6'><li><i class='fa fa-times-circle text-danger me-3 fs-2'></i>" + message + "</li></ul>";
153
- elementToAppend.className += 'alert alert-InvalidValidation bg-light-danger text-danger';
154
- elementToAppend.id += 'errorId';
155
- // tslint:disable-next-line: prefer-for-of
156
- const elementToAppen = elementToAppend.cloneNode(true);
157
- // let targetElement = object.getElementsByClassName("b-control")[0];
158
- object.insertBefore(elementToAppen, object.firstChild);
159
- }
160
- else {
161
- let ul = document.createElement("ul");
162
- elementToAppend.appendChild(ul);
163
- for (const iterator of errorMessage) {
164
- let li = document.createElement("li");
165
- li.innerHTML = iterator;
166
- ul.appendChild(li);
167
- }
168
- elementToAppend.className += 'alert alert-InvalidValidation bg-light-danger text-danger';
169
- elementToAppend.id += 'errorId';
170
- // tslint:disable-next-line: prefer-for-of
171
- const elementToAppen = elementToAppend.cloneNode(true);
172
- // let targetElement = object.getElementsByClassName("b-control")[0];
173
- object.insertBefore(elementToAppen, object.firstChild);
174
- }
175
- this.isCreatedBefor = true;
176
- }
177
- removeGlobalError() {
178
- const removedList = document.getElementsByClassName('alert alert-InvalidValidation bg-light-danger text-danger');
179
- // tslint:disable-next-line: prefer-for-of
180
- for (let index = 0; index < removedList.length; index++) {
181
- const element = removedList[index];
182
- element.remove();
183
- }
184
- this.isCreatedBefor = false;
185
- }
186
- showInputErro(errors) {
187
- // show error on top of form
188
- this.showGlobalError();
189
- // remove old error from server
190
- this.removeElementsByClass('errortemplet');
191
- // Looping in error Object
192
- for (const key in errors) {
193
- if (errors.hasOwnProperty(key)) {
194
- for (const iterator of errors[key]) {
195
- const input = document.querySelectorAll('[ng-reflect-name=' + key + ']')[0];
196
- if (input.attributes['ng-reflect-name'].value === key) {
197
- this.removeElementsByClass('erroclass-' + key);
198
- const tagName = 'p';
199
- const elementToAppend = document.createElement(tagName); // Your tag name here
200
- elementToAppend.innerHTML = iterator;
201
- elementToAppend.style.color = 'red';
202
- elementToAppend.className += 'errortemplet erroclass-' + key;
203
- const elementToappen = elementToAppend.cloneNode(true);
204
- input.parentNode.insertBefore(elementToappen, input.lastChild);
205
- break;
206
- }
207
- }
208
- }
209
- }
210
- }
211
- removeElementsByClass(className) {
212
- const elements = document.getElementsByClassName(className);
213
- while (elements.length > 0) {
214
- elements[0].parentNode.removeChild(elements[0]);
215
- }
216
- }
217
- renderServerErrors(form, err, requestOptions, formId) {
218
- if (err.error == null) {
219
- return;
220
- }
221
- let errorsArray = [];
222
- this.requestOptions = requestOptions;
223
- if (err.error.validation_errors) {
224
- err.error.validation_errors.forEach((element) => {
225
- let fieldName = element.field;
226
- let controlName = element.controlName;
227
- let message = element.message;
228
- if (form == null) {
229
- this.requestOptions.customErrorMessage ? this.utilityService.notifyErrorMessage(this.requestOptions.customErrorMessage) : this.utilityService.notifyErrorMessage(`${message}`);
230
- }
231
- else if (controlName && !this.hasControlName(form, controlName)) {
232
- errorsArray.push(`${fieldName}: ${message}`);
233
- }
234
- else {
235
- this.setFieldError(form, controlName, fieldName, message);
236
- this.showGlobalError(null, formId);
237
- }
238
- });
239
- if (errorsArray.length > 0)
240
- this.showGlobalError(errorsArray, formId);
241
- }
242
- }
243
- hasControlName(form, controlName) {
244
- let control = form.get(controlName);
245
- return control != null;
246
- }
247
- setFieldError(form, controlName, fieldName, message) {
248
- let control = null;
249
- if (controlName)
250
- control = this.getControlFormNameByFieldName(form, controlName);
251
- else
252
- control = this.getControlFormNameByFieldName(form, fieldName.split('.')[0]);
253
- let errors = { "errorMassage": message };
254
- let fieldNameArray = fieldName.split('.');
255
- if (fieldNameArray.length >= 1) {
256
- switch (fieldNameArray[fieldNameArray.length - 1].toLocaleLowerCase()) {
257
- case "english":
258
- let englishControl = control.get("English");
259
- englishControl.setErrors(errors);
260
- break;
261
- case "arabic":
262
- let arabicControl = control.get("Arabic");
263
- arabicControl.setErrors(errors);
264
- break;
265
- default:
266
- control.setErrors(errors);
267
- }
268
- }
269
- else {
270
- this.requestOptions.customErrorMessage ? this.utilityService.notifyErrorMessage(this.requestOptions.customErrorMessage) : this.utilityService.notifyErrorMessage(`${message}`);
271
- }
272
- }
273
- getControlFormNameByFieldName(form, fieldName) {
274
- const formControls = form.controls;
275
- let controlName = Object.keys(formControls).find(c => c.toLocaleLowerCase() === fieldName.toLocaleLowerCase());
276
- let control = form.get(controlName);
277
- return control;
278
- }
279
- }
280
- ControlValidationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ControlValidationService, deps: [{ token: UtilityService }], target: i0.ɵɵFactoryTarget.Injectable });
281
- ControlValidationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ControlValidationService, providedIn: 'root' });
282
- __decorate([
283
- BlockUI()
284
- ], ControlValidationService.prototype, "blockUI", void 0);
285
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ControlValidationService, decorators: [{
286
- type: Injectable,
287
- args: [{
288
- providedIn: 'root'
289
- }]
290
- }], ctorParameters: function () { return [{ type: UtilityService }]; }, propDecorators: { blockUI: [] } });
291
-
292
- // This file can be replaced during build by using the `fileReplacements` array.
293
- // `ng build ---prod` replaces `environment.ts` with `environment.prod.ts`.
294
- // The list of file replacements can be found in `angular.json`.
295
- const environment = Object.assign({}, window.Environment);
296
- /*
297
- * In development mode, to ignore zone related error stack frames such as
298
- * `zone.run`, `zoneDelegate.invokeTask` for easier debugging, you can
299
- * import the following file, but please comment it out in production mode
300
- * because it will have performance impact when throw error
301
- */
302
- // import 'zone.js/dist/zone-error'; // Included with Angular CLI.
303
-
304
- class EnvironmentService {
305
- getEnvironmentObject() {
306
- return environment;
307
- }
308
- getBaseUrl() {
309
- return environment["BBSF_BaseURL"];
310
- }
311
- getApiUrl() {
312
- return environment["BBSF_ApiUrl"];
313
- }
314
- getProductionMode() {
315
- return environment["BBSF_IsProduction"];
316
- }
317
- getDefaultLanguage() {
318
- return environment["BBSF_DefaultLanguage"];
319
- }
320
- getIdentityServerUrl() {
321
- return environment["BBSF_IdentityServerUrl"];
322
- }
323
- getIsIdentityServerExternal() {
324
- return environment["BBSF_IsExternalIdentityServer"];
325
- }
326
- getIsIdentityServerClientId() {
327
- return environment["BBSF_IdentityServer_Client_Id"];
328
- }
329
- getIsIdentityServerClientSecret() {
330
- return environment["BBSF_IdentityServer_Client_Secret"];
331
- }
332
- getBBSFAuthenticationMode() {
333
- let Mode = environment["BBSF_AuthenticationMode"];
334
- return Mode;
335
- }
336
- getUAEPassBaseUrl() {
337
- let Mode = environment["UAEPass_BaseUrl"];
338
- return Mode;
339
- }
340
- getUAEPassClientID() {
341
- let Mode = environment["UAEPass_ClientID"];
342
- return Mode;
343
- }
344
- getUAEPassRedirectUrl() {
345
- let Mode = environment["UAEPass_RedirectUrl"];
346
- return Mode;
347
- }
348
- getUAEPassAuthorizationEndPoint() {
349
- let Mode = environment["UAEPass_AuthorizationEndPoint"];
350
- return Mode;
351
- }
352
- getUAEPassRedirectLogoutUrl() {
353
- let Mode = environment["UAEPass_RedirectLogoutUrl"];
354
- return Mode;
355
- }
356
- getUAEPassLogoutEndPoint() {
357
- let Mode = environment["UAEPass_LogoutEndPoint"];
358
- return Mode;
359
- }
360
- getIsEnableWindowsAuthentication() {
361
- let Mode = environment["BBSF_Enable_WindowsAuthentication"];
362
- return Mode.toLocaleLowerCase() == 'true';
363
- }
364
- }
365
- EnvironmentService.areaList = [];
366
- EnvironmentService.AreaList = [];
367
- EnvironmentService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: EnvironmentService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
368
- EnvironmentService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: EnvironmentService, providedIn: 'root' });
369
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: EnvironmentService, decorators: [{
370
- type: Injectable,
371
- args: [{
372
- providedIn: 'root'
373
- }]
374
- }] });
375
-
376
- class MasterLayoutService {
377
- constructor(router, http, authService, stylesBundleService, translate, environmentService) {
378
- this.router = router;
379
- this.http = http;
380
- this.authService = authService;
381
- this.stylesBundleService = stylesBundleService;
382
- this.translate = translate;
383
- this.environmentService = environmentService;
384
- this.apiUrl = '/api/Home/';
385
- }
386
- switchLang(lang, bundleEnglishName, bundleArabicName) {
387
- this.changeLanguage(lang).subscribe((result) => {
388
- this.updateUserInfo().subscribe((Value) => {
389
- let UserInfoObject = Value;
390
- this.authService.handleAccessToken(UserInfoObject.token);
391
- this.stylesBundleService.loadThemes(lang, bundleEnglishName, bundleArabicName);
392
- localStorage.setItem('language', lang);
393
- this.translate.use(lang);
394
- });
395
- });
396
- }
397
- reloadComponent() {
398
- let currentUrl = this.router.url;
399
- this.router.routeReuseStrategy.shouldReuseRoute = () => false;
400
- this.router.onSameUrlNavigation = 'reload';
401
- this.router.navigate([currentUrl]);
402
- }
403
- changeLanguage(key) {
404
- let params = new HttpParams();
405
- params = params.append('UserId', this.authService.user.profile.id);
406
- params = params.append('LanguageKey', key);
407
- return this.http.post(this.apiUrl + 'UpdateLanguage', null, null, params);
408
- }
409
- logError(error) {
410
- let params = new HttpParams();
411
- params = params.append('error', error);
412
- return this.http.post(this.apiUrl + 'LogError', null, null, params);
413
- }
414
- updateUserInfo() {
415
- return this.http.get(this.apiUrl + 'UpdateUserInfo', null, null);
416
- }
417
- switchRole(permissionSetID) {
418
- this.updateRole(permissionSetID).subscribe((result) => {
419
- this.updateUserInfo().subscribe((Value) => {
420
- let UserInfoObject = Value;
421
- this.authService.handleAccessToken(UserInfoObject.token);
422
- });
423
- });
424
- }
425
- updateRole(permissionSetID) {
426
- let params = new HttpParams();
427
- params = params.append('UserId', this.authService.user.profile.id);
428
- params = params.append('RoleID', permissionSetID);
429
- return this.http.post(this.apiUrl + 'SwitchRole', null, null, params);
430
- }
431
- }
432
- MasterLayoutService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MasterLayoutService, deps: [{ token: i1$1.Router }, { token: RequestHandlerService }, { token: AuthService }, { token: StylesBundleService }, { token: i4.TranslateService }, { token: EnvironmentService }], target: i0.ɵɵFactoryTarget.Injectable });
433
- MasterLayoutService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MasterLayoutService, providedIn: 'root' });
434
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MasterLayoutService, decorators: [{
435
- type: Injectable,
436
- args: [{
437
- providedIn: 'root',
438
- }]
439
- }], ctorParameters: function () { return [{ type: i1$1.Router }, { type: RequestHandlerService }, { type: AuthService }, { type: StylesBundleService }, { type: i4.TranslateService }, { type: EnvironmentService }]; } });
440
-
441
- class RequestHandlerService {
442
- constructor(http, authService, environmentService, utilityService, bbsfTranslateService, router) {
443
- this.http = http;
444
- this.authService = authService;
445
- this.environmentService = environmentService;
446
- this.utilityService = utilityService;
447
- this.bbsfTranslateService = bbsfTranslateService;
448
- this.router = router;
449
- this.requestOptions = new RequestOptionsModel();
450
- this.currentLanguage = "";
451
- this.onDestroy$ = new Subject();
452
- //using localStorage to avoid call getCurrentLanguage() because it is not all to use async in constructor
453
- this.bbsfTranslateService.onLangChange.subscribe((event) => {
454
- if (this.currentLanguage != event.lang) {
455
- this.currentLanguage = event.lang;
456
- }
457
- });
458
- }
459
- getLuckyNumber() {
460
- return Observable.create((subject) => {
461
- setInterval(() => {
462
- const number = Math.floor(Math.random() * 10);
463
- console.log(number);
464
- subject.next(number);
465
- }, 1000);
466
- }).pipe(takeUntil(this.onDestroy$));
467
- }
468
- get(Url, params, responseType, requestOptions) {
469
- if (requestOptions)
470
- this.requestOptions = requestOptions;
471
- let headers = this.getHeaders();
472
- if (!this.requestOptions.disableBlockUI)
473
- this.utilityService.startBlockUI();
474
- return this.http.get(this.environmentService.getApiUrl() + Url, { headers: headers, params: params }).pipe(takeUntil(this.onDestroy$), tap((result) => {
475
- if (!this.requestOptions.disableBlockUI)
476
- this.utilityService.stopBlockUI();
477
- }, error => {
478
- if (!this.requestOptions.disableErrorHandler)
479
- this.handleError(error);
480
- }), map((data) => {
481
- if (this.requestOptions.castResponsetoClass)
482
- return plainToClass(responseType, data, { excludeExtraneousValues: true });
483
- else
484
- return data;
485
- }));
486
- }
487
- post(Url, model, responseType, params, requestOptions) {
488
- if (requestOptions)
489
- this.requestOptions = requestOptions;
490
- let headers = this.getHeaders();
491
- if (!this.requestOptions.disableBlockUI)
492
- this.utilityService.startBlockUI();
493
- return this.http.post(this.environmentService.getApiUrl() + Url, model, { headers: headers, params: params, responseType: this.requestOptions.responseType }).pipe(takeUntil(this.onDestroy$), tap((result) => {
494
- if (!this.requestOptions.disableBlockUI)
495
- this.utilityService.stopBlockUI();
496
- }, error => {
497
- if (!this.requestOptions.disableErrorHandler)
498
- this.handleError(error);
499
- }), map((data) => {
500
- if (this.requestOptions.castResponsetoClass)
501
- return plainToClass(responseType, data, { excludeExtraneousValues: true });
502
- else
503
- return data;
504
- }));
505
- }
506
- delete(Url, deletedId, requestOptions, responseType, params) {
507
- if (requestOptions)
508
- this.requestOptions = requestOptions;
509
- let headers = this.getHeaders();
510
- if (!this.requestOptions.disableBlockUI)
511
- this.utilityService.startBlockUI();
512
- return this.http.delete(this.environmentService.getApiUrl() + Url + `/${deletedId}`, { headers: headers, params: params }).pipe(takeUntil(this.onDestroy$), tap((result) => {
513
- if (!this.requestOptions.disableBlockUI)
514
- this.utilityService.stopBlockUI();
515
- }, error => {
516
- if (!this.requestOptions.disableErrorHandler)
517
- this.handleError(error);
518
- }), map((data) => {
519
- if (this.requestOptions.castResponsetoClass)
520
- return plainToClass(responseType, data, { excludeExtraneousValues: true });
521
- else
522
- return data;
523
- }));
524
- }
525
- put(Url, model, params, responseType, requestOptions) {
526
- if (requestOptions)
527
- this.requestOptions = requestOptions;
528
- let headers = this.getHeaders();
529
- if (!this.requestOptions.disableBlockUI)
530
- this.utilityService.startBlockUI();
531
- return this.http.put(this.environmentService.getApiUrl() + Url, model, { headers: headers, params: params, responseType: this.requestOptions.responseType }).pipe(takeUntil(this.onDestroy$), tap((result) => {
532
- if (!this.requestOptions.disableBlockUI)
533
- this.utilityService.stopBlockUI();
534
- }, error => {
535
- if (!this.requestOptions.disableErrorHandler)
536
- this.handleError(error);
537
- }), map((data) => {
538
- if (this.requestOptions.castResponsetoClass)
539
- return plainToClass(responseType, data, { excludeExtraneousValues: true });
540
- else
541
- return data;
542
- }));
543
- }
544
- patch(Url, model, responseType, params, requestOptions) {
545
- if (requestOptions)
546
- this.requestOptions = requestOptions;
547
- let headers = new HttpHeaders({
548
- 'Content-Type': 'application/json',
549
- 'Authorization': this.authService.authorizationHeaderValue(),
550
- });
551
- this.currentLanguage = localStorage.getItem('language');
552
- headers = headers.set('Accept-Language', this.currentLanguage.toString());
553
- headers = headers.set('ignore-cookies', 'true');
554
- if (!this.requestOptions.disableBlockUI)
555
- this.utilityService.startBlockUI();
556
- return this.http.patch(this.environmentService.getApiUrl() + Url, model, { headers: headers, params: params, responseType: this.requestOptions.responseType }).pipe(takeUntil(this.onDestroy$), tap((result) => {
557
- if (!this.requestOptions.disableBlockUI)
558
- this.utilityService.stopBlockUI();
559
- }, error => {
560
- if (!this.requestOptions.disableErrorHandler)
561
- this.handleError(error);
562
- }), map((data) => {
563
- if (this.requestOptions.castResponsetoClass)
564
- return plainToClass(responseType, data, { excludeExtraneousValues: true });
565
- else
566
- return data;
567
- }));
568
- }
569
- download(Url, params, requestOptions) {
570
- if (requestOptions)
571
- this.requestOptions = requestOptions;
572
- let headers = this.getHeaders();
573
- if (!this.requestOptions.disableBlockUI)
574
- this.utilityService.startBlockUI();
575
- return this.http.get(this.environmentService.getApiUrl() + Url, { headers: headers, params: params, responseType: this.requestOptions.responseType }).pipe(takeUntil(this.onDestroy$), tap((result) => {
576
- if (!this.requestOptions.disableBlockUI)
577
- this.utilityService.stopBlockUI();
578
- }, error => {
579
- if (!this.requestOptions.disableErrorHandler)
580
- this.handleError(error);
581
- }));
582
- }
583
- destroyHandler() {
584
- this.onDestroy$.next();
585
- }
586
- ngOnDestroy() {
587
- console.log("clearInterval");
588
- this.destroyHandler();
589
- }
590
- handleError(err) {
591
- var isEnglish = this.utilityService.getCurrentLanguage() == "en";
592
- if (err.error instanceof ErrorEvent) {
593
- this.utilityService.notifyErrorMessage();
594
- }
595
- else {
596
- if (err.status == 400)
597
- throwError(err); //error 400 is thrown to be catch by the Form component to handle Fluent validation errors
598
- else if (err.status == 401)
599
- this.router.navigate(["/Admin/account/login"]);
600
- else if (err.status == 403)
601
- this.utilityService.notifyErrorMessage(isEnglish ? "Sorry, You're not authorized to access this action" : "عذرا ليس لديك الصلاحيه لهذا الطلب");
602
- else if (err.status == 510)
603
- this.utilityService.notifyErrorMessage(isEnglish ? "Can not delete this item as it is related to others" : "لا يمكن حذف هذا العنصر لأنه مرتبط بعناصر أخرى");
604
- else if (err.status == 515)
605
- this.utilityService.notifyErrorMessage((err.error ? err.error.Message : err.message));
606
- else {
607
- console.log(`error message is: ${err.error ? err.error.Message : err.message}`);
608
- this.utilityService.notifyErrorMessage(this.utilityService.getResourceValue("ErrorMassage"));
609
- }
610
- }
611
- this.utilityService.stopBlockUI();
612
- }
613
- getHeaders() {
614
- return new HttpHeaders({
615
- 'Content-Type': 'application/json',
616
- 'Authorization': this.authService.authorizationHeaderValue(),
617
- 'Client-Local-Time-Zone': Intl.DateTimeFormat().resolvedOptions().timeZone,
618
- 'Accept-Language': localStorage.getItem('language'),
619
- 'ignore-cookies': 'true'
620
- });
621
- }
622
- }
623
- RequestHandlerService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RequestHandlerService, deps: [{ token: i1.HttpClient }, { token: AuthService }, { token: EnvironmentService }, { token: UtilityService }, { token: BBSFTranslateService }, { token: i1$1.Router }], target: i0.ɵɵFactoryTarget.Injectable });
624
- RequestHandlerService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RequestHandlerService });
625
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RequestHandlerService, decorators: [{
626
- type: Injectable
627
- }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: AuthService }, { type: EnvironmentService }, { type: UtilityService }, { type: BBSFTranslateService }, { type: i1$1.Router }]; } });
628
-
629
- class StylesBundleService {
630
- constructor(document, translateService) {
631
- this.document = document;
632
- this.translateService = translateService;
633
- }
634
- loadThemes(lang, bundleEnglishName, bundleArabicName) {
635
- if (lang == "ar") {
636
- this.loadStyleBundle(bundleArabicName.toString());
637
- document.querySelector('html').setAttribute("b-lang", "ar"); //use b-lang instead of lang to fix firefox number inputs in Arabic locale
638
- document.querySelector('html').setAttribute("dir", "rtl");
639
- }
640
- else {
641
- this.loadStyleBundle(bundleEnglishName.toString());
642
- document.querySelector('html').setAttribute("b-lang", "en");
643
- document.querySelector('html').setAttribute("dir", "ltr");
644
- }
645
- }
646
- loadThemesColor(theme, bundleDarkName, bundleLightName) {
647
- if (theme == "Light")
648
- this.loadStyleBundle(bundleLightName.toString());
649
- else
650
- this.loadStyleBundle(bundleDarkName.toString());
651
- }
652
- loadStyleBundle(styleName) {
653
- const head = this.document.getElementsByTagName('head')[0];
654
- let themeLink = this.document.getElementById('client-theme');
655
- if (themeLink && themeLink.href.includes(styleName)) {
656
- return;
657
- }
658
- else if (themeLink && !themeLink.href.includes(styleName)) {
659
- themeLink.remove();
660
- }
661
- const style = this.document.createElement('link');
662
- style.id = 'client-theme';
663
- style.rel = 'stylesheet';
664
- style.href = `${styleName}`;
665
- head.appendChild(style);
666
- }
667
- }
668
- StylesBundleService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: StylesBundleService, deps: [{ token: DOCUMENT }, { token: BBSFTranslateService }], target: i0.ɵɵFactoryTarget.Injectable });
669
- StylesBundleService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: StylesBundleService, providedIn: 'root' });
670
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: StylesBundleService, decorators: [{
671
- type: Injectable,
672
- args: [{
673
- providedIn: 'root'
674
- }]
675
- }], ctorParameters: function () {
676
- return [{ type: Document, decorators: [{
677
- type: Inject,
678
- args: [DOCUMENT]
679
- }] }, { type: BBSFTranslateService }];
680
- } });
681
-
682
- class BBSFTranslateService extends TranslateService {
683
- }
684
- BBSFTranslateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: BBSFTranslateService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
685
- BBSFTranslateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: BBSFTranslateService, providedIn: 'root' });
686
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: BBSFTranslateService, decorators: [{
687
- type: Injectable,
688
- args: [{
689
- providedIn: 'root'
690
- }]
691
- }] });
692
-
693
- const TranslationResolverService = () => {
694
- let translateService = inject(BBSFTranslateService);
695
- return translateService.getTranslation(translateService.currentLang);
696
- };
697
-
698
- class UtilityService {
699
- constructor(translator, environmentService, injector) {
700
- this.translator = translator;
701
- this.environmentService = environmentService;
702
- this.injector = injector;
703
- this.isCreatedBefore = false;
704
- }
705
- getResourceValue(Key) {
706
- let ResourceValue = this.translator.instant(Key);
707
- return ResourceValue;
708
- }
709
- getCurrentLanguage() {
710
- let currentLanguage = this.environmentService.getDefaultLanguage();
711
- let lang = localStorage.getItem('language');
712
- if (lang)
713
- currentLanguage = lang;
714
- else
715
- localStorage.setItem('language', currentLanguage);
716
- return currentLanguage;
717
- }
718
- isCurrentLanguageEnglish() {
719
- return this.getCurrentLanguage() == "en";
720
- }
721
- isCurrentLanguageArabic() {
722
- return this.getCurrentLanguage() == "ar";
723
- }
724
- notifySuccessMessage(Message, title, time, showHeader = true) {
725
- let MessageTemplate = this.getResourceValue("SuccessMessage");
726
- let titleTemplate;
727
- if (Message) {
728
- MessageTemplate = Message;
729
- }
730
- if (title) {
731
- titleTemplate = title;
732
- }
733
- let toaster = this.injector.get(ToastrService);
734
- showHeader ? toaster.success(MessageTemplate, titleTemplate) : toaster.success(MessageTemplate);
735
- }
736
- notifyErrorMessage(Message, title, time, showHeader = true) {
737
- let MessageTemplate = this.getResourceValue("ErrorMessage");
738
- let titleTemplate = this.getResourceValue("Error");
739
- if (Message) {
740
- MessageTemplate = Message;
741
- }
742
- if (title) {
743
- titleTemplate = title;
744
- }
745
- const toaster = this.injector.get(ToastrService);
746
- showHeader ? toaster.error(MessageTemplate, titleTemplate) : toaster.error(MessageTemplate);
747
- }
748
- notifyWarningMessage(Message, title, time, showHeader = true) {
749
- let MessageTemplate = this.getResourceValue("WarningMessage");
750
- let titleTemplate = this.getResourceValue("Warning");
751
- if (Message) {
752
- MessageTemplate = Message;
753
- }
754
- if (title) {
755
- titleTemplate = title;
756
- }
757
- const toaster = this.injector.get(ToastrService);
758
- showHeader ? toaster.warning(MessageTemplate, titleTemplate) : toaster.warning(MessageTemplate);
759
- }
760
- startBlockUI() {
761
- this.blockUI.start();
762
- }
763
- stopBlockUI() {
764
- this.blockUI.stop();
765
- }
766
- }
767
- UtilityService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UtilityService, deps: [{ token: BBSFTranslateService }, { token: EnvironmentService }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
768
- UtilityService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UtilityService, providedIn: 'root' });
769
- __decorate([
770
- BlockUI()
771
- ], UtilityService.prototype, "blockUI", void 0);
772
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UtilityService, decorators: [{
773
- type: Injectable,
774
- args: [{
775
- providedIn: 'root'
776
- }]
777
- }], ctorParameters: function () { return [{ type: BBSFTranslateService }, { type: EnvironmentService }, { type: i0.Injector }]; }, propDecorators: { blockUI: [] } });
778
-
779
- const contentTypesXML = `
780
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
781
-
782
- <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
783
- <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml" />
784
- <Default Extension="jpeg" ContentType="image/jpeg"/>
785
- <Default Extension="png" ContentType="image/png"/>
786
- <Default Extension="xml" ContentType="application/xml"/>
787
- <Override PartName="/_rels/.rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
788
- <Override PartName="/word/_rels/document.xml.rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
789
- <Override PartName="/word/_rels/footer1.xml.rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
790
- <Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/>
791
- <Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/>
792
- <Override PartName="/word/numbering.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml"/>
793
- <Override PartName="/word/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/>
794
- <Override PartName="/word/fontTable.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml"/>
795
- <Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>
796
- <Override PartName="/word/settings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"/>
797
- <Override PartName="/word/webSettings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml"/>
798
- <Override PartName="/word/afchunk.mht" ContentType="message/rfc822"/>
799
- <Override PartName="/word/afchunkheader.mht" ContentType="message/rfc822"/>
800
- <Override PartName="/word/afchunkfooter.mht" ContentType="message/rfc822"/>
801
- </Types>
802
- `;
803
-
804
- const namespaces = {
805
- a: 'http://schemas.openxmlformats.org/drawingml/2006/main',
806
- b: 'http://schemas.openxmlformats.org/officeDocument/2006/bibliography',
807
- cdr: 'http://schemas.openxmlformats.org/drawingml/2006/chartDrawing',
808
- dc: 'http://purl.org/dc/elements/1.1/',
809
- dcmitype: 'http://purl.org/dc/dcmitype/',
810
- dcterms: 'http://purl.org/dc/terms/',
811
- o: 'urn:schemas-microsoft-com:office:office',
812
- pic: 'http://schemas.openxmlformats.org/drawingml/2006/picture',
813
- r: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships',
814
- v: 'urn:schemas-microsoft-com:vml',
815
- ve: 'http://schemas.openxmlformats.org/markup-compatibility/2006',
816
- vt: 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes',
817
- w: 'http://schemas.openxmlformats.org/wordprocessingml/2006/main',
818
- w10: 'urn:schemas-microsoft-com:office:word',
819
- wp: 'http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing',
820
- wne: 'http://schemas.microsoft.com/office/word/2006/wordml',
821
- xsd: 'http://www.w3.org/2001/XMLSchema',
822
- xsi: 'http://www.w3.org/2001/XMLSchema-instance',
823
- numbering: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering',
824
- hyperlinks: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink',
825
- images: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',
826
- styles: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles',
827
- headers: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/header',
828
- footers: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer',
829
- themes: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme',
830
- coreProperties: 'http://schemas.openxmlformats.org/package/2006/metadata/core-properties',
831
- officeDocumentRelation: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument',
832
- corePropertiesRelation: 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties',
833
- settingsRelation: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings',
834
- webSettingsRelation: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings',
835
- sl: 'http://schemas.openxmlformats.org/schemaLibrary/2006/main',
836
- contentTypes: 'http://schemas.openxmlformats.org/package/2006/content-types',
837
- relationship: 'http://schemas.openxmlformats.org/package/2006/relationships',
838
- };
839
-
840
- const applicationName = 'html-to-docx';
841
- const defaultOrientation = 'portrait';
842
- const landscapeWidth = 15840;
843
- const landscapeHeight = 12240;
844
- const landscapeMargins = {
845
- top: 1800,
846
- right: 1440,
847
- bottom: 1800,
848
- left: 1440,
849
- header: 720,
850
- footer: 720,
851
- gutter: 0,
852
- };
853
- const portraitMargins = {
854
- top: 1440,
855
- right: 1800,
856
- bottom: 1440,
857
- left: 1800,
858
- header: 720,
859
- footer: 720,
860
- gutter: 0,
861
- };
862
- const defaultFont = 'Times New Roman';
863
- const defaultFontSize = 22;
864
- const defaultDocumentOptions = {
865
- orientation: defaultOrientation,
866
- margins: cloneDeep(portraitMargins),
867
- title: '',
868
- subject: '',
869
- creator: applicationName,
870
- keywords: [applicationName],
871
- description: '',
872
- lastModifiedBy: applicationName,
873
- revision: 1,
874
- createdAt: new Date(),
875
- modifiedAt: new Date(),
876
- headerType: 'default',
877
- header: false,
878
- footerType: 'default',
879
- footer: false,
880
- font: defaultFont,
881
- fontSize: defaultFontSize,
882
- complexScriptFontSize: defaultFontSize,
883
- table: {
884
- row: {
885
- cantSplit: false,
886
- },
887
- },
888
- pageSize: {
889
- width: landscapeHeight,
890
- height: landscapeWidth,
891
- },
892
- pageNumber: false,
893
- skipFirstHeaderFooter: false,
894
- lineNumber: false,
895
- lineNumberOptions: {
896
- countBy: 1,
897
- start: 0,
898
- restart: 'continuous',
899
- },
900
- numbering: {
901
- defaultOrderedListStyleType: 'decimal',
902
- },
903
- };
904
- const defaultHTMLString = '<p></p>';
905
- const relsFolderName = '_rels';
906
- const headerFileName = 'header1';
907
- const footerFileName = 'footer1';
908
- const themeFileName = 'theme1';
909
- const documentFileName = 'document';
910
- const headerType = 'header';
911
- const footerType = 'footer';
912
- const themeType = 'theme';
913
- const hyperlinkType = 'hyperlink';
914
- const imageType = 'image';
915
- const internalRelationship = 'Internal';
916
- const wordFolder = 'word';
917
- const themeFolder = 'theme';
918
- const paragraphBordersObject = {
919
- top: {
920
- size: 0,
921
- spacing: 3,
922
- color: 'FFFFFF',
923
- },
924
- left: {
925
- size: 0,
926
- spacing: 3,
927
- color: 'FFFFFF',
928
- },
929
- bottom: {
930
- size: 0,
931
- spacing: 3,
932
- color: 'FFFFFF',
933
- },
934
- right: {
935
- size: 0,
936
- spacing: 3,
937
- color: 'FFFFFF',
938
- },
939
- };
940
- const colorlessColors = ['transparent', 'auto'];
941
- const verticalAlignValues = ['top', 'middle', 'bottom'];
942
-
943
- const generateCoreXML = (title = '', subject = '', creator = applicationName, keywords = [applicationName], description = '', lastModifiedBy = applicationName, revision = 1, createdAt = new Date(), modifiedAt = new Date()) => `
944
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
945
-
946
- <cp:coreProperties
947
- xmlns:cp="${namespaces.coreProperties}"
948
- xmlns:dc="${namespaces.dc}"
949
- xmlns:dcterms="${namespaces.dcterms}"
950
- xmlns:dcmitype="${namespaces.dcmitype}"
951
- xmlns:xsi="${namespaces.xsi}"
952
- >
953
- <dc:title>${title}</dc:title>
954
- <dc:subject>${subject}</dc:subject>
955
- <dc:creator>${creator}</dc:creator>
956
- ${keywords && Array.isArray(keywords)
957
- ? `<cp:keywords>${keywords.join(', ')}</cp:keywords>`
958
- : ''}
959
- <dc:description>${description}</dc:description>
960
- <cp:lastModifiedBy>${lastModifiedBy}</cp:lastModifiedBy>
961
- <cp:revision>${revision}</cp:revision>
962
- <dcterms:created xsi:type="dcterms:W3CDTF">${createdAt instanceof Date ? createdAt.toISOString() : new Date().toISOString()}</dcterms:created>
963
- <dcterms:modified xsi:type="dcterms:W3CDTF">${modifiedAt instanceof Date ? modifiedAt.toISOString() : new Date().toISOString()}</dcterms:modified>
964
- </cp:coreProperties>
965
- `;
966
-
967
- const documentRelsXML = `
968
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
969
-
970
- <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
971
- <Relationship Id="rId1" Type="${namespaces.numbering}" Target="numbering.xml"/>
972
- <Relationship Id="rId2" Type="${namespaces.styles}" Target="styles.xml"/>
973
- <Relationship Id="rId3" Type="${namespaces.settingsRelation}" Target="settings.xml"/>
974
- <Relationship Id="rId4" Type="${namespaces.webSettingsRelation}" Target="webSettings.xml"/>
975
- <Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/aFChunk" Target="/word/afchunk.mht" Id="htmlChunk" />
976
- <Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/aFChunk" Target="/word/afchunkheader.mht" Id="htmlChunkHeader" />
977
- <Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/aFChunk" Target="/word/afchunkfooter.mht" Id="htmlChunkFooter" />
978
- </Relationships>
979
- `;
980
-
981
- const relsXML = `
982
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
983
-
984
- <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
985
- <Relationship Id="rId1" Type="${namespaces.officeDocumentRelation}" Target="word/document.xml"/>
986
- <Relationship Id="rId2" Type="${namespaces.corePropertiesRelation}" Target="docProps/core.xml"/>
987
- </Relationships>
988
- `;
989
-
990
- const generateNumberingXMLTemplate = () => `
991
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
992
-
993
- <w:numbering
994
- xmlns:w="${namespaces.w}"
995
- xmlns:ve="${namespaces.ve}"
996
- xmlns:o="${namespaces.o}"
997
- xmlns:r="${namespaces.r}"
998
- xmlns:v="${namespaces.v}"
999
- xmlns:wp="${namespaces.wp}"
1000
- xmlns:w10="${namespaces.w10}"
1001
- xmlns:wne="${namespaces.wne}">
1002
- </w:numbering>
1003
- `;
1004
-
1005
- const generateStylesXML = (font = defaultFont, fontSize = defaultFontSize, complexScriptFontSize = defaultFontSize) => `
1006
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
1007
-
1008
- <w:styles xmlns:w="${namespaces.w}" xmlns:r="${namespaces.r}">
1009
- <w:docDefaults>
1010
- <w:rPrDefault>
1011
- <w:rPr>
1012
- <w:rFonts w:ascii="${font}" w:eastAsiaTheme="minorHAnsi" w:hAnsiTheme="minorHAnsi" w:cstheme="minorBidi" />
1013
- <w:sz w:val="${fontSize}" />
1014
- <w:szCs w:val="${complexScriptFontSize}" />
1015
- <w:lang w:val="en-US" w:eastAsia="en-US" w:bidi="ar-SA" />
1016
- </w:rPr>
1017
- </w:rPrDefault>
1018
- <w:pPrDefault>
1019
- <w:pPr>
1020
- <w:spacing w:after="120" w:line="240" w:lineRule="atLeast" />
1021
- </w:pPr>
1022
- </w:pPrDefault>
1023
- </w:docDefaults>
1024
- <w:style w:type="character" w:styleId="Hyperlink">
1025
- <w:name w:val="Hyperlink" />
1026
- <w:rPr>
1027
- <w:color w:val="0000FF" />
1028
- <w:u w:val="single" />
1029
- </w:rPr>
1030
- </w:style>
1031
- <w:style w:type="paragraph" w:styleId="Heading1">
1032
- <w:name w:val="heading 1" />
1033
- <w:basedOn w:val="Normal" />
1034
- <w:next w:val="Normal" />
1035
- <w:uiPriority w:val="9" />
1036
- <w:qFormat />
1037
- <w:pPr>
1038
- <w:keepNext />
1039
- <w:keepLines />
1040
- <w:spacing w:before="480" />
1041
- <w:outlineLvl w:val="0" />
1042
- </w:pPr>
1043
- <w:rPr>
1044
- <w:b />
1045
- <w:sz w:val="48" />
1046
- <w:szCs w:val="48" />
1047
- </w:rPr>
1048
- </w:style>
1049
- <w:style w:type="paragraph" w:styleId="Heading2">
1050
- <w:name w:val="heading 2" />
1051
- <w:basedOn w:val="Normal" />
1052
- <w:next w:val="Normal" />
1053
- <w:uiPriority w:val="9" />
1054
- <w:unhideWhenUsed />
1055
- <w:qFormat />
1056
- <w:pPr>
1057
- <w:keepNext />
1058
- <w:keepLines />
1059
- <w:spacing w:before="360" w:after="80" />
1060
- <w:outlineLvl w:val="1" />
1061
- </w:pPr>
1062
- <w:rPr>
1063
- <w:b />
1064
- <w:sz w:val="36" />
1065
- <w:szCs w:val="36" />
1066
- </w:rPr>
1067
- </w:style>
1068
- <w:style w:type="paragraph" w:styleId="Heading3">
1069
- <w:name w:val="heading 3" />
1070
- <w:basedOn w:val="Normal" />
1071
- <w:next w:val="Normal" />
1072
- <w:uiPriority w:val="9" />
1073
- <w:semiHidden />
1074
- <w:unhideWhenUsed />
1075
- <w:qFormat />
1076
- <w:pPr>
1077
- <w:keepNext />
1078
- <w:keepLines />
1079
- <w:spacing w:before="280" w:after="80" />
1080
- <w:outlineLvl w:val="2" />
1081
- </w:pPr>
1082
- <w:rPr>
1083
- <w:b />
1084
- <w:sz w:val="28" />
1085
- <w:szCs w:val="28" />
1086
- </w:rPr>
1087
- </w:style>
1088
- <w:style w:type="paragraph" w:styleId="Heading4">
1089
- <w:name w:val="heading 4" />
1090
- <w:basedOn w:val="Normal" />
1091
- <w:next w:val="Normal" />
1092
- <w:uiPriority w:val="9" />
1093
- <w:semiHidden />
1094
- <w:unhideWhenUsed />
1095
- <w:qFormat />
1096
- <w:pPr>
1097
- <w:keepNext />
1098
- <w:keepLines />
1099
- <w:spacing w:before="240" w:after="40" />
1100
- <w:outlineLvl w:val="3" />
1101
- </w:pPr>
1102
- <w:rPr>
1103
- <w:b />
1104
- <w:sz w:val="24" />
1105
- <w:szCs w:val="24" />
1106
- </w:rPr>
1107
- </w:style>
1108
- <w:style w:type="paragraph" w:styleId="Heading5">
1109
- <w:name w:val="heading 5" />
1110
- <w:basedOn w:val="Normal" />
1111
- <w:next w:val="Normal" />
1112
- <w:uiPriority w:val="9" />
1113
- <w:semiHidden />
1114
- <w:unhideWhenUsed />
1115
- <w:qFormat />
1116
- <w:pPr>
1117
- <w:keepNext />
1118
- <w:keepLines />
1119
- <w:spacing w:before="220" w:after="40" />
1120
- <w:outlineLvl w:val="4" />
1121
- </w:pPr>
1122
- <w:rPr>
1123
- <w:b />
1124
- </w:rPr>
1125
- </w:style>
1126
- <w:style w:type="paragraph" w:styleId="Heading6">
1127
- <w:name w:val="heading 6" />
1128
- <w:basedOn w:val="Normal" />
1129
- <w:next w:val="Normal" />
1130
- <w:uiPriority w:val="9" />
1131
- <w:semiHidden />
1132
- <w:unhideWhenUsed />
1133
- <w:qFormat />
1134
- <w:pPr>
1135
- <w:keepNext />
1136
- <w:keepLines />
1137
- <w:spacing w:before="200" w:after="40" />
1138
- <w:outlineLvl w:val="5" />
1139
- </w:pPr>
1140
- <w:rPr>
1141
- <w:b />
1142
- <w:sz w:val="20" />
1143
- <w:szCs w:val="20" />
1144
- </w:rPr>
1145
- </w:style>
1146
- </w:styles>
1147
- `;
1148
-
1149
- const fontTableXML = `
1150
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
1151
-
1152
- <w:fonts
1153
- xmlns:r="${namespaces.r}"
1154
- xmlns:w="${namespaces.w}"
1155
- >
1156
- <w:font w:name="Symbol">
1157
- <w:panose1 w:val="05050102010706020507"/>
1158
- <w:charset w:val="02"/>
1159
- <w:family w:val="decorative"/>
1160
- <w:pitch w:val="variable"/>
1161
- <w:sig w:usb0="00000000" w:usb1="10000000" w:usb2="00000000" w:usb3="00000000" w:csb0="80000000" w:csb1="00000000"/>
1162
- </w:font>
1163
- <w:font w:name="Calibri">
1164
- <w:panose1 w:val="020F0502020204030204"/>
1165
- <w:charset w:val="00"/>
1166
- <w:family w:val="swiss"/>
1167
- <w:pitch w:val="variable"/>
1168
- <w:sig w:usb0="E4002EFF" w:usb1="C000247B" w:usb2="00000009" w:usb3="00000000" w:csb0="000001FF" w:csb1="00000000"/>
1169
- </w:font>
1170
- <w:font w:name="Times New Roman">
1171
- <w:panose1 w:val="02020603050405020304"/>
1172
- <w:charset w:val="00"/>
1173
- <w:family w:val="roman"/>
1174
- <w:pitch w:val="variable"/>
1175
- <w:sig w:usb0="E0002EFF" w:usb1="C000785B" w:usb2="00000009" w:usb3="00000000" w:csb0="000001FF" w:csb1="00000000"/>
1176
- </w:font>
1177
- <w:font w:name="Calibri Light">
1178
- <w:panose1 w:val="020F0302020204030204"/>
1179
- <w:charset w:val="00"/>
1180
- <w:family w:val="swiss"/>
1181
- <w:pitch w:val="variable"/>
1182
- <w:sig w:usb0="E4002EFF" w:usb1="C000247B" w:usb2="00000009" w:usb3="00000000" w:csb0="000001FF" w:csb1="00000000"/>
1183
- </w:font>
1184
- </w:fonts>
1185
- `;
1186
-
1187
- const generateThemeXML = (font = defaultFont) => `
1188
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
1189
-
1190
- <a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office Theme">
1191
- <a:themeElements>
1192
- <a:clrScheme name="Office">
1193
- <a:dk1>
1194
- <a:sysClr val="windowText" lastClr="000000"/>
1195
- </a:dk1>
1196
- <a:lt1>
1197
- <a:sysClr val="window" lastClr="FFFFFF"/>
1198
- </a:lt1>
1199
- <a:dk2>
1200
- <a:srgbClr val="44546A"/>
1201
- </a:dk2>
1202
- <a:lt2>
1203
- <a:srgbClr val="E7E6E6"/>
1204
- </a:lt2>
1205
- <a:accent1>
1206
- <a:srgbClr val="4472C4"/>
1207
- </a:accent1>
1208
- <a:accent2>
1209
- <a:srgbClr val="ED7D31"/>
1210
- </a:accent2>
1211
- <a:accent3>
1212
- <a:srgbClr val="A5A5A5"/>
1213
- </a:accent3>
1214
- <a:accent4>
1215
- <a:srgbClr val="FFC000"/>
1216
- </a:accent4>
1217
- <a:accent5>
1218
- <a:srgbClr val="5B9BD5"/>
1219
- </a:accent5>
1220
- <a:accent6>
1221
- <a:srgbClr val="70AD47"/>
1222
- </a:accent6>
1223
- <a:hlink>
1224
- <a:srgbClr val="0563C1"/>
1225
- </a:hlink>
1226
- <a:folHlink>
1227
- <a:srgbClr val="954F72"/>
1228
- </a:folHlink>
1229
- </a:clrScheme>
1230
- <a:fontScheme name="Office">
1231
- <a:majorFont>
1232
- <a:latin typeface="${font}"/>
1233
- <a:ea typeface="${font}"/>
1234
- <a:cs typeface=""/>
1235
- </a:majorFont>
1236
- <a:minorFont>
1237
- <a:latin typeface="${font}"/>
1238
- <a:ea typeface="${font}"/>
1239
- <a:cs typeface=""/>
1240
- </a:minorFont>
1241
- </a:fontScheme>
1242
- <a:fmtScheme name="Office">
1243
- <a:fillStyleLst>
1244
- <a:solidFill>
1245
- <a:schemeClr val="phClr"/>
1246
- </a:solidFill>
1247
- <a:gradFill rotWithShape="1">
1248
- <a:gsLst>
1249
- <a:gs pos="0">
1250
- <a:schemeClr val="phClr">
1251
- <a:lumMod val="110000"/>
1252
- <a:satMod val="105000"/>
1253
- <a:tint val="67000"/>
1254
- </a:schemeClr>
1255
- </a:gs>
1256
- <a:gs pos="50000">
1257
- <a:schemeClr val="phClr">
1258
- <a:lumMod val="105000"/>
1259
- <a:satMod val="103000"/>
1260
- <a:tint val="73000"/>
1261
- </a:schemeClr>
1262
- </a:gs>
1263
- <a:gs pos="100000">
1264
- <a:schemeClr val="phClr">
1265
- <a:lumMod val="105000"/>
1266
- <a:satMod val="109000"/>
1267
- <a:tint val="81000"/>
1268
- </a:schemeClr>
1269
- </a:gs>
1270
- </a:gsLst>
1271
- <a:lin ang="5400000" scaled="0"/>
1272
- </a:gradFill>
1273
- <a:gradFill rotWithShape="1">
1274
- <a:gsLst>
1275
- <a:gs pos="0">
1276
- <a:schemeClr val="phClr">
1277
- <a:satMod val="103000"/>
1278
- <a:lumMod val="102000"/>
1279
- <a:tint val="94000"/>
1280
- </a:schemeClr>
1281
- </a:gs>
1282
- <a:gs pos="50000">
1283
- <a:schemeClr val="phClr">
1284
- <a:satMod val="110000"/>
1285
- <a:lumMod val="100000"/>
1286
- <a:shade val="100000"/>
1287
- </a:schemeClr>
1288
- </a:gs>
1289
- <a:gs pos="100000">
1290
- <a:schemeClr val="phClr">
1291
- <a:lumMod val="99000"/>
1292
- <a:satMod val="120000"/>
1293
- <a:shade val="78000"/>
1294
- </a:schemeClr>
1295
- </a:gs>
1296
- </a:gsLst>
1297
- <a:lin ang="5400000" scaled="0"/>
1298
- </a:gradFill>
1299
- </a:fillStyleLst>
1300
- <a:lnStyleLst>
1301
- <a:ln w="6350" cap="flat" cmpd="sng" algn="ctr">
1302
- <a:solidFill>
1303
- <a:schemeClr val="phClr"/>
1304
- </a:solidFill>
1305
- <a:prstDash val="solid"/>
1306
- <a:miter lim="800000"/>
1307
- </a:ln>
1308
- <a:ln w="12700" cap="flat" cmpd="sng" algn="ctr">
1309
- <a:solidFill>
1310
- <a:schemeClr val="phClr"/>
1311
- </a:solidFill>
1312
- <a:prstDash val="solid"/>
1313
- <a:miter lim="800000"/>
1314
- </a:ln>
1315
- <a:ln w="19050" cap="flat" cmpd="sng" algn="ctr">
1316
- <a:solidFill>
1317
- <a:schemeClr val="phClr"/>
1318
- </a:solidFill>
1319
- <a:prstDash val="solid"/>
1320
- <a:miter lim="800000"/>
1321
- </a:ln>
1322
- </a:lnStyleLst>
1323
- <a:effectStyleLst>
1324
- <a:effectStyle>
1325
- <a:effectLst/>
1326
- </a:effectStyle>
1327
- <a:effectStyle>
1328
- <a:effectLst/>
1329
- </a:effectStyle>
1330
- <a:effectStyle>
1331
- <a:effectLst>
1332
- <a:outerShdw blurRad="57150" dist="19050" dir="5400000" algn="ctr" rotWithShape="0">
1333
- <a:srgbClr val="000000">
1334
- <a:alpha val="63000"/>
1335
- </a:srgbClr>
1336
- </a:outerShdw>
1337
- </a:effectLst>
1338
- </a:effectStyle>
1339
- </a:effectStyleLst>
1340
- <a:bgFillStyleLst>
1341
- <a:solidFill>
1342
- <a:schemeClr val="phClr"/>
1343
- </a:solidFill>
1344
- <a:solidFill>
1345
- <a:schemeClr val="phClr">
1346
- <a:tint val="95000"/>
1347
- <a:satMod val="170000"/>
1348
- </a:schemeClr>
1349
- </a:solidFill>
1350
- <a:gradFill rotWithShape="1">
1351
- <a:gsLst>
1352
- <a:gs pos="0">
1353
- <a:schemeClr val="phClr">
1354
- <a:tint val="93000"/>
1355
- <a:satMod val="150000"/>
1356
- <a:shade val="98000"/>
1357
- <a:lumMod val="102000"/>
1358
- </a:schemeClr>
1359
- </a:gs>
1360
- <a:gs pos="50000">
1361
- <a:schemeClr val="phClr">
1362
- <a:tint val="98000"/>
1363
- <a:satMod val="130000"/>
1364
- <a:shade val="90000"/>
1365
- <a:lumMod val="103000"/>
1366
- </a:schemeClr>
1367
- </a:gs>
1368
- <a:gs pos="100000">
1369
- <a:schemeClr val="phClr">
1370
- <a:shade val="63000"/>
1371
- <a:satMod val="120000"/>
1372
- </a:schemeClr>
1373
- </a:gs>
1374
- </a:gsLst>
1375
- <a:lin ang="5400000" scaled="0"/>
1376
- </a:gradFill>
1377
- </a:bgFillStyleLst>
1378
- </a:fmtScheme>
1379
- </a:themeElements>
1380
- </a:theme>
1381
- `;
1382
-
1383
- const settingsXML = `
1384
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
1385
-
1386
- <w:settings xmlns:w="${namespaces.w}" xmlns:o="${namespaces.o}" xmlns:r="${namespaces.r}" xmlns:v="${namespaces.v}" xmlns:w10="${namespaces.w10}" xmlns:sl="${namespaces.sl}">
1387
- <w:zoom w:percent="100"/>
1388
- <w:defaultTabStop w:val="720"/>
1389
- <w:decimalSymbol w:val="."/>
1390
- <w:listSeparator w:val=","/>
1391
- </w:settings>
1392
- `;
1393
-
1394
- const webSettingsXML = `
1395
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
1396
-
1397
- <w:webSettings xmlns:w="${namespaces.w}" xmlns:r="${namespaces.r}">
1398
- </w:webSettings>
1399
- `;
1400
-
1401
- const genericRelsXML = `
1402
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
1403
-
1404
- <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
1405
- <Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/aFChunk" Target="/word/afchunk.mht" Id="htmlChunk" />
1406
- <Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/aFChunk" Target="/word/afchunkheader.mht" Id="htmlChunkHeader" />
1407
- <Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/aFChunk" Target="/word/afchunkfooter.mht" Id="htmlChunkFooter" />
1408
- </Relationships>
1409
- `;
1410
-
1411
- const generateDocumentTemplate = (width, height, orientation, margins) => `
1412
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
1413
- <w:document
1414
- xmlns:a="${namespaces.a}"
1415
- xmlns:cdr="${namespaces.cdr}"
1416
- xmlns:o="${namespaces.o}"
1417
- xmlns:pic="${namespaces.pic}"
1418
- xmlns:r="${namespaces.r}"
1419
- xmlns:v="${namespaces.v}"
1420
- xmlns:ve="${namespaces.ve}"
1421
- xmlns:vt="${namespaces.vt}"
1422
- xmlns:w="${namespaces.w}"
1423
- xmlns:w10="${namespaces.w10}"
1424
- xmlns:wp="${namespaces.wp}"
1425
- xmlns:wne="${namespaces.wne}"
1426
- >
1427
- <w:body>
1428
-
1429
- <w:altChunk r:id="htmlChunk" />
1430
- <w:sectPr>
1431
- <w:pgSz w:w="${width}" w:h="${height}" w:orient="${orientation}" />
1432
- <w:pgMar w:top="${margins.top}"
1433
- w:right="${margins.right}"
1434
- w:bottom="${margins.bottom}"
1435
- w:left="${margins.left}"
1436
- w:header="${margins.header}"
1437
- w:footer="${margins.footer}"
1438
- w:gutter="${margins.gutter}"/>
1439
- </w:sectPr>
1440
- </w:body>
1441
- </w:document>
1442
- `;
1443
- const generateDocumentTemplateHeader = `
1444
- <w:hdr
1445
- xmlns:a="${namespaces.a}"
1446
- xmlns:cdr="${namespaces.cdr}"
1447
- xmlns:o="${namespaces.o}"
1448
- xmlns:pic="${namespaces.pic}"
1449
- xmlns:r="${namespaces.r}"
1450
- xmlns:v="${namespaces.v}"
1451
- xmlns:ve="${namespaces.ve}"
1452
- xmlns:vt="${namespaces.vt}"
1453
- xmlns:w="${namespaces.w}"
1454
- xmlns:w10="${namespaces.w10}"
1455
- xmlns:wp="${namespaces.wp}"
1456
- xmlns:wne="${namespaces.wne}"
1457
- >
1458
- <w:altChunk r:id="htmlChunkHeader" />
1459
- </w:hdr>
1460
- `;
1461
- const generateDocumentTemplateFooter = `
1462
- <w:ftr
1463
- xmlns:a="${namespaces.a}"
1464
- xmlns:cdr="${namespaces.cdr}"
1465
- xmlns:o="${namespaces.o}"
1466
- xmlns:pic="${namespaces.pic}"
1467
- xmlns:r="${namespaces.r}"
1468
- xmlns:v="${namespaces.v}"
1469
- xmlns:ve="${namespaces.ve}"
1470
- xmlns:vt="${namespaces.vt}"
1471
- xmlns:w="${namespaces.w}"
1472
- xmlns:w10="${namespaces.w10}"
1473
- xmlns:wp="${namespaces.wp}"
1474
- >
1475
- <w:altChunk r:id="htmlChunkFooter" />
1476
- <w:p w:rsidR="0014021C" w:rsidRDefault="0014021C" w:rsidP="0014021C">
1477
- <w:pPr>
1478
- <w:pStyle w:val="Footer"/>
1479
- <w:jc w:val="center"/>
1480
- </w:pPr>
1481
- <w:fldSimple xmlns:ns2="http://schemas.openxmlformats.org/wordprocessingml/2006/main" ns2:instr="PAGE">
1482
- <w:r/>
1483
- </w:fldSimple>
1484
- </w:p>
1485
- </w:ftr>
1486
- `;
1487
- const generateDocumentTemplateFooterWithoutPaging = `
1488
- <w:ftr
1489
- xmlns:a="${namespaces.a}"
1490
- xmlns:cdr="${namespaces.cdr}"
1491
- xmlns:o="${namespaces.o}"
1492
- xmlns:pic="${namespaces.pic}"
1493
- xmlns:r="${namespaces.r}"
1494
- xmlns:v="${namespaces.v}"
1495
- xmlns:ve="${namespaces.ve}"
1496
- xmlns:vt="${namespaces.vt}"
1497
- xmlns:w="${namespaces.w}"
1498
- xmlns:w10="${namespaces.w10}"
1499
- xmlns:wp="${namespaces.wp}"
1500
- >
1501
- <w:altChunk r:id="htmlChunkFooter" />
1502
- </w:ftr>
1503
- `;
1504
- { /* <w:altChunk r:id="htmlChunkFooter" /> */ }
1505
- {
1506
- /* <w:altChunk r:id="htmlChunkFooter" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" /> */
1507
- }
1508
- {
1509
- /* <w:ftr xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
1510
- <fldSimple xmlns:ns2="http://schemas.openxmlformats.org/wordprocessingml/2006/main" ns2:instr="PAGE">
1511
- </fldSimple>
1512
- <w:altChunk r:id="htmlChunkFooter" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" />
1513
- </w:ftr> */
1514
- }
1515
-
1516
- /* eslint-disable no-param-reassign */
1517
- const rgbRegex = /rgb\((\d+),\s*([\d.]+),\s*([\d.]+)\)/i;
1518
- const hslRegex = /hsl\((\d+),\s*([\d.]+)%,\s*([\d.]+)%\)/i;
1519
- const hexRegex = /#([0-9A-F]{6})/i;
1520
- const hex3Regex = /#([0-9A-F])([0-9A-F])([0-9A-F])/i;
1521
- // eslint-disable-next-line import/prefer-default-export
1522
- const rgbToHex = (red, green, blue) => {
1523
- const hexColorCode = [red, green, blue]
1524
- .map((x) => {
1525
- // eslint-disable-next-line radix, no-param-reassign
1526
- x = parseInt(x).toString(16);
1527
- return x.length === 1 ? `0${x}` : x;
1528
- })
1529
- .join('');
1530
- return hexColorCode;
1531
- };
1532
- const hslToHex = (hue, saturation, luminosity) => {
1533
- hue /= 360;
1534
- saturation /= 100;
1535
- luminosity /= 100;
1536
- // eslint-disable-next-line one-var
1537
- let red, green, blue;
1538
- if (saturation === 0) {
1539
- // eslint-disable-next-line no-multi-assign
1540
- red = green = blue = luminosity; // achromatic
1541
- }
1542
- else {
1543
- const hue2rgb = (p, q, t) => {
1544
- if (t < 0)
1545
- t += 1;
1546
- if (t > 1)
1547
- t -= 1;
1548
- if (t < 1 / 6)
1549
- return p + (q - p) * 6 * t;
1550
- if (t < 1 / 2)
1551
- return q;
1552
- if (t < 2 / 3)
1553
- return p + (q - p) * (2 / 3 - t) * 6;
1554
- return p;
1555
- };
1556
- const q = luminosity < 0.5
1557
- ? luminosity * (1 + saturation)
1558
- : luminosity + saturation - luminosity * saturation;
1559
- const p = 2 * luminosity - q;
1560
- red = hue2rgb(p, q, hue + 1 / 3);
1561
- green = hue2rgb(p, q, hue);
1562
- blue = hue2rgb(p, q, hue - 1 / 3);
1563
- }
1564
- return [red, green, blue]
1565
- .map((x) => {
1566
- const hex = Math.round(x * 255).toString(16);
1567
- return hex.length === 1 ? `0${hex}` : hex;
1568
- })
1569
- .join('');
1570
- };
1571
- const hex3ToHex = (red, green, blue) => {
1572
- const hexColorCode = [red, green, blue].map((x) => `${x}${x}`).join('');
1573
- return hexColorCode;
1574
- };
1575
-
1576
- const pixelRegex = /([\d.]+)px/i;
1577
- const percentageRegex = /([\d.]+)%/i;
1578
- const pointRegex = /([\d.]+)pt/i;
1579
- const cmRegex = /([\d.]+)cm/i;
1580
- const inchRegex = /([\d.]+)in/i;
1581
- const pixelToEMU = (pixelValue) => Math.round(pixelValue * 9525);
1582
- const EMUToPixel = (EMUValue) => Math.round(EMUValue / 9525);
1583
- const TWIPToEMU = (TWIPValue) => Math.round(TWIPValue * 635);
1584
- const EMUToTWIP = (EMUValue) => Math.round(EMUValue / 635);
1585
- const pointToTWIP = (pointValue) => Math.round(pointValue * 20);
1586
- const TWIPToPoint = (TWIPValue) => Math.round(TWIPValue / 20);
1587
- const pointToHIP = (pointValue) => Math.round(pointValue * 2);
1588
- const HIPToPoint = (HIPValue) => Math.round(HIPValue / 2);
1589
- const HIPToTWIP = (HIPValue) => Math.round(HIPValue * 10);
1590
- const TWIPToHIP = (TWIPValue) => Math.round(TWIPValue / 10);
1591
- const pixelToTWIP = (pixelValue) => EMUToTWIP(pixelToEMU(pixelValue));
1592
- const TWIPToPixel = (TWIPValue) => EMUToPixel(TWIPToEMU(TWIPValue));
1593
- const pixelToHIP = (pixelValue) => TWIPToHIP(EMUToTWIP(pixelToEMU(pixelValue)));
1594
- const HIPToPixel = (HIPValue) => EMUToPixel(TWIPToEMU(HIPToTWIP(HIPValue)));
1595
- const inchToPoint = (inchValue) => Math.round(inchValue * 72);
1596
- const inchToTWIP = (inchValue) => pointToTWIP(inchToPoint(inchValue));
1597
- const cmToInch = (cmValue) => cmValue * 0.3937008;
1598
- const cmToTWIP = (cmValue) => inchToTWIP(cmToInch(cmValue));
1599
- const pixelToPoint = (pixelValue) => HIPToPoint(pixelToHIP(pixelValue));
1600
- const pointToPixel = (pointValue) => HIPToPixel(pointToHIP(pointValue));
1601
- const EIPToPoint = (EIPValue) => Math.round(EIPValue / 8);
1602
- const pointToEIP = (PointValue) => Math.round(PointValue * 8);
1603
- const pixelToEIP = (pixelValue) => pointToEIP(pixelToPoint(pixelValue));
1604
- const EIPToPixel = (EIPValue) => pointToPixel(EIPToPoint(EIPValue));
1605
-
1606
- // eslint-disable-next-line import/prefer-default-export
1607
- const vNodeHasChildren = (vNode) => vNode && vNode.children && Array.isArray(vNode.children) && vNode.children.length;
1608
-
1609
- const isValidUrl = (urlString) => {
1610
- const urlRegex = /http(s)?:\/\/(\w+:?\w*@)?(\S+)(:\d+)?((?<=\.)\w+)+(\/([\w#!:.?+=&%@!\-/])*)?/gi;
1611
- return Boolean(urlRegex.test(urlString));
1612
- };
1613
-
1614
- // eslint-disable-next-line consistent-return
1615
- const fixupColorCode = (colorCodeString) => {
1616
- if (Object.prototype.hasOwnProperty.call(colorNames, colorCodeString.toLowerCase())) {
1617
- const [red, green, blue] = colorNames[colorCodeString.toLowerCase()];
1618
- return rgbToHex(red, green, blue);
1619
- }
1620
- else if (rgbRegex.test(colorCodeString)) {
1621
- const matchedParts = colorCodeString.match(rgbRegex);
1622
- const red = matchedParts[1];
1623
- const green = matchedParts[2];
1624
- const blue = matchedParts[3];
1625
- return rgbToHex(red, green, blue);
1626
- }
1627
- else if (hslRegex.test(colorCodeString)) {
1628
- const matchedParts = colorCodeString.match(hslRegex);
1629
- const hue = matchedParts[1];
1630
- const saturation = matchedParts[2];
1631
- const luminosity = matchedParts[3];
1632
- return hslToHex(hue, saturation, luminosity);
1633
- }
1634
- else if (hexRegex.test(colorCodeString)) {
1635
- const matchedParts = colorCodeString.match(hexRegex);
1636
- return matchedParts[1];
1637
- }
1638
- else if (hex3Regex.test(colorCodeString)) {
1639
- const matchedParts = colorCodeString.match(hex3Regex);
1640
- const red = matchedParts[1];
1641
- const green = matchedParts[2];
1642
- const blue = matchedParts[3];
1643
- return hex3ToHex(red, green, blue);
1644
- }
1645
- else {
1646
- return '000000';
1647
- }
1648
- };
1649
- const buildRunFontFragment = (fontName = defaultFont) => fragment({ namespaceAlias: { w: namespaces.w } })
1650
- .ele('@w', 'rFonts')
1651
- .att('@w', 'ascii', fontName)
1652
- .att('@w', 'hAnsi', fontName)
1653
- .up();
1654
- const buildRunStyleFragment = (type = 'Hyperlink') => fragment({ namespaceAlias: { w: namespaces.w } })
1655
- .ele('@w', 'rStyle')
1656
- .att('@w', 'val', type)
1657
- .up();
1658
- const buildTableRowHeight = (tableRowHeight) => fragment({ namespaceAlias: { w: namespaces.w } })
1659
- .ele('@w', 'trHeight')
1660
- .att('@w', 'val', tableRowHeight)
1661
- .att('@w', 'hRule', 'atLeast')
1662
- .up();
1663
- const buildVerticalAlignment = (verticalAlignment) => {
1664
- if (verticalAlignment.toLowerCase() === 'middle') {
1665
- verticalAlignment = 'center';
1666
- }
1667
- return fragment({ namespaceAlias: { w: namespaces.w } })
1668
- .ele('@w', 'vAlign')
1669
- .att('@w', 'val', verticalAlignment)
1670
- .up();
1671
- };
1672
- const buildVerticalMerge = (verticalMerge = 'continue') => fragment({ namespaceAlias: { w: namespaces.w } })
1673
- .ele('@w', 'vMerge')
1674
- .att('@w', 'val', verticalMerge)
1675
- .up();
1676
- const buildColor = (colorCode) => fragment({ namespaceAlias: { w: namespaces.w } })
1677
- .ele('@w', 'color')
1678
- .att('@w', 'val', colorCode)
1679
- .up();
1680
- const buildFontSize = (fontSize) => fragment({ namespaceAlias: { w: namespaces.w } })
1681
- .ele('@w', 'sz')
1682
- .att('@w', 'val', fontSize)
1683
- .up();
1684
- const buildShading = (colorCode) => fragment({ namespaceAlias: { w: namespaces.w } })
1685
- .ele('@w', 'shd')
1686
- .att('@w', 'val', 'clear')
1687
- .att('@w', 'fill', colorCode)
1688
- .up();
1689
- const buildHighlight = (color = 'yellow') => fragment({ namespaceAlias: { w: namespaces.w } })
1690
- .ele('@w', 'highlight')
1691
- .att('@w', 'val', color)
1692
- .up();
1693
- const buildVertAlign = (type = 'baseline') => fragment({ namespaceAlias: { w: namespaces.w } })
1694
- .ele('@w', 'vertAlign')
1695
- .att('@w', 'val', type)
1696
- .up();
1697
- const buildStrike = () => fragment({ namespaceAlias: { w: namespaces.w } })
1698
- .ele('@w', 'strike')
1699
- .att('@w', 'val', true)
1700
- .up();
1701
- const buildBold = () => fragment({ namespaceAlias: { w: namespaces.w } })
1702
- .ele('@w', 'b')
1703
- .up();
1704
- const buildItalics = () => fragment({ namespaceAlias: { w: namespaces.w } })
1705
- .ele('@w', 'i')
1706
- .up();
1707
- const buildUnderline = (type = 'single') => fragment({ namespaceAlias: { w: namespaces.w } })
1708
- .ele('@w', 'u')
1709
- .att('@w', 'val', type)
1710
- .up();
1711
- const buildLineBreak = (type = 'textWrapping') => fragment({ namespaceAlias: { w: namespaces.w } })
1712
- .ele('@w', 'br')
1713
- .att('@w', 'type', type)
1714
- .up();
1715
- const buildBorder = (borderSide = 'top', borderSize = 0, borderSpacing = 0, borderColor = fixupColorCode('black'), borderStroke = 'single') => fragment({ namespaceAlias: { w: namespaces.w } })
1716
- .ele('@w', borderSide)
1717
- .att('@w', 'val', borderStroke)
1718
- .att('@w', 'sz', borderSize)
1719
- .att('@w', 'space', borderSpacing)
1720
- .att('@w', 'color', borderColor)
1721
- .up();
1722
- const buildTextElement = (text) => fragment({ namespaceAlias: { w: namespaces.w } })
1723
- .ele('@w', 't')
1724
- .att('@xml', 'space', 'preserve')
1725
- .txt(text)
1726
- .up();
1727
- // eslint-disable-next-line consistent-return
1728
- const fixupLineHeight = (lineHeight, fontSize) => {
1729
- // FIXME: If line height is anything other than a number
1730
- // eslint-disable-next-line no-restricted-globals
1731
- if (!isNaN(lineHeight)) {
1732
- if (fontSize) {
1733
- const actualLineHeight = +lineHeight * fontSize;
1734
- return HIPToTWIP(actualLineHeight);
1735
- }
1736
- else {
1737
- // 240 TWIP or 12 point is default line height
1738
- return +lineHeight * 240;
1739
- }
1740
- }
1741
- else {
1742
- // 240 TWIP or 12 point is default line height
1743
- return 240;
1744
- }
1745
- };
1746
- // eslint-disable-next-line consistent-return
1747
- const fixupFontSize$1 = (fontSizeString) => {
1748
- if (pointRegex.test(fontSizeString)) {
1749
- const matchedParts = fontSizeString.match(pointRegex);
1750
- // convert point to half point
1751
- return pointToHIP(matchedParts[1]);
1752
- }
1753
- else if (pixelRegex.test(fontSizeString)) {
1754
- const matchedParts = fontSizeString.match(pixelRegex);
1755
- // convert pixels to half point
1756
- return pixelToHIP(matchedParts[1]);
1757
- }
1758
- };
1759
- // eslint-disable-next-line consistent-return
1760
- const fixupRowHeight = (rowHeightString) => {
1761
- if (pointRegex.test(rowHeightString)) {
1762
- const matchedParts = rowHeightString.match(pointRegex);
1763
- // convert point to half point
1764
- return pointToTWIP(matchedParts[1]);
1765
- }
1766
- else if (pixelRegex.test(rowHeightString)) {
1767
- const matchedParts = rowHeightString.match(pixelRegex);
1768
- // convert pixels to half point
1769
- return pixelToTWIP(matchedParts[1]);
1770
- }
1771
- else if (cmRegex.test(rowHeightString)) {
1772
- const matchedParts = rowHeightString.match(cmRegex);
1773
- return cmToTWIP(matchedParts[1]);
1774
- }
1775
- else if (inchRegex.test(rowHeightString)) {
1776
- const matchedParts = rowHeightString.match(inchRegex);
1777
- return inchToTWIP(matchedParts[1]);
1778
- }
1779
- };
1780
- // eslint-disable-next-line consistent-return
1781
- const fixupColumnWidth = (columnWidthString) => {
1782
- if (pointRegex.test(columnWidthString)) {
1783
- const matchedParts = columnWidthString.match(pointRegex);
1784
- return pointToTWIP(matchedParts[1]);
1785
- }
1786
- else if (pixelRegex.test(columnWidthString)) {
1787
- const matchedParts = columnWidthString.match(pixelRegex);
1788
- return pixelToTWIP(matchedParts[1]);
1789
- }
1790
- else if (cmRegex.test(columnWidthString)) {
1791
- const matchedParts = columnWidthString.match(cmRegex);
1792
- return cmToTWIP(matchedParts[1]);
1793
- }
1794
- else if (inchRegex.test(columnWidthString)) {
1795
- const matchedParts = columnWidthString.match(inchRegex);
1796
- return inchToTWIP(matchedParts[1]);
1797
- }
1798
- };
1799
- // eslint-disable-next-line consistent-return
1800
- const fixupMargin = (marginString) => {
1801
- if (pointRegex.test(marginString)) {
1802
- const matchedParts = marginString.match(pointRegex);
1803
- // convert point to half point
1804
- return pointToTWIP(matchedParts[1]);
1805
- }
1806
- else if (pixelRegex.test(marginString)) {
1807
- const matchedParts = marginString.match(pixelRegex);
1808
- // convert pixels to half point
1809
- return pixelToTWIP(matchedParts[1]);
1810
- }
1811
- };
1812
- const modifiedStyleAttributesBuilder = (vNode, attributes, options) => {
1813
- const modifiedAttributes = Object.assign({}, attributes);
1814
- // styles
1815
- if (isVNode(vNode) && vNode.properties && vNode.properties.style) {
1816
- if (vNode.properties.style.color && !colorlessColors.includes(vNode.properties.style.color)) {
1817
- modifiedAttributes.color = fixupColorCode(vNode.properties.style.color);
1818
- }
1819
- if (vNode.properties.style['background-color'] &&
1820
- !colorlessColors.includes(vNode.properties.style['background-color'])) {
1821
- modifiedAttributes.backgroundColor = fixupColorCode(vNode.properties.style['background-color']);
1822
- }
1823
- if (vNode.properties.style['vertical-align'] &&
1824
- verticalAlignValues.includes(vNode.properties.style['vertical-align'])) {
1825
- modifiedAttributes.verticalAlign = vNode.properties.style['vertical-align'];
1826
- }
1827
- if (vNode.properties.style['text-align'] &&
1828
- ['left', 'right', 'center', 'justify'].includes(vNode.properties.style['text-align'])) {
1829
- modifiedAttributes.textAlign = vNode.properties.style['text-align'];
1830
- }
1831
- // FIXME: remove bold check when other font weights are handled.
1832
- if (vNode.properties.style['font-weight'] && vNode.properties.style['font-weight'] === 'bold') {
1833
- modifiedAttributes.strong = vNode.properties.style['font-weight'];
1834
- }
1835
- if (vNode.properties.style['font-size']) {
1836
- modifiedAttributes.fontSize = fixupFontSize$1(vNode.properties.style['font-size']);
1837
- }
1838
- if (vNode.properties.style['line-height']) {
1839
- modifiedAttributes.lineHeight = fixupLineHeight(vNode.properties.style['line-height'], vNode.properties.style['font-size']
1840
- ? fixupFontSize$1(vNode.properties.style['font-size'])
1841
- : null);
1842
- }
1843
- if (vNode.properties.style['margin-left'] || vNode.properties.style['margin-right']) {
1844
- const leftMargin = fixupMargin(vNode.properties.style['margin-left']);
1845
- const rightMargin = fixupMargin(vNode.properties.style['margin-right']);
1846
- const indentation = {};
1847
- if (leftMargin) {
1848
- indentation.left = leftMargin;
1849
- }
1850
- if (rightMargin) {
1851
- indentation.right = rightMargin;
1852
- }
1853
- if (leftMargin || rightMargin) {
1854
- modifiedAttributes.indentation = indentation;
1855
- }
1856
- }
1857
- if (vNode.properties.style.display) {
1858
- modifiedAttributes.display = vNode.properties.style.display;
1859
- }
1860
- if (vNode.properties.style.width) {
1861
- modifiedAttributes.width = vNode.properties.style.width;
1862
- }
1863
- }
1864
- // paragraph only
1865
- if (options && options.isParagraph) {
1866
- if (isVNode(vNode) && vNode.tagName === 'blockquote') {
1867
- modifiedAttributes.indentation = { left: 284 };
1868
- modifiedAttributes.textAlign = 'justify';
1869
- }
1870
- else if (isVNode(vNode) && vNode.tagName === 'code') {
1871
- modifiedAttributes.highlightColor = 'lightGray';
1872
- }
1873
- else if (isVNode(vNode) && vNode.tagName === 'pre') {
1874
- modifiedAttributes.font = 'Courier';
1875
- }
1876
- }
1877
- return modifiedAttributes;
1878
- };
1879
- // html tag to formatting function
1880
- // options are passed to the formatting function if needed
1881
- const buildFormatting = (htmlTag, options) => {
1882
- switch (htmlTag) {
1883
- case 'strong':
1884
- case 'b':
1885
- return buildBold();
1886
- case 'em':
1887
- case 'i':
1888
- return buildItalics();
1889
- case 'ins':
1890
- case 'u':
1891
- return buildUnderline();
1892
- case 'strike':
1893
- case 'del':
1894
- case 's':
1895
- return buildStrike();
1896
- case 'sub':
1897
- return buildVertAlign('subscript');
1898
- case 'sup':
1899
- return buildVertAlign('superscript');
1900
- case 'mark':
1901
- return buildHighlight();
1902
- case 'code':
1903
- return buildHighlight('lightGray');
1904
- case 'highlightColor':
1905
- return buildHighlight(options && options.color ? options.color : 'lightGray');
1906
- case 'font':
1907
- case 'pre':
1908
- return buildRunFontFragment('Courier');
1909
- case 'color':
1910
- return buildColor(options && options.color ? options.color : 'black');
1911
- case 'backgroundColor':
1912
- return buildShading(options && options.color ? options.color : 'black');
1913
- case 'fontSize':
1914
- // does this need a unit of measure?
1915
- return buildFontSize(options && options.fontSize ? options.fontSize : 10);
1916
- case 'hyperlink':
1917
- return buildRunStyleFragment('Hyperlink');
1918
- }
1919
- return null;
1920
- };
1921
- const buildRunProperties = (attributes) => {
1922
- const runPropertiesFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'rPr');
1923
- if (attributes && attributes.constructor === Object) {
1924
- Object.keys(attributes).forEach((key) => {
1925
- const options = {};
1926
- if (key === 'color' || key === 'backgroundColor' || key === 'highlightColor') {
1927
- options.color = attributes[key];
1928
- }
1929
- if (key === 'fontSize') {
1930
- options.fontSize = attributes[key];
1931
- }
1932
- const formattingFragment = buildFormatting(key, options);
1933
- if (formattingFragment) {
1934
- runPropertiesFragment.import(formattingFragment);
1935
- }
1936
- });
1937
- }
1938
- runPropertiesFragment.up();
1939
- return runPropertiesFragment;
1940
- };
1941
- const buildRun = (vNode, attributes, docxDocumentInstance) => __awaiter(void 0, void 0, void 0, function* () {
1942
- const runFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'r');
1943
- const runPropertiesFragment = buildRunProperties(cloneDeep(attributes));
1944
- // case where we have recursive spans representing font changes
1945
- if (isVNode(vNode) && vNode.tagName === 'span') {
1946
- // eslint-disable-next-line no-use-before-define
1947
- return buildRunOrRuns(vNode, attributes, docxDocumentInstance);
1948
- }
1949
- if (isVNode(vNode) &&
1950
- [
1951
- 'strong',
1952
- 'b',
1953
- 'em',
1954
- 'i',
1955
- 'u',
1956
- 'ins',
1957
- 'strike',
1958
- 'del',
1959
- 's',
1960
- 'sub',
1961
- 'sup',
1962
- 'mark',
1963
- 'blockquote',
1964
- 'code',
1965
- 'pre',
1966
- ].includes(vNode.tagName)) {
1967
- const runFragmentsArray = [];
1968
- let vNodes = [vNode];
1969
- // create temp run fragments to split the paragraph into different runs
1970
- let tempAttributes = cloneDeep(attributes);
1971
- let tempRunFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'r');
1972
- while (vNodes.length) {
1973
- const tempVNode = vNodes.shift();
1974
- if (isVText(tempVNode)) {
1975
- const textFragment = buildTextElement(tempVNode.text);
1976
- const tempRunPropertiesFragment = buildRunProperties(Object.assign(Object.assign({}, attributes), tempAttributes));
1977
- tempRunFragment.import(tempRunPropertiesFragment);
1978
- tempRunFragment.import(textFragment);
1979
- runFragmentsArray.push(tempRunFragment);
1980
- // re initialize temp run fragments with new fragment
1981
- tempAttributes = cloneDeep(attributes);
1982
- tempRunFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'r');
1983
- }
1984
- else if (isVNode(tempVNode)) {
1985
- if ([
1986
- 'strong',
1987
- 'b',
1988
- 'em',
1989
- 'i',
1990
- 'u',
1991
- 'ins',
1992
- 'strike',
1993
- 'del',
1994
- 's',
1995
- 'sub',
1996
- 'sup',
1997
- 'mark',
1998
- 'code',
1999
- 'pre',
2000
- ].includes(tempVNode.tagName)) {
2001
- tempAttributes = {};
2002
- switch (tempVNode.tagName) {
2003
- case 'strong':
2004
- case 'b':
2005
- tempAttributes.strong = true;
2006
- break;
2007
- case 'i':
2008
- tempAttributes.i = true;
2009
- break;
2010
- case 'u':
2011
- tempAttributes.u = true;
2012
- break;
2013
- case 'sub':
2014
- tempAttributes.sub = true;
2015
- break;
2016
- case 'sup':
2017
- tempAttributes.sup = true;
2018
- break;
2019
- }
2020
- const formattingFragment = buildFormatting(tempVNode);
2021
- if (formattingFragment) {
2022
- runPropertiesFragment.import(formattingFragment);
2023
- }
2024
- // go a layer deeper if there is a span somewhere in the children
2025
- }
2026
- else if (tempVNode.tagName === 'span') {
2027
- // eslint-disable-next-line no-use-before-define
2028
- const spanFragment = yield buildRunOrRuns(tempVNode, Object.assign(Object.assign({}, attributes), tempAttributes), docxDocumentInstance);
2029
- // if spanFragment is an array, we need to add each fragment to the runFragmentsArray. If the fragment is an array, perform a depth first search on the array to add each fragment to the runFragmentsArray
2030
- if (Array.isArray(spanFragment)) {
2031
- spanFragment.flat(Infinity);
2032
- runFragmentsArray.push(...spanFragment);
2033
- }
2034
- else {
2035
- runFragmentsArray.push(spanFragment);
2036
- }
2037
- // do not slice and concat children since this is already accounted for in the buildRunOrRuns function
2038
- // eslint-disable-next-line no-continue
2039
- continue;
2040
- }
2041
- }
2042
- if (tempVNode.children && tempVNode.children.length) {
2043
- if (tempVNode.children.length > 1) {
2044
- attributes = Object.assign(Object.assign({}, attributes), tempAttributes);
2045
- }
2046
- vNodes = tempVNode.children.slice().concat(vNodes);
2047
- }
2048
- }
2049
- if (runFragmentsArray.length) {
2050
- return runFragmentsArray;
2051
- }
2052
- }
2053
- runFragment.import(runPropertiesFragment);
2054
- if (isVText(vNode)) {
2055
- const textFragment = buildTextElement(vNode.text);
2056
- runFragment.import(textFragment);
2057
- }
2058
- else if (attributes && attributes.type === 'picture') {
2059
- let response = null;
2060
- const base64Uri = decodeURIComponent(vNode.properties.src);
2061
- if (base64Uri) {
2062
- response = docxDocumentInstance.createMediaFile(base64Uri);
2063
- }
2064
- if (response) {
2065
- docxDocumentInstance.zip
2066
- .folder('word')
2067
- .folder('media')
2068
- .file(response.fileNameWithExtension, Buffer.from(response.fileContent, 'base64'), {
2069
- createFolders: false,
2070
- });
2071
- const documentRelsId = docxDocumentInstance.createDocumentRelationships(docxDocumentInstance.relationshipFilename, imageType, `media/${response.fileNameWithExtension}`, internalRelationship);
2072
- attributes.inlineOrAnchored = true;
2073
- attributes.relationshipId = documentRelsId;
2074
- attributes.id = response.id;
2075
- attributes.fileContent = response.fileContent;
2076
- attributes.fileNameWithExtension = response.fileNameWithExtension;
2077
- }
2078
- const { type, inlineOrAnchored } = attributes, otherAttributes = __rest(attributes, ["type", "inlineOrAnchored"]);
2079
- // eslint-disable-next-line no-use-before-define
2080
- const imageFragment = buildDrawing(inlineOrAnchored, type, otherAttributes);
2081
- runFragment.import(imageFragment);
2082
- }
2083
- else if (isVNode(vNode) && vNode.tagName === 'br') {
2084
- const lineBreakFragment = buildLineBreak();
2085
- runFragment.import(lineBreakFragment);
2086
- }
2087
- runFragment.up();
2088
- return runFragment;
2089
- });
2090
- const buildRunOrRuns = (vNode, attributes, docxDocumentInstance) => __awaiter(void 0, void 0, void 0, function* () {
2091
- if (isVNode(vNode) && vNode.tagName === 'span') {
2092
- let runFragments = [];
2093
- for (let index = 0; index < vNode.children.length; index++) {
2094
- const childVNode = vNode.children[index];
2095
- const modifiedAttributes = modifiedStyleAttributesBuilder(vNode, attributes);
2096
- const tempRunFragments = yield buildRun(childVNode, modifiedAttributes, docxDocumentInstance);
2097
- runFragments = runFragments.concat(Array.isArray(tempRunFragments) ? tempRunFragments : [tempRunFragments]);
2098
- }
2099
- return runFragments;
2100
- }
2101
- else {
2102
- const tempRunFragments = yield buildRun(vNode, attributes, docxDocumentInstance);
2103
- return tempRunFragments;
2104
- }
2105
- });
2106
- const buildRunOrHyperLink = (vNode, attributes, docxDocumentInstance) => __awaiter(void 0, void 0, void 0, function* () {
2107
- if (isVNode(vNode) && vNode.tagName === 'a') {
2108
- const relationshipId = docxDocumentInstance.createDocumentRelationships(docxDocumentInstance.relationshipFilename, hyperlinkType, vNode.properties && vNode.properties.href ? vNode.properties.href : '');
2109
- const hyperlinkFragment = fragment({ namespaceAlias: { w: namespaces.w, r: namespaces.r } })
2110
- .ele('@w', 'hyperlink')
2111
- .att('@r', 'id', `rId${relationshipId}`);
2112
- const modifiedAttributes = Object.assign({}, attributes);
2113
- modifiedAttributes.hyperlink = true;
2114
- const runFragments = yield buildRunOrRuns(vNode.children[0], modifiedAttributes, docxDocumentInstance);
2115
- if (Array.isArray(runFragments)) {
2116
- for (let index = 0; index < runFragments.length; index++) {
2117
- const runFragment = runFragments[index];
2118
- hyperlinkFragment.import(runFragment);
2119
- }
2120
- }
2121
- else {
2122
- hyperlinkFragment.import(runFragments);
2123
- }
2124
- hyperlinkFragment.up();
2125
- return hyperlinkFragment;
2126
- }
2127
- const runFragments = yield buildRunOrRuns(vNode, attributes, docxDocumentInstance);
2128
- return runFragments;
2129
- });
2130
- const buildNumberingProperties = (levelId, numberingId) => fragment({ namespaceAlias: { w: namespaces.w } })
2131
- .ele('@w', 'numPr')
2132
- .ele('@w', 'ilvl')
2133
- .att('@w', 'val', String(levelId))
2134
- .up()
2135
- .ele('@w', 'numId')
2136
- .att('@w', 'val', String(numberingId))
2137
- .up()
2138
- .up();
2139
- const buildNumberingInstances = () => fragment({ namespaceAlias: { w: namespaces.w } })
2140
- .ele('@w', 'num')
2141
- .ele('@w', 'abstractNumId')
2142
- .up()
2143
- .up();
2144
- const buildSpacing = (lineSpacing, beforeSpacing, afterSpacing) => {
2145
- const spacingFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'spacing');
2146
- if (lineSpacing) {
2147
- spacingFragment.att('@w', 'line', lineSpacing);
2148
- }
2149
- if (beforeSpacing) {
2150
- spacingFragment.att('@w', 'before', beforeSpacing);
2151
- }
2152
- if (afterSpacing) {
2153
- spacingFragment.att('@w', 'after', afterSpacing);
2154
- }
2155
- spacingFragment.att('@w', 'lineRule', 'auto').up();
2156
- return spacingFragment;
2157
- };
2158
- const buildIndentation = ({ left, right }) => {
2159
- const indentationFragment = fragment({
2160
- namespaceAlias: { w: namespaces.w },
2161
- }).ele('@w', 'ind');
2162
- if (left) {
2163
- indentationFragment.att('@w', 'left', left);
2164
- }
2165
- if (right) {
2166
- indentationFragment.att('@w', 'right', right);
2167
- }
2168
- indentationFragment.up();
2169
- return indentationFragment;
2170
- };
2171
- const buildPStyle = (style = 'Normal') => fragment({ namespaceAlias: { w: namespaces.w } })
2172
- .ele('@w', 'pStyle')
2173
- .att('@w', 'val', style)
2174
- .up();
2175
- const buildHorizontalAlignment = (horizontalAlignment) => {
2176
- if (horizontalAlignment === 'justify') {
2177
- horizontalAlignment = 'both';
2178
- }
2179
- return fragment({ namespaceAlias: { w: namespaces.w } })
2180
- .ele('@w', 'jc')
2181
- .att('@w', 'val', horizontalAlignment)
2182
- .up();
2183
- };
2184
- const buildParagraphBorder = () => {
2185
- const paragraphBorderFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'pBdr');
2186
- const bordersObject = cloneDeep(paragraphBordersObject);
2187
- Object.keys(bordersObject).forEach((borderName) => {
2188
- if (bordersObject[borderName]) {
2189
- const { size, spacing, color } = bordersObject[borderName];
2190
- const borderFragment = buildBorder(borderName, size, spacing, color);
2191
- paragraphBorderFragment.import(borderFragment);
2192
- }
2193
- });
2194
- paragraphBorderFragment.up();
2195
- return paragraphBorderFragment;
2196
- };
2197
- const buildParagraphProperties = (attributes) => {
2198
- const paragraphPropertiesFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'pPr');
2199
- if (attributes && attributes.constructor === Object) {
2200
- Object.keys(attributes).forEach((key) => {
2201
- switch (key) {
2202
- case 'numbering':
2203
- const { levelId, numberingId } = attributes[key];
2204
- const numberingPropertiesFragment = buildNumberingProperties(levelId, numberingId);
2205
- paragraphPropertiesFragment.import(numberingPropertiesFragment);
2206
- // eslint-disable-next-line no-param-reassign
2207
- delete attributes.numbering;
2208
- break;
2209
- case 'textAlign':
2210
- const horizontalAlignmentFragment = buildHorizontalAlignment(attributes[key]);
2211
- paragraphPropertiesFragment.import(horizontalAlignmentFragment);
2212
- // eslint-disable-next-line no-param-reassign
2213
- delete attributes.textAlign;
2214
- break;
2215
- case 'backgroundColor':
2216
- // Add shading to Paragraph Properties only if display is block
2217
- // Essentially if background color needs to be across the row
2218
- if (attributes.display === 'block') {
2219
- const shadingFragment = buildShading(attributes[key]);
2220
- paragraphPropertiesFragment.import(shadingFragment);
2221
- // FIXME: Inner padding in case of shaded paragraphs.
2222
- const paragraphBorderFragment = buildParagraphBorder();
2223
- paragraphPropertiesFragment.import(paragraphBorderFragment);
2224
- // eslint-disable-next-line no-param-reassign
2225
- delete attributes.backgroundColor;
2226
- }
2227
- break;
2228
- case 'paragraphStyle':
2229
- const pStyleFragment = buildPStyle(attributes.paragraphStyle);
2230
- paragraphPropertiesFragment.import(pStyleFragment);
2231
- delete attributes.paragraphStyle;
2232
- break;
2233
- case 'indentation':
2234
- const indentationFragment = buildIndentation(attributes[key]);
2235
- paragraphPropertiesFragment.import(indentationFragment);
2236
- // eslint-disable-next-line no-param-reassign
2237
- delete attributes.indentation;
2238
- break;
2239
- }
2240
- });
2241
- const spacingFragment = buildSpacing(attributes.lineHeight, attributes.beforeSpacing, attributes.afterSpacing);
2242
- // eslint-disable-next-line no-param-reassign
2243
- delete attributes.lineHeight;
2244
- // eslint-disable-next-line no-param-reassign
2245
- delete attributes.beforeSpacing;
2246
- // eslint-disable-next-line no-param-reassign
2247
- delete attributes.afterSpacing;
2248
- paragraphPropertiesFragment.import(spacingFragment);
2249
- }
2250
- paragraphPropertiesFragment.up();
2251
- return paragraphPropertiesFragment;
2252
- };
2253
- const computeImageDimensions = (vNode, attributes) => {
2254
- const { maximumWidth, originalWidth, originalHeight } = attributes;
2255
- const aspectRatio = originalWidth / originalHeight;
2256
- const maximumWidthInEMU = TWIPToEMU(maximumWidth);
2257
- let originalWidthInEMU = pixelToEMU(originalWidth);
2258
- let originalHeightInEMU = pixelToEMU(originalHeight);
2259
- if (originalWidthInEMU > maximumWidthInEMU) {
2260
- originalWidthInEMU = maximumWidthInEMU;
2261
- originalHeightInEMU = Math.round(originalWidthInEMU / aspectRatio);
2262
- }
2263
- let modifiedHeight;
2264
- let modifiedWidth;
2265
- if (vNode.properties && vNode.properties.style) {
2266
- if (vNode.properties.style.width) {
2267
- if (vNode.properties.style.width !== 'auto') {
2268
- if (pixelRegex.test(vNode.properties.style.width)) {
2269
- modifiedWidth = pixelToEMU(vNode.properties.style.width.match(pixelRegex)[1]);
2270
- }
2271
- else if (percentageRegex.test(vNode.properties.style.width)) {
2272
- const percentageValue = vNode.properties.style.width.match(percentageRegex)[1];
2273
- modifiedWidth = Math.round((percentageValue / 100) * originalWidthInEMU);
2274
- }
2275
- }
2276
- else {
2277
- // eslint-disable-next-line no-lonely-if
2278
- if (vNode.properties.style.height && vNode.properties.style.height === 'auto') {
2279
- modifiedWidth = originalWidthInEMU;
2280
- modifiedHeight = originalHeightInEMU;
2281
- }
2282
- }
2283
- }
2284
- if (vNode.properties.style.height) {
2285
- if (vNode.properties.style.height !== 'auto') {
2286
- if (pixelRegex.test(vNode.properties.style.height)) {
2287
- modifiedHeight = pixelToEMU(vNode.properties.style.height.match(pixelRegex)[1]);
2288
- }
2289
- else if (percentageRegex.test(vNode.properties.style.height)) {
2290
- const percentageValue = vNode.properties.style.width.match(percentageRegex)[1];
2291
- modifiedHeight = Math.round((percentageValue / 100) * originalHeightInEMU);
2292
- if (!modifiedWidth) {
2293
- modifiedWidth = Math.round(modifiedHeight * aspectRatio);
2294
- }
2295
- }
2296
- }
2297
- else {
2298
- // eslint-disable-next-line no-lonely-if
2299
- if (modifiedWidth) {
2300
- if (!modifiedHeight) {
2301
- modifiedHeight = Math.round(modifiedWidth / aspectRatio);
2302
- }
2303
- }
2304
- else {
2305
- modifiedHeight = originalHeightInEMU;
2306
- modifiedWidth = originalWidthInEMU;
2307
- }
2308
- }
2309
- }
2310
- if (modifiedWidth && !modifiedHeight) {
2311
- modifiedHeight = Math.round(modifiedWidth / aspectRatio);
2312
- }
2313
- else if (modifiedHeight && !modifiedWidth) {
2314
- modifiedWidth = Math.round(modifiedHeight * aspectRatio);
2315
- }
2316
- }
2317
- else {
2318
- modifiedWidth = originalWidthInEMU;
2319
- modifiedHeight = originalHeightInEMU;
2320
- }
2321
- // eslint-disable-next-line no-param-reassign
2322
- attributes.width = modifiedWidth;
2323
- // eslint-disable-next-line no-param-reassign
2324
- attributes.height = modifiedHeight;
2325
- };
2326
- const buildParagraph = (vNode, attributes, docxDocumentInstance) => __awaiter(void 0, void 0, void 0, function* () {
2327
- const paragraphFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'p');
2328
- const modifiedAttributes = modifiedStyleAttributesBuilder(vNode, attributes, {
2329
- isParagraph: true,
2330
- });
2331
- const paragraphPropertiesFragment = buildParagraphProperties(modifiedAttributes);
2332
- paragraphFragment.import(paragraphPropertiesFragment);
2333
- if (isVNode(vNode) && vNodeHasChildren(vNode)) {
2334
- if ([
2335
- 'span',
2336
- 'strong',
2337
- 'b',
2338
- 'em',
2339
- 'i',
2340
- 'u',
2341
- 'ins',
2342
- 'strike',
2343
- 'del',
2344
- 's',
2345
- 'sub',
2346
- 'sup',
2347
- 'mark',
2348
- 'a',
2349
- 'code',
2350
- 'pre',
2351
- ].includes(vNode.tagName)) {
2352
- const runOrHyperlinkFragments = yield buildRunOrHyperLink(vNode, modifiedAttributes, docxDocumentInstance);
2353
- if (Array.isArray(runOrHyperlinkFragments)) {
2354
- for (let iteratorIndex = 0; iteratorIndex < runOrHyperlinkFragments.length; iteratorIndex++) {
2355
- const runOrHyperlinkFragment = runOrHyperlinkFragments[iteratorIndex];
2356
- paragraphFragment.import(runOrHyperlinkFragment);
2357
- }
2358
- }
2359
- else {
2360
- paragraphFragment.import(runOrHyperlinkFragments);
2361
- }
2362
- }
2363
- else if (vNode.tagName === 'blockquote') {
2364
- const runFragmentOrFragments = yield buildRun(vNode, attributes);
2365
- if (Array.isArray(runFragmentOrFragments)) {
2366
- for (let index = 0; index < runFragmentOrFragments.length; index++) {
2367
- paragraphFragment.import(runFragmentOrFragments[index]);
2368
- }
2369
- }
2370
- else {
2371
- paragraphFragment.import(runFragmentOrFragments);
2372
- }
2373
- }
2374
- else {
2375
- for (let index = 0; index < vNode.children.length; index++) {
2376
- const childVNode = vNode.children[index];
2377
- if (childVNode.tagName === 'img') {
2378
- let base64String;
2379
- const imageSource = childVNode.properties.src;
2380
- if (isValidUrl(imageSource)) {
2381
- base64String = yield imageToBase64(imageSource).catch((error) => {
2382
- // eslint-disable-next-line no-console
2383
- console.warning(`skipping image download and conversion due to ${error}`);
2384
- });
2385
- if (base64String && mimeTypes.lookup(imageSource)) {
2386
- childVNode.properties.src = `data:${mimeTypes.lookup(imageSource)};base64, ${base64String}`;
2387
- }
2388
- else {
2389
- break;
2390
- }
2391
- }
2392
- else {
2393
- // eslint-disable-next-line no-useless-escape, prefer-destructuring
2394
- base64String = imageSource.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/)[2];
2395
- }
2396
- const imageBuffer = Buffer.from(decodeURIComponent(base64String), 'base64');
2397
- const imageProperties = sizeOf(imageBuffer);
2398
- modifiedAttributes.maximumWidth =
2399
- modifiedAttributes.maximumWidth || docxDocumentInstance.availableDocumentSpace;
2400
- modifiedAttributes.originalWidth = imageProperties.width;
2401
- modifiedAttributes.originalHeight = imageProperties.height;
2402
- computeImageDimensions(childVNode, modifiedAttributes);
2403
- }
2404
- const runOrHyperlinkFragments = yield buildRunOrHyperLink(childVNode, isVNode(childVNode) && childVNode.tagName === 'img'
2405
- ? Object.assign(Object.assign({}, modifiedAttributes), { type: 'picture' }) : modifiedAttributes, docxDocumentInstance);
2406
- if (Array.isArray(runOrHyperlinkFragments)) {
2407
- for (let iteratorIndex = 0; iteratorIndex < runOrHyperlinkFragments.length; iteratorIndex++) {
2408
- const runOrHyperlinkFragment = runOrHyperlinkFragments[iteratorIndex];
2409
- paragraphFragment.import(runOrHyperlinkFragment);
2410
- }
2411
- }
2412
- else {
2413
- paragraphFragment.import(runOrHyperlinkFragments);
2414
- }
2415
- }
2416
- }
2417
- }
2418
- else {
2419
- // In case paragraphs has to be rendered where vText is present. Eg. table-cell
2420
- // Or in case the vNode is something like img
2421
- if (isVNode(vNode) && vNode.tagName === 'img') {
2422
- const imageSource = vNode.properties.src;
2423
- let base64String = imageSource;
2424
- if (isValidUrl(imageSource)) {
2425
- base64String = yield imageToBase64(imageSource).catch((error) => {
2426
- // eslint-disable-next-line no-console
2427
- console.warning(`skipping image download and conversion due to ${error}`);
2428
- });
2429
- if (base64String && mimeTypes.lookup(imageSource)) {
2430
- vNode.properties.src = `data:${mimeTypes.lookup(imageSource)};base64, ${base64String}`;
2431
- }
2432
- else {
2433
- paragraphFragment.up();
2434
- return paragraphFragment;
2435
- }
2436
- }
2437
- else {
2438
- // eslint-disable-next-line no-useless-escape, prefer-destructuring
2439
- base64String = base64String.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/)[2];
2440
- }
2441
- const imageBuffer = Buffer.from(decodeURIComponent(base64String), 'base64');
2442
- const imageProperties = sizeOf(imageBuffer);
2443
- modifiedAttributes.maximumWidth =
2444
- modifiedAttributes.maximumWidth || docxDocumentInstance.availableDocumentSpace;
2445
- modifiedAttributes.originalWidth = imageProperties.width;
2446
- modifiedAttributes.originalHeight = imageProperties.height;
2447
- computeImageDimensions(vNode, modifiedAttributes);
2448
- }
2449
- const runFragments = yield buildRunOrRuns(vNode, modifiedAttributes, docxDocumentInstance);
2450
- if (Array.isArray(runFragments)) {
2451
- for (let index = 0; index < runFragments.length; index++) {
2452
- const runFragment = runFragments[index];
2453
- paragraphFragment.import(runFragment);
2454
- }
2455
- }
2456
- else {
2457
- paragraphFragment.import(runFragments);
2458
- }
2459
- }
2460
- paragraphFragment.up();
2461
- return paragraphFragment;
2462
- });
2463
- const buildGridSpanFragment = (spanValue) => fragment({ namespaceAlias: { w: namespaces.w } })
2464
- .ele('@w', 'gridSpan')
2465
- .att('@w', 'val', spanValue)
2466
- .up();
2467
- const buildTableCellSpacing = (cellSpacing = 0) => fragment({ namespaceAlias: { w: namespaces.w } })
2468
- .ele('@w', 'tblCellSpacing')
2469
- .att('@w', 'w', cellSpacing)
2470
- .att('@w', 'type', 'dxa')
2471
- .up();
2472
- const buildTableCellBorders = (tableCellBorder) => {
2473
- const tableCellBordersFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'tcBorders');
2474
- const { color, stroke } = tableCellBorder, borders = __rest(tableCellBorder, ["color", "stroke"]);
2475
- Object.keys(borders).forEach((border) => {
2476
- if (tableCellBorder[border]) {
2477
- const borderFragment = buildBorder(border, tableCellBorder[border], 0, color, stroke);
2478
- tableCellBordersFragment.import(borderFragment);
2479
- }
2480
- });
2481
- tableCellBordersFragment.up();
2482
- return tableCellBordersFragment;
2483
- };
2484
- const buildTableCellWidth = (tableCellWidth) => fragment({ namespaceAlias: { w: namespaces.w } })
2485
- .ele('@w', 'tcW')
2486
- .att('@w', 'w', fixupColumnWidth(tableCellWidth))
2487
- .att('@w', 'type', 'dxa')
2488
- .up();
2489
- const buildTableCellProperties = (attributes) => {
2490
- const tableCellPropertiesFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'tcPr');
2491
- if (attributes && attributes.constructor === Object) {
2492
- Object.keys(attributes).forEach((key) => {
2493
- switch (key) {
2494
- case 'backgroundColor':
2495
- const shadingFragment = buildShading(attributes[key]);
2496
- tableCellPropertiesFragment.import(shadingFragment);
2497
- // eslint-disable-next-line no-param-reassign
2498
- delete attributes.backgroundColor;
2499
- break;
2500
- case 'verticalAlign':
2501
- const verticalAlignmentFragment = buildVerticalAlignment(attributes[key]);
2502
- tableCellPropertiesFragment.import(verticalAlignmentFragment);
2503
- // eslint-disable-next-line no-param-reassign
2504
- delete attributes.verticalAlign;
2505
- break;
2506
- case 'colSpan':
2507
- const gridSpanFragment = buildGridSpanFragment(attributes[key]);
2508
- tableCellPropertiesFragment.import(gridSpanFragment);
2509
- // eslint-disable-next-line no-param-reassign
2510
- delete attributes.colSpan;
2511
- break;
2512
- case 'tableCellBorder':
2513
- const tableCellBorderFragment = buildTableCellBorders(attributes[key]);
2514
- tableCellPropertiesFragment.import(tableCellBorderFragment);
2515
- // eslint-disable-next-line no-param-reassign
2516
- delete attributes.tableCellBorder;
2517
- break;
2518
- case 'rowSpan':
2519
- const verticalMergeFragment = buildVerticalMerge(attributes[key]);
2520
- tableCellPropertiesFragment.import(verticalMergeFragment);
2521
- delete attributes.rowSpan;
2522
- break;
2523
- case 'width':
2524
- const widthFragment = buildTableCellWidth(attributes[key]);
2525
- tableCellPropertiesFragment.import(widthFragment);
2526
- delete attributes.width;
2527
- break;
2528
- }
2529
- });
2530
- }
2531
- tableCellPropertiesFragment.up();
2532
- return tableCellPropertiesFragment;
2533
- };
2534
- const fixupTableCellBorder = (vNode, attributes) => {
2535
- if (Object.prototype.hasOwnProperty.call(vNode.properties.style, 'border')) {
2536
- if (vNode.properties.style.border === 'none' || vNode.properties.style.border === 0) {
2537
- attributes.tableCellBorder = {};
2538
- }
2539
- else {
2540
- // eslint-disable-next-line no-use-before-define
2541
- const [borderSize, borderStroke, borderColor] = cssBorderParser(vNode.properties.style.border);
2542
- attributes.tableCellBorder = {
2543
- top: borderSize,
2544
- left: borderSize,
2545
- bottom: borderSize,
2546
- right: borderSize,
2547
- color: borderColor,
2548
- stroke: borderStroke,
2549
- };
2550
- }
2551
- }
2552
- if (vNode.properties.style['border-top'] && vNode.properties.style['border-top'] === '0') {
2553
- attributes.tableCellBorder = Object.assign(Object.assign({}, attributes.tableCellBorder), { top: 0 });
2554
- }
2555
- else if (vNode.properties.style['border-top'] && vNode.properties.style['border-top'] !== '0') {
2556
- // eslint-disable-next-line no-use-before-define
2557
- const [borderSize, borderStroke, borderColor] = cssBorderParser(vNode.properties.style['border-top']);
2558
- attributes.tableCellBorder = Object.assign(Object.assign({}, attributes.tableCellBorder), { top: borderSize, color: borderColor, stroke: borderStroke });
2559
- }
2560
- if (vNode.properties.style['border-left'] && vNode.properties.style['border-left'] === '0') {
2561
- attributes.tableCellBorder = Object.assign(Object.assign({}, attributes.tableCellBorder), { left: 0 });
2562
- }
2563
- else if (vNode.properties.style['border-left'] &&
2564
- vNode.properties.style['border-left'] !== '0') {
2565
- // eslint-disable-next-line no-use-before-define
2566
- const [borderSize, borderStroke, borderColor] = cssBorderParser(vNode.properties.style['border-left']);
2567
- attributes.tableCellBorder = Object.assign(Object.assign({}, attributes.tableCellBorder), { left: borderSize, color: borderColor, stroke: borderStroke });
2568
- }
2569
- if (vNode.properties.style['border-bottom'] && vNode.properties.style['border-bottom'] === '0') {
2570
- attributes.tableCellBorder = Object.assign(Object.assign({}, attributes.tableCellBorder), { bottom: 0 });
2571
- }
2572
- else if (vNode.properties.style['border-bottom'] &&
2573
- vNode.properties.style['border-bottom'] !== '0') {
2574
- // eslint-disable-next-line no-use-before-define
2575
- const [borderSize, borderStroke, borderColor] = cssBorderParser(vNode.properties.style['border-bottom']);
2576
- attributes.tableCellBorder = Object.assign(Object.assign({}, attributes.tableCellBorder), { bottom: borderSize, color: borderColor, stroke: borderStroke });
2577
- }
2578
- if (vNode.properties.style['border-right'] && vNode.properties.style['border-right'] === '0') {
2579
- attributes.tableCellBorder = Object.assign(Object.assign({}, attributes.tableCellBorder), { right: 0 });
2580
- }
2581
- else if (vNode.properties.style['border-right'] &&
2582
- vNode.properties.style['border-right'] !== '0') {
2583
- // eslint-disable-next-line no-use-before-define
2584
- const [borderSize, borderStroke, borderColor] = cssBorderParser(vNode.properties.style['border-right']);
2585
- attributes.tableCellBorder = Object.assign(Object.assign({}, attributes.tableCellBorder), { right: borderSize, color: borderColor, stroke: borderStroke });
2586
- }
2587
- };
2588
- const buildTableCell = (vNode, attributes, rowSpanMap, columnIndex, docxDocumentInstance) => __awaiter(void 0, void 0, void 0, function* () {
2589
- const tableCellFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'tc');
2590
- let modifiedAttributes = Object.assign({}, attributes);
2591
- if (isVNode(vNode) && vNode.properties) {
2592
- if (vNode.properties.rowSpan) {
2593
- rowSpanMap.set(columnIndex.index, { rowSpan: vNode.properties.rowSpan - 1, colSpan: 0 });
2594
- modifiedAttributes.rowSpan = 'restart';
2595
- }
2596
- else {
2597
- const previousSpanObject = rowSpanMap.get(columnIndex.index);
2598
- rowSpanMap.set(columnIndex.index,
2599
- // eslint-disable-next-line prefer-object-spread
2600
- Object.assign({}, previousSpanObject, {
2601
- rowSpan: 0,
2602
- colSpan: (previousSpanObject && previousSpanObject.colSpan) || 0,
2603
- }));
2604
- }
2605
- if (vNode.properties.colSpan ||
2606
- (vNode.properties.style && vNode.properties.style['column-span'])) {
2607
- modifiedAttributes.colSpan =
2608
- vNode.properties.colSpan ||
2609
- (vNode.properties.style && vNode.properties.style['column-span']);
2610
- const previousSpanObject = rowSpanMap.get(columnIndex.index);
2611
- rowSpanMap.set(columnIndex.index,
2612
- // eslint-disable-next-line prefer-object-spread
2613
- Object.assign({}, previousSpanObject, {
2614
- colSpan: parseInt(modifiedAttributes.colSpan) || 0,
2615
- }));
2616
- columnIndex.index += parseInt(modifiedAttributes.colSpan) - 1;
2617
- }
2618
- if (vNode.properties.style) {
2619
- modifiedAttributes = Object.assign(Object.assign({}, modifiedAttributes), modifiedStyleAttributesBuilder(vNode, attributes));
2620
- fixupTableCellBorder(vNode, modifiedAttributes);
2621
- }
2622
- }
2623
- const tableCellPropertiesFragment = buildTableCellProperties(modifiedAttributes);
2624
- tableCellFragment.import(tableCellPropertiesFragment);
2625
- if (vNodeHasChildren(vNode)) {
2626
- for (let index = 0; index < vNode.children.length; index++) {
2627
- const childVNode = vNode.children[index];
2628
- if (isVNode(childVNode) && childVNode.tagName === 'img') {
2629
- const imageFragment = yield buildImage(docxDocumentInstance, childVNode, modifiedAttributes.maximumWidth);
2630
- if (imageFragment) {
2631
- tableCellFragment.import(imageFragment);
2632
- }
2633
- }
2634
- else if (isVNode(childVNode) && childVNode.tagName === 'figure') {
2635
- if (vNodeHasChildren(childVNode)) {
2636
- // eslint-disable-next-line no-plusplus
2637
- for (let iteratorIndex = 0; iteratorIndex < childVNode.children.length; iteratorIndex++) {
2638
- const grandChildVNode = childVNode.children[iteratorIndex];
2639
- if (grandChildVNode.tagName === 'img') {
2640
- const imageFragment = yield buildImage(docxDocumentInstance, grandChildVNode, modifiedAttributes.maximumWidth);
2641
- if (imageFragment) {
2642
- tableCellFragment.import(imageFragment);
2643
- }
2644
- }
2645
- }
2646
- }
2647
- }
2648
- else if (isVNode(childVNode) && ['ul', 'ol'].includes(childVNode.tagName)) {
2649
- // render list in table
2650
- if (vNodeHasChildren(childVNode)) {
2651
- yield buildList(childVNode, docxDocumentInstance, tableCellFragment);
2652
- }
2653
- }
2654
- else {
2655
- const paragraphFragment = yield buildParagraph(childVNode, modifiedAttributes, docxDocumentInstance);
2656
- tableCellFragment.import(paragraphFragment);
2657
- }
2658
- }
2659
- }
2660
- else {
2661
- // TODO: Figure out why building with buildParagraph() isn't working
2662
- const paragraphFragment = fragment({ namespaceAlias: { w: namespaces.w } })
2663
- .ele('@w', 'p')
2664
- .up();
2665
- tableCellFragment.import(paragraphFragment);
2666
- }
2667
- tableCellFragment.up();
2668
- return tableCellFragment;
2669
- });
2670
- const buildRowSpanCell = (rowSpanMap, columnIndex, attributes) => {
2671
- const rowSpanCellFragments = [];
2672
- let spanObject = rowSpanMap.get(columnIndex.index);
2673
- while (spanObject && spanObject.rowSpan) {
2674
- const rowSpanCellFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'tc');
2675
- const tableCellPropertiesFragment = buildTableCellProperties(Object.assign(Object.assign({}, attributes), { rowSpan: 'continue', colSpan: spanObject.colSpan ? spanObject.colSpan : 0 }));
2676
- rowSpanCellFragment.import(tableCellPropertiesFragment);
2677
- const paragraphFragment = fragment({ namespaceAlias: { w: namespaces.w } })
2678
- .ele('@w', 'p')
2679
- .up();
2680
- rowSpanCellFragment.import(paragraphFragment);
2681
- rowSpanCellFragment.up();
2682
- rowSpanCellFragments.push(rowSpanCellFragment);
2683
- if (spanObject.rowSpan - 1 === 0) {
2684
- rowSpanMap.delete(columnIndex.index);
2685
- }
2686
- else {
2687
- rowSpanMap.set(columnIndex.index, {
2688
- rowSpan: spanObject.rowSpan - 1,
2689
- colSpan: spanObject.colSpan || 0,
2690
- });
2691
- }
2692
- columnIndex.index += spanObject.colSpan || 1;
2693
- spanObject = rowSpanMap.get(columnIndex.index);
2694
- }
2695
- return rowSpanCellFragments;
2696
- };
2697
- const buildTableRowProperties = (attributes) => {
2698
- const tableRowPropertiesFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'trPr');
2699
- if (attributes && attributes.constructor === Object) {
2700
- Object.keys(attributes).forEach((key) => {
2701
- switch (key) {
2702
- case 'tableRowHeight':
2703
- const tableRowHeightFragment = buildTableRowHeight(attributes[key]);
2704
- tableRowPropertiesFragment.import(tableRowHeightFragment);
2705
- // eslint-disable-next-line no-param-reassign
2706
- delete attributes.tableRowHeight;
2707
- break;
2708
- case 'rowCantSplit':
2709
- if (attributes.rowCantSplit) {
2710
- const cantSplitFragment = fragment({ namespaceAlias: { w: namespaces.w } })
2711
- .ele('@w', 'cantSplit')
2712
- .up();
2713
- tableRowPropertiesFragment.import(cantSplitFragment);
2714
- // eslint-disable-next-line no-param-reassign
2715
- delete attributes.rowCantSplit;
2716
- }
2717
- break;
2718
- }
2719
- });
2720
- }
2721
- tableRowPropertiesFragment.up();
2722
- return tableRowPropertiesFragment;
2723
- };
2724
- const buildTableRow = (vNode, attributes, rowSpanMap, docxDocumentInstance) => __awaiter(void 0, void 0, void 0, function* () {
2725
- const tableRowFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'tr');
2726
- const modifiedAttributes = Object.assign({}, attributes);
2727
- if (isVNode(vNode) && vNode.properties) {
2728
- // FIXME: find a better way to get row height from cell style
2729
- if ((vNode.properties.style && vNode.properties.style.height) ||
2730
- (vNode.children[0] &&
2731
- isVNode(vNode.children[0]) &&
2732
- vNode.children[0].properties.style &&
2733
- vNode.children[0].properties.style.height)) {
2734
- modifiedAttributes.tableRowHeight = fixupRowHeight((vNode.properties.style && vNode.properties.style.height) ||
2735
- (vNode.children[0] &&
2736
- isVNode(vNode.children[0]) &&
2737
- vNode.children[0].properties.style &&
2738
- vNode.children[0].properties.style.height
2739
- ? vNode.children[0].properties.style.height
2740
- : undefined));
2741
- }
2742
- if (vNode.properties.style) {
2743
- fixupTableCellBorder(vNode, modifiedAttributes);
2744
- }
2745
- }
2746
- const tableRowPropertiesFragment = buildTableRowProperties(modifiedAttributes);
2747
- tableRowFragment.import(tableRowPropertiesFragment);
2748
- const columnIndex = { index: 0 };
2749
- if (vNodeHasChildren(vNode)) {
2750
- const tableColumns = vNode.children.filter((childVNode) => ['td', 'th'].includes(childVNode.tagName));
2751
- const maximumColumnWidth = docxDocumentInstance.availableDocumentSpace / tableColumns.length;
2752
- // eslint-disable-next-line no-restricted-syntax
2753
- for (const column of tableColumns) {
2754
- const rowSpanCellFragments = buildRowSpanCell(rowSpanMap, columnIndex, modifiedAttributes);
2755
- if (Array.isArray(rowSpanCellFragments)) {
2756
- for (let iteratorIndex = 0; iteratorIndex < rowSpanCellFragments.length; iteratorIndex++) {
2757
- const rowSpanCellFragment = rowSpanCellFragments[iteratorIndex];
2758
- tableRowFragment.import(rowSpanCellFragment);
2759
- }
2760
- }
2761
- const tableCellFragment = yield buildTableCell(column, Object.assign(Object.assign({}, modifiedAttributes), { maximumWidth: maximumColumnWidth }), rowSpanMap, columnIndex, docxDocumentInstance);
2762
- columnIndex.index++;
2763
- tableRowFragment.import(tableCellFragment);
2764
- }
2765
- }
2766
- if (columnIndex.index < rowSpanMap.size) {
2767
- const rowSpanCellFragments = buildRowSpanCell(rowSpanMap, columnIndex, modifiedAttributes);
2768
- if (Array.isArray(rowSpanCellFragments)) {
2769
- for (let iteratorIndex = 0; iteratorIndex < rowSpanCellFragments.length; iteratorIndex++) {
2770
- const rowSpanCellFragment = rowSpanCellFragments[iteratorIndex];
2771
- tableRowFragment.import(rowSpanCellFragment);
2772
- }
2773
- }
2774
- }
2775
- tableRowFragment.up();
2776
- return tableRowFragment;
2777
- });
2778
- const buildTableGridCol = (gridWidth) => fragment({ namespaceAlias: { w: namespaces.w } })
2779
- .ele('@w', 'gridCol')
2780
- .att('@w', 'w', String(gridWidth));
2781
- const buildTableGrid = (vNode, attributes) => {
2782
- const tableGridFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'tblGrid');
2783
- if (vNodeHasChildren(vNode)) {
2784
- const gridColumns = vNode.children.filter((childVNode) => childVNode.tagName === 'col');
2785
- const gridWidth = attributes.maximumWidth / gridColumns.length;
2786
- for (let index = 0; index < gridColumns.length; index++) {
2787
- const tableGridColFragment = buildTableGridCol(gridWidth);
2788
- tableGridFragment.import(tableGridColFragment);
2789
- }
2790
- }
2791
- tableGridFragment.up();
2792
- return tableGridFragment;
2793
- };
2794
- const buildTableGridFromTableRow = (vNode, attributes) => {
2795
- const tableGridFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'tblGrid');
2796
- if (vNodeHasChildren(vNode)) {
2797
- const numberOfGridColumns = vNode.children.reduce((accumulator, childVNode) => {
2798
- const colSpan = childVNode.properties.colSpan ||
2799
- (childVNode.properties.style && childVNode.properties.style['column-span']);
2800
- return accumulator + (colSpan ? parseInt(colSpan) : 1);
2801
- }, 0);
2802
- const gridWidth = attributes.maximumWidth / numberOfGridColumns;
2803
- for (let index = 0; index < numberOfGridColumns; index++) {
2804
- const tableGridColFragment = buildTableGridCol(gridWidth);
2805
- tableGridFragment.import(tableGridColFragment);
2806
- }
2807
- }
2808
- tableGridFragment.up();
2809
- return tableGridFragment;
2810
- };
2811
- const buildTableBorders = (tableBorder) => {
2812
- const tableBordersFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'tblBorders');
2813
- const { color, stroke } = tableBorder, borders = __rest(tableBorder, ["color", "stroke"]);
2814
- Object.keys(borders).forEach((border) => {
2815
- if (borders[border]) {
2816
- const borderFragment = buildBorder(border, borders[border], 0, color, stroke);
2817
- tableBordersFragment.import(borderFragment);
2818
- }
2819
- });
2820
- tableBordersFragment.up();
2821
- return tableBordersFragment;
2822
- };
2823
- const buildTableWidth = (tableWidth) => fragment({ namespaceAlias: { w: namespaces.w } })
2824
- .ele('@w', 'tblW')
2825
- .att('@w', 'type', 'dxa')
2826
- .att('@w', 'w', String(tableWidth))
2827
- .up();
2828
- const buildCellMargin = (side, margin) => fragment({ namespaceAlias: { w: namespaces.w } })
2829
- .ele('@w', side)
2830
- .att('@w', 'type', 'dxa')
2831
- .att('@w', 'w', String(margin))
2832
- .up();
2833
- const buildTableCellMargins = (margin) => {
2834
- const tableCellMarFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'tblCellMar');
2835
- ['top', 'bottom'].forEach((side) => {
2836
- const marginFragment = buildCellMargin(side, margin / 2);
2837
- tableCellMarFragment.import(marginFragment);
2838
- });
2839
- ['left', 'right'].forEach((side) => {
2840
- const marginFragment = buildCellMargin(side, margin);
2841
- tableCellMarFragment.import(marginFragment);
2842
- });
2843
- return tableCellMarFragment;
2844
- };
2845
- const buildTableProperties = (attributes) => {
2846
- const tablePropertiesFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'tblPr');
2847
- if (attributes && attributes.constructor === Object) {
2848
- Object.keys(attributes).forEach((key) => {
2849
- switch (key) {
2850
- case 'tableBorder':
2851
- const tableBordersFragment = buildTableBorders(attributes[key]);
2852
- tablePropertiesFragment.import(tableBordersFragment);
2853
- // eslint-disable-next-line no-param-reassign
2854
- delete attributes.tableBorder;
2855
- break;
2856
- case 'tableCellSpacing':
2857
- const tableCellSpacingFragment = buildTableCellSpacing(attributes[key]);
2858
- tablePropertiesFragment.import(tableCellSpacingFragment);
2859
- // eslint-disable-next-line no-param-reassign
2860
- delete attributes.tableCellSpacing;
2861
- break;
2862
- case 'width':
2863
- if (attributes[key]) {
2864
- const tableWidthFragment = buildTableWidth(attributes[key]);
2865
- tablePropertiesFragment.import(tableWidthFragment);
2866
- }
2867
- // eslint-disable-next-line no-param-reassign
2868
- delete attributes.width;
2869
- break;
2870
- }
2871
- });
2872
- }
2873
- const tableCellMarginFragment = buildTableCellMargins(160);
2874
- tablePropertiesFragment.import(tableCellMarginFragment);
2875
- // by default, all tables are center aligned.
2876
- const alignmentFragment = buildHorizontalAlignment('center');
2877
- tablePropertiesFragment.import(alignmentFragment);
2878
- tablePropertiesFragment.up();
2879
- return tablePropertiesFragment;
2880
- };
2881
- const cssBorderParser = (borderString) => {
2882
- let [size, stroke, color] = borderString.split(' ');
2883
- if (pointRegex.test(size)) {
2884
- const matchedParts = size.match(pointRegex);
2885
- // convert point to eighth of a point
2886
- size = pointToEIP(matchedParts[1]);
2887
- }
2888
- else if (pixelRegex.test(size)) {
2889
- const matchedParts = size.match(pixelRegex);
2890
- // convert pixels to eighth of a point
2891
- size = pixelToEIP(matchedParts[1]);
2892
- }
2893
- stroke = stroke && ['dashed', 'dotted', 'double'].includes(stroke) ? stroke : 'single';
2894
- color = color && fixupColorCode(color).toUpperCase();
2895
- return [size, stroke, color];
2896
- };
2897
- const buildTable = (vNode, attributes, docxDocumentInstance) => __awaiter(void 0, void 0, void 0, function* () {
2898
- const tableFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'tbl');
2899
- const modifiedAttributes = Object.assign({}, attributes);
2900
- if (isVNode(vNode) && vNode.properties) {
2901
- const tableAttributes = vNode.properties.attributes || {};
2902
- const tableStyles = vNode.properties.style || {};
2903
- const tableBorders = {};
2904
- const tableCellBorders = {};
2905
- let [borderSize, borderStrike, borderColor] = [2, 'single', '000000'];
2906
- // eslint-disable-next-line no-restricted-globals
2907
- if (!isNaN(tableAttributes.border)) {
2908
- borderSize = parseInt(tableAttributes.border, 10);
2909
- }
2910
- // css style overrides table border properties
2911
- if (tableStyles.border) {
2912
- const [cssSize, cssStroke, cssColor] = cssBorderParser(tableStyles.border);
2913
- borderSize = cssSize || borderSize;
2914
- borderColor = cssColor || borderColor;
2915
- borderStrike = cssStroke || borderStrike;
2916
- }
2917
- tableBorders.top = borderSize;
2918
- tableBorders.bottom = borderSize;
2919
- tableBorders.left = borderSize;
2920
- tableBorders.right = borderSize;
2921
- tableBorders.stroke = borderStrike;
2922
- tableBorders.color = borderColor;
2923
- if (tableStyles['border-collapse'] === 'collapse') {
2924
- tableBorders.insideV = borderSize;
2925
- tableBorders.insideH = borderSize;
2926
- }
2927
- else {
2928
- tableBorders.insideV = 0;
2929
- tableBorders.insideH = 0;
2930
- tableCellBorders.top = 1;
2931
- tableCellBorders.bottom = 1;
2932
- tableCellBorders.left = 1;
2933
- tableCellBorders.right = 1;
2934
- }
2935
- modifiedAttributes.tableBorder = tableBorders;
2936
- modifiedAttributes.tableCellSpacing = 0;
2937
- if (Object.keys(tableCellBorders).length) {
2938
- modifiedAttributes.tableCellBorder = tableCellBorders;
2939
- }
2940
- let minimumWidth;
2941
- let maximumWidth;
2942
- let width;
2943
- // Calculate minimum width of table
2944
- if (pixelRegex.test(tableStyles['min-width'])) {
2945
- minimumWidth = pixelToTWIP(tableStyles['min-width'].match(pixelRegex)[1]);
2946
- }
2947
- else if (percentageRegex.test(tableStyles['min-width'])) {
2948
- const percentageValue = tableStyles['min-width'].match(percentageRegex)[1];
2949
- minimumWidth = Math.round((percentageValue / 100) * attributes.maximumWidth);
2950
- }
2951
- // Calculate maximum width of table
2952
- if (pixelRegex.test(tableStyles['max-width'])) {
2953
- pixelRegex.lastIndex = 0;
2954
- maximumWidth = pixelToTWIP(tableStyles['max-width'].match(pixelRegex)[1]);
2955
- }
2956
- else if (percentageRegex.test(tableStyles['max-width'])) {
2957
- percentageRegex.lastIndex = 0;
2958
- const percentageValue = tableStyles['max-width'].match(percentageRegex)[1];
2959
- maximumWidth = Math.round((percentageValue / 100) * attributes.maximumWidth);
2960
- }
2961
- // Calculate specified width of table
2962
- if (pixelRegex.test(tableStyles.width)) {
2963
- pixelRegex.lastIndex = 0;
2964
- width = pixelToTWIP(tableStyles.width.match(pixelRegex)[1]);
2965
- }
2966
- else if (percentageRegex.test(tableStyles.width)) {
2967
- percentageRegex.lastIndex = 0;
2968
- const percentageValue = tableStyles.width.match(percentageRegex)[1];
2969
- width = Math.round((percentageValue / 100) * attributes.maximumWidth);
2970
- }
2971
- // If width isn't supplied, we should have min-width as the width.
2972
- if (width) {
2973
- modifiedAttributes.width = width;
2974
- if (maximumWidth) {
2975
- modifiedAttributes.width = Math.min(modifiedAttributes.width, maximumWidth);
2976
- }
2977
- if (minimumWidth) {
2978
- modifiedAttributes.width = Math.max(modifiedAttributes.width, minimumWidth);
2979
- }
2980
- }
2981
- else if (minimumWidth) {
2982
- modifiedAttributes.width = minimumWidth;
2983
- }
2984
- if (modifiedAttributes.width) {
2985
- modifiedAttributes.width = Math.min(modifiedAttributes.width, attributes.maximumWidth);
2986
- }
2987
- }
2988
- const tablePropertiesFragment = buildTableProperties(modifiedAttributes);
2989
- tableFragment.import(tablePropertiesFragment);
2990
- const rowSpanMap = new Map();
2991
- if (vNodeHasChildren(vNode)) {
2992
- for (let index = 0; index < vNode.children.length; index++) {
2993
- const childVNode = vNode.children[index];
2994
- if (childVNode.tagName === 'colgroup') {
2995
- const tableGridFragment = buildTableGrid(childVNode, modifiedAttributes);
2996
- tableFragment.import(tableGridFragment);
2997
- }
2998
- else if (childVNode.tagName === 'thead') {
2999
- for (let iteratorIndex = 0; iteratorIndex < childVNode.children.length; iteratorIndex++) {
3000
- const grandChildVNode = childVNode.children[iteratorIndex];
3001
- if (grandChildVNode.tagName === 'tr') {
3002
- if (iteratorIndex === 0) {
3003
- const tableGridFragment = buildTableGridFromTableRow(grandChildVNode, modifiedAttributes);
3004
- tableFragment.import(tableGridFragment);
3005
- }
3006
- const tableRowFragment = yield buildTableRow(grandChildVNode, modifiedAttributes, rowSpanMap, docxDocumentInstance);
3007
- tableFragment.import(tableRowFragment);
3008
- }
3009
- }
3010
- }
3011
- else if (childVNode.tagName === 'tbody') {
3012
- for (let iteratorIndex = 0; iteratorIndex < childVNode.children.length; iteratorIndex++) {
3013
- const grandChildVNode = childVNode.children[iteratorIndex];
3014
- if (grandChildVNode.tagName === 'tr') {
3015
- if (iteratorIndex === 0) {
3016
- const tableGridFragment = buildTableGridFromTableRow(grandChildVNode, modifiedAttributes);
3017
- tableFragment.import(tableGridFragment);
3018
- }
3019
- const tableRowFragment = yield buildTableRow(grandChildVNode, modifiedAttributes, rowSpanMap, docxDocumentInstance);
3020
- tableFragment.import(tableRowFragment);
3021
- }
3022
- }
3023
- }
3024
- else if (childVNode.tagName === 'tr') {
3025
- if (index === 0) {
3026
- const tableGridFragment = buildTableGridFromTableRow(childVNode, modifiedAttributes);
3027
- tableFragment.import(tableGridFragment);
3028
- }
3029
- const tableRowFragment = yield buildTableRow(childVNode, modifiedAttributes, rowSpanMap, docxDocumentInstance);
3030
- tableFragment.import(tableRowFragment);
3031
- }
3032
- }
3033
- }
3034
- tableFragment.up();
3035
- return tableFragment;
3036
- });
3037
- const buildPresetGeometry = () => fragment({ namespaceAlias: { a: namespaces.a } })
3038
- .ele('@a', 'prstGeom')
3039
- .att('prst', 'rect')
3040
- .up();
3041
- const buildExtents = ({ width, height }) => fragment({ namespaceAlias: { a: namespaces.a } })
3042
- .ele('@a', 'ext')
3043
- .att('cx', width)
3044
- .att('cy', height)
3045
- .up();
3046
- const buildOffset = () => fragment({ namespaceAlias: { a: namespaces.a } })
3047
- .ele('@a', 'off')
3048
- .att('x', '0')
3049
- .att('y', '0')
3050
- .up();
3051
- const buildGraphicFrameTransform = (attributes) => {
3052
- const graphicFrameTransformFragment = fragment({ namespaceAlias: { a: namespaces.a } }).ele('@a', 'xfrm');
3053
- const offsetFragment = buildOffset();
3054
- graphicFrameTransformFragment.import(offsetFragment);
3055
- const extentsFragment = buildExtents(attributes);
3056
- graphicFrameTransformFragment.import(extentsFragment);
3057
- graphicFrameTransformFragment.up();
3058
- return graphicFrameTransformFragment;
3059
- };
3060
- const buildShapeProperties = (attributes) => {
3061
- const shapeProperties = fragment({ namespaceAlias: { pic: namespaces.pic } }).ele('@pic', 'spPr');
3062
- const graphicFrameTransformFragment = buildGraphicFrameTransform(attributes);
3063
- shapeProperties.import(graphicFrameTransformFragment);
3064
- const presetGeometryFragment = buildPresetGeometry();
3065
- shapeProperties.import(presetGeometryFragment);
3066
- shapeProperties.up();
3067
- return shapeProperties;
3068
- };
3069
- const buildFillRect = () => fragment({ namespaceAlias: { a: namespaces.a } })
3070
- .ele('@a', 'fillRect')
3071
- .up();
3072
- const buildStretch = () => {
3073
- const stretchFragment = fragment({ namespaceAlias: { a: namespaces.a } }).ele('@a', 'stretch');
3074
- const fillRectFragment = buildFillRect();
3075
- stretchFragment.import(fillRectFragment);
3076
- stretchFragment.up();
3077
- return stretchFragment;
3078
- };
3079
- const buildSrcRectFragment = () => fragment({ namespaceAlias: { a: namespaces.a } })
3080
- .ele('@a', 'srcRect')
3081
- .att('b', '0')
3082
- .att('l', '0')
3083
- .att('r', '0')
3084
- .att('t', '0')
3085
- .up();
3086
- const buildBinaryLargeImageOrPicture = (relationshipId) => fragment({
3087
- namespaceAlias: { a: namespaces.a, r: namespaces.r },
3088
- })
3089
- .ele('@a', 'blip')
3090
- .att('@r', 'embed', `rId${relationshipId}`)
3091
- // FIXME: possible values 'email', 'none', 'print', 'hqprint', 'screen'
3092
- .att('cstate', 'print')
3093
- .up();
3094
- const buildBinaryLargeImageOrPictureFill = (relationshipId) => {
3095
- const binaryLargeImageOrPictureFillFragment = fragment({
3096
- namespaceAlias: { pic: namespaces.pic },
3097
- }).ele('@pic', 'blipFill');
3098
- const binaryLargeImageOrPictureFragment = buildBinaryLargeImageOrPicture(relationshipId);
3099
- binaryLargeImageOrPictureFillFragment.import(binaryLargeImageOrPictureFragment);
3100
- const srcRectFragment = buildSrcRectFragment();
3101
- binaryLargeImageOrPictureFillFragment.import(srcRectFragment);
3102
- const stretchFragment = buildStretch();
3103
- binaryLargeImageOrPictureFillFragment.import(stretchFragment);
3104
- binaryLargeImageOrPictureFillFragment.up();
3105
- return binaryLargeImageOrPictureFillFragment;
3106
- };
3107
- const buildNonVisualPictureDrawingProperties = () => fragment({ namespaceAlias: { pic: namespaces.pic } })
3108
- .ele('@pic', 'cNvPicPr')
3109
- .up();
3110
- const buildNonVisualDrawingProperties = (pictureId, pictureNameWithExtension, pictureDescription = '') => fragment({ namespaceAlias: { pic: namespaces.pic } })
3111
- .ele('@pic', 'cNvPr')
3112
- .att('id', pictureId)
3113
- .att('name', pictureNameWithExtension)
3114
- .att('descr', pictureDescription)
3115
- .up();
3116
- const buildNonVisualPictureProperties = (pictureId, pictureNameWithExtension, pictureDescription) => {
3117
- const nonVisualPicturePropertiesFragment = fragment({
3118
- namespaceAlias: { pic: namespaces.pic },
3119
- }).ele('@pic', 'nvPicPr');
3120
- // TODO: Handle picture attributes
3121
- const nonVisualDrawingPropertiesFragment = buildNonVisualDrawingProperties(pictureId, pictureNameWithExtension, pictureDescription);
3122
- nonVisualPicturePropertiesFragment.import(nonVisualDrawingPropertiesFragment);
3123
- const nonVisualPictureDrawingPropertiesFragment = buildNonVisualPictureDrawingProperties();
3124
- nonVisualPicturePropertiesFragment.import(nonVisualPictureDrawingPropertiesFragment);
3125
- nonVisualPicturePropertiesFragment.up();
3126
- return nonVisualPicturePropertiesFragment;
3127
- };
3128
- const buildPicture = ({ id, fileNameWithExtension, description, relationshipId, width, height, }) => {
3129
- const pictureFragment = fragment({ namespaceAlias: { pic: namespaces.pic } }).ele('@pic', 'pic');
3130
- const nonVisualPicturePropertiesFragment = buildNonVisualPictureProperties(id, fileNameWithExtension, description);
3131
- pictureFragment.import(nonVisualPicturePropertiesFragment);
3132
- const binaryLargeImageOrPictureFill = buildBinaryLargeImageOrPictureFill(relationshipId);
3133
- pictureFragment.import(binaryLargeImageOrPictureFill);
3134
- const shapeProperties = buildShapeProperties({ width, height });
3135
- pictureFragment.import(shapeProperties);
3136
- pictureFragment.up();
3137
- return pictureFragment;
3138
- };
3139
- const buildGraphicData = (graphicType, attributes) => {
3140
- const graphicDataFragment = fragment({ namespaceAlias: { a: namespaces.a } })
3141
- .ele('@a', 'graphicData')
3142
- .att('uri', 'http://schemas.openxmlformats.org/drawingml/2006/picture');
3143
- if (graphicType === 'picture') {
3144
- const pictureFragment = buildPicture(attributes);
3145
- graphicDataFragment.import(pictureFragment);
3146
- }
3147
- graphicDataFragment.up();
3148
- return graphicDataFragment;
3149
- };
3150
- const buildGraphic = (graphicType, attributes) => {
3151
- const graphicFragment = fragment({ namespaceAlias: { a: namespaces.a } }).ele('@a', 'graphic');
3152
- // TODO: Handle drawing type
3153
- const graphicDataFragment = buildGraphicData(graphicType, attributes);
3154
- graphicFragment.import(graphicDataFragment);
3155
- graphicFragment.up();
3156
- return graphicFragment;
3157
- };
3158
- const buildDrawingObjectNonVisualProperties = (pictureId, pictureName) => fragment({ namespaceAlias: { wp: namespaces.wp } })
3159
- .ele('@wp', 'docPr')
3160
- .att('id', pictureId)
3161
- .att('name', pictureName)
3162
- .up();
3163
- const buildWrapSquare = () => fragment({ namespaceAlias: { wp: namespaces.wp } })
3164
- .ele('@wp', 'wrapSquare')
3165
- .att('wrapText', 'bothSides')
3166
- .att('distB', '228600')
3167
- .att('distT', '228600')
3168
- .att('distL', '228600')
3169
- .att('distR', '228600')
3170
- .up();
3171
- // eslint-disable-next-line no-unused-vars
3172
- const buildWrapNone = () => fragment({ namespaceAlias: { wp: namespaces.wp } })
3173
- .ele('@wp', 'wrapNone')
3174
- .up();
3175
- const buildEffectExtentFragment = () => fragment({ namespaceAlias: { wp: namespaces.wp } })
3176
- .ele('@wp', 'effectExtent')
3177
- .att('b', '0')
3178
- .att('l', '0')
3179
- .att('r', '0')
3180
- .att('t', '0')
3181
- .up();
3182
- const buildExtent = ({ width, height }) => fragment({ namespaceAlias: { wp: namespaces.wp } })
3183
- .ele('@wp', 'extent')
3184
- .att('cx', width)
3185
- .att('cy', height)
3186
- .up();
3187
- const buildPositionV = () => fragment({ namespaceAlias: { wp: namespaces.wp } })
3188
- .ele('@wp', 'positionV')
3189
- .att('relativeFrom', 'paragraph')
3190
- .ele('@wp', 'posOffset')
3191
- .txt('19050')
3192
- .up()
3193
- .up();
3194
- const buildPositionH = () => fragment({ namespaceAlias: { wp: namespaces.wp } })
3195
- .ele('@wp', 'positionH')
3196
- .att('relativeFrom', 'column')
3197
- .ele('@wp', 'posOffset')
3198
- .txt('19050')
3199
- .up()
3200
- .up();
3201
- const buildSimplePos = () => fragment({ namespaceAlias: { wp: namespaces.wp } })
3202
- .ele('@wp', 'simplePos')
3203
- .att('x', '0')
3204
- .att('y', '0')
3205
- .up();
3206
- const buildAnchoredDrawing = (graphicType, attributes) => {
3207
- const anchoredDrawingFragment = fragment({ namespaceAlias: { wp: namespaces.wp } })
3208
- .ele('@wp', 'anchor')
3209
- .att('distB', '0')
3210
- .att('distL', '0')
3211
- .att('distR', '0')
3212
- .att('distT', '0')
3213
- .att('relativeHeight', '0')
3214
- .att('behindDoc', 'false')
3215
- .att('locked', 'true')
3216
- .att('layoutInCell', 'true')
3217
- .att('allowOverlap', 'false')
3218
- .att('simplePos', 'false');
3219
- // Even though simplePos isnt supported by Word 2007 simplePos is required.
3220
- const simplePosFragment = buildSimplePos();
3221
- anchoredDrawingFragment.import(simplePosFragment);
3222
- const positionHFragment = buildPositionH();
3223
- anchoredDrawingFragment.import(positionHFragment);
3224
- const positionVFragment = buildPositionV();
3225
- anchoredDrawingFragment.import(positionVFragment);
3226
- const extentFragment = buildExtent({ width: attributes.width, height: attributes.height });
3227
- anchoredDrawingFragment.import(extentFragment);
3228
- const effectExtentFragment = buildEffectExtentFragment();
3229
- anchoredDrawingFragment.import(effectExtentFragment);
3230
- const wrapSquareFragment = buildWrapSquare();
3231
- anchoredDrawingFragment.import(wrapSquareFragment);
3232
- const drawingObjectNonVisualPropertiesFragment = buildDrawingObjectNonVisualProperties(attributes.id, attributes.fileNameWithExtension);
3233
- anchoredDrawingFragment.import(drawingObjectNonVisualPropertiesFragment);
3234
- const graphicFragment = buildGraphic(graphicType, attributes);
3235
- anchoredDrawingFragment.import(graphicFragment);
3236
- anchoredDrawingFragment.up();
3237
- return anchoredDrawingFragment;
3238
- };
3239
- const buildInlineDrawing = (graphicType, attributes) => {
3240
- const inlineDrawingFragment = fragment({ namespaceAlias: { wp: namespaces.wp } })
3241
- .ele('@wp', 'inline')
3242
- .att('distB', '0')
3243
- .att('distL', '0')
3244
- .att('distR', '0')
3245
- .att('distT', '0');
3246
- const extentFragment = buildExtent({ width: attributes.width, height: attributes.height });
3247
- inlineDrawingFragment.import(extentFragment);
3248
- const effectExtentFragment = buildEffectExtentFragment();
3249
- inlineDrawingFragment.import(effectExtentFragment);
3250
- const drawingObjectNonVisualPropertiesFragment = buildDrawingObjectNonVisualProperties(attributes.id, attributes.fileNameWithExtension);
3251
- inlineDrawingFragment.import(drawingObjectNonVisualPropertiesFragment);
3252
- const graphicFragment = buildGraphic(graphicType, attributes);
3253
- inlineDrawingFragment.import(graphicFragment);
3254
- inlineDrawingFragment.up();
3255
- return inlineDrawingFragment;
3256
- };
3257
- const buildDrawing = (inlineOrAnchored = false, graphicType, attributes) => {
3258
- const drawingFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'drawing');
3259
- const inlineOrAnchoredDrawingFragment = inlineOrAnchored
3260
- ? buildInlineDrawing(graphicType, attributes)
3261
- : buildAnchoredDrawing(graphicType, attributes);
3262
- drawingFragment.import(inlineOrAnchoredDrawingFragment);
3263
- drawingFragment.up();
3264
- return drawingFragment;
3265
- };
3266
- // eslint-disable-next-line consistent-return, no-shadow
3267
- const buildImage = (docxDocumentInstance, vNode, maximumWidth = null) => __awaiter(void 0, void 0, void 0, function* () {
3268
- let response = null;
3269
- let base64Uri = null;
3270
- try {
3271
- const imageSource = vNode.properties.src;
3272
- if (isValidUrl(imageSource)) {
3273
- const base64String = yield imageToBase64(imageSource).catch((error) => {
3274
- // eslint-disable-next-line no-console
3275
- console.warning(`skipping image download and conversion due to ${error}`);
3276
- });
3277
- if (base64String) {
3278
- base64Uri = `data:${mimeTypes.lookup(imageSource)};base64, ${base64String}`;
3279
- }
3280
- }
3281
- else {
3282
- base64Uri = decodeURIComponent(vNode.properties.src);
3283
- }
3284
- if (base64Uri) {
3285
- response = docxDocumentInstance.createMediaFile(base64Uri);
3286
- }
3287
- }
3288
- catch (error) {
3289
- // NOOP
3290
- }
3291
- if (response) {
3292
- docxDocumentInstance.zip
3293
- .folder('word')
3294
- .folder('media')
3295
- .file(response.fileNameWithExtension, Buffer.from(response.fileContent, 'base64'), {
3296
- createFolders: false,
3297
- });
3298
- const documentRelsId = docxDocumentInstance.createDocumentRelationships(docxDocumentInstance.relationshipFilename, imageType, `media/${response.fileNameWithExtension}`, internalRelationship);
3299
- const imageBuffer = Buffer.from(response.fileContent, 'base64');
3300
- const imageProperties = sizeOf(imageBuffer);
3301
- const imageFragment = yield xmlBuilder.buildParagraph(vNode, Object.assign(Object.assign({ type: 'picture', inlineOrAnchored: true, relationshipId: documentRelsId }, response), { maximumWidth: maximumWidth || docxDocumentInstance.availableDocumentSpace, originalWidth: imageProperties.width, originalHeight: imageProperties.height }), docxDocumentInstance);
3302
- return imageFragment;
3303
- }
3304
- });
3305
- const buildList = (vNode, docxDocumentInstance, xmlFragment) => __awaiter(void 0, void 0, void 0, function* () {
3306
- const listElements = [];
3307
- let vNodeObjects = [
3308
- {
3309
- node: vNode,
3310
- level: 0,
3311
- type: vNode.tagName,
3312
- numberingId: docxDocumentInstance.createNumbering(vNode.tagName, vNode.properties),
3313
- },
3314
- ];
3315
- while (vNodeObjects.length) {
3316
- const tempVNodeObject = vNodeObjects.shift();
3317
- if (isVText(tempVNodeObject.node) ||
3318
- (isVNode(tempVNodeObject.node) && !['ul', 'ol', 'li'].includes(tempVNodeObject.node.tagName))) {
3319
- const paragraphFragment = yield xmlBuilder.buildParagraph(tempVNodeObject.node, {
3320
- numbering: { levelId: tempVNodeObject.level, numberingId: tempVNodeObject.numberingId },
3321
- }, docxDocumentInstance);
3322
- xmlFragment.import(paragraphFragment);
3323
- }
3324
- if (tempVNodeObject.node.children &&
3325
- tempVNodeObject.node.children.length &&
3326
- ['ul', 'ol', 'li'].includes(tempVNodeObject.node.tagName)) {
3327
- const tempVNodeObjects = tempVNodeObject.node.children.reduce((accumulator, childVNode) => {
3328
- if (['ul', 'ol'].includes(childVNode.tagName)) {
3329
- accumulator.push({
3330
- node: childVNode,
3331
- level: tempVNodeObject.level + 1,
3332
- type: childVNode.tagName,
3333
- numberingId: docxDocumentInstance.createNumbering(childVNode.tagName, childVNode.properties),
3334
- });
3335
- }
3336
- else {
3337
- // eslint-disable-next-line no-lonely-if
3338
- if (accumulator.length > 0 &&
3339
- isVNode(accumulator[accumulator.length - 1].node) &&
3340
- accumulator[accumulator.length - 1].node.tagName.toLowerCase() === 'p') {
3341
- accumulator[accumulator.length - 1].node.children.push(childVNode);
3342
- }
3343
- else {
3344
- const paragraphVNode = new VNode('p', null,
3345
- // eslint-disable-next-line no-nested-ternary
3346
- isVText(childVNode)
3347
- ? [childVNode]
3348
- : // eslint-disable-next-line no-nested-ternary
3349
- isVNode(childVNode)
3350
- ? childVNode.tagName.toLowerCase() === 'li'
3351
- ? [...childVNode.children]
3352
- : [childVNode]
3353
- : []);
3354
- accumulator.push({
3355
- // eslint-disable-next-line prettier/prettier, no-nested-ternary
3356
- node: isVNode(childVNode)
3357
- ? // eslint-disable-next-line prettier/prettier, no-nested-ternary
3358
- childVNode.tagName.toLowerCase() === 'li'
3359
- ? childVNode
3360
- : childVNode.tagName.toLowerCase() !== 'p'
3361
- ? paragraphVNode
3362
- : childVNode
3363
- : // eslint-disable-next-line prettier/prettier
3364
- paragraphVNode,
3365
- level: tempVNodeObject.level,
3366
- type: tempVNodeObject.type,
3367
- numberingId: tempVNodeObject.numberingId,
3368
- });
3369
- }
3370
- }
3371
- return accumulator;
3372
- }, []);
3373
- vNodeObjects = tempVNodeObjects.concat(vNodeObjects);
3374
- }
3375
- }
3376
- return listElements;
3377
- });
3378
-
3379
- const convertHTML$1 = HTMLToVDOM({
3380
- VNode: VNode$1,
3381
- VText,
3382
- });
3383
- function findXMLEquivalent(docxDocumentInstance, vNode, xmlFragment) {
3384
- return __awaiter(this, void 0, void 0, function* () {
3385
- if (vNode.tagName === 'div' &&
3386
- (vNode.properties.attributes.class === 'page-break' ||
3387
- (vNode.properties.style && vNode.properties.style['page-break-after']))) {
3388
- const paragraphFragment = fragment({ namespaceAlias: { w: namespaces.w } })
3389
- .ele('@w', 'p')
3390
- .ele('@w', 'r')
3391
- .ele('@w', 'br')
3392
- .att('@w', 'type', 'page')
3393
- .up()
3394
- .up()
3395
- .up();
3396
- xmlFragment.import(paragraphFragment);
3397
- return;
3398
- }
3399
- switch (vNode.tagName) {
3400
- case 'h1':
3401
- case 'h2':
3402
- case 'h3':
3403
- case 'h4':
3404
- case 'h5':
3405
- case 'h6':
3406
- const headingFragment = yield buildParagraph(vNode, {
3407
- paragraphStyle: `Heading${vNode.tagName[1]}`,
3408
- }, docxDocumentInstance);
3409
- xmlFragment.import(headingFragment);
3410
- return;
3411
- case 'span':
3412
- case 'strong':
3413
- case 'b':
3414
- case 'em':
3415
- case 'i':
3416
- case 'u':
3417
- case 'ins':
3418
- case 'strike':
3419
- case 'del':
3420
- case 's':
3421
- case 'sub':
3422
- case 'sup':
3423
- case 'mark':
3424
- case 'p':
3425
- case 'a':
3426
- case 'blockquote':
3427
- case 'code':
3428
- case 'pre':
3429
- const paragraphFragment = yield buildParagraph(vNode, {}, docxDocumentInstance);
3430
- xmlFragment.import(paragraphFragment);
3431
- return;
3432
- case 'figure':
3433
- if (vNodeHasChildren(vNode)) {
3434
- // eslint-disable-next-line no-plusplus
3435
- for (let index = 0; index < vNode.children.length; index++) {
3436
- const childVNode = vNode.children[index];
3437
- if (childVNode.tagName === 'table') {
3438
- const tableFragment = yield buildTable(childVNode, {
3439
- maximumWidth: docxDocumentInstance.availableDocumentSpace,
3440
- rowCantSplit: docxDocumentInstance.tableRowCantSplit,
3441
- }, docxDocumentInstance);
3442
- xmlFragment.import(tableFragment);
3443
- // Adding empty paragraph for space after table
3444
- const emptyParagraphFragment = yield buildParagraph(null, {});
3445
- xmlFragment.import(emptyParagraphFragment);
3446
- }
3447
- else if (childVNode.tagName === 'img') {
3448
- const imageFragment = yield buildImage(docxDocumentInstance, childVNode);
3449
- if (imageFragment) {
3450
- xmlFragment.import(imageFragment);
3451
- }
3452
- }
3453
- }
3454
- }
3455
- return;
3456
- case 'table':
3457
- const tableFragment = yield buildTable(vNode, {
3458
- maximumWidth: docxDocumentInstance.availableDocumentSpace,
3459
- rowCantSplit: docxDocumentInstance.tableRowCantSplit,
3460
- }, docxDocumentInstance);
3461
- xmlFragment.import(tableFragment);
3462
- // Adding empty paragraph for space after table
3463
- const emptyParagraphFragment = yield buildParagraph(null, {});
3464
- xmlFragment.import(emptyParagraphFragment);
3465
- return;
3466
- case 'ol':
3467
- case 'ul':
3468
- yield buildList(vNode, docxDocumentInstance, xmlFragment);
3469
- return;
3470
- case 'img':
3471
- const imageFragment = yield buildImage(docxDocumentInstance, vNode);
3472
- if (imageFragment) {
3473
- xmlFragment.import(imageFragment);
3474
- }
3475
- return;
3476
- case 'br':
3477
- const linebreakFragment = yield buildParagraph(null, {});
3478
- xmlFragment.import(linebreakFragment);
3479
- return;
3480
- }
3481
- if (vNodeHasChildren(vNode)) {
3482
- // eslint-disable-next-line no-plusplus
3483
- for (let index = 0; index < vNode.children.length; index++) {
3484
- const childVNode = vNode.children[index];
3485
- // eslint-disable-next-line no-use-before-define
3486
- yield convertVTreeToXML(docxDocumentInstance, childVNode, xmlFragment);
3487
- }
3488
- }
3489
- });
3490
- }
3491
- // eslint-disable-next-line consistent-return
3492
- function convertVTreeToXML(docxDocumentInstance, vTree, xmlFragment) {
3493
- return __awaiter(this, void 0, void 0, function* () {
3494
- if (!vTree) {
3495
- // eslint-disable-next-line no-useless-return
3496
- return '';
3497
- }
3498
- if (Array.isArray(vTree) && vTree.length) {
3499
- // eslint-disable-next-line no-plusplus
3500
- for (let index = 0; index < vTree.length; index++) {
3501
- const vNode = vTree[index];
3502
- yield convertVTreeToXML(docxDocumentInstance, vNode, xmlFragment);
3503
- }
3504
- }
3505
- else if (isVNode(vTree)) {
3506
- yield findXMLEquivalent(docxDocumentInstance, vTree, xmlFragment);
3507
- }
3508
- else if (isVText(vTree)) {
3509
- buildTextElement(xmlFragment, escape(String(vTree.text)));
3510
- }
3511
- return xmlFragment;
3512
- });
3513
- }
3514
- function renderDocumentFile(docxDocumentInstance) {
3515
- return __awaiter(this, void 0, void 0, function* () {
3516
- const vTree = convertHTML$1(docxDocumentInstance.htmlString);
3517
- const xmlFragment = fragment({ namespaceAlias: { w: namespaces.w } });
3518
- const populatedXmlFragment = yield convertVTreeToXML(docxDocumentInstance, vTree, xmlFragment);
3519
- return populatedXmlFragment;
3520
- });
3521
- }
3522
-
3523
- /* eslint-disable import/prefer-default-export */
3524
-
3525
- class ListStyleBuilder {
3526
- // defaults is an object passed in from constants.js / numbering with the following properties:
3527
- // defaultOrderedListStyleType: 'decimal' (unless otherwise specified)
3528
- constructor(defaults) {
3529
- this.defaults = defaults || { defaultOrderedListStyleType: 'decimal' };
3530
- }
3531
- // eslint-disable-next-line class-methods-use-this
3532
- getListStyleType(listType) {
3533
- switch (listType) {
3534
- case 'upper-roman':
3535
- return 'upperRoman';
3536
- case 'lower-roman':
3537
- return 'lowerRoman';
3538
- case 'upper-alpha':
3539
- case 'upper-alpha-bracket-end':
3540
- return 'upperLetter';
3541
- case 'lower-alpha':
3542
- case 'lower-alpha-bracket-end':
3543
- return 'lowerLetter';
3544
- case 'decimal':
3545
- case 'decimal-bracket':
3546
- return 'decimal';
3547
- default:
3548
- return this.defaults.defaultOrderedListStyleType;
3549
- }
3550
- }
3551
- getListPrefixSuffix(style, lvl) {
3552
- let listType = this.defaults.defaultOrderedListStyleType;
3553
- if (style && style['list-style-type']) {
3554
- listType = style['list-style-type'];
3555
- }
3556
- switch (listType) {
3557
- case 'upper-roman':
3558
- case 'lower-roman':
3559
- case 'upper-alpha':
3560
- case 'lower-alpha':
3561
- return `%${lvl + 1}.`;
3562
- case 'upper-alpha-bracket-end':
3563
- case 'lower-alpha-bracket-end':
3564
- case 'decimal-bracket-end':
3565
- return `%${lvl + 1})`;
3566
- case 'decimal-bracket':
3567
- return `(%${lvl + 1})`;
3568
- case 'decimal':
3569
- default:
3570
- return `%${lvl + 1}.`;
3571
- }
3572
- }
3573
- }
3574
-
3575
- function generateContentTypesFragments(contentTypesXML, type, objects) {
3576
- if (objects && Array.isArray(objects)) {
3577
- objects.forEach((object) => {
3578
- const contentTypesFragment = fragment({ defaultNamespace: { ele: namespaces.contentTypes } })
3579
- .ele('Override')
3580
- .att('PartName', `/word/${type}${object[`${type}Id`]}.xml`)
3581
- .att('ContentType', `application/vnd.openxmlformats-officedocument.wordprocessingml.${type}+xml`)
3582
- .up();
3583
- contentTypesXML.root().import(contentTypesFragment);
3584
- });
3585
- }
3586
- }
3587
- function generateSectionReferenceXML(documentXML, documentSectionType, objects, isEnabled) {
3588
- if (isEnabled && objects && Array.isArray(objects) && objects.length) {
3589
- const xmlFragment = fragment();
3590
- objects.forEach(({ relationshipId, type }) => {
3591
- const objectFragment = fragment({ namespaceAlias: { w: namespaces.w, r: namespaces.r } })
3592
- .ele('@w', `${documentSectionType}Reference`)
3593
- .att('@r', 'id', `rId${relationshipId}`)
3594
- .att('@w', 'type', type)
3595
- .up();
3596
- xmlFragment.import(objectFragment);
3597
- });
3598
- documentXML.root().first().first().import(xmlFragment);
3599
- }
3600
- }
3601
- function generateXMLString(xmlString) {
3602
- const xmlDocumentString = create({ encoding: 'UTF-8', standalone: true }, xmlString);
3603
- return xmlDocumentString.toString({ prettyPrint: true });
3604
- }
3605
- function generateSectionXML(vTree, type = 'header') {
3606
- return __awaiter(this, void 0, void 0, function* () {
3607
- debugger;
3608
- const sectionXML = create({
3609
- encoding: 'UTF-8',
3610
- standalone: true,
3611
- namespaceAlias: {
3612
- a: namespaces.a,
3613
- cdr: namespaces.cdr,
3614
- o: namespaces.o,
3615
- pic: namespaces.pic,
3616
- r: namespaces.r,
3617
- v: namespaces.v,
3618
- ve: namespaces.ve,
3619
- vt: namespaces.vt,
3620
- w: namespaces.w,
3621
- w10: namespaces.w10,
3622
- wp: namespaces.wp,
3623
- wne: namespaces.wne
3624
- },
3625
- }).ele('@w', type === 'header' ? 'hdr' : 'ftr');
3626
- const XMLFragment = fragment();
3627
- yield convertVTreeToXML(this, vTree, XMLFragment);
3628
- if (type === 'footer' && XMLFragment.first().node.tagName === 'p' && this.pageNumber) {
3629
- XMLFragment.first().import(fragment({ namespaceAlias: { w: namespaces.w } })
3630
- .ele('@w', 'fldSimple')
3631
- .att('@w', 'instr', 'PAGE')
3632
- .ele('@w', 'r')
3633
- .up()
3634
- .up());
3635
- }
3636
- sectionXML.root().import(XMLFragment);
3637
- const referenceName = type === 'header' ? 'Header' : 'Footer';
3638
- this[`last${referenceName}Id`] += 1;
3639
- return { [`${type}Id`]: this[`last${referenceName}Id`], [`${type}XML`]: sectionXML };
3640
- });
3641
- }
3642
- class DocxDocument {
3643
- constructor(properties) {
3644
- this.zip = properties.zip;
3645
- this.htmlString = properties.htmlString;
3646
- this.orientation = properties.orientation;
3647
- this.pageSize = properties.pageSize || defaultDocumentOptions.pageSize;
3648
- const isPortraitOrientation = this.orientation === defaultOrientation;
3649
- const height = this.pageSize.height ? this.pageSize.height : landscapeHeight;
3650
- const width = this.pageSize.width ? this.pageSize.width : landscapeWidth;
3651
- this.width = isPortraitOrientation ? width : height;
3652
- this.height = isPortraitOrientation ? height : width;
3653
- const marginsObject = properties.margins;
3654
- this.margins =
3655
- // eslint-disable-next-line no-nested-ternary
3656
- marginsObject && Object.keys(marginsObject).length
3657
- ? marginsObject
3658
- : isPortraitOrientation
3659
- ? portraitMargins
3660
- : landscapeMargins;
3661
- this.availableDocumentSpace = this.width - this.margins.left - this.margins.right;
3662
- this.title = properties.title || '';
3663
- this.subject = properties.subject || '';
3664
- this.creator = properties.creator || applicationName;
3665
- this.keywords = properties.keywords || [applicationName];
3666
- this.description = properties.description || '';
3667
- this.lastModifiedBy = properties.lastModifiedBy || applicationName;
3668
- this.revision = properties.revision || 1;
3669
- this.createdAt = properties.createdAt || new Date();
3670
- this.modifiedAt = properties.modifiedAt || new Date();
3671
- this.headerType = properties.headerType || 'default';
3672
- this.header = properties.header || false;
3673
- this.footerType = properties.footerType || 'default';
3674
- this.footer = properties.footer || false;
3675
- this.font = properties.font || defaultFont;
3676
- this.fontSize = properties.fontSize || defaultFontSize;
3677
- this.complexScriptFontSize = properties.complexScriptFontSize || defaultFontSize;
3678
- this.tableRowCantSplit =
3679
- (properties.table && properties.table.row && properties.table.row.cantSplit) || false;
3680
- this.pageNumber = properties.pageNumber || false;
3681
- this.skipFirstHeaderFooter = properties.skipFirstHeaderFooter || false;
3682
- this.lineNumber = properties.lineNumber ? properties.lineNumberOptions : null;
3683
- this.lastNumberingId = 0;
3684
- this.lastMediaId = 0;
3685
- this.lastHeaderId = 0;
3686
- this.lastFooterId = 0;
3687
- this.stylesObjects = [];
3688
- this.numberingObjects = [];
3689
- this.relationshipFilename = documentFileName;
3690
- this.relationships = [{ fileName: documentFileName, lastRelsId: 4, rels: [] }];
3691
- this.mediaFiles = [];
3692
- this.headerObjects = [];
3693
- this.footerObjects = [];
3694
- this.documentXML = null;
3695
- this.generateContentTypesXML = this.generateContentTypesXML.bind(this);
3696
- this.generateDocumentXML = this.generateDocumentXML.bind(this);
3697
- this.generateCoreXML = this.generateCoreXML.bind(this);
3698
- this.generateSettingsXML = this.generateSettingsXML.bind(this);
3699
- this.generateWebSettingsXML = this.generateWebSettingsXML.bind(this);
3700
- this.generateStylesXML = this.generateStylesXML.bind(this);
3701
- this.generateFontTableXML = this.generateFontTableXML.bind(this);
3702
- this.generateThemeXML = this.generateThemeXML.bind(this);
3703
- this.generateNumberingXML = this.generateNumberingXML.bind(this);
3704
- this.generateRelsXML = this.generateRelsXML.bind(this);
3705
- this.createMediaFile = this.createMediaFile.bind(this);
3706
- this.createDocumentRelationships = this.createDocumentRelationships.bind(this);
3707
- this.generateHeaderXML = this.generateHeaderXML.bind(this);
3708
- this.generateFooterXML = this.generateFooterXML.bind(this);
3709
- this.generateSectionXML = generateSectionXML.bind(this);
3710
- this.ListStyleBuilder = new ListStyleBuilder(properties.numbering);
3711
- }
3712
- generateContentTypesXML() {
3713
- const contentTypesXML$1 = create({ encoding: 'UTF-8', standalone: true }, contentTypesXML);
3714
- generateContentTypesFragments(contentTypesXML$1, 'header', this.headerObjects);
3715
- generateContentTypesFragments(contentTypesXML$1, 'footer', this.footerObjects);
3716
- return contentTypesXML$1.toString({ prettyPrint: true });
3717
- }
3718
- generateDocumentXML() {
3719
- const documentXML = create({ encoding: 'UTF-8', standalone: true }, generateDocumentTemplate(this.width, this.height, this.orientation, this.margins));
3720
- // documentXML.root().first().import(this.documentXML);
3721
- generateSectionReferenceXML(documentXML, 'header', this.headerObjects, this.header);
3722
- generateSectionReferenceXML(documentXML, 'footer', this.footerObjects, this.footer);
3723
- if ((this.header || this.footer) && this.skipFirstHeaderFooter) {
3724
- documentXML
3725
- .root()
3726
- .first()
3727
- .first()
3728
- .import(fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'titlePg'));
3729
- }
3730
- if (this.lineNumber) {
3731
- const { countBy, start, restart } = this.lineNumber;
3732
- documentXML
3733
- .root()
3734
- .first()
3735
- .first()
3736
- .import(fragment({ namespaceAlias: { w: namespaces.w } })
3737
- .ele('@w', 'lnNumType')
3738
- .att('@w', 'countBy', countBy)
3739
- .att('@w', 'start', start)
3740
- .att('@w', 'restart', restart));
3741
- }
3742
- return documentXML.toString({ prettyPrint: true });
3743
- }
3744
- generateCoreXML() {
3745
- return generateXMLString(generateCoreXML(this.title, this.subject, this.creator, this.keywords, this.description, this.lastModifiedBy, this.revision, this.createdAt, this.modifiedAt));
3746
- }
3747
- // eslint-disable-next-line class-methods-use-this
3748
- generateSettingsXML() {
3749
- return generateXMLString(settingsXML);
3750
- }
3751
- // eslint-disable-next-line class-methods-use-this
3752
- generateWebSettingsXML() {
3753
- return generateXMLString(webSettingsXML);
3754
- }
3755
- generateStylesXML() {
3756
- return generateXMLString(generateStylesXML(this.font, this.fontSize, this.complexScriptFontSize));
3757
- }
3758
- // eslint-disable-next-line class-methods-use-this
3759
- generateFontTableXML() {
3760
- return generateXMLString(fontTableXML);
3761
- }
3762
- generateThemeXML() {
3763
- return generateXMLString(generateThemeXML(this.font));
3764
- }
3765
- generateNumberingXML() {
3766
- const numberingXML = create({ encoding: 'UTF-8', standalone: true }, generateNumberingXMLTemplate());
3767
- const abstractNumberingFragments = fragment();
3768
- const numberingFragments = fragment();
3769
- this.numberingObjects.forEach(({ numberingId, type, properties }) => {
3770
- const abstractNumberingFragment = fragment({ namespaceAlias: { w: namespaces.w } })
3771
- .ele('@w', 'abstractNum')
3772
- .att('@w', 'abstractNumId', String(numberingId));
3773
- [...Array(8).keys()].forEach((level) => {
3774
- const levelFragment = fragment({ namespaceAlias: { w: namespaces.w } })
3775
- .ele('@w', 'lvl')
3776
- .att('@w', 'ilvl', level)
3777
- .ele('@w', 'start')
3778
- .att('@w', 'val', type === 'ol'
3779
- ? (properties.attributes && properties.attributes['data-start']) || 1
3780
- : '1')
3781
- .up()
3782
- .ele('@w', 'numFmt')
3783
- .att('@w', 'val', type === 'ol'
3784
- ? this.ListStyleBuilder.getListStyleType(properties.style && properties.style['list-style-type'])
3785
- : 'bullet')
3786
- .up()
3787
- .ele('@w', 'lvlText')
3788
- .att('@w', 'val', type === 'ol' ? this.ListStyleBuilder.getListPrefixSuffix(properties.style, level) : '')
3789
- .up()
3790
- .ele('@w', 'lvlJc')
3791
- .att('@w', 'val', 'left')
3792
- .up()
3793
- .ele('@w', 'pPr')
3794
- .ele('@w', 'tabs')
3795
- .ele('@w', 'tab')
3796
- .att('@w', 'val', 'num')
3797
- .att('@w', 'pos', (level + 1) * 720)
3798
- .up()
3799
- .up()
3800
- .ele('@w', 'ind')
3801
- .att('@w', 'left', (level + 1) * 720)
3802
- .att('@w', 'hanging', 360)
3803
- .up()
3804
- .up()
3805
- .up();
3806
- if (type === 'ul') {
3807
- levelFragment.last().import(fragment({ namespaceAlias: { w: namespaces.w } })
3808
- .ele('@w', 'rPr')
3809
- .ele('@w', 'rFonts')
3810
- .att('@w', 'ascii', 'Symbol')
3811
- .att('@w', 'hAnsi', 'Symbol')
3812
- .att('@w', 'hint', 'default')
3813
- .up()
3814
- .up());
3815
- }
3816
- abstractNumberingFragment.import(levelFragment);
3817
- });
3818
- abstractNumberingFragment.up();
3819
- abstractNumberingFragments.import(abstractNumberingFragment);
3820
- numberingFragments.import(fragment({ namespaceAlias: { w: namespaces.w } })
3821
- .ele('@w', 'num')
3822
- .att('@w', 'numId', String(numberingId))
3823
- .ele('@w', 'abstractNumId')
3824
- .att('@w', 'val', String(numberingId))
3825
- .up()
3826
- .up());
3827
- });
3828
- numberingXML.root().import(abstractNumberingFragments);
3829
- numberingXML.root().import(numberingFragments);
3830
- return numberingXML.toString({ prettyPrint: true });
3831
- }
3832
- // eslint-disable-next-line class-methods-use-this
3833
- appendRelationships(xmlFragment, relationships) {
3834
- relationships.forEach(({ relationshipId, type, target, targetMode }) => {
3835
- xmlFragment.import(fragment({ defaultNamespace: { ele: namespaces.relationship } })
3836
- .ele('Relationship')
3837
- .att('Id', `rId${relationshipId}`)
3838
- .att('Type', type)
3839
- .att('Target', target)
3840
- .att('TargetMode', targetMode)
3841
- .up());
3842
- });
3843
- }
3844
- generateRelsXML() {
3845
- const relationshipXMLStrings = this.relationships.map(({ fileName, rels }) => {
3846
- const xmlFragment = create({ encoding: 'UTF-8', standalone: true }, fileName === documentFileName ? documentRelsXML : genericRelsXML);
3847
- this.appendRelationships(xmlFragment.root(), rels);
3848
- return { fileName, xmlString: xmlFragment.toString({ prettyPrint: true }) };
3849
- });
3850
- return relationshipXMLStrings;
3851
- }
3852
- createNumbering(type, properties) {
3853
- this.lastNumberingId += 1;
3854
- this.numberingObjects.push({ numberingId: this.lastNumberingId, type, properties });
3855
- return this.lastNumberingId;
3856
- }
3857
- createMediaFile(base64String) {
3858
- // eslint-disable-next-line no-useless-escape
3859
- const matches = base64String.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/);
3860
- if (matches.length !== 3) {
3861
- throw new Error('Invalid base64 string');
3862
- }
3863
- const base64FileContent = matches[2];
3864
- // matches array contains file type in base64 format - image/jpeg and base64 stringified data
3865
- const fileExtension = matches[1].match(/\/(.*?)$/)[1] === 'octet-stream' ? 'png' : matches[1].match(/\/(.*?)$/)[1];
3866
- const fileNameWithExtension = `image-${nanoid()}.${fileExtension}`;
3867
- this.lastMediaId += 1;
3868
- return { id: this.lastMediaId, fileContent: base64FileContent, fileNameWithExtension };
3869
- }
3870
- createDocumentRelationships(fileName = 'document', type, target, targetMode = 'External') {
3871
- debugger;
3872
- let relationshipObject = this.relationships.find((relationship) => relationship.fileName === fileName);
3873
- let lastRelsId = 1;
3874
- if (relationshipObject) {
3875
- lastRelsId = relationshipObject.lastRelsId + 1;
3876
- relationshipObject.lastRelsId = lastRelsId;
3877
- }
3878
- else {
3879
- relationshipObject = { fileName, lastRelsId, rels: [] };
3880
- this.relationships.push(relationshipObject);
3881
- }
3882
- let relationshipType;
3883
- switch (type) {
3884
- case hyperlinkType:
3885
- relationshipType = namespaces.hyperlinks;
3886
- break;
3887
- case imageType:
3888
- relationshipType = namespaces.images;
3889
- break;
3890
- case headerType:
3891
- relationshipType = namespaces.headers;
3892
- break;
3893
- case footerType:
3894
- relationshipType = namespaces.footers;
3895
- break;
3896
- case themeType:
3897
- relationshipType = namespaces.themes;
3898
- break;
3899
- }
3900
- relationshipObject.rels.push({
3901
- relationshipId: lastRelsId,
3902
- type: relationshipType,
3903
- target,
3904
- targetMode,
3905
- });
3906
- console.log(fileName);
3907
- console.log(relationshipObject.rels);
3908
- return lastRelsId;
3909
- }
3910
- generateHeaderXML(vTree) {
3911
- return this.generateSectionXML(vTree, 'header');
3912
- }
3913
- generateFooterXML(vTree) {
3914
- return this.generateSectionXML(vTree, 'footer');
3915
- }
3916
- }
3917
-
3918
- const defaultMargins = {
3919
- top: 1440,
3920
- right: 1440,
3921
- bottom: 1440,
3922
- left: 1440,
3923
- header: 720,
3924
- footer: 720,
3925
- gutter: 0,
3926
- };
3927
- const documentTemplate = (width, height, orient, margins) => {
3928
- return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
3929
- <w:document
3930
- xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
3931
- xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"
3932
- xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
3933
- xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
3934
- xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
3935
- xmlns:ns6="http://schemas.openxmlformats.org/schemaLibrary/2006/main"
3936
- xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart"
3937
- xmlns:ns8="http://schemas.openxmlformats.org/drawingml/2006/chartDrawing"
3938
- xmlns:dgm="http://schemas.openxmlformats.org/drawingml/2006/diagram"
3939
- xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture"
3940
- xmlns:ns11="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"
3941
- xmlns:dsp="http://schemas.microsoft.com/office/drawing/2008/diagram"
3942
- xmlns:ns13="urn:schemas-microsoft-com:office:excel"
3943
- xmlns:o="urn:schemas-microsoft-com:office:office"
3944
- xmlns:v="urn:schemas-microsoft-com:vml"
3945
- xmlns:w10="urn:schemas-microsoft-com:office:word"
3946
- xmlns:ns17="urn:schemas-microsoft-com:office:powerpoint"
3947
- xmlns:odx="http://opendope.org/xpaths"
3948
- xmlns:odc="http://opendope.org/conditions"
3949
- xmlns:odq="http://opendope.org/questions"
3950
- xmlns:odi="http://opendope.org/components"
3951
- xmlns:odgm="http://opendope.org/SmartArt/DataHierarchy"
3952
- xmlns:ns24="http://schemas.openxmlformats.org/officeDocument/2006/bibliography"
3953
- xmlns:ns25="http://schemas.openxmlformats.org/drawingml/2006/compatibility"
3954
- xmlns:ns26="http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas">
3955
- <w:body>
3956
- <w:altChunk r:id="htmlChunk" />
3957
- <w:sectPr>
3958
- <w:pgSz w:w="${width}" w:h="${height}" w:orient="${orient}" />
3959
- <w:pgMar w:top="${margins.top}"
3960
- w:right="${margins.right}"
3961
- w:bottom="${margins.bottom}"
3962
- w:left="${margins.left}"
3963
- w:header="${margins.header}"
3964
- w:footer="${margins.footer}"
3965
- w:gutter="${margins.gutter}"/>
3966
- </w:sectPr>
3967
- </w:body>
3968
- </w:document>
3969
- `;
3970
- };
3971
-
3972
- const mhtDocumentTemplate = (htmlSource, contentParts) => {
3973
- debugger;
3974
- return `MIME-Version: 1.0
3975
- Content-Type: multipart/related;
3976
- type="text/html";
3977
- boundary="----=mhtDocumentPart"
3978
-
3979
-
3980
- ------=mhtDocumentPart
3981
- Content-Type: text/html;
3982
- charset="utf-8"
3983
- Content-Transfer-Encoding: quoted-printable
3984
- Content-Location: file:///C:/fake/document.html
3985
-
3986
- ${htmlSource}
3987
-
3988
- ${contentParts}
3989
-
3990
- ------=mhtDocumentPart--
3991
- `;
3992
- };
3993
-
3994
- const mhtPartTemplate = (contentType, contentEncoding, contentLocation, encodedContent) => {
3995
- return `------=mhtDocumentPart
3996
- Content-Type: ${contentType}
3997
- Content-Transfer-Encoding: ${contentEncoding}
3998
- Content-Location: ${contentLocation}
3999
-
4000
- ${encodedContent}
4001
- `;
4002
- };
4003
-
4004
- function getMHTdocument(htmlSource) {
4005
- debugger;
4006
- const ref = _prepareImageParts(htmlSource);
4007
- const imageContentPartsString = ref.imageContentParts.join('\n');
4008
- htmlSource = ref.htmlSource.replace(/\=/g, '=3D');
4009
- return mhtDocumentTemplate(htmlSource, imageContentPartsString);
4010
- }
4011
- function _prepareImageParts(htmlSource) {
4012
- debugger;
4013
- const imageContentParts = [];
4014
- const inlinedSrcPattern = /"data:(\w+\/\w+);(\w+),(\S+)"/g;
4015
- const inlinedReplacer = (match, contentType, contentEncoding, encodedContent) => {
4016
- const index = imageContentParts.length;
4017
- const extension = contentType.split('/')[1];
4018
- const contentLocation = `file:///C:/fake/image${index}.${extension}`;
4019
- imageContentParts.push(mhtPartTemplate(contentType, contentEncoding, contentLocation, encodedContent));
4020
- return `\"${contentLocation}\"`;
4021
- };
4022
- if (!/<img/g.test(htmlSource)) {
4023
- return { htmlSource, imageContentParts };
4024
- }
4025
- htmlSource = htmlSource.replace(inlinedSrcPattern, inlinedReplacer);
4026
- return { htmlSource, imageContentParts };
4027
- }
4028
-
4029
- const convertHTML = HTMLToVDOM({
4030
- VNode: VNode$1,
4031
- VText,
4032
- });
4033
- const mergeOptions = (options, patch) => (Object.assign(Object.assign({}, options), patch));
4034
- const fixupFontSize = (fontSize) => {
4035
- let normalizedFontSize;
4036
- if (pointRegex.test(fontSize)) {
4037
- const matchedParts = fontSize.match(pointRegex);
4038
- normalizedFontSize = pointToHIP(matchedParts[1]);
4039
- }
4040
- else if (fontSize) {
4041
- // assuming it is already in HIP
4042
- normalizedFontSize = fontSize;
4043
- }
4044
- else {
4045
- normalizedFontSize = null;
4046
- }
4047
- return normalizedFontSize;
4048
- };
4049
- const normalizeUnits = (dimensioningObject, defaultDimensionsProperty) => {
4050
- let normalizedUnitResult = {};
4051
- if (typeof dimensioningObject === 'object' && dimensioningObject !== null) {
4052
- Object.keys(dimensioningObject).forEach((key) => {
4053
- if (pixelRegex.test(dimensioningObject[key])) {
4054
- const matchedParts = dimensioningObject[key].match(pixelRegex);
4055
- normalizedUnitResult[key] = pixelToTWIP(matchedParts[1]);
4056
- }
4057
- else if (cmRegex.test(dimensioningObject[key])) {
4058
- const matchedParts = dimensioningObject[key].match(cmRegex);
4059
- normalizedUnitResult[key] = cmToTWIP(matchedParts[1]);
4060
- }
4061
- else if (inchRegex.test(dimensioningObject[key])) {
4062
- const matchedParts = dimensioningObject[key].match(inchRegex);
4063
- normalizedUnitResult[key] = inchToTWIP(matchedParts[1]);
4064
- }
4065
- else if (dimensioningObject[key]) {
4066
- normalizedUnitResult[key] = dimensioningObject[key];
4067
- }
4068
- else {
4069
- // incase value is something like 0
4070
- normalizedUnitResult[key] = defaultDimensionsProperty[key];
4071
- }
4072
- });
4073
- }
4074
- else {
4075
- // eslint-disable-next-line no-param-reassign
4076
- normalizedUnitResult = null;
4077
- }
4078
- return normalizedUnitResult;
4079
- };
4080
- const normalizeDocumentOptions = (documentOptions) => {
4081
- const normalizedDocumentOptions = Object.assign({}, documentOptions);
4082
- Object.keys(documentOptions).forEach((key) => {
4083
- // eslint-disable-next-line default-case
4084
- switch (key) {
4085
- case 'pageSize':
4086
- case 'margins':
4087
- normalizedDocumentOptions[key] = normalizeUnits(documentOptions[key], defaultDocumentOptions[key]);
4088
- break;
4089
- case 'fontSize':
4090
- case 'complexScriptFontSize':
4091
- normalizedDocumentOptions[key] = fixupFontSize(documentOptions[key]);
4092
- break;
4093
- }
4094
- });
4095
- return normalizedDocumentOptions;
4096
- };
4097
- // Ref: https://en.wikipedia.org/wiki/Office_Open_XML_file_formats
4098
- // http://officeopenxml.com/anatomyofOOXML.php
4099
- function addFilesToContainer(zip, htmlString, suppliedDocumentOptions, headerHTMLString, footerHTMLString) {
4100
- return __awaiter(this, void 0, void 0, function* () {
4101
- debugger;
4102
- const normalizedDocumentOptions = normalizeDocumentOptions(suppliedDocumentOptions);
4103
- const documentOptions = mergeOptions(defaultDocumentOptions, normalizedDocumentOptions);
4104
- if (documentOptions.header && !headerHTMLString) {
4105
- // eslint-disable-next-line no-param-reassign
4106
- headerHTMLString = defaultHTMLString;
4107
- }
4108
- if (documentOptions.footer && !footerHTMLString) {
4109
- // eslint-disable-next-line no-param-reassign
4110
- footerHTMLString = defaultHTMLString;
4111
- }
4112
- const docxDocument = new DocxDocument(Object.assign({ zip, htmlString }, documentOptions));
4113
- // Conversion to Word XML happens here
4114
- docxDocument.documentXML = yield renderDocumentFile(docxDocument);
4115
- debugger;
4116
- zip
4117
- .folder(relsFolderName)
4118
- .file('.rels', create({ encoding: 'UTF-8', standalone: true }, relsXML).toString({ prettyPrint: true }), { createFolders: false });
4119
- zip.folder('docProps').file('core.xml', docxDocument.generateCoreXML(), {
4120
- createFolders: false,
4121
- });
4122
- if (docxDocument.header && headerHTMLString) {
4123
- const vTree = convertHTML(headerHTMLString);
4124
- docxDocument.relationshipFilename = headerFileName;
4125
- const { headerId, headerXML } = yield docxDocument.generateHeaderXML(vTree);
4126
- docxDocument.relationshipFilename = documentFileName;
4127
- const fileNameWithExt = `${headerType}${headerId}.xml`;
4128
- const relationshipId = docxDocument.createDocumentRelationships(docxDocument.relationshipFilename, headerType, fileNameWithExt, internalRelationship);
4129
- zip.folder(wordFolder).file(fileNameWithExt, generateDocumentTemplateHeader.toString({ prettyPrint: true }), {
4130
- createFolders: false,
4131
- });
4132
- docxDocument.headerObjects.push({ headerId, relationshipId, type: docxDocument.headerType });
4133
- }
4134
- if (docxDocument.footer && footerHTMLString) {
4135
- const vTree = convertHTML(footerHTMLString);
4136
- docxDocument.relationshipFilename = footerFileName;
4137
- const { footerId, footerXML } = yield docxDocument.generateFooterXML(vTree);
4138
- docxDocument.relationshipFilename = documentFileName;
4139
- const fileNameWithExt = `${footerType}${footerId}.xml`;
4140
- const relationshipId = docxDocument.createDocumentRelationships(docxDocument.relationshipFilename, footerType, fileNameWithExt, internalRelationship);
4141
- console.log(footerXML.toString({ prettyPrint: true }));
4142
- if (suppliedDocumentOptions.pageNumber)
4143
- zip.folder(wordFolder).file(fileNameWithExt, generateDocumentTemplateFooter.toString({ prettyPrint: true }), {
4144
- createFolders: false,
4145
- });
4146
- else
4147
- zip.folder(wordFolder).file(fileNameWithExt, generateDocumentTemplateFooterWithoutPaging.toString({ prettyPrint: true }), {
4148
- createFolders: false,
4149
- });
4150
- docxDocument.footerObjects.push({ footerId, relationshipId, type: docxDocument.footerType });
4151
- }
4152
- const themeFileNameWithExt = `${themeFileName}.xml`;
4153
- docxDocument.createDocumentRelationships(docxDocument.relationshipFilename, themeType, `${themeFolder}/${themeFileNameWithExt}`, internalRelationship);
4154
- zip
4155
- .folder(wordFolder)
4156
- .folder(themeFolder)
4157
- .file(themeFileNameWithExt, docxDocument.generateThemeXML(), {
4158
- createFolders: false,
4159
- });
4160
- zip
4161
- .folder(wordFolder)
4162
- .file('document.xml', docxDocument.generateDocumentXML(), { createFolders: false })
4163
- .file('afchunk.mht', getMHTdocument(htmlString), {
4164
- createFolders: false,
4165
- })
4166
- .file('afchunkheader.mht', getMHTdocument(headerHTMLString), {
4167
- createFolders: false,
4168
- })
4169
- .file('afchunkfooter.mht', getMHTdocument(footerHTMLString), {
4170
- createFolders: false,
4171
- })
4172
- .file('fontTable.xml', docxDocument.generateFontTableXML(), { createFolders: false })
4173
- .file('styles.xml', docxDocument.generateStylesXML(), { createFolders: false })
4174
- .file('numbering.xml', docxDocument.generateNumberingXML(), { createFolders: false })
4175
- .file('settings.xml', docxDocument.generateSettingsXML(), { createFolders: false })
4176
- .file('webSettings.xml', docxDocument.generateWebSettingsXML(), { createFolders: false });
4177
- const relationshipXMLs = docxDocument.generateRelsXML();
4178
- if (relationshipXMLs && Array.isArray(relationshipXMLs)) {
4179
- relationshipXMLs.forEach(({ fileName, xmlString }) => {
4180
- console.log(xmlString);
4181
- zip.folder(wordFolder).folder(relsFolderName).file(`${fileName}.xml.rels`, xmlString, {
4182
- createFolders: false,
4183
- });
4184
- });
4185
- }
4186
- if (relationshipXMLs && Array.isArray(relationshipXMLs)) {
4187
- relationshipXMLs.forEach(({ fileName, xmlString }) => {
4188
- zip.folder(wordFolder).folder(relsFolderName).file(`header1.xml.rels`, xmlString, {
4189
- createFolders: false,
4190
- });
4191
- });
4192
- }
4193
- if (relationshipXMLs && Array.isArray(relationshipXMLs)) {
4194
- relationshipXMLs.forEach(({ fileName, xmlString }) => {
4195
- zip.folder(wordFolder).folder(relsFolderName).file(`footer1.xml.rels`, xmlString, {
4196
- createFolders: false,
4197
- });
4198
- });
4199
- }
4200
- zip.file('[Content_Types].xml', docxDocument.generateContentTypesXML(), { createFolders: false });
4201
- return zip;
4202
- });
4203
- }
4204
-
4205
- const minifyHTMLString = (htmlString) => {
4206
- try {
4207
- if (typeof htmlString === 'string' || htmlString instanceof String) {
4208
- const minifiedHTMLString = htmlString
4209
- .replace(/\n/g, ' ')
4210
- .replace(/\r/g, ' ')
4211
- .replace(/\r\n/g, ' ')
4212
- .replace(/[\t]+\</g, '<')
4213
- .replace(/\>[\t ]+\</g, '><')
4214
- .replace(/\>[\t ]+$/g, '>');
4215
- return minifiedHTMLString;
4216
- }
4217
- throw new Error('invalid html string');
4218
- }
4219
- catch (error) {
4220
- return null;
4221
- }
4222
- };
4223
- function generateContainer(htmlString, headerHTMLString, documentOptions = {}, footerHTMLString) {
4224
- return __awaiter(this, void 0, void 0, function* () {
4225
- const zip = new JSZip();
4226
- let contentHTML = htmlString;
4227
- let headerHTML = headerHTMLString;
4228
- let footerHTML = footerHTMLString;
4229
- if (htmlString) {
4230
- contentHTML = minifyHTMLString(contentHTML);
4231
- }
4232
- if (headerHTMLString) {
4233
- headerHTML = minifyHTMLString(headerHTML);
4234
- }
4235
- if (footerHTMLString) {
4236
- footerHTML = minifyHTMLString(footerHTML);
4237
- }
4238
- yield addFilesToContainer(zip, contentHTML, documentOptions, headerHTML, footerHTML);
4239
- const buffer = yield zip.generateAsync({ type: 'arraybuffer' });
4240
- if (Object.prototype.hasOwnProperty.call(global, 'Buffer')) {
4241
- return Buffer.from(new Uint8Array(buffer));
4242
- }
4243
- if (Object.prototype.hasOwnProperty.call(global, 'Blob')) {
4244
- // eslint-disable-next-line no-undef
4245
- return new Blob([buffer], {
4246
- type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
4247
- });
4248
- }
4249
- throw new Error('Add blob support using a polyfill eg https://github.com/bjornstar/blob-polyfill');
4250
- });
4251
- }
4252
-
4253
- class WordDocumentService {
4254
- generateWordByteFile(model) {
4255
- return __awaiter(this, void 0, void 0, function* () {
4256
- let documentOptions = {};
4257
- if (model.options.isLandscape)
4258
- documentOptions.orientation = 'landscape';
4259
- documentOptions.pageSize = {
4260
- width: model.options.pageWidth * 15,
4261
- height: model.options.pageHeight * 15,
4262
- };
4263
- documentOptions.margins = {
4264
- top: model.options.top * 15,
4265
- right: model.options.right * 15,
4266
- bottom: model.options.bottom * 15,
4267
- left: model.options.left * 15,
4268
- header: model.options.top * 15 * 2,
4269
- footer: model.options.bottom * 15 * 2,
4270
- gutter: 0,
4271
- };
4272
- documentOptions.footer = true;
4273
- documentOptions.header = true;
4274
- documentOptions.pageNumber = model.options.showPaging;
4275
- documentOptions.table = { row: { cantSplit: true } };
4276
- var fileBuffer = yield generateContainer(model.body, model.header, documentOptions, model.footer);
4277
- return fileBuffer;
4278
- });
4279
- }
4280
- }
4281
- WordDocumentService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WordDocumentService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4282
- WordDocumentService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WordDocumentService, providedIn: 'root' });
4283
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WordDocumentService, decorators: [{
4284
- type: Injectable,
4285
- args: [{
4286
- providedIn: 'root',
4287
- }]
4288
- }] });
4289
-
4290
- const TOKEN_KEY = 'access_token';
4291
- class AuthService {
4292
- constructor(injector, http, environmentService, translateService, router, cookieService, utilityService) {
4293
- this.injector = injector;
4294
- this.http = http;
4295
- this.environmentService = environmentService;
4296
- this.translateService = translateService;
4297
- this.router = router;
4298
- this.cookieService = cookieService;
4299
- this.utilityService = utilityService;
4300
- this.redirectUrl = '';
4301
- this.jwtHelper = new JwtHelperService();
4302
- this.isAuthenticatedSubject = new BehaviorSubject(this.hasToken());
4303
- this.isAuthenticate$ = this.isAuthenticatedSubject.asObservable();
4304
- this.user = this.getUserManager();
4305
- }
4306
- hasToken() {
4307
- const token = this.cookieService.get(TOKEN_KEY);
4308
- return token && !this.jwtHelper.isTokenExpired(token);
4309
- }
4310
- getUserManager() {
4311
- const token = this.cookieService.get(TOKEN_KEY);
4312
- if (token)
4313
- this.handleAccessTokenWithoutLanguage(token);
4314
- return AuthService.user;
4315
- }
4316
- getUser() {
4317
- this.user = AuthService.user;
4318
- }
4319
- storUser(User) {
4320
- AuthService.user = this.user = this.user;
4321
- }
4322
- getCurrentUser() {
4323
- return AuthService.user;
4324
- }
4325
- isAuthenticated() {
4326
- return __awaiter(this, void 0, void 0, function* () {
4327
- return AuthService.user != null && !this.jwtHelper.isTokenExpired(AuthService.user.access_token);
4328
- });
4329
- }
4330
- isUserInRole(allowedPermission) {
4331
- let selectedPermissionSetID = Number.parseInt(this.user.profile['selectedpermissionsetid']);
4332
- return allowedPermission.includes(selectedPermissionSetID);
4333
- }
4334
- authorizationHeaderValue() {
4335
- return AuthService.user
4336
- ? `${AuthService.user.token_type} ${AuthService.user.access_token}`
4337
- : '';
4338
- }
4339
- name() {
4340
- return AuthService.user != null ? AuthService.user.profile.given_name : '';
4341
- }
4342
- setUrl(url) {
4343
- localStorage.setItem('redirectUrl', url);
4344
- }
4345
- getUrl() {
4346
- var _a;
4347
- return (_a = localStorage.getItem('redirectUrl')) !== null && _a !== void 0 ? _a : "/";
4348
- }
4349
- signOut() {
4350
- AuthService.timers.map(t => clearInterval(t));
4351
- AuthService.timers = [];
4352
- if (!this.isAuthenticated()) {
4353
- this.cookieService.delete(TOKEN_KEY);
4354
- this.router.navigate(['/Admin/account/login']);
4355
- }
4356
- this.logout().subscribe(res => {
4357
- this.cookieService.delete(TOKEN_KEY);
4358
- if (this.environmentService.getBBSFAuthenticationMode() == AuthenticationModes.UAEPass)
4359
- this.logoutFromUAEPass();
4360
- else
4361
- this.router.navigate(['/Admin/account/login']);
4362
- });
4363
- }
4364
- logout() {
4365
- const httpOptions = {
4366
- headers: new HttpHeaders({
4367
- 'Content-Type': 'application/json',
4368
- }),
4369
- };
4370
- let ApiUrl = '/Account/';
4371
- return this.http.get(this.environmentService.getApiUrl() + ApiUrl + 'Logout', httpOptions);
4372
- }
4373
- clearUserSessionClaims() {
4374
- const httpOptions = {
4375
- headers: new HttpHeaders({
4376
- 'Content-Type': 'application/json',
4377
- }),
4378
- };
4379
- let ApiUrl = '/api/Home/';
4380
- return this.http.get(this.environmentService.getBaseUrl() + ApiUrl + 'ClearCurrentUserSession', httpOptions);
4381
- }
4382
- handleAccessToken(response) {
4383
- return __awaiter(this, void 0, void 0, function* () {
4384
- const token = response;
4385
- AuthService.user = new User();
4386
- AuthService.user.token_type = "Bearer";
4387
- AuthService.user.access_token = token;
4388
- AuthService.user.profile = this.jwtHelper.decodeToken(token);
4389
- AuthService.user.expires_at = this.jwtHelper.getTokenExpirationDate(token);
4390
- AuthService.timers.map(t => clearInterval(t));
4391
- AuthService.timers = [];
4392
- this.setTokenSeconds();
4393
- AuthService.timers.push(this.checkRefreshToken());
4394
- this.user = AuthService.user;
4395
- yield this.updateLanguage();
4396
- this.cookieService.set(TOKEN_KEY, token, null, null, null, true, 'Strict');
4397
- this.isAuthenticatedSubject.next(true);
4398
- });
4399
- }
4400
- handleAccessTokenWithoutLanguage(response) {
4401
- const token = response;
4402
- AuthService.user = new User();
4403
- AuthService.user.token_type = "Bearer";
4404
- AuthService.user.access_token = token;
4405
- AuthService.user.profile = this.jwtHelper.decodeToken(token);
4406
- AuthService.user.expires_at = this.jwtHelper.getTokenExpirationDate(token);
4407
- this.setTokenSeconds();
4408
- this.user = AuthService.user;
4409
- this.cookieService.set(TOKEN_KEY, token, null, null, null, true, 'Strict');
4410
- this.isAuthenticatedSubject.next(true);
4411
- }
4412
- updateLanguage() {
4413
- return __awaiter(this, void 0, void 0, function* () {
4414
- if (!localStorage.getItem('language') ||
4415
- localStorage.getItem('language') == this.user.profile.locale)
4416
- localStorage.setItem('language', this.user.profile.locale);
4417
- if (this.translateService.currentLang != localStorage.getItem('language')) {
4418
- this.translateService.resetLang(this.translateService.currentLang);
4419
- yield this.translateService
4420
- .reloadLang(localStorage.getItem('language'))
4421
- .subscribe((res) => {
4422
- console.log(res);
4423
- });
4424
- }
4425
- });
4426
- }
4427
- checkRefreshToken() {
4428
- let date = new Date();
4429
- return setInterval(() => {
4430
- if (Math.floor(AuthService.seconds) < 120 && this.isAuthenticated())
4431
- this.refresh();
4432
- AuthService.seconds--;
4433
- }, 1000);
4434
- }
4435
- setTokenSeconds() {
4436
- let date = new Date();
4437
- AuthService.seconds = (AuthService.user.expires_at - date) / 1000;
4438
- }
4439
- refresh() {
4440
- const httpOptions = {
4441
- headers: new HttpHeaders({
4442
- 'Content-Type': 'application/json',
4443
- 'Authorization': this.authorizationHeaderValue(),
4444
- }),
4445
- };
4446
- let ApiUrl = '/api/Home/';
4447
- this.http.get(this.environmentService.getApiUrl() + ApiUrl + 'RefreshAccessToken', httpOptions).subscribe((res) => {
4448
- this.cookieService.delete(TOKEN_KEY);
4449
- this.handleAccessTokenWithoutLanguage(res.val);
4450
- });
4451
- }
4452
- loginWithUAEPass() {
4453
- const authEndpoint = `${this.environmentService.getUAEPassBaseUrl()}${this.environmentService.getUAEPassAuthorizationEndPoint()}`;
4454
- const queryParams = {
4455
- response_type: 'code',
4456
- client_id: `${this.environmentService.getUAEPassClientID()}`,
4457
- redirect_uri: `${this.environmentService.getBaseUrl()}${this.environmentService.getUAEPassRedirectUrl()}`,
4458
- scope: 'urn:uae:digitalid:profile:general urn:uae:digitalid:profile:general:profileType urn:uae:digitalid:profile:general:unifiedId',
4459
- state: 'pd3PgezRwk596u2yfRwqOgru',
4460
- acr_values: 'urn:safelayer:tws:policies:authentication:level:low'
4461
- };
4462
- const queryParamsString = Object.entries(queryParams)
4463
- .map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
4464
- .join('&');
4465
- const loginUrl = `${authEndpoint}?${queryParamsString}`;
4466
- window.location.href = loginUrl;
4467
- return;
4468
- }
4469
- logoutFromUAEPass() {
4470
- const logoutEndpoint = `${this.environmentService.getUAEPassBaseUrl()}${this.environmentService.getUAEPassLogoutEndPoint()}`;
4471
- const queryParams = {
4472
- redirect_uri: `${this.environmentService.getBaseUrl()}`,
4473
- };
4474
- const queryParamsString = Object.entries(queryParams)
4475
- .map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
4476
- .join('&');
4477
- const logoutUrl = `${logoutEndpoint}?${queryParamsString}`;
4478
- window.location.href = logoutUrl;
4479
- return;
4480
- }
4481
- }
4482
- AuthService.user = null;
4483
- AuthService.UserClaims = null;
4484
- //refresh
4485
- AuthService.timers = [];
4486
- AuthService.seconds = 0;
4487
- AuthService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AuthService, deps: [{ token: i0.Injector }, { token: i1.HttpClient }, { token: EnvironmentService }, { token: BBSFTranslateService }, { token: i1$1.Router }, { token: i4$1.CookieService }, { token: UtilityService }], target: i0.ɵɵFactoryTarget.Injectable });
4488
- AuthService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AuthService, providedIn: 'root' });
4489
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AuthService, decorators: [{
4490
- type: Injectable,
4491
- args: [{
4492
- providedIn: 'root',
4493
- }]
4494
- }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i1.HttpClient }, { type: EnvironmentService }, { type: BBSFTranslateService }, { type: i1$1.Router }, { type: i4$1.CookieService }, { type: UtilityService }]; } });
4495
-
4496
- class BBSFUtilitiesModule {
4497
- }
4498
- BBSFUtilitiesModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: BBSFUtilitiesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
4499
- BBSFUtilitiesModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: BBSFUtilitiesModule, imports: [CommonModule,
4500
- RouterModule, i1$2.BlockUIModule, i2.ToastrModule] });
4501
- BBSFUtilitiesModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: BBSFUtilitiesModule, providers: [
4502
- UtilityService,
4503
- EnvironmentService,
4504
- AuthService,
4505
- RequestHandlerService,
4506
- StylesBundleService,
4507
- TranslateService,
4508
- BBSFTranslateService,
4509
- ControlValidationService,
4510
- MasterLayoutService,
4511
- ConfigurationService,
4512
- CookieService
4513
- ], imports: [CommonModule,
4514
- RouterModule,
4515
- BlockUIModule.forRoot(),
4516
- ToastrModule.forRoot()] });
4517
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: BBSFUtilitiesModule, decorators: [{
4518
- type: NgModule,
4519
- args: [{
4520
- declarations: [],
4521
- imports: [
4522
- CommonModule,
4523
- RouterModule,
4524
- BlockUIModule.forRoot(),
4525
- ToastrModule.forRoot(),
4526
- ],
4527
- exports: [],
4528
- providers: [
4529
- UtilityService,
4530
- EnvironmentService,
4531
- AuthService,
4532
- RequestHandlerService,
4533
- StylesBundleService,
4534
- TranslateService,
4535
- BBSFTranslateService,
4536
- ControlValidationService,
4537
- MasterLayoutService,
4538
- ConfigurationService,
4539
- CookieService
4540
- ]
4541
- }]
4542
- }] });
4543
-
4544
- /*
4545
- * Public API Surface of @bnsights/bbsf-utilities
4546
- */
4547
- //Module
4548
- //#endregion
4549
-
4550
- /**
4551
- * Generated bundle index. Do not edit.
4552
- */
4553
-
4554
- export { AppearanceConfigurationService, AuthService, AuthenticationModes, BBSFTranslateService, BBSFUtilitiesModule, ConfigurationService, ControlValidationService, DocumentOptionsModel, EnvironmentService, MasterLayoutService, RequestHandlerService, RequestOptionsModel, StylesBundleService, TranslationResolverService, UtilityService, WordDocumentModel, WordDocumentService, environment };
4555
- //# sourceMappingURL=bnsights-bbsf-utilities.mjs.map