j1-template 2023.8.2 → 2023.9.1
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/_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);
|