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,100 +1,173 @@
|
|
|
1
|
-
import {isElement, normalizeData} from "../functions";
|
|
1
|
+
import { isElement, normalizeData } from "../functions";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* get (элемент, имя, флаг - вырезать data-) - метод выбирает значение атрибута по его имени, если в поле имени передать 'data' -> будут выбраны только дата атрибуты, если 'all' -> метод вернет значение всех атрибутов
|
|
6
|
-
* has (элемент, имя) - есть ли атрибут у элемента
|
|
7
|
-
* set (элемент, имя, значение) - установка у элемента атрибута или его изменение
|
|
8
|
-
* remove (элемент, имя) - удаляет атрибут у элемента
|
|
9
|
-
* hide(элемент) - скрыть элемент
|
|
10
|
-
* show(элемент) - показать элемент
|
|
4
|
+
* Утилиты для работы с атрибутами и классами DOM-элементов.
|
|
11
5
|
*/
|
|
12
6
|
const Manipulator = {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Получает значение атрибута, data-атрибутов или всех атрибутов.
|
|
9
|
+
* @param {Element} element - DOM-элемент.
|
|
10
|
+
* @param {string} nameAttribute - Имя атрибута ('data', 'all' или конкретное имя).
|
|
11
|
+
* @param {boolean} isRemoveDataName - Убрать префикс 'data-' у data-атрибутов.
|
|
12
|
+
* @returns {any|Object} - Значение атрибута или объект атрибутов.
|
|
13
|
+
*/
|
|
14
|
+
get(element, nameAttribute = "data", isRemoveDataName = true) {
|
|
15
|
+
if (!isElement(element)) return {};
|
|
16
|
+
|
|
17
|
+
// Все атрибуты
|
|
18
|
+
if (nameAttribute === "all") {
|
|
19
|
+
return Array.from(element.attributes).reduce((acc, attr) => {
|
|
20
|
+
acc[attr.name] = attr.value;
|
|
21
|
+
return acc;
|
|
22
|
+
}, {});
|
|
16
23
|
}
|
|
17
24
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
if (!elmBase.includes(name)) {
|
|
31
|
-
if (isRemoveDataName) name = name.slice(5);
|
|
32
|
-
attributes[name] = normalizeData(v.value)
|
|
25
|
+
// Data-атрибуты
|
|
26
|
+
if (nameAttribute === "data") {
|
|
27
|
+
const baseKeys = new Set(['data-vg-toggle', 'data-vg-target', 'data-vg-dismiss', 'data-vg-loaded']);
|
|
28
|
+
const dataAttrs = {};
|
|
29
|
+
|
|
30
|
+
Array.from(element.attributes)
|
|
31
|
+
.filter(attr => attr.name.startsWith('data-'))
|
|
32
|
+
.forEach(attr => {
|
|
33
|
+
if (!baseKeys.has(attr.name)) {
|
|
34
|
+
const key = isRemoveDataName ? attr.name.slice(5) : attr.name;
|
|
35
|
+
dataAttrs[key] = normalizeData(attr.value);
|
|
33
36
|
}
|
|
34
37
|
});
|
|
35
|
-
}
|
|
36
38
|
|
|
37
|
-
return
|
|
38
|
-
} else if (nameAttribute === 'all') {
|
|
39
|
-
return element.getAttributeNames().reduce((acc, name) => {
|
|
40
|
-
return {...acc, [name]: element.getAttribute(name)};
|
|
41
|
-
}, {});
|
|
42
|
-
} else {
|
|
43
|
-
return element.getAttribute(nameAttribute);
|
|
39
|
+
return dataAttrs;
|
|
44
40
|
}
|
|
41
|
+
|
|
42
|
+
// Конкретный атрибут
|
|
43
|
+
return element.getAttribute(nameAttribute);
|
|
45
44
|
},
|
|
46
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Проверяет наличие атрибута у элемента.
|
|
48
|
+
* @param {Element} element - DOM-элемент.
|
|
49
|
+
* @param {string} nameAttribute - Имя атрибута.
|
|
50
|
+
* @returns {boolean}
|
|
51
|
+
*/
|
|
47
52
|
has(element, nameAttribute) {
|
|
48
|
-
return element.hasAttribute(nameAttribute);
|
|
53
|
+
return isElement(element) && element.hasAttribute(nameAttribute);
|
|
49
54
|
},
|
|
50
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Устанавливает атрибут элементу.
|
|
58
|
+
* @param {Element} element - DOM-элемент.
|
|
59
|
+
* @param {string} name - Имя атрибута.
|
|
60
|
+
* @param {string} value - Значение атрибута.
|
|
61
|
+
*/
|
|
51
62
|
set(element, name, value) {
|
|
52
63
|
if (isElement(element) && name) {
|
|
53
64
|
element.setAttribute(name, value);
|
|
54
65
|
}
|
|
55
66
|
},
|
|
56
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Удаляет атрибут у элемента.
|
|
70
|
+
* @param {Element} element - DOM-элемент.
|
|
71
|
+
* @param {string} nameAttribute - Имя атрибута.
|
|
72
|
+
*/
|
|
57
73
|
remove(element, nameAttribute) {
|
|
58
74
|
if (isElement(element) && nameAttribute) {
|
|
59
75
|
element.removeAttribute(nameAttribute);
|
|
60
76
|
}
|
|
61
77
|
},
|
|
62
78
|
|
|
63
|
-
|
|
64
|
-
|
|
79
|
+
/**
|
|
80
|
+
* Скрывает элемент.
|
|
81
|
+
* @param {Element} element - DOM-элемент.
|
|
82
|
+
*/
|
|
83
|
+
hide(element) {
|
|
84
|
+
if (isElement(element)) {
|
|
85
|
+
element.style.display = 'none';
|
|
86
|
+
}
|
|
65
87
|
},
|
|
66
88
|
|
|
67
|
-
|
|
68
|
-
|
|
89
|
+
/**
|
|
90
|
+
* Отображает элемент.
|
|
91
|
+
* @param {Element} element - DOM-элемент.
|
|
92
|
+
* @param {string} state - display-значение (по умолчанию 'block').
|
|
93
|
+
*/
|
|
94
|
+
show(element, state = 'block') {
|
|
95
|
+
if (isElement(element)) {
|
|
96
|
+
element.style.display = state;
|
|
97
|
+
}
|
|
69
98
|
},
|
|
70
|
-
}
|
|
99
|
+
};
|
|
71
100
|
|
|
72
|
-
|
|
101
|
+
/**
|
|
102
|
+
* Утилиты для работы с classList элемента.
|
|
103
|
+
*/
|
|
104
|
+
const Classes = {
|
|
105
|
+
/**
|
|
106
|
+
* Удаляет класс(ы) у элемента.
|
|
107
|
+
* @param {Element} element - DOM-элемент.
|
|
108
|
+
* @param {string|string[]} className - Класс или массив классов.
|
|
109
|
+
*/
|
|
73
110
|
remove(element, className) {
|
|
74
|
-
if (
|
|
75
|
-
if (typeof className === 'string') {
|
|
76
|
-
className = className.split(' ');
|
|
77
|
-
}
|
|
111
|
+
if (!isElement(element) || !className) return;
|
|
78
112
|
|
|
79
|
-
|
|
80
|
-
|
|
113
|
+
const classes = Array.isArray(className) ? className : className.split(' ').filter(Boolean);
|
|
114
|
+
element.classList.remove(...classes);
|
|
81
115
|
},
|
|
82
116
|
|
|
117
|
+
/**
|
|
118
|
+
* Добавляет класс(ы) к элементу.
|
|
119
|
+
* @param {Element} element - DOM-элемент.
|
|
120
|
+
* @param {string|string[]} className - Класс или массив классов.
|
|
121
|
+
* @param {boolean} isString - Если true — возвращает строку вместо применения.
|
|
122
|
+
* @returns {string|undefined} - Строка с классами (если isString=true).
|
|
123
|
+
*/
|
|
83
124
|
add(element, className, isString = false) {
|
|
84
|
-
if (className)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
125
|
+
if (!className) return;
|
|
126
|
+
|
|
127
|
+
const classes = Array.isArray(className) ? className : className.split(' ').filter(Boolean);
|
|
128
|
+
|
|
129
|
+
if (isString) {
|
|
130
|
+
return classes.join(' ');
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (isElement(element)) {
|
|
134
|
+
element.classList.add(...classes);
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Переключает класс у элемента.
|
|
140
|
+
* @param {Element} element - DOM-элемент.
|
|
141
|
+
* @param {string} className - Имя класса.
|
|
142
|
+
* @param {boolean} condition - Условие переключения.
|
|
143
|
+
*/
|
|
144
|
+
toggle(element, className, condition = true) {
|
|
145
|
+
if (isElement(element) && className) {
|
|
146
|
+
element.classList.toggle(className, !!condition);
|
|
96
147
|
}
|
|
97
|
-
}
|
|
98
|
-
|
|
148
|
+
},
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Заменяет один класс на другой.
|
|
152
|
+
* @param {Element} element - DOM-элемент.
|
|
153
|
+
* @param {string} oldClass - Старый класс.
|
|
154
|
+
* @param {string} newClass - Новый класс.
|
|
155
|
+
*/
|
|
156
|
+
replace(element, oldClass, newClass) {
|
|
157
|
+
if (isElement(element) && oldClass && newClass) {
|
|
158
|
+
element.classList.replace(oldClass, newClass);
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Проверяет наличие класса у элемента.
|
|
164
|
+
* @param {Element} element - DOM-элемент.
|
|
165
|
+
* @param {string} className - Имя класса.
|
|
166
|
+
* @returns {boolean} - Возвращает true, если элемент содержит указанный класс.
|
|
167
|
+
*/
|
|
168
|
+
has(element, className) {
|
|
169
|
+
return isElement(element) && element.classList.contains(className);
|
|
170
|
+
},
|
|
171
|
+
};
|
|
99
172
|
|
|
100
|
-
export {Manipulator, Classes}
|
|
173
|
+
export { Manipulator, Classes };
|
|
@@ -1,105 +1,180 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* @returns {*}
|
|
2
|
+
* Утилиты для работы с DOM-селекторами
|
|
3
|
+
* Поддержка data-атрибутов, href и CSS-экранирование
|
|
5
4
|
*/
|
|
6
|
-
import {isElement} from "../functions";
|
|
7
5
|
|
|
8
|
-
|
|
9
|
-
if (selector && window.CSS && window.CSS.escape) {
|
|
10
|
-
selector = selector.replace(/#([^\s"#']+)/g, (match, id) => `#${CSS.escape(id)}`)
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
return selector
|
|
14
|
-
}
|
|
6
|
+
import { isElement } from '../functions';
|
|
15
7
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Экранирует ID в CSS-селекторах, если поддерживается браузером
|
|
10
|
+
* @param {string} id
|
|
11
|
+
* @returns {string}
|
|
12
|
+
*/
|
|
13
|
+
const escapeId = (id) => {
|
|
14
|
+
if (id && window.CSS?.escape) {
|
|
15
|
+
return CSS.escape(id);
|
|
16
|
+
}
|
|
17
|
+
// Резервное экранирование для старых браузеров
|
|
18
|
+
return id.replace(/([:.#[]])/g, '\\$1');
|
|
19
|
+
};
|
|
24
20
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Извлекает селектор из элемента через data-атрибут или href
|
|
23
|
+
* @param {Element} element
|
|
24
|
+
* @returns {string|null}
|
|
25
|
+
*/
|
|
26
|
+
const getSelector = (element) => {
|
|
27
|
+
const dataTarget = element.getAttribute('data-vg-target');
|
|
28
|
+
if (dataTarget && dataTarget !== '#') {
|
|
29
|
+
return dataTarget.trim();
|
|
30
|
+
}
|
|
28
31
|
|
|
29
|
-
|
|
32
|
+
const href = element.getAttribute('href');
|
|
33
|
+
if (!href || (!href.includes('#') && !href.startsWith('.'))) {
|
|
34
|
+
return null;
|
|
30
35
|
}
|
|
31
36
|
|
|
32
|
-
|
|
33
|
-
}
|
|
37
|
+
const selector = href.includes('#') && !href.startsWith('#')
|
|
38
|
+
? `#${href.split('#')[1]}`
|
|
39
|
+
: href;
|
|
34
40
|
|
|
41
|
+
return selector !== '#' ? selector.trim() : null;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Основной объект для работы с селекторами
|
|
46
|
+
*/
|
|
35
47
|
const Selectors = {
|
|
36
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Находит один элемент по селектору или возвращает сам элемент
|
|
50
|
+
* @param {string|Element} selector
|
|
51
|
+
* @param {Element} [container=document.documentElement]
|
|
52
|
+
* @returns {Element|null}
|
|
53
|
+
*/
|
|
54
|
+
find(selector, container = document.documentElement) {
|
|
37
55
|
if (isElement(selector)) {
|
|
38
56
|
return selector;
|
|
39
|
-
}
|
|
40
|
-
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
return container.querySelector(selector);
|
|
60
|
+
} catch (e) {
|
|
61
|
+
console.warn('Invalid selector:', selector, e);
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Находит элемент по ID с экранированием
|
|
68
|
+
* @param {string} id
|
|
69
|
+
* @param {Element} [container=document]
|
|
70
|
+
* @returns {Element|null}
|
|
71
|
+
*/
|
|
72
|
+
findID(id, container = document) {
|
|
73
|
+
try {
|
|
74
|
+
const escaped = escapeId(id);
|
|
75
|
+
return container.getElementById(escaped) || container.querySelector(`#${escaped}`);
|
|
76
|
+
} catch (e) {
|
|
77
|
+
console.warn('Invalid ID in findID:', id, e);
|
|
78
|
+
return null;
|
|
41
79
|
}
|
|
42
80
|
},
|
|
43
81
|
|
|
82
|
+
/**
|
|
83
|
+
* Находит все элементы по селектору
|
|
84
|
+
* @param {string} selector
|
|
85
|
+
* @param {Element} [container=document.documentElement]
|
|
86
|
+
* @returns {Element[]}
|
|
87
|
+
*/
|
|
44
88
|
findAll(selector, container = document.documentElement) {
|
|
45
|
-
|
|
89
|
+
try {
|
|
90
|
+
return Array.from(container.querySelectorAll(selector));
|
|
91
|
+
} catch (e) {
|
|
92
|
+
console.warn('Invalid selector in findAll:', selector, e);
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
46
95
|
},
|
|
47
96
|
|
|
97
|
+
/**
|
|
98
|
+
* Получает валидный селектор из элемента
|
|
99
|
+
* @param {Element} element
|
|
100
|
+
* @returns {string|null}
|
|
101
|
+
*/
|
|
48
102
|
getSelectorFromElement(element) {
|
|
49
103
|
const selector = getSelector(element);
|
|
50
|
-
|
|
51
|
-
return null
|
|
104
|
+
return selector && this.find(selector) ? selector : null;
|
|
52
105
|
},
|
|
53
106
|
|
|
107
|
+
/**
|
|
108
|
+
* Получает целевой элемент по селектору из элемента
|
|
109
|
+
* @param {Element} element
|
|
110
|
+
* @returns {Element|null}
|
|
111
|
+
*/
|
|
54
112
|
getElementFromSelector(element) {
|
|
55
113
|
const selector = getSelector(element);
|
|
56
|
-
return selector ?
|
|
114
|
+
return selector ? this.find(selector) : null;
|
|
57
115
|
},
|
|
58
116
|
|
|
117
|
+
/**
|
|
118
|
+
* Получает все целевые элементы (для множественного выбора)
|
|
119
|
+
* @param {Element} element
|
|
120
|
+
* @returns {Element[]}
|
|
121
|
+
*/
|
|
59
122
|
getMultipleElementsFromSelector(element) {
|
|
60
123
|
const selector = getSelector(element);
|
|
61
|
-
return selector ?
|
|
124
|
+
return selector ? this.findAll(selector) : [];
|
|
62
125
|
},
|
|
63
126
|
|
|
127
|
+
/**
|
|
128
|
+
* Находит всех родителей, соответствующих селектору
|
|
129
|
+
* @param {Element} element
|
|
130
|
+
* @param {string} selector
|
|
131
|
+
* @returns {Element[]}
|
|
132
|
+
*/
|
|
64
133
|
parents(element, selector) {
|
|
65
|
-
const parents = []
|
|
66
|
-
let
|
|
134
|
+
const parents = [];
|
|
135
|
+
let parent = element.parentElement?.closest(selector);
|
|
67
136
|
|
|
68
|
-
while (
|
|
69
|
-
parents.push(
|
|
70
|
-
|
|
137
|
+
while (parent) {
|
|
138
|
+
parents.push(parent);
|
|
139
|
+
parent = parent.parentElement?.closest(selector);
|
|
71
140
|
}
|
|
72
141
|
|
|
73
|
-
return parents
|
|
142
|
+
return parents;
|
|
74
143
|
},
|
|
75
144
|
|
|
145
|
+
/**
|
|
146
|
+
* Находит следующий соседний элемент, соответствующий селектору
|
|
147
|
+
* @param {Element} element
|
|
148
|
+
* @param {string} selector
|
|
149
|
+
* @returns {Element[]}
|
|
150
|
+
*/
|
|
76
151
|
next(element, selector) {
|
|
77
|
-
let
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
return [next]
|
|
152
|
+
let sibling = element.nextElementSibling;
|
|
153
|
+
while (sibling) {
|
|
154
|
+
if (sibling.matches(selector)) {
|
|
155
|
+
return [sibling];
|
|
82
156
|
}
|
|
83
|
-
|
|
84
|
-
next = next.nextElementSibling;
|
|
157
|
+
sibling = sibling.nextElementSibling;
|
|
85
158
|
}
|
|
86
|
-
|
|
87
|
-
return []
|
|
159
|
+
return [];
|
|
88
160
|
},
|
|
89
161
|
|
|
162
|
+
/**
|
|
163
|
+
* Находит предыдущий соседний элемент, соответствующий селектору
|
|
164
|
+
* @param {Element} element
|
|
165
|
+
* @param {string} selector
|
|
166
|
+
* @returns {Element[]}
|
|
167
|
+
*/
|
|
90
168
|
prev(element, selector) {
|
|
91
|
-
let
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
return [previous]
|
|
169
|
+
let sibling = element.previousElementSibling;
|
|
170
|
+
while (sibling) {
|
|
171
|
+
if (sibling.matches(selector)) {
|
|
172
|
+
return [sibling];
|
|
96
173
|
}
|
|
97
|
-
|
|
98
|
-
previous = previous.previousElementSibling
|
|
174
|
+
sibling = sibling.previousElementSibling;
|
|
99
175
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
176
|
+
return [];
|
|
177
|
+
},
|
|
178
|
+
};
|
|
104
179
|
|
|
105
180
|
export default Selectors;
|