uikit 3.25.27-dev.2d5695a → 3.25.27-dev.9e97c1f

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 (224) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/build/prefix.js +1 -1
  3. package/build/publishDev.js +1 -1
  4. package/build/scope.js +1 -1
  5. package/build/scss.js +1 -1
  6. package/build/util.js +0 -2
  7. package/dist/css/uikit-core-rtl.css +1327 -1204
  8. package/dist/css/uikit-core-rtl.min.css +1 -1
  9. package/dist/css/uikit-core.css +1327 -1204
  10. package/dist/css/uikit-core.min.css +1 -1
  11. package/dist/css/uikit-rtl.css +1339 -1223
  12. package/dist/css/uikit-rtl.min.css +1 -1
  13. package/dist/css/uikit.css +1339 -1223
  14. package/dist/css/uikit.min.css +1 -1
  15. package/dist/js/components/countdown.js +1 -1
  16. package/dist/js/components/countdown.min.js +1 -1
  17. package/dist/js/components/filter.js +1 -1
  18. package/dist/js/components/filter.min.js +1 -1
  19. package/dist/js/components/lightbox-panel.js +134 -135
  20. package/dist/js/components/lightbox-panel.min.js +1 -1
  21. package/dist/js/components/lightbox.js +135 -136
  22. package/dist/js/components/lightbox.min.js +1 -1
  23. package/dist/js/components/marquee.js +215 -0
  24. package/dist/js/components/marquee.min.js +1 -0
  25. package/dist/js/components/notification.js +8 -6
  26. package/dist/js/components/notification.min.js +1 -1
  27. package/dist/js/components/parallax.js +8 -12
  28. package/dist/js/components/parallax.min.js +1 -1
  29. package/dist/js/components/slider-parallax.js +8 -12
  30. package/dist/js/components/slider-parallax.min.js +1 -1
  31. package/dist/js/components/slider.js +51 -25
  32. package/dist/js/components/slider.min.js +1 -1
  33. package/dist/js/components/slideshow-parallax.js +8 -12
  34. package/dist/js/components/slideshow-parallax.min.js +1 -1
  35. package/dist/js/components/slideshow.js +81 -102
  36. package/dist/js/components/slideshow.min.js +1 -1
  37. package/dist/js/components/sortable.js +1 -1
  38. package/dist/js/components/sortable.min.js +1 -1
  39. package/dist/js/components/tooltip.js +15 -17
  40. package/dist/js/components/tooltip.min.js +1 -1
  41. package/dist/js/components/upload.js +1 -1
  42. package/dist/js/components/upload.min.js +1 -1
  43. package/dist/js/uikit-core.js +874 -323
  44. package/dist/js/uikit-core.min.js +1 -1
  45. package/dist/js/uikit-icons.js +1 -1
  46. package/dist/js/uikit-icons.min.js +1 -1
  47. package/dist/js/uikit.js +737 -395
  48. package/dist/js/uikit.min.js +1 -1
  49. package/package.json +1 -1
  50. package/src/js/api/component.js +2 -3
  51. package/src/js/api/observables.js +16 -4
  52. package/src/js/api/options.js +6 -3
  53. package/src/js/api/props.js +1 -3
  54. package/src/js/api/state.js +7 -8
  55. package/src/js/components/index.js +1 -0
  56. package/src/js/components/internal/lightbox-animations.js +7 -26
  57. package/src/js/components/internal/slider-preload.js +1 -0
  58. package/src/js/components/internal/slideshow-animations.js +15 -62
  59. package/src/js/components/lightbox-panel.js +121 -96
  60. package/src/js/components/lightbox.js +5 -8
  61. package/src/js/components/marquee.js +156 -0
  62. package/src/js/components/notification.js +7 -5
  63. package/src/js/core/accordion.js +62 -31
  64. package/src/js/core/alert.js +1 -1
  65. package/src/js/core/drop.js +4 -3
  66. package/src/js/core/dropnav.js +3 -3
  67. package/src/js/core/grid.js +5 -19
  68. package/src/js/core/margin.js +3 -0
  69. package/src/js/core/overflow-auto.js +5 -1
  70. package/src/js/core/sticky.js +1 -1
  71. package/src/js/core/switcher.js +12 -49
  72. package/src/js/core/video.js +236 -21
  73. package/src/js/mixin/connect.js +90 -0
  74. package/src/js/mixin/internal/slideshow-animations.js +5 -13
  75. package/src/js/mixin/internal/slideshow-transitioner.js +2 -2
  76. package/src/js/mixin/parallax.js +1 -4
  77. package/src/js/mixin/position.js +1 -1
  78. package/src/js/mixin/scroll-driven.js +57 -0
  79. package/src/js/mixin/slider-parallax.js +9 -38
  80. package/src/js/mixin/togglable.js +13 -14
  81. package/src/js/util/attr.js +7 -7
  82. package/src/js/util/dom.js +3 -4
  83. package/src/js/util/lang.js +2 -2
  84. package/src/js/util/player.js +4 -2
  85. package/src/js/util/style.js +12 -13
  86. package/src/js/util/viewport.js +22 -25
  87. package/src/less/components/_import.less +8 -3
  88. package/src/less/components/animation.less +1 -1
  89. package/src/less/components/base.less +1 -1
  90. package/src/less/components/button.less +1 -1
  91. package/src/less/components/card.less +8 -8
  92. package/src/less/components/dropcap.less +71 -0
  93. package/src/less/components/floating-shadow.less +66 -0
  94. package/src/less/components/form.less +15 -15
  95. package/src/less/components/grid.less +58 -65
  96. package/src/less/components/lightbox.less +2 -8
  97. package/src/less/components/logo.less +94 -0
  98. package/src/less/components/margin.less +155 -124
  99. package/src/less/components/marquee.less +133 -0
  100. package/src/less/components/modal.less +1 -4
  101. package/src/less/components/nav.less +1 -1
  102. package/src/less/components/navbar.less +1 -1
  103. package/src/less/components/padding.less +9 -9
  104. package/src/less/components/position.less +9 -4
  105. package/src/less/components/search.less +1 -1
  106. package/src/less/components/slideshow.less +1 -4
  107. package/src/less/components/switcher.less +5 -2
  108. package/src/less/components/table.less +4 -4
  109. package/src/less/components/text.less +10 -4
  110. package/src/less/components/utility.less +0 -163
  111. package/src/less/components/visibility.less +4 -4
  112. package/src/less/theme/_import.less +6 -2
  113. package/src/less/theme/alert.less +0 -5
  114. package/src/less/theme/dropcap.less +29 -0
  115. package/src/less/theme/floating-shadow.less +20 -0
  116. package/src/less/theme/logo.less +29 -0
  117. package/src/less/theme/marquee.less +14 -0
  118. package/src/less/theme/thumbnav.less +1 -4
  119. package/src/less/theme/utility.less +0 -32
  120. package/src/scss/components/_import.scss +8 -3
  121. package/src/scss/components/animation.scss +1 -1
  122. package/src/scss/components/base.scss +1 -1
  123. package/src/scss/components/button.scss +1 -1
  124. package/src/scss/components/card.scss +8 -8
  125. package/src/scss/components/dropcap.scss +63 -0
  126. package/src/scss/components/floating-shadow.scss +63 -0
  127. package/src/scss/components/form.scss +14 -14
  128. package/src/scss/components/grid.scss +57 -64
  129. package/src/scss/components/lightbox.scss +2 -8
  130. package/src/scss/components/logo.scss +75 -0
  131. package/src/scss/components/margin.scss +155 -124
  132. package/src/scss/components/marquee.scss +136 -0
  133. package/src/scss/components/modal.scss +1 -4
  134. package/src/scss/components/nav.scss +1 -1
  135. package/src/scss/components/navbar.scss +1 -1
  136. package/src/scss/components/padding.scss +9 -9
  137. package/src/scss/components/position.scss +9 -4
  138. package/src/scss/components/search.scss +1 -1
  139. package/src/scss/components/slideshow.scss +1 -4
  140. package/src/scss/components/switcher.scss +5 -2
  141. package/src/scss/components/table.scss +4 -4
  142. package/src/scss/components/text.scss +10 -4
  143. package/src/scss/components/utility.scss +0 -129
  144. package/src/scss/components/visibility.scss +4 -4
  145. package/src/scss/mixins-theme.scss +44 -43
  146. package/src/scss/mixins.scss +40 -31
  147. package/src/scss/variables-theme.scss +14 -14
  148. package/src/scss/variables.scss +14 -14
  149. package/tests/accordion.html +77 -10
  150. package/tests/alert.html +1 -1
  151. package/tests/align.html +5 -5
  152. package/tests/animation.html +4 -4
  153. package/tests/article.html +7 -7
  154. package/tests/background.html +2 -2
  155. package/tests/badge.html +1 -1
  156. package/tests/base.html +2 -2
  157. package/tests/button.html +1 -1
  158. package/tests/card.html +15 -15
  159. package/tests/close.html +2 -2
  160. package/tests/comment.html +9 -9
  161. package/tests/container.html +2 -2
  162. package/tests/countdown.html +21 -21
  163. package/tests/cover.html +3 -3
  164. package/tests/description-list.html +1 -1
  165. package/tests/divider.html +3 -3
  166. package/tests/dotnav.html +1 -1
  167. package/tests/drop.html +7 -7
  168. package/tests/dropbar.html +5 -5
  169. package/tests/dropcap.html +26 -0
  170. package/tests/dropdown.html +1 -1
  171. package/tests/dropnav.html +18 -18
  172. package/tests/filter.html +3 -3
  173. package/tests/floating-shadow.html +44 -0
  174. package/tests/form.html +14 -14
  175. package/tests/grid.html +41 -47
  176. package/tests/heading.html +2 -2
  177. package/tests/height-viewport.html +4 -4
  178. package/tests/height.html +5 -5
  179. package/tests/icon.html +8 -8
  180. package/tests/image.html +6 -6
  181. package/tests/index.html +13 -13
  182. package/tests/js/index.js +1 -1
  183. package/tests/leader.html +5 -5
  184. package/tests/lightbox.html +6 -6
  185. package/tests/link.html +1 -1
  186. package/tests/list.html +4 -4
  187. package/tests/logo.html +84 -0
  188. package/tests/margin.html +59 -7
  189. package/tests/marker.html +3 -3
  190. package/tests/marquee.html +617 -0
  191. package/tests/modal.html +3 -3
  192. package/tests/nav.html +5 -5
  193. package/tests/navbar.html +27 -27
  194. package/tests/notification.html +8 -2
  195. package/tests/offcanvas.html +12 -12
  196. package/tests/overlay.html +3 -3
  197. package/tests/padding.html +1 -1
  198. package/tests/pagination.html +3 -3
  199. package/tests/parallax.html +1 -1
  200. package/tests/position.html +6 -6
  201. package/tests/scrollspy.html +13 -13
  202. package/tests/search.html +5 -5
  203. package/tests/section.html +17 -17
  204. package/tests/slidenav.html +3 -3
  205. package/tests/slider.html +5 -5
  206. package/tests/slideshow.html +33 -3
  207. package/tests/sortable.html +15 -15
  208. package/tests/sticky-navbar.html +4 -4
  209. package/tests/sticky-parallax.html +3 -3
  210. package/tests/sticky.html +3 -3
  211. package/tests/svg.html +3 -2
  212. package/tests/switcher.html +7 -7
  213. package/tests/tab.html +5 -5
  214. package/tests/text.html +9 -3
  215. package/tests/tile.html +4 -4
  216. package/tests/toggle.html +1 -1
  217. package/tests/tooltip.html +3 -3
  218. package/tests/totop.html +2 -2
  219. package/tests/transition.html +1 -1
  220. package/tests/upload.html +5 -5
  221. package/tests/utility.html +16 -116
  222. package/tests/video.html +224 -24
  223. package/tests/visibility.html +4 -4
  224. package/tests/width.html +12 -12
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "uikit",
3
3
  "title": "UIkit",
