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.
- checksums.yaml +4 -4
- data/_layouts/compress.html +12 -4
- data/assets/data/private.json +49 -0
- data/assets/themes/j1/adapter/js/{j1scroll.js → scroller.js} +285 -304
- data/assets/themes/j1/core/js/template.js +4098 -223
- data/assets/themes/j1/core/js/template.min.js +9 -8
- data/assets/themes/j1/core/js/template.min.js.map +1 -1
- data/assets/themes/j1/modules/{j1Deepl/js/j1deepl.js → deeplAPI/js/deeplAPI.js} +36 -11
- data/assets/themes/j1/modules/deeplAPI/js/deeplAPI.min.js +18 -0
- data/assets/themes/j1/modules/{j1Scroll → scroller}/css/theme/uno.css +2 -2
- data/assets/themes/j1/modules/{j1Scroll → scroller}/css/theme/uno.min.css +0 -0
- data/assets/themes/j1/modules/scroller/js/scroller.js +346 -0
- data/assets/themes/j1/modules/scroller/js/scroller.min.js +15 -0
- data/lib/j1/version.rb +1 -1
- data/lib/starter_web/Gemfile +1 -1
- data/lib/starter_web/_config.yml +6 -2
- data/lib/starter_web/_data/modules/{j1scroll.yml → scroller.yml} +30 -5
- data/lib/starter_web/_data/private.default.yml +8 -1
- data/lib/starter_web/_data/private.yml +8 -1
- data/lib/starter_web/_data/resources.yml +14 -35
- data/lib/starter_web/_includes/attributes.asciidoc +1 -1
- data/lib/starter_web/_plugins/lunr_index.rb +1 -1
- data/lib/starter_web/index.html +2 -1
- data/lib/starter_web/package.json +1 -1
- data/lib/starter_web/pages/public/blog/navigator/index.html +1 -1
- data/lib/starter_web/pages/public/manuals/dropdown-help.adoc +743 -743
- data/lib/starter_web/utilsrv/_defaults/package.json +1 -1
- data/lib/starter_web/utilsrv/package.json +1 -1
- metadata +11 -12
- data/assets/themes/j1/modules/j1Deepl/js/j1deepl.min.js +0 -18
- data/assets/themes/j1/modules/j1Scroll/js/j1scroll.js +0 -280
- data/assets/themes/j1/modules/j1Scroll/js/j1scroll.min.js +0 -15
- data/assets/themes/j1/modules/showOnScroll/js/showOnScroll.js +0 -73
- 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/
|
4
|
-
# J1 core module for
|
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 = '
|
28
|
+
var pluginName = 'deeplAPI',
|
29
29
|
defaults = {
|
30
30
|
api: 'free', // free (default) | pro
|
31
|
-
auth_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
|
65
|
+
// init()
|
66
|
+
// initialize|run the translation
|
67
67
|
// -----------------------------------------------------------------------
|
68
68
|
init: function(options) {
|
69
|
-
var
|
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
|
-
|
73
|
-
|
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('
|
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
|
4
|
-
# Provides styles for J1 Module
|
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
|
File without changes
|
@@ -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
data/lib/starter_web/Gemfile
CHANGED
@@ -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.
|
56
|
+
gem 'j1-template', '~> 2021.3.0'
|
57
57
|
|
58
58
|
# ------------------------------------------------------------------------------
|
59
59
|
# PRODUCTION: Gem needed for the Jekyll and J1 prod environment
|
data/lib/starter_web/_config.yml
CHANGED
@@ -53,7 +53,7 @@ environment: development
|
|
53
53
|
# ------------------------------------------------------------------------------
|
54
54
|
# Sets the build version of J1 Template Gem
|
55
55
|
#
|
56
|
-
version: 2021.
|
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/
|
3
|
-
# User configuration for J1
|
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/
|
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
|
-
|
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
|
-
|
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
|
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
|