vgapp 1.3.4 → 1.3.6

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 (88) hide show
  1. package/app/langs/en/buttons.json +17 -17
  2. package/app/langs/en/messages.json +36 -36
  3. package/app/langs/ru/buttons.json +17 -17
  4. package/app/langs/ru/messages.json +36 -36
  5. package/app/modules/base-module.js +111 -111
  6. package/app/modules/vgalert/js/vgalert.js +52 -52
  7. package/app/modules/vgalert/readme.md +105 -105
  8. package/app/modules/vgdynamictable/index.js +5 -5
  9. package/app/modules/vgdynamictable/js/editable.js +19 -19
  10. package/app/modules/vgdynamictable/js/filters.js +21 -21
  11. package/app/modules/vgdynamictable/js/fixed.js +179 -179
  12. package/app/modules/vgdynamictable/js/pagination.js +1 -1
  13. package/app/modules/vgdynamictable/js/search.js +12 -12
  14. package/app/modules/vgdynamictable/js/sortable.js +71 -71
  15. package/app/modules/vgdynamictable/js/summary-footer.js +28 -28
  16. package/app/modules/vgdynamictable/js/table-remote.js +79 -79
  17. package/app/modules/vgdynamictable/js/table-url-state.js +31 -31
  18. package/app/modules/vgdynamictable/js/utils/common.js +48 -48
  19. package/app/modules/vgdynamictable/js/vgdynamictable.js +268 -268
  20. package/app/modules/vgdynamictable/readme.md +250 -250
  21. package/app/modules/vgdynamictable/scss/_skeleton.scss +6 -6
  22. package/app/modules/vgdynamictable/scss/_sortable.scss +24 -24
  23. package/app/modules/vgdynamictable/scss/_table.scss +4 -4
  24. package/app/modules/vgdynamictable/scss/_variables.scss +79 -79
  25. package/app/modules/vgdynamictable/scss/vgdynamictable.scss +27 -27
  26. package/app/modules/vgfilepreview/js/i18n.js +56 -56
  27. package/app/modules/vgfilepreview/js/renderers/image-modal.js +145 -145
  28. package/app/modules/vgfilepreview/js/renderers/image.js +92 -92
  29. package/app/modules/vgfilepreview/js/renderers/index.js +19 -19
  30. package/app/modules/vgfilepreview/js/renderers/office-modal.js +168 -168
  31. package/app/modules/vgfilepreview/js/renderers/office.js +79 -79
  32. package/app/modules/vgfilepreview/js/renderers/pdf-modal.js +260 -260
  33. package/app/modules/vgfilepreview/js/renderers/pdf.js +76 -76
  34. package/app/modules/vgfilepreview/js/renderers/playlist.js +71 -71
  35. package/app/modules/vgfilepreview/js/renderers/text-modal.js +343 -343
  36. package/app/modules/vgfilepreview/js/renderers/text.js +83 -83
  37. package/app/modules/vgfilepreview/js/renderers/video-modal.js +272 -272
  38. package/app/modules/vgfilepreview/js/renderers/video.js +80 -80
  39. package/app/modules/vgfilepreview/js/renderers/zip-modal.js +522 -522
  40. package/app/modules/vgfilepreview/js/renderers/zip.js +89 -89
  41. package/app/modules/vgfilepreview/js/vgfilepreview.js +7 -7
  42. package/app/modules/vgfilepreview/readme.md +68 -68
  43. package/app/modules/vgfilepreview/scss/_variables.scss +113 -113
  44. package/app/modules/vgfilepreview/scss/vgfilepreview.scss +464 -464
  45. package/app/modules/vgfiles/js/base.js +26 -26
  46. package/app/modules/vgfiles/js/droppable.js +260 -260
  47. package/app/modules/vgfiles/js/render.js +153 -153
  48. package/app/modules/vgfiles/js/vgfiles.js +104 -104
  49. package/app/modules/vgfiles/readme.md +123 -123
  50. package/app/modules/vgfiles/scss/_variables.scss +18 -18
  51. package/app/modules/vgfiles/scss/vgfiles.scss +148 -148
  52. package/app/modules/vgformsender/js/hideshowpass.js +16 -16
  53. package/app/modules/vgformsender/scss/vgformsender.scss +34 -34
  54. package/app/modules/vgmodal/js/vgmodal.drag.js +332 -332
  55. package/app/modules/vgmodal/js/vgmodal.js +188 -188
  56. package/app/modules/vgmodal/js/vgmodal.resize.js +27 -27
  57. package/app/modules/vgmodal/scss/vgmodal.scss +14 -14
  58. package/app/modules/vgnav/js/vgnav.js +135 -135
  59. package/app/modules/vgnav/readme.md +67 -67
  60. package/app/modules/vgnestable/README.md +307 -307
  61. package/app/modules/vgnestable/scss/_variables.scss +60 -60
  62. package/app/modules/vgnestable/scss/vgnestable.scss +163 -163
  63. package/app/modules/vgrangeslider/js/skins.js +222 -222
  64. package/app/modules/vgrangeslider/js/vgrangeslider.js +704 -704
  65. package/app/modules/vgrangeslider/readme.md +523 -523
  66. package/app/modules/vgrangeslider/scss/_variables.scss +53 -53
  67. package/app/modules/vgrangeslider/scss/vgrangeslider.scss +240 -240
  68. package/app/modules/vgselect/js/vgselect.js +39 -39
  69. package/app/modules/vgselect/scss/vgselect.scss +22 -22
  70. package/app/modules/vgspy/readme.md +28 -28
  71. package/app/modules/vgtoast/readme.md +18 -18
  72. package/app/modules/vgtoast/scss/vgtoast.scss +48 -48
  73. package/app/modules/vgtooltip/js/vgtooltip.js +89 -89
  74. package/app/modules/vgtooltip/readme.md +181 -181
  75. package/app/utils/js/components/ajax.js +117 -117
  76. package/app/utils/js/components/audio-metadata.js +240 -240
  77. package/app/utils/js/components/backdrop.js +17 -17
  78. package/app/utils/js/components/file-icon.js +109 -109
  79. package/app/utils/js/components/file-preview.js +304 -304
  80. package/app/utils/js/components/sanitize.js +150 -150
  81. package/app/utils/js/components/video-metadata.js +140 -140
  82. package/app/vgapp.js +46 -46
  83. package/build/vgapp.css +1 -1
  84. package/build/vgapp.css.map +1 -1
  85. package/build/vgapp.js +1 -1
  86. package/build/vgapp.js.map +1 -1
  87. package/index.js +14 -14
  88. package/package.json +3 -1
