j1-template 2021.2.12 → 2021.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/_layouts/compress.html +12 -4
  3. data/assets/data/private.json +49 -0
  4. data/assets/themes/j1/adapter/js/{j1scroll.js → scroller.js} +285 -304
  5. data/assets/themes/j1/core/js/template.js +4098 -223
  6. data/assets/themes/j1/core/js/template.min.js +9 -8
  7. data/assets/themes/j1/core/js/template.min.js.map +1 -1
  8. data/assets/themes/j1/modules/{j1Deepl/js/j1deepl.js → deeplAPI/js/deeplAPI.js} +36 -11
  9. data/assets/themes/j1/modules/deeplAPI/js/deeplAPI.min.js +18 -0
  10. data/assets/themes/j1/modules/{j1Scroll → scroller}/css/theme/uno.css +2 -2
  11. data/assets/themes/j1/modules/{j1Scroll → scroller}/css/theme/uno.min.css +0 -0
  12. data/assets/themes/j1/modules/scroller/js/scroller.js +346 -0
  13. data/assets/themes/j1/modules/scroller/js/scroller.min.js +15 -0
  14. data/lib/j1/version.rb +1 -1
  15. data/lib/starter_web/Gemfile +1 -1
  16. data/lib/starter_web/_config.yml +6 -2
  17. data/lib/starter_web/_data/modules/{j1scroll.yml → scroller.yml} +30 -5
  18. data/lib/starter_web/_data/private.default.yml +8 -1
  19. data/lib/starter_web/_data/private.yml +8 -1
  20. data/lib/starter_web/_data/resources.yml +14 -35
  21. data/lib/starter_web/_includes/attributes.asciidoc +1 -1
  22. data/lib/starter_web/_plugins/lunr_index.rb +1 -1
  23. data/lib/starter_web/index.html +2 -1
  24. data/lib/starter_web/package.json +1 -1
  25. data/lib/starter_web/pages/public/blog/navigator/index.html +1 -1
  26. data/lib/starter_web/pages/public/manuals/dropdown-help.adoc +743 -743
  27. data/lib/starter_web/utilsrv/_defaults/package.json +1 -1
  28. data/lib/starter_web/utilsrv/package.json +1 -1
  29. metadata +11 -12
  30. data/assets/themes/j1/modules/j1Deepl/js/j1deepl.min.js +0 -18
  31. data/assets/themes/j1/modules/j1Scroll/js/j1scroll.js +0 -280
  32. data/assets/themes/j1/modules/j1Scroll/js/j1scroll.min.js +0 -15
  33. data/assets/themes/j1/modules/showOnScroll/js/showOnScroll.js +0 -73
  34. data/assets/themes/j1/modules/showOnScroll/js/showOnScroll.min.js +0 -15
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  # -----------------------------------------------------------------------------
3
- # ~/assets/themes/j1/modules/j1Deepl/js/j1deepl.js
4
- # J1 core module for j1Deepl
3
+ # ~/assets/themes/j1/modules/deeplAPI/js/deeplAPI.js
4
+ # J1 core module for deeplAPI
5
5
  #
6
6
  # Product/Info:
7
7
  # https://jekyll.one
@@ -25,10 +25,10 @@
25
25
  'use strict';
26
26
 
27
27
  // Create the defaults
