griffincss-ui 0.26.2 → 0.27.1
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/dist/griffincss-ui-scoped.css +1 -1
- package/dist/griffincss-ui.css +1 -1
- package/dist/griffincss-ui.js +1 -1
- package/dist/griffincss-ui.js.map +1 -1
- package/dist/griffinjs-combobox.js +1 -1
- package/dist/griffinjs-combobox.js.map +1 -1
- package/dist/griffinjs-core.js +1 -1
- package/dist/griffinjs-core.js.map +1 -1
- package/dist/griffinjs-counter.js +1 -1
- package/dist/griffinjs-counter.js.map +1 -1
- package/dist/griffinjs-datetime.js +1 -1
- package/dist/griffinjs-datetime.js.map +1 -1
- package/dist/griffinjs-dialog.js +1 -1
- package/dist/griffinjs-dialog.js.map +1 -1
- package/dist/griffinjs-dropdown.js +1 -1
- package/dist/griffinjs-dropdown.js.map +1 -1
- package/dist/griffinjs-fields.js +1 -1
- package/dist/griffinjs-fields.js.map +1 -1
- package/dist/griffinjs-file.js +1 -1
- package/dist/griffinjs-file.js.map +1 -1
- package/dist/griffinjs-lightbox.js +1 -1
- package/dist/griffinjs-lightbox.js.map +1 -1
- package/dist/griffinjs-loader.js +1 -1
- package/dist/griffinjs-loader.js.map +1 -1
- package/dist/griffinjs-mask.js +1 -1
- package/dist/griffinjs-mask.js.map +1 -1
- package/dist/griffinjs-megamenu.js +1 -1
- package/dist/griffinjs-megamenu.js.map +1 -1
- package/dist/griffinjs-otp.js +1 -1
- package/dist/griffinjs-otp.js.map +1 -1
- package/dist/griffinjs-phone.js +1 -1
- package/dist/griffinjs-phone.js.map +1 -1
- package/dist/griffinjs-range.js +1 -1
- package/dist/griffinjs-range.js.map +1 -1
- package/dist/griffinjs-rating.js +1 -1
- package/dist/griffinjs-rating.js.map +1 -1
- package/dist/griffinjs-slider.js +1 -1
- package/dist/griffinjs-slider.js.map +1 -1
- package/dist/griffinjs-sortable.js +1 -1
- package/dist/griffinjs-sortable.js.map +1 -1
- package/dist/griffinjs-tooltip.js +1 -1
- package/dist/griffinjs-tooltip.js.map +1 -1
- package/dist/griffinjs-track.js +1 -1
- package/dist/griffinjs-track.js.map +1 -1
- package/dist/griffinjs-validate.js +1 -1
- package/dist/griffinjs-validate.js.map +1 -1
- package/dist/griffinjs.css +1 -1
- package/dist/griffinjs.js +1 -1
- package/dist/griffinjs.js.map +1 -1
- package/package.json +2 -2
- package/scss/_prose.scss +116 -0
- package/scss/_steps.scss +81 -38
- package/scss/_table.scss +17 -6
- package/scss/griffincss-ui-scoped.scss +1 -0
- package/scss/griffincss-ui.scss +1 -0
- package/scss/griffinjs/_track.scss +10 -0
- package/scss/griffinjs/griffinjs.scss +1 -1
- package/src/griffincss-ui.js +5 -5
- package/src/griffinjs/core/griffinjs-core.js +10 -10
- package/src/griffinjs/core/loader.js +2 -2
- package/src/griffinjs/core/options.js +1 -1
- package/src/griffinjs/core/track.js +2 -2
- package/src/griffinjs/fields/counter.js +1 -1
- package/src/griffinjs/fields/datetime.js +2 -2
- package/src/griffinjs/fields/file.js +1 -1
- package/src/griffinjs/fields/mask.js +1 -1
- package/src/griffinjs/fields/otp.js +1 -1
- package/src/griffinjs/fields/phone.js +3 -3
- package/src/griffinjs/fields/rating.js +1 -1
- package/src/griffinjs/fields/validate.js +1 -1
- package/src/griffinjs/widgets/combobox.js +19 -6
- package/src/griffinjs/widgets/dialog.js +41 -12
- package/src/griffinjs/widgets/dropdown.js +1 -1
- package/src/griffinjs/widgets/gallery.js +1 -1
- package/src/griffinjs/widgets/lightbox.js +67 -20
- package/src/griffinjs/widgets/megamenu.js +28 -8
- package/src/griffinjs/widgets/range.js +2 -2
- package/src/griffinjs/widgets/slider.js +1 -1
- package/src/griffinjs/widgets/sortable.js +1 -1
- package/src/griffinjs/widgets/tooltip.js +1 -1
|
@@ -19,9 +19,12 @@
|
|
|
19
19
|
* * остановка медиа при закрытии: <video>/<audio> на паузу, <iframe>
|
|
20
20
|
* разгружается и возвращается при следующем открытии;
|
|
21
21
|
* * ajax-содержимое: data-gr-src грузится один раз в [data-gr-content]
|
|
22
|
-
* (или в само окно), состояния loading → open | error
|
|
22
|
+
* (или в само окно), состояния loading → open | error. Только ответ
|
|
23
|
+
* своего origin с типом text/html: чужой адрес, data: и прочие
|
|
24
|
+
* схемы — error без запроса;
|
|
23
25
|
* * hash: открытие пишет #id в историю, «Назад» закрывает окно,
|
|
24
|
-
* а страница, открытая с #id, показывает окно
|
|
26
|
+
* а страница, открытая с #id, показывает окно сразу — закрытие
|
|
27
|
+
* такого окна снимает #id из адреса на месте, а не шагом назад;
|
|
25
28
|
* * рост окна (Этап 48d) — data-gr-dialog="grow": ResizeObserver
|
|
26
29
|
* на окне, и смена высоты больше 24 px идёт анимацией от прежней
|
|
27
30
|
* к новой (element.animate по block-size — не спорит с transition
|
|
@@ -80,6 +83,28 @@
|
|
|
80
83
|
return (value || '').replace(/^#/, '');
|
|
81
84
|
}
|
|
82
85
|
|
|
86
|
+
// Фрагмент — только ответ своего origin с типом text/html: разметку
|
|
87
|
+
// из innerHTML браузер оживляет, и <img onerror> чужого ответа исполнился
|
|
88
|
+
// бы в origin страницы. Адрес — http(s) своего origin (у data: origin —
|
|
89
|
+
// строка 'null'); редирект на чужой отклоняет mode: 'same-origin'; тип
|
|
90
|
+
// ответа отсекает свой JSON или текст, отражающий запрос.
|
|
91
|
+
function fragment(src) {
|
|
92
|
+
var url = null;
|
|
93
|
+
|
|
94
|
+
try { url = new URL(src, document.baseURI); } catch (e) { /* не адрес */ }
|
|
95
|
+
|
|
96
|
+
if (!url || !/^https?:$/.test(url.protocol) || url.origin !== location.origin) {
|
|
97
|
+
return Promise.reject(new Error('foreign origin'));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return fetch(url.href, { mode: 'same-origin' }).then(function (response) {
|
|
101
|
+
if (!response.ok) throw new Error('HTTP ' + response.status);
|
|
102
|
+
if (!/^text\/html/i.test(response.headers.get('content-type'))) throw new Error('not text/html');
|
|
103
|
+
|
|
104
|
+
return response.text();
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
83
108
|
// Прокручиваемый предок внутри окна: жест в теле окна с прокруткой —
|
|
84
109
|
// законный, всё остальное двигало бы страницу.
|
|
85
110
|
function scrollable(node, root) {
|
|
@@ -135,6 +160,7 @@
|
|
|
135
160
|
var loaded = false;
|
|
136
161
|
var frames = []; // [{el, src}] — разгруженные iframe
|
|
137
162
|
var byHistory = false; // закрыто кнопкой «Назад»: back() не зовём
|
|
163
|
+
var pushed = false; // #id в адресе записало само окно
|
|
138
164
|
var record = { el: el, o: o };
|
|
139
165
|
var grow = null; // ResizeObserver — только по grow
|
|
140
166
|
var known = 0; // высота окна по последнему наблюдению
|
|
@@ -181,7 +207,7 @@
|
|
|
181
207
|
loaded = true;
|
|
182
208
|
|
|
183
209
|
if (typeof fetch !== 'function') {
|
|
184
|
-
G.warn('
|
|
210
|
+
G.warn('dialog: fetch is unavailable, ' + src + ' not loaded');
|
|
185
211
|
setAttr(el, 'data-gr-state', 'error');
|
|
186
212
|
return;
|
|
187
213
|
}
|
|
@@ -190,15 +216,11 @@
|
|
|
190
216
|
|
|
191
217
|
setAttr(el, 'data-gr-state', 'loading');
|
|
192
218
|
|
|
193
|
-
|
|
194
|
-
if (!response.ok) throw new Error('HTTP ' + response.status);
|
|
195
|
-
|
|
196
|
-
return response.text();
|
|
197
|
-
}).then(function (html) {
|
|
219
|
+
fragment(src).then(function (html) {
|
|
198
220
|
target.innerHTML = html;
|
|
199
221
|
setAttr(el, 'data-gr-state', isOpen() ? 'open' : 'ready');
|
|
200
222
|
}, function (error) {
|
|
201
|
-
G.warn('
|
|
223
|
+
G.warn('dialog: ' + src + ' not loaded: ' + (error && error.message));
|
|
202
224
|
setAttr(el, 'data-gr-state', 'error');
|
|
203
225
|
});
|
|
204
226
|
}
|
|
@@ -244,13 +266,19 @@
|
|
|
244
266
|
function pushHash() {
|
|
245
267
|
if (!o.hash || !id() || typeof history === 'undefined' || hashIs()) return;
|
|
246
268
|
|
|
247
|
-
try { history.pushState(null, '', '#' + id()); } catch (e) { /* file:// и прочее */ }
|
|
269
|
+
try { history.pushState(null, '', '#' + id()); pushed = true; } catch (e) { /* file:// и прочее */ }
|
|
248
270
|
}
|
|
249
271
|
|
|
272
|
+
// Свой #id закрытие убирает шагом назад по истории. #id, пришедший
|
|
273
|
+
// со ссылкой (страница открыта сразу с окном), так не убрать: «назад»
|
|
274
|
+
// увёл бы с сайта. Он снимается из адреса на месте, без новой записи.
|
|
250
275
|
function popHash() {
|
|
251
276
|
if (!o.hash || byHistory || typeof history === 'undefined' || !hashIs()) return;
|
|
252
277
|
|
|
253
|
-
try {
|
|
278
|
+
try {
|
|
279
|
+
if (pushed) history.back();
|
|
280
|
+
else history.replaceState(history.state, '', location.pathname + location.search);
|
|
281
|
+
} catch (e) { /* без истории */ }
|
|
254
282
|
}
|
|
255
283
|
|
|
256
284
|
// --- Открытие и закрытие ------------------------------------------------
|
|
@@ -291,6 +319,7 @@
|
|
|
291
319
|
relock();
|
|
292
320
|
stopMedia();
|
|
293
321
|
popHash();
|
|
322
|
+
pushed = false;
|
|
294
323
|
byHistory = false;
|
|
295
324
|
|
|
296
325
|
if (el.getAttribute('data-gr-state') !== 'loading') setAttr(el, 'data-gr-state', 'ready');
|
|
@@ -356,7 +385,7 @@
|
|
|
356
385
|
function open(target) {
|
|
357
386
|
var w = instanceOf(target);
|
|
358
387
|
|
|
359
|
-
if (!w) { G.warn('
|
|
388
|
+
if (!w) { G.warn('dialog not found: ' + target); return null; }
|
|
360
389
|
|
|
361
390
|
return w.open();
|
|
362
391
|
}
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
var trigger = el.firstElementChild;
|
|
105
105
|
var panel = trigger && trigger.nextElementSibling;
|
|
106
106
|
|
|
107
|
-
if (!trigger || !panel) throw new Error('
|
|
107
|
+
if (!trigger || !panel) throw new Error('the dropdown has no button and panel');
|
|
108
108
|
|
|
109
109
|
var kind = el.tagName === 'DETAILS' ? 'details' : panel.hasAttribute('popover') ? 'popover' : 'css';
|
|
110
110
|
var opened = false; // для popover и css: <details> знает сам
|
|
@@ -2,23 +2,36 @@
|
|
|
2
2
|
* GriffinJS — лайтбокс: <dialog> + дорожка.
|
|
3
3
|
*
|
|
4
4
|
* <a href="large.jpg" data-gr-lightbox="promo" data-gr-caption="Подпись"><img src="thumb.jpg" alt="…"></a>
|
|
5
|
+
* <a href="https://rutube.ru/video/…/" data-gr-src="https://rutube.ru/play/embed/…" data-gr-lightbox>…</a>
|
|
5
6
|
*
|
|
6
7
|
* Значение атрибута — группа: элементы с одним значением листаются в одном
|
|
7
8
|
* окне; пустое значение — окно на один элемент, и дорожка вырождается
|
|
8
|
-
* в один кадр без кнопок.
|
|
9
|
-
*
|
|
9
|
+
* в один кадр без кнопок. Адрес кадра — data-gr-src, без него — href:
|
|
10
|
+
* у видео это разные адреса — во фрейм встаёт только плеер, страницу ролика
|
|
11
|
+
* хостинги во фрейме не показывают, а ссылка без скрипта ведёт именно на неё.
|
|
12
|
+
* Тип — по адресу кадра (картинка, видео, iframe для плееров YouTube, Vimeo,
|
|
13
|
+
* Rutube и VK Видео — по хосту адреса) или явно: data-gr-type="iframe".
|
|
10
14
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* а
|
|
14
|
-
*
|
|
15
|
+
* Адрес кадра — http(s), относительный, data: или blob:. Любой другой кадр
|
|
16
|
+
* не открывает: javascript: во фрейме исполнился бы в origin страницы,
|
|
17
|
+
* а data-* редакторы и фильтры CMS не проверяют как ссылку. Отвергнутый
|
|
18
|
+
* кадр из группы выпадает; щелчок по нему остаётся браузеру.
|
|
19
|
+
*
|
|
20
|
+
* База без JS — ссылка на большое изображение или на страницу ролика.
|
|
21
|
+
* Окно строится при открытии и уничтожается при закрытии: так видео
|
|
22
|
+
* гарантированно останавливается, а в документе не копится по <dialog>
|
|
23
|
+
* на каждую группу. Верхний слой, ловушка фокуса, Esc, возврат фокуса —
|
|
24
|
+
* от <dialog>.
|
|
15
25
|
*/
|
|
16
26
|
(function (G) {
|
|
17
27
|
'use strict';
|
|
18
28
|
|
|
19
29
|
var ATTR = 'data-gr-lightbox';
|
|
20
30
|
var VIDEO = /\.(mp4|webm|ogv|mov)(\?|#|$)/i;
|
|
21
|
-
|
|
31
|
+
// Хост и путь разобранного адреса: хостинг — сам хост или его поддомен,
|
|
32
|
+
// а не подстрока где угодно (картинка …/rutube.ru-logo.png — не плеер).
|
|
33
|
+
var EMBED = /^([\w-]+\.)*((youtube\.com|youtu\.be|vimeo\.com|rutube\.ru|vkvideo\.ru)\/|vk\.com\/video)/i;
|
|
34
|
+
var SCHEMES = /^(https?|data|blob):$/;
|
|
22
35
|
|
|
23
36
|
var dialog = null;
|
|
24
37
|
var track = null;
|
|
@@ -26,19 +39,31 @@
|
|
|
26
39
|
var events = G.listeners();
|
|
27
40
|
var listen = events.add;
|
|
28
41
|
|
|
42
|
+
// Адрес по правилам браузера: регистр, пробелы по краям и табы внутри
|
|
43
|
+
// схемы разбор снимает. Не адрес — null.
|
|
44
|
+
function parse(src) {
|
|
45
|
+
try {
|
|
46
|
+
return new URL(src, document.baseURI);
|
|
47
|
+
} catch (e) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
29
52
|
function typeOf(node, src) {
|
|
30
53
|
var explicit = node && node.getAttribute && node.getAttribute('data-gr-type');
|
|
31
54
|
|
|
32
55
|
if (explicit) return explicit;
|
|
33
56
|
if (VIDEO.test(src)) return 'video';
|
|
34
|
-
if (EMBED.test(src)) return 'iframe';
|
|
35
57
|
|
|
36
|
-
|
|
58
|
+
var url = parse(src);
|
|
59
|
+
|
|
60
|
+
return url && EMBED.test(url.hostname + url.pathname) ? 'iframe' : 'image';
|
|
37
61
|
}
|
|
38
62
|
|
|
39
|
-
// Элемент разметки → описание кадра.
|
|
63
|
+
// Элемент разметки → описание кадра. data-gr-src старше href: у видео
|
|
64
|
+
// href — страница ролика для перехода без скрипта, а кадр — плеер.
|
|
40
65
|
function itemOf(node) {
|
|
41
|
-
var src = node.getAttribute('
|
|
66
|
+
var src = node.getAttribute('data-gr-src') || node.getAttribute('href') || '';
|
|
42
67
|
var img = node.querySelector ? node.querySelector('img') : null;
|
|
43
68
|
|
|
44
69
|
return {
|
|
@@ -91,21 +116,41 @@
|
|
|
91
116
|
// --- Открытие ----------------------------------------------------------------
|
|
92
117
|
|
|
93
118
|
function open(items, index, opts) {
|
|
119
|
+
var list = [];
|
|
120
|
+
|
|
121
|
+
index = index || 0;
|
|
122
|
+
|
|
123
|
+
// Кадр с отвергнутым адресом выпадает из группы; отвергнут
|
|
124
|
+
// открываемый — окна нет.
|
|
125
|
+
for (var k = 0; k < items.length; k++) {
|
|
126
|
+
var url = parse(items[k].src);
|
|
127
|
+
|
|
128
|
+
if (url && SCHEMES.test(url.protocol)) {
|
|
129
|
+
list.push(items[k]);
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
G.warn('lightbox: frame address refused: ' + items[k].src);
|
|
134
|
+
|
|
135
|
+
if (k === index) return null;
|
|
136
|
+
if (k < index) index--;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (!list.length) return null;
|
|
140
|
+
|
|
94
141
|
close();
|
|
95
142
|
|
|
96
143
|
opts = opts || {};
|
|
97
|
-
|
|
144
|
+
items = list;
|
|
98
145
|
|
|
99
146
|
var n = items.length;
|
|
100
147
|
|
|
101
|
-
if (n === 0) return null;
|
|
102
|
-
|
|
103
148
|
dialog = element('dialog', 'gr-modal gr-lightbox', { 'aria-label': opts.label || 'Просмотр' });
|
|
104
149
|
|
|
105
150
|
var trackEl = element('div', 'gr-track gr-lightbox-track', { tabindex: '0' });
|
|
106
151
|
|
|
107
152
|
for (var i = 0; i < n; i++) {
|
|
108
|
-
var figure = element('figure', 'gr-
|
|
153
|
+
var figure = element('figure', 'gr-lightbox-item');
|
|
109
154
|
|
|
110
155
|
figure.appendChild(media(items[i]));
|
|
111
156
|
|
|
@@ -177,8 +222,6 @@
|
|
|
177
222
|
}
|
|
178
223
|
|
|
179
224
|
function openFrom(node) {
|
|
180
|
-
trigger = node;
|
|
181
|
-
|
|
182
225
|
var group = groupOf(node);
|
|
183
226
|
var items = [];
|
|
184
227
|
var index = 0;
|
|
@@ -188,7 +231,11 @@
|
|
|
188
231
|
items.push(itemOf(group[i]));
|
|
189
232
|
}
|
|
190
233
|
|
|
191
|
-
|
|
234
|
+
var opened = open(items, index);
|
|
235
|
+
|
|
236
|
+
if (opened) trigger = node;
|
|
237
|
+
|
|
238
|
+
return opened;
|
|
192
239
|
}
|
|
193
240
|
|
|
194
241
|
// --- Закрытие ----------------------------------------------------------------
|
|
@@ -235,10 +282,10 @@
|
|
|
235
282
|
|
|
236
283
|
function onClick(event, node) {
|
|
237
284
|
// Ctrl/Cmd/средняя кнопка — читатель хочет новую вкладку, а не окно.
|
|
238
|
-
|
|
285
|
+
// Кадр не открылся — ссылка работает как без скрипта.
|
|
286
|
+
if (event.metaKey || event.ctrlKey || event.shiftKey || event.button || !openFrom(node)) return false;
|
|
239
287
|
|
|
240
288
|
if (event.preventDefault) event.preventDefault();
|
|
241
|
-
openFrom(node);
|
|
242
289
|
|
|
243
290
|
return true;
|
|
244
291
|
}
|
|
@@ -27,7 +27,9 @@
|
|
|
27
27
|
* закрывает и возвращает фокус на заголовок;
|
|
28
28
|
* * закрытие щелчком мимо полосы и уходом фокуса;
|
|
29
29
|
* * ajax-панели: data-gr-src на пункте грузится при первом открытии,
|
|
30
|
-
* состояния loading → ready | error пишутся на
|
|
30
|
+
* состояния loading → ready | error пишутся на пункт. Только ответ
|
|
31
|
+
* своего origin с типом text/html: чужой адрес, data: и прочие
|
|
32
|
+
* схемы — error без запроса;
|
|
31
33
|
* * закрытие с состоянием (Этап 48d): панель, чей уход тема анимирует,
|
|
32
34
|
* не пропадает в первом же кадре — на пункт ставится
|
|
33
35
|
* data-gr-state="closing", open снимается по transitionend/animationend
|
|
@@ -98,6 +100,28 @@
|
|
|
98
100
|
return document.activeElement === node;
|
|
99
101
|
}
|
|
100
102
|
|
|
103
|
+
// Фрагмент — только ответ своего origin с типом text/html: разметку
|
|
104
|
+
// из innerHTML браузер оживляет, и <img onerror> чужого ответа исполнился
|
|
105
|
+
// бы в origin страницы. Адрес — http(s) своего origin (у data: origin —
|
|
106
|
+
// строка 'null'); редирект на чужой отклоняет mode: 'same-origin'; тип
|
|
107
|
+
// ответа отсекает свой JSON или текст, отражающий запрос.
|
|
108
|
+
function fragment(src) {
|
|
109
|
+
var url = null;
|
|
110
|
+
|
|
111
|
+
try { url = new URL(src, document.baseURI); } catch (e) { /* не адрес */ }
|
|
112
|
+
|
|
113
|
+
if (!url || !/^https?:$/.test(url.protocol) || url.origin !== location.origin) {
|
|
114
|
+
return Promise.reject(new Error('foreign origin'));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return fetch(url.href, { mode: 'same-origin' }).then(function (response) {
|
|
118
|
+
if (!response.ok) throw new Error('HTTP ' + response.status);
|
|
119
|
+
if (!/^text\/html/i.test(response.headers.get('content-type'))) throw new Error('not text/html');
|
|
120
|
+
|
|
121
|
+
return response.text();
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
101
125
|
// Длительность --gr-transition у узла, мс: «0.2s ease» → 200, «150ms» → 150,
|
|
102
126
|
// пусто или 0s → 0. Одно чтение вычисленного стиля при закрытии.
|
|
103
127
|
function duration(node) {
|
|
@@ -282,22 +306,18 @@
|
|
|
282
306
|
item.loaded = true;
|
|
283
307
|
|
|
284
308
|
if (typeof fetch !== 'function') {
|
|
285
|
-
G.warn('
|
|
309
|
+
G.warn('megamenu: fetch is unavailable, panel ' + src + ' not loaded');
|
|
286
310
|
setAttr(item.el, 'data-gr-state', 'error');
|
|
287
311
|
return;
|
|
288
312
|
}
|
|
289
313
|
|
|
290
314
|
setAttr(item.el, 'data-gr-state', 'loading');
|
|
291
315
|
|
|
292
|
-
|
|
293
|
-
if (!response.ok) throw new Error('HTTP ' + response.status);
|
|
294
|
-
|
|
295
|
-
return response.text();
|
|
296
|
-
}).then(function (html) {
|
|
316
|
+
fragment(src).then(function (html) {
|
|
297
317
|
item.panel.innerHTML = html;
|
|
298
318
|
setAttr(item.el, 'data-gr-state', 'ready');
|
|
299
319
|
}, function (error) {
|
|
300
|
-
G.warn('
|
|
320
|
+
G.warn('megamenu: panel ' + src + ' not loaded: ' + (error && error.message));
|
|
301
321
|
setAttr(item.el, 'data-gr-state', 'error');
|
|
302
322
|
});
|
|
303
323
|
}
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
var listeners = G.listeners();
|
|
75
75
|
var fields = [];
|
|
76
76
|
|
|
77
|
-
if (!inputs.length) throw new Error('
|
|
77
|
+
if (!inputs.length) throw new Error('no <input type="range"> inside');
|
|
78
78
|
|
|
79
79
|
function doneOf(input) {
|
|
80
80
|
var min = edge(input, 'min', 0);
|
|
@@ -172,7 +172,7 @@
|
|
|
172
172
|
for (var f = 0; f < inputs.length; f++) {
|
|
173
173
|
var field = document.querySelector(selectors[f] || '#');
|
|
174
174
|
|
|
175
|
-
if (!field) throw new Error('
|
|
175
|
+
if (!field) throw new Error('field "' + selectors[f] + '" not found');
|
|
176
176
|
|
|
177
177
|
fields.push(field);
|
|
178
178
|
pull(f);
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
|
|
44
44
|
var trackEl = el.querySelector('.gr-track') || el.firstElementChild;
|
|
45
45
|
|
|
46
|
-
if (!trackEl) throw new Error('
|
|
46
|
+
if (!trackEl) throw new Error('the slider has no track');
|
|
47
47
|
|
|
48
48
|
var track = G.track(trackEl, { loop: o.loop, rewind: o.rewind, step: o.step, engine: o.engine, index: o.index || 0 });
|
|
49
49
|
var attrs = G.recorder();
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
return el.querySelector('tbody');
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
if (!bodyOf() || !heads.length) throw new Error('
|
|
92
|
+
if (!bodyOf() || !heads.length) throw new Error('needs tbody and headers with aria-sort');
|
|
93
93
|
|
|
94
94
|
var attrs = G.recorder();
|
|
95
95
|
var events = G.listeners();
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
var target = el.firstElementChild;
|
|
54
54
|
var tip = el.querySelector('[role="tooltip"]') || el.lastElementChild;
|
|
55
55
|
|
|
56
|
-
if (!target || !tip || tip === target) throw new Error('
|
|
56
|
+
if (!target || !tip || tip === target) throw new Error('the tooltip has no anchor and text');
|
|
57
57
|
|
|
58
58
|
var shown = false;
|
|
59
59
|
var timer = null;
|