Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Plugin: Speech recognition #1453

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.