28
- var pluginName = 'j1deepl',
28
+ var pluginName = 'deeplAPI',
29
29
  defaults = {
30
30
  api: 'free', // free (default) | pro
31
- auth_key: false, // API authorization key.
31
+ auth_key: '', // API authorization key
32
32
  source_lang: 'auto', // autodetection (default: auto)|supported language. Specifies the language for the input text.
33
33
  target_lang: 'DE', // language to be tranlasted in.
34
34
  max_chars: false, // false (unlimited) or number. Number of chars from the source text passed for translation.
@@ -62,15 +62,39 @@
62
62
  // Avoid plugin prototype conflicts
63
63
  $.extend(Plugin.prototype, {
64
64
  // -----------------------------------------------------------------------
65
- // init
66
- // initialize the plugin
65
+ // init()
66
+ // initialize|run the translation
67
67
  // -----------------------------------------------------------------------
68
68
  init: function(options) {
69
- var logger = log4javascript.getLogger('j1deepl.init');
69
+ var _this = this;
70
+ var logger = log4javascript.getLogger('deeplAPI.init');
71
+ var data_url = '/assets/data/private.json';
72
+ var settings = options;
73
+ var auth_key;
70
74
 
71
75
  logger.info('\n' + 'initializing plugin: started');
72
- this.translate(options);
73
- logger.info('\n' + 'initializing plugin: finished');
76
+
77
+ // loading private data (auth key)
78
+ $.ajax({
79
+ url: data_url,
80
+ dataType: 'json',
81
+ success: function (data) {
82
+ auth_key = data.translators.deepl.auth_key;
83
+ },
84
+ error: function (jqXHR, textStatus, errorThrown) {
85
+ logger.error('\n' + 'failed to retrieve Yaml data from: ' + data_url);
86
+ }
87
+ });
88
+
89
+ // run the translation (if private data loaded)
90
+ var dependencies_met_page_ready = setInterval (function () {
91
+ if (typeof auth_key !== 'undefined' ) {
92
+ settings.auth_key = auth_key;
93
+ _this.translate(settings);
94
+ logger.info('\n' + 'translation: in progress');
95
+ clearInterval(dependencies_met_page_ready);
96
+ }
97
+ });
74
98
  },
75
99
 
76
100
  // -----------------------------------------------------------------------
@@ -113,7 +137,7 @@
113
137
  // then display the result, designed as a module.
114
138
  // -----------------------------------------------------------------------
115
139
  translate: function (settings) {
116
- const logger = log4javascript.getLogger('j1deepl.translate');
140
+ const logger = log4javascript.getLogger('deeplAPI.translate');
117
141
  const READYSTATE_DONE = 4;
118
142
  const STATUS_OK = 200;
119
143
  const SUPPORTED_LANG = ['BG', 'CS', 'DA', 'DE', 'EL', 'EN-GB', 'EN-US', 'EN', 'ES', 'ET', 'FI', 'FR', 'HU', 'IT', 'JA', 'LT', 'LV', 'NL', 'PL', 'PT-PT', 'PT-BR', 'PT', 'RO', 'RU', 'SK', 'SL', 'SV', 'ZH'];
@@ -196,7 +220,8 @@
196
220
  translated_text += result.translations[i].text;
197
221
  translated_text += "\n";
198
222
  }
199
-
223
+ logger.info('\n' + 'translation: finished');
224
+
200
225
  // update the HTM element (content) by the tranlation
201
226
  if (ELEMENT_TYPE === 'TEXTAREA') {
202
227
  $(TARGET_ELEMENT).val(translated_text);
@@ -0,0 +1,18 @@
1
+ /*
2
+ # -----------------------------------------------------------------------------
3
+ # ~/assets/themes/j1/modules/j1Deepl/js/j1deepl.min.js
4
+ # J1 core module for j1Deepl
5
+ #
6
+ # Product/Info:
7
+ # https://jekyll.one
8
+ #
9
+ # Copyright (C) 2021 Juergen Adams
10
+ #
11
+ # J1 Template is licensed under the MIT License.
12
+ # For details, see https://jekyll.one
13
+ # -----------------------------------------------------------------------------
14
+ # NOTE: Based on https://github.com/jquery-boilerplate/jquery-boilerplate
15
+ # See: https://www.dotnetcurry.com/jquery/1069/authoring-jquery-plugins
16
+ # -----------------------------------------------------------------------------
17
+ */
18
+ (function(e,c,a,g){var d="deeplAPI",f={api:"free",auth_key:"",source_lang:"auto",target_lang:"DE",max_chars:false,split_sentences:"1",preserve_formatting:"0",formality:"default",tag_handling:false,outline_detection:true,non_splitting_tags:false,splitting_tags:false,ignore_tags:false,onInit:function(){},onBeforeTranslation:function(){},onAfterTranslation:function(){}};function b(i,h){this.element=i;this.settings=e.extend({},f,h);this.settings.elementID="#"+this.element.id;this.xhr=new XMLHttpRequest();this.init(this.settings)}e.extend(b.prototype,{init:function(i){var n=this;var h=log4javascript.getLogger("deeplAPI.init");var j="/assets/data/private.json";var k=i;var l;h.info("\ninitializing plugin: started");e.ajax({url:j,dataType:"json",success:function(o){l=o.translators.deepl.auth_key},error:function(o,q,p){h.error("\nfailed to retrieve Yaml data from: "+j)}});var m=setInterval(function(){if(typeof l!=="undefined"){k.auth_key=l;n.translate(k);h.info("\ntranslation: in progress");clearInterval(m)}})},prepareXHR:function(h){if(h.api==="free"){this.xhr.open("POST","https://api-free.deepl.com/v2/translate",true)}else{if(h.api==="pro"){this.xhr.open("POST","https://api.deepl.com/v2/translate",true)}else{this.xhr.open("POST","https://api-free.deepl.com/v2/translate",true)}}this.xhr.setRequestHeader("Accept","*/*");this.xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")},prepareText:function(h){return h.split("\n")},translate:function(C){const H=log4javascript.getLogger("deeplAPI.translate");const n=4;const t=200;const u=["BG","CS","DA","DE","EL","EN-GB","EN-US","EN","ES","ET","FI","FR","HU","IT","JA","LT","LV","NL","PL","PT-PT","PT-BR","PT","RO","RU","SK","SL","SV","ZH"];const h=["DE","FR","IT","ES","NL","PL","PT","PT-BR","RU"];const r=["xml"];const w=C.targetElement;const q=e(w).length;const D="Translation failed.\nReason: ";const o="Translation skipped.\nReason: ";var y;var F;var v;var x={};x["400"]="Bad request. Please check error message and your parameters.";x["401"]="Authorization failed. Please supply a valid DeepL-Auth-Key.";x["403"]="Forbidden. The access to the requested resource is denied, because of insufficient access rights.";x["404"]="The requested resource could not be found.";x["413"]="The request size exceeds the limit.";x["415"]="The requested entries format specified in the Accept header is not supported.";x["429"]="Too many requests. Please wait and resend your request.";x["456"]="Quota exceeded. The maximum amount of glossaries has been reached.";x["500"]="Internal server error";x["503"]="Resource currently unavailable. Try again later.";x["529"]="Too many requests. Please wait and resend your request.";var l;var k="";var j="";var B="";var E="";var m;var G;if(q){y=(w.includes(".")||w.includes("#"))?w.substring(1):w;F=e(w).get(0).nodeName;if(F==="TEXTAREA"){B=this.element.value}else{if(F==="P"){j=this.element;B=e(w).text()}}v=B.length}else{H.error("\ntarget element does not exists: "+w);return false}if(C.max_char&&B.length>C.max_char){var s=B.substring(0,C.max_char-3);B=s+" ...";H.info("\nlimit for source text (max: "+C.max_char+") reached: "+B.length)}E=this.prepareText(B);this.prepareXHR(C);var p="";for(var A=0;A<E.length;A++){p+="&text="+E[A]}this.xhr.onload=function(){if(this.readyState===n){if(this.status===t){var I=JSON.parse(this.responseText);var J="";for(var K=0;K<I.translations.length;K++){J+=I.translations[K].text;J+="\n"}H.info("\ntranslation: finished");if(F==="TEXTAREA"){e(w).val(J)}else{if(F==="P"){e(w).text(J)}}}else{H.error("\nAPI returned "+this.status+": "+x[this.status])}}};m=this.settings.source_lang;G=this.settings.target_lang;if(this.settings.source_lang!=="auto"){this.settings.source_lang=(u.indexOf(this.settings.source_lang)>-1)?this.settings.source_lang:false}this.settings.target_lang=(u.indexOf(this.settings.target_lang)>-1)?this.settings.target_lang:false;if(!this.settings.auth_key||!this.settings.source_lang||!this.settings.target_lang){if(!this.settings.auth_key){l="NO AUTH key passed.";H.error("\ninvalid option found. "+l)}if(!this.settings.source_lang){l="WRONG source language passed: "+m;H.error("\ninvalid option found. "+l)}if(!this.settings.target_lang){l="WRONG target language passed: "+G;H.error("\ninvalid option found. "+l)}if(F==="TEXTAREA"){e(w).val(D+l)}else{if(F==="P"){e(w).text(D+l)}}return false}if(!v){l="NO text found for translation";if(F==="TEXTAREA"){e(w).val(o+l)}else{if(F==="P"){e(w).text(o+l)}}H.warn("\nno text found for translation");return false}if(this.settings.formality!=="default"){if(!(h.indexOf(this.settings.target_lang)>-1)){H.warn("\nwrong language found for formality setting: "+this.settings.target_lang)}this.settings.formality=(h.indexOf(this.settings.target_lang)>-1)?this.settings.formality:"default"}if(this.settings.tag_handling){var z=this.settings.tag_handling;this.settings.tag_handling=(r.indexOf(this.settings.tag_handling)>-1)?this.settings.tag_handling:false;if(this.settings.tag_handling){this.settings.non_splitting_tags=this.settings.non_splitting_tags?encodeURIComponent(this.settings.non_splitting_tags):false;this.settings.splitting_tags=this.settings.splitting_tags?encodeURIComponent(this.settings.splitting_tags):false;this.settings.ignore_tags=this.settings.ignore_tags?encodeURIComponent(this.settings.ignore_tags):false}else{H.error("\ninvalid option found for tag handling : "+z);H.warn("\ndisable option: tag_handling");if(this.settings.non_splitting_tags){H.warn("\ndisable option: "+this.settings.non_splitting_tags);this.settings.non_splitting_tags=false}if(this.settings.splitting_tags){H.warn("\ndisable option : "+this.settings.splitting_tags);this.settings.splitting_tags=false}if(this.settings.ignore_tags){H.warn("\ndisable option: "+this.settings.ignore_tags);this.settings.ignore_tags=false}}}else{if(this.settings.non_splitting_tags){H.warn("\ninvalid option found: "+this.settings.non_splitting_tags);this.settings.non_splitting_tags=false}if(this.settings.splitting_tags){H.warn("\ninvalid option found: "+this.settings.splitting_tags);this.settings.splitting_tags=false}if(this.settings.ignore_tags){H.warn("\ninvalid option found: "+this.settings.ignore_tags);this.settings.ignore_tags=false}}k="auth_key="+this.settings.auth_key;k+=(this.settings.source_lang!=="auto")?"&source_lang="+this.settings.source_lang:"";k+="&target_lang="+this.settings.target_lang;k+=(this.settings.formality!=="default")?"&formality="+this.settings.formality:"";k+=(this.settings.split_sentences)?"&split_sentences="+this.settings.formality:"";k+=(this.settings.tag_handling)?"&tag_handling="+this.settings.tag_handling:"&tag_handling=0";k+=(this.settings.tag_handling&&this.settings.non_splitting_tags)?"&non_splitting_tags="+this.settings.non_splitting_tags:"";k+=(this.settings.tag_handling&&this.settings.splitting_tags)?"&splitting_tags="+this.settings.splitting_tags:"";k+=(this.settings.tag_handling&&this.settings.ignore_tags)?"&ignore_tags="+this.settings.ignore_tags:"";k+=p;this.xhr.send(k)}});e.fn[d]=function(i){var h=arguments;if(i===g||typeof i==="object"){return this.each(function(){if(!e.data(this,"plugin_"+d)){e.data(this,"plugin_"+d,new b(this,i))}})}else{if(typeof i==="string"&&i[0]!=="_"&&i!=="init"){var j;this.each(function(){var k=e.data(this,"plugin_"+d);if(k instanceof b&&typeof k[i]==="function"){j=k[i].apply(k,Array.prototype.slice.call(h,1))}if(i==="destroy"){e.data(this,"plugin_"+d,null)}});return j!==g?j:this}}}})(jQuery,window,document);
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  # -----------------------------------------------------------------------------
3
- # ~/assets/themes/j1/modules/j1Scroll/css/uno.css
4
- # Provides styles for J1 Module j1Scroll
3
+ # ~/assets/themes/j1/modules//css/uno.css
4
+ # Provides styles for J1 Module
5
5
  #
6
6
  # Product/Info:
7
7
  # https://jekyll.one
@@ -0,0 +1,346 @@
1
+ /*
2
+ # -----------------------------------------------------------------------------
3
+ # ~/assets/themes/j1/modules/scroller/js/scroller.js
4
+ # J1 core module for scroller
5
+ #
6
+ # Product/Info:
7
+ # https://jekyll.one
8
+ #
9
+ # Copyright (C) 2021 Juergen Adams
10
+ #
11
+ # J1 Template is licensed under the MIT License.
12
+ # For details, see https://jekyll.one
13
+ # -----------------------------------------------------------------------------
14
+ # NOTE: Based on https://github.com/jquery-boilerplate/jquery-boilerplate
15
+ # See: https://www.dotnetcurry.com/jquery/1069/authoring-jquery-plugins
16
+ # -----------------------------------------------------------------------------
17
+ */
18
+
19
+ // the semi-colon before function invocation is a SAFETY method
20
+ // against concatenated scripts and/or other plugins which may
21
+ // NOT be closed properly.
22
+ //
23
+ ;(function($, window, document, undefined) {
24
+ 'use strict';
25
+
26
+ // Create the defaults
27
+ var pluginName = 'scroller',
28
+ defaults = {
29
+ type: 'infiniteScroll',
30
+ scrollOffset: 100,
31
+ elementScroll: false,
32
+ firstPage: 2,
33
+ lastPage: false,
34
+ infoLastPage: false,
35
+ loadStatus: false,
36
+ onInit: function (){}, // callback after plugin has initialized
37
+ onBeforeLoad: function (){}, // callback before new items are loaded
38
+ onAfterLoad: function (){} // callback after new items are loaded
39
+ };
40
+
41
+ // Plugin constructor
42
+ function Plugin (element, options) {
43
+ this.element = element;
44
+ this.settings = $.extend( {}, defaults, options);
45
+ this.settings.elementID = '#' + this.element.id;
46
+
47
+ // call the initializer
48
+ this.init(this.settings);
49
+ }
50
+
51
+ // Avoid plugin prototype conflicts
52
+ $.extend(Plugin.prototype, {
53
+ // -----------------------------------------------------------------------
54
+ // init()
55
+ // plugin initializer
56
+ // -----------------------------------------------------------------------
57
+ init: function(options) {
58
+ var _this = this;
59
+ var logger = log4javascript.getLogger('');
60
+
61
+ logger.info('\n' + 'initializing plugin: started');
62
+ logger.info('\n' + 'state: started');
63
+
64
+ if (options.elementScroll) {
65
+ _this.scroller = _this.element;
66
+ } else {
67
+ _this.scroller = window;
68
+ }
69
+
70
+ if (options.loadStatus) {
71
+ var spinner = '<div class="loader-ellips" style="display: none"> <span class="loader-ellips__dot"></span> <span class="loader-ellips__dot"></span> <span class="loader-ellips__dot"></span> <span class="loader-ellips__dot"></span> </div>';
72
+ $(spinner).insertAfter(options.elementID);
73
+ }
74
+
75
+ if (options.infoLastPage) {
76
+ var message = options.lastPageInfo;
77
+ $(message).insertAfter(options.elementID);
78
+ }
79
+
80
+ // jadams, 2021-11-08: for testing reason, registerScrollEvent delayed
81
+ // until page_ready state
82
+ var dependencies_met_page_ready = setInterval (function () {
83
+ if (j1.getState() === 'finished') {
84
+
85
+ // initialize infinite scroll
86
+ if ( options.type === 'infiniteScroll') {
87
+ logger.info('\n' + 'processing mode: ' + options.type);
88
+ logger.info('\n' + 'loading items from path: ' + options.pagePath + "#void");
89
+ logger.info('\n' + 'monitoring element set to: ' + this.scroller);
90
+ _this.registerScrollEvent(options);
91
+ }
92
+ // initialize show on scroll
93
+ if ( options.type === 'showOnScroll') {
94
+ logger.info('\n' + 'processing mode: ' + options.type);
95
+ logger.info('\n' + 'loading items from path: ' + options.pagePath + "#void");
96
+ logger.info('\n' + 'monitoring element set to: ' + this.scroller);
97
+ _this.registerScrollEvent(options);
98
+ }
99
+ logger.info('\n' + 'initializing plugin: finished');
100
+ logger.info('\n' + 'state: finished');
101
+ clearInterval(dependencies_met_page_ready);
102
+ }
103
+ });
104
+ },
105
+
106
+ // -------------------------------------------------------------------------
107
+ // isInViewport()
108
+ // detects if an element is visible in an viewport specified
109
+ // -------------------------------------------------------------------------
110
+ isInViewport: function (elm, offset) {
111
+ // if the element doesn't exist, abort
112
+ if( elm.length == 0 ) {
113
+ return;
114
+ }
115
+ var $window = jQuery(window);
116
+ var viewport_top = $window.scrollTop();
117
+ var viewport_height = $window.height();
118
+ var viewport_bottom = viewport_top + viewport_height;
119
+ var $elm = jQuery(elm);
120
+ var top = $elm.offset().top + offset;
121
+ var height = $elm.height();
122
+ var bottom = top + height;
123
+
124
+ return (top >= viewport_top && top < viewport_bottom) ||
125
+ (bottom > viewport_top && bottom <= viewport_bottom) ||
126
+ (height > viewport_height && top <= viewport_top && bottom >= viewport_bottom);
127
+ },
128
+
129
+ // -------------------------------------------------------------------------
130
+ // bottomReached()
131
+ // detect final scroll position
132
+ // NOTE: the calculation for BOTTOM position is different for
133
+ // elementScroll and windowScroll. For elementScroll, the
134
+ // trigger isBottomReached is TRUE, if the scroll position has
135
+ // the end of the container PLUS a given scrollOffset.
136
+ // For windowScroll, the trigger isBottomReached is TRUE, if
137
+ // the scroll position has the end of the window MINUS
138
+ // a given scrollOffset.
139
+ // -------------------------------------------------------------------------
140
+ isBottomReached: function (options) {
141
+ var _this = this;
142
+ var bottom, scrollY;
143
+ var clientHeight = $(options.elementID).height();
144
+
145
+ if (_this.settings.elementScroll) {
146
+ // check scroll position of the container items are to be added
147
+ var $window = $(window);
148
+ var viewport_top = $window.scrollTop();
149
+ var viewport_height = $window.height();
150
+ var viewport_bottom = viewport_top + viewport_height - options.scrollOffset;
151
+ var $elm = $(options.elementID);
152
+ var top = $elm.offset().top + clientHeight;
153
+ var height = $elm.height();
154
+ bottom = top + height;
155
+
156
+ return (top >= viewport_top && top < viewport_bottom) ||
157
+ (bottom > viewport_top && bottom <= viewport_bottom) ||
158
+ (height > viewport_height && top <= viewport_top && bottom >= viewport_bottom);
159
+ } else {
160
+ // check scroll position of the (overall) window
161
+ return (window.innerHeight + window.pageYOffset + options.scrollOffset >= document.body.offsetHeight);
162
+ }
163
+ },
164
+
165
+ // -------------------------------------------------------------------------
166
+ // detectScroll()
167
+ // EventHandler to load new items for infinite scroll if final scroll
168
+ // position reached
169
+ // -------------------------------------------------------------------------
170
+ registerScrollEvent: function (options) {
171
+ var _this = this;
172
+ var logger = log4javascript.getLogger('');
173
+
174
+ // scroller type infiniteScroll
175
+ if (options.type === 'infiniteScroll') {
176
+ logger.info('\n' + 'register scroll event of type: ' + options.type);
177
+
178
+ // register event function DYNAMICALLY
179
+ _this[options.id] = function (event) {
180
+ var options = _this.settings;
181
+
182
+ if (_this.isBottomReached(options)) {
183
+ if (options.firstPage > options.lastPage ) {
184
+ logger.info('\n' + 'last page detected on: ' + options.lastPage);
185
+ window.removeEventListener('scroll', _this[options.id]);
186
+ logger.info('\n' + 'scroll event: removed');
187
+
188
+ if (options.infoLastPage ) {
189
+ _this.infoLastPage(options);
190
+ }
191
+ return false;
192
+ }
193
+ _this.getNewPost(options);
194
+ }
195
+ };
196
+ window.addEventListener('scroll', _this[options.id]);
197
+ logger.info('\n' + 'scroll event: registered');
198
+ }
199
+
200
+ // scroller type showOnScroll
201
+ if (options.type === 'showOnScroll') {
202
+ logger.info('\n' + 'register scroll event of type: ' + options.type);
203
+
204
+ // register event function DYNAMICALLY
205
+ _this[options.id] = function (event) {
206
+ if (_this.isInViewport ($('#' + options.id ), options.scrollOffset)) {
207
+ logger.info('\n' + 'specified container is in view: ' + options.id);
208
+ $('.' + options.id).show(options.showDelay);
209
+ logger.info('\n' + 'remove eventHandler');
210
+ window.removeEventListener('scroll', _this[options.id]);
211
+ }
212
+ }
213
+ window.addEventListener('scroll', _this[options.id]);
214
+ }
215
+
216
+ },
217
+
218
+ // -------------------------------------------------------------------------
219
+ // getNewPost()
220
+ // load new items (from current path)
221
+ // Note: loader flag prevents to load items if AJAX load in progress
222
+ // is NOT finished
223
+ // -------------------------------------------------------------------------
224
+ getNewPost: function (options) {
225
+ var _this = this;
226
+ var logger = log4javascript.getLogger('');
227
+
228
+ logger.info('\n' + 'trigger loading ');
229
+
230
+ // initialze loader flag
231
+ if (this.itemsLoaded === false) return false;
232
+
233
+ // set loader flag (false == not loaded)
234
+ this.itemsLoaded = false;
235
+
236
+ // display spinner while loading
237
+ if (options.loadStatus) {
238
+ logger.info('\n' + 'show: spinner');
239
+ $('.loader-ellips').show();
240
+ }
241
+
242
+ var xmlhttp = new XMLHttpRequest();
243
+ xmlhttp.onreadystatechange = function () {
244
+ if (xmlhttp.readyState == XMLHttpRequest.DONE) {
245
+ if (xmlhttp.status == 200) {
246
+ options.firstPage++;
247
+ var childItems = _this.getChildItemsByAjaxHTML(options, xmlhttp.responseText);
248
+ _this.appendNewItems(childItems);
249
+
250
+ logger.info('\n' + 'loading new items: successful');
251
+
252
+ // hide the spinner after loading
253
+ if (options.loadStatus) {
254
+ logger.info('\n' + 'hide: spinner');
255
+ $('.loader-ellips').hide();
256
+ }
257
+
258
+ // set loader flag (true == loaded)
259
+ // return _this.itemsLoaded = true;
260
+ _this.itemsLoaded = true;
261
+ } else {
262
+ // hide the spinner
263
+ if (options.loadStatus) {
264
+ logger.info('\n' + 'hide: spinner');
265
+ $('.loader-ellips').hide();
266
+ }
267
+
268
+ logger.error('\n' + 'loading new items failed, HTTP response: ' + xmlhttp.status );
269
+ // set loader flag (true == loaded)
270
+ // return _this.itemsLoaded = false;
271
+ _this.itemsLoaded = false;
272
+ }
273
+ }
274
+ };
275
+ logger.info('\n' + 'loading new items from path: ' + options.pagePath + options.firstPage);
276
+ xmlhttp.open("GET", location.origin + options.pagePath + options.firstPage + '/index.html', true);
277
+ xmlhttp.send();
278
+ },
279
+
280
+ // -------------------------------------------------------------------------
281
+ // getChildItemsByAjaxHTML()
282
+ // extract items from page loaded
283
+ // -------------------------------------------------------------------------
284
+ getChildItemsByAjaxHTML: function (options, HTMLText) {
285
+ var newHTML = document.createElement('html');
286
+ var logger = log4javascript.getLogger('');
287
+
288
+ logger.info('\n' + 'load new items');
289
+ newHTML.innerHTML = HTMLText;
290
+ var childItems = newHTML.querySelectorAll(options.elementID + ' > *');
291
+ return childItems;
292
+ },
293
+
294
+ // -------------------------------------------------------------------------
295
+ // appendNewItems()
296
+ // append items and run post processing
297
+ // -------------------------------------------------------------------------
298
+ appendNewItems: function (items) {
299
+ var _this = this;
300
+ var logger = log4javascript.getLogger('');
301
+ var cookie_names = j1.getCookieNames();
302
+ var user_translate = j1.readCookie(cookie_names.user_translate);
303
+
304
+ logger.info('\n' + 'append new items');
305
+ items.forEach(function (item) {
306
+ _this.element.appendChild(item);
307
+ });
308
+
309
+ // no dropcaps if translation enabled
310
+ if (user_translate.translationEnabled) {
311
+ logger.info('\n' + 'translation enabled: ' + user_translate.translationEnabled);
312
+ logger.warn('\n' + 'skipped processing of dropcaps');
313
+ } else {
314
+ // initialize dropcaps
315
+ logger.info('\n' + 'post processing: createDropCap');
316
+ j1.core.createDropCap();
317
+ }
318
+
319
+ },
320
+
321
+ // -------------------------------------------------------------------------
322
+ // getNewPost()
323
+ // load|append new items
324
+ // Note: loader flag prevents to load items if AJAX load in progress
325
+ // is NOT finished
326
+ // -------------------------------------------------------------------------
327
+ infoLastPage: function (options) {
328
+ var _this = this;
329
+ var logger = log4javascript.getLogger('');
330
+
331
+ logger.info('\n' + 'show: infoLastPage');
332
+ $('.page-scroll-last').show();
333
+ }
334
+ }); // END prototype
335
+
336
+ // wrapper around the constructor to prevent multiple instantiations
337
+ $.fn [pluginName] = function(options) {
338
+ return this.each(function() {
339
+ if (!$.data( this, "plugin_" + pluginName)) {
340
+ $.data(this, "plugin_" +
341
+ pluginName, new Plugin(this, options));
342
+ }
343
+ });
344
+ };
345
+
346
+ })(jQuery, window, document);
@@ -0,0 +1,15 @@
1
+ /*
2
+ # -----------------------------------------------------------------------------
3
+ # ~/assets/themes/j1/modules//js/scroller.min.js
4
+ # J1 core module for scroller
5
+ #
6
+ # Product/Info:
7
+ # https://jekyll.one
8
+ #
9
+ # Copyright (C) 2021 Juergen Adams
10
+ #
11
+ # J1 Template is licensed under the MIT License.
12
+ # For details, see https://jekyll.one
13
+ # -----------------------------------------------------------------------------
14
+ */
15
+ (function(e,c,a,g){var d="scroller",f={type:"infiniteScroll",scrollOffset:100,elementScroll:false,firstPage:2,lastPage:false,infoLastPage:false,loadStatus:false,onInit:function(){},onBeforeLoad:function(){},onAfterLoad:function(){}};function b(i,h){this.element=i;this.settings=e.extend({},f,h);this.settings.elementID="#"+this.element.id;this.init(this.settings)}e.extend(b.prototype,{init:function(i){var m=this;var h=log4javascript.getLogger("");h.info("\ninitializing plugin: started");h.info("\nstate: started");if(i.elementScroll){m.scroller=m.element}else{m.scroller=c}if(i.loadStatus){var l='<div class="loader-ellips" style="display: none"> <span class="loader-ellips__dot"></span> <span class="loader-ellips__dot"></span> <span class="loader-ellips__dot"></span> <span class="loader-ellips__dot"></span> </div>';e(l).insertAfter(i.elementID)}if(i.infoLastPage){var j=i.lastPageInfo;e(j).insertAfter(i.elementID)}var k=setInterval(function(){if(j1.getState()==="finished"){if(i.type==="infiniteScroll"){h.info("\nprocessing mode: "+i.type);h.info("\nloading items from path: "+i.pagePath+"#void");h.info("\nmonitoring element set to: "+this.scroller);m.registerScrollEvent(i)}if(i.type==="showOnScroll"){h.info("\nprocessing mode: "+i.type);h.info("\nloading items from path: "+i.pagePath+"#void");h.info("\nmonitoring element set to: "+this.scroller);m.registerScrollEvent(i)}h.info("\ninitializing plugin: finished");h.info("\nstate: finished");clearInterval(k)}})},isInViewport:function(n,m){if(n.length==0){return}var j=jQuery(c);var q=j.scrollTop();var i=j.height();var k=q+i;var l=jQuery(n);var o=l.offset().top+m;var p=l.height();var h=o+p;return(o>=q&&o<k)||(h>q&&h<=k)||(p>i&&o<=q&&h>=k)},isBottomReached:function(s){var n=this;var h,p;var m=e(s.elementID).height();if(n.settings.elementScroll){var j=e(c);var r=j.scrollTop();var i=j.height();var l=r+i-s.scrollOffset;var k=e(s.elementID);var o=k.offset().top+m;var q=k.height();h=o+q;return(o>=r&&o<l)||(h>r&&h<=l)||(q>i&&o<=r&&h>=l)}else{return(c.innerHeight+c.pageYOffset+s.scrollOffset>=a.body.offsetHeight)}},registerScrollEvent:function(i){var j=this;var h=log4javascript.getLogger("");if(i.type==="infiniteScroll"){h.info("\nregister scroll event of type: "+i.type);j[i.id]=function(l){var k=j.settings;if(j.isBottomReached(k)){if(k.firstPage>k.lastPage){h.info("\nlast page detected on: "+k.lastPage);c.removeEventListener("scroll",j[k.id]);h.info("\nscroll event: removed");if(k.infoLastPage){j.infoLastPage(k)}return false}j.getNewPost(k)}};c.addEventListener("scroll",j[i.id]);h.info("\nscroll event: registered")}if(i.type==="showOnScroll"){h.info("\nregister scroll event of type: "+i.type);j[i.id]=function(k){if(j.isInViewport(e("#"+i.id),i.scrollOffset)){h.info("\nspecified container is in view: "+i.id);e("."+i.id).show(i.showDelay);h.info("\nremove eventHandler");c.removeEventListener("scroll",j[i.id])}};c.addEventListener("scroll",j[i.id])}},getNewPost:function(i){var k=this;var h=log4javascript.getLogger("");h.info("\ntrigger loading ");if(this.itemsLoaded===false){return false}this.itemsLoaded=false;if(i.loadStatus){h.info("\nshow: spinner");e(".loader-ellips").show()}var j=new XMLHttpRequest();j.onreadystatechange=function(){if(j.readyState==XMLHttpRequest.DONE){if(j.status==200){i.firstPage++;var l=k.getChildItemsByAjaxHTML(i,j.responseText);k.appendNewItems(l);h.info("\nloading new items: successful");if(i.loadStatus){h.info("\nhide: spinner");e(".loader-ellips").hide()}k.itemsLoaded=true}else{if(i.loadStatus){h.info("\nhide: spinner");e(".loader-ellips").hide()}h.error("\nloading new items failed, HTTP response: "+j.status);k.itemsLoaded=false}}};h.info("\nloading new items from path: "+i.pagePath+i.firstPage);j.open("GET",location.origin+i.pagePath+i.firstPage+"/index.html",true);j.send()},getChildItemsByAjaxHTML:function(j,i){var l=a.createElement("html");var h=log4javascript.getLogger("");h.info("\nload new items");l.innerHTML=i;var k=l.querySelectorAll(j.elementID+" > *");return k},appendNewItems:function(h){var l=this;var i=log4javascript.getLogger("");var k=j1.getCookieNames();var j=j1.readCookie(k.user_translate);i.info("\nappend new items");h.forEach(function(m){l.element.appendChild(m)});if(j.translationEnabled){i.info("\ntranslation enabled: "+j.translationEnabled);i.warn("\nskipped processing of dropcaps")}else{i.info("\npost processing: createDropCap");j1.core.createDropCap()}},infoLastPage:function(i){var j=this;var h=log4javascript.getLogger("");h.info("\nshow: infoLastPage");e(".page-scroll-last").show()}});e.fn[d]=function(h){return this.each(function(){if(!e.data(this,"plugin_"+d)){e.data(this,"plugin_"+d,new b(this,h))}})}})(jQuery,window,document);
data/lib/j1/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module J1
2
- VERSION = '2021.2.12'
2
+ VERSION = '2021.3.0'
3
3
  end
@@ -53,7 +53,7 @@ gem 'jekyll', '~> 4.2'
53
53
 
54
54
  # Theme Rubies, default: J1 Template (NOT used for the development system)
55
55
  #
56
- gem 'j1-template', '~> 2021.2.12'
56
+ gem 'j1-template', '~> 2021.3.0'
57
57
 
58
58
  # ------------------------------------------------------------------------------
59
59
  # PRODUCTION: Gem needed for the Jekyll and J1 prod environment
@@ -53,7 +53,7 @@ environment: development
53
53
  # ------------------------------------------------------------------------------
54
54
  # Sets the build version of J1 Template Gem
55
55
  #
56
- version: 2021.2.12
56
+ version: 2021.3.0
57
57
 
58
58
  # version
59
59
  # ------------------------------------------------------------------------------
@@ -592,6 +592,7 @@ defaults:
592
592
  values:
593
593
  layout: page
594
594
  author: J1 Team
595
+ compress: true
595
596
 
596
597
  robots:
597
598
  index: true
@@ -636,6 +637,7 @@ defaults:
636
637
  values:
637
638
  layout: post
638
639
  author: J1 Team
640
+ compress: true
639
641
 
640
642
  robots:
641
643
  index: true
@@ -680,6 +682,7 @@ defaults:
680
682
  values:
681
683
  layout: post
682
684
  author: J1 Team
685
+ compress: true
683
686
 
684
687
  robots:
685
688
  index: true
@@ -722,6 +725,7 @@ defaults:
722
725
  values:
723
726
  layout: page
724
727
  sitemap: false
728
+ compress: true
725
729
 
726
730
  robots:
727
731
  index: false
@@ -735,7 +739,7 @@ defaults:
735
739
  advertising: false
736
740
  youtube: false
737
741
  vimeo: false
738
-
742
+
739
743
 
740
744
  # ==============================================================================
741
745
  # 6. LAYOUT configuration
@@ -1,6 +1,6 @@
1
1
  # ------------------------------------------------------------------------------
2
- # ~/_data/modules/j1Scroll.yml
3
- # User configuration for J1 infiniteScroll
2
+ # ~/_data/modules/scroller.yml
3
+ # User configuration for J1 Scroller API
4
4
  #
5
5
  # Product/Info:
6
6
  # https://jekyll.one
@@ -18,7 +18,7 @@ about_config:
18
18
 
19
19
  title:
20
20
  scope: User settings
21
- location: _data/modules/j1Scroll.yml
21
+ location: _data/modules/scroller.yml
22
22
 
23
23
  # ------------------------------------------------------------------------------
24
24
  # User configuration settings
@@ -27,14 +27,38 @@ settings:
27
27
  enabled: true
28
28
 
29
29
  scrollers:
30
+
31
+ # --------------------------------------------------------------------------
32
+ # Intro Panel
33
+ #
34
+ - scroller:
35
+ enabled: true
36
+ type: showOnScroll
37
+ id: home_intro_panel
38
+ container: home_intro_panel
39
+ showDelay: 700
40
+ scrollOffset: 500
41
+
42
+ # --------------------------------------------------------------------------
43
+ # Service Panel
44
+ #
45
+ - scroller:
46
+ enabled: false
47
+ type: showOnScroll
48
+ id: home_service_panel
49
+ container: home_service_panel
50
+ showDelay: 700
51
+ scrollOffset: 200
52
+
30
53
  # --------------------------------------------------------------------------
31
54
  # News Panel
32
55
  #
33
56
  - scroller:
34
57
  enabled: true
58
+ type: infiniteScroll
35
59
  id: home_news_panel
36
60
  container: home_news_panel-scroll-group
37
- path: /assets/data/news_panel_posts/page
61
+ pagePath: /assets/data/news_panel_posts/page
38
62
  elementScroll: true # false = window, true = container
39
63
  scrollOffset: 100
40
64
  lastPage: 3
@@ -52,9 +76,10 @@ settings:
52
76
  #
53
77
  - scroller:
54
78
  enabled: true
79
+ type: infiniteScroll
55
80
  id: blog_navigator_preview
56
81
  container: timeline
57
- path: /pages/public/blog/navigator/page
82
+ pagePath: /pages/public/blog/navigator/page
58
83
  elementScroll: true
59
84
  scrollOffset: 200
60
85
  lastPage: 4
@@ -23,9 +23,16 @@
23
23
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24
24
  global:
25
25
 
26
- # used by J1 to encrypt cookies
26
+ # used by J1 for encryption
27
27
  session_secret: <your-secret-string>
28
28
 
29
+ # ==============================================================================
30
+ # Translator settings
31
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
32
+ translators:
33
+
34
+ deepl:
35
+ auth_key: <your-auth-key>
29
36
 
30
37
  # ==============================================================================
31
38
  # MODULE settings