Skip to content

Commit

Permalink
Merge pull request #1453 from Eruvaer74/develop
Browse files Browse the repository at this point in the history
New Plugin: Speech recognition
  • Loading branch information
Alex-D authored Jan 29, 2025
2 parents 7d56742 + e8a5f53 commit bf9bf2f
Show file tree
Hide file tree
Showing 6 changed files with 358 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/demos/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ <h1 class="documentation-title">
<li><a href="./plugins/resizimg.html">Resizimg</a></li>
<li><a href="./plugins/ruby.html">Ruby</a></li>
<li><a href="./plugins/specialchars.html">Special chars</a></li>
<li><a href="./plugins/speechrecognition.html">Speech recognition</a></li>
<li><a href="./plugins/table.html">Table</a></li>
<li><a href="./plugins/template.html">Template</a></li>
<li><a href="./plugins/upload.html">Upload</a></li>
Expand Down
87 changes: 87 additions & 0 deletions docs/demos/plugins/speechrecognition.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Speech recognition plugin | Trumbowyg</title>
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="../../css/main.css">
</head>
<body class="documentation-body">
<div class="main main-demo-inner">
<section class="wrapper section">
<h2 class="section-title">Speech recognition plugin</h2>

<div class="feature">
<h3>Basic usage</h3>
<p>
This plugins allow you to enter text via speech recognition in Trumbowyg. Suddenly it does not work with Firefox which has not implemented the Web Speech API yet.
</p>

<a href="../../documentation/plugins/#plugin-speechrecognition" class="button button-demo">Read speech recognition plugin documentation</a>

<div id="editor"></div>

<h4>The code</h4>
<pre><code class="js-code-to-eval javascript">
$('#editor')
.trumbowyg({
btns: [
['speechrecognition']
]
});
</code></pre>
</div>

<div class="feature">
<h3>Language setting</h3>

<div id="editor-settings-lang"></div>

<h4>The code</h4>
<pre><code class="js-code-to-eval javascript">
$('#editor-settings-lang')
.trumbowyg({
btns: [
['speechrecognition']
],
plugins: {
speechrecognition: {
lang: 'de-DE'
}
}
});
</code></pre>
</div>

<div class="feature">
<h3>Setup</h3>

<h4>In head tag</h4>
<pre><code class="html loading-head">
</code></pre>
<h4>At the end of body</h4>
<pre><code class="html loading-body">
&lt;!-- Import jQuery -->
&lt;script src="//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js">&lt;/script>
&lt;script>window.jQuery || document.write('&lt;script src="js/vendor/jquery-3.3.1.min.js">&lt;\/script>')&lt;/script>
</code></pre>
</div>
</section>
</div>


<!-- Import jQuery -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="../../js/vendor/jquery-3.3.1.min.js"><\/script>')</script>

<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->
<script src="../js/loader.js"></script>
<script>
loadStyle('dist/ui/trumbowyg.min.css');
loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');
loadScript('dist/plugins/speechrecognition/trumbowyg.speechrecognition.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');
</script>
<script src="../js/runExampleCode.js"></script>
<script src="../js/highlight.js"></script>
</body>
</html>
60 changes: 60 additions & 0 deletions docs/documentation/plugins/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ <h1 class="documentation-title">
<li><a href="#plugin-resizimg">Resizimg</a></li>
<li><a href="#plugin-ruby">Ruby</a></li>
<li><a href="#plugin-specialchars">Special Chars</a></li>
<li><a href="#plugin-speechrecognition">Speech recognition</a></li>
<li><a href="#plugin-table">Table</a></li>
<li><a href="#plugin-template">Template</a></li>
<li><a href="#plugin-upload">Upload</a></li>
Expand Down Expand Up @@ -1196,6 +1197,65 @@ <h4>Options</h4>
</code></pre>
</div>

<div class="feature">
<h3 id="plugin-speechrecognition">Speech recogintion</h3>

