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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/_includes/themes/j1/layouts/content_generator_post.html +19 -49
  3. data/_includes/themes/j1/procedures/posts/collate_timeline.proc +185 -192
  4. data/_includes/themes/j1/procedures/posts/create_series_header.proc +1 -14
  5. data/_includes/themes/j1/procedures/posts/pager.proc +39 -46
  6. data/assets/themes/j1/adapter/js/speak2me.js +1 -1
  7. data/assets/themes/j1/adapter/js/translator.js +4 -2
  8. data/assets/themes/j1/core/css/themes/bootstrap/bootstrap.css +31 -26
  9. data/assets/themes/j1/core/css/themes/bootstrap/bootstrap.min.css +2 -2
  10. data/assets/themes/j1/core/css/themes/unodark/bootstrap.css +31 -26
  11. data/assets/themes/j1/core/css/themes/unodark/bootstrap.min.css +2 -2
  12. data/assets/themes/j1/core/css/themes/unolight/bootstrap.css +37 -29
  13. data/assets/themes/j1/core/css/themes/unolight/bootstrap.min.css +3 -3
  14. data/assets/themes/j1/core/js/template.js +58 -43
  15. data/assets/themes/j1/core/js/template.min.js +7 -7
  16. data/assets/themes/j1/core/js/template.min.js.map +1 -1
  17. data/lib/j1/version.rb +1 -1
  18. data/lib/starter_web/Gemfile +2 -2
  19. data/lib/starter_web/README.md +5 -5
  20. data/lib/starter_web/_config.yml +1 -1
  21. data/lib/starter_web/_data/blocks/footer.yml +6 -4
  22. data/lib/starter_web/_data/modules/defaults/blog_navigator.yml +89 -135
  23. data/lib/starter_web/_data/modules/defaults/speak2me.yml +1 -0
  24. data/lib/starter_web/_data/modules/justifiedGallery.yml +3 -3
  25. data/lib/starter_web/_data/modules/navigator_menu.yml +14 -7
  26. data/lib/starter_web/_data/templates/feed.xml +1 -1
  27. data/lib/starter_web/_plugins/index/lunr.rb +1 -1
  28. data/lib/starter_web/collections/posts/public/featured/_posts/0000-00-00-welcome-to-j1.adoc.erb +74 -70
  29. data/lib/starter_web/collections/posts/public/featured/_posts/2021-01-01-about-cookies.adoc +110 -84
  30. data/lib/starter_web/collections/posts/public/featured/_posts/2021-02-01-static-site-generators.adoc +49 -33
  31. data/lib/starter_web/collections/posts/public/featured/_posts/2022-02-01-about-j1.adoc +47 -26
  32. data/lib/starter_web/package.json +1 -1
  33. data/lib/starter_web/pages/public/blog/navigator/archive/allview.html +66 -63
  34. data/lib/starter_web/pages/public/blog/navigator/archive/categoryview.html +76 -77
  35. data/lib/starter_web/pages/public/blog/navigator/archive/dateview.html +63 -64
  36. data/lib/starter_web/pages/public/blog/navigator/archive/tagview.html +79 -64
  37. data/lib/starter_web/pages/public/blog/navigator/index.html +55 -99
  38. data/lib/starter_web/pages/public/learn/roundtrip/_includes/documents/themes_bootstrap.asciidoc +6 -2
  39. data/lib/starter_web/pages/public/learn/roundtrip/asciidoc_extensions.adoc +59 -35
  40. data/lib/starter_web/pages/public/learn/roundtrip/bootstrap_themes.adoc +4 -4
  41. data/lib/starter_web/pages/public/learn/roundtrip/highlghter_rouge.adoc +1 -1
  42. data/lib/starter_web/pages/public/learn/roundtrip/icon_fonts.adoc +28 -12
  43. data/lib/starter_web/pages/public/learn/roundtrip/lunr_search.adoc +12 -4
  44. data/lib/starter_web/pages/public/learn/roundtrip/modal_extentions.adoc +5 -1
  45. data/lib/starter_web/pages/public/learn/roundtrip/present_images.adoc +512 -470
  46. data/lib/starter_web/pages/public/learn/roundtrip/present_videos.adoc +20 -6
  47. data/lib/starter_web/pages/public/learn/roundtrip/responsive_tables.adoc +5 -2
  48. data/lib/starter_web/pages/public/learn/where_to_go.adoc +24 -13
  49. data/lib/starter_web/pages/public/legal/en/100_copyright.adoc +4 -1
  50. data/lib/starter_web/pages/public/legal/en/200_impress.adoc +4 -1
  51. data/lib/starter_web/pages/public/legal/en/300_privacy.adoc +632 -595
  52. data/lib/starter_web/pages/public/legal/en/400_comment_policy.adoc +12 -3
  53. data/lib/starter_web/utilsrv/_defaults/package.json +1 -1
  54. data/lib/starter_web/utilsrv/package.json +1 -1
  55. 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: http://articulate.purefreedom.com
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
- // Get headings array
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
- // Remove last two elements are a fraction of subText
5063
+ // remove last two elements are a fraction of subText
5064
+ //
5053
5065
  stringArray.pop();
5054
5066
  stringArray.pop();
5055
5067
 
5056
- // built the new string
5068
+ // build the new string
5069
+ //
5057
5070
  subText = stringArray.join('');
5058
5071
  subText = subText.replaceAll('.', '');
5059
5072
 
5060
- // at least two words required
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
- // manage scrolling and highlightning for the active spoken text
5093
+ // listener to ENABLE highlightning and scrolling
5094
+ // on active spoken elements
5080
5095
  //
5081
5096
  speaker.addEventListener('start', event => {
5082
- // store current scroll position
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 manage highlightning for spoken text elements
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 WRONG offsetTop positions (LOWER as expected)
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 sto the voice output
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);