vgapp 0.9.5 → 0.9.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.
@@ -53,7 +53,15 @@ class VGFilesBase extends BaseModule {
53
53
  _init() {
54
54
  if (!this._isInitialized) return;
55
55
 
56
- this._preventOriginalInputFromSubmit();
56
+ const isSingle = Number(this._params?.limits?.count) === 1;
57
+
58
+ if (isSingle) {
59
+ this._preventOriginalInputFromSubmit(true);
60
+ this._cleanupFakeInputs();
61
+ } else {
62
+ this._preventOriginalInputFromSubmit();
63
+ }
64
+
57
65
  this._addEventListener();
58
66
  }
59
67
 
@@ -63,13 +71,19 @@ class VGFilesBase extends BaseModule {
63
71
 
64
72
  const filesArray = Array.from(incomingFiles);
65
73
 
74
+ const isSingle = Number(this._params?.limits?.count) === 1;
66
75
  const shouldReplaceOnSingle =
67
76
  Boolean(this._params?.replace) &&
68
- Number(this._params?.limits?.count) === 1;
77
+ isSingle;
69
78
 
70
79
  if (shouldReplaceOnSingle) {
71
- this.clear();
72
- this.append(filesArray, true);
80
+ this._revokeUrls();
81
+ this._cleanupFakeInputs();
82
+ this._cleanupErrors();
83
+
84
+ this._files = this._filterFiles(filesArray);
85
+ if (this._params.prepend) this._files.reverse();
86
+
73
87
  this.build();
74
88
  return;
75
89
  }
@@ -96,7 +110,13 @@ class VGFilesBase extends BaseModule {
96
110
  this._renderUI(this._files);
97
111
  } else {
98
112
  this._renderUI(this._files);
99
- this._generateHiddenInputs(this._files);
113
+
114
+ const isSingle = Number(this._params?.limits?.count) === 1;
115
+ if (!isSingle) {
116
+ this._generateHiddenInputs(this._files);
117
+ } else {
118
+ this._cleanupFakeInputs();
119
+ }
100
120
  }
101
121
  }
102
122
 
@@ -428,21 +448,18 @@ class VGFilesBase extends BaseModule {
428
448
  _generateHiddenInputs(files) {
429
449
  this._cleanupFakeInputs();
430
450
  const fragment = document.createDocumentFragment();
431
- const idInput = this._element.querySelector('label').getAttribute('for') || '';
432
- const name = this._element.querySelector('#' + idInput)?.name || this._element.querySelector('#' + idInput)?.dataset.originalName || 'files[]';
451
+ const idInput = Manipulator.get(Selectors.find('label', this._element), 'for') || '';
452
+ const name = Selectors.findID(idInput, this._element)?.name || Selectors.findID(idInput, this._element)?.dataset.originalName || 'files[]';
433
453
 
434
- // если name уже "files[]" — убираем скобки, чтобы дальше корректно собрать имя
435
454
  const baseName = name.endsWith('[]') ? name.slice(0, -2) : name;
436
455
  const isSingle = Number(this._params?.limits?.count) === 1;
437
456
 
457
+ if (isSingle) return;
458
+
438
459
  files.forEach((file, index) => {
439
460
  const input = document.createElement('input');
440
461
  input.type = 'file';
441
-
442
- // count=1 => name без массива (без [] и без [0])
443
- // иначе => name как массив: baseName[index]
444
- input.name = isSingle ? baseName : `${baseName}[${index}]`;
445
-
462
+ input.name = `${baseName}[${index}]`;
446
463
  input.dataset.vgFiles = 'generated';
447
464
  Manipulator.hide(input);
448
465
 
@@ -26,7 +26,12 @@ const PROPERTY_MARGIN = 'margin-right';
26
26
  */
27
27
  class ScrollBarHelper {
28
28
  constructor() {
29
- this._element = document.body;
29
+ // Не кэшируем body: при Turbo/partial navigation DOM может меняться.
30
+ // Актуальный body берём через геттер.
31
+ }
32
+
33
+ get _element() {
34
+ return document.body;
30
35
  }
31
36
 
32
37
  /**
@@ -50,7 +55,7 @@ class ScrollBarHelper {
50
55
  * Скрывает скроллбар и корректирует макет
51
56
  */
52
57
  hide() {
53
- if (this.isOverflowing && !isMobileDevice()) {
58
+ if (this.isOverflowing() && !isMobileDevice()) {
54
59
  const width = this.getWidth();
55
60
  this._disableOverflow();
56
61
 
@@ -137,13 +142,15 @@ class ScrollBarHelper {
137
142
  * @private
138
143
  */
139
144
  _saveInitialStyle(element, property) {
145
+ // Сохраняем только один раз, чтобы "оригинал" не перетирался
146
+ // при повторных открытиях/закрытиях.
147
+ if (Manipulator.get(element, property) !== null) return;
148
+
140
149
  const value = element.style.getPropertyValue(property);
141
150
 
142
- // Важно: сохраняем даже пустую строку (если inline-стиля не было)
151
+ // Важно: сохраняем даже пустую строку (если inline-стиля не было),
143
152
  // чтобы reset() мог корректно восстановить "как было".
144
- if (value !== null) {
145
- //Manipulator.set(element, property, value);
146
- }
153
+ Manipulator.set(element, property, value);
147
154
  }
148
155
 
149
156
  /**
@@ -69,10 +69,33 @@ const Selectors = {
69
69
  * @param {Element} [container=document]
70
70
  * @returns {Element|null}
71
71
  */
72
+ /**
73
+ * Находит элемент по ID с экранированием
74
+ * @param {string} id
75
+ * @param {Document|Element} [container=document]
76
+ * @returns {Element|null}
77
+ */
72
78
  findID(id, container = document) {
73
79
  try {
80
+ if (typeof id !== 'string' || id.trim() === '') return null;
81
+
82
+ const doc = container && container.nodeType === 9
83
+ ? container
84
+ : (container?.ownerDocument || document);
85
+
86
+ const byId = doc.getElementById(id);
87
+ if (byId) {
88
+ if (container && container.nodeType !== 9) {
89
+ return container.contains(byId) ? byId : null;
90
+ }
91
+ return byId;
92
+ }
93
+
94
+ const scope = (container && container.nodeType === 9) ? container.documentElement : container;
95
+ if (!scope || typeof scope.querySelector !== 'function') return null;
96
+
74
97
  const escaped = escapeId(id);
75
- return container.getElementById(escaped) || container.querySelector(`#${escaped}`);
98
+ return scope.querySelector(`#${escaped}`);
76
99
  } catch (e) {
77
100
  console.warn('Invalid ID in findID:', id, e);
78
101
  return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vgapp",
3
- "version": "0.9.5",
3
+ "version": "0.9.6",
4
4
  "description": "",
5
5
  "author": {
6
6
  "name": "Vegas Studio",