j1-template 2024.3.13 → 2024.3.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (193) hide show
  1. checksums.yaml +4 -4
  2. data/_includes/themes/j1/layouts/content_generator_news_panel_posts.html +1 -1
  3. data/_includes/themes/j1/layouts/layout_resource_generator.html +1 -4
  4. data/_includes/themes/j1/procedures/blocks/footer/boxes/social_media_icons.proc +24 -23
  5. data/_includes/themes/j1/procedures/layouts/content_writer.proc +4 -3
  6. data/_includes/themes/j1/procedures/layouts/default_writer.proc +37 -6
  7. data/_includes/themes/j1/procedures/layouts/module_writer.proc +31 -95
  8. data/_includes/themes/j1/procedures/layouts/resource_writer.proc +51 -29
  9. data/assets/data/amplitude.28.html +887 -0
  10. data/assets/data/amplitude.29.html +923 -0
  11. data/assets/data/amplitude.html +311 -46
  12. data/assets/data/banner.html +9 -7
  13. data/assets/data/masterslider.html +128 -7
  14. data/assets/data/panel.html +16 -65
  15. data/assets/theme/j1/adapter/js/amplitude.23.js +1165 -0
  16. data/assets/theme/j1/adapter/js/amplitude.24.js +1164 -0
  17. data/assets/theme/j1/adapter/js/amplitude.25.js +1268 -0
  18. data/assets/theme/j1/adapter/js/amplitude.js +294 -117
  19. data/assets/theme/j1/adapter/js/attic.js +14 -11
  20. data/assets/theme/j1/adapter/js/docsearch.js +2 -2
  21. data/assets/theme/j1/adapter/js/fab.js +2 -2
  22. data/assets/theme/j1/adapter/js/j1.js +8 -8
  23. data/assets/theme/j1/adapter/js/lazyLoader.js +60 -10
  24. data/assets/theme/j1/adapter/js/masonry.js +1 -1
  25. data/assets/theme/j1/adapter/js/masterslider.js +2 -2
  26. data/assets/theme/j1/adapter/js/particles.js +2 -2
  27. data/assets/theme/j1/adapter/js/scroller.js +2 -2
  28. data/assets/theme/j1/adapter/js/slick.js +2 -2
  29. data/assets/theme/j1/adapter/js/themes.js +1 -1
  30. data/assets/theme/j1/adapter/js/translator.js +2 -2
  31. data/assets/theme/j1/adapter/js/waves.js +1 -1
  32. data/assets/theme/j1/core/css/animate.css +1634 -1070
  33. data/assets/theme/j1/core/css/animate.css.map +1 -0
  34. data/assets/theme/j1/core/css/animate.min.css +2 -1
  35. data/assets/theme/j1/core/css/animate.min.css.map +1 -0
  36. data/assets/theme/j1/core/css/icon-fonts/fontawesome.css +3060 -1538
  37. data/assets/theme/j1/core/css/icon-fonts/fontawesome.css.map +1 -0
  38. data/assets/theme/j1/core/css/icon-fonts/fontawesome.min.css +2 -1
  39. data/assets/theme/j1/core/css/icon-fonts/fontawesome.min.css.map +1 -0
  40. data/assets/theme/j1/core/css/icon-fonts/iconify.css +2308 -1153
  41. data/assets/theme/j1/core/css/icon-fonts/iconify.css.map +1 -0
  42. data/assets/theme/j1/core/css/icon-fonts/iconify.min.css +2 -1
  43. data/assets/theme/j1/core/css/icon-fonts/iconify.min.css.map +1 -0
  44. data/assets/theme/j1/core/css/icon-fonts/mdi.css +16716 -8423
  45. data/assets/theme/j1/core/css/icon-fonts/mdi.css.map +1 -0
  46. data/assets/theme/j1/core/css/icon-fonts/mdi.min.css +2 -1
  47. data/assets/theme/j1/core/css/icon-fonts/mdi.min.css.map +1 -0
  48. data/assets/theme/j1/core/css/icon-fonts/mdib.css +5554 -2766
  49. data/assets/theme/j1/core/css/icon-fonts/mdib.css.map +1 -0
  50. data/assets/theme/j1/core/css/icon-fonts/mdib.min.css +2 -1
  51. data/assets/theme/j1/core/css/icon-fonts/mdib.min.css.map +1 -0
  52. data/assets/theme/j1/core/css/icon-fonts/mdil.css +742 -441
  53. data/assets/theme/j1/core/css/icon-fonts/mdil.css.map +1 -0
  54. data/assets/theme/j1/core/css/icon-fonts/mdil.min.css +2 -1
  55. data/assets/theme/j1/core/css/icon-fonts/mdil.min.css.map +1 -0
  56. data/assets/theme/j1/core/css/themes/bootstrap/bootstrap.css +6552 -3980
  57. data/assets/theme/j1/core/css/themes/bootstrap/bootstrap.css.map +1 -0
  58. data/assets/theme/j1/core/css/themes/bootstrap/bootstrap.min.css +2 -5
  59. data/assets/theme/j1/core/css/themes/bootstrap/bootstrap.min.css.map +1 -0
  60. data/assets/theme/j1/core/css/themes/unodark/bootstrap.css +6818 -4131
  61. data/assets/theme/j1/core/css/themes/unodark/bootstrap.css.map +1 -0
  62. data/assets/theme/j1/core/css/themes/unodark/bootstrap.min.css +2 -5
  63. data/assets/theme/j1/core/css/themes/unodark/bootstrap.min.css.map +1 -0
  64. data/assets/theme/j1/core/css/themes/unolight/bootstrap.css +18568 -11577
  65. data/assets/theme/j1/core/css/themes/unolight/bootstrap.css.map +1 -0
  66. data/assets/theme/j1/core/css/themes/unolight/bootstrap.min.css +2 -35
  67. data/assets/theme/j1/core/css/themes/unolight/bootstrap.min.css.map +1 -0
  68. data/assets/theme/j1/core/css/vendor.css +1771 -1043
  69. data/assets/theme/j1/core/css/vendor.css.map +1 -0
  70. data/assets/theme/j1/core/css/vendor.min.css +2 -1
  71. data/assets/theme/j1/core/css/vendor.min.css.map +1 -0
  72. data/assets/theme/j1/core/js/template.js +399 -447
  73. data/assets/theme/j1/core/js/template.min.js +7 -7
  74. data/assets/theme/j1/core/js/template.min.js.map +1 -1
  75. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/amplitude.css +4 -2
  76. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/player/compact.css +39 -4
  77. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/player/compact.min.css +1 -1
  78. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/player/large.css +57 -17
  79. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/player/large.min.css +1 -1
  80. data/assets/theme/j1/modules/amplitudejs/icons/player/blue/pause.png +0 -0
  81. data/assets/theme/j1/modules/amplitudejs/icons/player/blue/play.png +0 -0
  82. data/assets/theme/j1/modules/amplitudejs/icons/player/blue/play.svg +87 -0
  83. data/assets/theme/j1/modules/amplitudejs/icons/player/dark/skip-backward.svg +60 -0
  84. data/assets/theme/j1/modules/amplitudejs/icons/player/dark/skip-forward.svg +59 -0
  85. data/assets/theme/j1/modules/amplitudejs/js/amplitude.js +65 -21
  86. data/assets/theme/j1/modules/amplitudejs/js/amplitude.min.js +1 -1
  87. data/assets/theme/j1/modules/amplitudejs/js/tech/ytp.js +113 -0
  88. data/assets/theme/j1/modules/iconPicker/js/universal-icon-picker.js +471 -471
  89. data/assets/theme/j1/modules/j1LazyLoader/LICENSE +21 -0
  90. data/assets/theme/j1/modules/j1LazyLoader/js/j1Lazy.js +870 -0
  91. data/assets/theme/j1/modules/js-cookies/js/js.cookie.js +3 -3
  92. data/assets/theme/j1/modules/lazyCssLoader/js/main.0.js +166 -0
  93. data/assets/theme/j1/modules/lazyCssLoader/js/main.1.js +65 -0
  94. data/assets/theme/j1/modules/lazyCssLoader/js/main.js +66 -0
  95. data/assets/theme/j1/modules/lazyCssLoader/js/plugins/examplePlugin.js +13 -0
  96. data/assets/theme/j1/modules/lazyCssLoader/js/plugins/my-plugin.js +25 -0
  97. data/assets/theme/j1/modules/lazyCssLoader/js/plugins/plugin-interface.js +9 -0
  98. data/assets/theme/j1/modules/lazyCssLoader/js/plugins/pluginA.js +46 -0
  99. data/assets/theme/j1/modules/lazyLoader/js/plugins/README.md +324 -0
  100. data/assets/theme/j1/modules/lazyLoader/js/plugins/jquery.lazy.picture.js +188 -0
  101. data/assets/theme/j1/modules/lightGallery/js/lightgallery.js +1 -1
  102. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-video.0.js +794 -0
  103. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-video.js +151 -67
  104. data/assets/theme/j1/modules/slimSelect/js/select.js +1 -1
  105. data/assets/theme/j1/modules/slimSelect/js/select.min.js +3 -3
  106. data/assets/theme/j1/modules/themeSwitcher/js/switcher.js +2 -1
  107. data/assets/theme/j1/modules/videojs/js/plugins/players/dm/dailymotion.min.js +1 -1
  108. data/assets/theme/j1/modules/videojs/js/plugins/players/dm/icon/scalable/dailymotion.svg +62 -0
  109. data/assets/theme/j1/modules/videojs/js/plugins/players/yt/v3.0.0/youtube.js +832 -0
  110. data/assets/theme/j1/modules/videojs/js/plugins/players/yt/v3.0.0/youtube.min.js +17 -0
  111. data/assets/theme/j1/modules/videojs/js/plugins/players/yt/youtube.min.js +1 -1
  112. data/assets/theme/j1/modules/videojs/js/video.js +2 -2
  113. data/lib/j1/version.rb +1 -1
  114. data/lib/starter_web/README.md +577 -560
  115. data/lib/starter_web/_config.yml +2 -2
  116. data/lib/starter_web/_data/blocks/footer.yml +10 -5
  117. data/lib/starter_web/_data/blocks/panel.yml +2 -2
  118. data/lib/starter_web/_data/layouts/default.yml +14 -3
  119. data/lib/starter_web/_data/modules/amplitude.yml +145 -0
  120. data/lib/starter_web/_data/modules/defaults/amplitude.yml +29 -7
  121. data/lib/starter_web/_data/modules/defaults/lazyLoader.yml +2 -2
  122. data/lib/starter_web/_data/modules/gallery.yml +136 -0
  123. data/lib/starter_web/_data/modules/lazyLoader.0.yml +118 -0
  124. data/lib/starter_web/_data/modules/lazyLoader.yml +68 -31
  125. data/lib/starter_web/_data/modules/masonry.yml +4 -4
  126. data/lib/starter_web/_data/modules/masterslider.yml +118 -12
  127. data/lib/starter_web/_data/modules/navigator_menu.yml +831 -803
  128. data/lib/starter_web/_data/resources.yml +154 -190
  129. data/lib/starter_web/_data/templates/feed.xml +1 -1
  130. data/lib/starter_web/_includes/attributes.asciidoc +1 -0
  131. data/lib/starter_web/_plugins/asciidoctor/amplitude-block.rb +1 -1
  132. data/lib/starter_web/_plugins/asciidoctor/dailymotion-block.rb +1 -1
  133. data/lib/starter_web/_plugins/asciidoctor/gallery-block.rb +4 -2
  134. data/lib/starter_web/_plugins/asciidoctor/masonry-block.rb +1 -1
  135. data/lib/starter_web/_plugins/asciidoctor/videojs-block.rb +58 -46
  136. data/lib/starter_web/_plugins/asciidoctor/vimeo-block.rb +26 -19
  137. data/lib/starter_web/_plugins/asciidoctor/youtube-block.rb +30 -40
  138. data/lib/starter_web/_plugins/index/lunr.rb +1 -1
  139. data/lib/starter_web/assets/image/icons/lanus/favicon.ico +0 -0
  140. data/lib/starter_web/assets/image/icons/lanus/lanus-512x512.png +0 -0
  141. data/lib/starter_web/assets/image/icons/lanus/lanus.ico +0 -0
  142. data/lib/starter_web/assets/image/icons/lanus/lanus.png +0 -0
  143. data/lib/starter_web/assets/image/icons/lanus/scalable/lanus.svg +76 -0
  144. data/lib/starter_web/assets/image/icons/lanus/scalable/lanus_sw.svg +62 -0
  145. data/lib/starter_web/assets/image/modules/icons/social/scalable/icon-twitter-x-28 - social.svg +86 -0
  146. data/lib/starter_web/assets/image/modules/icons/social/scalable/icon-twitter-x-28.svg +64 -0
  147. data/lib/starter_web/assets/image/modules/icons/social/scalable/icon-twitter-x.svg +1 -0
  148. data/lib/starter_web/assets/image/modules/icons/social/twitter_x.png +0 -0
  149. data/lib/starter_web/package.json +7 -18
  150. data/lib/starter_web/pages/public/amplitude_yt_tester.adoc +218 -0
  151. data/lib/starter_web/pages/public/features/template.adoc +18 -8
  152. data/lib/starter_web/pages/public/features/template.asciidoc +758 -0
  153. data/lib/starter_web/pages/public/lazy_loader_tester.adoc +402 -0
  154. data/lib/starter_web/pages/public/manuals/ytdl/man.adoc +3020 -0
  155. data/lib/starter_web/pages/public/manuals/ytdl/man.md +2378 -0
  156. data/lib/starter_web/pages/public/tools/previewer/_includes/attributes.asciidoc +0 -16
  157. data/lib/starter_web/pages/public/tools/previewer/_includes/documents/amplitudejs.large.css.asciidoc +505 -0
  158. data/lib/starter_web/pages/public/tools/previewer/_includes/documents/frame.hover.html +69 -0
  159. data/lib/starter_web/pages/public/tools/previewer/_includes/documents/frame.nested.html +75 -0
  160. data/lib/starter_web/pages/public/tools/previewer/_includes/documents/frame.textarea.html +57 -0
  161. data/lib/starter_web/pages/public/tools/previewer/_includes/documents/my.content.html +112 -0
  162. data/lib/starter_web/pages/public/tools/previewer/preview_amplitudejs.adoc +172 -0
  163. data/lib/starter_web/pages/public/tour/_includes/attributes.asciidoc +2 -2
  164. data/lib/starter_web/pages/public/tour/_includes/documents/419_advanced_modals_demo.asciidoc +16 -16
  165. data/lib/starter_web/pages/public/tour/asciidoc_extensions.adoc +13 -3
  166. data/lib/starter_web/pages/public/tour/bootstrap_themes.adoc +12 -3
  167. data/lib/starter_web/pages/public/tour/highlghter_rouge.adoc +13 -3
  168. data/lib/starter_web/pages/public/tour/icon_fonts.adoc +12 -3
  169. data/lib/starter_web/pages/public/tour/modal_extentions.adoc +12 -6
  170. data/lib/starter_web/pages/public/tour/{playback_audio.adoc → play_audio.adoc} +207 -188
  171. data/lib/starter_web/pages/public/tour/{playback_video.adoc → play_video.adoc} +49 -51
  172. data/lib/starter_web/pages/public/tour/present_images.adoc +27 -5
  173. data/lib/starter_web/pages/public/tour/quicksearch.adoc +13 -3
  174. data/lib/starter_web/pages/public/tour/responsive_tables.adoc +13 -4
  175. data/lib/starter_web/pages/public/tour/typography.adoc +12 -3
  176. metadata +90 -22
  177. /data/assets/theme/j1/modules/{lazyLoader → j1LazyLoader/js}/plugins/README.md +0 -0
  178. /data/assets/theme/j1/modules/{lazyLoader/plugins/jquery.lazy.picture.js → j1LazyLoader/js/plugins/picture.js} +0 -0
  179. /data/assets/theme/j1/modules/lazyLoader/{plugins → js/plugins}/jquery.lazy.ajax.js +0 -0
  180. /data/assets/theme/j1/modules/lazyLoader/{plugins → js/plugins}/jquery.lazy.ajax.min.js +0 -0
  181. /data/assets/theme/j1/modules/lazyLoader/{plugins → js/plugins}/jquery.lazy.av.js +0 -0
  182. /data/assets/theme/j1/modules/lazyLoader/{plugins → js/plugins}/jquery.lazy.av.min.js +0 -0
  183. /data/assets/theme/j1/modules/lazyLoader/{plugins → js/plugins}/jquery.lazy.iframe.js +0 -0
  184. /data/assets/theme/j1/modules/lazyLoader/{plugins → js/plugins}/jquery.lazy.iframe.min.js +0 -0
  185. /data/assets/theme/j1/modules/lazyLoader/{plugins → js/plugins}/jquery.lazy.noop.js +0 -0
  186. /data/assets/theme/j1/modules/lazyLoader/{plugins → js/plugins}/jquery.lazy.noop.min.js +0 -0
  187. /data/assets/theme/j1/modules/lazyLoader/{plugins → js/plugins}/jquery.lazy.picture.min.js +0 -0
  188. /data/assets/theme/j1/modules/lazyLoader/{plugins → js/plugins}/jquery.lazy.script.js +0 -0
  189. /data/assets/theme/j1/modules/lazyLoader/{plugins → js/plugins}/jquery.lazy.script.min.js +0 -0
  190. /data/assets/theme/j1/modules/lazyLoader/{plugins → js/plugins}/jquery.lazy.vimeo.js +0 -0
  191. /data/assets/theme/j1/modules/lazyLoader/{plugins → js/plugins}/jquery.lazy.vimeo.min.js +0 -0
  192. /data/assets/theme/j1/modules/lazyLoader/{plugins → js/plugins}/jquery.lazy.youtube.js +0 -0
  193. /data/assets/theme/j1/modules/lazyLoader/{plugins → js/plugins}/jquery.lazy.youtube.min.js +0 -0