4
4
  "description": "UIkit is a lightweight and modular front-end framework for developing fast and powerful web interfaces.",
5
- "version": "3.25.27-dev.2d5695a",
5
+ "version": "3.25.27-dev.9e97c1f",
6
6
  "main": "dist/js/uikit.js",
7
7
  "style": "dist/css/uikit.css",
8
8
  "sideEffects": [
@@ -48,11 +48,10 @@ export function createComponent(name, element, data, ...args) {
48
48
  const instance = getComponent(element, name);
49
49
 
50
50
  if (instance) {
51
- if (data) {
52
- instance.$destroy();
53
- } else {
51
+ if (!data) {
54
52
  return instance;
55
53
  }
54
+ instance.$destroy();
56
55
  }
57
56
 
58
57
  return new Component({ el: element, data });
@@ -36,11 +36,9 @@ export function mutation(options) {
36
36
  export function lazyload(options = {}) {
37
37
  return intersection({
38
38
  handler: function (entries, observer) {
39
- const { targets = this.$el, preload = 5 } = options;
39
+ const { targets = this.$el, preload = 5, media = false } = options;
40
40
  for (const el of toNodes(isFunction(targets) ? targets(this) : targets)) {
41
- $$('[loading="lazy"]', el)
42
- .slice(0, preload - 1)
43
- .forEach((el) => removeAttr(el, 'loading'));
41
+ (media ? preloadMedia : loadLazyElements)(el, preload);
44
42
  }
45
43
 
46
44
  for (const { isIntersecting, target } of entries) {
@@ -51,6 +49,20 @@ export function lazyload(options = {}) {
51
49
  });
52
50
  }
53
51
 
52
+ export function preloadMedia(el, preload = 5) {
53
+ loadLazyElements(el, preload);
54
+
55
+ for (const video of $$('video[preload="none"]', el)) {
56
+ video.preload = '';
57
+ }
58
+ }
59
+
60
+ function loadLazyElements(el, preload) {
61
+ $$('[loading="lazy"]', el)
62
+ .slice(0, preload - 1)
63
+ .forEach((el) => removeAttr(el, 'loading'));
64
+ }
65
+
54
66
  export function viewport(options) {
55
67
  return observe((target, handler) => observeViewportResize(handler), options, 'resize');
56
68
  }
@@ -153,11 +153,14 @@ export function parseOptions(options, args = []) {
153
153
  export function coerce(type, value) {
154
154
  if (type === Boolean) {
155
155
  return toBoolean(value);
156
- } else if (type === Number) {
156
+ }
157
+ if (type === Number) {
157
158
  return toNumber(value);
158
- } else if (type === 'list') {
159
+ }
160
+ if (type === 'list') {
159
161
  return toList(value);
160
- } else if (type === Object && isString(value)) {
162
+ }
163
+ if (type === Object && isString(value)) {
161
164
  return parseOptions(value);
162
165
  }
163
166
 
@@ -67,9 +67,7 @@ function getProps(opts) {
67
67
 
68
68
  const getAttributes = memoize((id, props) => {
69
69
  const attributes = Object.keys(props);
70
- const filter = attributes
71
- .concat(id)
72
- .flatMap((key) => [hyphenate(key), `data-${hyphenate(key)}`]);
70
+ const filter = [...attributes, id].flatMap((key) => [hyphenate(key), `data-${hyphenate(key)}`]);
73
71
  return { attributes, filter };
74
72
  });
75
73
 
@@ -43,14 +43,13 @@ function initMethods(instance) {
43
43
 
44
44
  function normalizeData({ data = {} }, { args = [], props = {} }) {
45
45
  if (isArray(data)) {
46
- data = data.slice(0, args.length).reduce((data, value, index) => {
47
- if (isPlainObject(value)) {
48
- assign(data, value);
49
- } else {
50
- data[args[index]] = value;
51
- }
52
- return data;
53
- }, {});
46
+ data = data
47
+ .slice(0, args.length)
48
+ .reduce(
49
+ (data, value, index) =>
50
+ assign(data, isPlainObject(value) ? value : { [args[index]]: value }),
51
+ {},
52
+ );
54
53
  }
55
54
 
56
55
  for (const key in data) {
@@ -2,6 +2,7 @@ export { default as Countdown } from './countdown';
2
2
  export { default as Filter } from './filter';
3
3
  export { default as Lightbox } from './lightbox';
4
4
  export { default as LightboxPanel } from './lightbox-panel';
5
+ export { default as Marquee } from './marquee';
5
6
  export { default as Notification } from './notification';
6
7
  export { default as Parallax } from './parallax';
7
8
  export { default as Slider } from './slider';
@@ -5,36 +5,17 @@ import { scale3d } from './slideshow-animations';
5
5
  export default {
6
6
  ...Animations,
7
7
  fade: {
8
- show() {
9
- return [{ opacity: 0 }, { opacity: 1 }];
10
- },
8
+ percent: (current) => 1 - css(current, 'opacity'),
11
9
 
12
- percent(current) {
13
- return 1 - css(current, 'opacity');
14
- },
15
-
16
- translate(percent) {
17
- return [{ opacity: 1 - percent }, { opacity: percent }];
18
- },
10
+ translate: (percent) => [{ opacity: 1 - percent }, { opacity: percent }],
19
11
  },
20
12
 
21
13
  scale: {
22
- show() {
23
- return [
24
- { opacity: 0, transform: scale3d(1 - 0.2) },
25
- { opacity: 1, transform: scale3d(1) },
26
- ];
27
- },
28
-
29
- percent(current) {
30
- return 1 - css(current, 'opacity');
31
- },
14
+ percent: (current) => 1 - css(current, 'opacity'),
32
15
 
33
- translate(percent) {
34
- return [
35
- { opacity: 1 - percent, transform: scale3d(1 - 0.2 * percent) },
36
- { opacity: percent, transform: scale3d(1 - 0.2 + 0.2 * percent) },
37
- ];
38
- },
16
+ translate: (percent) => [
17
+ { opacity: 1 - percent, transform: scale3d(1 - 0.2 * percent) },
18
+ { opacity: percent, transform: scale3d(1 - 0.2 + 0.2 * percent) },
19
+ ],
39
20
  },
40
21
  };
@@ -4,6 +4,7 @@ export default {
4
4
  observe: lazyload({
5
5
  target: ({ slides }) => slides,
6
6
  targets: (instance) => instance.getAdjacentSlides(),
7
+ media: true,
7
8
  }),
8
9
 
9
10
  methods: {
@@ -4,55 +4,24 @@ import Animations, { translate, translated } from '../../mixin/internal/slidesho
4
4
  export default {
5
5
  ...Animations,
6
6
  fade: {
7
- show() {
8
- return [{ opacity: 0, zIndex: 0 }, { zIndex: -1 }];
9
- },
10
-
11
- percent(current) {
12
- return 1 - css(current, 'opacity');
13
- },
14
-
15
- translate(percent) {
16
- return [{ opacity: 1 - percent, zIndex: 0 }, { zIndex: -1 }];
17
- },
7
+ percent: (current) => 1 - css(current, 'opacity'),
8
+ translate: (percent) => [{ opacity: 1 - percent, zIndex: 0 }, { zIndex: -1 }],
18
9
  },
19
10
 
20
11
  scale: {
21
- show() {
22
- return [{ opacity: 0, transform: scale3d(1 + 0.5), zIndex: 0 }, { zIndex: -1 }];
23
- },
24
-
25
- percent(current) {
26
- return 1 - css(current, 'opacity');
27
- },
12
+ percent: (current) => 1 - css(current, 'opacity'),
28
13
 
29
- translate(percent) {
30
- return [
31
- { opacity: 1 - percent, transform: scale3d(1 + 0.5 * percent), zIndex: 0 },
32
- { zIndex: -1 },
33
- ];
34
- },
14
+ translate: (percent) => [
15
+ { opacity: 1 - percent, transform: scale3d(1 + 0.5 * percent), zIndex: 0 },
16
+ { zIndex: -1 },
17
+ ],
35
18
  },
36
19
 
37
20
  pull: {
38
- show(dir) {
39
- return dir < 0
40
- ? [
41
- { transform: translate(30), zIndex: -1 },
42
- { transform: translate(), zIndex: 0 },
43
- ]
44
- : [
45
- { transform: translate(-100), zIndex: 0 },
46
- { transform: translate(), zIndex: -1 },
47
- ];
48
- },
21
+ percent: (current, next, dir) => (dir < 0 ? 1 - translated(next) : translated(current)),
49
22
 
50
- percent(current, next, dir) {
51
- return dir < 0 ? 1 - translated(next) : translated(current);
52
- },
53
-
54
- translate(percent, dir) {
55
- return dir < 0
23
+ translate: (percent, dir) =>
24
+ dir < 0
56
25
  ? [
57
26
  { transform: translate(30 * percent), zIndex: -1 },
58
27
  { transform: translate(-100 * (1 - percent)), zIndex: 0 },
@@ -60,29 +29,14 @@ export default {
60
29
  : [
61
30
  { transform: translate(-percent * 100), zIndex: 0 },
62
31
  { transform: translate(30 * (1 - percent)), zIndex: -1 },
63
- ];
64
- },
32
+ ],
65
33
  },
66
34
 
67
35
  push: {
68
- show(dir) {
69
- return dir < 0
70
- ? [
71
- { transform: translate(100), zIndex: 0 },
72
- { transform: translate(), zIndex: -1 },
73
- ]
74
- : [
75
- { transform: translate(-30), zIndex: -1 },
76
- { transform: translate(), zIndex: 0 },
77
- ];
78
- },
79
-
80
- percent(current, next, dir) {
81
- return dir > 0 ? 1 - translated(next) : translated(current);
82
- },
36
+ percent: (current, next, dir) => (dir > 0 ? 1 - translated(next) : translated(current)),
83
37
 
84
- translate(percent, dir) {
85
- return dir < 0
38
+ translate: (percent, dir) =>
39
+ dir < 0
86
40
  ? [
87
41
  { transform: translate(percent * 100), zIndex: 0 },
88
42
  { transform: translate(-30 * (1 - percent)), zIndex: -1 },
@@ -90,8 +44,7 @@ export default {
90
44
  : [
91
45
  { transform: translate(-30 * percent), zIndex: -1 },
92
46
  { transform: translate(100 * (1 - percent)), zIndex: 0 },
93
- ];
94
- },
47
+ ],
95
48
  },
96
49
  };
97
50
 
@@ -269,103 +269,23 @@ export default {
269
269
  return;
270
270
  }
271
271
 
272
- let matches;
273
- const iframeAttrs = {
274
- allowfullscreen: '',
275
- style: 'max-width: 100%; box-sizing: border-box;',
276
- 'uk-responsive': '',
277
- 'uk-video': Boolean(this.videoAutoplay),
278
- };
279
-
280
- // Image
281
- if (type === 'image' || isImage(src)) {
282
- const img = createEl('img');
283
-
284
- wrapInPicture(img, item.sources);
285
- attr(img, {
286
- src,
287
- ...pick(item, ['alt', 'srcset', 'sizes']),
288
- ...attrs,
289
- });
290
-
291
- on(img, 'load', () => this.setItem(item, parent(img) || img));
292
- on(img, 'error', () => this.setError(item));
293
-
294
- // Video
295
- } else if (type === 'video' || isVideo(src)) {
296
- const inline = this.videoAutoplay === 'inline';
297
- const video = createEl('video', {
298
- src,
299
- playsinline: '',
300
- controls: inline ? null : '',
301
- loop: inline ? '' : null,
302
- muted: inline ? '' : null,
303
- poster: this.videoAutoplay ? null : item.poster,
304
- 'uk-video': Boolean(this.videoAutoplay),
305
- ...attrs,
306
- });
307
-
308
- on(video, 'loadedmetadata', () => this.setItem(item, video));
309
- on(video, 'error', () => this.setError(item));
310
-
311
- // Iframe
312
- } else if (type === 'iframe' || src.match(/\.(html|php)($|\?)/i)) {
313
- this.setItem(
314
- item,
315
- createEl('iframe', {
316
- src,
317
- allowfullscreen: '',
318
- class: 'uk-lightbox-iframe',
319
- ...attrs,
320
- }),
321
- );
322
-
323
- // YouTube
324
- } else if (
325
- (matches = src.match(
326
- /\/\/(?:.*?youtube(-nocookie)?\..*?(?:[?&]v=|\/shorts\/)|youtu\.be\/)([\w-]{11})[&?]?(.*)?/,
327
- ))
328
- ) {
329
- this.setItem(
330
- item,
331
- createEl('iframe', {
332
- src: `https://www.youtube${matches[1] || ''}.com/embed/${matches[2]}${
333
- matches[3] ? `?${matches[3]}` : ''
334
- }`,
335
- width: 1920,
336
- height: 1080,
337
- ...iframeAttrs,
338
- ...attrs,
339
- }),
340
- );
341
-
342
- // Vimeo
343
- } else if ((matches = src.match(/\/\/.*?vimeo\.[a-z]+\/(\d+)[&?]?(.*)?/))) {
344
- try {
345
- const { height, width } = await (
346
- await fetch(
347
- `https://vimeo.com/api/oembed.json?maxwidth=1920&url=${encodeURI(
348
- src,
349
- )}`,
350
- { credentials: 'omit' },
351
- )
352
- ).json();
353
-
354
- this.setItem(
355
- item,
356
- createEl('iframe', {
357
- src: `https://player.vimeo.com/video/${matches[1]}${
358
- matches[2] ? `?${matches[2]}` : ''
359
- }`,
360
- width,
361
- height,
362
- ...iframeAttrs,
363
- ...attrs,
364
- }),
365
- );
366
- } catch {
367
- this.setError(item);
272
+ try {
273
+ for (const loader of [
274
+ loadImage,
275
+ loadVideo,
276
+ loadIframe,
277
+ loadYouTube,
278
+ loadVimeo,
279
+ ]) {
280
+ const content = await loader({ src, type, attrs, item, cmp: this });
281
+
282
+ if (content) {
283
+ this.setItem(item, content);
284
+ return;
285
+ }
368
286
  }
287
+ } catch {
288
+ this.setError(item);
369
289
  }
370
290
  },
371
291
  },
@@ -441,6 +361,111 @@ function createEl(tag, attrs) {
441
361
  return el;
442
362
  }
443
363
 
364
+ async function loadImage({ src, type, attrs, item }) {
365
+ if (type !== 'image' && !isImage(src)) {
366
+ return;
367
+ }
368
+
369
+ const img = createEl('img');
370
+
371
+ wrapInPicture(img, item.sources);
372
+ attr(img, {
373
+ src,
374
+ ...pick(item, ['alt', 'srcset', 'sizes']),
375
+ ...attrs,
376
+ });
377
+
378
+ await img.decode();
379
+
380
+ return parent(img) || img;
381
+ }
382
+
383
+ function loadVideo({ src, type, attrs, item, cmp }) {
384
+ if (type !== 'video' && !isVideo(src)) {
385
+ return;
386
+ }
387
+
388
+ const inline = cmp.videoAutoplay === 'inline';
389
+ const video = createEl('video', {
390
+ src,
391
+ playsinline: '',
392
+ controls: inline ? null : '',
393
+ loop: inline ? '' : null,
394
+ muted: inline ? '' : null,
395
+ poster: cmp.videoAutoplay ? null : item.poster,
396
+ 'uk-video': Boolean(cmp.videoAutoplay),
397
+ ...attrs,
398
+ });
399
+
400
+ return new Promise((resolve, reject) => {
401
+ on(video, 'loadedmetadata', () => resolve(video));
402
+ on(video, 'error', reject);
403
+ });
404
+ }
405
+
406
+ function loadIframe({ src, type, attrs }) {
407
+ if (type !== 'iframe' && !/\.(html|php)($|\?)/i.test(src)) {
408
+ return;
409
+ }
410
+
411
+ return createEl('iframe', {
412
+ src,
413
+ allowfullscreen: '',
414
+ class: 'uk-lightbox-iframe',
415
+ ...attrs,
416
+ });
417
+ }
418
+
419
+ function loadYouTube({ src, attrs, cmp }) {
420
+ const matches = src.match(
421
+ /\/\/(?:.*?youtube(-nocookie)?\..*?(?:[?&]v=|\/shorts\/)|youtu\.be\/)([\w-]{11})[&?]?(.*)?/,
422
+ );
423
+
424
+ if (!matches) {
425
+ return;
426
+ }
427
+
428
+ return createEl('iframe', {
429
+ src: `https://www.youtube${matches[1] || ''}.com/embed/${matches[2]}${matches[3] ? `?${matches[3]}` : ''}`,
430
+ width: 1920,
431
+ height: 1080,
432
+ ...getIframeAttrs(cmp),
433
+ ...attrs,
434
+ });
435
+ }
436
+
437
+ async function loadVimeo({ src, attrs, cmp }) {
438
+ const matches = src.match(/\/\/.*?vimeo\.[a-z]+\/(\d+)[&?]?(.*)?/);
439
+
440
+ if (!matches) {
441
+ return;
442
+ }
443
+
444
+ const { height, width } = await (
445
+ await fetch(
446
+ `https://vimeo.com/api/oembed.json?maxwidth=1920&url=${encodeURIComponent(src)}`,
447
+ { credentials: 'omit' },
448
+ )
449
+ ).json();
450
+
451
+ return createEl('iframe', {
452
+ src: `https://player.vimeo.com/video/${matches[1]}${matches[2] ? `?${matches[2]}` : ''}`,
453
+ width,
454
+ height,
455
+ ...getIframeAttrs(cmp),
456
+ ...attrs,
457
+ });
458
+ }
459
+
460
+ function getIframeAttrs(cmp) {
461
+ return {
462
+ allowfullscreen: '',
463
+ style: 'max-width: 100%; box-sizing: border-box;',
464
+ 'uk-responsive': '',
465
+ 'uk-video': Boolean(cmp.videoAutoplay),
466
+ };
467
+ }
468
+
444
469
  function toThumbnavItem(item, videoAutoplay) {
445
470
  const el =
446
471
  item.poster || (item.thumb && (item.type === 'image' || isImage(item.thumb)))
@@ -98,14 +98,11 @@ function ensureThumb(toggles, items) {
98
98
  continue;
99
99
  }
100
100
 
101
- const parent = parents(toggle)
102
- .reverse()
103
- .concat(toggle)
104
- .find(
105
- (parent) =>
106
- this.$el.contains(parent) &&
107
- (parent === toggle || $$(this.toggle, parent).length === 1),
108
- );
101
+ const parent = [...parents(toggle).reverse(), toggle].find(
102
+ (parent) =>
103
+ this.$el.contains(parent) &&
104
+ (parent === toggle || $$(this.toggle, parent).length === 1),
105
+ );
109
106
 
110
107
  if (!parent) {
111
108
  continue;