j1-template 2021.2.12 → 2021.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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