<p>
Speech recognition plugin allows you to add text via speech.
</p>

<p>
<a href="../../demos/#plugins-speechrecognition" class="button button-demo">Try speech recognition live demo!</a>
<a href="https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/speechrecognition/trumbowyg.speechrecognition.js" class="button button-demo">
View speech recognition plugin code on GitHub
</a>
</p>

<h4>How to use it?</h4>
<pre><code class="html">
&lt;!-- Import Trumbowyg speech recognition at the end of &lt;body>... -->
&lt;script src="trumbowyg/dist/plugins/speechrecognition/trumbowyg.speechrecognition.min.js">&lt;/script>
</code></pre>
<p>
Then you can use the new button definition <code>speechrecognition</code>.
</p>

<pre><code class="javascript">
$('#my-editor').trumbowyg({
btns: [
['speechrecognition']
]
});
</code></pre>

<h4>Options</h4>
<dl>
<dt><strong><code>lang</code></strong> <code class="type">string</code></dt>
<dd>
Language code which language should be detected.
<br>
<strong>Default</strong>: en_GB
</dd>
</dl>

<p>
Example with options:
</p>
<pre><code class="javascript">
$('#my-editor)
.trumbowyg({
btns: [
['speechrecognition']
],
plugins: {
speechrecognition: {
lang: 'de-DE'
}
}
});
</code></pre>
</div>

<div class="feature">
<h3 id="plugin-table">Table</h3>

Expand Down
8 changes: 8 additions & 0 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,14 @@ <h3 class="section-subtitle">Extends Trumbowyg</h3>
Special chars
</a>
</li>
<li>
<a href="./documentation/plugins/#plugin-speechrecognition">
<svg>
<use xlink:href="#trumbowyg-speechrecognition"></use>
</svg>
Speech recognition
</a>
</li>
<li>
<a href="./documentation/plugins/#plugin-table">
<svg>
Expand Down
201 changes: 201 additions & 0 deletions plugins/speechrecognition/trumbowyg.speechrecognition.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
/* ===========================================================
* trumbowyg.speechrecognition.js v1.0
* Speech recognition plugin for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : Tobias Rohde
* Website : tobiasrohde.de
*/
(function ($) {
'use strict';

const defaultOptions = {
lang: 'en-GB'
};

const iconWrap = $(document.createElementNS('http://www.w3.org/2000/svg', 'svg'));
let btnElement = null;
let editor = null;
let finalText = '';
let recognizing = false;

const SpeechRecognition = window.webkitSpeechRecognition || window.SpeechRecognition;
const recognition = new SpeechRecognition();

recognition.continuous = true;
recognition.interimResults = true;

recognition.onstart = function() {
recognizing = true;
btnElement.style.fill='red';
};

recognition.onerror = function() {
recognizing = false;
btnElement.style.fill='#222';
};

recognition.onend = function() {
recognizing = false;
btnElement.style.fill='#222';
};

recognition.onresult = function(event) {
let interimText = '';
if (typeof(event.results) === 'undefined') {
recognition.onend = null;
recognition.stop();
return;
}
for (let i = event.resultIndex; i < event.results.length; i+=1) {
if (event.results[i].isFinal) {
finalText += event.results[i][0].transcript + '<br>';
editor.html(finalText);
} else {
interimText += event.results[i][0].transcript;
editor.html(finalText + interimText);
}
}
};

function buildButtonDef (trumbowyg) {
return {
fn: function () {
if (recognizing) {
recognition.stop();
return;
}

// I don't know it there's a more elegant way to access the speech recognition button.
btnElement = document.body.querySelector(`#${trumbowyg.$c[0].id}`).parentElement.querySelector('.trumbowyg-speechrecognition-button').firstChild;
editor = trumbowyg;
finalText = '';
recognition.lang = trumbowyg.o.plugins.speechrecognition.lang;
recognition.start();
btnElement.style.fill='red';
}
};
}

function buildButtonIcon() {
if ($('#trumbowyg-speechrecognition').length > 0) {
return;
}

iconWrap.addClass('trumbowyg-icons');

// Mic icon from Remix Icon - https://remixicon.com/
iconWrap.html(`
<symbol id="trumbowyg-speechrecognition" viewBox="0 0 24 24">
<path class="btn-speechrecognition" d="M11.9998 3C10.3429 3 8.99976 4.34315 8.99976 6V10C8.99976 11.6569 10.3429 13 11.9998 13C13.6566 13 14.9998 11.6569 14.9998 10V6C14.9998 4.34315 13.6566 3 11.9998 3ZM11.9998 1C14.7612 1 16.9998 3.23858 16.9998 6V10C16.9998 12.7614 14.7612 15 11.9998 15C9.23833 15 6.99976 12.7614 6.99976 10V6C6.99976 3.23858 9.23833 1 11.9998 1ZM3.05469 11H5.07065C5.55588 14.3923 8.47329 17 11.9998 17C15.5262 17 18.4436 14.3923 18.9289 11H20.9448C20.4837 15.1716 17.1714 18.4839 12.9998 18.9451V23H10.9998V18.9451C6.82814 18.4839 3.51584 15.1716 3.05469 11Z"></path>
</symbol>
`).appendTo(document.body);
}


$.extend(true, $.trumbowyg, {
langs: {
az: {
speechrecognition: 'Nitqin tanınması'
},
bg: {
speechrecognition: 'Разпознаване на реч'
},
by: {
speechrecognition: 'Распазнаванне маўлення'
},
ca: {
speechrecognition: 'Reconeixement de veu'
},
cs: {
speechrecognition: 'Rozpoznávání řeči'
},
da: {
speechrecognition: 'Talegenkendelse'
},
de: {
speechrecognition: 'Spracherkennung'
},
el: {
speechrecognition: 'Αναγνώριση ομιλίας'
},
en: {
speechrecognition: 'Speech recognition'
},
es: {
speechrecognition: 'Reconocimiento de voz'
},
et: {
speechrecognition: 'Kõnetuvastus'
},
fi: {
speechrecognition: 'Puheentunnistus'
},
fr: {
speechrecognition: 'Reconnaissance vocale'
},
hr: {
speechrecognition: 'Prepoznavanje govora'
},
hu: {
speechrecognition: 'Beszédfelismerés'
},
it: {
speechrecognition: 'Riconoscimento vocale'
},
lt: {
speechrecognition: 'Kalbos atpažinimas'
},
nb: {
speechrecognition: 'Talegjenkjenning'
},
nl: {
speechrecognition: 'Spraakherkenning'
},
pl: {
speechrecognition: 'Rozpoznawanie mowy'
},
pt: {
speechrecognition: 'Reconhecimento de voz'
},
ro: {
speechrecognition: 'Recunoașterea vorbirii'
},
rs: {
speechrecognition: 'Препознавање говора'
},
ru: {
speechrecognition: 'Распознавание речи'
},
sk: {
speechrecognition: 'Rozpoznávanie reči'
},
sq: {
speechrecognition: 'Njohja e të folurit'
},
sv: {
speechrecognition: 'Taligenkänning'
},
ua: {
speechrecognition: 'Розпізнавання мови'
}
},

plugins: {
speechrecognition: {
init: function (trumbowyg) {
trumbowyg.o.plugins.speechrecognition = $.extend(true, {},
defaultOptions,
trumbowyg.o.plugins.speechrecognition || {}
);

// Unfortunately Firefox has not implemented the WebSpeechAPI yet.
if(!navigator.userAgent.toLowerCase().includes('firefox')) {
buildButtonIcon();
trumbowyg.addBtnDef('speechrecognition', buildButtonDef(trumbowyg));
}
}
}
}
});
})(jQuery);
1 change: 1 addition & 0 deletions plugins/speechrecognition/ui/icons/speechrecognition.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit bf9bf2f

Please sign in to comment.