@@ -1,79 +1,79 @@
1
- import OfficeModal from "./office-modal";
2
-
3
- const OFFICE_EXTENSIONS = new Set([
4
- '.doc',
5
- '.docx',
6
- '.xls',
7
- '.xlsx',
8
- '.ppt',
9
- '.pptx',
10
- '.odt',
11
- '.ods',
12
- '.odp'
13
- ]);
14
-
15
- class OfficeFilePreviewRenderer {
16
- constructor() {
17
- this.name = 'office';
18
- this._modal = OfficeModal.getInstance();
19
- }
20
-
21
- canRender(context = {}) {
22
- const ext = String(context?.fileMeta?.ext || '').toLowerCase();
23
- return OFFICE_EXTENSIONS.has(ext);
24
- }
25
-
26
- render(context = {}) {
27
- const container = context?.previewContainer;
28
- const nameOnly = Boolean(context?.ui?.nameOnly);
29
- const i18n = context?.i18n;
30
-
31
- const src = context?.fileUrl?.href || context?.filePath || '';
32
- if (!src) {
33
- return false;
34
- }
35
-
36
- const openOffice = (event) => {
37
- if (event) {
38
- event.preventDefault();
39
- }
40
-
41
- this._modal.open({
42
- src,
43
- title: context?.fileMeta?.name || i18n?.message('office_title') || '',
44
- defaultTitle: i18n?.message('office_title') || '',
45
- downloadName: context?.fileMeta?.originalName || context?.fileMeta?.name || '',
46
- labels: {
47
- download: i18n?.button('download') || '',
48
- fallback: i18n?.message('office_fallback') || ''
49
- }
50
- });
51
- };
52
-
53
- const titleLink = context?.element?.querySelector('.name');
54
- if (titleLink && !titleLink.hasAttribute('data-vg-filepreview-office-bind')) {
55
- titleLink.setAttribute('data-vg-filepreview-office-bind', 'true');
56
- titleLink.classList.add('is-preview-action');
57
- titleLink.addEventListener('click', openOffice);
58
- }
59
-
60
- if (nameOnly) {
61
- return Boolean(titleLink);
62
- }
63
-
64
- if (!container) {
65
- return false;
66
- }
67
-
68
- const trigger = document.createElement('button');
69
- trigger.type = 'button';
70
- trigger.className = 'vg-filepreview-office-trigger';
71
- trigger.textContent = i18n?.button('open_office') || '';
72
- trigger.addEventListener('click', openOffice);
73
- container.appendChild(trigger);
74
-
75
- return true;
76
- }
77
- }
78
-
79
- export default OfficeFilePreviewRenderer;
1
+ import OfficeModal from "./office-modal";
2
+
3
+ const OFFICE_EXTENSIONS = new Set([
4
+ '.doc',
5
+ '.docx',
6
+ '.xls',
7
+ '.xlsx',
8
+ '.ppt',
9
+ '.pptx',
10
+ '.odt',
11
+ '.ods',
12
+ '.odp'
13
+ ]);
14
+
15
+ class OfficeFilePreviewRenderer {
16
+ constructor() {
17
+ this.name = 'office';
18
+ this._modal = OfficeModal.getInstance();
19
+ }
20
+
21
+ canRender(context = {}) {
22
+ const ext = String(context?.fileMeta?.ext || '').toLowerCase();
23
+ return OFFICE_EXTENSIONS.has(ext);
24
+ }
25
+
26
+ render(context = {}) {
27
+ const container = context?.previewContainer;
28
+ const nameOnly = Boolean(context?.ui?.nameOnly);
29
+ const i18n = context?.i18n;
30
+
31
+ const src = context?.fileUrl?.href || context?.filePath || '';
32
+ if (!src) {
33
+ return false;
34
+ }
35
+
36
+ const openOffice = (event) => {
37
+ if (event) {
38
+ event.preventDefault();
39
+ }
40
+
41
+ this._modal.open({
42
+ src,
43
+ title: context?.fileMeta?.name || i18n?.message('office_title') || '',
44
+ defaultTitle: i18n?.message('office_title') || '',
45
+ downloadName: context?.fileMeta?.originalName || context?.fileMeta?.name || '',
46
+ labels: {
47
+ download: i18n?.button('download') || '',
48
+ fallback: i18n?.message('office_fallback') || ''
49
+ }
50
+ });
51
+ };
52
+
53
+ const titleLink = context?.element?.querySelector('.name');
54
+ if (titleLink && !titleLink.hasAttribute('data-vg-filepreview-office-bind')) {
55
+ titleLink.setAttribute('data-vg-filepreview-office-bind', 'true');
56
+ titleLink.classList.add('is-preview-action');
57
+ titleLink.addEventListener('click', openOffice);
58
+ }
59
+
60
+ if (nameOnly) {
61
+ return Boolean(titleLink);
62
+ }
63
+
64
+ if (!container) {
65
+ return false;
66
+ }
67
+
68
+ const trigger = document.createElement('button');
69
+ trigger.type = 'button';
70
+ trigger.className = 'vg-filepreview-office-trigger';
71
+ trigger.textContent = i18n?.button('open_office') || '';
72
+ trigger.addEventListener('click', openOffice);
73
+ container.appendChild(trigger);
74
+
75
+ return true;
76
+ }
77
+ }
78
+
79
+ export default OfficeFilePreviewRenderer;
@@ -1,260 +1,260 @@
1
- import VGModal from "../../../vgmodal";
2
-
3
- class PdfModal {
4
- constructor() {
5
- this._modalId = 'vg-filepreview-pdf-modal';
6
- this._labels = {};
7
- this._src = '';
8
- this._downloadName = '';
9
- this._page = 1;
10
- this._zoom = 100;
11
- }
12
-
13
- static getInstance() {
14
- if (!PdfModal._instance) {
15
- PdfModal._instance = new PdfModal();
16
- }
17
-
18
- return PdfModal._instance;
19
- }
20
-
21
- open(payload = {}) {
22
- const src = String(payload.src || '').trim();
23
- if (!src) {
24
- return;
25
- }
26
-
27
- this._ensureModal();
28
- if (!this._modal || !this._frame) {
29
- return;
30
- }
31
-
32
- this._labels = payload?.labels && typeof payload.labels === 'object' ? payload.labels : {};
33
- this._src = src;
34
- this._downloadName = String(payload.downloadName || '').trim();
35
- this._page = 1;
36
- this._zoom = 100;
37
-
38
- const defaultTitle = String(payload.defaultTitle || '').trim();
39
- const title = String(payload.title || '').trim();
40
- this._title.textContent = title || defaultTitle;
41
-
42
- this._syncControls();
43
- this._updateFrameSrc();
44
- this._modal.show();
45
- }
46
-
47
- _ensureModal() {
48
- if (this._modal && this._root) {
49
- return;
50
- }
51
- this._initModal();
52
- }
53
-
54
- _initModal() {
55
- const params = {
56
- centered: true,
57
- dismiss: true,
58
- backdrop: true,
59
- keyboard: true,
60
- sizes: {
61
- width: 'fit-content',
62
- },
63
- animation: {
64
- enable: false
65
- }
66
- };
67
-
68
- const existed = document.getElementById(this._modalId);
69
- if (existed) {
70
- this._root = existed;
71
- this._modal = VGModal.getOrCreateInstance(existed, params);
72
- this._bindElements(existed);
73
- this._bindLifecycle(existed);
74
- return;
75
- }
76
-
77
- this._modal = VGModal.build(this._modalId, params, (modalInstance) => {
78
- const element = modalInstance._element;
79
- this._root = element;
80
- element.classList.add('vg-filepreview-pdf-modal');
81
-
82
- const body = element.querySelector('.vg-modal-body');
83
- const content = element.querySelector('.vg-modal-content');
84
- if (!body || !content) {
85
- return;
86
- }
87
-
88
- body.classList.add('vg-filepreview-pdf-modal__body');
89
- body.innerHTML = '';
90
-
91
- let header = element.querySelector('.vg-modal-header');
92
- if (!header) {
93
- header = document.createElement('div');
94
- header.className = 'vg-modal-header';
95
- content.prepend(header);
96
- }
97
-
98
- this._title = document.createElement('div');
99
- this._title.className = 'vg-modal-title';
100
-
101
- const toolbar = document.createElement('div');
102
- toolbar.className = 'vg-filepreview-pdf-modal__toolbar';
103
-
104
- this._pagePrev = document.createElement('button');
105
- this._pagePrev.type = 'button';
106
- this._pagePrev.className = 'vg-filepreview-pdf-modal__btn';
107
- this._pagePrev.setAttribute('data-role', 'page-prev');
108
- this._pagePrev.addEventListener('click', () => {
109
- this._page = Math.max(1, this._page - 1);
110
- this._syncControls();
111
- this._updateFrameSrc();
112
- });
113
-
114
- this._pageInfo = document.createElement('span');
115
- this._pageInfo.className = 'vg-filepreview-pdf-modal__meta';
116
- this._pageInfo.setAttribute('data-role', 'page');
117
-
118
- this._pageNext = document.createElement('button');
119
- this._pageNext.type = 'button';
120
- this._pageNext.className = 'vg-filepreview-pdf-modal__btn';
121
- this._pageNext.setAttribute('data-role', 'page-next');
122
- this._pageNext.addEventListener('click', () => {
123
- this._page += 1;
124
- this._syncControls();
125
- this._updateFrameSrc();
126
- });
127
-
128
- this._zoomOut = document.createElement('button');
129
- this._zoomOut.type = 'button';
130
- this._zoomOut.className = 'vg-filepreview-pdf-modal__btn';
131
- this._zoomOut.setAttribute('data-role', 'zoom-out');
132
- this._zoomOut.addEventListener('click', () => {
133
- this._zoom = Math.max(50, this._zoom - 10);
134
- this._syncControls();
135
- this._updateFrameSrc();
136
- });
137
-
138
- this._zoomIn = document.createElement('button');
139
- this._zoomIn.type = 'button';
140
- this._zoomIn.className = 'vg-filepreview-pdf-modal__btn';
141
- this._zoomIn.setAttribute('data-role', 'zoom-in');
142
- this._zoomIn.addEventListener('click', () => {
143
- this._zoom = Math.min(300, this._zoom + 10);
144
- this._syncControls();
145
- this._updateFrameSrc();
146
- });
147
-
148
- this._zoomInfo = document.createElement('span');
149
- this._zoomInfo.className = 'vg-filepreview-pdf-modal__meta';
150
- this._zoomInfo.setAttribute('data-role', 'zoom');
151
-
152
- this._download = document.createElement('button');
153
- this._download.type = 'button';
154
- this._download.className = 'vg-filepreview-pdf-modal__btn primary';
155
- this._download.setAttribute('data-role', 'download');
156
- this._download.addEventListener('click', () => this._downloadFile());
157
-
158
- toolbar.appendChild(this._pagePrev);
159
- toolbar.appendChild(this._pageInfo);
160
- toolbar.appendChild(this._pageNext);
161
- toolbar.appendChild(this._zoomOut);
162
- toolbar.appendChild(this._zoomInfo);
163
- toolbar.appendChild(this._zoomIn);
164
- toolbar.appendChild(this._download);
165
-
166
- this._frame = document.createElement('iframe');
167
- this._frame.className = 'vg-filepreview-pdf-modal__frame';
168
- this._frame.setAttribute('title', 'PDF preview');
169
-
170
- header.appendChild(this._title);
171
- //header.appendChild(toolbar);
172
- body.appendChild(this._frame);
173
-
174
- this._bindLifecycle(element);
175
- });
176
- }
177
-
178
- _bindElements(root) {
179
- this._title = root.querySelector('.vg-filepreview-pdf-modal__title');
180
- this._frame = root.querySelector('.vg-filepreview-pdf-modal__frame');
181
- this._pagePrev = root.querySelector('.vg-filepreview-pdf-modal__btn[data-role="page-prev"]');
182
- this._pageNext = root.querySelector('.vg-filepreview-pdf-modal__btn[data-role="page-next"]');
183
- this._zoomOut = root.querySelector('.vg-filepreview-pdf-modal__btn[data-role="zoom-out"]');
184
- this._zoomIn = root.querySelector('.vg-filepreview-pdf-modal__btn[data-role="zoom-in"]');
185
- this._download = root.querySelector('.vg-filepreview-pdf-modal__btn[data-role="download"]');
186
- this._pageInfo = root.querySelector('.vg-filepreview-pdf-modal__meta[data-role="page"]');
187
- this._zoomInfo = root.querySelector('.vg-filepreview-pdf-modal__meta[data-role="zoom"]');
188
- }
189
-
190
- _bindLifecycle(root) {
191
- if (!root || root.hasAttribute('data-vg-filepreview-pdf-lifecycle-bind')) {
192
- return;
193
- }
194
-
195
- root.setAttribute('data-vg-filepreview-pdf-lifecycle-bind', 'true');
196
- root.addEventListener('vg.modal.hidden', () => this._destroyModal());
197
- }
198
-
199
- _syncControls() {
200
- if (!this._pageInfo || !this._zoomInfo) {
201
- return;
202
- }
203
-
204
- this._pagePrev.textContent = this._label('prevPage');
205
- this._pageNext.textContent = this._label('nextPage');
206
- this._zoomOut.textContent = this._label('zoomOut');
207
- this._zoomIn.textContent = this._label('zoomIn');
208
- this._download.textContent = this._label('download');
209
- this._pageInfo.textContent = `${this._label('page')}: ${this._page}`;
210
- this._zoomInfo.textContent = `${this._label('zoom')}: ${this._zoom}%`;
211
- }
212
-
213
- _updateFrameSrc() {
214
- if (!this._frame || !this._src) {
215
- return;
216
- }
217
-
218
- const hash = `#page=${this._page}&zoom=${this._zoom}`;
219
- this._frame.src = `${this._src}${hash}`;
220
- }
221
-
222
- _downloadFile() {
223
- if (!this._src) {
224
- return;
225
- }
226
-
227
- const link = document.createElement('a');
228
- link.href = this._src;
229
- if (this._downloadName) {
230
- link.setAttribute('download', this._downloadName);
231
- }
232
- link.style.display = 'none';
233
- document.body.appendChild(link);
234
- link.click();
235
- document.body.removeChild(link);
236
- }
237
-
238
- _label(key) {
239
- const value = this._labels?.[key];
240
- return String(value || '').trim();
241
- }
242
-
243
- _destroyModal() {
244
- if (this._modal && typeof this._modal.dispose === 'function') {
245
- this._modal.dispose();
246
- }
247
- if (this._root && this._root.parentNode) {
248
- this._root.parentNode.removeChild(this._root);
249
- }
250
-
251
- this._root = null;
252
- this._modal = null;
253
- this._title = null;
254
- this._frame = null;
255
- this._labels = null;
256
- this._src = '';
257
- }
258
- }
259
-
260
- export default PdfModal;
1
+ import VGModal from "../../../vgmodal";
2
+
3
+ class PdfModal {
4
+ constructor() {
5
+ this._modalId = 'vg-filepreview-pdf-modal';
6
+ this._labels = {};
7
+ this._src = '';
8
+ this._downloadName = '';
9
+ this._page = 1;
10
+ this._zoom = 100;
11
+ }
12
+
13
+ static getInstance() {
14
+ if (!PdfModal._instance) {
15
+ PdfModal._instance = new PdfModal();
16
+ }
17
+
18
+ return PdfModal._instance;
19
+ }
20
+
21
+ open(payload = {}) {
22
+ const src = String(payload.src || '').trim();
23
+ if (!src) {
24
+ return;
25
+ }
26
+
27
+ this._ensureModal();
28
+ if (!this._modal || !this._frame) {
29
+ return;
30
+ }
31
+
32
+ this._labels = payload?.labels && typeof payload.labels === 'object' ? payload.labels : {};
33
+ this._src = src;
34
+ this._downloadName = String(payload.downloadName || '').trim();
35
+ this._page = 1;
36
+ this._zoom = 100;
37
+
38
+ const defaultTitle = String(payload.defaultTitle || '').trim();
39
+ const title = String(payload.title || '').trim();
40
+ this._title.textContent = title || defaultTitle;
41
+
42
+ this._syncControls();
43
+ this._updateFrameSrc();
44
+ this._modal.show();
45
+ }
46
+
47
+ _ensureModal() {
48
+ if (this._modal && this._root) {
49
+ return;
50
+ }
51
+ this._initModal();
52
+ }
53
+
54
+ _initModal() {
55
+ const params = {
56
+ centered: true,
57
+ dismiss: true,
58
+ backdrop: true,
59
+ keyboard: true,
60
+ sizes: {
61
+ width: 'fit-content',
62
+ },
63
+ animation: {
64
+ enable: false
65
+ }
66
+ };
67
+
68
+ const existed = document.getElementById(this._modalId);
69
+ if (existed) {
70
+ this._root = existed;
71
+ this._modal = VGModal.getOrCreateInstance(existed, params);
72
+ this._bindElements(existed);
73
+ this._bindLifecycle(existed);
74
+ return;
75
+ }
76
+
77
+ this._modal = VGModal.build(this._modalId, params, (modalInstance) => {
78
+ const element = modalInstance._element;
79
+ this._root = element;
80
+ element.classList.add('vg-filepreview-pdf-modal');
81
+
82
+ const body = element.querySelector('.vg-modal-body');
83
+ const content = element.querySelector('.vg-modal-content');
84
+ if (!body || !content) {
85
+ return;
86
+ }
87
+
88
+ body.classList.add('vg-filepreview-pdf-modal__body');
89
+ body.innerHTML = '';
90
+
91
+ let header = element.querySelector('.vg-modal-header');
92
+ if (!header) {
93
+ header = document.createElement('div');
94
+ header.className = 'vg-modal-header';
95
+ content.prepend(header);
96
+ }
97
+
98
+ this._title = document.createElement('div');
99
+ this._title.className = 'vg-modal-title';
100
+
101
+ const toolbar = document.createElement('div');
102
+ toolbar.className = 'vg-filepreview-pdf-modal__toolbar';
103
+
104
+ this._pagePrev = document.createElement('button');
105
+ this._pagePrev.type = 'button';
106
+ this._pagePrev.className = 'vg-filepreview-pdf-modal__btn';
107
+ this._pagePrev.setAttribute('data-role', 'page-prev');
108
+ this._pagePrev.addEventListener('click', () => {
109
+ this._page = Math.max(1, this._page - 1);
110
+ this._syncControls();
111
+ this._updateFrameSrc();
112
+ });
113
+
114
+ this._pageInfo = document.createElement('span');
115
+ this._pageInfo.className = 'vg-filepreview-pdf-modal__meta';
116
+ this._pageInfo.setAttribute('data-role', 'page');
117
+
118
+ this._pageNext = document.createElement('button');
119
+ this._pageNext.type = 'button';
120
+ this._pageNext.className = 'vg-filepreview-pdf-modal__btn';
121
+ this._pageNext.setAttribute('data-role', 'page-next');
122
+ this._pageNext.addEventListener('click', () => {
123
+ this._page += 1;
124
+ this._syncControls();
125
+ this._updateFrameSrc();
126
+ });
127
+
128
+ this._zoomOut = document.createElement('button');
129
+ this._zoomOut.type = 'button';
130
+ this._zoomOut.className = 'vg-filepreview-pdf-modal__btn';
131
+ this._zoomOut.setAttribute('data-role', 'zoom-out');
132
+ this._zoomOut.addEventListener('click', () => {
133
+ this._zoom = Math.max(50, this._zoom - 10);
134
+ this._syncControls();
135
+ this._updateFrameSrc();
136
+ });
137
+
138
+ this._zoomIn = document.createElement('button');
139
+ this._zoomIn.type = 'button';
140
+ this._zoomIn.className = 'vg-filepreview-pdf-modal__btn';
141
+ this._zoomIn.setAttribute('data-role', 'zoom-in');
142
+ this._zoomIn.addEventListener('click', () => {
143
+ this._zoom = Math.min(300, this._zoom + 10);
144
+ this._syncControls();
145
+ this._updateFrameSrc();
146
+ });
147
+
148
+ this._zoomInfo = document.createElement('span');
149
+ this._zoomInfo.className = 'vg-filepreview-pdf-modal__meta';
150
+ this._zoomInfo.setAttribute('data-role', 'zoom');
151
+
152
+ this._download = document.createElement('button');
153
+ this._download.type = 'button';
154
+ this._download.className = 'vg-filepreview-pdf-modal__btn primary';
155
+ this._download.setAttribute('data-role', 'download');
156
+ this._download.addEventListener('click', () => this._downloadFile());
157
+
158
+ toolbar.appendChild(this._pagePrev);
159
+ toolbar.appendChild(this._pageInfo);
160
+ toolbar.appendChild(this._pageNext);
161
+ toolbar.appendChild(this._zoomOut);
162
+ toolbar.appendChild(this._zoomInfo);
163
+ toolbar.appendChild(this._zoomIn);
164
+ toolbar.appendChild(this._download);
165
+
166
+ this._frame = document.createElement('iframe');
167
+ this._frame.className = 'vg-filepreview-pdf-modal__frame';
168
+ this._frame.setAttribute('title', 'PDF preview');
169
+
170
+ header.appendChild(this._title);
171
+ //header.appendChild(toolbar);
172
+ body.appendChild(this._frame);
173
+
174
+ this._bindLifecycle(element);
175
+ });
176
+ }
177
+
178
+ _bindElements(root) {
179
+ this._title = root.querySelector('.vg-filepreview-pdf-modal__title');
180
+ this._frame = root.querySelector('.vg-filepreview-pdf-modal__frame');
181
+ this._pagePrev = root.querySelector('.vg-filepreview-pdf-modal__btn[data-role="page-prev"]');
182
+ this._pageNext = root.querySelector('.vg-filepreview-pdf-modal__btn[data-role="page-next"]');
183
+ this._zoomOut = root.querySelector('.vg-filepreview-pdf-modal__btn[data-role="zoom-out"]');
184
+ this._zoomIn = root.querySelector('.vg-filepreview-pdf-modal__btn[data-role="zoom-in"]');
185
+ this._download = root.querySelector('.vg-filepreview-pdf-modal__btn[data-role="download"]');
186
+ this._pageInfo = root.querySelector('.vg-filepreview-pdf-modal__meta[data-role="page"]');
187
+ this._zoomInfo = root.querySelector('.vg-filepreview-pdf-modal__meta[data-role="zoom"]');
188
+ }
189
+
190
+ _bindLifecycle(root) {
191
+ if (!root || root.hasAttribute('data-vg-filepreview-pdf-lifecycle-bind')) {
192
+ return;
193
+ }
194
+
195
+ root.setAttribute('data-vg-filepreview-pdf-lifecycle-bind', 'true');
196
+ root.addEventListener('vg.modal.hidden', () => this._destroyModal());
197
+ }
198
+
199
+ _syncControls() {
200
+ if (!this._pageInfo || !this._zoomInfo) {
201
+ return;
202
+ }
203
+
204
+ this._pagePrev.textContent = this._label('prevPage');
205
+ this._pageNext.textContent = this._label('nextPage');
206
+ this._zoomOut.textContent = this._label('zoomOut');
207
+ this._zoomIn.textContent = this._label('zoomIn');
208
+ this._download.textContent = this._label('download');
209
+ this._pageInfo.textContent = `${this._label('page')}: ${this._page}`;
210
+ this._zoomInfo.textContent = `${this._label('zoom')}: ${this._zoom}%`;
211
+ }
212
+
213
+ _updateFrameSrc() {
214
+ if (!this._frame || !this._src) {
215
+ return;
216
+ }
217
+
218
+ const hash = `#page=${this._page}&zoom=${this._zoom}`;
219
+ this._frame.src = `${this._src}${hash}`;
220
+ }
221
+
222
+ _downloadFile() {
223
+ if (!this._src) {
224
+ return;
225
+ }
226
+
227
+ const link = document.createElement('a');
228
+ link.href = this._src;
229
+ if (this._downloadName) {
230
+ link.setAttribute('download', this._downloadName);
231
+ }
232
+ link.style.display = 'none';
233
+ document.body.appendChild(link);
234
+ link.click();
235
+ document.body.removeChild(link);
236
+ }
237
+
238
+ _label(key) {
239
+ const value = this._labels?.[key];
240
+ return String(value || '').trim();
241
+ }
242
+
243
+ _destroyModal() {
244
+ if (this._modal && typeof this._modal.dispose === 'function') {
245
+ this._modal.dispose();
246
+ }
247
+ if (this._root && this._root.parentNode) {
248
+ this._root.parentNode.removeChild(this._root);
249
+ }
250
+
251
+ this._root = null;
252
+ this._modal = null;
253
+ this._title = null;
254
+ this._frame = null;
255
+ this._labels = null;
256
+ this._src = '';
257
+ }
258
+ }
259
+
260
+ export default PdfModal;