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.
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);