This is a user script for Chrome. It provides hotkeys for two modes of dictation (replacement and insertion).
The included shell script was used when I was looking at doing this with a bookmarklet.
This is a user script for Chrome. It provides hotkeys for two modes of dictation (replacement and insertion).
The included shell script was used when I was looking at doing this with a bookmarklet.
| #!/bin/bash | |
| nodejs <<- EOF | |
| var compressor = require('node-minify'); | |
| // Using Google Closure Compiler | |
| compressor.minify({ | |
| compressor: 'gcc', | |
| input: 'voice.js', | |
| output: 'out.js', | |
| callback: function (err, min) { | |
| // console.log(min); | |
| console.log(err); | |
| } | |
| }); | |
| EOF | |
| echo 'javascript:' | cat - out.js | tr -d '\n' | xsel -ib | |
| echo 'javascript:' | cat - out.js | tr -d '\n' |
| (function(){ | |
| function buildRecognition() { | |
| var recognition = new webkitSpeechRecognition(); | |
| recognition.isOn = false; | |
| recognition.continuous = false; | |
| recognition.interimResults = false; | |
| return recognition; | |
| } | |
| var recognition = buildRecognition(); | |
| function extractTranscript(event) { | |
| var transcript = ''; | |
| for (var i = event.resultIndex; i < event.results.length; ++i) { | |
| transcript += event.results[i][0].transcript; | |
| } | |
| return transcript || ''; | |
| } | |
| function dictate(input, onresult) { | |
| if (recognition.isOn) { | |
| recognition.stop(); | |
| } | |
| else { | |
| recognition.onresult = onresult; | |
| recognition.onstart = function onstart(event) { | |
| input.style.background = '#dfd'; | |
| recognition.isOn = true; | |
| }; | |
| recognition.onend = function onend(event) { | |
| input.style.background = input.origBg || ''; | |
| recognition.isOn = false; | |
| }; | |
| recognition.start(); | |
| } | |
| } | |
| function replaceText(input) { | |
| dictate(input, function(event) { | |
| input.value = extractTranscript(event); | |
| }); | |
| } | |
| function replaceTextFocused() { | |
| replaceText(document.activeElement); | |
| } | |
| function insertText(input) { | |
| dictate(input, function(event) { | |
| var t = input.value || ''; | |
| var d = extractTranscript(event); | |
| var i = input.selectionStart; | |
| input.value = t.slice(0, i) + d + t.slice(i); | |
| input.selectionStart = i + d.length; | |
| input.selectionEnd = i + d.length; | |
| }); | |
| } | |
| var textareas = Array.prototype.slice.call(document.getElementsByTagName('textarea')); | |
| var textinputs = Array.prototype.slice.call(document.getElementsByTagName('input')).filter(function (o) { | |
| return o.type == 'text' || !o.type; | |
| }); | |
| var els = textinputs.concat(textareas); | |
| for (var i in els) { | |
| var e = els[i]; | |
| if (!e.style) continue; | |
| e.onkeypress = function(evt) { | |
| if (evt.ctrlKey && evt.which == 14) | |
| replaceText(this); | |
| else if (evt.ctrlKey && evt.which == 12) | |
| insertText(this); | |
| else | |
| console.log('key', evt.which); | |
| }; | |
| console.log(e); | |
| e.origBg = e.style.background; | |
| } | |
| // Add access to fns from global namespace | |
| var script = document.createElement('script'); | |
| script.appendChild(document.createTextNode('(function(){' | |
| + 'var buildRecognition = ' + buildRecognition + ';' | |
| + 'var recognition = buildRecognition();' | |
| + 'var extractTranscript = ' + extractTranscript + ';' | |
| + 'var dictate = ' + dictate + ';' | |
| + 'var replaceText = ' + replaceText + ';' | |
| + 'window.replaceTextFocused = ' + replaceTextFocused + ';' | |
| + 'var insertText = ' + insertText + ';' | |
| + '})();')); | |
| (document.body || document.head || document.documentElement).appendChild(script); | |
| console.log('userscript loaded 10'); | |
| })(); |