j1-template 2023.9.1 → 2023.9.2

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.
@@ -4595,7 +4595,7 @@ module.exports = function parseContent(options) {
4595
4595
  var chunkCounter = 0;
4596
4596
  var userStoppedSpeaking = false;
4597
4597
  var chunkSpoken = false;
4598
- var scrollOnce = true;
4598
+ var lastScrollPosition = false;
4599
4599
  var rateUserDefault;
4600
4600
  var pitchUserDefault;
4601
4601
  var volumeUserDefault;
@@ -4652,18 +4652,19 @@ module.exports = function parseContent(options) {
4652
4652
  'de-DE': 'Microsoft Katja Online (Natural) - German (Germany)'
4653
4653
  };
4654
4654
 
4655
- // -------------------------------------------------------------------------
4655
+ // ---------------------------------------------------------------------------
4656
4656
  // Internal functions
4657
- // -------------------------------------------------------------------------
4657
+ // ---------------------------------------------------------------------------
4658
4658
 
4659
4659
  // scan a page to get correct positions for scrolling and highlightning
4660
4660
  //
4661
4661
  function scanPage(options) {
4662
4662
  // see: https://stackoverflow.com/questions/3163615/how-to-scroll-an-html-page-to-a-given-anchor
4663
4663
  // see: https://stackoverflow.com/questions/22154129/how-to-make-setinterval-behave-more-in-sync-or-how-to-use-settimeout-instea
4664
- var line = 0;
4664
+ var line = options.startLine;
4665
4665
  var lines;
4666
4666
  function scanSection(counter) {
4667
+ // jadams, 2023-09-28:
4667
4668
  // because of the current translation in progress, the length
4668
4669
  // of a page may change to higher or lower values (asian)
4669
4670
  //
@@ -4683,11 +4684,20 @@ module.exports = function parseContent(options) {
4683
4684
  setTimeout(function () {
4684
4685
  scanFinished = true;
4685
4686
  $('#content').attr("style", "opacity: 1");
4686
- $(window).scrollTop(0);
4687
+
4688
+ // jadams, 2023-09-28:
4689
+ // do NOT scroll on stop if paused
4690
+ // disabled
4691
+ // -------------------------------------------------------------------
4692
+ // if (!myOptions.isPaused) {
4693
+ // window.scrollTo({top: 0, behavior: 'smooth'});
4694
+ // }
4687
4695
  }, pageScanCycle);
4688
4696
  }
4689
4697
  }
4690
- scanSection(0);
4698
+ scanSection({
4699
+ startLine: 0
4700
+ });
4691
4701
  } // END scanPage
4692
4702
 
4693
4703
  // merge (configuration) objects
@@ -4815,26 +4825,31 @@ module.exports = function parseContent(options) {
4815
4825
  var voiceLanguageDefault = voiceLanguageFirefoxDefault[currentLanguage];
4816
4826
  }
4817
4827
 
4818
- // -------------------------------------------------------------------------
4828
+ // ---------------------------------------------------------------------------
4819
4829
  // Public functions (methods)
4820
- // -------------------------------------------------------------------------
4830
+ // ---------------------------------------------------------------------------
4821
4831
  //
4822
4832
  var methods = {
4823
4833
  // main speak2me method.
4824
4834
  //
4825
4835
  speak: function (options) {
4826
- var opts = $.extend({}, $.fn.speak2me.defaults, options);
4827
4836
  var toSpeak = '';
4828
4837
  var voiceTags = new Array();
4829
4838
  var _this = this;
4830
4839
  var obj, processed, finished;
4831
4840
  var ignoreTags;
4832
4841
  scanFinished = false;
4833
- myOptions = extend(defaultOptions, customOptions || {});
4842
+ myOptions = extend(options, defaultOptions, customOptions || {});
4834
4843
 
4835
4844
  // scan page to find correct positions for scrolling and highlightning
4836
4845
  //
4837
- scanPage();
4846
+ if (!myOptions.isPaused) {
4847
+ scanPage({
4848
+ startLine: 0
4849
+ });
4850
+ } else {
4851
+ scanFinished = true;
4852
+ }
4838
4853
 
4839
4854
  // Default values
4840
4855
  //
@@ -4847,19 +4862,16 @@ module.exports = function parseContent(options) {
4847
4862
  voiceTags['img'] = new voiceTag('Start of an embedded image with the description,', ', ');
4848
4863
  voiceTags['table'] = new voiceTag('Start of an embedded table,', 'This element ist not spoken.');
4849
4864
  voiceTags['card-header'] = new voiceTag('', '');
4850
- voiceTags['doc-example'] = new voiceTag('Start of an embedded example element,', 'This element ist not spoken.');
4851
- voiceTags['admonitionblock'] = new voiceTag('Start of an attention element of type, ', ':');
4852
- voiceTags['listingblock'] = new voiceTag('Start of an embedded structured text block,', 'This element ist not spoken.');
4853
- voiceTags['carousel'] = new voiceTag('Start of an embedded carousel element,', 'This element ist not spoken.');
4854
- voiceTags['slider'] = new voiceTag('Start of an embedded slider element,', 'This element ist not spoken.');
4855
- voiceTags['masonry'] = new voiceTag('Start of an embedded masonry element,', 'This element ist not spoken.');
4856
- voiceTags['lightbox'] = new voiceTag('Start of an embedded lightbox element,', 'This element ist not spoken.');
4857
- voiceTags['gallery'] = new voiceTag('Start of an embedded gallery element,', 'This element ist not spoken.');
4865
+ voiceTags['.doc-example'] = new voiceTag('Start of an embedded example element,', 'This element ist not spoken.');
4866
+ voiceTags['.admonitionblock'] = new voiceTag('Start of an attention element of type, ', ':');
4867
+ voiceTags['.listingblock'] = new voiceTag('Start of an embedded structured text block,', 'This element ist not spoken.');
4868
+ voiceTags['.slider'] = new voiceTag('Start of an embedded slider element,', 'This element ist not spoken.');
4869
+ voiceTags['.masonry'] = new voiceTag('Start of an embedded masonry element,', 'This element ist not spoken.');
4870
+ voiceTags['.lightbox-block'] = new voiceTag('Start of an embedded lightbox element,', 'This element ist not spoken.');
4871
+ voiceTags['.gallery'] = new voiceTag('Start of an embedded gallery element,', 'This element ist not spoken.');
4858
4872
  voiceTags['figure'] = new voiceTag('Start of an embedded figure with the caption,', '');
4859
4873
  voiceTags['blockquote'] = new voiceTag('Blockquote start.', 'Blockquote end.');
4860
4874
  voiceTags['quoteblock'] = new voiceTag('Start of an embedded quote block element,', 'Quote block element end.');
4861
-
4862
- // ignoreTags = ['masonry', 'carousel', 'slider', 'pre','audio','button','canvas','code','del','dialog','embed','form','head','iframe','meter','nav','noscript','object','s','script','select','style','textarea','video'];
4863
4875
  ignoreTags = ['audio', 'button', 'canvas', 'code', 'del', 'pre', 'dialog', 'embed', 'form', 'head', 'iframe', 'meter', 'nav', 'noscript', 'object', 's', 'script', 'select', 'style', 'textarea', 'video'];
4864
4876
 
4865
4877
  // TODO: NOT working for multiple 'tab' windows
@@ -5124,6 +5136,7 @@ module.exports = function parseContent(options) {
5124
5136
  if (speaker.offsetTop >= speaker.previousScrollPosition) {
5125
5137
  speaker.previousScrollPosition = speaker.offsetTop;
5126
5138
  }
5139
+ lastScrollPosition = speaker.offsetTop - scrollBlockOffset;
5127
5140
  }
5128
5141
 
5129
5142
  // remove highlightning for the paragraph already spoken
@@ -5137,6 +5150,7 @@ module.exports = function parseContent(options) {
5137
5150
 
5138
5151
  // loop to prepare ALL chunks to speak or STOP the voice output
5139
5152
  //
5153
+ var wasRunOnce = false;
5140
5154
  var speechMonitor = setInterval(function () {
5141
5155
  // check if all chunks (text) are spoken
5142
5156
  //
@@ -5145,13 +5159,24 @@ module.exports = function parseContent(options) {
5145
5159
  userStoppedSpeaking = false;
5146
5160
  chunkSpoken = false;
5147
5161
  speaker.$paragraph !== undefined && speaker.$paragraph.removeClass('speak-highlighted');
5148
- window.scrollTo({
5149
- top: 0,
5150
- behavior: 'smooth'
5151
- });
5162
+
5163
+ // jadams, 2023-09-28:
5164
+ // do NOT scroll on stop if paused
5165
+ // disabled
5166
+ // -----------------------------------------------------------------
5167
+ // if (!myOptions.isPaused) {
5168
+ // window.scrollTo({top: 0, behavior: 'smooth'});
5169
+ // }
5170
+
5171
+ // remove speak indication;
5152
5172
  $('.mdib-speaker').removeClass('mdib-spin');
5153
5173
  clearInterval(speechMonitor);
5154
5174
  } else {
5175
+ if (!wasRunOnce && myOptions.isPaused) {
5176
+ chunkCounter = myOptions.lastChunk;
5177
+ wasRunOnce = true;
5178
+ }
5179
+
5155
5180
  // prepare speaker data and start the voice
5156
5181
  //
5157
5182
  speaker.text = chunks[chunkCounter].text;
@@ -5315,22 +5340,20 @@ module.exports = function parseContent(options) {
5315
5340
  copy = anchor[0].innerText;
5316
5341
  prepend = voiceTags['a'].prepend;
5317
5342
  appended = voiceTags['a'].append;
5318
-
5319
- // jQuery('<div>' + prepend + copy + '</div>').insertBefore(this);
5320
5343
  jQuery('<div>' + copy + '</div>').insertBefore(this);
5321
5344
  jQuery('<div>' + appended + '</div>').insertBefore(this);
5322
5345
  jQuery(this).remove();
5323
5346
  });
5324
5347
 
5325
- // Search for admonitionblock elements and extract the type and
5348
+ // Search for admonition block elements and extract the type and
5326
5349
  // content. Insert type and content and then remove the DOM object.
5327
5350
  //
5328
- jQuery(clone).find('.admonitionblock').addBack('admonitionblock').each(function () {
5351
+ jQuery(clone).find('.admonitionblock').addBack('.admonitionblock').each(function () {
5329
5352
  content_type = this.classList[1];
5330
5353
  content_element = jQuery(this).find('.content');
5331
5354
  content = content_element[0].innerText;
5332
- prepend = voiceTags['admonitionblock'].prepend + content_type + '. ';
5333
- appended = voiceTags['admonitionblock'].append;
5355
+ prepend = voiceTags['.admonitionblock'].prepend + content_type + '. ';
5356
+ appended = voiceTags['.admonitionblock'].append;
5334
5357
  if (content !== undefined && content != '') {
5335
5358
  jQuery('<div>' + prepend + ' ' + content + '</div>').insertBefore(this);
5336
5359
  jQuery('<div>' + appended + '</div>').insertBefore(this);
@@ -5353,7 +5376,7 @@ module.exports = function parseContent(options) {
5353
5376
  jQuery(this).remove();
5354
5377
  });
5355
5378
 
5356
- // Search for <table>, check for <caption>, insert text
5379
+ // Search for <table> tags, check for <caption>, insert text
5357
5380
  // if exists and then remove the DOM object.
5358
5381
  //
5359
5382
  jQuery(clone).find('table').addBack('table').each(function () {
@@ -5385,27 +5408,27 @@ module.exports = function parseContent(options) {
5385
5408
 
5386
5409
  // Search for doc-example elements and then remove the DOM object.
5387
5410
  //
5388
- jQuery(clone).find('.doc-example').addBack('doc-example').each(function () {
5389
- prepend = voiceTags['doc-example'].prepend;
5390
- appended = voiceTags['doc-example'].append;
5411
+ jQuery(clone).find('.doc-example').addBack('.doc-example').each(function () {
5412
+ prepend = voiceTags['.doc-example'].prepend;
5413
+ appended = voiceTags['.doc-example'].append;
5391
5414
  jQuery('<div>' + prepend + '</div>').insertBefore(this);
5392
5415
  jQuery('<div>' + appended + pause_spoken + '</div>').insertBefore(this);
5393
5416
  jQuery(this).remove();
5394
5417
  });
5395
5418
 
5396
- // Search for listingblock elements, check for previous declared <div>
5419
+ // Search for listing block elements, check for previous declared <div>
5397
5420
  // container that contains the title element and insert the
5398
5421
  // text if exists and then finally remove the DOM object.
5399
5422
  //
5400
- jQuery(clone).find('.listingblock').addBack('listingblock').each(function () {
5423
+ jQuery(clone).find('.listingblock').addBack('.listingblock').each(function () {
5401
5424
  title_element = jQuery(this).find('.title');
5402
5425
  if (title_element.length) {
5403
5426
  copy = title_element[0].innerText;
5404
5427
  } else {
5405
5428
  copy = '';
5406
5429
  }
5407
- prepend = voiceTags['listingblock'].prepend;
5408
- appended = voiceTags['listingblock'].append;
5430
+ prepend = voiceTags['.listingblock'].prepend;
5431
+ appended = voiceTags['.listingblock'].append;
5409
5432
  if (copy !== undefined && copy != '') {
5410
5433
  jQuery('<div>' + prepend + ' with the caption,' + copy + pause_spoken + '</div>').insertBefore(this);
5411
5434
  jQuery('<div>' + appended + '</div>').insertBefore(this);
@@ -5416,37 +5439,11 @@ module.exports = function parseContent(options) {
5416
5439
  jQuery(this).remove();
5417
5440
  });
5418
5441
 
5419
- // Search for <carousel> tags, check for previous declared <div>
5420
- // container that contains the title element and insert the
5421
- // text if exists and finally remove the DOM object.
5422
- //
5423
- jQuery(clone).find('carousel').addBack('carousel').each(function () {
5424
- if ($(this).prev()[0].innerText !== undefined) {
5425
- title = $(this).prev()[0].innerText;
5426
- title_element = jQuery(this).prev();
5427
- // remove the title 'before' the DOM object deleted
5428
- //
5429
- jQuery(title_element).remove();
5430
- } else {
5431
- title = '';
5432
- }
5433
- prepend = voiceTags['carousel'].prepend;
5434
- appended = voiceTags['carousel'].append;
5435
- if (title !== undefined && title != '') {
5436
- jQuery('<div>' + prepend + ' with the caption,' + title + pause_spoken + '</div>').insertBefore(this);
5437
- jQuery('<div>' + appended + '</div>').insertBefore(this);
5438
- } else {
5439
- jQuery('<div>' + prepend + '</div>').insertBefore(this);
5440
- jQuery('<div>' + appended + '</div>').insertBefore(this);
5441
- }
5442
- jQuery(this).remove();
5443
- });
5444
-
5445
- // Search for <masonry> tags, check for previous declared <div>
5442
+ // Search for masonry elements, check for previous declared <div>
5446
5443
  // container that contains the title element and insert the
5447
5444
  // text if exists and finally remove the DOM object.
5448
5445
  //
5449
- jQuery(clone).find('masonry').addBack('masonry').each(function () {
5446
+ jQuery(clone).find('.masonry').addBack('.masonry').each(function () {
5450
5447
  if ($(this).prev()[0].innerText !== undefined) {
5451
5448
  title = $(this).prev()[0].innerText;
5452
5449
  title_element = jQuery(this).prev();
@@ -5456,8 +5453,8 @@ module.exports = function parseContent(options) {
5456
5453
  } else {
5457
5454
  title = '';
5458
5455
  }
5459
- prepend = voiceTags['masonry'].prepend;
5460
- appended = voiceTags['masonry'].append;
5456
+ prepend = voiceTags['.masonry'].prepend;
5457
+ appended = voiceTags['.masonry'].append;
5461
5458
  if (title !== undefined && title != '') {
5462
5459
  jQuery('<div>' + prepend + ' with the caption,' + title + pause_spoken + '</div>').insertBefore(this);
5463
5460
  jQuery('<div>' + appended + '</div>').insertBefore(this);
@@ -5468,11 +5465,11 @@ module.exports = function parseContent(options) {
5468
5465
  jQuery(this).remove();
5469
5466
  });
5470
5467
 
5471
- // Search for <slider> tags, check for previous declared <div>
5468
+ // Search for slider elements, check for previous declared <div>
5472
5469
  // container that contains the title element and insert the
5473
5470
  // text if exists and finally remove the DOM object.
5474
5471
  //
5475
- jQuery(clone).find('slider').addBack('slider').each(function () {
5472
+ jQuery(clone).find('.slider').addBack('.slider').each(function () {
5476
5473
  if ($(this).prev()[0].innerText !== undefined) {
5477
5474
  title = $(this).prev()[0].innerText;
5478
5475
  title_element = jQuery(this).prev();
@@ -5482,8 +5479,8 @@ module.exports = function parseContent(options) {
5482
5479
  } else {
5483
5480
  title = '';
5484
5481
  }
5485
- prepend = voiceTags['slider'].prepend;
5486
- appended = voiceTags['slider'].append;
5482
+ prepend = voiceTags['.slider'].prepend;
5483
+ appended = voiceTags['.slider'].append;
5487
5484
  if (title !== undefined && title != '') {
5488
5485
  jQuery('<div>' + prepend + ' with the caption, ' + title + pause_spoken + '</div>').insertBefore(this);
5489
5486
  jQuery('<div>' + appended + '</div>').insertBefore(this);
@@ -5494,11 +5491,11 @@ module.exports = function parseContent(options) {
5494
5491
  jQuery(this).remove();
5495
5492
  });
5496
5493
 
5497
- // Search for <gallery> tags, check for previous declared <div>
5494
+ // Search for gallery elements, check for previous declared <div>
5498
5495
  // container that contains the title element and insert the
5499
5496
  // text if exists and finally remove the DOM object.
5500
5497
  //
5501
- jQuery(clone).find('gallery').addBack('gallery').each(function () {
5498
+ jQuery(clone).find('.gallery').addBack('.gallery').each(function () {
5502
5499
  if ($(this).prev()[0].innerText !== undefined) {
5503
5500
  title = $(this).prev()[0].innerText;
5504
5501
  title_element = jQuery(this).prev();
@@ -5508,8 +5505,8 @@ module.exports = function parseContent(options) {
5508
5505
  } else {
5509
5506
  title = '';
5510
5507
  }
5511
- prepend = voiceTags['gallery'].prepend;
5512
- appended = voiceTags['gallery'].append;
5508
+ prepend = voiceTags['.gallery'].prepend;
5509
+ appended = voiceTags['.gallery'].append;
5513
5510
  if (title !== undefined && title != '') {
5514
5511
  prepend !== '' && jQuery('<div>' + prepend + ' with the caption ' + title + pause_spoken + '</div>').insertBefore(this);
5515
5512
  appended !== '' && jQuery('<div>' + appended + '</div>').insertBefore(this);
@@ -5520,10 +5517,10 @@ module.exports = function parseContent(options) {
5520
5517
  jQuery(this).remove();
5521
5518
  });
5522
5519
 
5523
- // Search for <slider> tags, and extract the <caption> tag data,
5520
+ // Search for a lightbox blocks and extract the <caption> tag data,
5524
5521
  // insert the text if exists and finally remove the DOM object.
5525
5522
  //
5526
- jQuery(clone).find('lightbox').addBack('gallery').each(function () {
5523
+ jQuery(clone).find('.lightbox-block').addBack('.lightbox-block').each(function () {
5527
5524
  if ($(this).prev()[0].innerText !== undefined) {
5528
5525
  title = $(this).prev()[0].innerText;
5529
5526
  title_element = jQuery(this).prev();
@@ -5533,8 +5530,8 @@ module.exports = function parseContent(options) {
5533
5530
  } else {
5534
5531
  title = '';
5535
5532
  }
5536
- prepend = voiceTags['lightbox'].prepend;
5537
- appended = voiceTags['lightbox'].append;
5533
+ prepend = voiceTags['.lightbox-block'].prepend;
5534
+ appended = voiceTags['.lightbox-block'].append;
5538
5535
  if (title !== undefined && title != '') {
5539
5536
  jQuery('<div>' + prepend + ' with the caption,' + title + pause_spoken + '</div>').insertBefore(this);
5540
5537
  jQuery('<div>' + appended + '</div>').insertBefore(this);
@@ -5716,10 +5713,12 @@ module.exports = function parseContent(options) {
5716
5713
  window.speechSynthesis.cancel();
5717
5714
  userStoppedSpeaking = true;
5718
5715
 
5719
- // jadams
5716
+ // jadams, 2023-09-28;
5717
+ // do not work
5718
+ // -----------------------------------------------------------------------
5720
5719
  // NOTE: stopping coincident active speech synthesis
5721
5720
  // in multiple browser windows (tabs) does NOT work
5722
- //
5721
+ // -----------------------------------------------------------------------
5723
5722
  // user_session.speech_synthesis_active = false;
5724
5723
  // j1.writeCookie({
5725
5724
  // name: 'user_session',
@@ -5728,8 +5727,9 @@ module.exports = function parseContent(options) {
5728
5727
  // expires: 0
5729
5728
  // });
5730
5729
 
5731
- return this;
5730
+ // return this;
5732
5731
  },
5732
+
5733
5733
  // END stop
5734
5734
 
5735
5735
  enabled: function () {
@@ -5740,8 +5740,25 @@ module.exports = function parseContent(options) {
5740
5740
  isSpeaking: function () {
5741
5741
  return window.speechSynthesis.speaking;
5742
5742
  },
5743
- // END is Speaking
5743
+ // END isSpeaking
5744
+
5745
+ isSpoken: function () {
5746
+ if (window.speechSynthesis.speaking) {
5747
+ return chunkCounter;
5748
+ } else {
5749
+ return false;
5750
+ }
5751
+ },
5752
+ // END isSpoken
5744
5753
 
5754
+ isScrolled: function () {
5755
+ if (window.speechSynthesis.speaking) {
5756
+ return lastScrollPosition;
5757
+ } else {
5758
+ return false;
5759
+ }
5760
+ },
5761
+ // END isSpoken
5745
5762
  isPaused: function () {
5746
5763
  return window.speechSynthesis.paused;
5747
5764
  },
@@ -5891,7 +5908,7 @@ module.exports = function parseContent(options) {
5891
5908
  }
5892
5909
  } else {
5893
5910
  if (voices[i].name.includes(voiceUserDefault)) {
5894
- // option.setAttribute('selected', 'selected');
5911
+ // option.setAttribute('selected', 'selected');
5895
5912
  }
5896
5913
  }
5897
5914
  option.setAttribute('data-speak2me-language', voices[i].language);
@@ -5899,7 +5916,7 @@ module.exports = function parseContent(options) {
5899
5916
  }
5900
5917
  return i - skippedVoices;
5901
5918
  },
5902
- // END get Voiuces
5919
+ // END getVoiuces
5903
5920
 
5904
5921
  setVoice: function () {
5905
5922
  // The setVoice function has to have two attributes
@@ -5946,8 +5963,8 @@ module.exports = function parseContent(options) {
5946
5963
  }
5947
5964
  }
5948
5965
  return this;
5949
- } // END set Voice
5950
- }; // END methods
5966
+ } // END setVoice
5967
+ }; // END public methods
5951
5968
 
5952
5969
  // main speak2me method
5953
5970
  //
@@ -5959,7 +5976,7 @@ module.exports = function parseContent(options) {
5959
5976
  } else {
5960
5977
  jQuery.error('Method ' + method + ' does not exist on jQuery.speak2me');
5961
5978
  }
5962
- };
5979
+ }; // END main
5963
5980
  })(jQuery);
5964
5981
 
5965
5982
  /***/ }),