j1-template 2023.7.0 → 2023.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (132) hide show
  1. checksums.yaml +4 -4
  2. data/_includes/themes/j1/modules/searcher/procedures/topsearch.proc +2 -1
  3. data/_includes/themes/j1/procedures/global/create_bs_button.proc +0 -1
  4. data/_includes/themes/j1/procedures/global/create_word_cloud.proc +3 -2
  5. data/_includes/themes/j1/procedures/global/date-german.proc +2 -7
  6. data/_includes/themes/j1/procedures/global/get_category.proc +13 -19
  7. data/_includes/themes/j1/procedures/global/get_category_item.proc +29 -33
  8. data/_includes/themes/j1/procedures/global/get_documents_dir.proc +8 -8
  9. data/_includes/themes/j1/procedures/global/get_page_url.proc +9 -14
  10. data/_includes/themes/j1/procedures/global/select_color.proc +12 -17
  11. data/_includes/themes/j1/procedures/global/select_font_size.proc +31 -35
  12. data/_includes/themes/j1/procedures/global/select_icon_size.proc +38 -40
  13. data/_includes/themes/j1/procedures/global/select_location.proc +56 -59
  14. data/_includes/themes/j1/procedures/global/set_base_vars_folders.proc +2 -4
  15. data/_includes/themes/j1/procedures/global/set_image_block.proc +4 -2
  16. data/_includes/themes/j1/procedures/global/setup.proc +8 -3
  17. data/assets/data/masonry.html +13 -13
  18. data/assets/themes/j1/adapter/js/masterslider.js +2 -1
  19. data/assets/themes/j1/adapter/js/slick.js +13 -10
  20. data/assets/themes/j1/core/css/themes/unolight/bootstrap.css +70 -0
  21. data/assets/themes/j1/core/css/themes/unolight/bootstrap.min.css +1 -1
  22. data/assets/themes/j1/core/js/template.js +1339 -3
  23. data/assets/themes/j1/core/js/template.min.js +7 -7
  24. data/assets/themes/j1/core/js/template.min.js.map +1 -1
  25. data/assets/themes/j1/modules/carousel/css/theme/uno.css +5 -0
  26. data/assets/themes/j1/modules/carousel/css/theme/uno.min.css +1 -1
  27. data/assets/themes/j1/modules/masonry/css/theme/readme +1 -0
  28. data/assets/themes/j1/modules/masterslider/css/theme/uno.css +2 -3
  29. data/assets/themes/j1/modules/masterslider/css/theme/uno.min.css +1 -1
  30. data/assets/themes/j1/modules/slick/lightbox/css/theme/uno.css +13 -2
  31. data/assets/themes/j1/modules/slick/lightbox/css/theme/uno.min.css +1 -1
  32. data/assets/themes/j1/modules/slick/lightbox/js/slick-lightbox.js +373 -347
  33. data/assets/themes/j1/modules/slick/slider/css/theme/uno.css +20 -51
  34. data/assets/themes/j1/modules/slick/slider/css/theme/uno.min.css +2 -2
  35. data/lib/j1/version.rb +1 -1
  36. data/lib/starter_web/Gemfile +2 -2
  37. data/lib/starter_web/README.md +5 -5
  38. data/lib/starter_web/_config.yml +1 -1
  39. data/lib/starter_web/_data/blocks/banner.yml +8 -9
  40. data/lib/starter_web/_data/blocks/footer.yml +3 -3
  41. data/lib/starter_web/_data/modules/masonry.yml +9 -1
  42. data/lib/starter_web/_data/modules/masterslider.yml +69 -116
  43. data/lib/starter_web/_data/modules/navigator_menu.yml +58 -51
  44. data/lib/starter_web/_data/resources.yml +3 -3
  45. data/lib/starter_web/_data/templates/feed.xml +1 -1
  46. data/lib/starter_web/_includes/attributes.asciidoc +1 -0
  47. data/lib/starter_web/_plugins/asciidoctor/callout.rb +2 -2
  48. data/lib/starter_web/_plugins/asciidoctor/masterslider-block.rb +1 -1
  49. data/lib/starter_web/_plugins/asciidoctor/slick-block.rb +1 -1
  50. data/lib/starter_web/_plugins/index/lunr.rb +1 -1
  51. data/lib/starter_web/assets/images/collections/books/biography/a_life_in_questions.jpg +0 -0
  52. data/lib/starter_web/collections/posts/public/featured/_posts/0000-00-00-welcome-to-j1.adoc.erb +5 -5
  53. data/lib/starter_web/index.html +6 -6
  54. data/lib/starter_web/package.json +1 -1
  55. data/lib/starter_web/pages/public/blog/navigator/archive/categoryview.html +0 -1
  56. data/lib/starter_web/pages/public/tools/previewer/preview_bootstrap_theme.adoc +148 -140
  57. data/lib/starter_web/utilsrv/_defaults/package.json +1 -1
  58. data/lib/starter_web/utilsrv/package.json +1 -1
  59. metadata +3 -75
  60. data/assets/themes/j1/modules/carousel/js/carousel.js +0 -1517
  61. data/assets/themes/j1/modules/carousel/js/carousel.min.js +0 -57
  62. data/assets/themes/j1/modules/masonry/css/theme/uno.css +0 -35
  63. data/assets/themes/j1/modules/masonry/css/theme/uno.min.css +0 -15
  64. data/assets/themes/j1/modules/speak2me/LICENSE +0 -21
  65. data/assets/themes/j1/modules/speak2me/js/speak2me.js +0 -947
  66. data/assets/themes/j1/modules/speak2me/js/speak2me.min.js +0 -26
  67. data/lib/starter_web/_data/modules/buymeacoffee.yml +0 -30
  68. data/lib/starter_web/_data/modules/defaults/buymeacoffee.yml +0 -30
  69. data/lib/starter_web/assets/images/modules/masterslider/slider_5/ms-free-food-restaurant-140x80.jpg +0 -0
  70. data/lib/starter_web/assets/images/modules/masterslider/slider_5/ms-free-food-restaurant.jpg +0 -0
  71. data/lib/starter_web/assets/images/modules/masterslider/slider_5/ms-free-food-single-man-140x80.jpg +0 -0
  72. data/lib/starter_web/assets/images/modules/masterslider/slider_5/ms-free-food-single-man.jpg +0 -0
  73. data/lib/starter_web/assets/images/modules/masterslider/slider_5/ms-free-food-single-woman-140x80.jpg +0 -0
  74. data/lib/starter_web/assets/images/modules/masterslider/slider_5/ms-free-food-single-woman.jpg +0 -0
  75. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/attributes.asciidoc +0 -58
  76. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/accordion.asciidoc +0 -34
  77. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/alerts.asciidoc +0 -15
  78. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/badges.asciidoc +0 -9
  79. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/body.asciidoc +0 -14
  80. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/breadcrumbs.asciidoc +0 -14
  81. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/buttons.asciidoc +0 -75
  82. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/cards.asciidoc +0 -22
  83. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/carousel.asciidoc +0 -37
  84. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/close.asciidoc +0 -15
  85. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/code.asciidoc +0 -14
  86. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/color_system.asciidoc +0 -353
  87. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/components.asciidoc +0 -69
  88. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/dropdowns.asciidoc +0 -53
  89. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/figures.asciidoc +0 -5
  90. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/forms.asciidoc +0 -270
  91. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/grid.asciidoc +0 -49
  92. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/links.asciidoc +0 -21
  93. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/list_groups.asciidoc +0 -28
  94. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/modals.asciidoc +0 -43
  95. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/navbar.asciidoc +0 -45
  96. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/navs.asciidoc +0 -28
  97. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/offcanvas.asciidoc +0 -16
  98. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/options.asciidoc +0 -30
  99. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/pagination.asciidoc +0 -40
  100. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/paragraph.asciidoc +0 -5
  101. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/placeholders.asciidoc +0 -5
  102. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/popovers.asciidoc +0 -28
  103. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/position.asciidoc +0 -8
  104. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/progress_bars.asciidoc +0 -12
  105. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/spacing.asciidoc +0 -14
  106. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/spinners.asciidoc +0 -12
  107. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/tables.asciidoc +0 -55
  108. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/thumbnails.asciidoc +0 -9
  109. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/toasts.asciidoc +0 -18
  110. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/tooltips.asciidoc +0 -28
  111. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/typography.asciidoc +0 -115
  112. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/documents/z_index.asciidoc +0 -26
  113. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/tables/_table.asciidoc +0 -9
  114. data/lib/starter_web/pages/public/learn/bs_sass_variables/_includes/tables/accordion.asciidoc +0 -87
  115. data/lib/starter_web/pages/public/learn/bs_sass_variables/bs_sass_variables.adoc +0 -267
  116. data/lib/starter_web/pages/public/learn/core_web_vitals/_includes/attributes.asciidoc +0 -59
  117. data/lib/starter_web/pages/public/learn/core_web_vitals/_includes/documents/100_chapter.asciidoc +0 -541
  118. data/lib/starter_web/pages/public/learn/core_web_vitals/_includes/documents/200_chapter.asciidoc +0 -33
  119. data/lib/starter_web/pages/public/learn/core_web_vitals/_includes/tables/build_command_options.asciidoc +0 -72
  120. data/lib/starter_web/pages/public/learn/core_web_vitals/_includes/tables/files_and_folders.asciidoc +0 -66
  121. data/lib/starter_web/pages/public/learn/core_web_vitals/_includes/tables/global_configuration_options.asciidoc +0 -63
  122. data/lib/starter_web/pages/public/learn/core_web_vitals/_includes/tables/global_variables.asciidoc +0 -26
  123. data/lib/starter_web/pages/public/learn/core_web_vitals/_includes/tables/page_variables.asciidoc +0 -54
  124. data/lib/starter_web/pages/public/learn/core_web_vitals/_includes/tables/serve_command_options.asciidoc +0 -45
  125. data/lib/starter_web/pages/public/learn/core_web_vitals/_includes/tables/site_variables.asciidoc +0 -59
  126. data/lib/starter_web/pages/public/learn/core_web_vitals/core_web_vitals.adoc +0 -447
  127. data/lib/starter_web/pages/public/learn/roundtrip/lunr_search.1.asciidoc +0 -460
  128. data/lib/starter_web/pages/public/manuals/speak2me.adoc +0 -412
  129. data/lib/starter_web/pages/public/tools/cheatsheet/gem.adoc +0 -259
  130. data/lib/starter_web/pages/public/tools/cheatsheet/git.adoc +0 -1462
  131. data/lib/starter_web/pages/public/tools/cheatsheet/j1.adoc +0 -177
  132. data/lib/starter_web/pages/public/tools/cheatsheet/yaml.adoc +0 -522
