vgapp 0.7.9 → 0.8.0
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.
- package/CHANGELOG.md +4 -0
- package/app/langs/en/buttons.json +10 -0
- package/app/langs/en/messages.json +32 -0
- package/app/langs/en/titles.json +6 -0
- package/app/langs/ru/buttons.json +10 -0
- package/app/langs/ru/messages.json +32 -0
- package/app/langs/ru/titles.json +6 -0
- package/app/modules/base-module.js +12 -1
- package/app/modules/module-fn.js +20 -9
- package/app/modules/vgalert/js/vgalert.js +12 -6
- package/app/modules/vgalert/readme.md +1 -1
- package/app/modules/vgcollapse/readme.md +1 -1
- package/app/modules/vgdropdown/js/vgdropdown.js +140 -38
- package/app/modules/vgdropdown/readme.md +225 -0
- package/app/modules/vgfiles/js/base.js +499 -0
- package/app/modules/vgfiles/js/droppable.js +159 -0
- package/app/modules/vgfiles/js/loader.js +389 -0
- package/app/modules/vgfiles/js/render.js +83 -0
- package/app/modules/vgfiles/js/sortable.js +155 -0
- package/app/modules/vgfiles/js/vgfiles.js +796 -280
- package/app/modules/vgfiles/readme.md +193 -0
- package/app/modules/vgfiles/scss/_animations.scss +18 -0
- package/app/modules/vgfiles/scss/_mixins.scss +73 -0
- package/app/modules/vgfiles/scss/_variables.scss +103 -26
- package/app/modules/vgfiles/scss/vgfiles.scss +573 -60
- package/app/modules/vgformsender/js/vgformsender.js +5 -1
- package/app/modules/vgformsender/readme.md +1 -1
- package/app/modules/vglawcookie/js/vglawcookie.js +96 -62
- package/app/modules/vglawcookie/readme.md +102 -0
- package/app/modules/vgsidebar/js/vgsidebar.js +6 -4
- package/app/utils/js/components/ajax.js +172 -122
- package/app/utils/js/components/animation.js +124 -39
- package/app/utils/js/components/backdrop.js +54 -31
- package/app/utils/js/components/lang.js +69 -88
- package/app/utils/js/components/params.js +34 -31
- package/app/utils/js/components/scrollbar.js +118 -67
- package/app/utils/js/components/templater.js +14 -4
- package/app/utils/js/dom/cookie.js +107 -64
- package/app/utils/js/dom/data.js +68 -20
- package/app/utils/js/dom/event.js +272 -239
- package/app/utils/js/dom/manipulator.js +135 -62
- package/app/utils/js/dom/selectors.js +134 -59
- package/app/utils/js/functions.js +183 -349
- package/build/vgapp.css +1 -1
- package/build/vgapp.css.map +1 -1
- package/package.json +1 -1
- package/app/utils/js/components/overflow.js +0 -28
|
@@ -1,127 +1,170 @@
|
|
|
1
1
|
/*! js-cookie v3.0.1 | MIT */
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
'use strict';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Объединяет несколько объектов в один (аналог Object.assign)
|
|
7
|
+
* @param {Object} target - целевой объект
|
|
8
|
+
* @param {...Object} sources - источники
|
|
9
|
+
* @returns {Object}
|
|
10
|
+
*/
|
|
11
|
+
function assign(target) {
|
|
12
|
+
const sources = Array.prototype.slice.call(arguments, 1);
|
|
13
|
+
sources.forEach(source => {
|
|
14
|
+
if (!source) return;
|
|
15
|
+
Object.keys(source).forEach(key => {
|
|
7
16
|
target[key] = source[key];
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
return target
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
return target;
|
|
11
20
|
}
|
|
12
21
|
|
|
13
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Конвертер для чтения и записи значений cookie
|
|
24
|
+
*/
|
|
25
|
+
const defaultConverter = {
|
|
26
|
+
/**
|
|
27
|
+
* Читает значение cookie, убирая кавычки и декодируя
|
|
28
|
+
* @param {string} value
|
|
29
|
+
* @param {string} key
|
|
30
|
+
* @returns {string}
|
|
31
|
+
*/
|
|
14
32
|
read: function (value) {
|
|
15
33
|
if (value[0] === '"') {
|
|
16
34
|
value = value.slice(1, -1);
|
|
17
35
|
}
|
|
18
|
-
return value.replace(/(%[\dA-F]{2})+/gi, decodeURIComponent)
|
|
36
|
+
return value.replace(/(%[\dA-F]{2})+/gi, decodeURIComponent);
|
|
19
37
|
},
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Записывает значение cookie, кодируя его
|
|
41
|
+
* @param {string} value
|
|
42
|
+
* @param {string} key
|
|
43
|
+
* @returns {string}
|
|
44
|
+
*/
|
|
20
45
|
write: function (value) {
|
|
21
46
|
return encodeURIComponent(value).replace(
|
|
22
47
|
/%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,
|
|
23
48
|
decodeURIComponent
|
|
24
|
-
)
|
|
49
|
+
);
|
|
25
50
|
}
|
|
26
51
|
};
|
|
27
52
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
53
|
+
/**
|
|
54
|
+
* Инициализация функционала работы с cookie
|
|
55
|
+
* @param {Object} converter - объект с методами read/write
|
|
56
|
+
* @param {Object} defaultAttributes - атрибуты по умолчанию (например, path, expires)
|
|
57
|
+
* @returns {Object} - API: set, get, remove, withAttributes, withConverter
|
|
58
|
+
*/
|
|
59
|
+
function init(converter, defaultAttributes) {
|
|
60
|
+
/**
|
|
61
|
+
* Устанавливает cookie
|
|
62
|
+
*/
|
|
63
|
+
function set(key, value, attributes) {
|
|
64
|
+
if (typeof document === 'undefined') return;
|
|
65
|
+
|
|
66
|
+
// Объединяем атрибуты: по умолчанию → экземпляр → вызов
|
|
34
67
|
attributes = assign({}, defaultAttributes, attributes);
|
|
35
68
|
|
|
69
|
+
// Обработка expires: число → дата
|
|
36
70
|
if (typeof attributes.expires === 'number') {
|
|
37
|
-
|
|
71
|
+
const daysInMs = 864e5; // 24 * 60 * 60 * 1000
|
|
72
|
+
attributes.expires = new Date(Date.now() + attributes.expires * daysInMs);
|
|
38
73
|
}
|
|
74
|
+
|
|
75
|
+
// Преобразуем дату в строку, если есть
|
|
39
76
|
if (attributes.expires) {
|
|
40
77
|
attributes.expires = attributes.expires.toUTCString();
|
|
41
78
|
}
|
|
42
79
|
|
|
80
|
+
// Кодируем ключ
|
|
43
81
|
key = encodeURIComponent(key)
|
|
44
82
|
.replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent)
|
|
45
83
|
.replace(/[()]/g, escape);
|
|
46
84
|
|
|
85
|
+
// Формируем строку атрибутов
|
|
47
86
|
let stringifiedAttributes = '';
|
|
48
|
-
|
|
49
|
-
if (!attributes[attributeName])
|
|
50
|
-
continue
|
|
51
|
-
}
|
|
87
|
+
Object.keys(attributes).forEach(attributeName => {
|
|
88
|
+
if (!attributes[attributeName]) return;
|
|
52
89
|
|
|
53
90
|
stringifiedAttributes += '; ' + attributeName;
|
|
54
91
|
|
|
55
|
-
|
|
56
|
-
|
|
92
|
+
// Булевые атрибуты (например, Secure) не требуют значения
|
|
93
|
+
if (attributes[attributeName] !== true) {
|
|
94
|
+
// RFC 6265: обрезаем значение до первого `;`
|
|
95
|
+
const sanitizedValue = String(attributes[attributeName]).split(';')[0];
|
|
96
|
+
stringifiedAttributes += '=' + sanitizedValue;
|
|
57
97
|
}
|
|
98
|
+
});
|
|
58
99
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
// 3. If the remaining unparsed-attributes contains a %x3B (";")
|
|
62
|
-
// character:
|
|
63
|
-
// Consume the characters of the unparsed-attributes up to,
|
|
64
|
-
// not including, the first %x3B (";") character.
|
|
65
|
-
// ...
|
|
66
|
-
stringifiedAttributes += '=' + attributes[attributeName].split(';')[0];
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return (document.cookie =
|
|
70
|
-
key + '=' + converter.write(value, key) + stringifiedAttributes)
|
|
100
|
+
// Устанавливаем cookie
|
|
101
|
+
return (document.cookie = key + '=' + converter.write(value, key) + stringifiedAttributes);
|
|
71
102
|
}
|
|
72
103
|
|
|
73
|
-
|
|
104
|
+
/**
|
|
105
|
+
* Получает значение cookie по ключу
|
|
106
|
+
*/
|
|
107
|
+
function get(key) {
|
|
74
108
|
if (typeof document === 'undefined' || (arguments.length && !key)) {
|
|
75
|
-
return
|
|
109
|
+
return;
|
|
76
110
|
}
|
|
77
111
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
let jar = {};
|
|
112
|
+
const cookies = document.cookie ? document.cookie.split('; ') : [];
|
|
113
|
+
const jar = {};
|
|
114
|
+
|
|
82
115
|
for (let i = 0; i < cookies.length; i++) {
|
|
83
|
-
|
|
84
|
-
|
|
116
|
+
const parts = cookies[i].split('=');
|
|
117
|
+
const value = parts.slice(1).join('=');
|
|
118
|
+
const encodedKey = parts[0];
|
|
85
119
|
|
|
86
120
|
try {
|
|
87
|
-
|
|
121
|
+
const foundKey = decodeURIComponent(encodedKey);
|
|
88
122
|
jar[foundKey] = converter.read(value, foundKey);
|
|
89
123
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
124
|
+
// Прерываем, если нашли нужный ключ
|
|
125
|
+
if (key === foundKey) break;
|
|
126
|
+
} catch (e) {
|
|
127
|
+
// Игнорируем поврежденные cookie
|
|
128
|
+
}
|
|
94
129
|
}
|
|
95
130
|
|
|
96
|
-
return key ? jar[key] : jar
|
|
131
|
+
return key ? jar[key] : jar;
|
|
97
132
|
}
|
|
98
133
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
134
|
+
// Возвращаем API
|
|
135
|
+
return Object.create(
|
|
136
|
+
{
|
|
137
|
+
set,
|
|
138
|
+
get,
|
|
139
|
+
/**
|
|
140
|
+
* Удаляет cookie, устанавливая срок действия в прошлое
|
|
141
|
+
*/
|
|
102
142
|
remove: function (key, attributes) {
|
|
103
|
-
set(
|
|
104
|
-
key,
|
|
105
|
-
'',
|
|
106
|
-
assign({}, attributes, {
|
|
107
|
-
expires: -1
|
|
108
|
-
})
|
|
109
|
-
);
|
|
143
|
+
set(key, '', assign({}, attributes, { expires: -1 }));
|
|
110
144
|
},
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Создаёт новый экземпляр с новыми атрибутами по умолчанию
|
|
148
|
+
*/
|
|
111
149
|
withAttributes: function (attributes) {
|
|
112
|
-
return init(this.converter, assign({}, this.attributes, attributes))
|
|
150
|
+
return init(this.converter, assign({}, this.attributes, attributes));
|
|
113
151
|
},
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Создаёт новый экземпляр с новым конвертером
|
|
155
|
+
*/
|
|
114
156
|
withConverter: function (converter) {
|
|
115
|
-
return init(assign({}, this.converter, converter), this.attributes)
|
|
157
|
+
return init(assign({}, this.converter, converter), this.attributes);
|
|
116
158
|
}
|
|
117
159
|
},
|
|
118
160
|
{
|
|
119
161
|
attributes: { value: Object.freeze(defaultAttributes) },
|
|
120
162
|
converter: { value: Object.freeze(converter) }
|
|
121
163
|
}
|
|
122
|
-
)
|
|
164
|
+
);
|
|
123
165
|
}
|
|
124
166
|
|
|
125
|
-
|
|
167
|
+
// Экспорт по умолчанию: экземпляр с атрибутом path: '/'
|
|
168
|
+
const Cookies = init(defaultConverter, { path: '/' });
|
|
126
169
|
|
|
127
|
-
export default
|
|
170
|
+
export default Cookies;
|
package/app/utils/js/dom/data.js
CHANGED
|
@@ -3,49 +3,97 @@
|
|
|
3
3
|
* Bootstrap data.js
|
|
4
4
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
5
5
|
* --------------------------------------------------------------------------
|
|
6
|
-
*
|
|
6
|
+
* Управление данными-экземплярами, привязанными к DOM-элементам.
|
|
7
|
+
* Использует Map для эффективного хранения и контроля уникальности.
|
|
7
8
|
*/
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
|
-
*
|
|
11
|
+
* Внутренняя карта для хранения данных по элементам.
|
|
12
|
+
* Структура: Element → Map<Key, Instance>
|
|
11
13
|
*/
|
|
14
|
+
const elementMap = new Map();
|
|
12
15
|
|
|
13
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Утилита для безопасного получения вложенной карты экземпляров.
|
|
18
|
+
* @param {Element} element
|
|
19
|
+
* @returns {Map<string, any>|null}
|
|
20
|
+
*/
|
|
21
|
+
function getInstanceMap(element) {
|
|
22
|
+
if (!elementMap.has(element)) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
return elementMap.get(element);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Утилита для создания новой вложенной карты для элемента.
|
|
30
|
+
* @param {Element} element
|
|
31
|
+
* @returns {Map<string, any>}
|
|
32
|
+
*/
|
|
33
|
+
function createInstanceMap(element) {
|
|
34
|
+
const map = new Map();
|
|
35
|
+
elementMap.set(element, map);
|
|
36
|
+
return map;
|
|
37
|
+
}
|
|
14
38
|
|
|
15
39
|
export default {
|
|
40
|
+
/**
|
|
41
|
+
* Устанавливает экземпляр для элемента по ключу.
|
|
42
|
+
* Запрещает несколько экземпляров на один элемент.
|
|
43
|
+
*
|
|
44
|
+
* @param {Element} element - DOM-элемент
|
|
45
|
+
* @param {string} key - уникальный ключ (например, имя компонента)
|
|
46
|
+
* @param {any} instance - экземпляр класса или объект
|
|
47
|
+
*/
|
|
16
48
|
set(element, key, instance) {
|
|
17
|
-
if (!
|
|
18
|
-
|
|
49
|
+
if (!getInstanceMap(element)) {
|
|
50
|
+
createInstanceMap(element);
|
|
19
51
|
}
|
|
20
52
|
|
|
21
|
-
const instanceMap =
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
53
|
+
const instanceMap = getInstanceMap(element);
|
|
54
|
+
|
|
55
|
+
// Проверяем, есть ли уже экземпляр (кроме случая, если это первая запись)
|
|
56
|
+
if (instanceMap.size > 0 && !instanceMap.has(key)) {
|
|
57
|
+
const existingKey = Array.from(instanceMap.keys())[0];
|
|
58
|
+
console.error(
|
|
59
|
+
`VGApp не допускает более одного экземпляра для каждого элемента. Связанный экземпляр: ${existingKey}.`
|
|
60
|
+
);
|
|
61
|
+
return;
|
|
25
62
|
}
|
|
26
63
|
|
|
27
64
|
instanceMap.set(key, instance);
|
|
28
65
|
},
|
|
29
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Получает экземпляр по элементу и ключу.
|
|
69
|
+
*
|
|
70
|
+
* @param {Element} element - DOM-элемент
|
|
71
|
+
* @param {string} key - ключ
|
|
72
|
+
* @returns {any|null} - экземпляр или null
|
|
73
|
+
*/
|
|
30
74
|
get(element, key) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
75
|
+
const instanceMap = getInstanceMap(element);
|
|
76
|
+
if (!instanceMap) return null;
|
|
34
77
|
|
|
35
|
-
return null
|
|
78
|
+
return instanceMap.get(key) || null;
|
|
36
79
|
},
|
|
37
80
|
|
|
81
|
+
/**
|
|
82
|
+
* Удаляет экземпляр по ключу.
|
|
83
|
+
* Если у элемента не остаётся экземпляров — удаляет и сам элемент из хранилища.
|
|
84
|
+
*
|
|
85
|
+
* @param {Element} element - DOM-элемент
|
|
86
|
+
* @param {string} key - ключ
|
|
87
|
+
*/
|
|
38
88
|
remove(element, key) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const instanceMap = elementMap.get(element)
|
|
89
|
+
const instanceMap = getInstanceMap(element);
|
|
90
|
+
if (!instanceMap) return;
|
|
44
91
|
|
|
45
92
|
instanceMap.delete(key);
|
|
46
93
|
|
|
94
|
+
// Очищаем корневую запись, если больше нет экземпляров
|
|
47
95
|
if (instanceMap.size === 0) {
|
|
48
|
-
elementMap.delete(element)
|
|
96
|
+
elementMap.delete(element);
|
|
49
97
|
}
|
|
50
98
|
}
|
|
51
|
-
}
|
|
99
|
+
};
|