@@ -0,0 +1,870 @@
1
+ /*
2
+ * jQuery Lazy - v1.7.10
3
+ * http://jquery.eisbehr.de/lazy/
4
+ *
5
+ * Copyright 2012 - 2018, Daniel 'Eisbehr' Kern
6
+ *
7
+ * Licensed under the MIT license
8
+ * http://www.opensource.org/licenses/mit-license.php
9
+ *
10
+ */
11
+
12
+ ;(function(window, undefined) {
13
+ "use strict";
14
+
15
+ // noinspection JSUnresolvedVariable
16
+ /**
17
+ * library instance - here and not in construct to be shorter in minimization
18
+ * @return void
19
+ */
20
+ var $ = window.jQuery || window.Zepto,
21
+
22
+ /**
23
+ * unique plugin instance id counter
24
+ * @type {number}
25
+ */
26
+ lazyInstanceId = 0,
27
+
28
+ /**
29
+ * helper to register window load for jQuery 3
30
+ * @type {boolean}
31
+ */
32
+ windowLoaded = false;
33
+
34
+ /**
35
+ * make lazy available to jquery - and make it a bit more case-insensitive :)
36
+ * @access public
37
+ * @type {function}
38
+ * @param {object} settings
39
+ * @return {LazyPlugin}
40
+ */
41
+ $.fn.Lazy = $.fn.lazy = function(settings) {
42
+ return new LazyPlugin(this, settings);
43
+ };
44
+
45
+ /**
46
+ * helper to add plugins to lazy prototype configuration
47
+ * @access public
48
+ * @type {function}
49
+ * @param {string|Array} names
50
+ * @param {string|Array|function} [elements]
51
+ * @param {function} loader
52
+ * @return void
53
+ */
54
+ $.Lazy = $.lazy = function(names, elements, loader) {
55
+ // make second parameter optional
56
+ if ($.isFunction(elements)) {
57
+ loader = elements;
58
+ elements = [];
59
+ }
60
+
61
+ // exit here if parameter is not a callable function
62
+ if (!$.isFunction(loader)) {
63
+ return;
64
+ }
65
+
66
+ // make parameters an array of names to be sure
67
+ names = $.isArray(names) ? names : [names];
68
+ elements = $.isArray(elements) ? elements : [elements];
69
+
70
+ var config = LazyPlugin.prototype.config,
71
+ forced = config._f || (config._f = {});
72
+
73
+ // add the loader plugin for every name
74
+ for (var i = 0, l = names.length; i < l; i++) {
75
+ if (config[names[i]] === undefined || $.isFunction(config[names[i]])) {
76
+ config[names[i]] = loader;
77
+ }
78
+ }
79
+
80
+ // add forced elements loader
81
+ for (var c = 0, a = elements.length; c < a; c++) {
82
+ forced[elements[c]] = names[0];
83
+ }
84
+ };
85
+
86
+ /**
87
+ * contains all logic and the whole element handling
88
+ * is packed in a private function outside class to reduce memory usage, because it will not be created on every plugin instance
89
+ * @access private
90
+ * @type {function}
91
+ * @param {LazyPlugin} instance
92
+ * @param {object} config
93
+ * @param {object|Array} items
94
+ * @param {object} events
95
+ * @param {string} namespace
96
+ * @return void
97
+ */
98
+ function _executeLazy(instance, config, items, events, namespace) {
99
+ /**
100
+ * a helper to trigger the 'onFinishedAll' callback after all other events
101
+ * @access private
102
+ * @type {number}
103
+ */
104
+ var _awaitingAfterLoad = 0,
105
+
106
+ /**
107
+ * visible content width
108
+ * @access private
109
+ * @type {number}
110
+ */
111
+ _actualWidth = -1,
112
+
113
+ /**
114
+ * visible content height
115
+ * @access private
116
+ * @type {number}
117
+ */
118
+ _actualHeight = -1,
119
+
120
+ /**
121
+ * determine possibly detected high pixel density
122
+ * @access private
123
+ * @type {boolean}
124
+ */
125
+ _isRetinaDisplay = false,
126
+
127
+ /**
128
+ * dictionary entry for better minimization
129
+ * @access private
130
+ * @type {string}
131
+ */
132
+ _afterLoad = 'afterLoad',
133
+
134
+ /**
135
+ * dictionary entry for better minimization
136
+ * @access private
137
+ * @type {string}
138
+ */
139
+ _load = 'load',
140
+
141
+ /**
142
+ * dictionary entry for better minimization
143
+ * @access private
144
+ * @type {string}
145
+ */
146
+ _error = 'error',
147
+
148
+ /**
149
+ * dictionary entry for better minimization
150
+ * @access private
151
+ * @type {string}
152
+ */
153
+ _img = 'img',
154
+
155
+ /**
156
+ * dictionary entry for better minimization
157
+ * @access private
158
+ * @type {string}
159
+ */
160
+ _src = 'src',
161
+
162
+ /**
163
+ * dictionary entry for better minimization
164
+ * @access private
165
+ * @type {string}
166
+ */
167
+ _srcset = 'srcset',
168
+
169
+ /**
170
+ * dictionary entry for better minimization
171
+ * @access private
172
+ * @type {string}
173
+ */
174
+ _sizes = 'sizes',
175
+
176
+ /**
177
+ * dictionary entry for better minimization
178
+ * @access private
179
+ * @type {string}
180
+ */
181
+ _backgroundImage = 'background-image';
182
+
183
+ /**
184
+ * initialize plugin
185
+ * bind loading to events or set delay time to load all items at once
186
+ * @access private
187
+ * @return void
188
+ */
189
+ function _initialize() {
190
+ // detect actual device pixel ratio
191
+ // noinspection JSUnresolvedVariable
192
+ _isRetinaDisplay = window.devicePixelRatio > 1;
193
+
194
+ // prepare all initial items
195
+ items = _prepareItems(items);
196
+
197
+ // if delay time is set load all items at once after delay time
198
+ if (config.delay >= 0) {
199
+ setTimeout(function() {
200
+ _lazyLoadItems(true);
201
+ }, config.delay);
202
+ }
203
+
204
+ // if no delay is set or combine usage is active bind events
205
+ if (config.delay < 0 || config.combined) {
206
+ // create unique event function
207
+ events.e = _throttle(config.throttle, function(event) {
208
+ // reset detected window size on resize event
209
+ if (event.type === 'resize') {
210
+ _actualWidth = _actualHeight = -1;
211
+ }
212
+
213
+ // execute 'lazy magic'
214
+ _lazyLoadItems(event.all);
215
+ });
216
+
217
+ // create function to add new items to instance
218
+ events.a = function(additionalItems) {
219
+ additionalItems = _prepareItems(additionalItems);
220
+ items.push.apply(items, additionalItems);
221
+ };
222
+
223
+ // create function to get all instance items left
224
+ events.g = function() {
225
+ // filter loaded items before return in case internal filter was not running until now
226
+ return (items = $(items).filter(function() {
227
+ return !$(this).data(config.loadedName);
228
+ }));
229
+ };
230
+
231
+ // create function to force loading elements
232
+ events.f = function(forcedItems) {
233
+ for (var i = 0; i < forcedItems.length; i++) {
234
+ // only handle item if available in current instance
235
+ // use a compare function, because Zepto can't handle object parameter for filter
236
+ // var item = items.filter(forcedItems[i]);
237
+ /* jshint loopfunc: true */
238
+ var item = items.filter(function() {
239
+ return this === forcedItems[i];
240
+ });
241
+
242
+ if (item.length) {
243
+ _lazyLoadItems(false, item);
244
+ }
245
+ }
246
+ };
247
+
248
+ // load initial items
249
+ _lazyLoadItems();
250
+
251
+ // bind lazy load functions to scroll and resize event
252
+ // noinspection JSUnresolvedVariable
253
+ $(config.appendScroll).on('scroll.' + namespace + ' resize.' + namespace, events.e);
254
+ }
255
+ }
256
+
257
+ /**
258
+ * prepare items before handle them
259
+ * @access private
260
+ * @param {Array|object|jQuery} items
261
+ * @return {Array|object|jQuery}
262
+ */
263
+ function _prepareItems(items) {
264
+ // fetch used configurations before loops
265
+ var defaultImage = config.defaultImage,
266
+ placeholder = config.placeholder,
267
+ imageBase = config.imageBase,
268
+ srcsetAttribute = config.srcsetAttribute,
269
+ loaderAttribute = config.loaderAttribute,
270
+ forcedTags = config._f || {};
271
+
272
+ // filter items and only add those who not handled yet and got needed attributes available
273
+ items = $(items).filter(function() {
274
+ var element = $(this),
275
+ tag = _getElementTagName(this);
276
+
277
+ return !element.data(config.handledName) &&
278
+ (element.attr(config.attribute) || element.attr(srcsetAttribute) || element.attr(loaderAttribute) || forcedTags[tag] !== undefined);
279
+ })
280
+
281
+ // append plugin instance to all elements
282
+ .data('plugin_' + config.name, instance);
283
+
284
+ for (var i = 0, l = items.length; i < l; i++) {
285
+ var element = $(items[i]),
286
+ tag = _getElementTagName(items[i]),
287
+ elementImageBase = element.attr(config.imageBaseAttribute) || imageBase;
288
+
289
+ // generate and update source set if an image base is set
290
+ if (tag === _img && elementImageBase && element.attr(srcsetAttribute)) {
291
+ element.attr(srcsetAttribute, _getCorrectedSrcSet(element.attr(srcsetAttribute), elementImageBase));
292
+ }
293
+
294
+ // add loader to forced element types
295
+ if (forcedTags[tag] !== undefined && !element.attr(loaderAttribute)) {
296
+ element.attr(loaderAttribute, forcedTags[tag]);
297
+ }
298
+
299
+ // set default image on every element without source
300
+ if (tag === _img && defaultImage && !element.attr(_src)) {
301
+ element.attr(_src, defaultImage);
302
+ }
303
+
304
+ // set placeholder on every element without background image
305
+ else if (tag !== _img && placeholder && (!element.css(_backgroundImage) || element.css(_backgroundImage) === 'none')) {
306
+ element.css(_backgroundImage, "url('" + placeholder + "')");
307
+ }
308
+ }
309
+
310
+ return items;
311
+ }
312
+
313
+ /**
314
+ * the 'lazy magic' - check all items
315
+ * @access private
316
+ * @param {boolean} [allItems]
317
+ * @param {object} [forced]
318
+ * @return void
319
+ */
320
+ function _lazyLoadItems(allItems, forced) {
321
+ // skip if no items where left
322
+ if (!items.length) {
323
+ // destroy instance if option is enabled
324
+ if (config.autoDestroy) {
325
+ // noinspection JSUnresolvedFunction
326
+ instance.destroy();
327
+ }
328
+
329
+ return;
330
+ }
331
+
332
+ var elements = forced || items,
333
+ loadTriggered = false,
334
+ imageBase = config.imageBase || '',
335
+ srcsetAttribute = config.srcsetAttribute,
336
+ handledName = config.handledName;
337
+
338
+ // loop all available items
339
+ for (var i = 0; i < elements.length; i++) {
340
+ // item is at least in loadable area
341
+ if (allItems || forced || _isInLoadableArea(elements[i])) {
342
+ var element = $(elements[i]),
343
+ tag = _getElementTagName(elements[i]),
344
+ attribute = element.attr(config.attribute),
345
+ elementImageBase = element.attr(config.imageBaseAttribute) || imageBase,
346
+ customLoader = element.attr(config.loaderAttribute);
347
+
348
+ // is not already handled
349
+ if (!element.data(handledName) &&
350
+ // and is visible or visibility doesn't matter
351
+ (!config.visibleOnly || element.is(':visible')) && (
352
+ // and image source or source set attribute is available
353
+ (attribute || element.attr(srcsetAttribute)) && (
354
+ // and is image tag where attribute is not equal source or source set
355
+ (tag === _img && (elementImageBase + attribute !== element.attr(_src) || element.attr(srcsetAttribute) !== element.attr(_srcset))) ||
356
+ // or is non image tag where attribute is not equal background
357
+ (tag !== _img && elementImageBase + attribute !== element.css(_backgroundImage))
358
+ ) ||
359
+ // or custom loader is available
360
+ customLoader))
361
+ {
362
+ // mark element always as handled as this point to prevent double handling
363
+ loadTriggered = true;
364
+ element.data(handledName, true);
365
+
366
+ // load item
367
+ _handleItem(element, tag, elementImageBase, customLoader);
368
+ }
369
+ }
370
+ }
371
+
372
+ // when something was loaded remove them from remaining items
373
+ if (loadTriggered) {
374
+ items = $(items).filter(function() {
375
+ return !$(this).data(handledName);
376
+ });
377
+ }
378
+ }
379
+
380
+ /**
381
+ * load the given element the lazy way
382
+ * @access private
383
+ * @param {object} element
384
+ * @param {string} tag
385
+ * @param {string} imageBase
386
+ * @param {function} [customLoader]
387
+ * @return void
388
+ */
389
+ function _handleItem(element, tag, imageBase, customLoader) {
390
+ // increment count of items waiting for after load
391
+ ++_awaitingAfterLoad;
392
+
393
+ // extended error callback for correct 'onFinishedAll' handling
394
+ var errorCallback = function() {
395
+ _triggerCallback('onError', element);
396
+ _reduceAwaiting();
397
+
398
+ // prevent further callback calls
399
+ errorCallback = $.noop;
400
+ };
401
+
402
+ // trigger function before loading image
403
+ _triggerCallback('beforeLoad', element);
404
+
405
+ // fetch all double used data here for better code minimization
406
+ var srcAttribute = config.attribute,
407
+ srcsetAttribute = config.srcsetAttribute,
408
+ sizesAttribute = config.sizesAttribute,
409
+ retinaAttribute = config.retinaAttribute,
410
+ removeAttribute = config.removeAttribute,
411
+ loadedName = config.loadedName,
412
+ elementRetina = element.attr(retinaAttribute);
413
+
414
+ // handle custom loader
415
+ if (customLoader) {
416
+ // on load callback
417
+ var loadCallback = function() {
418
+ // remove attribute from element
419
+ if (removeAttribute) {
420
+ element.removeAttr(config.loaderAttribute);
421
+ }
422
+
423
+ // mark element as loaded
424
+ element.data(loadedName, true);
425
+
426
+ // call after load event
427
+ _triggerCallback(_afterLoad, element);
428
+
429
+ // remove item from waiting queue and possibly trigger finished event
430
+ // it's needed to be asynchronous to run after filter was in _lazyLoadItems
431
+ setTimeout(_reduceAwaiting, 1);
432
+
433
+ // prevent further callback calls
434
+ loadCallback = $.noop;
435
+ };
436
+
437
+ // bind error event to trigger callback and reduce waiting amount
438
+ element.off(_error).one(_error, errorCallback)
439
+
440
+ // bind after load callback to element
441
+ .one(_load, loadCallback);
442
+
443
+ // trigger custom loader and handle response
444
+ if (!_triggerCallback(customLoader, element, function(response) {
445
+ if(response) {
446
+ element.off(_load);
447
+ loadCallback();
448
+ }
449
+ else {
450
+ element.off(_error);
451
+ errorCallback();
452
+ }
453
+ })) {
454
+ element.trigger(_error);
455
+ }
456
+ }
457
+
458
+ // handle images
459
+ else {
460
+ // create image object
461
+ var imageObj = $(new Image());
462
+
463
+ // bind error event to trigger callback and reduce waiting amount
464
+ imageObj.one(_error, errorCallback)
465
+
466
+ // bind after load callback to image
467
+ .one(_load, function() {
468
+ // remove element from view
469
+ element.hide();
470
+
471
+ // set image back to element
472
+ // do it as single 'attr' calls, to be sure 'src' is set after 'srcset'
473
+ if (tag === _img) {
474
+ element.attr(_sizes, imageObj.attr(_sizes))
475
+ .attr(_srcset, imageObj.attr(_srcset))
476
+ .attr(_src, imageObj.attr(_src));
477
+ }
478
+ else {
479
+ element.css(_backgroundImage, "url('" + imageObj.attr(_src) + "')");
480
+ }
481
+
482
+ // bring it back with some effect!
483
+ element[config.effect](config.effectTime);
484
+
485
+ // remove attribute from element
486
+ if (removeAttribute) {
487
+ element.removeAttr(srcAttribute + ' ' + srcsetAttribute + ' ' + retinaAttribute + ' ' + config.imageBaseAttribute);
488
+
489
+ // only remove 'sizes' attribute, if it was a custom one
490
+ if (sizesAttribute !== _sizes) {
491
+ element.removeAttr(sizesAttribute);
492
+ }
493
+ }
494
+
495
+ // mark element as loaded
496
+ element.data(loadedName, true);
497
+
498
+ // call after load event
499
+ _triggerCallback(_afterLoad, element);
500
+
501
+ // cleanup image object
502
+ imageObj.remove();
503
+
504
+ // remove item from waiting queue and possibly trigger finished event
505
+ _reduceAwaiting();
506
+ });
507
+
508
+ // set sources
509
+ // do it as single 'attr' calls, to be sure 'src' is set after 'srcset'
510
+ var imageSrc = (_isRetinaDisplay && elementRetina ? elementRetina : element.attr(srcAttribute)) || '';
511
+ imageObj.attr(_sizes, element.attr(sizesAttribute))
512
+ .attr(_srcset, element.attr(srcsetAttribute))
513
+ .attr(_src, imageSrc ? imageBase + imageSrc : null);
514
+
515
+ // call after load even on cached image
516
+ imageObj.complete && imageObj.trigger(_load); // jshint ignore : line
517
+ }
518
+ }
519
+
520
+ /**
521
+ * check if the given element is inside the current viewport or threshold
522
+ * @access private
523
+ * @param {object} element
524
+ * @return {boolean}
525
+ */
526
+ function _isInLoadableArea(element) {
527
+ var elementBound = element.getBoundingClientRect(),
528
+ direction = config.scrollDirection,
529
+ threshold = config.threshold,
530
+ vertical = // check if element is in loadable area from top
531
+ ((_getActualHeight() + threshold) > elementBound.top) &&
532
+ // check if element is even in loadable are from bottom
533
+ (-threshold < elementBound.bottom),
534
+ horizontal = // check if element is in loadable area from left
535
+ ((_getActualWidth() + threshold) > elementBound.left) &&
536
+ // check if element is even in loadable area from right
537
+ (-threshold < elementBound.right);
538
+
539
+ if (direction === 'vertical') {
540
+ return vertical;
541
+ }
542
+ else if (direction === 'horizontal') {
543
+ return horizontal;
544
+ }
545
+
546
+ return vertical && horizontal;
547
+ }
548
+
549
+ /**
550
+ * receive the current viewed width of the browser
551
+ * @access private
552
+ * @return {number}
553
+ */
554
+ function _getActualWidth() {
555
+ return _actualWidth >= 0 ? _actualWidth : (_actualWidth = $(window).width());
556
+ }
557
+
558
+ /**
559
+ * receive the current viewed height of the browser
560
+ * @access private
561
+ * @return {number}
562
+ */
563
+ function _getActualHeight() {
564
+ return _actualHeight >= 0 ? _actualHeight : (_actualHeight = $(window).height());
565
+ }
566
+
567
+ /**
568
+ * get lowercase tag name of an element
569
+ * @access private
570
+ * @param {object} element
571
+ * @returns {string}
572
+ */
573
+ function _getElementTagName(element) {
574
+ return element.tagName.toLowerCase();
575
+ }
576
+
577
+ /**
578
+ * prepend image base to all srcset entries
579
+ * @access private
580
+ * @param {string} srcset
581
+ * @param {string} imageBase
582
+ * @returns {string}
583
+ */
584
+ function _getCorrectedSrcSet(srcset, imageBase) {
585
+ if (imageBase) {
586
+ // trim, remove unnecessary spaces and split entries
587
+ var entries = srcset.split(',');
588
+ srcset = '';
589
+
590
+ for (var i = 0, l = entries.length; i < l; i++) {
591
+ srcset += imageBase + entries[i].trim() + (i !== l - 1 ? ',' : '');
592
+ }
593
+ }
594
+
595
+ return srcset;
596
+ }
597
+
598
+ /**
599
+ * helper function to throttle down event triggering
600
+ * @access private
601
+ * @param {number} delay
602
+ * @param {function} callback
603
+ * @return {function}
604
+ */
605
+ function _throttle(delay, callback) {
606
+ var timeout,
607
+ lastExecute = 0;
608
+
609
+ return function(event, ignoreThrottle) {
610
+ var elapsed = +new Date() - lastExecute;
611
+
612
+ function run() {
613
+ lastExecute = +new Date();
614
+ // noinspection JSUnresolvedFunction
615
+ callback.call(instance, event);
616
+ }
617
+
618
+ timeout && clearTimeout(timeout); // jshint ignore : line
619
+
620
+ if (elapsed > delay || !config.enableThrottle || ignoreThrottle) {
621
+ run();
622
+ }
623
+ else {
624
+ timeout = setTimeout(run, delay - elapsed);
625
+ }
626
+ };
627
+ }
628
+
629
+ /**
630
+ * reduce count of awaiting elements to 'afterLoad' event and fire 'onFinishedAll' if reached zero
631
+ * @access private
632
+ * @return void
633
+ */
634
+ function _reduceAwaiting() {
635
+ --_awaitingAfterLoad;
636
+
637
+ // if no items were left trigger finished event
638
+ if (!items.length && !_awaitingAfterLoad) {
639
+ _triggerCallback('onFinishedAll');
640
+ }
641
+ }
642
+
643
+ /**
644
+ * single implementation to handle callbacks, pass element and set 'this' to current instance
645
+ * @access private
646
+ * @param {string|function} callback
647
+ * @param {object} [element]
648
+ * @param {*} [args]
649
+ * @return {boolean}
650
+ */
651
+ function _triggerCallback(callback, element, args) {
652
+ if ((callback = config[callback])) {
653
+ // jQuery's internal '$(arguments).slice(1)' are causing problems at least on old iPads
654
+ // below is shorthand of 'Array.prototype.slice.call(arguments, 1)'
655
+ callback.apply(instance, [].slice.call(arguments, 1));
656
+ return true;
657
+ }
658
+
659
+ return false;
660
+ }
661
+
662
+ // if event driven or window is already loaded don't wait for page loading
663
+ if (config.bind === 'event' || windowLoaded) {
664
+ _initialize();
665
+ }
666
+
667
+ // otherwise load initial items and start lazy after page load
668
+ else {
669
+ // noinspection JSUnresolvedVariable
670
+ $(window).on(_load + '.' + namespace, _initialize);
671
+ }
672
+ }
673
+
674
+ /**
675
+ * lazy plugin class constructor
676
+ * @constructor
677
+ * @access private
678
+ * @param {object} elements
679
+ * @param {object} settings
680
+ * @return {object|LazyPlugin}
681
+ */
682
+ function LazyPlugin(elements, settings) {
683
+ /**
684
+ * this lazy plugin instance
685
+ * @access private
686
+ * @type {object|LazyPlugin|LazyPlugin.prototype}
687
+ */
688
+ var _instance = this,
689
+
690
+ /**
691
+ * this lazy plugin instance configuration
692
+ * @access private
693
+ * @type {object}
694
+ */
695
+ _config = $.extend({}, _instance.config, settings),
696
+
697
+ /**
698
+ * instance generated event executed on container scroll or resize
699
+ * packed in an object to be referenceable and short named because properties will not be minified
700
+ * @access private
701
+ * @type {object}
702
+ */
703
+ _events = {},
704
+
705
+ /**
706
+ * unique namespace for instance related events
707
+ * @access private
708
+ * @type {string}
709
+ */
710
+ _namespace = _config.name + '-' + (++lazyInstanceId);
711
+
712
+ // noinspection JSUndefinedPropertyAssignment
713
+ /**
714
+ * wrapper to get or set an entry from plugin instance configuration
715
+ * much smaller on minify as direct access
716
+ * @access public
717
+ * @type {function}
718
+ * @param {string} entryName
719
+ * @param {*} [value]
720
+ * @return {LazyPlugin|*}
721
+ */
722
+ _instance.config = function(entryName, value) {
723
+ if (value === undefined) {
724
+ return _config[entryName];
725
+ }
726
+
727
+ _config[entryName] = value;
728
+ return _instance;
729
+ };
730
+
731
+ // noinspection JSUndefinedPropertyAssignment
732
+ /**
733
+ * add additional items to current instance
734
+ * @access public
735
+ * @param {Array|object|string} items
736
+ * @return {LazyPlugin}
737
+ */
738
+ _instance.addItems = function(items) {
739
+ _events.a && _events.a($.type(items) === 'string' ? $(items) : items); // jshint ignore : line
740
+ return _instance;
741
+ };
742
+
743
+ // noinspection JSUndefinedPropertyAssignment
744
+ /**
745
+ * get all left items of this instance
746
+ * @access public
747
+ * @returns {object}
748
+ */
749
+ _instance.getItems = function() {
750
+ return _events.g ? _events.g() : {};
751
+ };
752
+
753
+ // noinspection JSUndefinedPropertyAssignment
754
+ /**
755
+ * force lazy to load all items in loadable area right now
756
+ * by default without throttle
757
+ * @access public
758
+ * @type {function}
759
+ * @param {boolean} [useThrottle]
760
+ * @return {LazyPlugin}
761
+ */
762
+ _instance.update = function(useThrottle) {
763
+ _events.e && _events.e({}, !useThrottle); // jshint ignore : line
764
+ return _instance;
765
+ };
766
+
767
+ // noinspection JSUndefinedPropertyAssignment
768
+ /**
769
+ * force element(s) to load directly, ignoring the viewport
770
+ * @access public
771
+ * @param {Array|object|string} items
772
+ * @return {LazyPlugin}
773
+ */
774
+ _instance.force = function(items) {
775
+ _events.f && _events.f($.type(items) === 'string' ? $(items) : items); // jshint ignore : line
776
+ return _instance;
777
+ };
778
+
779
+ // noinspection JSUndefinedPropertyAssignment
780
+ /**
781
+ * force lazy to load all available items right now
782
+ * this call ignores throttling
783
+ * @access public
784
+ * @type {function}
785
+ * @return {LazyPlugin}
786
+ */
787
+ _instance.loadAll = function() {
788
+ _events.e && _events.e({all: true}, true); // jshint ignore : line
789
+ return _instance;
790
+ };
791
+
792
+ // noinspection JSUndefinedPropertyAssignment
793
+ /**
794
+ * destroy this plugin instance
795
+ * @access public
796
+ * @type {function}
797
+ * @return undefined
798
+ */
799
+ _instance.destroy = function() {
800
+ // unbind instance generated events
801
+ // noinspection JSUnresolvedFunction, JSUnresolvedVariable
802
+ $(_config.appendScroll).off('.' + _namespace, _events.e);
803
+ // noinspection JSUnresolvedVariable
804
+ $(window).off('.' + _namespace);
805
+
806
+ // clear events
807
+ _events = {};
808
+
809
+ return undefined;
810
+ };
811
+
812
+ // start using lazy and return all elements to be chainable or instance for further use
813
+ // noinspection JSUnresolvedVariable
814
+ _executeLazy(_instance, _config, elements, _events, _namespace);
815
+ return _config.chainable ? elements : _instance;
816
+ }
817
+
818
+ /**
819
+ * settings and configuration data
820
+ * @access public
821
+ * @type {object|*}
822
+ */
823
+ LazyPlugin.prototype.config = {
824
+ // general
825
+ name : 'lazy',
826
+ chainable : true,
827
+ autoDestroy : true,
828
+ bind : 'load',
829
+ threshold : 500,
830
+ visibleOnly : false,
831
+ appendScroll : window,
832
+ scrollDirection : 'both',
833
+ imageBase : null,
834
+ defaultImage : 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',
835
+ placeholder : null,
836
+ delay : -1,
837
+ combined : false,
838
+
839
+ // attributes
840
+ attribute : 'data-src',
841
+ srcsetAttribute : 'data-srcset',
842
+ sizesAttribute : 'data-sizes',
843
+ retinaAttribute : 'data-retina',
844
+ loaderAttribute : 'data-loader',
845
+ imageBaseAttribute : 'data-imagebase',
846
+ removeAttribute : true,
847
+ handledName : 'handled',
848
+ loadedName : 'loaded',
849
+
850
+ // effect
851
+ effect : 'show',
852
+ effectTime : 0,
853
+
854
+ // throttle
855
+ enableThrottle : true,
856
+ throttle : 250,
857
+
858
+ // callbacks
859
+ beforeLoad : undefined,
860
+ afterLoad : undefined,
861
+ onError : undefined,
862
+ onFinishedAll : undefined
863
+ };
864
+
865
+ // register window load event globally to prevent not loading elements
866
+ // since jQuery 3.X ready state is fully async and may be executed after 'load'
867
+ $(window).on('load', function() {
868
+ windowLoaded = true;
869
+ });
870
+ })(window);