j1-template 2023.8.2 → 2023.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/_includes/themes/j1/layouts/content_generator_post.html +19 -49
- data/_includes/themes/j1/procedures/posts/collate_timeline.proc +185 -192
- data/_includes/themes/j1/procedures/posts/create_series_header.proc +1 -14
- data/_includes/themes/j1/procedures/posts/pager.proc +39 -46
- data/assets/themes/j1/adapter/js/speak2me.js +1 -1
- data/assets/themes/j1/adapter/js/translator.js +4 -2
- data/assets/themes/j1/core/css/themes/bootstrap/bootstrap.css +31 -26
- data/assets/themes/j1/core/css/themes/bootstrap/bootstrap.min.css +2 -2
- data/assets/themes/j1/core/css/themes/unodark/bootstrap.css +31 -26
- data/assets/themes/j1/core/css/themes/unodark/bootstrap.min.css +2 -2
- data/assets/themes/j1/core/css/themes/unolight/bootstrap.css +37 -29
- data/assets/themes/j1/core/css/themes/unolight/bootstrap.min.css +3 -3
- data/assets/themes/j1/core/js/template.js +58 -43
- data/assets/themes/j1/core/js/template.min.js +7 -7
- data/assets/themes/j1/core/js/template.min.js.map +1 -1
- data/lib/j1/version.rb +1 -1
- data/lib/starter_web/Gemfile +2 -2
- data/lib/starter_web/README.md +5 -5
- data/lib/starter_web/_config.yml +1 -1
- data/lib/starter_web/_data/blocks/footer.yml +6 -4
- data/lib/starter_web/_data/modules/defaults/blog_navigator.yml +89 -135
- data/lib/starter_web/_data/modules/defaults/speak2me.yml +1 -0
- data/lib/starter_web/_data/modules/justifiedGallery.yml +3 -3
- data/lib/starter_web/_data/modules/navigator_menu.yml +14 -7
- data/lib/starter_web/_data/templates/feed.xml +1 -1
- data/lib/starter_web/_plugins/index/lunr.rb +1 -1
- data/lib/starter_web/collections/posts/public/featured/_posts/0000-00-00-welcome-to-j1.adoc.erb +74 -70
- data/lib/starter_web/collections/posts/public/featured/_posts/2021-01-01-about-cookies.adoc +110 -84
- data/lib/starter_web/collections/posts/public/featured/_posts/2021-02-01-static-site-generators.adoc +49 -33
- data/lib/starter_web/collections/posts/public/featured/_posts/2022-02-01-about-j1.adoc +47 -26
- data/lib/starter_web/package.json +1 -1
- data/lib/starter_web/pages/public/blog/navigator/archive/allview.html +66 -63
- data/lib/starter_web/pages/public/blog/navigator/archive/categoryview.html +76 -77
- data/lib/starter_web/pages/public/blog/navigator/archive/dateview.html +63 -64
- data/lib/starter_web/pages/public/blog/navigator/archive/tagview.html +79 -64
- data/lib/starter_web/pages/public/blog/navigator/index.html +55 -99
- data/lib/starter_web/pages/public/learn/roundtrip/_includes/documents/themes_bootstrap.asciidoc +6 -2
- data/lib/starter_web/pages/public/learn/roundtrip/asciidoc_extensions.adoc +59 -35
- data/lib/starter_web/pages/public/learn/roundtrip/bootstrap_themes.adoc +4 -4
- data/lib/starter_web/pages/public/learn/roundtrip/highlghter_rouge.adoc +1 -1
- data/lib/starter_web/pages/public/learn/roundtrip/icon_fonts.adoc +28 -12
- data/lib/starter_web/pages/public/learn/roundtrip/lunr_search.adoc +12 -4
- data/lib/starter_web/pages/public/learn/roundtrip/modal_extentions.adoc +5 -1
- data/lib/starter_web/pages/public/learn/roundtrip/present_images.adoc +512 -470
- data/lib/starter_web/pages/public/learn/roundtrip/present_videos.adoc +20 -6
- data/lib/starter_web/pages/public/learn/roundtrip/responsive_tables.adoc +5 -2
- data/lib/starter_web/pages/public/learn/where_to_go.adoc +24 -13
- data/lib/starter_web/pages/public/legal/en/100_copyright.adoc +4 -1
- data/lib/starter_web/pages/public/legal/en/200_impress.adoc +4 -1
- data/lib/starter_web/pages/public/legal/en/300_privacy.adoc +632 -595
- data/lib/starter_web/pages/public/legal/en/400_comment_policy.adoc +12 -3
- data/lib/starter_web/utilsrv/_defaults/package.json +1 -1
- data/lib/starter_web/utilsrv/package.json +1 -1
- metadata +2 -2
@@ -4546,7 +4546,12 @@ module.exports = function parseContent(options) {
|
|
4546
4546
|
/* Articulate.js (1.1.0). (C) 2017 Adam Coti.
|
4547
4547
|
MIT @license: en.wikipedia.org/wiki/MIT_License
|
4548
4548
|
See Github page at: https://github.com/acoti/articulate.js
|
4549
|
-
See Web site at:
|
4549
|
+
See Web site at: https://purefreedom.com/articulate/
|
4550
|
+
*/
|
4551
|
+
|
4552
|
+
/* Further reading
|
4553
|
+
https://dev.to/jankapunkt/cross-browser-speech-synthesis-the-hard-way-and-the-easy-way-353
|
4554
|
+
https://github.com/jankapunkt/easy-speech
|
4550
4555
|
*/
|
4551
4556
|
|
4552
4557
|
(function ($) {
|
@@ -4944,31 +4949,37 @@ module.exports = function parseContent(options) {
|
|
4944
4949
|
// strip strange elements from text
|
4945
4950
|
// unclear why a elements of ' >' is generated in text
|
4946
4951
|
// may caused by a HTML tag
|
4952
|
+
//
|
4947
4953
|
text = text.replace(/^\s+>/gm, '');
|
4948
4954
|
text = text.replaceAll(' ..', '.');
|
4949
4955
|
|
4950
4956
|
// cleanup text
|
4957
|
+
//
|
4951
4958
|
text = text.replace(/(\r\n|\n|\r)/gm, '');
|
4952
4959
|
text = text.replace(/\s+/gm, ' ');
|
4953
4960
|
chunks = text.split('.');
|
4954
4961
|
|
4955
4962
|
// 1st cleanup of chunks
|
4963
|
+
//
|
4956
4964
|
chunks.forEach((chunk, index) => {
|
4957
4965
|
chunks[index] = chunks[index].replace(/^\s+/g, '');
|
4958
4966
|
chunks[index] = chunks[index].replaceAll('""', '');
|
4959
4967
|
});
|
4960
4968
|
|
4961
4969
|
// 2nd cleanup of chunks (delete chunks NOT speakable)
|
4970
|
+
//
|
4962
4971
|
chunks.forEach((chunk, index) => {
|
4963
4972
|
if (chunks[index].length > 0) {
|
4964
4973
|
chunks[index] = chunks[index] + '. ';
|
4965
4974
|
} else {
|
4966
4975
|
// remove empty text element from chunks array
|
4976
|
+
//
|
4967
4977
|
chunks.splice(index, 1);
|
4968
4978
|
}
|
4969
4979
|
});
|
4970
4980
|
|
4971
4981
|
// 3rd cleanup of chunks (delete empty chunks)
|
4982
|
+
//
|
4972
4983
|
chunks.forEach((chunk, index) => {
|
4973
4984
|
if (chunks[index].length == 0) {
|
4974
4985
|
// remove empty text element from chunks array
|
@@ -4997,31 +5008,30 @@ module.exports = function parseContent(options) {
|
|
4997
5008
|
});
|
4998
5009
|
});
|
4999
5010
|
|
5000
|
-
//
|
5011
|
+
// create the headings array
|
5012
|
+
//
|
5001
5013
|
headingsArray = parseContent.selectHeadings(defaultOptions.contentSelector, defaultOptions.headingSelector);
|
5002
5014
|
|
5003
5015
|
// parse the headingsArray to add missing offset values
|
5004
|
-
// for headlines
|
5005
5016
|
//
|
5006
5017
|
chunkSet.forEach((chunk, index) => {
|
5007
5018
|
var text;
|
5008
5019
|
var innerText;
|
5009
5020
|
if (chunk.offset === undefined) {
|
5010
5021
|
// cleanup the spoken text for compare
|
5022
|
+
//
|
5011
5023
|
text = chunk.text.replaceAll('. ', '');
|
5012
|
-
|
5013
|
-
// jadams:
|
5014
|
-
// for this type of loop, NOT all headings are found in the array
|
5015
5024
|
if (headingsArray !== null) {
|
5016
5025
|
// see: https://stackoverflow.com/questions/29285897/difference-between-for-in-and-for-of-statements
|
5017
5026
|
// for in loops over enumerable property names of an object
|
5018
5027
|
// for of (new in ES6) does use an object-specific iterator
|
5019
5028
|
// and loops over the values generated by that.
|
5029
|
+
// for (var node in headingsArray) {
|
5020
5030
|
for (var node of headingsArray) {
|
5021
|
-
// for (var node in headingsArray) {
|
5022
5031
|
// cleanup the innerText for compare
|
5032
|
+
//
|
5023
5033
|
innerText = node.innerText.replaceAll('?', '');
|
5024
|
-
innerText = node.innerText;
|
5034
|
+
innerText = node.innerText.replaceAll('!', '');
|
5025
5035
|
if (innerText == text) {
|
5026
5036
|
var headline = $('#' + node.id);
|
5027
5037
|
if (headline.length > 0) {
|
@@ -5030,12 +5040,13 @@ module.exports = function parseContent(options) {
|
|
5030
5040
|
// console.debug('speak2me, text: ' + node.innerText + ', offsetTop: ' + chunk.offsetTop);
|
5031
5041
|
} else {
|
5032
5042
|
// console.warn('speak2me, text: ' + node.innerText + ', offsetTop not caclulated.');
|
5033
|
-
}
|
5034
|
-
}
|
5035
|
-
}
|
5036
|
-
}
|
5037
|
-
}
|
5038
|
-
});
|
5043
|
+
} // END if headline.length
|
5044
|
+
} // END if innerText
|
5045
|
+
} // END for headingsArray
|
5046
|
+
} // END if headingsArray
|
5047
|
+
} // END if chunk.offset
|
5048
|
+
}); // END forEach chunkSet
|
5049
|
+
|
5039
5050
|
return chunkSet;
|
5040
5051
|
}
|
5041
5052
|
|
@@ -5049,15 +5060,18 @@ module.exports = function parseContent(options) {
|
|
5049
5060
|
var stringArray = subText.split(/(\s+)/);
|
5050
5061
|
var words;
|
5051
5062
|
|
5052
|
-
//
|
5063
|
+
// remove last two elements are a fraction of subText
|
5064
|
+
//
|
5053
5065
|
stringArray.pop();
|
5054
5066
|
stringArray.pop();
|
5055
5067
|
|
5056
|
-
//
|
5068
|
+
// build the new string
|
5069
|
+
//
|
5057
5070
|
subText = stringArray.join('');
|
5058
5071
|
subText = subText.replaceAll('.', '');
|
5059
5072
|
|
5060
|
-
// at least
|
5073
|
+
// at least wordsMin words required
|
5074
|
+
//
|
5061
5075
|
words = wordCount(subText);
|
5062
5076
|
if (words < wordsMin) {
|
5063
5077
|
return undefined;
|
@@ -5076,32 +5090,15 @@ module.exports = function parseContent(options) {
|
|
5076
5090
|
//
|
5077
5091
|
$('.mdib-speaker').addClass('mdib-spin');
|
5078
5092
|
|
5079
|
-
//
|
5093
|
+
// listener to ENABLE highlightning and scrolling
|
5094
|
+
// on active spoken elements
|
5080
5095
|
//
|
5081
5096
|
speaker.addEventListener('start', event => {
|
5082
|
-
//
|
5083
|
-
//
|
5084
|
-
if (speaker.offsetTop !== undefined) {
|
5085
|
-
speaker.currentScrollPosition = speaker.offsetTop;
|
5086
|
-
}
|
5087
|
-
|
5088
|
-
// adjust scrolling position offsetTop for 'post series'
|
5089
|
-
//
|
5090
|
-
if ($('.bmd-layout-header').length) {
|
5091
|
-
speaker.offsetTop = $('.bmd-layout-header')[0].offsetTop + (scrollBlockOffset / 2 + 3) + speaker.offsetTop;
|
5092
|
-
speaker.previousScrollPosition = speaker.offsetTop;
|
5093
|
-
}
|
5094
|
-
|
5095
|
-
// add highlightning
|
5096
|
-
//
|
5097
|
-
if (speaker.$paragraph !== undefined) {
|
5098
|
-
speaker.$paragraph.addClass('speak-highlighted');
|
5099
|
-
}
|
5100
|
-
|
5101
|
-
// scroll to paragraph currently spoken if a valid
|
5102
|
-
// offsetTop is available
|
5097
|
+
// scroll on ALL valid offsetTop for headings and paragraphs
|
5103
5098
|
//
|
5104
5099
|
if (speaker.offsetTop !== undefined) {
|
5100
|
+
// skip scrolling if offsetTop position is LOWER than expected
|
5101
|
+
//
|
5105
5102
|
if (speaker.offsetTop >= speaker.previousScrollPosition) {
|
5106
5103
|
window.scrollTo({
|
5107
5104
|
top: speaker.offsetTop - scrollBlockOffset,
|
@@ -5109,13 +5106,19 @@ module.exports = function parseContent(options) {
|
|
5109
5106
|
});
|
5110
5107
|
}
|
5111
5108
|
}
|
5109
|
+
|
5110
|
+
// manage highlightning on currently spoken paragraph
|
5111
|
+
//
|
5112
|
+
if (speaker.$paragraph !== undefined) {
|
5113
|
+
speaker.$paragraph.addClass('speak-highlighted');
|
5114
|
+
}
|
5112
5115
|
});
|
5113
5116
|
|
5114
|
-
// listener to
|
5115
|
-
// and set next chunk to speak
|
5117
|
+
// listener to STOP highlightning for already spoken
|
5118
|
+
// text elements and set next chunk to speak
|
5116
5119
|
//
|
5117
5120
|
speaker.addEventListener('end', function (event) {
|
5118
|
-
// workaround
|
5121
|
+
// workaround to detect offsetTop positions LOWER than expected
|
5119
5122
|
//
|
5120
5123
|
if (speaker.offsetTop !== undefined) {
|
5121
5124
|
if (speaker.offsetTop >= speaker.previousScrollPosition) {
|
@@ -5132,7 +5135,7 @@ module.exports = function parseContent(options) {
|
|
5132
5135
|
chunkCounter++;
|
5133
5136
|
});
|
5134
5137
|
|
5135
|
-
// loop to prepare chunks to speak or
|
5138
|
+
// loop to prepare ALL chunks to speak or STOP the voice output
|
5136
5139
|
//
|
5137
5140
|
var speechMonitor = setInterval(function () {
|
5138
5141
|
// check if all chunks (text) are spoken
|
@@ -5671,6 +5674,18 @@ module.exports = function parseContent(options) {
|
|
5671
5674
|
txt.innerHTML = final;
|
5672
5675
|
final = txt.value;
|
5673
5676
|
|
5677
|
+
// Replace single word in line
|
5678
|
+
//
|
5679
|
+
final = final.replace(/^\s*(\b\w+\b)\s*$/gm, "$1. ");
|
5680
|
+
|
5681
|
+
// Replace month year in line
|
5682
|
+
//
|
5683
|
+
final = final.replace(/^\s*(\b\w+\b\s*[0-9]{4})$/gm, "$1. ");
|
5684
|
+
|
5685
|
+
// Replace multiple whitespaces
|
5686
|
+
//
|
5687
|
+
final = final.replace(/\s+/g, ' ');
|
5688
|
+
|
5674
5689
|
// split the final text in to chunks (sentences).
|
5675
5690
|
//
|
5676
5691
|
const textChunks = splitTextIntoChunks(final);
|