@@ -1,947 +0,0 @@
1
- /*
2
- # -----------------------------------------------------------------------------
3
- # ~/assets/themes/j1/modules/speak2me/js/speak2me.js
4
- # speak2me v.1.0 implementation (based on Articulate.js) for J1 Theme
5
- #
6
- # Product/Info:
7
- # https://jekyll.one
8
- # https://github.com/acoti/articulate.js/tree/master
9
- #
10
- # Copyright (C) 2023 Juergen Adams
11
- # Copyright (C) 2017 Adam Coti
12
- #
13
- # J1 Theme is licensed under the MIT License.
14
- # See: https://github.com/jekyll-one-org/j1-template/blob/main/LICENSE.md
15
- # Articulate is licensed under the MIT License.
16
- # See: https://github.com/acoti/articulate.js/blob/master/LICENSE
17
- # -----------------------------------------------------------------------------
18
- */
19
-
20
- /* Articulate.js (1.1.0). (C) 2017 Adam Coti.
21
- MIT @license: en.wikipedia.org/wiki/MIT_License
22
- See Github page at: https://github.com/acoti/articulate.js
23
- See Web site at: http://articulate.purefreedom.com
24
- */
25
-
26
- (function($) {
27
- 'use strict';
28
-
29
- var ignoreTagsUser = new Array();
30
- var recognizeTagsUser = new Array();
31
- var replacements = new Array();
32
- var customTags = new Array();
33
- var voices = new Array();
34
-
35
- var rateDefault = 0.9;
36
- var pitchDefault = 1;
37
- var volumeDefault = 0.9;
38
- var rate = rateDefault;
39
- var pitch = pitchDefault;
40
- var volume = volumeDefault;
41
-
42
- var currentTranslation = getCookie('googtrans');
43
-
44
- var voiceUserDefault = 'Google UK English Female';
45
- var voiceChromeDefault = 'Google US English';
46
- var ignoreProvider = 'Microsoft';
47
- var preferredVoice = 'Natural';
48
-
49
- var voiceLanguageGoogleDefault = {
50
- 'de-DE': 'Google Deutsch',
51
- 'en-US': 'Google US English',
52
- 'en-GB': 'Google UK English Female',
53
- 'es-ES': 'Google español',
54
- 'fr-FR': 'Google français',
55
- // 'hi-IN': 'Google हिन्दी',
56
- // 'id-ID': 'Google Bahasa Indonesia',
57
- 'it-IT': 'Google italiano',
58
- // 'jp-JP': 'Google 日本語',
59
- // 'ko-KR': 'Google 한국의',
60
- 'nl-NL': 'Google Nederlands',
61
- 'pl-PL': 'Google polski',
62
- // 'pt-BR': 'Google português do Brasil',
63
- 'pt-PT': 'Google português do Brasil',
64
- // 'ru-RU': 'Google русский',
65
- // 'zh-CN': 'Google 普通话(中国大陆)',
66
- };
67
-
68
- var voiceLanguageMicrosoftDefault = {
69
- 'sq-AL': 'Microsoft Anila Online (Natural) - Albanian (Albania)',
70
- 'ar-EG': 'Microsoft Salma Online (Natural) - Arabic (Egypt)',
71
- 'bg-BG': 'Microsoft Kalina Online (Natural) - Bulgarian (Bulgaria)',
72
- 'zh-CN': 'Microsoft Xiaoxiao Online (Natural) - Chinese (Mainland)',
73
- 'hr-HR': 'Microsoft Gabrijela Online (Natural) - Croatian (Croatia)',
74
- 'cs-CZ': 'Microsoft Antonin Online (Natural) - Czech (Czech)',
75
- 'da-DK': 'Microsoft Christel Online (Natural) - Danish (Denmark)',
76
- 'nl-NL': 'Microsoft Colette Online (Natural) - Dutch (Netherlands)',
77
- 'en-GB': 'Microsoft Libby Online (Natural) - English (United Kingdom)',
78
- 'en-US': 'Microsoft Aria Online (Natural) - English (United States)',
79
- 'et-EE': 'Microsoft Anu Online (Natural) - Estonian (Estonia)',
80
- 'fi-FI': 'Microsoft Noora Online (Natural) - Finnish (Finland)',
81
- 'fr-FR': 'Microsoft Denise Online (Natural) - French (France)',
82
- 'ka-GE': 'Microsoft Giorgi Online (Natural) - Georgian (Georgia)',
83
- 'de-DE': 'Microsoft Katja Online (Natural) - German (Germany)',
84
- 'el-GR': 'Microsoft Athina Online (Natural) - Greek (Greece)',
85
- 'he-IL': 'Microsoft Avri Online (Natural) - Hebrew (Israel)',
86
- 'hi-IN': 'Microsoft Madhur Online (Natural) - Hindi (India)',
87
- 'hu-HU': 'Microsoft Noemi Online (Natural) - Hungarian (Hungary)',
88
- 'it-IT': 'Microsoft Elsa Online (Natural) - Italian (Italy)',
89
- 'ja-JP': 'Microsoft Nanami Online (Natural) - Japanese (Japan)',
90
- }
91
-
92
- var isEdge = /Edg/i.test( navigator.userAgent );
93
- var chrome = /chrome/i.test( navigator.userAgent );
94
- var isChrome = ((chrome) && (!isEdge));
95
-
96
- var rateUserDefault;
97
- var pitchUserDefault;
98
- var volumeUserDefault;
99
- var currentLanguage;
100
- var voiceLanguageDefault;
101
- var chunkCounter = 0;
102
- var chunkCounterMax;
103
- var userStoppedSpeaking = false;
104
- var currentSection;
105
- // var chunksEnd = false;
106
-
107
-
108
- // -------------------------------------------------------------------------
109
- // Internal functions
110
- // -------------------------------------------------------------------------
111
- //
112
- function getCookie(name) {
113
- var nameEQ = name + '=';
114
- var ca = document.cookie.split(';');
115
- for (var i = 0; i < ca.length; i++) {
116
- var c = ca[i];
117
- while (c.charAt(0) === ' ') {
118
- c = c.substring(1, c.length);
119
- }
120
- if (c.indexOf(nameEQ) === 0) {
121
- var value = c.substring(nameEQ.length, c.length);
122
- return value;
123
- }
124
- }
125
- return undefined;
126
- }
127
-
128
- function voiceTag(prepend,append) {
129
- this.prepend = prepend;
130
- this.append = append;
131
- }
132
-
133
- function voiceObj(name,language) {
134
- this.name = name;
135
- this.language = language;
136
- }
137
-
138
- // This populates the "voices" array with objects that represent the
139
- // available voices in the current browser. Each object has two
140
- // properties: name and language. It is loaded asynchronously in
141
- // deference to Chrome.
142
- //
143
- function populateVoiceList() {
144
- var systemVoices = speechSynthesis.getVoices();
145
- for(var i = 0; i < systemVoices.length ; i++) {
146
- voices.push(new voiceObj(systemVoices[i].name,systemVoices[i].lang));
147
- }
148
- }
149
-
150
- populateVoiceList();
151
- if (typeof speechSynthesis !== 'undefined' && speechSynthesis.onvoiceschanged !== undefined) {
152
- speechSynthesis.onvoiceschanged = populateVoiceList;
153
- }
154
-
155
- // After checking for compatability, define the utterance object and
156
- // then cancel the speech immediately even though nothing is yet spoken.
157
- // This is to fix a quirk in Windows Chrome.
158
- //
159
- if ('speechSynthesis' in window) {
160
- var speech = new SpeechSynthesisUtterance();
161
- window.speechSynthesis.cancel();
162
- }
163
-
164
- if ( currentTranslation === undefined ) {
165
- currentLanguage = 'en-US'
166
- } else {
167
- var translation = currentTranslation.split('/');
168
- if ( translation[2] == 'en') {
169
- currentLanguage = 'en-GB';
170
- } else if ( translation[2].includes('ar') ) {
171
- currentLanguage = 'ar-EG';
172
- } else if ( translation[2].includes('cs') ) {
173
- currentLanguage = 'cs-CZ';
174
- } else if ( translation[2].includes('da') ) {
175
- currentLanguage = 'da-DK';
176
- } else if ( translation[2].includes('en') ) {
177
- currentLanguage = 'en-UK';
178
- } else if ( translation[2].includes('et') ) {
179
- currentLanguage = 'et-EE';
180
- } else if ( translation[2].includes('ka') ) {
181
- currentLanguage = 'ka-GE';
182
- } else if ( translation[2].includes('el') ) {
183
- currentLanguage = 'el-GR';
184
- } else if ( translation[2].includes('iw') ) {
185
- currentLanguage = 'he-IL';
186
- } else if ( translation[2].includes('hi') ) {
187
- currentLanguage = 'hi-IN';
188
- } else if ( translation[2].includes('ja') ) {
189
- currentLanguage = 'ja-JP';
190
- } else if ( translation[2].includes('zh') ) {
191
- currentLanguage = 'zh-CN';
192
- } else {
193
- currentLanguage = translation[2] + '-' + translation[2].toUpperCase();
194
- }
195
- }
196
-
197
- if (isChrome) {
198
- var voiceLanguageDefault = voiceLanguageGoogleDefault[currentLanguage];
199
- }
200
-
201
- if (isEdge) {
202
- var voiceLanguageDefault = voiceLanguageMicrosoftDefault[currentLanguage];
203
- }
204
-
205
- // -------------------------------------------------------------------------
206
- // Public functions
207
- // -------------------------------------------------------------------------
208
- //
209
- var methods = {
210
-
211
- speak: function(options) {
212
- var opts = $.extend( {}, $.fn.speak2me.defaults, options );
213
- var toSpeak = '';
214
- var obj, processed, finished;
215
- var voiceTags = new Array();
216
- var ignoreTags;
217
- // var chunksEnd = false;
218
-
219
- // Default values
220
- //
221
- voiceTags['a'] = new voiceTag('clicking the link,', '');
222
- voiceTags['q'] = new voiceTag(',', '');
223
- voiceTags['ol'] = new voiceTag('Start of list.', 'End of list.');
224
- voiceTags['ul'] = new voiceTag('Start of list.', 'End of list.');
225
- // voiceTags["li"] = new voiceTag(',', ',');
226
- voiceTags['dl'] = new voiceTag('Start of list.', 'End of list.');
227
- voiceTags['dt'] = new voiceTag('', ', ');
228
- voiceTags['img'] = new voiceTag('There\'s an embedded image with the description,', '');
229
- voiceTags['table'] = new voiceTag('There\'s an embedded table with the caption,', 'Note, table contents are not spoken, ');
230
- // voiceTags["tbody"] = new voiceTag(', ', ',');
231
- voiceTags['figure'] = new voiceTag('There\'s an embedded figure with the caption,', '');
232
- voiceTags['blockquote'] = new voiceTag('Blockquote start.', 'Blockquote end.');
233
-
234
- // ignoreTags = ['audio','button','canvas','code','del','dialog','dl','embed','form','head','iframe','meter','nav','noscript','object','s','script','select','style','textarea','video'];
235
- ignoreTags = ['audio','button','canvas','code','del','dialog','embed','form','head','iframe','meter','nav','noscript','object','s','script','select','style','textarea','video'];
236
-
237
- // Check to see if the browser supports the functionality.
238
- //
239
- if (!('speechSynthesis' in window)) {
240
- alert('Sorry, this browser does not support the Web Speech API.');
241
- return
242
- };
243
-
244
- // If something is currently being spoken, ignore new voice
245
- // request. Otherwise it would be queued, which is doable if
246
- // someone wanted that, but not what I wanted.
247
- //
248
- if (window.speechSynthesis.speaking) {
249
- return
250
- };
251
-
252
- // Cycle through all the elements in the original jQuery
253
- // selector, process and clean them one at a time, and
254
- // continually append it to the variable "toSpeak".
255
- //
256
- this.each(function() {
257
- obj = $(this).clone(); // clone the DOM node and its descendants of what the user wants spoken
258
- processed = processDOMelements(obj); // process and manipulate DOM tree of this clone
259
- processed = jQuery(processed).html(); // convert the result of all that to a string
260
- finished = cleanDOMelements(processed); // do some text manipulation
261
- // toSpeak = toSpeak + ' ' + finished; // add it to what will ultimately be spoken after cycling through selectors
262
- toSpeak = finished;
263
- });
264
-
265
- // Check if users have set their own rate/pitch/volume
266
- // defaults, otherwise use defaults
267
- //
268
- if (rateUserDefault !== undefined) {
269
- rate = rateUserDefault;
270
- } else {
271
- rate = rateDefault;
272
- }
273
- if (pitchUserDefault !== undefined) {
274
- pitch = pitchUserDefault;
275
- } else {
276
- pitch = pitchDefault;
277
- }
278
- if (volumeUserDefault !== undefined) {
279
- volume = volumeUserDefault;
280
- } else {
281
- volume = volumeDefault;
282
- }
283
-
284
- // jadams
285
- // To debug, uncomment the following to see exactly what's
286
- // about to be spoken.
287
- // console.log(toSpeak)
288
-
289
- // jadams
290
- // This is where the magic happens. Well, not magic, but at
291
- // least we can finally hear something. After the line that
292
- // fixes the Windows Chrome quirk, the custom voice is set
293
- // if one has been chosen.
294
- //
295
- speech = new SpeechSynthesisUtterance();
296
- // speech.text = toSpeak;
297
- speech.rate = rate;
298
- speech.pitch = pitch;
299
- speech.volume = volume;
300
- speech.voice = undefined;
301
-
302
- // jadams
303
- if (isChrome) {
304
- speech.voice = speechSynthesis.getVoices().filter(function(voice) { return voice.name == voiceLanguageDefault; })[0];
305
- // speech.voice = speechSynthesis.getVoices().filter(function(voice) { return voice.name == voiceChromeDefault; })[0];
306
- };
307
-
308
- // jadams
309
- if (isEdge) {
310
- speech.voice = speechSynthesis.getVoices().filter(function(voice) { return voice.name == voiceLanguageDefault; })[0];
311
- };
312
-
313
- // jadams
314
- processTextChunks(speech, toSpeak);
315
-
316
- // jadams
317
- function splitTextIntoChunks(text, chunkSize) {
318
- const chunks = text.split(/[.!?]/);
319
-
320
- // cleanup chunks
321
- //
322
- chunks.forEach((chunk, index) => {
323
- chunks[index] = chunk.replace(/^\s+|\s+$/g, '');
324
- chunks[index] = chunks[index] + '. ';
325
- });
326
-
327
- return chunks;
328
- }
329
-
330
- // jadams
331
- // function splitSectionIntoSentences(section) {
332
- // const chunks = section.innerHTML.split(/[.!?]/);
333
- //
334
- // // cleanup chunks
335
- // //
336
- // chunks.forEach((chunk, index) => {
337
- // if (chunks[index] !== '') {
338
- // chunks[index] = chunks[index] + '.';
339
- // // chunks[index] = chunks[index].wrap('<span class="new"/>');
340
- // }
341
- //
342
- // // chunks[index] = chunk.replace(/^\s+|\s+$/g, '');
343
- // // chunks[index] = chunk.replace(/^\s+|\s+$/g, '');
344
- // });
345
- //
346
- // return chunks;
347
- // }
348
-
349
- // jadams
350
- // Funktion zur sequenziellen Verarbeitung der Textkette
351
- //
352
- function processTextChunks(speaker, chunks) {
353
- const synth = window.speechSynthesis;
354
-
355
- speaker.text = chunks[chunkCounter];
356
- synth.speak(speaker);
357
-
358
- speaker.addEventListener('start', (event) => {
359
- // console.log('speak2me start:', event);
360
- $('.mdib-speaker').addClass('mdib-spin');
361
- });
362
-
363
- speaker.addEventListener('end', function (event) {
364
- chunkCounter ++;
365
- // console.log('speak2me end:', chunkCounter);
366
- $(currentSection).removeClass('speak-highlighted');
367
- });
368
-
369
- // jadams
370
- var speechMonitor = setInterval(function () {
371
- // chunkCounterMax = 4;
372
- if (! synth.speaking ) {
373
- if (chunkCounter == chunkCounterMax || userStoppedSpeaking ) {
374
- chunkCounter = 0;
375
- userStoppedSpeaking = false;
376
-
377
- synth.cancel();
378
- $('.mdib-speaker').removeClass('mdib-spin');
379
- clearInterval(speechMonitor);
380
- } else {
381
- speaker.text = chunks[chunkCounter];
382
- var sectionText = speaker.text.substr(0, 20);
383
-
384
- currentSection = $('#content').find("p:contains('" + sectionText + "')")[0];
385
- $(currentSection).addClass('speak-highlighted');
386
-
387
- synth.speak(speaker);
388
- }
389
- }
390
- }, 500); // END speechMonitor
391
-
392
- } // END processTextChunks
393
-
394
- // jadams
395
- function processDOMelements(clone) {
396
- var copy, content, appended, prepend;
397
-
398
- // Remove tags from the "ignoreTags" array because the
399
- // user called "speak2me('recognize')" and said he/she
400
- // doesn't want some tags un-spoken. Double negative there,
401
- // but it does make sense.
402
- //
403
- if (recognizeTagsUser.length > 0) {
404
- for (var prop in recognizeTagsUser) {
405
- var index = ignoreTags.indexOf(recognizeTagsUser[prop]);
406
- if (index > -1) {
407
- ignoreTags.splice(index, 1);
408
- }
409
- };
410
- };
411
-
412
- // Remove DOM objects from those listed in the "ignoreTags"
413
- // array now that the user has specified which ones,
414
- // if any, he/she wants to keep
415
- //
416
- for (var prop in ignoreTags) {
417
- jQuery(clone).find(ignoreTags[prop]).addBack(ignoreTags[prop]).not('[data-speak2me-recognize]').each(function() {
418
- jQuery(this).html('');
419
- });
420
- };
421
-
422
- // Remove DOM objects specified in the "ignoreTagsUser"
423
- // array that the user specified when calling "speak2me('ignore')".
424
- //
425
- if (ignoreTagsUser.length > 0) {
426
- for (var prop in ignoreTagsUser) {
427
- jQuery(clone).find(ignoreTagsUser[prop]).addBack(ignoreTagsUser[prop]).not('[data-speak2me-recognize]').each(function() {
428
- jQuery(this).html('');
429
- });
430
- };
431
- };
432
-
433
- // Remove DOM objects specified in the HTML with
434
- // "data-speak2me-ignore"
435
- //
436
- jQuery(clone).find('[data-speak2me-ignore]').addBack('[data-speak2me-ignore]').each(function() {
437
- jQuery(this).html('');
438
- });
439
-
440
- // jadams
441
- // Remove DOM objects specified in the HTML by class "speak2me-ignore"
442
- //
443
- jQuery(clone).find('.speak2me-ignore').addBack('[data-speak2me-ignore]').each(function() {
444
- // jQuery(this).html("The following element in the article is skipped to be spoken. ");
445
- jQuery(this).html('');
446
- });
447
-
448
- // Search for prepend data specified in the HTML
449
- // with "data-speak2me-prepend"
450
- jQuery(clone).find('[data-speak2me-prepend]').addBack('[data-speak2me-prepend]').each(function() {
451
- copy = jQuery(this).data('speak2me-prepend');
452
- jQuery(this).prepend(copy + ' ');
453
- });
454
-
455
- // Search for append data specified in the HTML
456
- // with "data-speak2me-append"
457
- //
458
- jQuery(clone).find('[data-speak2me-append]').addBack('[data-speak2me-append]').each(function() {
459
- copy = jQuery(this).data('speak2me-append');
460
- jQuery(this).append(' ' + copy);
461
- });
462
-
463
- // jadams
464
- // Search for tags to prepend and append specified by
465
- // the "voiceTags" array.
466
- //
467
- var count = 0;
468
- for (var tag in voiceTags) {
469
- // count++
470
- // if (count <= 4) {
471
- jQuery(clone).find(tag).each(function() {
472
- if (customTags[tag]) {
473
- jQuery(this).prepend(customTags[tag].prepend + ' ');
474
- jQuery(this).append(' ' + customTags[tag].append);
475
- } else {
476
- jQuery(this).prepend(voiceTags[tag].prepend + ' ');
477
- jQuery(this).append(' ' + voiceTags[tag].append);
478
- };
479
- });
480
- // };
481
- };
482
-
483
- // Search for <h1> through <h6> and <li> and <br> to add
484
- // a pause at the end of those tags. This is done
485
- // because these tags require a pause, but often don't
486
- // have a comma or period at the end of their text.
487
- //
488
- jQuery(clone).find('h1,h2,h3,h4,h5,h6,li,p').addBack('h1,h2,h3,h4,h5,h6,li,p').each(function() {
489
- jQuery(this).append('. ');
490
- });
491
- jQuery(clone).find('br').each(function() {
492
- jQuery(this).after(', ');
493
- });
494
-
495
- // Search for <figure>, check for <figcaption>, insert
496
- // that text if it exists and then remove the whole DOM object
497
- //
498
- jQuery(clone).find('figure').addBack('figure').each(function() {
499
- copy = jQuery(this).find('figcaption').html();
500
- if (customTags['figure']) {
501
- prepend = customTags['figure'].prepend
502
- }
503
- else {
504
- prepend = voiceTags['figure'].prepend
505
- }
506
- if ((copy != undefined) && (copy !== '')) {
507
- jQuery('<div>' + prepend + ' ' + copy + '.</div>').insertBefore(this);
508
- }
509
- jQuery(this).remove();
510
- });
511
-
512
- // Search for <image>, check for ALT attribute, insert that
513
- // text if it exists and then remove the whole DOM object.
514
- // Had to make adjustments for nesting in <picture> tags.
515
- //
516
- jQuery(clone).find('img').addBack('img').each(function() {
517
- copy = jQuery(this).attr('alt');
518
- var parent = jQuery(this).parent();
519
- var parentName = parent.get(0).tagName;
520
- if (customTags['img']) {
521
- prepend = customTags['img'].prepend
522
- }
523
- else {
524
- prepend = voiceTags['img'].prepend
525
- };
526
- if ((copy !== undefined) && (copy != '')) {
527
- if (parentName == 'PICTURE') {
528
- var par
529
- jQuery('<div>' + prepend + ' ' + copy + '.</div>').insertBefore(parent);
530
- } else {
531
- jQuery('<div>' + prepend + ' ' + copy + '.</div>').insertBefore(this);
532
- }
533
- };
534
- jQuery(this).remove();
535
- });
536
-
537
- // jadams
538
- // Search for <table>, check for <caption>, insert that
539
- // text if it exists and then remove the whole DOM object
540
- //
541
- jQuery(clone).find('table').addBack('table').each(function() {
542
- copy = jQuery(this).find('caption').text();
543
- // content = jQuery(this).find("tbody");
544
-
545
- if (customTags['table']) {
546
- prepend = customTags['table'].prepend
547
- appended = customTags['table'].append;
548
- }
549
- else {
550
- prepend = voiceTags['table'].prepend
551
- appended = voiceTags['table'].append;
552
- }
553
-
554
- if ((copy !== undefined) && (copy != '')) {
555
- jQuery('<div>' + prepend + ' ' + copy + '.</div>').insertBefore(this);
556
- jQuery('<div>' + appended + ' ' + '.</div>').insertBefore(this);
557
- }
558
-
559
- // TODO: processing the table contents
560
- //
561
- // if ((content !== undefined) && (content != '')) {
562
- // jQuery('<div>' + ' ' + content + "</div>").insertBefore(this);
563
- // }
564
-
565
- jQuery(this).remove();
566
- });
567
-
568
- // Search for DOM object to be replaced specified in
569
- // the HTML with "data-speak2me-swap"
570
- //
571
- jQuery(clone).find('[data-speak2me-swap]').addBack('[data-speak2me-swap]').each(function() {
572
- copy = jQuery(this).data('speak2me-swap');
573
- jQuery(this).text(copy);
574
- });
575
-
576
- // Search for DOM object to spelled out specified in
577
- // the HTML with "data-speak2me-spell".
578
- // I find this function fun if, admittedly, not too practical.
579
- //
580
- jQuery(clone).find('[data-speak2me-spell]').addBack('[data-speak2me-spell]').each(function() {
581
- copy = jQuery(this).text();
582
- copy = copy.split('').join(' ');
583
- jQuery(this).text(copy);
584
- });
585
- return clone;
586
- }
587
-
588
- // jadams
589
- function cleanDOMelements(final) {
590
- var start,ended,speak,part1,part2,final;
591
-
592
- // Search for <speak2me> in comments, copy the text,
593
- // place it outside the comment, and then splice together
594
- // "final" string again, which omits the comment.
595
- //
596
- while (final.indexOf('<!-- <speak2me>') != -1) {
597
- start = final.indexOf('<!-- <speak2me>');
598
- ended = final.indexOf('</speak2me> -->', start);
599
- if (ended == -1) { break; }
600
- speak = final.substring(start + 17, ended);
601
- part1 = final.substring(0, start);
602
- part2 = final.substring(ended + 17);
603
- final = part1 + ' ' + speak + ' ' + part2;
604
- };
605
-
606
- // Strip out remaining comments.
607
- //
608
- final = final.replace(/<!--[\s\S]*?-->/g, '');
609
-
610
- // Strip out remaining HTML tags
611
- //
612
- final = final.replace(/(<([^>]+)>)/ig, '');
613
-
614
- // Replace a string of characters with another as specified
615
- // by "speak2me('replace')".
616
- //
617
- var len = replacements.length;
618
- var i = 0;
619
- var old, rep;
620
- while (i < len) {
621
- old = replacements[i];
622
- old = old.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
623
- rep = replacements[i + 1] + ' ';
624
- var regexp = new RegExp(old, 'gi');
625
- var final = final.replace(regexp, rep);
626
- i = i + 2;
627
- };
628
-
629
- // Replace double smart quotes with proper text, same as what
630
- // was done previously with <q>
631
- //
632
- if (customTags['q']) {
633
- final = final.replace(/“/g, customTags['q'].prepend + ' ');
634
- final = final.replace(/”/g, ' ' + customTags['q'].append);
635
- } else {
636
- final = final.replace(/“/g, voiceTags['q'].prepend + ' ');
637
- final = final.replace(/”/g, ' ' + voiceTags['q'].append);
638
- }
639
-
640
- // jadams
641
- // Replace colons ':' with a pause since
642
- // the browser doesn't do so when reading.
643
- //
644
- final = final.replace(/:/g, ', ');
645
-
646
- // jadams
647
- // Replace empty lines
648
- //
649
- final = final.replace(/^$/g, '\n');
650
- final = final.replace(/^\s+$/g, '\n');
651
-
652
- // jadams
653
- // Replace single full stops in line ' . ' or '. '
654
- //
655
- final = final.replace(/\s+\.\s+/g, '\n');
656
- final = final.replace(/\s+\.\s+$/g, '\n');
657
-
658
- // jadams
659
- // Replace strange double full stops '..'
660
- //
661
- final = final.replace(/\.\./g, '.');
662
-
663
- // jadams
664
- // Replace the abbreviation '.e.g.'or ',.e.g.,'
665
- //
666
- final = final.replace(/\se\.g\.\s/g, ' for example, ');
667
- final = final.replace(/\,\s+\.g\.\s+\,/g, ' for example, ');
668
-
669
- // jadams
670
- // Replace question and exclamation (?|!) marks
671
- //
672
- final = final.replace(/[\!\?]/g, ', ');
673
-
674
- // Replace em-dashes and double-dashes with a pause since
675
- // the browser doesn't do so when reading.
676
- //
677
- final = final.replace(/—/g, ', ');
678
- final = final.replace(/--/g, ', ');
679
-
680
- // When read from the DOM, a few special characters
681
- // (&amp; for example) display as their hex codes
682
- // rather than resolving into their actual character
683
- //
684
- var txt = document.createElement('textarea');
685
- txt.innerHTML = final;
686
- final = txt.value;
687
-
688
- // Strip out new line characters and carriage returns,
689
- // which cause unwanted pauses.
690
- //
691
- final = final.replace(/(\r\n|\n|\r)/gm, '');
692
-
693
- // Strip out multiple spaces and periods and commas
694
- // for neatness more than anything else since
695
- // none of this will affect the speech. But it helps when
696
- // checking progress in the console.
697
- //
698
- final = final.replace(/ +/g, ' ');
699
- final = final.replace(/\.\./g, '.');
700
- final = final.replace(/,,/g, ',');
701
- final = final.replace(/ ,/g, ',');
702
- final = final.replace(/^\s+|\s+$/g, '');
703
-
704
- // final = final.replace(/^\s+|\s+$/g,'\n');
705
- // final = final.replace(/\. /g, '. \n');
706
-
707
- // Definiere die Größe der Abschnitte
708
- const chunkSize = 100;
709
-
710
- // Teile den Text in Abschnitte auf
711
- const textChunks = splitTextIntoChunks(final, chunkSize);
712
- chunkCounterMax = textChunks.length;
713
-
714
- // return final;
715
- return textChunks;
716
- }
717
-
718
- // return the SpeechSynthesisUtterance object to be used
719
- return speech;
720
- },
721
-
722
- pause: function() {
723
- window.speechSynthesis.pause();
724
- return this;
725
- },
726
-
727
- resume: function() {
728
- window.speechSynthesis.resume();
729
- return this;
730
- },
731
-
732
- // jadams
733
- stop: function() {
734
- window.speechSynthesis.cancel();
735
- userStoppedSpeaking = true;
736
- return this;
737
- },
738
-
739
- enabled: function() {
740
- return ('speechSynthesis' in window);
741
- },
742
-
743
- isSpeaking: function() {
744
- return (window.speechSynthesis.speaking);
745
- },
746
-
747
- isPaused: function() {
748
- return (window.speechSynthesis.paused);
749
- },
750
-
751
- rate: function() {
752
- var num = arguments[0];
753
- if ((num >= 0.1) && (num <= 10)) {
754
- rateUserDefault = num;
755
- } else if (num === undefined) {
756
- rateUserDefault = void 0;
757
- rate = rateDefault;
758
- };
759
- return this;
760
- },
761
-
762
- pitch: function() {
763
- var num = arguments[0];
764
- if ((num >= 0.1) && (num <= 2)) {
765
- pitchUserDefault = num;
766
- } else if (num === undefined) {
767
- pitchUserDefault = void 0;
768
- pitch = pitchDefault;
769
- };
770
- return this;
771
- },
772
-
773
- volume: function() {
774
- var num = arguments[0];
775
- if ((num >= 0) && (num <= 1)) {
776
- volumeUserDefault = num;
777
- } else if (num === undefined) {
778
- volumeUserDefault = void 0;
779
- volume = volumeDefault;
780
- };
781
- return this;
782
- },
783
-
784
- ignore: function() {
785
- var len = arguments.length;
786
- ignoreTagsUser.length = 0;
787
- while (len > 0) {
788
- len--;
789
- ignoreTagsUser.push(arguments[len]);
790
- };
791
- return this;
792
- },
793
-
794
- recognize: function() {
795
- var len = arguments.length;
796
- recognizeTagsUser.length = 0;
797
- while (len > 0) {
798
- len--;
799
- recognizeTagsUser.push(arguments[len]);
800
- };
801
- return this;
802
- },
803
-
804
- replace: function() {
805
- var len = arguments.length;
806
- replacements.length = 0;
807
- var i = 0;
808
- while (i < len) {
809
- replacements.push(arguments[i], arguments[i + 1]);
810
- i = i + 2;
811
- if ((len - i) == 1) { break; };
812
- };
813
- return this;
814
- },
815
-
816
- customize: function() {
817
- var len = arguments.length;
818
- if (len == 0) {
819
- customTags = [];
820
- };
821
- if (len == 2) {
822
- if (['img','table','figure'].indexOf(arguments[0]) == -1) { console.log("Error: When customizing, tag indicated must be either 'img', 'table', or 'figure'."); return; }
823
- customTags[arguments[0].toString()] = new voiceTag(arguments[1].toString());
824
- };
825
- if (len == 3) {
826
- if (['q',"ol","ul","blockquote"].indexOf(arguments[0]) == -1) { console.log("Error: When customizing, tag indicated must be either 'q', 'ol', 'ul' or 'blockquote'."); return; }
827
- customTags[arguments[0].toString()] = new voiceTag(arguments[1].toString(), arguments[2].toString());
828
- };
829
- return this;
830
- },
831
-
832
- getVoices: function() {
833
- // If no arguments, then the user has requested the array of
834
- // voices populated earlier.
835
- //
836
- if (arguments.length == 0) {
837
- return voices;
838
- };
839
- // If there's another argument, we'll assume it's a jQuery
840
- // selector designating where to put the dropdown menu.
841
- // And if there's a third argument, that will be custom text
842
- // for the dropdown menu.
843
- // Then we'll create a dropdown menu with the voice names and,
844
- //in parenthesis, the language code.
845
- //
846
- var obj = jQuery(arguments[0]);
847
- var selectionTxt = 'Choose a voice';
848
-
849
- if (arguments[1] !== undefined) {
850
- selectionTxt = arguments[1];
851
- }
852
-
853
- obj.append(jQuery("<select id='voiceSelect' name='voiceSelect'><option value='none'>" + selectionTxt + "</option></select>"));
854
-
855
- // jadams
856
- var skippedVoices = 0;
857
- for (var i = 0; i < voices.length ; i++) {
858
- if (isChrome && voices[i].name.includes(ignoreProvider)) {
859
- skippedVoices++;
860
- continue;
861
- }
862
- if (isEdge && !voices[i].name.includes('Natural')) {
863
- skippedVoices++;
864
- continue;
865
- }
866
- var option = document.createElement('option');
867
- option.textContent = voices[i].name + ' (' + voices[i].language + ')';
868
- option.setAttribute('value', voices[i].name);
869
-
870
- // set used voice as 'selected'
871
- if (voiceLanguageDefault !== undefined) {
872
- if ( voices[i].name === voiceLanguageDefault ) {
873
- option.setAttribute('selected', 'selected');
874
- }
875
- } else {
876
- if ( voices[i].name.includes(voiceUserDefault) ) {
877
- // option.setAttribute('selected', 'selected');
878
- }
879
- }
880
-
881
- option.setAttribute('data-speak2me-language', voices[i].language);
882
- obj.find('select').append(option);
883
- }
884
-
885
- // jadams
886
- return i - skippedVoices;
887
- },
888
-
889
- setVoice: function() {
890
- // The setVoice function has to have two attributes
891
- // if not, exit the function.
892
- //
893
- if (arguments.length < 2) {
894
- return this
895
- }
896
- var requestedVoice, requestedLanguage;
897
-
898
- // User wants to change the voice directly. If that name indeed
899
- // exists, update the "voiceUserDefault" variable.
900
- //
901
- if (arguments[0] == 'name') {
902
- requestedVoice = arguments[1];
903
- for (var i = 0; i < voices.length; i++) {
904
- if (voices[i].name == requestedVoice) {
905
- voiceUserDefault = requestedVoice;
906
- };
907
- };
908
- };
909
-
910
- // User wants to change the voice by only specifying the
911
- // first two characters of the language code. Case insensitive.
912
- //
913
- if (arguments[0] == 'language') {
914
- requestedLanguage = arguments[1].toUpperCase();
915
- if (requestedLanguage.length == 2) {
916
- for (var i = 0; i < voices.length; i++) {
917
- if (voices[i].language.substring(0,2).toUpperCase() == requestedLanguage) {
918
- voiceUserDefault = voices[i].name;
919
- break
920
- };
921
- };
922
- } else {
923
- // User wants to change the voice by specifying the
924
- // complete language code.
925
- for (var i = 0; i < voices.length; i++) {
926
- if (voices[i].language == requestedLanguage) {
927
- voiceUserDefault = voices[i].name;
928
- break
929
- };
930
- };
931
- }
932
- };
933
- return this;
934
- },
935
- };
936
-
937
- $.fn.speak2me = function(method) {
938
- if (methods[method]) {
939
- return methods[method].apply( this, Array.prototype.slice.call(arguments, 1));
940
- } else if (typeof method === 'object' || ! method) {
941
- return methods.speak.apply(this, arguments);
942
- } else {
943
- jQuery.error('Method ' + method + ' does not exist on jQuery.speak2me');
944
- }
945
- };
946
-
947
- }(jQuery));